diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/config.py b/config.py new file mode 100644 index 0000000..bd6aa21 --- /dev/null +++ b/config.py @@ -0,0 +1,165 @@ +import os, sys +from src import applogger + +### +# Paths +## +ROOT = os.getcwd() +sys.path.append(ROOT) + +LOG = os.path.join(ROOT, "logs") +BUILD = os.path.join(ROOT, "build") + +### +# Logger +## +global logger +logger = applogger.Logger() + +### +# Utilities +## +class Parameters: + """ + [ + "minSize", + "maxSize", + "growthRate", + "nbSegPerEdge", + "nbSegPerRadius", + "chordalErrorEnabled", + "chordalError", + "secondOrder", + "optimize", + "quadAllowed", + "useSurfaceCurvature", + "fuseEdges", + "checkChartBoundary" + ] + """ + def __init__(self, **kwargs): + for (k, v) in kwargs.items(): + setattr(self, k, v) + +class ViscousLayers(Parameters): + """ + [ + "thickness", + "numberOfLayers", + "stretchFactor", + "isFacesToIgnore", + "facesToIgnore", + "extrusionMethod" + ] + """ + pass + +### +# Project variables +## +structures = [ + "simple", + "bodyCentered", + "faceCentered" +] +class simple: + theta = [c * 0.01 for c in range(1, 28 + 1)] + directions = [ + [1, 0, 0], + [0, 0, 1], + [1, 1, 1] + ] + fillet = True + fineness = 1 + parameters = Parameters( + minSize = 0.0005, + maxSize = 0.1, + growthRate = 0.5, + nbSegPerEdge = 0.5, + nbSegPerRadius = 0.5, + chordalErrorEnabled = False, + chordalError = -1, + secondOrder = False, + optimize = True, + quadAllowed = False, + useSurfaceCurvature = True, + fuseEdges = True, + checkChartBoundary = False + ) + viscousLayers = ViscousLayers( + thickness = 0.001, + numberOfLayers = 3, + stretchFactor = 1.2, + isFacesToIgnore = True, + facesToIgnore = None, + extrusionMethod = None + ) + + +class bodyCentered: + theta = [c * 0.01 for c in range(1, 13 + 1)] + directions = [ + [1, 0, 0], + [0, 0, 1], + [1, 1, 1] + ] + fillet = True + fineness = 1 + parameters = Parameters( + minSize = 0.0005, + maxSize = 0.1, + growthRate = 0.5, + nbSegPerEdge = 0.5, + nbSegPerRadius = 0.5, + chordalErrorEnabled = False, + chordalError = -1, + secondOrder = False, + optimize = True, + quadAllowed = False, + useSurfaceCurvature = True, + fuseEdges = True, + checkChartBoundary = False + ) + viscousLayers = ViscousLayers( + thickness = 0.001, + numberOfLayers = 3, + stretchFactor = 1.2, + isFacesToIgnore = True, + facesToIgnore = None, + extrusionMethod = None + ) + + +class faceCentered: + theta = [c * 0.01 for c in range(1, 18 + 1)] + directions = [ + [1, 0, 0], + [0, 0, 1], + [1, 1, 1] + ] + fillet = True + fineness = 1 + parameters = Parameters( + minSize = 0.0005, + maxSize = 0.1, + growthRate = 0.5, + nbSegPerEdge = 0.5, + nbSegPerRadius = 0.5, + chordalErrorEnabled = False, + chordalError = -1, + secondOrder = False, + optimize = True, + quadAllowed = False, + useSurfaceCurvature = True, + fuseEdges = True, + checkChartBoundary = False + ) + viscousLayers = ViscousLayers( + thickness = 0.001, + numberOfLayers = 3, + stretchFactor = 1.2, + isFacesToIgnore = True, + facesToIgnore = None, + extrusionMethod = None + ) + diff --git a/run.py b/run.py index f9c85e6..7ac599f 100644 --- a/run.py +++ b/run.py @@ -6,147 +6,144 @@ from datetime import timedelta import multiprocessing import shutil -ROOT = os.getcwd() -sys.path.append(ROOT) - -LOG = os.path.join(ROOT, "logs") -BUILD = os.path.join(ROOT, "build") - +import config +from config import logger +#from src import applogger from src import utils from src import salome_utils from src import foam_utils -def createTasks(): - ### - # Control variables - ## - structures = [ - "simple", - #"bodyCentered", - #"faceCentered" - ] - directions = [ - #[1, 0, 0], - [0, 0, 1], - #[1, 1, 1] - ] - fillet = 1 - ### - # Tasks - ## - Task = namedtuple("Task", ["structure", "coeff", "fillet", "direction", "saveto"]) +def main(): + if not os.path.exists(config.LOG): + os.makedirs(config.LOG) + + if not os.path.exists(config.BUILD): + os.makedirs(config.BUILD) + + #global logger + #logger = applogger.Logger() + + checkEnv() + tasks = createTasks() + + for task in tasks: + 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) + calculate(task) + + logger.info(f"Warnings: {logger.warnings}\tErrors: {logger.errors}") + + +def checkEnv(): + try: + pythonVersion = "Python {}".format(sys.version.split(" ")[0]) + salomeVersion = salome_utils.salomeVersion() + foamVersion = foam_utils.foamVersion() + + except Exception: + logger.critical("Missed environment") + + else: + logger.info(f"enviroment:\n\t{pythonVersion}\n\t{salomeVersion}\n\t{foamVersion}") + + +def createTasks(): + Task = namedtuple("Task", ["structure", "theta", "fillet", "direction", "export"]) tasks = [] + structures = [ getattr(config, s)() for s in config.structures ] for structure in structures: - if structure == "simple": - theta = [0.01] #[c * 0.01 for c in range(1, 28 + 1)] - #theta = [ 0.01, 0.28 ] + for direction in structure.directions: + for theta in structure.theta: + name = type(structure).__name__ + export = os.path.join( + config.BUILD, + name, + "direction-{}{}{}".format(*direction), + "theta-{}".format(theta) + ) - elif structure == "faceCentered": - #theta = [c * 0.01 for c in range(1, 13 + 1)] - theta = [ 0.01, 0.13 ] - - elif structure == "bodyCentered": - #theta = [c * 0.01 for c in range(1, 18 + 1)] - theta = [ 0.01, 0.13, 0.14, 0.18 ] - - for coeff in theta: - for direction in directions: - saveto = os.path.join(BUILD, structure, "coeff-{}".format(coeff), - "direction-{}{}{}".format(direction[0], direction[1], direction[2])) - - if not os.path.exists(saveto): - os.makedirs(saveto) - - t = Task(structure, coeff, fillet, direction, saveto) - tasks.append(t) + tasks.append( + Task(name, theta, structure.fillet, direction, export) + ) return tasks -def createMesh(tasks): - scriptpath = os.path.join(ROOT, "samples/__init__.py") +def createMesh(task): + scriptpath = os.path.join(config.ROOT, "samples/__init__.py") port = 2810 - errors = 0 + stime = time.monotonic() - for task in tasks: - logging.info("-" * 80) - logging.info("""createMesh: - task:\t{} / {}""".format(tasks.index(task) + 1, len(tasks))) - start_time = time.monotonic() - - returncode = salome_utils.runExecute(port, scriptpath, task.structure, task.coeff, task.fillet, "".join([str(coord) for coord in task.direction]), os.path.join(task.saveto, "mesh.unv")) - - end_time = time.monotonic() - logging.info("createMesh: elapsed time: {}".format(timedelta(seconds=end_time - start_time))) - logging.info("salome: return code:\t{}".format(returncode)) - - if returncode == 1: - #break - errors += 1 - pass - - return errors + args = ( + task.structure, + task.theta, + int(task.fillet), + "".join([str(coord) for coord in task.direction]), + os.path.join(task.export, "mesh.unv"), + config.ROOT + ) + returncode = salome_utils.runExecute(port, scriptpath, *args) + etime = time.monotonic() + logger.info("createMesh: elapsed time: {}".format(timedelta(seconds = etime - stime))) -def calculate(tasks): + +def calculate(task): foamCase = [ "0", "constant", "system" ] - rmDirs = ["0", "constant", "system", "postProcessing", "logs"] + [ "processor{}".format(n) for n in range(4)] - for task in tasks: - - for d in rmDirs: - if os.path.exists(os.path.join(task.saveto, d)): - shutil.rmtree(os.path.join(task.saveto, d)) + os.chdir(task.export) + foam_utils.foamClean() - for d in foamCase: - if not os.path.exists(os.path.join(task.saveto, d)): - shutil.copytree(os.path.join(ROOT, "src/cubicFoam", d), - os.path.join(task.saveto, d)) + for d in foamCase: + shutil.copytree( + os.path.join(config.ROOT, "src/cubicFoam", d), + os.path.join(task.export, d) + ) - os.chdir(task.saveto) - casepath = "." - - logging.info("-" * 80) - logging.info("""calculate: - task:\t{} / {} - structure type:\t{} - coefficient:\t{} - flow direction:\t{} - path:\t{}""".format( - tasks.index(task) + 1, - len(tasks) , - task.structure, - task.coeff, - task.direction, - task.saveto - )) + stime = time.monotonic() - foam_utils.ideasUnvToFoam("mesh.unv") - - foam_utils.createPatch(dictfile = "system/createPatchDict.symetry") - - foam_utils.checkMesh() + if not os.path.exists("mesh.unv"): + logger.critical(f"calculate: missed 'mesh.unv'") + return - scale = (1e-5, 1e-5, 1e-5) - foam_utils.transformPoints(scale) - - foam_utils.decomposePar() + foam_utils.ideasUnvToFoam("mesh.unv") + + foam_utils.createPatch(dictfile = "system/createPatchDict.symetry") + + foam_utils.checkMesh() - foam_utils.renumberMesh() - - foam_utils.potentialFoam() - - for n in range(4): - foam_utils.foamDictionary("processor{}/0/U".format(n), - "boundaryField.inlet.type", "pressureInletVelocity") - foam_utils.foamDictionary("processor{}/0/U".format(n), - "boundaryField.inlet.value", "uniform (0 0 0)") - - foam_utils.simpleFoam() + scale = (1e-5, 1e-5, 1e-5) + foam_utils.transformPoints(scale) + + foam_utils.decomposePar() - os.chdir(ROOT) + foam_utils.renumberMesh() + + foam_utils.potentialFoam() + + for n in range(os.cpu_count()): + foam_utils.foamDictionary(f"processor{n}/0/U", "boundaryField.inlet.type", "pressureInletVelocity") + foam_utils.foamDictionary(f"processor{n}/0/U", "boundaryField.inlet.value", "uniform (0 0 0)") + + foam_utils.simpleFoam() + + os.chdir(config.ROOT) + + etime = time.monotonic() + logger.info("calculate: elapsed time: {}".format(timedelta(seconds = etime - stime))) def postprocessing(tasks): @@ -157,7 +154,7 @@ def postprocessing(tasks): for task in tasks: direction = "direction-{}{}{}".format(task.direction[0], task.direction[1], task.direction[2]) path = os.path.join(BUILD, task.structure, "postProcessing", direction) - surfaceFieldValuePath = os.path.join(task.saveto, "postProcessing", "") + surfaceFieldValuePath = os.path.join(task.export, "postProcessing", "") if not os.path.exists(path): os.makedirs(path) @@ -168,67 +165,10 @@ def postprocessing(tasks): io.write("{}\t{}".format(task.coeff, surfaceFieldValues[-1][1])) +### +# Main entry +## if __name__ == "__main__": - - if not os.path.exists(LOG): - os.makedirs(LOG) + main() - if not os.path.exists(BUILD): - os.makedirs(BUILD) - - logging.basicConfig( - level=logging.INFO, - format="%(levelname)s: %(message)s", - handlers = [ - logging.StreamHandler(), - logging.FileHandler("{}/cubic.log".format(LOG)) - ]) - - # TODO: add force arg - Args = namedtuple("Args", ["mesh", "calc", "pp"]) - - if len(sys.argv) > 1: - action = sys.argv[1] - - if action == "mesh": - args = Args(True, False, False) - - elif action == "calc": - args = Args(False, True, False) - - elif action == "pp": - args = Args(False, False, True) - - elif action == "all": - args = Args(True, True, True) - - else: - args = Args(True, True, True) - - tasks = createTasks() - logging.info("Tasks: {}".format(len(tasks))) - - if args.mesh: - start_time = time.monotonic() - #logging.info("Started at {}".format(timedelta(seconds=start_time))) - - errors = createMesh(tasks) - - end_time = time.monotonic() - logging.info("-" * 80) - logging.info("Elapsed time:\t{}".format(timedelta(seconds=end_time - start_time))) - logging.info("Errors:\t{}".format(errors)) - - if args.calc: - start_time = time.monotonic() - #logging.info("Started at {}".format(timedelta(seconds=start_time))) - - calculate(tasks) - - end_time = time.monotonic() - logging.info("-" * 80) - logging.info("Elapsed time: {}".format(timedelta(seconds=end_time - start_time))) - - if args.pp: - postprocessing(tasks) diff --git a/samples/__init__.py b/samples/__init__.py index aa4a594..c654bfa 100644 --- a/samples/__init__.py +++ b/samples/__init__.py @@ -4,13 +4,13 @@ import logging from pyquaternion import Quaternion import math -ROOT = "/home/nafaryus/projects/anisotrope-cube" -sys.path.append(ROOT) - -LOG = os.path.join(ROOT, "logs") - import salome +sys.path.append(sys.argv[6]) + +import config +from config import logger +#from src import applogger from simple import simpleCubic, simpleHexagonalPrism from faceCentered import faceCenteredCubic, faceCenteredHexagonalPrism from bodyCentered import bodyCenteredCubic, bodyCenteredHexagonalPrism @@ -18,14 +18,26 @@ from bodyCentered import bodyCenteredCubic, bodyCenteredHexagonalPrism from src import geometry_utils from src import mesh_utils -def genMesh(stype, theta, fillet, direction, saveto): - logging.info("""genMesh: +def main(): + + 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, saveto)) + export path:\t{}""".format(stype, theta, fillet, direction, export)) params = (theta, fillet, direction) @@ -41,6 +53,10 @@ def genMesh(stype, theta, fillet, direction, saveto): elif direction == [1, 1, 1]: structure = simpleHexagonalPrism + fineness = config.simple.fineness + parameters = config.simple.parameters + viscousLayers = config.simple.viscousLayers + elif stype == "faceCentered": if direction in [[1, 0, 0], [0, 0, 1]]: structure = faceCenteredCubic @@ -48,6 +64,10 @@ def genMesh(stype, theta, fillet, direction, saveto): elif direction == [1, 1, 1]: structure = faceCenteredHexagonalPrism + fineness = config.faceCentered.fineness + parameters = config.faceCentered.parameters + viscousLayers = config.faceCentered.viscousLayers + elif stype == "bodyCentered": if direction in [[1, 0, 0], [0, 0, 1]]: structure = bodyCenteredCubic @@ -55,6 +75,10 @@ def genMesh(stype, theta, fillet, direction, saveto): elif direction == [1, 1, 1]: structure = bodyCenteredHexagonalPrism + fineness = config.bodyCentered.fineness + parameters = config.bodyCentered.parameters + viscousLayers = config.bodyCentered.viscousLayers + ### # Shape ## @@ -62,7 +86,7 @@ def genMesh(stype, theta, fillet, direction, saveto): shape, groups = structure(*params) [length, surfaceArea, volume] = geompy.BasicProperties(shape, theTolerance = 1e-06) - logging.info("""shape: + logger.info("""shape: edges length:\t{} surface area:\t{} volume:\t{}""".format(length, surfaceArea, volume)) @@ -70,60 +94,23 @@ def genMesh(stype, theta, fillet, direction, saveto): ### # Mesh ## - fineness = 0 - parameters = mesh_utils.Parameters( - minSize = 0.001, - maxSize = 0.1, - growthRate = 0.5, - nbSegPerEdge = 0.5, - nbSegPerRadius = 0.5, - chordalErrorEnabled = False, - chordalError = -1, - secondOrder = False, - optimize = True, - quadAllowed = False, - useSurfaceCurvature = True, - fuseEdges = True, - checkChartBoundary = False - ) - facesToIgnore = [] for group in groups: if group.GetName() in ["inlet", "outlet"]: facesToIgnore.append(group) - viscousLayers = mesh_utils.ViscousLayers( - thickness = 0.001, - numberOfLayers = 3, - stretchFactor = 1.2, - isFacesToIgnore = True, - facesToIgnore = facesToIgnore, - extrusionMethod = mesh_utils.smeshBuilder.NODE_OFFSET - ) + viscousLayers.facesToIgnore = facesToIgnore + viscousLayers.extrusionMethod = mesh_utils.smeshBuilder.NODE_OFFSET mesh = mesh_utils.meshCreate(shape, groups, fineness, parameters, viscousLayers) mesh_utils.meshCompute(mesh) - mesh_utils.meshExport(mesh, saveto) + mesh_utils.meshExport(mesh, export) salome.salome_close() if __name__ == "__main__": - - logging.basicConfig( - level=logging.INFO, - format="%(levelname)s: %(message)s", - handlers = [ - logging.StreamHandler(), - logging.FileHandler("{}/cubic.log".format(LOG)) - ]) - - stype = str(sys.argv[1]) - theta = float(sys.argv[2]) - fillet = True if int(sys.argv[3]) == 1 else False - flowdirection = [int(coord) for coord in sys.argv[4]] - saveto = str(sys.argv[5]) - - genMesh(stype, theta, fillet, flowdirection, saveto) + main() + diff --git a/samples/bodyCentered.py b/samples/bodyCentered.py index bba7331..8679bcf 100644 --- a/samples/bodyCentered.py +++ b/samples/bodyCentered.py @@ -151,6 +151,7 @@ def bodyCenteredCubic(theta = 0.01, fillet = False, direction = [1, 0, 0]): return shape, groups + def bodyCenteredHexagonalPrism(theta = 0.01, fillet = False, direction = [1, 1, 1]): ### diff --git a/src/applogger.py b/src/applogger.py new file mode 100644 index 0000000..d33ce87 --- /dev/null +++ b/src/applogger.py @@ -0,0 +1,41 @@ +import logging +import config + +class Logger(): + def __init__(self): + logging.basicConfig( + level = logging.INFO, + format = "%(levelname)s: %(message)s", + handlers = [ + logging.StreamHandler(), + logging.FileHandler(f"{config.LOG}/anisotrope.log") + ] + ) + + self.logger = logging.getLogger("anisotrope") + self.warnings = 0 + self.errors = 0 + self.criticals = 0 + self.exceptions = 0 + + def info(self, *args): + self.logger.info(*args) + + def warning(self, *args): + self.warnings += 1 + self.logger.warning(*args) + + def error(self, *args): + self.errors += 1 + self.logger.error(*args) + + def critical(self, *args): + self.criticals += 1 + self.logger.critical(*args) + + def exception(self, *args): + self.exceptions += 1 + self.logger.exception(*args) + + def fanctline(self): + self.logger.info("-" * 80) diff --git a/src/foam_utils.py b/src/foam_utils.py index b87f319..8decb1d 100644 --- a/src/foam_utils.py +++ b/src/foam_utils.py @@ -4,6 +4,7 @@ import logging import time import re from datetime import timedelta +from config import logger def application(name: str, *args: str, case: str = None, stderr: bool = True, useMPI: bool = False) -> int: @@ -21,7 +22,7 @@ def application(name: str, *args: str, case: str = None, stderr: bool = True, us if args: cmd.extend([*args]) - logging.info("{}: {}".format(name, [*args])) + logger.info("{}: {}".format(name, [*args])) logpath = os.path.join(case if case else "", "{}.log".format(name)) with subprocess.Popen(cmd, @@ -40,16 +41,26 @@ def application(name: str, *args: str, case: str = None, stderr: bool = True, us logfile.write(err) if err and stderr: - logging.error("""{}: + logger.error("""{}: {}""".format(name, str(err, "utf-8"))) return out, p.returncode def foamVersion() -> str: - return "OpenFOAM-{}".format(os.environ["WM_PROJECT_VERSION"]) + +def foamClean(case: str = None): + rmDirs = ["0", "constant", "system", "postProcessing", "logs"] + rmDirs.extend([ "processor{}".format(n) for n in range(os.cpu_count()) ]) + path = case if case else "" + + for d in rmDirs: + if os.path.exists(os.path.join(path, d)): + shutil.rmtree(os.path.join(path, d)) + + def ideasUnvToFoam(mesh: str, case: str = None): application("ideasUnvToFoam", mesh, case = case, stderr = True) @@ -79,7 +90,7 @@ def checkMesh(case: str = None): warnings.append(line.replace("***", "").strip()) if warnings: - logging.warning("checkMesh:\n\t{}".format("\n\t".join(warnings))) + logger.warning("checkMesh:\n\t{}".format("\n\t".join(warnings))) def foamDictionary(filepath: str, entry: str, value: str = None, case: str = None): args = [filepath, "-entry", entry] @@ -89,13 +100,6 @@ def foamDictionary(filepath: str, entry: str, value: str = None, case: str = Non application("foamDictionary", *args, case = case, stderr = False) -#def foamDictionaryGet(case, foamFile, entry): -# application("foamDictionary", case, True, [foamFile, "-entry", entry]) - - -#def foamDictionarySet(case, foamFile, entry, value): -# application("foamDictionary", case, False, [foamFile, "-entry", entry, "-set", value]) - def decomposePar(case: str = None): application("decomposePar", case = case, stderr = True) @@ -115,6 +119,6 @@ def simpleFoam(case: str = None): with open("simpleFoam.log", "r") as io: for line in io: if re.search("solution converged", line): - logging.info("simpleFoam:\n\t{}".format(line)) + logger.info("simpleFoam:\n\t{}".format(line)) diff --git a/src/geometry_utils.py b/src/geometry_utils.py index ad28871..5486ada 100644 --- a/src/geometry_utils.py +++ b/src/geometry_utils.py @@ -11,19 +11,6 @@ import numpy as np def getGeom(): return geompy -#def rotate(gobj, ang): -# x = geompy.MakeVectorDXDYDZ(1, 0, 0) -# y = geompy.MakeVectorDXDYDZ(0, 1, 0) -# z = geompy.MakeVectorDXDYDZ(0, 0, 1) - - # yaw -# rotated = geompy.MakeRotation(gobj, z, ang[2]) - # pitch -# rotated = geompy.MakeRotation(rotated, y, ang[1]) - # roll -# rotated = geompy.MakeRotation(rotated, x, ang[0]) - -# return rotated def createGroup(gobj, planelist, grains, name): gr = geompy.CreateGroup(gobj, geompy.ShapeType["FACE"], name) @@ -39,19 +26,9 @@ def createGroup(gobj, planelist, grains, name): def createBoundary(gobj, bcount, dvec, norm, grains): - - #normvec = Quaternion(0, norm[0], norm[1], norm[2]).normalised - #ax = lambda alpha: Quaternion( - # np.cos(alpha * 0.5), - # np.sin(alpha * 0.5) * dvec[0], - # 0, 0).normalised - #np.sin(alpha * 0.5) * dvec[1], - #np.sin(alpha * 0.5) * dvec[2]).normalised - ang = lambda n, count: 2 * np.pi * n / count limit = bcount if np.mod(bcount, 2) else int(bcount / 2) - #vecs = [ ax(ang(n, bcount)) * normvec * ax(ang(n, bcount)).inverse for n in range(limit) ] vecs = [ Quaternion(axis = dvec, angle = ang(n, bcount)).rotate(norm) for n in range(limit) ] logging.info("""createBoundary: diff --git a/src/mesh_utils.py b/src/mesh_utils.py index ca23bff..2310648 100644 --- a/src/mesh_utils.py +++ b/src/mesh_utils.py @@ -2,33 +2,7 @@ import SMESH from salome.smesh import smeshBuilder smesh = smeshBuilder.New() -import logging -from collections import namedtuple - -Parameters = namedtuple("Parameters", [ - "minSize", - "maxSize", - "growthRate", - "nbSegPerEdge", - "nbSegPerRadius", - "chordalErrorEnabled", - "chordalError", - "secondOrder", - "optimize", - "quadAllowed", - "useSurfaceCurvature", - "fuseEdges", - "checkChartBoundary" -]) - -ViscousLayers = namedtuple("ViscousLayers", [ - "thickness", - "numberOfLayers", - "stretchFactor", - "isFacesToIgnore", - "facesToIgnore", - "extrusionMethod" -]) +from config import logger def getSmesh(): return smesh @@ -91,7 +65,7 @@ def meshCreate(shape, groups, fineness, parameters, viscousLayers = None): param.SetCheckChartBoundary(parameters.checkChartBoundary) - logging.info("""meshCreate: + logger.info("""meshCreate: fineness:\t{} min size:\t{} max size:\t{} @@ -129,7 +103,7 @@ def meshCreate(shape, groups, fineness, parameters, viscousLayers = None): viscousLayers.extrusionMethod ) - logging.info("""meshCreate: + logger.info("""meshCreate: viscous layers: thickness:\t{} number:\t{} @@ -141,7 +115,7 @@ def meshCreate(shape, groups, fineness, parameters, viscousLayers = None): else: - logging.info("""meshCreate: + logger.info("""meshCreate: viscous layers: disabled""") @@ -159,7 +133,7 @@ def meshCompute(mobj): #else: # msg = "Not computed" - #logging.info("""meshCompute: + #logger.info("""meshCompute: #status:\t{}""".format(msg)) if status: @@ -183,7 +157,7 @@ def meshCompute(mobj): elements = edges + faces + volumes - logging.info("""meshCompute: + logger.info("""meshCompute: Elements:\t{} Edges:\t{} Faces:\t{} @@ -195,7 +169,7 @@ def meshCompute(mobj): elements, edges, faces, triangles, volumes, tetra, prism, pyramid)) else: - logging.warning("meshCompute: not computed") + logger.warning("meshCompute: not computed") def meshExport(mobj, path): @@ -209,10 +183,10 @@ def meshExport(mobj, path): try: mobj.ExportUNV(path) - logging.info("""meshExport: + logger.info("""meshExport: format:\t{}""".format("unv")) except: - logging.error("""meshExport: Cannot export.""") + logger.error("""meshExport: Cannot export.""") diff --git a/src/salome_utils.py b/src/salome_utils.py index b909227..e460870 100644 --- a/src/salome_utils.py +++ b/src/salome_utils.py @@ -2,13 +2,15 @@ import subprocess import logging import sys +import config +from config import logger def hasDesktop() -> bool: return salome.sg.hasDesktop() def startServer(port): - logging.info("Starting SALOME on port {} ...".format(port)) + logger.info("Starting SALOME on port {} ...".format(port)) p = subprocess.Popen(["salome", "start", "--port", str(port), "-t"], #shell = False, @@ -25,7 +27,7 @@ def runExecute(port: int, scriptpath: str, *args) -> int: cmd = ["salome", "start", "--shutdown-servers=1", "--port", str(port), "-t", scriptpath, "args:{}".format(", ".join([str(arg) for arg in args]))] - logging.info("salome: {}".format(cmd[1 : 6])) + logger.info("salome: {}".format(cmd[1 : 6])) #logpath = os.path.join() #p = subprocess.Popen(["salome", "start", "--shutdown-servers=1", "--port", str(port), "-t", scriptpath, "args:{}".format(", ".join([str(arg) for arg in args]))], @@ -45,19 +47,19 @@ def runExecute(port: int, scriptpath: str, *args) -> int: #logfile.write(err) if err and p.returncode == 1: - logging.error("salome:\n\t{}".format(str(err, "utf-8"))) + logger.error("salome:\n\t{}".format(str(err, "utf-8"))) #if err: # if p.returncode == 1: - # logging.error(err) + # logger.error(err) # else: - # logging.warning(err) + # logger.warning(err) return p.returncode def killServer(port): - logging.info("Terminating SALOME on port {} ...".format(port)) + logger.info("Terminating SALOME on port {} ...".format(port)) p = subprocess.Popen(["salome", "kill", str(port)], #shell = True, @@ -68,7 +70,7 @@ def killServer(port): def remote(port, cmd): - logging.info("Executing command in the SALOME on port {} ...".format(port)) + 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)], @@ -78,4 +80,3 @@ def remote(port, cmd): return p - diff --git a/temp/samples.old.2/run.py b/temp/samples.old.2/run.py new file mode 100644 index 0000000..f9c85e6 --- /dev/null +++ b/temp/samples.old.2/run.py @@ -0,0 +1,234 @@ +import os, sys +from collections import namedtuple +import time +import logging +from datetime import timedelta +import multiprocessing +import shutil + +ROOT = os.getcwd() +sys.path.append(ROOT) + +LOG = os.path.join(ROOT, "logs") +BUILD = os.path.join(ROOT, "build") + +from src import utils +from src import salome_utils +from src import foam_utils + +def createTasks(): + ### + # Control variables + ## + structures = [ + "simple", + #"bodyCentered", + #"faceCentered" + ] + directions = [ + #[1, 0, 0], + [0, 0, 1], + #[1, 1, 1] + ] + fillet = 1 + + ### + # Tasks + ## + Task = namedtuple("Task", ["structure", "coeff", "fillet", "direction", "saveto"]) + tasks = [] + + for structure in structures: + if structure == "simple": + theta = [0.01] #[c * 0.01 for c in range(1, 28 + 1)] + #theta = [ 0.01, 0.28 ] + + elif structure == "faceCentered": + #theta = [c * 0.01 for c in range(1, 13 + 1)] + theta = [ 0.01, 0.13 ] + + elif structure == "bodyCentered": + #theta = [c * 0.01 for c in range(1, 18 + 1)] + theta = [ 0.01, 0.13, 0.14, 0.18 ] + + for coeff in theta: + for direction in directions: + saveto = os.path.join(BUILD, structure, "coeff-{}".format(coeff), + "direction-{}{}{}".format(direction[0], direction[1], direction[2])) + + if not os.path.exists(saveto): + os.makedirs(saveto) + + t = Task(structure, coeff, fillet, direction, saveto) + tasks.append(t) + + return tasks + + +def createMesh(tasks): + scriptpath = os.path.join(ROOT, "samples/__init__.py") + port = 2810 + errors = 0 + + for task in tasks: + logging.info("-" * 80) + logging.info("""createMesh: + task:\t{} / {}""".format(tasks.index(task) + 1, len(tasks))) + start_time = time.monotonic() + + returncode = salome_utils.runExecute(port, scriptpath, task.structure, task.coeff, task.fillet, "".join([str(coord) for coord in task.direction]), os.path.join(task.saveto, "mesh.unv")) + + end_time = time.monotonic() + logging.info("createMesh: elapsed time: {}".format(timedelta(seconds=end_time - start_time))) + logging.info("salome: return code:\t{}".format(returncode)) + + if returncode == 1: + #break + errors += 1 + pass + + return errors + + +def calculate(tasks): + foamCase = [ "0", "constant", "system" ] + rmDirs = ["0", "constant", "system", "postProcessing", "logs"] + [ "processor{}".format(n) for n in range(4)] + + for task in tasks: + + for d in rmDirs: + if os.path.exists(os.path.join(task.saveto, d)): + shutil.rmtree(os.path.join(task.saveto, d)) + + for d in foamCase: + if not os.path.exists(os.path.join(task.saveto, d)): + shutil.copytree(os.path.join(ROOT, "src/cubicFoam", d), + os.path.join(task.saveto, d)) + + os.chdir(task.saveto) + casepath = "." + + logging.info("-" * 80) + logging.info("""calculate: + task:\t{} / {} + structure type:\t{} + coefficient:\t{} + flow direction:\t{} + path:\t{}""".format( + tasks.index(task) + 1, + len(tasks) , + task.structure, + task.coeff, + task.direction, + task.saveto + )) + + foam_utils.ideasUnvToFoam("mesh.unv") + + foam_utils.createPatch(dictfile = "system/createPatchDict.symetry") + + foam_utils.checkMesh() + + scale = (1e-5, 1e-5, 1e-5) + foam_utils.transformPoints(scale) + + foam_utils.decomposePar() + + foam_utils.renumberMesh() + + foam_utils.potentialFoam() + + for n in range(4): + foam_utils.foamDictionary("processor{}/0/U".format(n), + "boundaryField.inlet.type", "pressureInletVelocity") + foam_utils.foamDictionary("processor{}/0/U".format(n), + "boundaryField.inlet.value", "uniform (0 0 0)") + + foam_utils.simpleFoam() + + os.chdir(ROOT) + + +def postprocessing(tasks): + + surfaceFieldValue = {} + porosity = {} + + for task in tasks: + direction = "direction-{}{}{}".format(task.direction[0], task.direction[1], task.direction[2]) + path = os.path.join(BUILD, task.structure, "postProcessing", direction) + surfaceFieldValuePath = os.path.join(task.saveto, "postProcessing", "") + + if not os.path.exists(path): + os.makedirs(path) + + surfaceFieldValues = [ line.strip().split() for line in open(surfaceFieldValuePath, "r").readlines() ] + + with open(os.path.join(path, "porosity.dat")) as io: + io.write("{}\t{}".format(task.coeff, surfaceFieldValues[-1][1])) + + +if __name__ == "__main__": + + if not os.path.exists(LOG): + os.makedirs(LOG) + + if not os.path.exists(BUILD): + os.makedirs(BUILD) + + logging.basicConfig( + level=logging.INFO, + format="%(levelname)s: %(message)s", + handlers = [ + logging.StreamHandler(), + logging.FileHandler("{}/cubic.log".format(LOG)) + ]) + + # TODO: add force arg + Args = namedtuple("Args", ["mesh", "calc", "pp"]) + + if len(sys.argv) > 1: + action = sys.argv[1] + + if action == "mesh": + args = Args(True, False, False) + + elif action == "calc": + args = Args(False, True, False) + + elif action == "pp": + args = Args(False, False, True) + + elif action == "all": + args = Args(True, True, True) + + else: + args = Args(True, True, True) + + tasks = createTasks() + logging.info("Tasks: {}".format(len(tasks))) + + if args.mesh: + start_time = time.monotonic() + #logging.info("Started at {}".format(timedelta(seconds=start_time))) + + errors = createMesh(tasks) + + end_time = time.monotonic() + logging.info("-" * 80) + logging.info("Elapsed time:\t{}".format(timedelta(seconds=end_time - start_time))) + logging.info("Errors:\t{}".format(errors)) + + if args.calc: + start_time = time.monotonic() + #logging.info("Started at {}".format(timedelta(seconds=start_time))) + + calculate(tasks) + + end_time = time.monotonic() + logging.info("-" * 80) + logging.info("Elapsed time: {}".format(timedelta(seconds=end_time - start_time))) + + if args.pp: + postprocessing(tasks) +