Mod: working flow computation

Fix: some mistakes
New: db models for flow/flow approximation/flow results
This commit is contained in:
L-Nafaryus 2021-08-23 17:13:44 +05:00
parent 9b023313b6
commit a7342affee
12 changed files with 251 additions and 99 deletions

View File

@ -77,14 +77,7 @@ faceCentered = true
[structures.flow]
scale = [ 1e-5, 1e-5, 1e-5 ]
constant.nu = 1e-6
approx.pressure.boundaryField.inlet = { type = "fixedValue", value = 1e-3 }
approx.pressure.boundaryField.outlet = { type = "fixedValue", value = 0 }
# multiplication velocity value with flow direction vector
approx.velocity.boundaryField.inlet = { type = "fixedValue", value = 6e-5 }
approx.velocity.boundaryField.outlet = { type = "zeroGradient", value = "None" }
transportProperties.nu = 1e-6
pressure.boundaryField.inlet = { type = "fixedValue", value = 1e-3 }
pressure.boundaryField.outlet = { type = "fixedValue", value = 0 }
@ -92,6 +85,16 @@ faceCentered = true
velocity.boundaryField.inlet = { type = "fixedValue", value = 0.0 }
velocity.boundaryField.outlet = { type = "zeroGradient", value = "None" }
[structures.flowapprox]
transportProperties.nu = 1e-6
pressure.boundaryField.inlet = { type = "fixedValue", value = 1e-3 }
pressure.boundaryField.outlet = { type = "fixedValue", value = 0 }
# multiplication velocity value with flow direction vector
velocity.boundaryField.inlet = { type = "fixedValue", value = 6e-5 }
velocity.boundaryField.outlet = { type = "zeroGradient", value = "None" }
[[structures]]
[structures.structure]
type = "bodyCentered"
@ -162,14 +165,7 @@ faceCentered = true
[structures.flow]
scale = [ 1e-5, 1e-5, 1e-5 ]
constant.nu = 1e-6
approx.pressure.boundaryField.inlet = { type = "fixedValue", value = 1e-3 }
approx.pressure.boundaryField.outlet = { type = "fixedValue", value = 0 }
# multiplication velocity value with direction vector
approx.velocity.boundaryField.inlet = { type = "fixedValue", value = 6e-5 }
approx.velocity.boundaryField.outlet = { type = "zeroGradient", value = "None" }
transportProperties.nu = 1e-6
pressure.boundaryField.inlet = { type = "fixedValue", value = 1e-3 }
pressure.boundaryField.outlet = { type = "fixedValue", value = 0 }
@ -177,6 +173,16 @@ faceCentered = true
velocity.boundaryField.inlet = { type = "fixedValue", value = 0.0 }
velocity.boundaryField.outlet = { type = "zeroGradient", value = "None" }
[structures.flowapprox]
transportProperties.nu = 1e-6
pressure.boundaryField.inlet = { type = "fixedValue", value = 1e-3 }
pressure.boundaryField.outlet = { type = "fixedValue", value = 0 }
# multiplication velocity value with direction vector
velocity.boundaryField.inlet = { type = "fixedValue", value = 6e-5 }
velocity.boundaryField.outlet = { type = "zeroGradient", value = "None" }
[[structures]]
[structures.structure]
type = "faceCentered"
@ -247,18 +253,21 @@ faceCentered = true
[structures.flow]
scale = [ 1e-5, 1e-5, 1e-5 ]
constant.nu = 1e-6
approx.pressure.boundaryField.inlet = { type = "fixedValue", value = 1e-3 }
approx.pressure.boundaryField.outlet = { type = "fixedValue", value = 0 }
# multiplication velocity value with direction vector
approx.velocity.boundaryField.inlet = { type = "fixedValue", value = 6e-5 }
approx.velocity.boundaryField.outlet = { type = "zeroGradient", value = "None" }
transportProperties.nu = 1e-6
pressure.boundaryField.inlet = { type = "fixedValue", value = 1e-3 }
pressure.boundaryField.outlet = { type = "fixedValue", value = 0 }
velocity.boundaryField.inlet = { type = "fixedValue", value = 0.0 }
velocity.boundaryField.outlet = { type = "zeroGradient", value = "None" }
[structures.flowapprox]
transportProperties.nu = 1e-6
pressure.boundaryField.inlet = { type = "fixedValue", value = 1e-3 }
pressure.boundaryField.outlet = { type = "fixedValue", value = 0 }
# multiplication velocity value with direction vector
velocity.boundaryField.inlet = { type = "fixedValue", value = 6e-5 }
velocity.boundaryField.outlet = { type = "zeroGradient", value = "None" }

