diff --git a/INSTALL.rst b/INSTALL.rst new file mode 100644 index 0000000..cd7a81d --- /dev/null +++ b/INSTALL.rst @@ -0,0 +1,3 @@ +Installation +============ + diff --git a/anisotropy/__init__.py b/anisotropy/__init__.py index cfb6c87..a15ed92 100644 --- a/anisotropy/__init__.py +++ b/anisotropy/__init__.py @@ -27,7 +27,7 @@ env.update( env.update( logger_name = "anisotropy", db_path = env["BUILD"], - salome_port = 2810, + salome_timeout = 15 * 60, openfoam_template = os.path.join(env["ROOT"], "anisotropy/openfoam/template") ) diff --git a/anisotropy/core/main.py b/anisotropy/core/main.py index 078e6bd..15d5b75 100644 --- a/anisotropy/core/main.py +++ b/anisotropy/core/main.py @@ -74,7 +74,7 @@ class Anisotropy(object): } try: - versions["Salome"] = salomepl.utils.version() + versions["Salome"] = salomepl.utils.SalomeManager().version() versions["OpenFOAM"] = openfoam.version() except Exception: @@ -230,20 +230,25 @@ class Anisotropy(object): :return: Process output, error messages and returncode :rtype: tuple(str, str, int) """ - scriptpath = os.path.join(self.env["ROOT"], "anisotropy/core/cli.py") - port = 2900 - p = self.params["structure"] + scriptpath = os.path.join(self.env["ROOT"], "anisotropy/core/cli.py") + salomeargs = [ + "computemesh", + p["type"], + p["direction"], + p["theta"], + ] + manager = salomepl.utils.SalomeManager() - return salomepl.utils.runSalome( - self.env["salome_port"], + return manager.execute( scriptpath, - self.env["ROOT"], - "computemesh", - p["type"], p["direction"], p["theta"], + *salomeargs, + timeout = self.env["salome_timeout"], + root = self.env["ROOT"], logpath = os.path.join(self.env["LOG"], "salome.log") ) + def genmesh(self): """Computes a mesh on shape diff --git a/anisotropy/salomepl/utils.py b/anisotropy/salomepl/utils.py index 666bbbf..321b36f 100644 --- a/anisotropy/salomepl/utils.py +++ b/anisotropy/salomepl/utils.py @@ -2,76 +2,105 @@ # This file is part of anisotropy. # License: GNU GPL version 3, see the file "LICENSE" for details. -#import salome import subprocess import logging import sys, os - -def hasDesktop() -> bool: - return salome.sg.hasDesktop() +import re class SalomeNotFound(Exception): pass -def version() -> str: - if os.environ.get("SALOME_PATH"): - cmd = os.path.join(os.environ["SALOME_PATH"], "salome") +class SalomeManager(object): + def __init__(self): + self.__port = None + self.__lastproc = None - else: - raise(SalomeNotFound("Can't find salome executable.")) - proc = subprocess.Popen( - [ cmd, "--version" ], - stdout = subprocess.PIPE, - stderr = subprocess.PIPE - ) + def runner(self, cmdargs: list, **kwargs): + timeout = kwargs.pop("timeout") if kwargs.get("timeout") else None - out, err = proc.communicate() + try: + with subprocess.Popen( + cmdargs, + stdout = kwargs.pop("stdout") if kwargs.get("stdout") else subprocess.PIPE, + stderr = kwargs.pop("stdout") if kwargs.get("stderr") else subprocess.PIPE, + **kwargs + ) as proc: + self.__lastproc = proc + out, err = proc.communicate(timeout = timeout) - return str(out, "utf-8").strip().split(" ")[-1] + except FileNotFoundError: + raise SalomeNotFound() -def runSalome(port: int, scriptpath: str, root: str, *args, logpath: str = None) -> int: - # ISSUE: salome removes commas from string list + return out, err, proc.returncode - if os.environ.get("SALOME_PATH"): - cmd = [ os.path.join(os.environ["SALOME_PATH"], "salome") ] - else: - raise(SalomeNotFound("Can't find salome executable.")) + def port(self) -> int: + out, err, returncode = self.runner(["salome", "start", "--print-port"], text = True) + + if returncode == 0: + reg = re.search("(?!port:)([0-9]+)", out) - if not logpath: - logpath = "/tmp/salome.log" + if reg: + return int(reg.group()) - #fullargs = list(args) - args = list(args) - args.insert(1, root) - fmtargs = "args:{}".format(",".join([ '"{}"'.format(str(arg)) for arg in args ])) - cmdargs = [ - "start", "-t", - "--shutdown-servers=1", - "--port", str(port), - scriptpath, - fmtargs - ] + return 2810 - cmd.extend(cmdargs) - with subprocess.Popen( - cmd, - stdout = subprocess.PIPE, - stderr = subprocess.PIPE - ) as proc, open(logpath, "wb") as logfile: + def version(self) -> int: + out, err, returncode = self.runner(["salome", "--version"], text = True) - logfile = open(logpath, "wb") - for line in proc.stdout: - logfile.write(line) + return out.strip().split(" ")[-1] - out, err = proc.communicate() - if err: - logfile.write(err) + def kill(self, port: int = None): + return self.runner(["salome", "kill", str(self.__port or port)]) + + + def execute(self, scriptpath: str, *args, root: str = None, logpath: str = None, timeout: int = None, **kwargs): + + if not root: + root = os.environ["HOME"] + + # ISSUE: salome removes commas from string list + args = list(args) + args.insert(1, root) + + salomeargs = "args:" + salomeargs += ",".join([ '"{}"'.format(str(arg)) for arg in args ]) + + if kwargs: + salomeargs += "," + ",".join([ '{}="{}"'.format(k, v) for k, v in kwargs.items() ]) + + ### + self.__port = self.port() + cmd = [ + "salome", + "start", + "-t", + "--shutdown-servers=1", + "--port", str(self.__port), + scriptpath, + salomeargs + ] + + try: + out, err, returncode = self.runner(cmd, timeout = timeout) + + except subprocess.TimeoutExpired: + lastproc = self.__lastproc + self.kill() + + out, err = lastproc.communicate() + returncode = lastproc.returncode + + if logpath: + with open(os.path.join(logpath, "salome.log"), "wb") as io: + io.write(out) + io.write(err) + + return str(out, "utf-8"), str(err, "utf-8"), returncode - return out, err, proc.returncode diff --git a/conf/bashrc b/conf/bashrc new file mode 100644 index 0000000..8aa1874 --- /dev/null +++ b/conf/bashrc @@ -0,0 +1,2 @@ +export PATH="${PATH}:${HOME}/programs/salome/SALOME-9.7.0-MPI" +source "${HOME}/programs/OpenFOAM/OpenFOAM-v2012/etc/bashrc" diff --git a/docs/source/INSTALL.rst b/docs/source/INSTALL.rst new file mode 100644 index 0000000..cd7a81d --- /dev/null +++ b/docs/source/INSTALL.rst @@ -0,0 +1,3 @@ +Installation +============ + diff --git a/docs/source/anisotropy.rst b/docs/source/anisotropy.rst index 844840b..255eea7 100644 --- a/docs/source/anisotropy.rst +++ b/docs/source/anisotropy.rst @@ -5,7 +5,7 @@ Subpackages ----------- .. toctree:: - :maxdepth: 4 + :maxdepth: 1 anisotropy.core anisotropy.openfoam diff --git a/docs/source/index.rst b/docs/source/index.rst index caf6b00..2495dd9 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -10,7 +10,8 @@ Welcome to anisotropy's documentation! :maxdepth: 2 :caption: Contents: - modules + INSTALL + anisotropy .. include:: ../../README.rst