diff --git a/anisotropy/anisotropy.py b/anisotropy/anisotropy.py index 93bd4b5..837593d 100644 --- a/anisotropy/anisotropy.py +++ b/anisotropy/anisotropy.py @@ -46,8 +46,12 @@ import os import toml from copy import deepcopy from anisotropy.models import db, Structure, Mesh +from anisotropy.utils import struct import salomepl +### +# Environment variables and config +## env = { "ROOT": os.path.abspath(".") } env.update({ "BUILD": os.path.join(env["ROOT"], "build"), @@ -67,10 +71,13 @@ if os.path.exists(env["CONFIG"]): for restricted in ["ROOT", "BUILD", "LOG", "CONFIG"]: if config.get(restricted): config.pop(restricted) + + # TODO: dict replacing + #env.update(config) - env.update(config) - - +### +# Logger +## logger_env = env.get("logger", {}) logging.basicConfig( level = logging.INFO, @@ -99,9 +106,9 @@ def timer(func): class Anisotropy(object): def __init__(self): self.db = self._setupDB() - self.structures = self._expandConfigParams(env["structures"]) + self.params = [] - #self.updateDB() + self.evalParameters(env) @staticmethod def version(): @@ -130,126 +137,120 @@ class Anisotropy(object): return db - @staticmethod - def _expandConfigParams(params): - structures = deepcopy(params) - - for structure in structures: - theta = structure["geometry"]["theta"] - start, end = int(theta[0] / theta[2]), int(theta[1] / theta[2]) + 1 - structure["geometry"]["theta"] = list( - map(lambda n: n * theta[2], range(start, end)) - ) - - thickness = structure["mesh"]["thickness"] - count = len(structure["geometry"]["theta"]) - structure["mesh"]["thickness"] = list( - map(lambda n: thickness[0] + n * (thickness[1] - thickness[0]) / (count - 1), range(0, count)) - ) - - return structures - - @staticmethod - def _setupQueue(params): - structures = deepcopy(params) - queue = [] - - for structure in structures: - for direction in structure["geometry"]["directions"]: - for n, theta in enumerate(structure["geometry"]["theta"]): - prequeue = deepcopy(structure) - del prequeue["geometry"]["directions"] - - prequeue["geometry"]["direction"] = direction - prequeue["geometry"]["theta"] = theta - - prequeue["path"] = os.path.join( - env["BUILD"], - structure["name"], - "direction-{}{}{}".format(*direction), - "theta-{}".format(theta) - ) - - prequeue["mesh"]["thickness"] = structure["mesh"]["thickness"][n] - - queue.append(prequeue) - - return queue - - def updateDB(self): - queue = self._setupQueue(self.structures) - - for structure in queue: - s = Structure.create( - name = structure["name"], - path = structure["path"], - **structure["geometry"] - ) - - Mesh.create( - structure = s, - **structure["mesh"] - ) - - def computeGeometryParams(self): + def evalParameters(self, _env: dict): from math import sqrt - structures = self._setupQueue(self.structures) - - for s in structures: - theta = s["geometry"]["theta"] + structures = deepcopy(_env["structures"]) - if s["name"] == "simple": - r0 = 1 - L = 2 * r0 - radius = r0 / (1 - theta) - - C1, C2 = 0.8, 0.5 - theta1, theta2 = 0.01, 0.28 - Cf = C1 + (C2 - C1) / (theta2 - theta1) * (theta - theta1) - delta = 0.2 - fillets = delta - Cf * (radius - r0) - - elif s["name"] == "faceCentered": - L = 1.0 - r0 = L * sqrt(2) / 4 - radius = r0 / (1 - theta) - - C1, C2 = 0.3, 0.2 - theta1, theta2 = 0.01, 0.13 - Cf = C1 + (C2 - C1) / (theta2 - theta1) * (theta - theta1) - delta = 0.012 - fillets = delta - Cf * (radius - r0) - - elif s["name"] == "bodyCentered": - L = 1.0 - r0 = L * sqrt(3) / 4 - radius = r0 / (1 - theta) - - C1, C2 = 0.3, 0.2 - theta1, theta2 = 0.01, 0.18 - Cf = C1 + (C2 - C1) / (theta2 - theta1) * (theta - theta1) - delta = 0.02 - fillets = delta - Cf * (radius - r0) - - buf = {} #deepcopy(s) - buf.update( - {"name": s["name"], - "path": s["path"]}, - **s["geometry"] - ) - buf.update({ - "r0": r0, - "L": L, - "radius": radius, - "fillets": fillets - }) - stable = Structure.create(**buf) - Mesh.create( - structure = stable, - **s["mesh"] + for structure in structures: + _theta = structure["geometry"]["theta"] + thetaMin = int(_theta[0] / _theta[2]) + thetaMax = int(_theta[1] / _theta[2]) + 1 + thetaList = list( + map(lambda n: n * _theta[2], range(thetaMin, thetaMax)) ) + _thickness = structure["mesh"]["thickness"] + count = len(thetaList) + thicknessList = list( + map(lambda n: _thickness[0] + n * (_thickness[1] - _thickness[0]) / (count - 1), range(0, count)) + ) + + for direction in structure["geometry"]["directions"]: + for n, theta in enumerate(thetaList): + if structure["name"] == "simple": + r0 = 1 + L = 2 * r0 + radius = r0 / (1 - theta) + + C1, C2 = 0.8, 0.5 + Cf = C1 + (C2 - C1) / (thetaMax - thetaMin) * (theta - thetaMin) + delta = 0.2 + fillets = delta - Cf * (radius - r0) + + elif structure["name"] == "faceCentered": + L = 1.0 + r0 = L * sqrt(2) / 4 + radius = r0 / (1 - theta) + + C1, C2 = 0.3, 0.2 + Cf = C1 + (C2 - C1) / (thetaMax - thetaMin) * (theta - thetaMin) + delta = 0.012 + fillets = delta - Cf * (radius - r0) + + elif structure["name"] == "bodyCentered": + L = 1.0 + r0 = L * sqrt(3) / 4 + radius = r0 / (1 - theta) + + C1, C2 = 0.3, 0.2 + Cf = C1 + (C2 - C1) / (thetaMax - thetaMin) * (theta - thetaMin) + delta = 0.02 + fillets = delta - Cf * (radius - r0) + + + path = os.path.join( + _env["BUILD"], + structure["name"], + f"direction-{ direction }", + f"theta-{ theta }" + ) + geometry = dict( + theta = theta, + direction = direction, + r0 = r0, + L = L, + radius = radius, + filletsEnabled = structure["geometry"]["filletsEnabled"], + fillets = fillets + + ) + mesh = deepcopy(structure["mesh"]) + mesh.update( + thickness = thicknessList[n] + ) + self.params.append({ + "name": structure["name"], + "path": path, + "geometry": geometry, + "mesh": mesh, + "submesh": deepcopy(structure["submesh"]) + }) + + + # 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; + def updateDB(self): + for entry in self.params: + query = (Structure + .select() + .where( + Structure.name == entry["name"], + Structure.direction == str(entry["geometry"]["direction"]), + Structure.theta == entry["geometry"]["theta"] + ) + ) + + s = deepcopy(entry["geometry"]) + s.update( + name = entry["name"], + path = entry["path"] + ) + + m = deepcopy(entry["mesh"]) + + if not query.exists(): + with self.db.atomic(): + stab = Structure.create(**s) + + m.update(structure = stab) + mtab = Mesh.create(**m) + + else: + with self.db.atomic(): + stab = Structure.update(**s) + + m.update(structure = stab) + mtab = Mesh.update(**m) @timer def computeMesh(self): @@ -258,9 +259,6 @@ class Anisotropy(object): out, err, returncode = salomepl.runSalome(port, scriptpath, env["ROOT"], case) - - - def computeFlow(self): pass diff --git a/anisotropy/default.toml b/anisotropy/default.toml index 5149171..a59831f 100644 --- a/anisotropy/default.toml +++ b/anisotropy/default.toml @@ -17,7 +17,7 @@ faceCentered = true [0, 0, 1], [1, 1, 1] ] - fillet = true + filletsEnabled = true [structures.mesh] viscousLayers = true @@ -38,7 +38,7 @@ faceCentered = true [0, 0, 1], [1, 1, 1] ] - fillet = true + filletsEnabled = true [structures.mesh] viscousLayers = true @@ -59,7 +59,7 @@ faceCentered = true [0, 0, 1], [1, 1, 1] ] - fillet = true + filletsEnabled = true [structures.mesh] viscousLayers = true diff --git a/anisotropy/models.py b/anisotropy/models.py index 07d5214..b0be959 100644 --- a/anisotropy/models.py +++ b/anisotropy/models.py @@ -1,11 +1,37 @@ from peewee import * -db = SqliteDatabase(None) +class ListField(Field): + field_type = "list" + + def db_value(self, value): + return str(value) + + def python_value(self, value): + pval = [] + + for ch in value[1 : -1].split(","): + try: + pval.append(float(ch)) + + except: + pass + + finally: + pval.append(ch.strip()) + + return pval + +db = SqliteDatabase( + None, + pragmas = { "foreign_keys": 1 }, + field_types = { "list": "text" } +) class BaseModel(Model): class Meta: database = db + class Structure(BaseModel): name = TextField() direction = TextField() @@ -15,39 +41,48 @@ class Structure(BaseModel): L = FloatField() radius = FloatField() - fillet = BooleanField() + filletsEnabled = BooleanField() fillets = FloatField() path = TextField() + class Mesh(BaseModel): - structure = ForeignKeyField(Structure, backref = "meshes") + structure_id = ForeignKeyField(Structure, backref = "meshes") - maxSize = FloatField() - minSize = FloatField() + maxSize = FloatField(null = True) + minSize = FloatField(null = True) - fineness = IntegerField() - growthRate = FloatField() - nbSegPerEdge = FloatField() - nbSegPerRadius = FloatField() + fineness = IntegerField(null = True) + growthRate = FloatField(null = True) + nbSegPerEdge = FloatField(null = True) + nbSegPerRadius = FloatField(null = True) - chordalErrorEnabled = BooleanField() - chordalError = FloatField() + chordalErrorEnabled = BooleanField(null = True) + chordalError = FloatField(null = True) - secondOrder = BooleanField() - optimize = BooleanField() - quadAllowed = BooleanField() - useSurfaceCurvature = BooleanField() - fuseEdges = BooleanField() - checkChartBoundary = BooleanField() + secondOrder = BooleanField(null = True) + optimize = BooleanField(null = True) + quadAllowed = BooleanField(null = True) + useSurfaceCurvature = BooleanField(null = True) + fuseEdges = BooleanField(null = True) + checkChartBoundary = BooleanField(null = True) - viscousLayers = BooleanField() - thickness = FloatField() - numberOfLayers = IntegerField() - stretchFactor = FloatField() - isFacesToIgnore = BooleanField() + viscousLayers = BooleanField(null = True) + thickness = FloatField(null = True) + numberOfLayers = IntegerField(null = True) + stretchFactor = FloatField(null = True) + isFacesToIgnore = BooleanField(null = True) #facesToIgnore = ["inlet", "outlet"] #faces = [] #extrusionMethod = ExtrusionMethod.SURF_OFFSET_SMOOTH - calculationTime = TimeField() +class SubMesh(Mesh): + mesh_id = ForeignKeyField(Mesh, backref = "submeshes") + + +class MeshResult(BaseModel): + mesh_id = ForeignKeyField(Mesh, backref = "meshresults") + + calculationTime = TimeField(null = True) + diff --git a/salomepl/mesh.py b/salomepl/mesh.py index db48f44..63cd2d5 100644 --- a/salomepl/mesh.py +++ b/salomepl/mesh.py @@ -66,23 +66,23 @@ def defaultParameters(**configParameters): return p def updateParams(old, new: dict): - old.SetMaxSize(new.get("maxSize") if new.get("maxSize") else old.GetMaxSize()) - old.SetMinSize(new.get("minSize") if new.get("minSize") else old.GetMinSize()) + old.SetMaxSize(new.get("maxSize", old.GetMaxSize())) + old.SetMinSize(new.get("minSize", old.GetMinSize())) - old.SetFineness(new.get("fineness") if new.get("fineness") else old.GetFineness()) - old.SetGrowthRate(new.get("growthRate") if new.get("growthRate") else old.GetGrowthRate()) - old.SetNbSegPerEdge(new.get("nbSegPerEdge") if new.get("nbSegPerEdge") else old.GetNbSegPerEdge()) - old.SetNbSegPerRadius(new.get("nbSegPerRadius") if new.get("nbSegPerRadius") else old.GetNbSegPerRadius()) + old.SetFineness(new.get("fineness", old.GetFineness())) + old.SetGrowthRate(new.get("growthRate", old.GetGrowthRate())) + old.SetNbSegPerEdge(new.get("nbSegPerEdge", old.GetNbSegPerEdge())) + old.SetNbSegPerRadius(new.get("nbSegPerRadius", old.GetNbSegPerRadius())) - old.SetChordalErrorEnabled(new.get("chordalErrorEnabled") if new.get("chordalErrorEnabled") else old.GetChordalErrorEnabled()) - old.SetChordalError(new.get("chordalError") if new.get("chordalError") else old.GetChordalError()) + old.SetChordalErrorEnabled(new.get("chordalErrorEnabled", old.GetChordalErrorEnabled())) + old.SetChordalError(new.get("chordalError", old.GetChordalError())) - old.SetSecondOrder(new.get("secondOrder") if new.get("secondOrder") else old.GetSecondOrder()) - old.SetOptimize(new.get("optimize") if new.get("optimize") else old.GetOptimize()) - old.SetQuadAllowed(new.get("quadAllowed") if new.get("quadAllowed") else old.GetQuadAllowed()) - old.SetUseSurfaceCurvature(new.get("useSurfaceCurvature") if new.get("useSurfaceCurvature") else old.GetUseSurfaceCurvature()) - old.SetFuseEdges(new.get("fuseEdges") if new.get("fuseEdges") else old.GetFuseEdges()) - old.SetCheckChartBoundary(new.get("checkChartBoundary") if new.get("checkChartBoundary") else old.GetCheckChartBoundary()) + old.SetSecondOrder(new.get("secondOrder", old.GetSecondOrder())) + old.SetOptimize(new.get("optimize", old.GetOptimize())) + old.SetQuadAllowed(new.get("quadAllowed", old.GetQuadAllowed())) + old.SetUseSurfaceCurvature(new.get("useSurfaceCurvature", old.GetUseSurfaceCurvature())) + old.SetFuseEdges(new.get("fuseEdges", old.GetFuseEdges())) + old.SetCheckChartBoundary(new.get("checkChartBoundary", old.GetCheckChartBoundary())) class Mesh(object):