Mod: everything for db

This commit is contained in:
L-Nafaryus 2021-07-26 18:00:23 +05:00
parent c2a6303f17
commit 39db5447c9
4 changed files with 183 additions and 124 deletions

View File

@ -71,7 +71,7 @@ if os.path.exists(env["CONFIG"]):
for restricted in ["ROOT", "BUILD", "LOG", "CONFIG"]: for restricted in ["ROOT", "BUILD", "LOG", "CONFIG"]:
if config.get(restricted): if config.get(restricted):
config.pop(restricted) config.pop(restricted)
for m, structure in enumerate(config["structures"]): for m, structure in enumerate(config["structures"]):
for n, estructure in enumerate(env["structures"]): for n, estructure in enumerate(env["structures"]):
if estructure["name"] == structure["name"]: if estructure["name"] == structure["name"]:
@ -110,10 +110,12 @@ def timer(func):
class Anisotropy(object): class Anisotropy(object):
def __init__(self): def __init__(self):
self.db = self._setupDB() self.env = env
self.db = None
self.params = [] self.params = []
self.evalParameters(env) #self.evalParameters(env)
self.setupDB()
@staticmethod @staticmethod
def version(): def version():
@ -133,23 +135,21 @@ class Anisotropy(object):
return "\n".join([ f"{ k }: { v }" for k, v in versions.items() ]) return "\n".join([ f"{ k }: { v }" for k, v in versions.items() ])
@staticmethod def setupDB(self):
def _setupDB(): self.db = db.init(self.env["db_path"])
db.init(env["db_path"])
if not os.path.exists(env["db_path"]): if not os.path.exists(self.env["db_path"]):
db.create_tables([Structure, Mesh]) self.db.create_tables([Structure, Mesh])
return db def evalEnvParameters(self):
""" 'Uncompress' and eval environment parameters """
def evalParameters(self, _env: dict):
from math import sqrt from math import sqrt
structures = deepcopy(_env["structures"]) structures = deepcopy(self.env["structures"])
for structure in structures: for structure in structures:
_theta = structure["geometry"]["theta"] _theta = structure["geometry"]["theta"]
thetaMin = int(_theta[0] / _theta[2]) thetaMin = int(_theta[0] / _theta[2])
thetaMax = int(_theta[1] / _theta[2]) + 1 thetaMax = int(_theta[1] / _theta[2]) + 1
thetaList = list( thetaList = list(
map(lambda n: n * _theta[2], range(thetaMin, thetaMax)) map(lambda n: n * _theta[2], range(thetaMin, thetaMax))
@ -168,7 +168,7 @@ class Anisotropy(object):
L = 2 * r0 L = 2 * r0
radius = r0 / (1 - theta) radius = r0 / (1 - theta)
C1, C2 = 0.8, 0.5 C1, C2 = 0.8, 0.5
Cf = C1 + (C2 - C1) / (thetaMax - thetaMin) * (theta - thetaMin) Cf = C1 + (C2 - C1) / (thetaMax - thetaMin) * (theta - thetaMin)
delta = 0.2 delta = 0.2
fillets = delta - Cf * (radius - r0) fillets = delta - Cf * (radius - r0)
@ -188,14 +188,14 @@ class Anisotropy(object):
r0 = L * sqrt(3) / 4 r0 = L * sqrt(3) / 4
radius = r0 / (1 - theta) radius = r0 / (1 - theta)
C1, C2 = 0.3, 0.2 C1, C2 = 0.3, 0.2
Cf = C1 + (C2 - C1) / (thetaMax - thetaMin) * (theta - thetaMin) Cf = C1 + (C2 - C1) / (thetaMax - thetaMin) * (theta - thetaMin)
delta = 0.02 delta = 0.02
fillets = delta - Cf * (radius - r0) fillets = delta - Cf * (radius - r0)
path = os.path.join( path = os.path.join(
_env["BUILD"], self.env["BUILD"],
structure["name"], structure["name"],
f"direction-{ direction }", f"direction-{ direction }",
f"theta-{ theta }" f"theta-{ theta }"
@ -214,16 +214,25 @@ class Anisotropy(object):
mesh.update( mesh.update(
thickness = thicknessList[n] thickness = thicknessList[n]
) )
self.params.append({ self.params.append(dict(
"name": structure["name"], name = structure["name"],
"path": path, path = path,
"geometry": geometry, geometry = geometry,
"mesh": mesh, mesh = mesh,
"submesh": deepcopy(structure["submesh"]) submesh = deepcopy(structure["submesh"])
}) ))
def getParams(structure, direction, theta):
for entry in self.params:
if entry["name"] == structure and
entry["geometry"]["direction"] == direction and
entry["geometry"]["theta"] == theta:
return entry
# SELECT * FROM structure LEFT OUTER JOIN mesh ON mesh.structure_id = structure.id WHERE name = "faceCentered" AND direction = "[1, 1, 1]" AND theta = 0.12; # SELECT * FROM structure LEFT OUTER JOIN mesh ON mesh.structure_id = structure.id WHERE name = "faceCentered" AND direction = "[1, 1, 1]" AND theta = 0.12;
# Structure.select().join(Mesh, JOIN.LEFT_OUTER, on = (Mesh.structure_id == Structure.id)).where(Structure.name == "simple", Structure.direction == "[1, 0, 0]", Structure.theta == 0.13).dicts().get()
@timer
def updateDB(self): def updateDB(self):
for entry in self.params: for entry in self.params:
query = (Structure query = (Structure
@ -242,7 +251,7 @@ class Anisotropy(object):
) )
m = deepcopy(entry["mesh"]) m = deepcopy(entry["mesh"])
if not query.exists(): if not query.exists():
with self.db.atomic(): with self.db.atomic():
stab = Structure.create(**s) stab = Structure.create(**s)
@ -251,12 +260,38 @@ class Anisotropy(object):
mtab = Mesh.create(**m) mtab = Mesh.create(**m)
else: else:
# TODO: not working update; incorrect update (all entries)
with self.db.atomic(): with self.db.atomic():
stab = Structure.update(**s) (Structure.update(**s)
.where(
Structure.name == entry["name"],
Structure.direction == str(entry["geometry"]["direction"]),
Structure.theta == entry["geometry"]["theta"]
)
.execute())
m.update(structure_id = stab) (Mesh.update(**m)
mtab = Mesh.update(**m) .where(
Mesh.structure_id == query.get().id
)
.execute())
@timer
def updateFromDB(self):
squery = Structure.select().order_by(Structure.id)
mquery = Mesh.select().order_by(Mesh.structure_id)
for s, m in zip(squery.dicts(), mquery.dicts()):
name = s.pop("name")
path = s.pop("path")
self.params.append(dict(
name = name,
path = path,
geometry = s,
mesh = m
))
self.params = sorted(self.params, key = lambda entry: f"{ entry['name'] } { entry['geometry']['direction'] } { entry['geometry']['theta'] }")
@timer @timer
def computeMesh(self): def computeMesh(self):

View File

@ -15,32 +15,32 @@ class ListField(Field):
except: except:
pass pass
finally: finally:
pval.append(ch.strip()) pval.append(ch.strip().replace("'", ""))
return pval return pval
db = SqliteDatabase( db = SqliteDatabase(
None, None,
pragmas = { "foreign_keys": 1 }, pragmas = { "foreign_keys": 1 },
field_types = { "list": "text" } field_types = { "list": "text" }
) )
class BaseModel(Model): class BaseModel(Model):
class Meta: class Meta:
database = db database = db
class Structure(BaseModel): class Structure(BaseModel):
name = TextField() name = TextField()
direction = TextField() direction = ListField()
theta = FloatField() theta = FloatField()
r0 = FloatField() r0 = FloatField()
L = FloatField() L = FloatField()
radius = FloatField() radius = FloatField()
filletsEnabled = BooleanField() filletsEnabled = BooleanField()
fillets = FloatField() fillets = FloatField()
path = TextField() path = TextField()

View File

@ -2,115 +2,159 @@
# This file executes inside salome environment # This file executes inside salome environment
# #
# salome starts at user home directory # salome starts at user home directory
#
# sys.argv = [ .., ROOT, case ]
## ##
import os, sys import os, sys
import math import math
import salome import salome
# get project path from args
ROOT = sys.argv[1]
CASE = sys.argv[2]
sys.path.append(ROOT) @click.command()
# site-packages from virtual env @click.argument("root")
sys.path.append(os.path.join(ROOT, "env/lib/python3.9/site-packages")) @click.argument("name")
@click.argument("direction")
import toml @click.argument("theta", type = click.FLOAT)
import logging def genmesh(root, name, direction, theta):
from anisotropy.utils import struct ###
# Args
from salomepl.simple import simple ##
from salomepl.faceCentered import faceCentered direction = list(map(lambda num: float(num), direction[1:-1].split(",")))
from salomepl.bodyCentered import bodyCentered
from salomepl.geometry import getGeom
from salomepl.mesh import Mesh, Fineness, ExtrusionMethod, defaultParameters
def genmesh(config): ###
# Modules
logger.info(f"""genmesh: ##
structure type:\t{ config.structure } sys.path.extend([
coefficient:\t{ config.geometry.theta } root,
fillet:\t{ config.geometry.fillet } os.path.join(root, "env/lib/python3.9/site-packages")
flow direction:\t{ config.geometry.direction }""") ])
import logging
import click
from anisotropy import Anisotropy
from salomepl.simple import simple
from salomepl.faceCentered import faceCentered
from salomepl.bodyCentered import bodyCentered
from salomepl.geometry import getGeom
from salomepl.mesh import Mesh, Fineness, ExtrusionMethod, defaultParameters
###
# Model
##
model = Anisotropy()
model.updateFromDB()
p = model.getParams(name, direction, theta)
###
# Logger
##
logging.basicConfig(
level = logging.INFO,
format = model.env["logger"]["format"],
handlers = [
logging.StreamHandler(),
logging.FileHandler(
os.path.join(model.env["LOG"], model.env["logger"]["name"])
)
]
)
logger = logging.getLogger(model.env["logger"]["name"])
###
# Entry
##
logger.info("\n".join([
"genmesh:",
f"structure type:\t{ p['name'] }",
f"coefficient:\t{ p['geometry']['theta'] }",
f"fillet:\t{ p['geometry']['fillets'] }",
f"flow direction:\t{ p['geometry']['direction'] }"
]))
salome.salome_init() salome.salome_init()
### ###
# Shape # Shape
## ##
geompy = getGeom() geompy = getGeom()
structure = globals().get(config.structure) structure = globals().get(p["name"])
shape, groups = structure(config.geometry.theta, config.geometry.fillet, config.geometry.direction) shape, groups = structure(
p["geometry"]["theta"],
p["geometry"]["fillets"],
p["geometry"]["direction"]
)
[length, surfaceArea, volume] = geompy.BasicProperties(shape, theTolerance = 1e-06) [length, surfaceArea, volume] = geompy.BasicProperties(shape, theTolerance = 1e-06)
logger.info(f"""shape: logger.info("\n".join([
edges length:\t{ length } "shape:"
surface area:\t{ surfaceArea } f"edges length:\t{ length }",
volume:\t{ volume }""") f"surface area:\t{ surfaceArea }",
f"volume:\t{ volume }"
]))
### ###
# Mesh # Mesh
## ##
config = dict(config) mp = p["mesh"]
mconfig = defaultParameters(**config["mesh"]) lengths = [
geompy.BasicProperties(edge)[0] for edge in geompy.SubShapeAll(shape, geompy.ShapeType["EDGE"])
lengths = [ geompy.BasicProperties(edge)[0] for edge in geompy.SubShapeAll(shape, geompy.ShapeType["EDGE"]) ] ]
meanSize = sum(lengths) / len(lengths) meanSize = sum(lengths) / len(lengths)
mconfig["maxSize"] = meanSize mp["maxSize"] = meanSize
mconfig["minSize"] = meanSize * 1e-1 mp["minSize"] = meanSize * 1e-1
mconfig["chordalError"] = mconfig["maxSize"] / 2 mp["chordalError"] = mp["maxSize"] / 2
faces = [] faces = []
for group in groups: for group in groups:
if group.GetName() in mconfig["facesToIgnore"]: if group.GetName() in mconfig["facesToIgnore"]:
faces.append(group) faces.append(group)
mconfig["faces"] = faces
mesh = Mesh(shape) mesh = Mesh(shape)
mesh.Tetrahedron(**mconfig) mesh.Tetrahedron(**mp)
if mconfig["viscousLayers"]: if mp["viscousLayers"]:
mesh.ViscousLayers(**mconfig) mesh.ViscousLayers(**mp, faces = faces)
config["mesh"].update(mconfig)
smconfigs = config["mesh"]["submesh"]
for name in smconfigs.keys(): smp = p["submesh"]
for name in smp.keys():
for group in groups: for group in groups:
if group.GetName() == name: if group.GetName() == name:
subshape = group subshape = group
smconfig = defaultParameters(**smconfigs[name]) smp["maxSize"] = meanSize * 1e-1
smconfig["maxSize"] = meanSize * 1e-1 smp["minSize"] = meanSize * 1e-3
smconfig["minSize"] = meanSize * 1e-3 smp["chordalError"] = smp["minSize"] * 1e+1
smconfig["chordalError"] = smconfig["minSize"] * 1e+1
mesh.Triangle(subshape, **smp)
mesh.Triangle(subshape, **smconfig)
config["mesh"]["submesh"][name].update(smconfig)
returncode, errors = mesh.compute() returncode, errors = mesh.compute()
if not returncode: if not returncode:
config["status"]["mesh"] = True # TODO: MeshResult
pass
else: else:
logger.error(errors) logger.error(errors)
with open(CONFIG, "w") as io:
toml.dump(config, io)
mesh.removePyramids() mesh.removePyramids()
mesh.assignGroups() mesh.assignGroups()
mesh.exportUNV(os.path.join(CASE, "mesh.unv")) mesh.exportUNV(os.path.join(p["path"], "mesh.unv"))
stats = "" stats = ""
for k, v in mesh.stats().items(): for k, v in mesh.stats().items():
@ -120,23 +164,3 @@ def genmesh(config):
salome.salome_close() salome.salome_close()
if __name__ == "__main__":
CONFIG = os.path.join(CASE, "task.toml")
config = struct(toml.load(CONFIG))
LOG = os.path.join(ROOT, "logs")
logging.basicConfig(
level = logging.INFO,
format = config.logger.format,
handlers = [
logging.StreamHandler(),
logging.FileHandler(f"{ LOG }/{ config.logger.name }.log")
]
)
logger = logging.getLogger(config.logger.name)
genmesh(config)

View File

@ -40,14 +40,14 @@ def runSalome(port: int, scriptpath: str, root: str, logpath: str = None, *args)
if not logpath: if not logpath:
logpath = "/tmp/salome.log" logpath = "/tmp/salome.log"
fullargs = list(args)
fullargs.extend([ root, logpath ])
fmtargs = "args:{}".format(", ".join([ str(arg) for arg in args ])) fmtargs = "args:{}".format(", ".join([ str(arg) for arg in args ]))
cmdargs = [ cmdargs = [
"start", "-t", "start", "-t",
"--shutdown-servers=1", "--shutdown-servers=1",
"--port", str(port), "--port", str(port),
scriptpath, scriptpath,
root,
logpath,
fmtargs fmtargs
] ]