View File

@ -11,6 +11,9 @@ class LiteralOption(click.Option):
class KeyValueOption(click.Option):
def _convert(self, ctx, value):
if not value:
return {}
if value.find("=") == -1:
raise click.BadParameter(f"{ value } (Missed '=')")
@ -60,7 +63,7 @@ def anisotropy():
@click.option("-s", "--stage", "stage", type = click.Choice(["all", "mesh", "flow"]), default = "all")
@click.option("-p", "--param", "params", metavar = "key=value", multiple = True, cls = KeyValueOption)
def compute(stage, params):
from anisotropy.core.main import Anisotropy
from anisotropy.core.main import Anisotropy, logger
args = dict()
@ -89,16 +92,20 @@ def compute(stage, params):
if stage == "all" or stage == "mesh":
((out, err, code), elapsed) = model.computeMesh(type, direction, theta)
model.load(type, direction, theta)
model.params["meshresult"]["calculationTime"] = elapsed
model.update()
if out: click.echo(out)
if err: click.echo(err)
if model.params.get("meshresult"):
model.load(type, direction, theta)
model.params["meshresult"]["calculationTime"] = elapsed
model.update()
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()
if model.params.get("flowresult"):
model.load(type, direction, theta)
model.params["flowresult"]["calculationTime"] = elapsed
model.update()
@anisotropy.command()

View File

@ -8,7 +8,12 @@ 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, Flow, FlowResult
from anisotropy.core.models import (
db, JOIN,
Structure,
Mesh, SubMesh, MeshResult,
Flow, FlowApproximation, FlowResult
)
logger = logging.getLogger(env["logger_name"])
setupLogger(logger, logging.INFO, env["LOG"])
@ -34,6 +39,7 @@ class Database(object):
SubMesh,
MeshResult,
Flow,
FlowApproximation,
FlowResult
])
@ -76,6 +82,21 @@ class Database(object):
if meshresultQuery.exists():
params["meshresult"] = meshresultQuery.dicts().get()
flowQuery = structureQuery.get().flows
if flowQuery.exists():
params["flow"] = flowQuery.dicts().get()
flowapproxQuery = flowQuery.get().flowapprox
if flowapproxQuery.exists():
params["flowapprox"] = flowapproxQuery.dicts().get()
flowresultsQuery = flowQuery.get().flowresults
if flowresultsQuery.exists():
params["flowresult"] = flowresultsQuery.dicts().get()
return params
@ -100,12 +121,17 @@ class Database(object):
query = (
Structure
.select(Structure, Mesh)
.select(Structure, Mesh, Flow)
.join(
Mesh,
JOIN.INNER,
on = (Mesh.structure_id == Structure.structure_id)
)
.join(
Flow,
JOIN.INNER,
on = (Flow.structure_id == Structure.structure_id)
)
.where(
Structure.type == params["structure"]["type"],
Structure.direction == str(params["structure"]["direction"]),
@ -122,7 +148,11 @@ class Database(object):
self._updateMeshResult(params.get("meshresult", {}), query, meshID)
# TODO: update method flow flow / flowresult
flowID = self._updateFlow(params["flow"], query, structureID)
self._updateFlowApproximation(params.get("flowapprox", {}), query, flowID)
self._updateFlowResult(params.get("flowresult", {}), query, flowID)
def _updateStructure(self, src: dict, queryMain) -> int:
raw = deepcopy(src)
@ -217,3 +247,73 @@ class Database(object):
)
)
query.execute()
def _updateFlow(self, src: dict, queryMain, structureID):
raw = deepcopy(src)
with self.__db.atomic():
if not queryMain.exists():
tabID = Flow.create(
structure_id = structureID,
**raw
)
else:
req = queryMain.dicts().get()
tabID = req["flow_id"]
query = (
Flow.update(**raw)
.where(
Flow.structure_id == structureID
)
)
query.execute()
return tabID
def _updateFlowApproximation(self, src: dict, queryMain, flowID):
if not src:
return
raw = deepcopy(src)
with self.__db.atomic():
if not FlowApproximation.select().where(FlowApproximation.flow_id == flowID).exists():
tabID = FlowApproximation.create(
flow_id = flowID,
**raw
)
logger.debug(f"[ DB ] Created FlowApproximation entry { tabID }")
else:
query = (
FlowApproximation.update(**raw)
.where(
FlowApproximation.flow_id == flowID
)
)
query.execute()
def _updateFlowResult(self, src: dict, queryMain, flowID):
if not src:
return
raw = deepcopy(src)
with self.__db.atomic():
if not FlowResult.select().where(FlowResult.flow_id == flowID).exists():
tabID = FlowResult.create(
flow_id = flowID,
**raw
)
logger.debug(f"[ DB ] Created FlowResult entry { tabID }")
else:
query = (
FlowResult.update(**raw)
.where(
FlowResult.flow_id == flowID
)
)
query.execute()

