Mod: flow computation
This commit is contained in:
parent
6abbce9eb7
commit
9b023313b6
@ -82,7 +82,7 @@ faceCentered = true
|
||||
approx.pressure.boundaryField.inlet = { type = "fixedValue", value = 1e-3 }
|
||||
approx.pressure.boundaryField.outlet = { type = "fixedValue", value = 0 }
|
||||
|
||||
# multiplication velocity value with direction vector
|
||||
# multiplication velocity value with flow direction vector
|
||||
approx.velocity.boundaryField.inlet = { type = "fixedValue", value = 6e-5 }
|
||||
approx.velocity.boundaryField.outlet = { type = "zeroGradient", value = "None" }
|
||||
|
||||
|
@ -1,4 +1,42 @@
|
||||
import click
|
||||
import ast
|
||||
|
||||
class LiteralOption(click.Option):
|
||||
def type_cast_value(self, ctx, value):
|
||||
try:
|
||||
return ast.literal_eval(value)
|
||||
|
||||
except:
|
||||
raise click.BadParameter(f"{ value } (Type error)")
|
||||
|
||||
class KeyValueOption(click.Option):
|
||||
def _convert(self, ctx, value):
|
||||
if value.find("=") == -1:
|
||||
raise click.BadParameter(f"{ value } (Missed '=')")
|
||||
|
||||
params = value.split("=")
|
||||
|
||||
if not len(params) == 2:
|
||||
raise click.BadParameter(f"{ value } (Syntax error)")
|
||||
|
||||
key, val = params[0].strip(), params[1].strip()
|
||||
|
||||
if val[0].isalpha():
|
||||
val = f"'{ val }'"
|
||||
|
||||
try:
|
||||
return { key: ast.literal_eval(val) }
|
||||
|
||||
except:
|
||||
raise click.BadParameter(f"{ value } (Type error)")
|
||||
|
||||
def type_cast_value(self, ctx, value):
|
||||
if isinstance(value, list):
|
||||
return [ self._convert(ctx, val) for val in value ]
|
||||
|
||||
else:
|
||||
return self._convert(ctx, value)
|
||||
|
||||
|
||||
#pass_anisotropy = click.make_pass_decorator(Anisotropy)
|
||||
def version():
|
||||
@ -20,10 +58,16 @@ def anisotropy():
|
||||
|
||||
@anisotropy.command()
|
||||
@click.option("-s", "--stage", "stage", type = click.Choice(["all", "mesh", "flow"]), default = "all")
|
||||
@click.option("-p", "--param", "params", metavar = "key=value", multiple = True)
|
||||
@click.option("-p", "--param", "params", metavar = "key=value", multiple = True, cls = KeyValueOption)
|
||||
def compute(stage, params):
|
||||
from anisotropy.core.main import Anisotropy
|
||||
|
||||
args = dict()
|
||||
|
||||
for param in params:
|
||||
args.update(param)
|
||||
|
||||
|
||||
model = Anisotropy()
|
||||
model.db.setup()
|
||||
|
||||
@ -33,14 +77,15 @@ def compute(stage, params):
|
||||
for entry in paramsAll:
|
||||
model.db.update(entry)
|
||||
|
||||
(type, direction, theta) = ("simple", [1.0, 0.0, 0.0], 0.01)
|
||||
type, direction, theta = args["type"], args["direction"], args["theta"]
|
||||
|
||||
model.load(type, direction, theta)
|
||||
# TODO: merge cli params with db params here
|
||||
model.evalParams()
|
||||
model.update()
|
||||
|
||||
# TODO: do smth with output
|
||||
# TODO: single compute / queue
|
||||
|
||||
if stage == "all" or stage == "mesh":
|
||||
((out, err, code), elapsed) = model.computeMesh(type, direction, theta)
|
||||
|
||||
@ -51,6 +96,10 @@ def compute(stage, params):
|
||||
if stage == "all" or stage == "flow":
|
||||
((out, err, code), elapsed) = model.computeFlow(type, direction, theta)
|
||||
|
||||
model.load(type, direction, theta)
|
||||
model.params["flowresult"]["calculationTime"] = elapsed
|
||||
model.update()
|
||||
|
||||
|
||||
@anisotropy.command()
|
||||
@click.argument("root")
|
||||
@ -58,6 +107,7 @@ def compute(stage, params):
|
||||
@click.argument("direction")
|
||||
@click.argument("theta")
|
||||
def computemesh(root, type, direction, theta):
|
||||
# ISSUE: can't hide command from help, hidden = True doesn't work
|
||||
# [Salome Environment]
|
||||
|
||||
###
|
||||
|
@ -8,7 +8,7 @@ from copy import deepcopy
|
||||
|
||||
from anisotropy import env
|
||||
from anisotropy.core.utils import setupLogger
|
||||
from anisotropy.core.models import db, JOIN, Structure, Mesh, SubMesh, MeshResult
|
||||
from anisotropy.core.models import db, JOIN, Structure, Mesh, SubMesh, MeshResult, Flow, FlowResult
|
||||
|
||||
logger = logging.getLogger(env["logger_name"])
|
||||
setupLogger(logger, logging.INFO, env["LOG"])
|
||||
@ -32,7 +32,9 @@ class Database(object):
|
||||
Structure,
|
||||
Mesh,
|
||||
SubMesh,
|
||||
MeshResult
|
||||
MeshResult,
|
||||
Flow,
|
||||
FlowResult
|
||||
])
|
||||
|
||||
|
||||
@ -77,6 +79,20 @@ class Database(object):
|
||||
return params
|
||||
|
||||
|
||||
def loadGeneral(self) -> list:
|
||||
query = (
|
||||
Structure
|
||||
.select()
|
||||
.order_by(Structure.type, Structure.direction, Structure.theta)
|
||||
)
|
||||
response = []
|
||||
|
||||
for entry in query.dicts():
|
||||
response.append({ "structure": entry })
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def update(self, params: dict):
|
||||
if not params:
|
||||
logger.error("Trying to update db from empty parameters")
|
||||
@ -106,6 +122,7 @@ class Database(object):
|
||||
|
||||
self._updateMeshResult(params.get("meshresult", {}), query, meshID)
|
||||
|
||||
# TODO: update method flow flow / flowresult
|
||||
|
||||
def _updateStructure(self, src: dict, queryMain) -> int:
|
||||
raw = deepcopy(src)
|
||||
|
@ -119,9 +119,23 @@ class Anisotropy(object):
|
||||
filletsEnabled = entry["structure"]["filletsEnabled"]
|
||||
),
|
||||
"mesh": mesh,
|
||||
"submesh": deepcopy(entry["submesh"])
|
||||
"submesh": deepcopy(entry["submesh"]),
|
||||
"flow": deepcopy(entry["flow"])
|
||||
}
|
||||
|
||||
# TODO: optimize it
|
||||
# For type = fixedValue only
|
||||
_velocity = entryNew["flow"]["approx"]["velocity"]["boundaryField"]["inlet"]["value"]
|
||||
entryNew["flow"]["approx"]["velocity"]["boundaryField"]["inlet"]["value"] = [
|
||||
val * _velocity for val in entryNew["structure"]["direction"]
|
||||
]
|
||||
|
||||
_velocity = entryNew["flow"]["velocity"]["boundaryField"]["inlet"]["value"]
|
||||
entryNew["flow"]["velocity"]["boundaryField"]["inlet"]["value"] = [
|
||||
val * _velocity for val in entryNew["structure"]["direction"]
|
||||
]
|
||||
|
||||
|
||||
paramsAll.append(entryNew)
|
||||
|
||||
return paramsAll
|
||||
@ -378,11 +392,13 @@ class Anisotropy(object):
|
||||
|
||||
if out:
|
||||
logger.info(out)
|
||||
# TODO: replace all task variables
|
||||
|
||||
openfoam.transformPoints(flow["scale"])
|
||||
|
||||
###
|
||||
# Decomposition and initial approximation
|
||||
#
|
||||
# NOTE: Temporarily without decomposition
|
||||
##
|
||||
openfoam.foamDictionary(
|
||||
"constant/transportProperties",
|
||||
@ -390,7 +406,7 @@ class Anisotropy(object):
|
||||
str(flow["constant"]["nu"])
|
||||
)
|
||||
|
||||
openfoam.decomposePar()
|
||||
#openfoam.decomposePar()
|
||||
|
||||
openfoam.renumberMesh()
|
||||
|
||||
@ -412,11 +428,11 @@ class Anisotropy(object):
|
||||
"boundaryField.outlet.value",
|
||||
openfoam.uniform(pressureBF["outlet"]["value"])
|
||||
)
|
||||
# TODO: flow variable
|
||||
|
||||
openfoam.foamDictionary(
|
||||
"0/U",
|
||||
"boundaryField.inlet.value",
|
||||
openfoam.uniform(velocityBF.inlet.value[direction])
|
||||
openfoam.uniform(velocityBF["inlet"]["value"])
|
||||
)
|
||||
|
||||
openfoam.potentialFoam()
|
||||
@ -424,21 +440,32 @@ class Anisotropy(object):
|
||||
###
|
||||
# Main computation
|
||||
##
|
||||
pressureBF = task.flow.main.pressure.boundaryField
|
||||
velocityBF = task.flow.main.velocity.boundaryField
|
||||
pressureBF = flow["pressure"]["boundaryField"]
|
||||
velocityBF = flow["velocity"]["boundaryField"]
|
||||
|
||||
for n in range(os.cpu_count()):
|
||||
openfoam.foamDictionary(
|
||||
f"processor{n}/0/U",
|
||||
"0/U",
|
||||
"boundaryField.inlet.type",
|
||||
velocityBF.inlet.type
|
||||
velocityBF["inlet"]["type"]
|
||||
)
|
||||
openfoam.foamDictionary(
|
||||
f"processor{n}/0/U",
|
||||
"0/U",
|
||||
"boundaryField.inlet.value",
|
||||
openfoam.uniform(velocityBF.inlet.value[direction])
|
||||
velocityBF["inlet"]["value"]
|
||||
)
|
||||
|
||||
#for n in range(os.cpu_count()):
|
||||
# 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)
|
||||
@ -446,25 +473,21 @@ class Anisotropy(object):
|
||||
###
|
||||
# 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
|
||||
|
||||
postProcessing = "postProcessing/flowRatePatch(name=outlet)/0/surfaceFieldValue.dat"
|
||||
|
||||
with open(postProcessing, "r") as io:
|
||||
lastLine = io.readlines()[-1]
|
||||
flowRate = float(lastLine.replace(" ", "").replace("\n", "").split("\t")[1])
|
||||
|
||||
task.statistics.flowRate = flowRate
|
||||
self.params["flowresult"] = dict(
|
||||
flowRate = flowRate
|
||||
)
|
||||
|
||||
with open(os.path.join(case, "task.toml"), "w") as io:
|
||||
toml.dump(dict(task), io)
|
||||
self.update()
|
||||
|
||||
os.chdir(ROOT)
|
||||
os.chdir(self.env["ROOT"])
|
||||
|
||||
return returncode
|
||||
|
||||
|
@ -132,8 +132,37 @@ class MeshResult(BaseModel):
|
||||
calculationTime = TimeField(null = True)
|
||||
|
||||
class Flow(BaseModel):
|
||||
# TODO: flow model
|
||||
pass
|
||||
# TODO: find better way
|
||||
flow_id = AutoField()
|
||||
structure_id = ForeignKeyField(Structure, backref = "flows")
|
||||
|
||||
class FlowResults(BaseModel):
|
||||
pass
|
||||
approx_pressure_boundaryField_inlet_type = TextField(null = True)
|
||||
approx_pressure_boundaryField_inlet_value = FloatField(null = True)
|
||||
|
||||
approx_pressure_boundaryField_outlet_type = TextField(null = True)
|
||||
approx_pressure_boundaryField_outlet_value = FloatField(null = True)
|
||||
|
||||
approx_velocity_boundaryField_inlet_type = TextField(null = True)
|
||||
approx_velocity_boundaryField_inlet_value = ListField(null = True)
|
||||
|
||||
approx_velocity_boundaryField_outlet_type = TextField(null = True)
|
||||
approx_velocity_boundaryField_outlet_value = ListField(null = True)
|
||||
|
||||
pressure_boundaryField_inlet_type = TextField(null = True)
|
||||
pressure_boundaryField_inlet_value = FloatField(null = True)
|
||||
|
||||
pressure_boundaryField_outlet_type = TextField(null = True)
|
||||
pressure_boundaryField_outlet_value = FloatField(null = True)
|
||||
|
||||
velocity_boundaryField_inlet_type = TextField(null = True)
|
||||
velocity_boundaryField_inlet_value = ListField(null = True)
|
||||
|
||||
velocity_boundaryField_outlet_type = TextField(null = True)
|
||||
velocity_boundaryField_outlet_value = ListField(null = True)
|
||||
|
||||
class FlowResult(BaseModel):
|
||||
flowresult_id = AutoField()
|
||||
flow_id = ForeignKeyField(Flow, backref = "flowresults")
|
||||
|
||||
flowRate = FloatField(null = True)
|
||||
calculationTime = TimeField(null = True)
|
||||
|
@ -171,7 +171,7 @@ def queue(cmd, qin, qout, *args):
|
||||
break
|
||||
|
||||
# Execute command
|
||||
res = cmd(*var, *args)
|
||||
res = cmd(var, *args)
|
||||
|
||||
# Put results to the queue
|
||||
qout.put((pos, res))
|
||||
@ -189,10 +189,6 @@ def parallel(np, var, cmd):
|
||||
qin = Queue(1)
|
||||
qout = Queue()
|
||||
|
||||
logging.info("cpu count: {}".format(np))
|
||||
logging.info("var: {}".format(var))
|
||||
logging.info("cmd: {}".format(cmd))
|
||||
|
||||
# Create processes
|
||||
for n in range(nprocs):
|
||||
pargs = [cmd, qin, qout]
|
||||
|
@ -2,12 +2,21 @@ from .application import application
|
||||
|
||||
import re
|
||||
|
||||
def potentialFoam(case: str = None):
|
||||
def potentialFoam(case: str = None, useMPI: bool = False):
|
||||
if useMPI:
|
||||
application("potentialFoam", "-parallel", useMPI = True, case = case, stderr = True)
|
||||
|
||||
else:
|
||||
application("potentialFoam", case = case, stderr = True)
|
||||
|
||||
def simpleFoam(case: str = None):
|
||||
|
||||
def simpleFoam(case: str = None, useMPI: bool = False):
|
||||
if useMPI:
|
||||
_, returncode = application("simpleFoam", "-parallel", useMPI = True, case = case, stderr = True)
|
||||
|
||||
else:
|
||||
_, returncode = application("simpleFoam", case = case, stderr = True)
|
||||
|
||||
out = ""
|
||||
|
||||
with open("simpleFoam.log", "r") as io:
|
||||
|
Loading…
Reference in New Issue
Block a user