Massive improvement
New: few control args Mod: struct to dict conversion New: configuration for flow Fix: missed logs from openfoam package (checkMesh, etc)
This commit is contained in:
parent
2532e20c53
commit
3d4e7abb66
@ -10,7 +10,26 @@ from utils import struct
|
||||
import toml
|
||||
import logging
|
||||
|
||||
CONFIG = os.path.join(ROOT, "conf/config.toml")
|
||||
###
|
||||
# Shell args
|
||||
##
|
||||
configPath = "conf/config.toml"
|
||||
mode = "safe"
|
||||
|
||||
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"
|
||||
|
||||
elif arg == "-a" or arg == "--all":
|
||||
mode = "all"
|
||||
|
||||
###
|
||||
# Load configuration and tools
|
||||
##
|
||||
CONFIG = os.path.join(ROOT, configPath)
|
||||
config = struct(toml.load(CONFIG))
|
||||
|
||||
LOG = os.path.join(ROOT, "logs")
|
||||
@ -31,26 +50,38 @@ logging.basicConfig(
|
||||
)
|
||||
logger = logging.getLogger(config.logger.name)
|
||||
|
||||
|
||||
###
|
||||
# Main
|
||||
##
|
||||
def main():
|
||||
if checkEnv():
|
||||
return
|
||||
|
||||
tasks = createTasks()
|
||||
logger.info(f"args:\n\tconfig:\t{ configPath }\n\tmode:\t{ mode }")
|
||||
|
||||
for n, case in enumerate(tasks):
|
||||
queue = createQueue()
|
||||
|
||||
for n, case in enumerate(queue):
|
||||
logger.info("-" * 80)
|
||||
logger.info(f"""main:
|
||||
task:\t{ n + 1 } / { len(tasks) }
|
||||
task:\t{ n + 1 } / { len(queue) }
|
||||
cpu count:\t{ os.cpu_count() }
|
||||
case:\t{ case }""")
|
||||
|
||||
###
|
||||
# Compute mesh
|
||||
##
|
||||
taskPath = os.path.join(case, "task.toml")
|
||||
|
||||
task = struct(toml.load(taskPath))
|
||||
|
||||
if not task.status.mesh or mode == "all":
|
||||
computeMesh(case)
|
||||
|
||||
task = struct(toml.load(os.path.join(case, "task.toml")))
|
||||
else:
|
||||
logger.info("computeMesh: mesh already computed")
|
||||
|
||||
task = struct(toml.load(taskPath))
|
||||
|
||||
if not task.status.mesh:
|
||||
logger.critical("mesh not computed: Skipping flow computation")
|
||||
@ -59,30 +90,41 @@ def main():
|
||||
###
|
||||
# Compute flow
|
||||
##
|
||||
|
||||
if not task.status.flow or mode == "all":
|
||||
computeFlow(case)
|
||||
|
||||
else:
|
||||
logger.info("computeFlow: flow already computed")
|
||||
|
||||
def createTasks():
|
||||
tasks = []
|
||||
|
||||
for structure in config.base.__dict__.keys():
|
||||
def createQueue():
|
||||
queue = []
|
||||
|
||||
###
|
||||
# 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) ]
|
||||
parameters_theta = {}
|
||||
mesh_thickness = {}
|
||||
|
||||
for structure in config.base.__dict__.keys():
|
||||
|
||||
theta = getattr(config, structure).parameters.theta
|
||||
parameters_theta[structure] = [ 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(parameters_theta[structure])
|
||||
mesh_thickness[structure] = [ thickness[0] + n * (thickness[1] - thickness[0]) / (count - 1) for n in range(0, count) ]
|
||||
|
||||
_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
|
||||
# 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 n, theta in enumerate(getattr(config, structure).parameters.theta):
|
||||
for n, theta in enumerate(parameters_theta[structure]):
|
||||
# create dirs for case path
|
||||
case = os.path.join(
|
||||
f"{ BUILD }",
|
||||
f"{ structure }",
|
||||
@ -90,16 +132,27 @@ def createTasks():
|
||||
f"theta-{ theta }"
|
||||
)
|
||||
|
||||
taskPath = os.path.join(case, "task.toml")
|
||||
|
||||
if os.path.exists(taskPath) and mode == "safe":
|
||||
queue.append(case)
|
||||
continue
|
||||
|
||||
if not os.path.exists(case):
|
||||
os.makedirs(case)
|
||||
|
||||
# prepare configuration for task
|
||||
task = {
|
||||
"logger": config.logger.__dict__,
|
||||
"logger": dict(config.logger),
|
||||
"structure": structure,
|
||||
"status": {
|
||||
"mesh": False,
|
||||
"flow": False
|
||||
},
|
||||
"statistics": {
|
||||
"meshTime": 0,
|
||||
"flowTime": 0
|
||||
},
|
||||
"parameters": {
|
||||
"theta": theta
|
||||
},
|
||||
@ -107,18 +160,21 @@ def createTasks():
|
||||
"direction": direction,
|
||||
"fillet": getattr(config, structure).geometry.fillet
|
||||
},
|
||||
"mesh": getattr(config, structure).mesh.__dict__
|
||||
"mesh": dict(getattr(config, structure).mesh),
|
||||
"flow": dict(config.flow)
|
||||
}
|
||||
|
||||
#task["mesh"]["thickness"] = task["mesh"]["thickness"][int(n)]
|
||||
# reassign special values
|
||||
task["mesh"]["thickness"] = mesh_thickness[structure][n]
|
||||
|
||||
##
|
||||
with open(os.path.join(case, "task.toml"), "w") as io:
|
||||
toml.dump(task, io)
|
||||
|
||||
##
|
||||
queue.append(case)
|
||||
|
||||
tasks.append(case)
|
||||
|
||||
return tasks
|
||||
return queue
|
||||
|
||||
|
||||
from salomepl.utils import runExecute, salomeVersion
|
||||
@ -130,13 +186,24 @@ def computeMesh(case):
|
||||
|
||||
returncode = runExecute(port, scriptpath, ROOT, case)
|
||||
|
||||
etime = time.monotonic()
|
||||
logger.info("computeMesh: elapsed time: {}".format(timedelta(seconds = etime - stime)))
|
||||
task = struct(toml.load(os.path.join(case, "task.toml")))
|
||||
elapsed = time.monotonic() - stime
|
||||
logger.info("computeMesh: elapsed time: {}".format(timedelta(seconds = elapsed)))
|
||||
|
||||
if returncode == 0:
|
||||
task.statistics.meshTime = elapsed
|
||||
|
||||
with open(os.path.join(case, "task.toml"), "w") as io:
|
||||
toml.dump(dict(task), io)
|
||||
|
||||
|
||||
|
||||
import openfoam
|
||||
|
||||
def computeFlow(case):
|
||||
###
|
||||
# Case preparation
|
||||
##
|
||||
foamCase = [ "0", "constant", "system" ]
|
||||
|
||||
os.chdir(case)
|
||||
@ -151,6 +218,9 @@ def computeFlow(case):
|
||||
|
||||
stime = time.monotonic()
|
||||
|
||||
###
|
||||
# Mesh manipulations
|
||||
##
|
||||
if not os.path.exists("mesh.unv"):
|
||||
logger.critical(f"computeFlow: missed 'mesh.unv'")
|
||||
return
|
||||
@ -164,48 +234,104 @@ def computeFlow(case):
|
||||
|
||||
openfoam.createPatch(dictfile = "system/createPatchDict.symetry")
|
||||
|
||||
openfoam.foamDictionary("constant/polyMesh/boundary", "entry0.defaultFaces.type", "wall")
|
||||
openfoam.foamDictionary("constant/polyMesh/boundary", "entry0.defaultFaces.inGroups", "1 (wall)")
|
||||
openfoam.foamDictionary(
|
||||
"constant/polyMesh/boundary",
|
||||
"entry0.defaultFaces.type",
|
||||
"wall"
|
||||
)
|
||||
openfoam.foamDictionary(
|
||||
"constant/polyMesh/boundary",
|
||||
"entry0.defaultFaces.inGroups",
|
||||
"1 (wall)"
|
||||
)
|
||||
|
||||
openfoam.checkMesh()
|
||||
out = openfoam.checkMesh()
|
||||
|
||||
scale = (1e-5, 1e-5, 1e-5)
|
||||
openfoam.transformPoints(scale)
|
||||
if out:
|
||||
logger.info(out)
|
||||
|
||||
openfoam.transformPoints(task.flow.scale)
|
||||
|
||||
###
|
||||
# Decomposition and initial approximation
|
||||
##
|
||||
openfoam.foamDictionary(
|
||||
"constant/transportProperties",
|
||||
"nu",
|
||||
str(task.flow.constant.nu)
|
||||
)
|
||||
|
||||
openfoam.decomposePar()
|
||||
|
||||
openfoam.renumberMesh()
|
||||
|
||||
pressureBF = task.flow.approx.pressure.boundaryField
|
||||
velocityBF = task.flow.approx.velocity.boundaryField
|
||||
direction = {
|
||||
"[1, 0, 0]": 0,
|
||||
"[0, 0, 1]": 1,
|
||||
"[1, 1, 1]": 2
|
||||
}[str(task.geometry.direction)]
|
||||
|
||||
openfoam.foamDictionary(
|
||||
"0/p",
|
||||
"boundaryField.inlet.value",
|
||||
openfoam.uniform(pressureBF.inlet.value)
|
||||
)
|
||||
openfoam.foamDictionary(
|
||||
"0/p",
|
||||
"boundaryField.outlet.value",
|
||||
openfoam.uniform(pressureBF.outlet.value)
|
||||
)
|
||||
|
||||
openfoam.foamDictionary(
|
||||
"0/U",
|
||||
"boundaryField.inlet.value",
|
||||
openfoam.uniform(velocityBF.inlet.value[direction])
|
||||
)
|
||||
|
||||
openfoam.potentialFoam()
|
||||
|
||||
###
|
||||
# Main computation
|
||||
##
|
||||
pressureBF = task.flow.main.pressure.boundaryField
|
||||
velocityBF = task.flow.main.velocity.boundaryField
|
||||
|
||||
for n in range(os.cpu_count()):
|
||||
openfoam.foamDictionary(f"processor{n}/0/U", "boundaryField.inlet.type", "pressureInletVelocity")
|
||||
openfoam.foamDictionary(f"processor{n}/0/U", "boundaryField.inlet.value", "uniform (0 0 0)")
|
||||
openfoam.foamDictionary(
|
||||
f"processor{n}/0/U",
|
||||
"boundaryField.inlet.type",
|
||||
velocityBF.inlet.type
|
||||
)
|
||||
openfoam.foamDictionary(
|
||||
f"processor{n}/0/U",
|
||||
"boundaryField.inlet.value",
|
||||
openfoam.uniform(velocityBF.inlet.value[direction])
|
||||
)
|
||||
|
||||
returncode, out = openfoam.simpleFoam()
|
||||
if out:
|
||||
logger.info(out)
|
||||
|
||||
###
|
||||
# Check results
|
||||
##
|
||||
elapsed = time.monotonic() - stime
|
||||
logger.info("computeFlow: elapsed time: {}".format(timedelta(seconds = elapsed)))
|
||||
|
||||
if returncode == 0:
|
||||
task.status.flow = True
|
||||
task.statistics.flowTime = elapsed
|
||||
|
||||
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)
|
||||
toml.dump(dict(task), io)
|
||||
|
||||
os.chdir(ROOT)
|
||||
|
||||
etime = time.monotonic()
|
||||
logger.info("computeFlow: elapsed time: {}".format(timedelta(seconds = etime - stime)))
|
||||
|
||||
return returncode
|
||||
|
||||
|
||||
def checkEnv():
|
||||
missed = False
|
||||
|
||||
|
@ -11,11 +11,19 @@ class struct:
|
||||
for (k, v) in args[0].items():
|
||||
if type(v) == dict:
|
||||
setattr(self, k, struct(v))
|
||||
|
||||
else:
|
||||
setattr(self, k, v)
|
||||
else:
|
||||
for (k, v) in kwargs.items():
|
||||
setattr(self, k, v)
|
||||
self.__dict__.update(kwargs)
|
||||
|
||||
def __iter__(self):
|
||||
for k in self.__dict__:
|
||||
if type(getattr(self, k)) == struct:
|
||||
yield k, dict(getattr(self, k))
|
||||
|
||||
else:
|
||||
yield k, getattr(self, k)
|
||||
|
||||
def __str__(self):
|
||||
members = []
|
||||
|
@ -15,6 +15,8 @@ anisotropy-help()
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " -c, --config <path-to-file> Use custom configuration file."
|
||||
echo " -s, --safe Safe mode (skip successfuly computed mesh/flow)"
|
||||
echo " -a, --all All mode (overwrites everything)"
|
||||
}
|
||||
|
||||
case $1 in
|
||||
@ -33,7 +35,7 @@ case $1 in
|
||||
run)
|
||||
source ${OPENFOAM}
|
||||
source env/bin/activate
|
||||
python ${DIR}/anisotropy/anisotropy.py
|
||||
python ${DIR}/anisotropy/anisotropy.py ${@:2}
|
||||
deactivate
|
||||
;;
|
||||
|
||||
|
@ -43,7 +43,7 @@ useSurfaceCurvature = true
|
||||
fuseEdges = true
|
||||
checkChartBoundary = false
|
||||
|
||||
thickness = [0.005, 0.005]
|
||||
thickness = [0.01, 0.005]
|
||||
numberOfLayers = 2
|
||||
stretchFactor = 1.2
|
||||
isFacesToIgnore = true
|
||||
@ -78,7 +78,7 @@ useSurfaceCurvature = true
|
||||
fuseEdges = true
|
||||
checkChartBoundary = false
|
||||
|
||||
thickness = [0.005, 0.005]
|
||||
thickness = [0.005, 0.001]
|
||||
numberOfLayers = 2
|
||||
stretchFactor = 1.2
|
||||
isFacesToIgnore = true
|
||||
@ -113,8 +113,50 @@ useSurfaceCurvature = true
|
||||
fuseEdges = true
|
||||
checkChartBoundary = false
|
||||
|
||||
thickness = [0.001, 0.001]
|
||||
thickness = [0.001, 0.0005]
|
||||
numberOfLayers = 2
|
||||
stretchFactor = 1.2
|
||||
isFacesToIgnore = true
|
||||
|
||||
###
|
||||
# Flow
|
||||
##
|
||||
[flow]
|
||||
scale = [1e-5, 1e-5, 1e-5]
|
||||
|
||||
[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"
|
||||
|
||||
|
||||
|
@ -4,7 +4,7 @@ from .meshManipulation import createPatch, transformPoints, checkMesh, renumberM
|
||||
from .miscellaneous import foamDictionary
|
||||
from .parallelProcessing import decomposePar
|
||||
from .solvers import potentialFoam, simpleFoam
|
||||
from .utils import foamVersion, foamClean
|
||||
from .utils import foamVersion, foamClean, uniform
|
||||
|
||||
__all__ = [
|
||||
# meshConversion
|
||||
@ -28,5 +28,6 @@ __all__ = [
|
||||
|
||||
# utils
|
||||
"foamVersion",
|
||||
"foamClean"
|
||||
"foamClean",
|
||||
"uniform"
|
||||
]
|
||||
|
@ -11,13 +11,13 @@ def createPatch(dictfile: str = None, case: str = None):
|
||||
application("createPatch", *args, case = case, stderr = True)
|
||||
|
||||
|
||||
def transformPoints(scale: tuple, case: str = None):
|
||||
scale_ = "{}".format(scale).replace(",", "")
|
||||
def transformPoints(scale, case: str = None):
|
||||
_scale = f"({ scale[0] } { scale[1] } { scale[2] })"
|
||||
|
||||
application("transformPoints", "-scale", scale_, case = case, stderr = True)
|
||||
application("transformPoints", "-scale", _scale, case = case, stderr = True)
|
||||
|
||||
|
||||
def checkMesh(case: str = None):
|
||||
def checkMesh(case: str = None) -> str:
|
||||
application("checkMesh", "-allGeometry", "-allTopology", case = case, stderr = True)
|
||||
out = ""
|
||||
|
||||
|
@ -14,3 +14,13 @@ def foamClean(case: str = None):
|
||||
if os.path.exists(os.path.join(path, d)):
|
||||
shutil.rmtree(os.path.join(path, d))
|
||||
|
||||
|
||||
def uniform(value) -> str:
|
||||
if type(value) == list or type(value) == tuple:
|
||||
return f"uniform ({ value[0] } { value[1] } { value[2] })"
|
||||
|
||||
elif type(value) == int or type(value) == float:
|
||||
return f"uniform { value }"
|
||||
|
||||
else:
|
||||
return ""
|
||||
|
@ -87,14 +87,7 @@ def genmesh():
|
||||
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)
|
||||
toml.dump(dict(config), io)
|
||||
|
||||
meshStats(mesh)
|
||||
meshExport(mesh, os.path.join(CASE, "mesh.unv"))
|
||||
|
@ -28,7 +28,8 @@ 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[0].split("/")[:-1]), "salome.log")
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user