diff --git a/anisotropy/anisotropy.py b/anisotropy/anisotropy.py index 20e59df..d8217f2 100644 --- a/anisotropy/anisotropy.py +++ b/anisotropy/anisotropy.py @@ -13,10 +13,6 @@ import logging CONFIG = os.path.join(ROOT, "conf/config.toml") config = struct(toml.load(CONFIG)) - - #CONFIG = os.path.abspath("../conf/config.toml") - #config = struct(toml.load(CONFIG)) - LOG = os.path.join(ROOT, "logs") if not os.path.exists(LOG): os.makedirs(LOG) @@ -35,109 +31,128 @@ logging.basicConfig( ) logger = logging.getLogger(config.logger.name) + def main(): if checkEnv(): return tasks = createTasks() - for task in tasks: + for n, case in enumerate(tasks): logger.info("-" * 80) logger.info(f"""main: - task:\t{tasks.index(task) + 1} / {len(tasks)} - cpu count:\t{os.cpu_count()} - structure:\t{task.structure} - direction:\t{task.direction} - theta:\t{task.theta} - fillet:\t{task.fillet} - export:\t{task.export}""") - - if not os.path.exists(task.export): - os.makedirs(task.export) - - createMesh(task) - - if os.path.exists(os.path.join(task.export, "mesh.unv")): - task.mesh = True - - returncode = calculate(task) - - if not returncode: - task.flow = True - - with open(os.path.join(LOG, "tasks.log"), "a") as io: - idx = tasks.index(task) - io.write(f"""Task {idx}: - structure:\t{task.structure} - direction:\t{task.direction} - theta:\t{task.theta} - mesh:\t{task.mesh} - flow:\t{task.flow}\n""") - - - #logger.info(f"Warnings: {logger.warnings}\tErrors: {logger.errors}") + task:\t{ n + 1 } / { len(tasks) } + cpu count:\t{ os.cpu_count() } + case:\t{ case }""") + + ### + # Compute mesh + ## + computeMesh(case) + + task = struct(toml.load(os.path.join(case, "task.toml"))) + + if not task.status.mesh: + logger.critical("mesh not computed: Skipping flow computation") + continue + ### + # Compute flow + ## + computeFlow(case) + def createTasks(): tasks = [] + for structure in config.base.__dict__.keys(): + ### + # Special values + ## + _theta = getattr(config, structure).parameters.theta + getattr(config, structure).parameters.theta = [ n * _theta[2] for n in range(int(_theta[0] / _theta[2]), int(_theta[1] / _theta[2]) + 1) ] + + _thickness = getattr(config, structure).mesh.thickness + _count = len(getattr(config, structure).parameters.theta) + getattr(config, structure).mesh.thickness = [ _thickness[0] + n * (_thickness[1] - _thickness[0]) / (_count - 1) for n in range(0, _count) ] + + ### + # structure type / flow direction / coefficient theta + ## for structure in config.base.__dict__.keys(): if getattr(config.base, structure): for direction in getattr(config, structure).geometry.directions: - for theta in getattr(config, structure).theta: - task = struct( - structure = structure, - theta = theta, - fillet = getattr(config, structure).geometry.fillet, - direction = direction, - export = os.path.join(ROOT, f"{ BUILD }/{ structure }/direction-{ direction[0] }{ direction [1] }{ direction [2] }/theta-{ theta }"), - mesh = False, - flow = False + for n, theta in enumerate(getattr(config, structure).parameters.theta): + case = os.path.join( + f"{ BUILD }", + f"{ structure }", + f"direction-{ direction[0] }{ direction [1] }{ direction [2] }", + f"theta-{ theta }" ) - tasks.append(task) + if not os.path.exists(case): + os.makedirs(case) + + task = { + "logger": config.logger.__dict__, + "structure": structure, + "status": { + "mesh": False, + "flow": False + }, + "parameters": { + "theta": theta + }, + "geometry": { + "direction": direction, + "fillet": getattr(config, structure).geometry.fillet + }, + "mesh": getattr(config, structure).mesh.__dict__ + } + + #task["mesh"]["thickness"] = task["mesh"]["thickness"][int(n)] + + with open(os.path.join(case, "task.toml"), "w") as io: + toml.dump(task, io) + + + tasks.append(case) return tasks + from salomepl.utils import runExecute, salomeVersion -def createMesh(task): +def computeMesh(case): scriptpath = os.path.join(ROOT, "salomepl/genmesh.py") port = 2810 stime = time.monotonic() - args = ( - task.structure, - task.theta, - int(task.fillet), - "".join([str(coord) for coord in task.direction]), - os.path.join(task.export, "mesh.unv"), - ROOT - ) - returncode = runExecute(port, scriptpath, *args) + returncode = runExecute(port, scriptpath, ROOT, case) etime = time.monotonic() - logger.info("createMesh: elapsed time: {}".format(timedelta(seconds = etime - stime))) + logger.info("computeMesh: elapsed time: {}".format(timedelta(seconds = etime - stime))) import openfoam -def calculate(task): +def computeFlow(case): foamCase = [ "0", "constant", "system" ] - os.chdir(task.export) + os.chdir(case) + task = struct(toml.load(os.path.join(case, "task.toml"))) openfoam.foamClean() for d in foamCase: shutil.copytree( os.path.join(ROOT, "openfoam/template", d), - os.path.join(task.export, d) + os.path.join(case, d) ) stime = time.monotonic() if not os.path.exists("mesh.unv"): - logger.critical(f"calculate: missed 'mesh.unv'") + logger.critical(f"computeFlow: missed 'mesh.unv'") return _, returncode = openfoam.ideasUnvToFoam("mesh.unv") @@ -171,10 +186,23 @@ def calculate(task): if out: logger.info(out) + if returncode == 0: + task.status.flow = True + + with open(os.path.join(case, "task.toml"), "w") as io: + toml.dump({ + "structure": task.structure, + "logger": task.logger.__dict__, + "status": task.status.__dict__, + "parameters": task.parameters.__dict__, + "geometry": task.geometry.__dict__, + "mesh": task.mesh.__dict__ + }, io) + os.chdir(ROOT) etime = time.monotonic() - logger.info("calculate: elapsed time: {}".format(timedelta(seconds = etime - stime))) + logger.info("computeFlow: elapsed time: {}".format(timedelta(seconds = etime - stime))) return returncode diff --git a/conf/config.toml b/conf/config.toml index 399c44b..1241235 100644 --- a/conf/config.toml +++ b/conf/config.toml @@ -1,3 +1,9 @@ +### +# Default config for anisotropy +# +# theta = [min, max, step] +## + [logger] name = "anisotropy" format = "%(levelname)s: %(message)s" @@ -7,8 +13,11 @@ simple = true bodyCentered = true faceCentered = true -[simple] -theta = [0.01, 0.28] +### +# Simple +## +[simple.parameters] +theta = [0.01, 0.28, 0.01] [simple.geometry] directions = [ @@ -34,13 +43,16 @@ useSurfaceCurvature = true fuseEdges = true checkChartBoundary = false -thickness = 0.005 +thickness = [0.005, 0.005] numberOfLayers = 2 stretchFactor = 1.2 isFacesToIgnore = true -[bodyCentered] -theta = [0.01, 0.18] +### +# Body-centered +## +[bodyCentered.parameters] +theta = [0.01, 0.18, 0.01] [bodyCentered.geometry] directions = [ @@ -66,13 +78,16 @@ useSurfaceCurvature = true fuseEdges = true checkChartBoundary = false -thickness = 0.005 +thickness = [0.005, 0.005] numberOfLayers = 2 stretchFactor = 1.2 isFacesToIgnore = true -[faceCentered] -theta = [0.01, 0.13] +### +# Face-centered +## +[faceCentered.parameters] +theta = [0.01, 0.13, 0.01] [faceCentered.geometry] directions = [ @@ -98,7 +113,7 @@ useSurfaceCurvature = true fuseEdges = true checkChartBoundary = false -thickness = 0.001 +thickness = [0.001, 0.001] numberOfLayers = 2 stretchFactor = 1.2 isFacesToIgnore = true diff --git a/salomepl/genmesh.py b/salomepl/genmesh.py index e8292c1..1425913 100644 --- a/salomepl/genmesh.py +++ b/salomepl/genmesh.py @@ -2,6 +2,8 @@ # This file executes inside salome environment # # salome starts at user home directory +# +# sys.argv = [ .., ROOT, case ] ## import os, sys import math @@ -9,7 +11,9 @@ import math import salome # get project path from args -ROOT = sys.argv[6] +ROOT = sys.argv[1] +CASE = sys.argv[2] + sys.path.append(ROOT) # site-packages from virtual env sys.path.append(os.path.join(ROOT, "env/lib/python3.9/site-packages")) @@ -18,7 +22,7 @@ import toml import logging from anisotropy.utils import struct -CONFIG = os.path.join(ROOT, "conf/config.toml") +CONFIG = os.path.join(CASE, "task.toml") config = struct(toml.load(CONFIG)) LOG = os.path.join(ROOT, "logs") @@ -41,25 +45,13 @@ from salomepl.geometry import getGeom from salomepl.mesh import smeshBuilder, meshCreate, meshCompute, meshStats, meshExport -def main(): +def genmesh(): - stype = str(sys.argv[1]) - theta = float(sys.argv[2]) - fillet = int(sys.argv[3]) - flowdirection = [int(coord) for coord in sys.argv[4]] - export = str(sys.argv[5]) - - genmesh(stype, theta, fillet, flowdirection, export) - - -def genmesh(stype, theta, fillet, direction, export): - - logger.info("""genMesh: - structure type:\t{} - coefficient:\t{} - fillet:\t{} - flow direction:\t{} - export path:\t{}""".format(stype, theta, fillet, direction, export)) + logger.info(f"""genmesh: + structure type:\t{ config.structure } + coefficient:\t{ config.parameters.theta } + fillet:\t{ config.geometry.fillet } + flow direction:\t{ config.geometry.direction }""") salome.salome_init() @@ -67,14 +59,14 @@ def genmesh(stype, theta, fillet, direction, export): # Shape ## geompy = getGeom() - structure = globals().get(stype) - shape, groups = structure(theta, fillet, direction) + structure = globals().get(config.structure) + shape, groups = structure(config.parameters.theta, config.geometry.fillet, config.geometry.direction) [length, surfaceArea, volume] = geompy.BasicProperties(shape, theTolerance = 1e-06) - logger.info("""shape: - edges length:\t{} - surface area:\t{} - volume:\t{}""".format(length, surfaceArea, volume)) + logger.info(f"""shape: + edges length:\t{ length } + surface area:\t{ surfaceArea } + volume:\t{ volume }""") ### # Mesh @@ -84,20 +76,33 @@ def genmesh(stype, theta, fillet, direction, export): if group.GetName() in ["inlet", "outlet"]: facesToIgnore.append(group) - meshParameters = getattr(config, stype).mesh + meshParameters = config.mesh meshParameters.facesToIgnore = facesToIgnore meshParameters.extrusionMethod = smeshBuilder.SURF_OFFSET_SMOOTH - mesh = meshCreate(shape, groups, meshParameters) #fineness, parameters, viscousLayers) - meshCompute(mesh) + mesh = meshCreate(shape, groups, meshParameters) + returncode = meshCompute(mesh) + + if returncode == 0: + config.status.mesh = True + + with open(CONFIG, "w") as io: + toml.dump({ + "structure": config.structure, + "logger": config.logger.__dict__, + "status": config.status.__dict__, + "parameters": config.parameters.__dict__, + "geometry": config.geometry.__dict__, + "mesh": config.mesh.__dict__ + }, io) meshStats(mesh) - meshExport(mesh, export) + meshExport(mesh, os.path.join(CASE, "mesh.unv")) salome.salome_close() if __name__ == "__main__": - main() + genmesh() diff --git a/salomepl/mesh.py b/salomepl/mesh.py index d026abf..6b654a4 100644 --- a/salomepl/mesh.py +++ b/salomepl/mesh.py @@ -153,6 +153,8 @@ def meshCompute(mobj): else: logger.warning("meshCompute: not computed") + return not status + def meshStats(mobj): """ diff --git a/salomepl/utils.py b/salomepl/utils.py index 9157e33..2ebbcdd 100644 --- a/salomepl/utils.py +++ b/salomepl/utils.py @@ -28,7 +28,7 @@ def runExecute(port: int, scriptpath: str, *args) -> int: scriptpath, "args:{}".format(", ".join([str(arg) for arg in args]))] logger.info("salome: {}".format(cmd[1 : 6])) - logpath = os.path.join("/".join(args[4].split("/")[:-1]), "salome.log") + logpath = os.path.join("/".join(args[0].split("/")[:-1]), "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)