anisotropy/src/simpleCubic.py

421 lines
13 KiB
Python
Raw Normal View History

2021-03-02 16:29:43 +05:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import salome, GEOM, SMESH, SALOMEDS
from salome.geom import geomBuilder
from salome.smesh import smeshBuilder
import math
import os, sys
2021-03-03 16:24:47 +05:00
import logging
import time
from datetime import timedelta
2021-03-02 16:29:43 +05:00
class simpleCubic:
def __init__(self, name = None):
self.name = name if type(name) != None else "simpleCubic"
self.geometry = None
2021-03-05 00:02:47 +05:00
self.geometrybbox = None
2021-03-02 16:29:43 +05:00
self.mesh = None
self.boundary = None
2021-03-05 00:02:47 +05:00
self.rombus = None
self.rombusbbox = None
2021-03-02 22:22:54 +05:00
salome.salome_init()
2021-03-02 16:29:43 +05:00
def geometryCreate(self, alpha):
2021-03-03 13:00:28 +05:00
"""
Create the simple cubic geometry.
Parameters:
alpha (float): Sphere intersection parameter which used for cutting spheres from box.
Radius = R_0 / (1 - alpha)
Should be from 0.01 to 0.13
Returns:
Configured geometry.
"""
2021-03-02 16:29:43 +05:00
geompy = geomBuilder.New()
#
R_0 = 1
R = R_0 / (1 - alpha)
2021-03-05 00:02:47 +05:00
R_fillet = 0.05
2021-03-02 16:29:43 +05:00
# xyz axes
axes = [
geompy.MakeVectorDXDYDZ(1, 0, 0),
geompy.MakeVectorDXDYDZ(0, 1, 0),
geompy.MakeVectorDXDYDZ(0, 0, 1)
]
# Main box
box = geompy.MakeBoxDXDYDZ(2 * math.sqrt(2), 2 * math.sqrt(2), 2)
box = geompy.MakeRotation(box, axes[2], 45 * math.pi / 180.0)
box = geompy.MakeTranslation(box, 2, 0, 0)
vtx = [
geompy.MakeVertex(2, 0, 0),
geompy.MakeVertex(2, 2, 0),
geompy.MakeVertex(2, 2, 2)
]
line = geompy.MakeLineTwoPnt(vtx[1], vtx[2])
# Spheres for cutting
sphere = geompy.MakeSpherePntR(vtx[0], R)
sphere = geompy.MakeMultiTranslation2D(sphere, None, 2, 3, None, 2, 3)
sphere = geompy.MakeTranslation(sphere, -2, 0, 0)
sphere2 = geompy.MakeTranslation(sphere, 0, 0, 2)
2021-03-05 00:02:47 +05:00
sphere3 = geompy.MakeTranslation(sphere2, 0, 0, 2)
2021-03-02 16:29:43 +05:00
sphere = geompy.ExtractShapes(sphere, geompy.ShapeType["SOLID"], True)
sphere2 = geompy.ExtractShapes(sphere2, geompy.ShapeType["SOLID"], True)
2021-03-05 00:02:47 +05:00
sphere3 = geompy.ExtractShapes(sphere3, geompy.ShapeType["SOLID"], True)
sphere = geompy.MakeFuseList(sphere + sphere2 + sphere3, True, True)
2021-03-02 16:29:43 +05:00
sphere = geompy.MakeFilletAll(sphere, R_fillet)
self.geometry = geompy.MakeCutList(box, [sphere], True)
2021-03-05 00:02:47 +05:00
self.geometrybbox = box
2021-03-02 16:29:43 +05:00
geompy.addToStudy(self.geometry, self.name)
2021-03-05 00:02:47 +05:00
# Rombus
h = 2
sk = geompy.Sketcher3D()
sk.addPointsAbsolute(0, 0, h * 2)
sk.addPointsAbsolute(h, 0, h)
sk.addPointsAbsolute(h, h, 0)
sk.addPointsAbsolute(0, h, h)
sk.addPointsAbsolute(0, 0, h * 2)
a3D_Sketcher_1 = sk.wire()
Face_1 = geompy.MakeFaceWires([a3D_Sketcher_1], 1)
Vector_1 = geompy.MakeVectorDXDYDZ(h, h, 0)
rombus = geompy.MakePrismVecH(Face_1, Vector_1, 2 * math.sqrt(2))
geompy.addToStudy(rombus, "romb")
self.rombus = geompy.MakeCutList(rombus, [sphere], True)
self.rombusbbox = rombus
2021-03-05 15:57:14 +05:00
Operators = ["FixShape"]
Parameters = ["FixShape.Tolerance3d"]
Values = ["1e-7"]
PS = geompy.ProcessShape(self.rombusbbox, Operators, Parameters, Values)
self.rombusbbox = PS
2021-03-05 00:02:47 +05:00
geompy.addToStudy(self.rombus, "rombus")
2021-03-02 16:29:43 +05:00
2021-03-03 13:00:28 +05:00
return self.geometry
2021-03-02 16:29:43 +05:00
def boundaryCreate(self, direction):
2021-03-03 13:00:28 +05:00
"""
Create the boundary faces from the geometry.
Parameters:
direction (str): Direction of the flow.
'001' for the flow with normal vector (0, 0, -1) to face.
'100' for the flow with normal vector (-1, 0, 0) to face.
Returns:
boundary (dict):
{
"inlet": <GEOM._objref_GEOM_Object>,
"outlet": <GEOM._objref_GEOM_Object>,
"symetryPlane": <GEOM._objref_GEOM_Object>,
"wall": <GEOM._objref_GEOM_Object>
}
"""
#
# _____ z |
# //////| | | flow
# ////// | |___y f
# | | / /
# |____|/ /x direction [0, 0, 1]
2021-03-02 16:29:43 +05:00
#
2021-03-03 13:00:28 +05:00
# _____ z f
# / /| | / flow
# /____/ | |___y /
# |||||| / /
# ||||||/ /x direction [1, 0, 0]
2021-03-02 16:29:43 +05:00
#
2021-03-03 13:00:28 +05:00
geompy = geomBuilder.New()
2021-03-02 16:29:43 +05:00
rot = [0, 0, 45]
2021-03-05 00:02:47 +05:00
buffergeometry = self.geometry
2021-03-02 16:29:43 +05:00
2021-03-02 22:22:54 +05:00
if direction == "001":
2021-03-05 00:02:47 +05:00
center = geompy.MakeVertex(2, 2, 1)
2021-03-02 16:29:43 +05:00
norm = geompy.MakeVector(center,
geompy.MakeVertexWithRef(center, 0, 0, 1))
2021-03-05 00:02:47 +05:00
2021-03-02 22:22:54 +05:00
vstep = 1
hstep = math.sqrt(2)
2021-03-02 16:29:43 +05:00
2021-03-02 22:22:54 +05:00
elif direction == "100":
2021-03-05 00:02:47 +05:00
center = geompy.MakeVertex(2, 2, 1)
2021-03-02 16:29:43 +05:00
norm = geompy.MakeVector(center,
2021-03-03 13:00:28 +05:00
geompy.MakeVertexWithRef(center,
2021-03-05 00:02:47 +05:00
-math.cos((90 + rot[2]) * math.pi / 180.0),
math.sin((90 + rot[2]) * math.pi / 180.0), 0))
2021-03-02 22:22:54 +05:00
vstep = math.sqrt(2)
hstep = 1
2021-03-05 00:02:47 +05:00
elif direction == "111":
center = geompy.MakeVertex(2, 2, 2)
norm = geompy.MakeVector(center,
geompy.MakeVertexWithRef(center,
-math.cos((90 + rot[2]) * math.pi / 180.0),
math.sin((90 + rot[2]) * math.pi / 180.0), math.sqrt(2) / 2))
vstep = math.sqrt(2)
hstep = 1
2021-03-02 16:29:43 +05:00
2021-03-05 00:02:47 +05:00
geompy.addToStudy(norm, "normalvector")
2021-03-02 16:29:43 +05:00
def createGroup(shape, name):
2021-03-05 00:02:47 +05:00
self.geometry = self.rombus
2021-03-02 16:29:43 +05:00
group = geompy.CreateGroup(self.geometry,
geompy.ShapeType["FACE"], name)
gip = geompy.GetInPlace(self.geometry, shape, True)
faces = geompy.SubShapeAll(gip, geompy.ShapeType["FACE"])
geompy.UnionList(group, faces)
return group
# xyz axes
2021-03-05 00:02:47 +05:00
#axes = [
# geompy.MakeVectorDXDYDZ(1, 0, 0),
# geompy.MakeVectorDXDYDZ(0, 1, 0),
# geompy.MakeVectorDXDYDZ(0, 0, 1)
#]
2021-03-02 16:29:43 +05:00
2021-03-02 22:22:54 +05:00
# Bounding box
2021-03-05 00:02:47 +05:00
#box = geompy.MakeBoxDXDYDZ(2 * math.sqrt(2), 2 * math.sqrt(2), 2)
#box = geompy.MakeRotation(box, axes[2], 45 * math.pi / 180.0)
#box = geompy.MakeTranslation(box, 2, 0, 0)
if direction == "111":
box = self.rombusbbox
else:
box = self.geometrybbox
2021-03-03 13:00:28 +05:00
planes = geompy.ExtractShapes(box, geompy.ShapeType["FACE"], True)
2021-03-02 16:29:43 +05:00
2021-03-02 22:22:54 +05:00
vplanes = []
hplanes = []
2021-03-05 00:02:47 +05:00
n = 0
2021-03-02 16:29:43 +05:00
for plane in planes:
2021-03-02 22:22:54 +05:00
planeNorm = geompy.GetNormal(plane)
2021-03-05 00:02:47 +05:00
n += 1
geompy.addToStudy(planeNorm, "normalplane-{}".format(n))
2021-03-05 15:57:14 +05:00
angle = abs(geompy.GetAngle(planeNorm, norm))
2021-03-05 00:02:47 +05:00
logging.info("angle = {}".format(angle))
2021-03-02 22:22:54 +05:00
if angle == 0 or angle == 180:
vplanes.append(plane)
else:
hplanes.append(plane)
2021-03-05 00:02:47 +05:00
if salome.sg.hasDesktop():
salome.sg.updateObjBrowser()
logging.info(len(vplanes))
logging.info(len(hplanes))
2021-03-02 22:22:54 +05:00
if direction == "001":
2021-03-03 13:00:28 +05:00
z1 = geompy.GetPosition(vplanes[0])[3]
z2 = geompy.GetPosition(vplanes[1])[3]
if z1 > z2:
inletplane = vplanes[0]
outletplane = vplanes[1]
2021-03-02 22:22:54 +05:00
else:
2021-03-03 13:00:28 +05:00
inletplane = vplanes[1]
outletplane = vplanes[0]
2021-03-02 22:22:54 +05:00
2021-03-05 00:02:47 +05:00
elif direction == "100" or direction == "111":
2021-03-03 13:00:28 +05:00
x1 = geompy.GetPosition(vplanes[0])[1]
x2 = geompy.GetPosition(vplanes[1])[1]
2021-03-05 00:02:47 +05:00
logging.info("x1 = {}, x2 = {}".format(x1, x2))
2021-03-03 13:00:28 +05:00
if x1 > x2:
inletplane = vplanes[0]
outletplane = vplanes[1]
2021-03-02 22:22:54 +05:00
else:
2021-03-03 13:00:28 +05:00
inletplane = vplanes[1]
outletplane = vplanes[0]
2021-03-02 22:22:54 +05:00
# inlet and outlet
common1 = geompy.MakeCommonList([self.geometry, inletplane], True)
inlet = createGroup(common1, "inlet")
2021-03-02 16:29:43 +05:00
2021-03-02 22:22:54 +05:00
common2 = geompy.MakeCommonList([self.geometry, outletplane], True)
outlet = createGroup(common2, "outlet")
# symetryPlane(s)
symetryPlane = geompy.CreateGroup(self.geometry, geompy.ShapeType["FACE"], "symetryPlane")
2021-03-02 16:29:43 +05:00
2021-03-02 22:22:54 +05:00
for plane in hplanes:
common3 = geompy.MakeCommonList([self.geometry, plane], True)
gip = geompy.GetInPlace(self.geometry, common3, True)
faces = geompy.SubShapeAll(gip, geompy.ShapeType["FACE"])
geompy.UnionList(symetryPlane, faces)
2021-03-02 16:29:43 +05:00
2021-03-02 22:22:54 +05:00
# wall
allgroup = geompy.CreateGroup(self.geometry, geompy.ShapeType["FACE"])
2021-03-02 16:29:43 +05:00
faces = geompy.SubShapeAllIDs(self.geometry, geompy.ShapeType["FACE"])
2021-03-02 22:22:54 +05:00
geompy.UnionIDs(allgroup, faces)
wall = geompy.CutListOfGroups([allgroup], [inlet, outlet, symetryPlane], "wall")
2021-03-02 16:29:43 +05:00
self.boundary = {
"inlet": inlet,
"outlet": outlet,
"symetryPlane": symetryPlane,
"wall": wall
}
return self.boundary
2021-03-03 13:00:28 +05:00
def meshCreate(self, fineness, viscousLayers=None):
"""
Creates a mesh from a geometry.
Parameters:
fineness (int): Fineness of mesh.
0 - Very coarse,
1 - Coarse,
2 - Moderate,
3 - Fine,
4 - Very fine.
viscousLayers (dict or None): Defines viscous layers for mesh.
By default, inlets and outlets specified without layers.
{
"thickness": float,
"number": int,
"stretch": float
}
Returns:
Configured instance of class <SMESH.SMESH_Mesh>, containig the parameters and boundary groups.
"""
2021-03-02 16:29:43 +05:00
smesh = smeshBuilder.New()
2021-03-03 13:00:28 +05:00
mesh = smesh.Mesh(self.geometry)
2021-03-02 16:29:43 +05:00
netgen = mesh.Tetrahedron(algo=smeshBuilder.NETGEN_1D2D3D)
param = netgen.Parameters()
param.SetSecondOrder( 0 )
param.SetOptimize( 1 )
param.SetChordalError( -1 )
param.SetChordalErrorEnabled( 0 )
param.SetUseSurfaceCurvature( 1 )
param.SetFuseEdges( 1 )
param.SetCheckChartBoundary( 0 )
param.SetMinSize( 0.01 )
param.SetMaxSize( 0.1 )
2021-03-03 13:00:28 +05:00
param.SetFineness(fineness)
2021-03-02 16:29:43 +05:00
#param.SetGrowthRate( 0.1 )
#param.SetNbSegPerEdge( 5 )
#param.SetNbSegPerRadius( 10 )
param.SetQuadAllowed( 0 )
2021-03-03 13:00:28 +05:00
if not viscousLayers is None:
vlayer = netgen.ViscousLayers(viscousLayers["thickness"],
viscousLayers["number"],
viscousLayers["stretch"],
[self.boundary["inlet"], self.boundary["outlet"]],
1, smeshBuilder.NODE_OFFSET)
for name, boundary in self.boundary.items():
mesh.GroupOnGeom(boundary, name, SMESH.FACE)
2021-03-02 16:29:43 +05:00
self.mesh = mesh
return self.mesh
def meshCompute(self):
2021-03-03 13:00:28 +05:00
"""Compute the mesh."""
2021-03-02 16:29:43 +05:00
status = self.mesh.Compute()
if status:
2021-03-03 22:16:36 +05:00
logging.info("Mesh succesfully computed.")
2021-03-02 16:29:43 +05:00
else:
2021-03-03 22:16:36 +05:00
logging.warning("Mesh is not computed.")
2021-03-02 16:29:43 +05:00
def meshExport(self, path):
2021-03-03 13:00:28 +05:00
"""
Export the mesh in a file in UNV format.
Parameters:
path (string): full path to the expected directory.
"""
2021-03-02 16:29:43 +05:00
exportpath = os.path.join(path, "{}.unv".format(self.name))
try:
self.mesh.ExportUNV(exportpath)
except:
2021-03-03 22:16:36 +05:00
logging.error("Cannot export mesh to '{}'".format(exportpath))
2021-03-02 16:29:43 +05:00
if __name__ == "__main__":
2021-03-03 16:24:47 +05:00
# Arguments
2021-03-02 16:29:43 +05:00
buildpath = str(sys.argv[1])
alpha = float(sys.argv[2])
direction = str(sys.argv[3])
2021-03-03 16:24:47 +05:00
name = "simpleCubic-{}-{}".format(direction, alpha)
# Logger
2021-03-03 22:16:36 +05:00
logging.basicConfig(
level=logging.INFO,
format="%(levelname)s: %(message)s",
handlers = [
logging.StreamHandler(),
2021-03-05 00:02:47 +05:00
logging.FileHandler(os.path.join(buildpath, "{}.log".format(name)))
2021-03-03 22:16:36 +05:00
])
2021-03-03 16:24:47 +05:00
start_time = time.monotonic()
# Simple cubic
sc = simpleCubic(name)
logging.info("Creating the geometry ...")
2021-03-02 16:29:43 +05:00
sc.geometryCreate(alpha)
2021-03-03 16:24:47 +05:00
logging.info("Extracting boundaries ...")
2021-03-02 16:29:43 +05:00
sc.boundaryCreate(direction)
2021-03-03 16:24:47 +05:00
logging.info("Creating the mesh ...")
2021-03-03 13:00:28 +05:00
sc.meshCreate(2, {
"thickness": 0.02,
"number": 2,
"stretch": 1.1
})
sc.meshCompute()
2021-03-03 16:24:47 +05:00
logging.info("Exporting the mesh ...")
sc.meshExport(buildpath)
end_time = time.monotonic()
logging.info("Elapsed time: {}".format(timedelta(seconds=end_time - start_time)))
logging.info("Done.")
2021-03-02 16:29:43 +05:00
if salome.sg.hasDesktop():
salome.sg.updateObjBrowser()