From 13e02b57a4d2eb7e1720cc538a687a80c780314e Mon Sep 17 00:00:00 2001 From: L-Nafaryus Date: Sat, 12 Feb 2022 01:10:15 +0500 Subject: [PATCH] Fix: shape primitives Mod: default config --- anisotropy/cli/cli.py | 20 ++++--- anisotropy/core/config.py | 69 ++++++++++++----------- anisotropy/core/runner.py | 88 ++++++++++++++++++++++-------- anisotropy/gui/layouts/settings.py | 8 +-- anisotropy/meshing/mesh.py | 2 +- anisotropy/shaping/primitives.py | 42 ++++++++------ anisotropy/shaping/shape.py | 1 - 7 files changed, 141 insertions(+), 89 deletions(-) diff --git a/anisotropy/cli/cli.py b/anisotropy/cli/cli.py index 3461d8c..e2342ab 100644 --- a/anisotropy/cli/cli.py +++ b/anisotropy/cli/cli.py @@ -28,17 +28,17 @@ def anisotropy_cli(): help = "Increase verbose level" ) def init(path, verbose): - from anisotropy.core import config + from anisotropy.core import config as core_config from anisotropy.core import utils as core_utils core_utils.setupLogger(utils.verbose_level(verbose)) logger = logging.getLogger(__name__) - conf = config.DefaultConfig() + config = config.default_config() filepath = os.path.abspath(os.path.join(path, "anisotropy.toml")) logger.info(f"Saving file at { filepath }") - conf.dump(filepath) + config.dump(filepath) @anisotropy_cli.command() @@ -109,7 +109,7 @@ def compute(path, configFile, nprocs, stage, overwrite, params, verbose, executi core_utils.setupLogger(utils.verbose_level(verbose), logfile) logger = logging.getLogger(__name__) - config = core_config.DefaultConfig() + config = core_config.default_config() if configFile: configFile = pathlib.Path(configFile).resolve() @@ -164,16 +164,18 @@ def compute(path, configFile, nprocs, stage, overwrite, params, verbose, executi ) def gui(path, verbose): import anisotropy - from anisotropy.core import core_utils + from anisotropy.core import utils as core_utils from anisotropy.gui import app anisotropy.loadEnv() - os.makedirs(os.path.abspath(path), exist_ok = True) - os.chdir(os.path.abspath(path)) - os.environ["ANISOTROPY_CWD"] = path + path = pathlib.Path(path).resolve() + path.mkdir(parents = True, exist_ok = True) + + os.chdir(path) + os.environ["ANISOTROPY_CWD"] = str(path) - core_utils.setupLogger(utils.verboseLevel(verbose)) + core_utils.setupLogger(utils.verbose_level(verbose)) # logger = logging.getLogger(__name__) app.run_server(debug = True) diff --git a/anisotropy/core/config.py b/anisotropy/core/config.py index 899a828..82e1a23 100644 --- a/anisotropy/core/config.py +++ b/anisotropy/core/config.py @@ -100,40 +100,43 @@ class Config(object): raise IndexError("list index out of range in cause of zero length of 'cases'") -class DefaultConfig(Config): - def __init__(self): - Config.__init__(self) +def default_config() -> Config: + config = Config() - self.options = { - "nprocs": 1, - "stage": "all", - "overwrite": False, - "database": "anisotropy.db", - "build": "build", - "logs": "logs" - } + config.options = { + "nprocs": 1, + "stage": "all", + "overwrite": False, + "database": "anisotropy.db", + "build": "build", + "logs": "logs", + "shapefile": "shape.step", + "meshfile": "mesh.mesh" + } - self.content = { - "structures": [] - } + config.content = { + "structures": [] + } - labels = ["simple", "bodyCentered", "faceCentered"] - alphas = [[0.01, 0.28], [0.01, 0.17], [0.01, 0.13]] + labels = ["simple", "bodyCentered", "faceCentered"] + alphas = [[0.01, 0.28], [0.01, 0.17], [0.01, 0.13]] - for label, alpha in zip(labels, alphas): - self.content["structures"].append({ - "label": label, - "alpha": alpha, - "alphaStep": 0.01, - "directions": [[1., 0., 0.], [0., 0., 1.], [1., 1., 1.]], - "r0": 1, - "filletsEnabled": True, - "pressureInlet": 1, - "pressureOutlet": 0, - "pressureInternal": 0, - "velocityInlet": [0., 0., 0.], - "velocityOutlet": None, - "velocityInternal": [0., 0., 0.], - "density": 1000, - "viscosity": 1e-3 - }) + for label, alpha in zip(labels, alphas): + config.content["structures"].append({ + "label": label, + "alpha": alpha, + "alphaStep": 0.01, + "directions": [[1., 0., 0.], [0., 0., 1.], [1., 1., 1.]], + "r0": 1, + "filletsEnabled": True, + "pressureInlet": 1, + "pressureOutlet": 0, + "pressureInternal": 0, + "velocityInlet": [0., 0., 0.], + "velocityOutlet": None, + "velocityInternal": [0., 0., 0.], + "density": 1000, + "viscosity": 1e-3 + }) + + return config diff --git a/anisotropy/core/runner.py b/anisotropy/core/runner.py index 33919a8..4c06280 100644 --- a/anisotropy/core/runner.py +++ b/anisotropy/core/runner.py @@ -22,26 +22,31 @@ logger = logging.getLogger(__name__) class UltimateRunner(object): - def __init__(self, config = None, exec_id: int = None, typo: str = "master"): + def __init__(self, config = None, exec_id: int = None, _type: str = "master"): + + self.type = _type # Configuration file - self.config = config or core_config.DefaultConfig() + self.config = config or core_config.default_config() # Database preparation self.database = Database(self.config["database"]) self.exec_id = None - if exec_id: + if exec_id is not None: if self.database.getExecution(exec_id): self.exec_id = exec_id else: logger.warning(f"Execution id '{ exec_id }' not found. Creating new.") - if not self.exec_id: + if self.exec_id is None: with self.database: self.exec_id = tables.Execution.create(date = datetime.now()) + if self.type == "master": + logger.info(f"Current execution id: { self.exec_id }") + # Parameters self.queue = [] @@ -112,6 +117,14 @@ class UltimateRunner(object): return path.resolve() + @property + def shapefile(self) -> PathLike: + return self.casepath / self.config["shapefile"] + + @property + def meshfile(self) -> PathLike: + return self.casepath / self.config["meshfile"] + def compute_shape(self): params = self.config.params shapeParams = self.database.getShape( @@ -124,17 +137,18 @@ class UltimateRunner(object): logger.info("Computing shape for {} with direction = {} and alpha = {}".format( params["label"], params["direction"], params["alpha"] )) - shapefile = self.casepath / "shape.step" timer = utils.Timer() + # check if ( - shapefile.exists() and + self.shapefile.exists() and shapeParams.shapeStatus == "done" and not self.config["overwrite"] ): logger.info("Shape exists. Skipping ...") return + # generate_shape = { "simple": shaping.primitives.simple, "bodyCentered": shaping.primitives.body_centered, @@ -153,7 +167,7 @@ class UltimateRunner(object): # export self.casepath.mkdir(parents = True, exist_ok = True) - shape.write(shapefile) + shape.write(self.shapefile) except Exception as e: logger.error(e, exc_info = True) @@ -182,24 +196,27 @@ class UltimateRunner(object): logger.info("Computing mesh for {} with direction = {} and alpha = {}".format( params["label"], params["direction"], params["alpha"] )) - meshfile = self.casepath / "mesh.mesh" timer = utils.Timer() + # check if ( - meshfile.exists() and + self.meshfile.exists() and meshParams.meshStatus == "done" and not self.config["overwrite"] ): logger.info("Mesh exists. Skipping ...") return + + elif not self.shapefile.exists(): + logger.error("Cannot find shape file to build a mesh.") + return # Shape shape = None try: # load shape - shapefile = self.casepath / "shape.step" - shape = shaping.Shape().read(shapefile) + shape = shaping.Shape().read(self.shapefile) # generate mesh parameters = meshing.MeshingParameters() @@ -209,7 +226,7 @@ class UltimateRunner(object): # export self.casepath.mkdir(parents = True, exist_ok = True) - mesh.write(meshfile) + mesh.write(self.meshfile) mesh.write(self.casepath / "mesh.msh") except Exception as e: @@ -240,6 +257,19 @@ class UltimateRunner(object): params["label"], params["direction"], params["alpha"] )) timer = utils.Timer() + + # check + if flowParams.flowStatus == "done" and not self.config["overwrite"]: + logger.info("Solution exists. Skipping ...") + return + + elif not self.shapefile.exists(): + logger.error("Cannot find shape file to compute a solution.") + return + + elif not self.meshfile.exists(): + logger.error("Cannot find mesh file to compute a solution.") + return # precalculate some parameters flowParams.viscosityKinematic = flowParams.viscosity / flowParams.density @@ -250,8 +280,7 @@ class UltimateRunner(object): try: # load shape - shapefile = self.casepath / "shape.step" - shape = shaping.Shape().read(shapefile) + shape = shaping.Shape().read(self.shapefile) # flow = solving.FlowOnePhase( @@ -296,21 +325,34 @@ class UltimateRunner(object): def pipeline(self, stage: str = None): stage = stage or self.config["stage"] + stages = ["shape", "mesh", "flow", "postProcess", "all"] - if stage in ["shape", "all"]: - self.compute_shape() + if stage not in stages: + logger.error(f"Unknown stage '{ stage }'.") + return + + for current in stages: + if current == "shape": + self.compute_shape() - if stage in ["mesh", "all"]: - self.compute_mesh() + if current == "mesh": + self.compute_mesh() - if stage in ["flow", "all"]: - self.compute_flow() + if current == "flow": + self.compute_flow() - if stage in ["postProcess", "all"]: - self.compute_postprocess() + if current == "postProcess": + self.compute_postprocess() + + if current == stage or current == "all": + break @staticmethod def subrunner(*args, **kwargs): - runner = UltimateRunner(config = kwargs["config"], exec_id = kwargs["exec_id"]) + runner = UltimateRunner( + config = kwargs["config"], + exec_id = kwargs["exec_id"], + _type = "worker" + ) runner.prepare_database() runner.pipeline() diff --git a/anisotropy/gui/layouts/settings.py b/anisotropy/gui/layouts/settings.py index dad9fc4..a41f4b8 100644 --- a/anisotropy/gui/layouts/settings.py +++ b/anisotropy/gui/layouts/settings.py @@ -90,11 +90,11 @@ def generalSave(clicks, cwd): [ Input("url", "pathname") ] ) def settingsLoad(pathname): - from anisotropy.core.config import DefaultConfig + from anisotropy.core import config as core_config import toml filepath = os.path.join(os.environ["ANISOTROPY_CWD"], os.environ["ANISOTROPY_CONF_FILE"]) - config = DefaultConfig() + config = core_config.default_config() if os.path.exists(filepath): config.load(filepath) @@ -115,11 +115,11 @@ def settingsLoad(pathname): prevent_initial_call = True ) def settingsSave(nclick, nprocs, stage, cases): - from anisotropy.core.config import DefaultConfig + from anisotropy.core import config as core_config import toml filepath = os.path.join(os.environ["ANISOTROPY_CWD"], os.environ["ANISOTROPY_CONF_FILE"]) - config = DefaultConfig() + config = core_config.default_config() if os.path.exists(filepath): config.load(filepath) diff --git a/anisotropy/meshing/mesh.py b/anisotropy/meshing/mesh.py index 7aad571..4502456 100644 --- a/anisotropy/meshing/mesh.py +++ b/anisotropy/meshing/mesh.py @@ -45,7 +45,7 @@ class MeshingParameters: """ self.__dict__.update(kwargs) - self.maxh = kwargs.get("maxh", 0.2) + self.maxh = kwargs.get("maxh", 0.1) self.curvaturesafety = kwargs.get("curvaturesafety", [1, 1.5, 2, 3, 5][key]) self.segmentsperedge = kwargs.get("segmentsperedge", [0.3, 0.5, 1, 2, 3][key]) self.grading = kwargs.get("grading", [0.7, 0.5, 0.3, 0.2, 0.1][key]) diff --git a/anisotropy/shaping/primitives.py b/anisotropy/shaping/primitives.py index bac3381..d338c40 100644 --- a/anisotropy/shaping/primitives.py +++ b/anisotropy/shaping/primitives.py @@ -53,13 +53,15 @@ def simple(alpha: float, direction: list | ndarray, **kwargs) -> Periodic: spheres.append(ng_occ.Sphere(ng_occ.Pnt(x, y, z), pc.radius)) - lattice = np.sum(spheres) - lattice = lattice.Scale(zero, pc.maximize) + pc.lattice = np.sum(spheres) if pc.filletsEnabled: - lattice = lattice.MakeFillet(lattice.edges, pc.fillets * pc.maximize) - - pc.lattice = lattice.Scale(zero, pc.minimize) + pc.lattice = pc.lattice.Scale(zero, pc.maximize) + pc.lattice = ( + pc.lattice + .MakeFillet(pc.lattice.edges, pc.fillets * pc.maximize) + .Scale(zero, pc.minimize) + ) # Inlet face if np.all(pc.direction == [1., 0., 0.]): @@ -210,13 +212,15 @@ def body_centered(alpha: float, direction: list | ndarray, **kwargs) -> Periodic # shifted spheres.append(ng_occ.Sphere(ng_occ.Pnt(x2, y2, z2), pc.radius)) - lattice = np.sum(spheres) - lattice = lattice.Scale(zero, pc.maximize) + pc.lattice = np.sum(spheres) if pc.filletsEnabled: - lattice = lattice.MakeFillet(lattice.edges, pc.fillets * pc.maximize) - - pc.lattice = lattice.Scale(zero, pc.minimize) + pc.lattice = pc.lattice.Scale(zero, pc.maximize) + pc.lattice = ( + pc.lattice + .MakeFillet(pc.lattice.edges, pc.fillets * pc.maximize) + .Scale(zero, pc.minimize) + ) # Inlet face if np.all(pc.direction == [1., 0., 0.]): @@ -341,7 +345,7 @@ def face_centered(alpha: float, direction: list | ndarray, **kwargs) -> Periodic # additional parameters pc.__dict__.update(kwargs) - pc.L = 4 / np.sqrt(2) * pc.r0 + pc.L = pc.r0 * 4 / np.sqrt(2) pc.direction = np.asarray(direction) # additional attributes @@ -383,17 +387,19 @@ def face_centered(alpha: float, direction: list | ndarray, **kwargs) -> Periodic .Rotate(ng_occ.Axis(ng_occ.Pnt(x2, y2, z2), ng_occ.Z), 45) ) - lattice = np.sum(spheres) - lattice = ( - lattice.Move(ng_occ.Vec(-pc.r0 * 2, -pc.r0 * 2, 0)) + pc.lattice = ( + np.sum(spheres) + .Move(ng_occ.Vec(-pc.r0 * 2, -pc.r0 * 2, 0)) .Rotate(ng_occ.Axis(zero, ng_occ.Z), 45) ) - lattice = lattice.Scale(zero, pc.maximize) if pc.filletsEnabled: - lattice = lattice.MakeFillet(lattice.edges, pc.fillets * pc.maximize) - - pc.lattice = lattice.Scale(zero, pc.minimize) + pc.lattice = pc.lattice.Scale(zero, pc.maximize) + pc.lattice = ( + pc.lattice + .MakeFillet(pc.lattice.edges, pc.fillets * pc.maximize) + .Scale(zero, pc.minimize) + ) # Inlet face if np.all(pc.direction == [1., 0., 0.]): diff --git a/anisotropy/shaping/shape.py b/anisotropy/shaping/shape.py index 346c47b..1b58fc5 100644 --- a/anisotropy/shaping/shape.py +++ b/anisotropy/shaping/shape.py @@ -15,7 +15,6 @@ class Shape(object): def __init__(self): """A Shape object contains OCC shape. """ - self.groups = {} self.shape = None @property