Mod: merge cae to pipeline

This commit is contained in:
L-Nafaryus 2021-11-18 22:00:30 +05:00
parent 88f07abf4a
commit c56504f120
No known key found for this signature in database
GPG Key ID: C76D8DCD2727DBB7
8 changed files with 128 additions and 107 deletions

View File

@ -1,4 +1,4 @@
.. image:: https://circleci.com/gh/L-Nafaryus/anisotropy/tree/devel.svg?style=svg&circle-token=423bc964a997ded671ebd4ceacc25f9967acdffa .. image:: https://circleci.com/gh/L-Nafaryus/anisotropy/tree/devel.svg?style=shield&circle-token=423bc964a997ded671ebd4ceacc25f9967acdffa
:target: https://circleci.com/gh/L-Nafaryus/anisotropy/tree/devel :target: https://circleci.com/gh/L-Nafaryus/anisotropy/tree/devel
anisotropy anisotropy

View File

@ -3,11 +3,14 @@
# License: GNU GPL version 3, see the file "LICENSE" for details. # License: GNU GPL version 3, see the file "LICENSE" for details.
from datetime import datetime from datetime import datetime
from os import path
from anisotropy.core.config import DefaultConfig from anisotropy.core.config import DefaultConfig
from anisotropy.database import * from anisotropy.database import *
from anisotropy.salomepl.runner import SalomeRunner from anisotropy.shaping import Simple, BodyCentered, FaceCentered
import anisotropy.samples as samples from anisotropy.meshing import Mesh
from anisotropy.openfoam.presets import CreatePatchDict
from anisotropy.solving.onephase import OnePhaseFlow
class UltimateRunner(object): class UltimateRunner(object):
def __init__(self, config = None, exec_id = False): def __init__(self, config = None, exec_id = False):
@ -15,101 +18,134 @@ class UltimateRunner(object):
self.config = config or DefaultConfig() self.config = config or DefaultConfig()
self.database = Database(self.config["database"]) self.database = Database(self.config["database"])
self.datebase.setup() self.database.setup()
if exec_id: if exec_id:
self._exec_id = Execution(date = datetime.now()) self._exec_id = Execution(date = datetime.now())
self._exec_id.save() self._exec_id.save()
self.shape = None
self.mesh = None
self.flow = None
def casePath(self): def casePath(self):
case = self.config.cases[0] case = self.config.cases[0]
return os.path.join( return path.join(
self.config["build"], self.config["build"],
case["label"], case["label"],
"direction-{}".format(str(case["direction"]).replace(" ", "")), "direction-[{},{},{}]".format(*[ str(d) for d in case["direction"] ]),
"theta-{}".format(case["theta"]) "theta-{}".format(case["theta"])
) )
def computeMesh(self): def computeShape(self):
case = self.config.cases[0] case = self.config.cases[0]
runner = SalomeRunner() filename = "shape.step"
cliArgs = [
"computemesh",
case["label"],
case["direction"],
case["theta"],
path
]
out, err, returncode = runner.execute( match case["label"]:
env["CLI"], case "simple":
*cliArgs, self.shape = Simple(case["direction"])
timeout = self.config["salome_timeout"],
root = env["ROOT"],
logpath = self.casePath()
)
return out, err, returncode case "bodyCentered":
self.shape = BodyCentered(case["direction"])
case "faceCentered":
self.shape = FaceCentered(case["direction"])
def _computeMesh(self): self.shape.build()
"""Function for Salome self.shape.export(path.join(case, filename))
Resolution pipeline: def computeMesh(self):
cli(UR -> computeMesh) -> salomeRunner(salome -> cli) -> computemesh(UR -> _computeMesh) case = self.config.cases[0]
""" filename = "mesh.mesh"
# TODO: add logger configuration here
sample = samples.__dict__[..]
# Build a shape
shape = sample.geometry(..)
shape.build()
shape.export(..)
# Build a mesh
mesh = sample.mesh(shape)
mesh.build()
mesh.export(..)
# Fill database
self.mesh = Mesh(self.shape.shape)
self.mesh.build()
self.mesh.export(path.join(case, filename))
def computeFlow(self): def computeFlow(self):
case = self.config.cases[0]
flow = OnePhaseFlow()
sample = samples.__dict__[..] # initial 43 unnamed patches ->
# 6 named patches (inlet, outlet, wall, symetry0 - 3/5) ->
# 4 inGroups (inlet, outlet, wall, symetry)
createPatchDict = CreatePatchDict()
createPatchDict["patches"] = []
patches = {}
for n, patch in enumerate(self.shape.shape.faces):
name = patch.name
if patches.get(name):
patches[name].append(n)
else:
patches[name] = [n]
for name in patches.keys():
match name:
case "inlet":
patchGroup = "inlet"
patchType = "patch"
case "outlet":
patchGroup = "outlet"
patchType = "patch"
case "wall":
patchGroup = "wall"
patchType = "wall"
case _:
patchGroup = "symetry"
patchType = "symetryPlane"
createPatchDict["patches"].append({
"name": name,
"patchInfo": {
"type": patchType,
"inGroups": [patchGroup]
},
"constructFrom": "patches",
"patches": patches[name]
})
flow.append(createPatchDict)
# Build a flow # Build a flow
flow = sample.onephaseflow(..)
flow.build() flow.build()
def pipeline(self, stage: str = None): def pipeline(self, stage: str = None):
stage = stage or config["stage"] stage = stage or self.config["stage"]
match stage: match stage:
case "mesh" | "all": case "shape" | "all":
with self.database.atomic(): with self.database.atomic():
Shape.create(self._exec_id, **self.config.cases[0]) Shape.create(self._exec_id, **self.config.cases[0])
self.computeShape()
case "mesh" | "all":
with self.database.atomic():
Mesh.create(self._exec_id) Mesh.create(self._exec_id)
self.computeMesh(..) self.computeMesh()
case "flow" | "all": case "flow" | "all":
with self.database.atomic(): with self.database.atomic():
Flow.create(self._exec_id) Flow.create(self._exec_id)
self.computeFlow(..) self.computeFlow()
case "postProcess" | "all": case "postProcess" | "all":
self.postProcess(..) self.postProcess()
def parallel(queue: list, nprocs = None): def parallel(queue: list, nprocs = None):
nprocs = nprocs or config["nprocs"] nprocs = nprocs or self.config["nprocs"]
parallel(nprocs, [()] * len(queue), [ runner.pipeline for runner in queue ]) parallel(nprocs, [()] * len(queue), [ runner.pipeline for runner in queue ])

