diff --git a/anisotropy/anisotropy.py b/anisotropy/anisotropy.py index 621ad81..93bd4b5 100644 --- a/anisotropy/anisotropy.py +++ b/anisotropy/anisotropy.py @@ -3,10 +3,10 @@ import time from datetime import timedelta, datetime import shutil -ROOT = "/".join(__file__.split("/")[:-2]) -sys.path.append(os.path.abspath(ROOT)) +#ROOT = "/".join(__file__.split("/")[:-2]) +#sys.path.append(os.path.abspath(ROOT)) -from anisotropy.utils import struct +#from anisotropy.utils import struct import toml import logging @@ -14,37 +14,39 @@ __version__ = "1.1" ### # Shell args ## -configPath = "conf/config.toml" -mode = "safe" +#configPath = "conf/config.toml" +#mode = "safe" -for n, arg in enumerate(sys.argv): - if arg == "-c" or arg == "--config": - configPath = sys.args[n + 1] +#for n, arg in enumerate(sys.argv): +# if arg == "-c" or arg == "--config": +# configPath = sys.args[n + 1] - if arg == "-s" or arg == "--safe": - mode = "safe" +# if arg == "-s" or arg == "--safe": +# mode = "safe" - elif arg == "-a" or arg == "--all": - mode = "all" +# elif arg == "-a" or arg == "--all": +# mode = "all" ### # Load configuration and tools ## -CONFIG = os.path.join(ROOT, configPath) -config = struct(toml.load(CONFIG)) +#CONFIG = os.path.join(ROOT, configPath) +#config = struct(toml.load(CONFIG)) -LOG = os.path.join(ROOT, "logs") -if not os.path.exists(LOG): - os.makedirs(LOG) +#LOG = os.path.join(ROOT, "logs") +#if not os.path.exists(LOG): +# os.makedirs(LOG) -BUILD = os.path.join(ROOT, "build") -if not os.path.exists(BUILD): - os.makedirs(BUILD) +#BUILD = os.path.join(ROOT, "build") +#if not os.path.exists(BUILD): +# os.makedirs(BUILD) ################################################################################## import os import toml -from models import db, Structure, Mesh +from copy import deepcopy +from anisotropy.models import db, Structure, Mesh +import salomepl env = { "ROOT": os.path.abspath(".") } env.update({ @@ -54,6 +56,10 @@ env.update({ }) env["db_path"] = os.path.join(env["BUILD"], "anisotropy.db") +_defaultConfig = os.path.join(env["ROOT"], "anisotropy/default.toml") + +if os.path.exists(_defaultConfig): + env.update(toml.load(_defaultConfig)) if os.path.exists(env["CONFIG"]): config = toml.load(env["CONFIG"]) @@ -72,19 +78,30 @@ logging.basicConfig( handlers = [ logging.StreamHandler(), logging.FileHandler( - os.path.join(env["LOG"]), logger_env.get("name", "anisotropy") + os.path.join(env["LOG"], logger_env.get("name", "anisotropy")) ) ] ) logger = logging.getLogger(logger_env.get("name", "anisotropy")) +def timer(func): + def inner(*args, **kwargs): + start = time.monotonic() + ret = func(*args, **kwargs) + elapsed = time.monotonic() - start + + return ret, elapsed + + return inner + + class Anisotropy(object): def __init__(self): self.db = self._setupDB() self.structures = self._expandConfigParams(env["structures"]) - self._updateDB() + #self.updateDB() @staticmethod def version(): @@ -96,7 +113,7 @@ class Anisotropy(object): } try: - salomeplVersion = salomeVersion() + salomeplVersion = salomepl.version() openfoamVersion = openfoam.foamVersion() except Exception: @@ -139,7 +156,7 @@ class Anisotropy(object): for structure in structures: for direction in structure["geometry"]["directions"]: - for theta in structure["geometry"]["theta"]: + for n, theta in enumerate(structure["geometry"]["theta"]): prequeue = deepcopy(structure) del prequeue["geometry"]["directions"] @@ -153,6 +170,8 @@ class Anisotropy(object): "theta-{}".format(theta) ) + prequeue["mesh"]["thickness"] = structure["mesh"]["thickness"][n] + queue.append(prequeue) return queue @@ -161,44 +180,86 @@ class Anisotropy(object): queue = self._setupQueue(self.structures) for structure in queue: - s = Structure.update( + s = Structure.create( name = structure["name"], path = structure["path"], **structure["geometry"] ) - Mesh.update( + Mesh.create( structure = s, **structure["mesh"] ) def computeGeometryParams(self): from math import sqrt - structures = list(Structure.select().dicts()) + + structures = self._setupQueue(self.structures) for s in structures: - if s["name"] == "simple": - s["L"] = 2 * s["r0"] - s["radius"] = s["r0"] / (1 - s["theta"]) - s["length"] = s["L"] * sqrt(2) - s["width"] = s["L"] * sqrt(2) - s["height"] = s["L"] + theta = s["geometry"]["theta"] - C1, C2 = 0.8, 0.5 #0.8, 0.05 + if s["name"] == "simple": + r0 = 1 + L = 2 * r0 + radius = r0 / (1 - theta) + + C1, C2 = 0.8, 0.5 theta1, theta2 = 0.01, 0.28 - Cf = C1 + (C2 - C1) / (theta2 - theta1) * (s["theta"] - theta1) + Cf = C1 + (C2 - C1) / (theta2 - theta1) * (theta - theta1) delta = 0.2 - s["fillets"] = delta - Cf * (s["radius"] - s["r0"]) + fillets = delta - Cf * (radius - r0) elif s["name"] == "faceCentered": - pass + L = 1.0 + r0 = L * sqrt(2) / 4 + radius = r0 / (1 - theta) + + C1, C2 = 0.3, 0.2 + theta1, theta2 = 0.01, 0.13 + Cf = C1 + (C2 - C1) / (theta2 - theta1) * (theta - theta1) + delta = 0.012 + fillets = delta - Cf * (radius - r0) elif s["name"] == "bodyCentered": - pass + L = 1.0 + r0 = L * sqrt(3) / 4 + radius = r0 / (1 - theta) + + C1, C2 = 0.3, 0.2 + theta1, theta2 = 0.01, 0.18 + Cf = C1 + (C2 - C1) / (theta2 - theta1) * (theta - theta1) + delta = 0.02 + fillets = delta - Cf * (radius - r0) + + buf = {} #deepcopy(s) + buf.update( + {"name": s["name"], + "path": s["path"]}, + **s["geometry"] + ) + buf.update({ + "r0": r0, + "L": L, + "radius": radius, + "fillets": fillets + }) + stable = Structure.create(**buf) + Mesh.create( + structure = stable, + **s["mesh"] + ) + @timer def computeMesh(self): - pass + scriptpath = os.path.join(env["ROOT"], "salomepl/genmesh.py") + port = 2900 + + out, err, returncode = salomepl.runSalome(port, scriptpath, env["ROOT"], case) + + + def computeFlow(self): pass @@ -341,7 +402,7 @@ def createQueue(): return queue -from salomepl.utils import runExecute, salomeVersion +#from salomepl.utils import runExecute, salomeVersion def computeMesh(case): scriptpath = os.path.join(ROOT, "salomepl/genmesh.py") diff --git a/anisotropy/models.py b/anisotropy/models.py index 2eca44a..07d5214 100644 --- a/anisotropy/models.py +++ b/anisotropy/models.py @@ -1,8 +1,10 @@ from peewee import * +db = SqliteDatabase(None) + class BaseModel(Model): class Meta: - database = db + database = db class Structure(BaseModel): name = TextField() @@ -12,10 +14,8 @@ class Structure(BaseModel): r0 = FloatField() L = FloatField() radius = FloatField() - length = FloatField() - width = FloatField() - height = FloatField() + fillet = BooleanField() fillets = FloatField() path = TextField() diff --git a/conf/config.toml b/conf/config.toml index 5b98663..97a925f 100644 --- a/conf/config.toml +++ b/conf/config.toml @@ -15,109 +15,66 @@ simple = false bodyCentered = false faceCentered = true -### -# Simple -## -[simple.geometry] -theta = [0.01, 0.28, 0.01] -directions = [ - [1, 0, 0], - [0, 0, 1], - [1, 1, 1] -] -fillet = true +[[structures]] + name = "simple" -[simple.mesh] -viscousLayers = true -thickness = [0.01, 0.005] + [structures.geometry] + theta = [0.01, 0.28, 0.01] + directions = [ + [1, 0, 0], + [0, 0, 1], + [1, 1, 1] + ] + fillet = true -[simple.mesh.submesh.strips] -growthRate = 0.2 -nbSegPerEdge = 2 -nbSegPerRadius = 3 + [structures.mesh] + viscousLayers = true + thickness = [0.01, 0.005] -### -# Body-centered -## -# TODO: 0.18 -[bodyCentered.geometry] -theta = [0.01, 0.17, 0.01] -directions = [ - [1, 0, 0], - [0, 0, 1], - [1, 1, 1] -] -fillet = true + [structures.submesh.strips] + growthRate = 0.2 + nbSegPerEdge = 2 + nbSegPerRadius = 3 -[bodyCentered.mesh] -viscousLayers = true -thickness = [0.005, 0.0005] +[[structures]] + name = "bodyCentered" -[bodyCentered.mesh.submesh.strips] -growthRate = 0.2 -nbSegPerEdge = 2 -nbSegPerRadius = 3 + [structures.geometry] + theta = [0.01, 0.17, 0.01] + directions = [ + [1, 0, 0], + [0, 0, 1], + [1, 1, 1] + ] + fillet = true -### -# Face-centered -## -[faceCentered.geometry] -theta = [0.01, 0.13, 0.01] -directions = [ - [1, 0, 0], - [0, 0, 1], - [1, 1, 1] -] -fillet = true + [structures.mesh] + viscousLayers = true + thickness = [0.005, 0.0005] -[faceCentered.mesh] -viscousLayers = true -thickness = [0.001, 0.0005] + [structures.submesh.strips] + growthRate = 0.2 + nbSegPerEdge = 2 + nbSegPerRadius = 3 -[faceCentered.mesh.submesh.strips] -growthRate = 0.2 -nbSegPerEdge = 2 -nbSegPerRadius = 3 +[[structures]] + name = "faceCentered" -### -# Flow -## -[flow] -scale = [1e-5, 1e-5, 1e-5] + [structures.geometry] + theta = [0.01, 0.13, 0.01] + directions = [ + [1, 0, 0], + [0, 0, 1], + [1, 1, 1] + ] + fillet = true -[flow.constant] -nu = 1e-6 - -[flow.approx.pressure.boundaryField] -inlet.type = "fixedValue" -inlet.value = 1e-3 -outlet.type = "fixedValue" -outlet.value = 0 - -[flow.approx.velocity.boundaryField] -inlet.type = "fixedValue" -inlet.value = [ - [ 6e-5, 6e-5, 0.0 ], - [ 0.0, 0.0, 6e-5 ], - [ 6e-5, 6e-5, 6e-5 ] -] -outlet.type = "zeroGradient" -outlet.value = "None" - -[flow.main.pressure.boundaryField] -inlet.type = "fixedValue" -inlet.value = 1e-3 -outlet.type = "fixedValue" -outlet.value = 0 - -[flow.main.velocity.boundaryField] -inlet.type = "pressureInletVelocity" -inlet.value = [ - [ 0, 0, 0 ], - [ 0, 0, 0 ], - [ 0, 0, 0 ] -] -outlet.type = "zeroGradient" -outlet.value = "None" + [structures.mesh] + viscousLayers = true + thickness = [0.001, 0.0005] + [structures.submesh.strips] + growthRate = 0.2 + nbSegPerEdge = 2 + nbSegPerRadius = 3 diff --git a/salomepl/utils.py b/salomepl/utils.py index 697809b..2fd5ef5 100644 --- a/salomepl/utils.py +++ b/salomepl/utils.py @@ -3,81 +3,68 @@ import subprocess import logging import sys, os -logger = logging.getLogger() - def hasDesktop() -> bool: return salome.sg.hasDesktop() -def startServer(port): - logger.info("Starting SALOME on port {} ...".format(port)) +class SalomeNotFound(Exception): + pass - p = subprocess.Popen(["salome", "start", "--port", str(port), "-t"], - #shell = False, + +def version() -> str: + if os.environ.get("SALOME_PATH"): + cmd = os.path.join(os.environ["SALOME_PATH"], "salome") + + else: + raise(SalomeNotFound("Can't find salome executable.")) + + proc = subprocess.Popen( + [ cmd, "--version" ], + stdout = subprocess.PIPE, + stderr = subprocess.PIPE + ) + + out, err = proc.communicate() + + return str(out, "utf-8").strip().split(" ")[-1] + + +def runSalome(port: int, scriptpath: str, root: str, logpath: str = None, *args) -> int: + + if os.environ.get("SALOME_PATH"): + cmd = os.path.join(os.environ["SALOME_PATH"], salome) + + else: + raise(SalomeNotFound("Can't find salome executable.")) + + if not logpath: + logpath = "/tmp/salome.log" + + fmtargs = "args:{}".format(", ".join([ str(arg) for arg in args ])) + cmdargs = [ + "start", "-t", + "--shutdown-servers=1", + "--port", str(port), + scriptpath, + root, + logpath, + fmtargs + ] + + with subprocess.Popen( + [ cmd, cmdargs ], stdout = subprocess.PIPE, - stderr = subprocess.PIPE) + stderr = subprocess.PIPE + ) as proc, open(logpath, "wb") as logfile: - return p - -def salomeVersion() -> str: - return "Salome 9.7.0 MPI" - -def runExecute(port: int, scriptpath: str, *args) -> int: - - cmd = ["salome-9.7.0-mpi", "start", "--shutdown-servers=1", "--port", str(port), "-t", - scriptpath, "args:{}".format(", ".join([str(arg) for arg in args]))] - - logger.info("salome: {}".format(cmd[1 : 6])) - case = args[1] - logpath = os.path.join(case, "salome.log") - - #p = subprocess.Popen(["salome", "start", "--shutdown-servers=1", "--port", str(port), "-t", scriptpath, "args:{}".format(", ".join([str(arg) for arg in args]))], - # stderr = subprocess.STDOUT) - #_, err = p.communicate() - - with subprocess.Popen(cmd, - stdout = subprocess.PIPE, - stderr = subprocess.PIPE) as p, \ - open(logpath, "wb") as logfile: - - for line in p.stdout: - # sys.stdout.buffer.write(line) + logfile = open(logpath, "wb") + for line in proc.stdout: logfile.write(line) out, err = p.communicate() - #print(str(err, "utf-8")) - logfile.write(err) if err: - logger.error("salome:\n\t{}".format(str(err, "utf-8"))) - #if err: - # if p.returncode == 1: - # logger.error(err) + logfile.write(err) - # else: - # logger.warning(err) + return out, err, proc.returncode - return p.returncode - -def killServer(port): - - logger.info("Terminating SALOME on port {} ...".format(port)) - - p = subprocess.Popen(["salome", "kill", str(port)], - #shell = True, - stdout = subprocess.PIPE, - stderr = subprocess.PIPE) - - return p - -def remote(port, cmd): - - logger.info("Executing command in the SALOME on port {} ...".format(port)) - - # cmd = "python -m"; = "python -c" - p = subprocess.Popen(["salome", "remote", "-p", str(port), "--", str(cmd)], - #shell = True, - stdout = subprocess.PIPE, - stderr = subprocess.PIPE) - - return p