Mod: merge cae to pipeline
This commit is contained in:
parent
88f07abf4a
commit
c56504f120
@ -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
|
||||||
|
@ -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 ])
|
||||||
|
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from .database import *
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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),
|
||||||
|
@ -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()
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user