View File

@ -0,0 +1,4 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from .database import *

View File

@ -2,4 +2,4 @@
# This file is part of anisotropy. # This file is part of anisotropy.
# License: GNU GPL version 3, see the file "LICENSE" for details. # License: GNU GPL version 3, see the file "LICENSE" for details.
from .mesh import Mesh

View File

@ -5,6 +5,7 @@
from netgen.occ import OCCGeometry from netgen.occ import OCCGeometry
from netgen import meshing from netgen import meshing
import numpy import numpy
import os
class Mesh(object): class Mesh(object):
def __init__(self, shape): def __init__(self, shape):
@ -84,7 +85,7 @@ class Mesh(object):
def volumes(self) -> numpy.array: def volumes(self) -> numpy.array:
# TODO: check each polyhedron # TODO: check each polyhedron
tetras = numpy.array([ [ [ vertex for vertex in mesh[index] ] for index in element.vertices ] for element in mesh.Elements3D() ]) tetras = numpy.array([ [ [ vertex for vertex in mesh[index] ] for index in element.vertices ] for element in self.mesh.Elements3D() ])
volumes = numpy.array([ 1 / 6 * linalg.det(numpy.append(tetra.transpose(), numpy.array([[1, 1, 1, 1]]), axis = 0)) for tetra in tetras ]) volumes = numpy.array([ 1 / 6 * linalg.det(numpy.append(tetra.transpose(), numpy.array([[1, 1, 1, 1]]), axis = 0)) for tetra in tetras ])
return volumes return volumes

View File