View File

@ -120,13 +120,13 @@ class Anisotropy(object):
),
"mesh": mesh,
"submesh": deepcopy(entry["submesh"]),
"flow": deepcopy(entry["flow"])
"flow": deepcopy(entry["flow"]),
"flowapprox": deepcopy(entry["flowapprox"])
}
# TODO: optimize it
# For type = fixedValue only
_velocity = entryNew["flow"]["approx"]["velocity"]["boundaryField"]["inlet"]["value"]
entryNew["flow"]["approx"]["velocity"]["boundaryField"]["inlet"]["value"] = [
_velocity = entryNew["flowapprox"]["velocity"]["boundaryField"]["inlet"]["value"]
entryNew["flowapprox"]["velocity"]["boundaryField"]["inlet"]["value"] = [
val * _velocity for val in entryNew["structure"]["direction"]
]
@ -212,7 +212,7 @@ class Anisotropy(object):
return os.path.join(
self.env["BUILD"],
structure["type"],
f"direction-{ structure['direction'] }",
"direction-{}".format(str(structure['direction']).replace(" ", "")),
f"theta-{ structure['theta'] }"
)
@ -350,15 +350,17 @@ class Anisotropy(object):
foamCase = [ "0", "constant", "system" ]
flow = self.params["flow"]
flowapprox = self.params["flowapprox"]
# ISSUE: ideasUnvToFoam cannot import mesh with '-case' flag so 'os.chdir' for that
os.chdir(self.getCasePath())
casePath = self.getCasePath()
os.chdir(casePath)
openfoam.foamClean()
for d in foamCase:
shutil.copytree(
os.path.join(self.env["openfoam_template"], d),
os.path.join(case, d)
os.path.join(casePath, d)
)
###
@ -369,11 +371,11 @@ class Anisotropy(object):
os.chdir(self.env["ROOT"])
return 1
_, returncode = openfoam.ideasUnvToFoam("mesh.unv")
out, err, returncode = openfoam.ideasUnvToFoam("mesh.unv")
if returncode:
os.chdir(self.env["ROOT"])
return returncode
return out, err, returncode
openfoam.createPatch(dictfile = "system/createPatchDict")
@ -398,25 +400,20 @@ class Anisotropy(object):
###
# Decomposition and initial approximation
#
# NOTE: Temporarily without decomposition
# NOTE: Temporary without decomposition
##
openfoam.foamDictionary(
"constant/transportProperties",
"nu",
str(flow["constant"]["nu"])
str(flow["transportProperties"]["nu"])
)
#openfoam.decomposePar()
openfoam.renumberMesh()
pressureBF = flow["approx"]["pressure"]["boundaryField"]
velocityBF = flow["approx"]["velocity"]["boundaryField"]
direction = {
"[1, 0, 0]": 0,
"[0, 0, 1]": 1,
"[1, 1, 1]": 2
}[str(task.geometry.direction)]
pressureBF = flowapprox["pressure"]["boundaryField"]
velocityBF = flowapprox["velocity"]["boundaryField"]
openfoam.foamDictionary(
"0/p",
@ -451,7 +448,7 @@ class Anisotropy(object):
openfoam.foamDictionary(
"0/U",
"boundaryField.inlet.value",
velocityBF["inlet"]["value"]
openfoam.uniform(velocityBF["inlet"]["value"])
)
#for n in range(os.cpu_count()):
@ -466,7 +463,7 @@ class Anisotropy(object):
# openfoam.uniform(velocityBF.inlet.value[direction])
# )
returncode, out = openfoam.simpleFoam()
out, err, returncode = openfoam.simpleFoam()
if out:
logger.info(out)
@ -477,7 +474,7 @@ class Anisotropy(object):
if returncode == 0:
postProcessing = "postProcessing/flowRatePatch(name=outlet)/0/surfaceFieldValue.dat"
with open(postProcessing, "r") as io:
with open(os.path.join(casePath, postProcessing), "r") as io:
lastLine = io.readlines()[-1]
flowRate = float(lastLine.replace(" ", "").replace("\n", "").split("\t")[1])
@ -489,7 +486,7 @@ class Anisotropy(object):
os.chdir(self.env["ROOT"])
return returncode
return out, err, returncode
def _queue(self):

View File

@ -10,6 +10,7 @@ from peewee import (
IntegerField, BooleanField,
TimeField
)
import json
db = SqliteDatabase(
None,
@ -42,6 +43,15 @@ class ListField(Field):
return pval
class JSONField(TextField):
def db_value(self, value):
return json.dumps(value)
def python_value(self, value):
if value is not None:
return json.loads(value)
class Structure(BaseModel):
structure_id = AutoField()
@ -132,33 +142,22 @@ class MeshResult(BaseModel):
calculationTime = TimeField(null = True)
class Flow(BaseModel):
# TODO: find better way
flow_id = AutoField()
structure_id = ForeignKeyField(Structure, backref = "flows")
approx_pressure_boundaryField_inlet_type = TextField(null = True)
approx_pressure_boundaryField_inlet_value = FloatField(null = True)
scale = ListField(null = True)
pressure = JSONField(null = True)
velocity = JSONField(null = True)
transportProperties = JSONField(null = True)
approx_pressure_boundaryField_outlet_type = TextField(null = True)
approx_pressure_boundaryField_outlet_value = FloatField(null = True)
class FlowApproximation(BaseModel):
flow_approximation_id = AutoField()
flow_id = ForeignKeyField(Flow, backref = "flowapprox")
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)
pressure = JSONField(null = True)
velocity = JSONField(null = True)
transportProperties = JSONField(null = True)
class FlowResult(BaseModel):
flowresult_id = AutoField()

View File

@ -105,24 +105,64 @@ class struct:
def deepupdate(target, src):
for k, v in src.items():
#if type(v) == list:
# if not k in target:
# target[k] = copy.deepcopy(v)
# else:
# target[k].extend(v)
if type(v) == dict:
if isinstance(v, dict):
if not k in target:
target[k] = copy.deepcopy(v)
else:
deepupdate(target[k], v)
#elif type(v) == set:
# if not k in target:
# target[k] = v.copy()
# else:
# target[k].update(v.copy())
else:
target[k] = copy.copy(v)
def collapse(source, key = None, level = 0, sep = "_"):
if isinstance(source, dict) and source:
level = level + 1
res = {}
for k, v in source.items():
ret, lvl = collapse(v, k, level)
for kk,vv in ret.items():
if level == lvl:
newkey = k
else:
newkey = "{}{}{}".format(k, sep, kk)
res.update({ newkey: vv })
if level == 1:
return res
else:
return res, level
else:
return { key: source }, level
def expand(source, sep = "_"):
res = {}
for k, v in source.items():
if k.find(sep) == -1:
res.update({ k: v })
else:
keys = k.split(sep)
cur = res
for n, kk in enumerate(keys):
if not len(keys) == n + 1:
if not cur.get(kk):
cur.update({ kk: {} })
cur = cur[kk]
else:
cur[kk] = v
return res
#if os.path.exists(env["CONFIG"]):
# config = toml.load(env["CONFIG"])

View File

@ -42,6 +42,6 @@ def application(name: str, *args: str, case: str = None, stderr: bool = True, us
logger.error("""{}:
{}""".format(name, str(err, "utf-8")))
return out, p.returncode
return out, err, p.returncode

View File

@ -34,5 +34,5 @@ def checkMesh(case: str = None) -> str:
def renumberMesh(case: str = None):
application("renumberMesh", "-parallel", "-overwrite", useMPI = True, case = case, stderr = True)
application("renumberMesh", "-overwrite", useMPI = False, case = case, stderr = True)

View File

@ -12,10 +12,10 @@ def potentialFoam(case: str = None, useMPI: bool = False):
def simpleFoam(case: str = None, useMPI: bool = False):
if useMPI:
_, returncode = application("simpleFoam", "-parallel", useMPI = True, case = case, stderr = True)
out, err, returncode = application("simpleFoam", "-parallel", useMPI = True, case = case, stderr = True)
else:
_, returncode = application("simpleFoam", case = case, stderr = True)
out, err, returncode = application("simpleFoam", case = case, stderr = True)
out = ""
@ -24,5 +24,5 @@ def simpleFoam(case: str = None, useMPI: bool = False):
if re.search("solution converged", line):
out = "simpleFoam:\n\t{}".format(line.strip())
return returncode, out
return out, err, returncode

View File

@ -7,7 +7,7 @@ try:
from salome.geom import geomBuilder
except ImportError:
logger.warning("Trying to get SALOME geometry modules outside SALOME environment. Modules won't be imported.")
logger.debug("Trying to get SALOME geometry modules outside SALOME environment. Modules won't be imported.")
if globals().get("geomBuilder"):
geompy = geomBuilder.New()

View File

@ -7,7 +7,7 @@ try:
from salome.smesh import smeshBuilder
except ImportError:
logger.warning("Trying to get SALOME mesh modules outside SALOME environment. Modules won't be imported.")
logger.debug("Trying to get SALOME mesh modules outside SALOME environment. Modules won't be imported.")
if globals().get("smeshBuilder"):
smesh = smeshBuilder.New()

View File

@ -44,7 +44,7 @@ class BodyCentered(object):
###
# Bounding box
##
if direction == [1, 0, 0]:
if self.direction == [1, 0, 0]:
sk = geompy.Sketcher3D()
sk.addPointsAbsolute(xl, 0, 0)
sk.addPointsAbsolute(0, yw, 0)
@ -56,7 +56,7 @@ class BodyCentered(object):
vecflow = geompy.GetNormal(inletface)
poreCell = geompy.MakePrismVecH(inletface, vecflow, diag)
elif direction == [0, 0, 1]:
elif self.direction == [0, 0, 1]:
sk = geompy.Sketcher3D()
sk.addPointsAbsolute(0, yw, 0)
sk.addPointsAbsolute(xl, 0, 0)