2021-12-09 13:59:32 +05:00

205 lines
5.8 KiB
Python

# -*- coding: utf-8 -*-
# This file is part of anisotropy.
# License: GNU GPL version 3, see the file "LICENSE" for details.
from datetime import datetime
from os import path
import logging
from anisotropy.core.config import DefaultConfig
from anisotropy.core.utils import parallel, ParallelRunner, setupLogger
from anisotropy.database import *
from anisotropy.shaping import Simple, BodyCentered, FaceCentered
from anisotropy.meshing import Mesh
from anisotropy.openfoam.presets import CreatePatchDict
from anisotropy.solving.onephase import OnePhaseFlow
logger = logging.getLogger("anisotropy")
setupLogger(logger, logging.INFO)
class UltimateRunner(object):
def __init__(self, config = None, exec_id = None, m_shape = None):
self.config = config or DefaultConfig()
if not m_shape:
self.database = Database(self.config["database"])
self.database.setup()
if not exec_id:
with self.database.database:
self.exec_id = Execution(date = datetime.now())
self.exec_id.save()
self.type = "master"
self.m_shape = None
else:
self.exec_id = exec_id
self.type = "worker"
self.m_shape = m_shape
self.shape = None
self.mesh = None
self.flow = None
self.queue = []
def fill(self):
self.config.expand()
for case in self.config.cases:
with self.database.database:
m_shape = Shape(
exec_id = self.exec_id,
**case
)
m_shape.save()
self.queue.append(UltimateRunner(
config = self.config,
exec_id = self.exec_id,
m_shape = m_shape
))
def start(self, queue: list = None, nprocs: int = None):
nprocs = nprocs or self.config["nprocs"]
parallel = ParallelRunner(nprocs = nprocs)
parallel.start()
for runner in self.queue:
parallel.append(runner.pipeline, args = [self.config["stage"]])
parallel.wait()
#parallel(nprocs, args, runners)
# TODO: if runner done - remove from queue; results from parallel function
def casepath(self):
with self.database.database:
params = Shape.get(
Shape.exec_id == self.exec_id,
Shape.shape_id == self.m_shape.shape_id
)
return path.abspath(path.join(
self.config["build"],
params.label,
"direction-[{},{},{}]".format(*[ str(d) for d in params.direction ]),
"theta-{}".format(params.theta)
))
def computeShape(self):
if not self.type == "worker":
return
self.database = Database(self.config["database"])
self.database.setup()
with self.database.database:
params = Shape.get(
Shape.exec_id == self.exec_id,
Shape.shape_id == self.m_shape.shape_id
)
filename = "shape.step"
logger.info([params.label, params.direction, params.theta])
self.shape = {
"simple": Simple,
"bodyCentered": BodyCentered,
"faceCentered": FaceCentered
}[params.label](params.direction)
self.shape.build()
os.makedirs(self.casepath(), exist_ok = True)
self.shape.export(path.join(self.casepath(), filename))
with self.database.database:
params.shapeStatus = "Done"
params.save()
def computeMesh(self):
params = self.config.cases[0]
filename = "mesh.mesh"
self.mesh = Mesh(self.shape.shape)
self.mesh.build()
os.makedirs(self.casepath(), exist_ok = True)
self.mesh.export(path.join(self.casepath(), filename))
def computeFlow(self):
params = self.config.cases[0]
flow = OnePhaseFlow(path = self.casepath())
# initial 43 unnamed patches ->
# 6 named patches (inlet, outlet, wall, symetry0 - 3/5) ->
# 4 inGroups (inlet, outlet, wall, symetry)
createPatchDict = CreatePatchDict()
createPatchDict["patches"] = []
patches = {}
for n, patch in enumerate(self.shape.shape.faces):
# shifted index
n += 1
name = patch.name
if patches.get(name):
patches[name].append(f"patch{ n }")
else:
patches[name] = [ f"patch{ n }" ]
for name in patches.keys():
if name == "inlet":
patchGroup = "inlet"
patchType = "patch"
elif name == "outlet":
patchGroup = "outlet"
patchType = "patch"
elif name == "wall":
patchGroup = "wall"
patchType = "wall"
else:
patchGroup = "symetry"
patchType = "symetryPlane"
createPatchDict["patches"].append({
"name": name,
"patchInfo": {
"type": patchType,
"inGroups": [patchGroup]
},
"constructFrom": "patches",
"patches": patches[name]
})
flow.append(createPatchDict)
flow.write()
# Build a flow
#flow.build()
def pipeline(self, stage: str = None):
stage = stage or self.config["stage"]
if stage in ["shape", "all"]:
self.computeShape()
elif stage in ["mesh", "all"]:
self.computeMesh()
elif stage in ["flow", "all"]:
self.computeFlow()
elif stage in ["postProcess", "all"]:
self.postProcess()