@ -73,6 +73,7 @@ class Simple(Periodic):
yw = xl yw = xl
zh = height zh = height
# TODO: correct compasion for arrays
if self.direction == [1, 0, 0]: if self.direction == [1, 0, 0]:
vertices = numpy.array([ vertices = numpy.array([
(xl, 0, 0), (xl, 0, 0),

View File

@ -3,12 +3,12 @@
# License: GNU GPL version 3, see the file "LICENSE" for details. # License: GNU GPL version 3, see the file "LICENSE" for details.
import anisotropy.openfoam as openfoam import anisotropy.openfoam as openfoam
from openfoam.presets import ( from anisotropy.openfoam.presets import (
ControlDict, FvSchemes, FvSolution, ControlDict, FvSchemes, FvSolution,
TransportProperties, TurbulenceProperties, CreatePatchDict, TransportProperties, TurbulenceProperties, CreatePatchDict,
P, U P, U
) )
from openfoam.foamcase import FoamCase from anisotropy.openfoam.foamcase import FoamCase
class OnePhaseFlow(FoamCase): class OnePhaseFlow(FoamCase):
def __init__(self): def __init__(self):
@ -66,34 +66,7 @@ class OnePhaseFlow(FoamCase):
simulationType = "laminar" simulationType = "laminar"
) )
createPatchDict = CreatePatchDict() boundaries = [ "inlet", "outlet", "symetry", "wall"]
createPatchDict["patches"] = []
for patch in ["inlet", "outlet", "wall", "strips", *[ f"symetry{ n }" for n in range(6) ]]:
newPatch = dict(
name = patch,
patchInfo = dict(
type = "patch",
inGroups = [patch]
),
constructFrom = "patches",
patches = [ f"smesh_{ patch }" ]
)
match patch:
case "wall" | "strips":
newPatch["patchInfo"].update(
type = "wall",
inGroups = [ "wall" ]
)
case patch if patch.find("symetry") == 0:
newPatch["patchInfo"]["inGroups"] = [ "symetryPlane" ]
createPatchDict["patches"].append(newPatch)
boundaries = [ "inlet", "outlet", "symetryPlane", "wall", "strips" ]
p = P() p = P()
p["boundaryField"] = {} p["boundaryField"] = {}
u = U() u = U()
@ -131,28 +104,33 @@ class OnePhaseFlow(FoamCase):
) )
self.extend([ self.extend([
controlDict, fvSchemes, fvSolution, createPatchDict, controlDict,
transportProperties, turbulenceProperties, fvSchemes,
p, u fvSolution,
transportProperties,
turbulenceProperties,
p,
u
]) ])
def build(self): def build(self):
# TODO: configure working directory (FoamCase) # TODO: configure working directory (FoamCase)
self.write() with self:
self.write()
openfoam.ideasUnvToFoam("mesh.unv") openfoam.netgenNeutralToFoam("mesh.mesh")
openfoam.createPatch() openfoam.createPatch()
openfoam.checkMesh() openfoam.checkMesh()
openfoam.transformPoints((1e-5, 1e-5, 1e-5)) openfoam.transformPoints((1e-5, 1e-5, 1e-5))
openfoam.renumberMesh() openfoam.renumberMesh()
openfoam.potentialFoam() openfoam.potentialFoam()
self.read() self.read()
self.solution.U["boundaryField"]["outlet"] = dict( self.solution.U["boundaryField"]["outlet"] = dict(
type = "pressureInletVelocity", type = "pressureInletVelocity",
value = "uniform (0 0 0)" # * direction value = "uniform (0 0 0)" # * direction
) )
self.write() self.write()
openfoam.simpleFoam() openfoam.simpleFoam()

View File

@ -15,12 +15,13 @@ class TestShaping(unittest.TestCase):
if not NETGEN_MODULE: if not NETGEN_MODULE:
self.skipTest("Missing Netgen.") self.skipTest("Missing Netgen.")
from anisotropy import shaping else:
from anisotropy import shaping
self.shaping = shaping self.shaping = shaping
self.outputPath = os.path.join(os.path.abspath("."), "tests/test_shaping_output") self.outputPath = os.path.join(os.path.abspath("."), "tests/test_shaping_output")
os.makedirs(self.outputPath, exist_ok = True) os.makedirs(self.outputPath, exist_ok = True)
def test_simple(self): def test_simple(self):
simple100 = self.shaping.Simple(direction = [1, 0, 0], alpha = 0.01) simple100 = self.shaping.Simple(direction = [1, 0, 0], alpha = 0.01)