Mod: improved mesh class

Mod: mesh subclass for each sample
New: foamfile, reader and writer
This commit is contained in:
L-Nafaryus 2021-10-20 21:48:59 +05:00
parent 77647b3370
commit b45954d153
No known key found for this signature in database
GPG Key ID: C76D8DCD2727DBB7
14 changed files with 755 additions and 309 deletions

View File

@ -291,104 +291,39 @@ class Anisotropy(object):
setupLogger(logger, logging.INFO, self.env["LOG"])
p = self.params
###
# Shape
##
logger.info("Constructing shape ...")
geompy = salomepl.geometry.getGeom()
structure = dict(
simple = Simple,
bodyCentered = BodyCentered,
faceCentered = FaceCentered
sGeometry, sMesh = dict(
simple = (Simple, SimpleMesh),
bodyCentered = (BodyCentered, BodyCenteredMesh),
faceCentered = (FaceCentered, FaceCenteredMesh)
)[p["structure"]["type"]]
shapeGeometry = structure(**p["structure"])
shapeGeometry.build()
[length, surfaceArea, volume] = geompy.BasicProperties(shapeGeometry.shape, theTolerance = 1e-06)
# Shape
logger.info("Constructing shape ...")
geometry = sGeometry(**p["structure"])
geometry.build()
###
# Mesh
##
logger.info("Prepairing mesh ...")
mesh = sMesh(geometry)
mesh.build()
params = db.Mesh()
mesh = mesh.Mesh(shapeGeometry)
algo3d = mesh.algo3d(Netgen3D)
algo3d.apply(**params)
mesh = smesh.Mesh(shape)
algo3d = mesh.Tetrahedron(algo = smeshBuilder.NETGEN_3D)
algo2d = mesh.Triangle(algo = smeshBuilder.NETGEN_2D)
hypo2d = algo2d.MaxElementArea(0.197375)
algo1d = mesh.Segment()
hypo1d = algo1d.AutomaticLength(1)
algo2d = mesh.Triangle(algo = smeshBuilder.NETGEN_2D, geom = strips)
hypo2d = algo2d.LengthFromEdges()
algo1d = mesh.Segment(algo = smeshBuilder.COMPOSITE, geom = strips)
hypo1d = algo1d.AutomaticLength(0.633882)
hypo1d.SetFineness( 1 )
mp = p["mesh"]
lengths = [
geompy.BasicProperties(edge)[0] for edge in geompy.SubShapeAll(shapeGeometry.shape, geompy.ShapeType["EDGE"])
]
meanSize = sum(lengths) / len(lengths)
mp["maxSize"] = meanSize
mp["minSize"] = meanSize * 1e-1
mp["chordalError"] = mp["maxSize"] / 2
faces = []
for group in shapeGeometry.groups:
if group.GetName() in mp["facesToIgnore"]:
faces.append(group)
mesh = salomepl.mesh.Mesh(shapeGeometry.shape)
mesh.Tetrahedron(**mp)
if mp["viscousLayers"]:
mesh.ViscousLayers(**mp, faces = faces)
# Submesh
smp = p["submesh"]
for submesh in smp:
for group in shapeGeometry.groups:
if submesh["name"] == group.GetName():
subshape = group
submesh["maxSize"] = meanSize * 1e-1
submesh["minSize"] = meanSize * 1e-3
submesh["chordalError"] = submesh["minSize"] * 1e+1
mesh.Triangle(subshape, **submesh)
self.update()
logger.info("Computing mesh ...")
out, err, returncode = mesh.compute()
###
# Results
##
#p["meshresult"] = dict()
if not returncode:
mesh.removePyramids()
mesh.assignGroups()
mesh.createGroups()
casePath = self.getCasePath(path)
os.makedirs(casePath, exist_ok = True)
logger.info("Exporting mesh ...")
returncode, err = mesh.exportUNV(os.path.join(casePath, "mesh.unv"))
out, err, returncode = mesh.export(os.path.join(casePath, "mesh.unv"))
if returncode:
logger.error(err)
# NOTE: edit from here
meshStats = mesh.stats()
p["meshresult"].update(
surfaceArea = surfaceArea,

View File

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# This file is part of anisotropy.
# License: GNU GPL version 3, see the file "LICENSE" for details.
from anisotropy.openfoam.foamfile import FoamFile
class ControlDict(FoamFile):
def __init__(self):
ff = FoamFile(
"system/controlDict",
_location = "system"
)
self.header = ff.header
self.content = {
"application": "simpleFoam",
"startFrom": "startTime",
"startTime": 0,
"stopAt": "endTime",
"endTime": 2000,
"deltaT": 1,
"writeControl": "timeStep",
"writeInterval": 100,
"purgeWrite": 0,
"writeFormat": "ascii",
"writePrecision": 6,
"writeCompression": "off",
"timeFormat": "general",
"timePrecision": 6,
"runTimeModifiable": True
}

View File

@ -0,0 +1,91 @@
# -*- coding: utf-8 -*-
# This file is part of anisotropy.
# License: GNU GPL version 3, see the file "LICENSE" for details.
from anisotropy.openfoam.utils import version
from PyFoam.RunDictionary.ParsedParameterFile import ParsedParameterFile
from PyFoam.Basics.FoamFileGenerator import FoamFileGenerator
import os
class FoamFile(object):
def __init__(self,
filename,
_version = 2.0,
_format = "ascii",
_class = "dictionary",
_location = None,
_object = None
):
self.path = os.path.abspath(filename)
self.header = {
"version": _version,
"format": _format,
"class": _class,
"object": _object or os.path.split(filename)[1]
}
self.content = {}
if _location:
self.header["location"] = f'"{ _location }"'
def __getitem__(self, key):
return self.content[key]
def __setitem__(self, key, value):
self.content[key] = value
def __delitem__(self, key):
del self.content[key]
def __len__(self):
return len(self.content)
def __iter__(self):
for key in self.content:
yield key
def read(self):
ppf = ParsedParameterFile(self.path)
self.header = ppf.header
self.content = ppf.content
def _template(self, header, content):
limit = 78
desc = [
"/*--------------------------------*- C++ -*----------------------------------*\\",
"| ========= | |",
"| \\\\ / F ield | OpenFOAM: The Open Source CFD Toolbox |",
"| \\\\ / O peration |",
"| \\\\ / A nd | |",
"| \\\\/ M anipulation | |",
"\*---------------------------------------------------------------------------*/"
]
desc[3] += " Version: {}".format(version() or "missed")
desc[3] += " " * (limit - len(desc[3])) + "|"
afterheader = "// " + 37 * "* " + "//"
endfile = "// " + 73 * "*" + " //"
return "\n".join([*desc, header, afterheader, content, endfile])
def write(self):
header = FoamFileGenerator({}, header = self.header)
header = header.makeString()[ :-2]
header = header.replace("\n ", "\n" + 4 * " ")
content = FoamFileGenerator(self.content)
content = content.makeString()[ :-1]
content = content.replace("\n ", "\n" + 4 * " ").replace(" \t// " + 73 * "*" + " //", "")
content = content.replace(" /* empty */ ", "")
prepared = self._template(header, content)
os.makedirs(os.path.split(self.path)[0], exist_ok = True)
with open(self.path, "w") as io:
_ = io.write(prepared)

View File

@ -1,96 +1,84 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2012 |
| \\ / A nd | Website: www.openfoam.com |
| \\ / O peration | Version: missed |
| \\ / A nd | |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSolution;
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSolution;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
solvers
{
p
{
solver GAMG;
tolerance 1e-06;
relTol 0.1;
smoother GaussSeidel;
}
U
{
solver smoothSolver;
smoother GaussSeidel;
nSweeps 2;
tolerance 1e-08;
relTol 0.1;
}
/*Phi
{
solver GAMG;
smoother GaussSeidel;
tolerance 1e-08;
relTol 0.01;
}*/
Phi
{
solver GAMG;
smoother DIC;
cacheAgglomeration on;
agglomerator faceAreaPair;
nCellsInCoarsestLevel 10;
mergeLevels 1;
tolerance 1e-06;
relTol 0.01;
}
p
{
solver GAMG;
tolerance 1e-06;
relTol 0.1;
smoother GaussSeidel;
}
U
{
solver smoothSolver;
smoother GaussSeidel;
nSweeps 2;
tolerance 1e-08;
relTol 0.1;
} /*Phi
{
solver GAMG;
smoother GaussSeidel;
tolerance 1e-08;
relTol 0.01;
}*/
Phi
{
solver GAMG;
smoother DIC;
cacheAgglomeration yes;
agglomerator faceAreaPair;
nCellsInCoarsestLevel 10;
mergeLevels 1;
tolerance 1e-06;
relTol 0.01;
}
}
potentialFlow
{
nNonOrthogonalCorrectors 20;
PhiRefCell 0;
PhiRefPoint 0;
PhiRefValue 0;
Phi 0;
nNonOrthogonalCorrectors 20;
PhiRefCell 0;
PhiRefPoint 0;
PhiRefValue 0;
Phi 0;
}
cache
{
grad(U);
}
grad(p) /* empty */ ;
}
SIMPLE
{
nNonOrthogonalCorrectors 10;
residualControl
{
p 1e-5;
U 1e-5;
}
nNonOrthogonalCorrectors 10;
residualControl
{
p 1e-05;
U 1e-05;
}
}
relaxationFactors
{
fields
{
p 0.3;
}
equations
{
U 0.5;
}
fields
{
p 0.3;
}
equations
{
U 0.5;
}
}
// ************************************************************************* //
// ************************************************************************* //

View File

@ -7,7 +7,7 @@ import shutil
from .application import application
def version() -> str:
return os.environ["WM_PROJECT_VERSION"]
return os.environ.get("WM_PROJECT_VERSION")
def foamCleanCustom(case: str = None):

View File

@ -58,7 +58,7 @@ class StructureGeometry(object):
# Geometry module
if not GEOM_IMPORTED:
raise ImportError("Cannot find the salome modules.")
raise ImportError("Cannot find the salome geometry modules.")
else:
self.geo = geomBuilder.New()

View File

@ -3,124 +3,77 @@
# License: GNU GPL version 3, see the file "LICENSE" for details.
import logging
logger = logging.getLogger("anisotropy")
SMESH_IMPORTED = False
try:
import SMESH
from salome.smesh import smeshBuilder
except ImportError:
logger.debug("Trying to get SALOME mesh modules outside SALOME environment. Modules won't be imported.")
if globals().get("smeshBuilder"):
smesh = smeshBuilder.New()
else:
smesh = None
import enum
class Fineness(enum.Enum):
VeryCoarse = 0
Coarse = 1
Moderate = 2
Fine = 3
VeryFine = 4
Custom = 5
def getSmesh():
return smesh
def updateParams(old, new: dict):
old.SetMaxSize(new.get("maxSize", old.GetMaxSize()))
old.SetMinSize(new.get("minSize", old.GetMinSize()))
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", old.GetChordalErrorEnabled()))
old.SetChordalError(new.get("chordalError", old.GetChordalError()))
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()))
SMESH_IMPORTED = True
except:
pass
class Mesh(object):
def __init__(self, shape, name = ""):
self.name = name if name else shape.GetName()
self.mesh = smesh.Mesh(shape, self.name)
self.geom = shape
self.algo = None
self.params = None
self.viscousLayers = None
def __init__(self, geom):
# Mesh module
if not SMESH_IMPORTED:
raise ImportError("Cannot find the salome mesh modules.")
self.submeshes = []
else:
self.smesh = smeshBuilder.New()
self.smeshBuilder = smeshBuilder
# General attributes
self.geom = geom
self.mesh = self.smesh.Mesh(self.geom.shape, self.geom.name)
def Tetrahedron(self, **kwargs):
self.algo = self.mesh.Tetrahedron(algo = smeshBuilder.NETGEN_1D2D3D)
self.params = self.algo.Parameters()
self.params = updateParams(self.params, kwargs)
def _extrusionMethod(self, key: str):
return dict(
SURF_OFFSET_SMOOTH = smeshBuilder.SURF_OFFSET_SMOOTH,
FACE_OFFSET = smeshBuilder.FACE_OFFSET,
NODE_OFFSET = smeshBuilder.NODE_OFFSET,
).get(key, smeshBuilder.SURF_OFFSET_SMOOTH)
def ViscousLayers(self,
thickness = 1,
numberOfLayers = 1,
stretchFactor = 0,
faces = [],
isFacesToIgnore = True,
extrMethod = "SURF_OFFSET_SMOOTH",
**kwargs
):
self.viscousLayers = self.algo.ViscousLayers(
thickness,
numberOfLayers,
stretchFactor,
faces,
isFacesToIgnore,
self._extrusionMethod(extrMethod)
)
def Triangle(self, subshape, **kwargs):
submesh = Submesh(self.mesh, subshape)
submesh.algo = self.mesh.Triangle(algo = smeshBuilder.NETGEN_1D2D, geom = subshape)
submesh.mesh = submesh.algo.subm
submesh.params = submesh.algo.Parameters()
submesh.params = updateParams(submesh.params, kwargs)
self.submeshes.append(submesh)
def algo3d(self, algo, type = "tetrahedron"):
smeshAlgo = self.mesh.__dict__.get(type.capitalize())
self.meshAlgorithm3d = algo()
self.meshAlgorithm3d.initialize(smeshAlgo(algo = self.meshAlgorithm3d.key))
self.mesh.AddHypothesis(self.meshAlgorithm3d.hypo)
return self.meshAlgorithm3d
def algo2d(self, algo, type = "triangle"):
smeshAlgo = self.mesh.__dict__.get(type.capitalize())
self.meshAlgorithm2d = algo()
self.meshAlgorithm2d.initialize(smeshAlgo(algo = self.meshAlgorithm2d.key))
self.mesh.AddHypothesis(self.meshAlgorithm2d.hypo)
return self.meshAlgorithm2d
def algo1d(self, algo, type = "segment"):
smeshAlgo = self.mesh.__dict__.get(type.capitalize())
self.meshAlgorithm1d = algo()
self.meshAlgorithm1d.initialize(smeshAlgo(algo = self.meshAlgorithm1d.key))
self.mesh.AddHypothesis(self.meshAlgorithm1d.hypo)
return self.meshAlgorithm1d
def createGroups(self, prefix = None):
prefix = prefix or ""
for group in self.shape.groups:
name = group.GetName()
if name:
name = prefix + name
self.mesh.GroupOnGeom(group, name, SMESH.FACE)
def assignGroups(self, withPrefix = True):
prefix = "smesh_" if withPrefix else ""
for group in self.mesh.geompyD.GetGroups(self.geom):
if group.GetName():
self.mesh.GroupOnGeom(group, f"{ prefix }{ group.GetName() }", SMESH.FACE)
def compute(self):
"""Compute mesh.
"""
isDone = self.mesh.Compute()
returncode = int(not isDone)
out = ""
err = self.mesh.GetComputeErrors()
return "", err, returncode
returncode = int(not isDone)
return out, err, returncode
def stats(self):
return {
"elements": self.mesh.NbElements(),
@ -132,19 +85,6 @@ class Mesh(object):
"pyramids": self.mesh.NbPyramids()
}
def exportUNV(self, path):
returncode = 0
error = ""
try:
self.mesh.ExportUNV(path)
except Exception as e:
error = e.details.text
returncode = 1
return returncode, error
def removePyramids(self):
if self.mesh.NbPyramids() > 0:
pyramidCriterion = smesh.GetCriterion(
@ -159,15 +99,206 @@ class Mesh(object):
self.mesh.SplitVolumesIntoTetra(pyramidVolumes, smesh.Hex_5Tet)
self.mesh.RemoveGroup(pyramidGroup)
self.mesh.RenumberElements()
self.mesh.RenumberElements()
def export(
filename: str
):
"""Export a mesh.
Supported formats: unv.
:param filename:
Name of the file to store the given mesh in.
:return:
Output, error messages and returncode
"""
out, err, returncode = "", "", 0
ext = os.path.splitext(filename)[1][1: ]
try:
if ext == "unv":
self.mesh.ExportUNV(self.mesh, filename)
else:
raise NotImplementedError(f"{ ext } is not supported")
except NotImplementedError as e:
err = e
returncode = 1
except Exception as e:
err = e.details.text
returncode = 1
return out, err, returncode
class MeshAlgorithm(object):
pass
class Submesh(object):
def __init__(self, father, subshape, name = ""):
self.name = name if name else subshape.GetName()
self.mesh = None
self.geom = subshape
self.algo = None
self.params = None
class AlgorithmHypothesis(object):
pass
class Netgen3D(MeshAlgorithm):
"""
MaxElementVolume
Parameters
ViscousLayers
"""
def __init__(self, **kwargs):
self.key = smeshBuilder.NETGEN_3D
def initialize(self, algo, hypo): #thesises: list):
self.algo = algo
#self.hypo = self.algo.Parameters()
#for hypo in hypothesises:
self.hypo = self.__dict__[hypo.__name__]()
class ViscousLayers(AlgorithmHypothesis):
def __init__(self,
algo,
thickness = 1,
numberOfLayers = 1,
stretchFactor = 0,
faces = [],
isFacesToIgnore = True,
extrMethod = "SURF_OFFSET_SMOOTH",
**kwargs
):
extrusionMethod = dict(
SURF_OFFSET_SMOOTH = smeshBuilder.SURF_OFFSET_SMOOTH,
FACE_OFFSET = smeshBuilder.FACE_OFFSET,
NODE_OFFSET = smeshBuilder.NODE_OFFSET,
).get(extrMethod, smeshBuilder.SURF_OFFSET_SMOOTH)
self.hypo = self.algo.ViscousLayers(
thickness,
numberOfLayers,
stretchFactor,
faces,
isFacesToIgnore,
extrusionMethod
)
class Parameters(AlgorithmHypothesis):
def __init__(self, algo):
self.hypo = self.algo.Parameters()
@property
def minSize(self):
return self.hypo.GetMinSize()
@minSize.setter
def minSize(self, value):
self.hypo.SetMinSize(value)
@property
def maxSize(self):
return self.hypo.GetMaxSize()
@maxSize.setter
def maxSize(self, value):
self.hypo.SetMaxSize(value)
@property
def fineness(self):
return self.hypo.GetFineness()
@fineness.setter
def fineness(self, value):
self.hypo.SetFineness(value)
@property
def growthRate(self):
return self.hypo.GetGrowthRate()
@growthRate.setter
def growthRate(self, value):
self.hypo.SetGrowthRate(value)
@property
def nbSegPerEdge(self):
return self.hypo.GetNbSegPerEdge()
@nbSegPerEdge.setter
def nbSegPerEdge(self, value):
self.hypo.SetNbSegPerEdge(value)
@property
def nbSegPerRadius(self):
return self.hypo.GetNbSegPerRadius()
@nbSegPerRadius.setter
def nbSegPerRadius(self, value):
self.hypo.SetNbSegPerRadius(value)
@property
def chordalErrorEnabled(self):
return self.hypo.GetChordalErrorEnabled()
@chordalErrorEnabled.setter
def chordalErrorEnabled(self, value):
self.hypo.SetChordalErrorEnabled(value)
@property
def chordalError(self):
return self.hypo.GetChordalError()
@chordalError.setter
def chordalError(self, value):
self.hypo.SetChordalError(value)
@property
def secondOrder(self):
return self.hypo.GetSecondOrder()
@secondOrder.setter
def secondOrder(self, value):
self.hypo.SetSecondOrder(value)
@property
def optimize(self):
return self.hypo.GetOptimize()
@optimize.setter
def optimize(self, value):
self.hypo.SetOptimize(value)
@property
def quadAllowed(self):
return self.hypo.GetQuadAllowed()
@quadAllowed.setter
def quadAllowed(self, value):
self.hypo.SetQuadAllowed(value)
@property
def useSurfaceCurvature(self):
return self.hypo.GetUseSurfaceCurvature()
@useSurfaceCurvature.setter
def useSurfaceCurvature(self, value):
self.hypo.SetUseSurfaceCurvature(value)
@property
def fuseEdges(self):
return self.hypo.GetFuseEdges()
@fuseEdges.setter
def fuseEdges(self, value):
self.hypo.SetFuseEdges(value)
@property
def checkChartBoundary(self):
return self.hypo.GetCheckChartBoundary()
@checkChartBoundary.setter
def GetCheckChartBoundary(self, value):
self.hypo.SetCheckChartBoundary(value)
class MEFISTO(MeshAlgorithm):
pass

View File

@ -2,6 +2,6 @@
# This file is part of anisotropy.
# License: GNU GPL version 3, see the file "LICENSE" for details.
from anisotropy.samples.simple import Simple
from anisotropy.samples.bodyCentered import BodyCentered
from anisotropy.samples.faceCentered import FaceCentered
#from anisotropy.samples.simple import Simple
#from anisotropy.samples.bodyCentered import BodyCentered
#from anisotropy.samples.faceCentered import FaceCentered

View File

@ -226,3 +226,26 @@ class BodyCentered(StructureGeometry):
self.groups.append(self.geo.CutListOfGroups([groupAll], self.groups, theName = "wall"))
class BodyCenteredMesh(Mesh):
def build(self):
algo2d = self.mesh.Triangle(algo = self.smeshBuilder.NETGEN_1D2D)
hypo2d = algo2d.Parameters()
hypo2d.SetMaxSize(0.1)
hypo2d.SetMinSize(0.001)
hypo2d.SetFineness(5)
hypo2d.SetGrowthRate(0.3)
hypo2d.SetNbSegPerEdge(2)
hypo2d.SetNbSegPerRadius(3)
hypo2d.SetChordalErrorEnabled(True)
hypo2d.SetChordalError(0.05)
hypo2d.SetOptimize(True)
hypo2d.SetUseSurfaceCurvature(True)
algo3d = self.mesh.Tetrahedron(algo = self.smeshBuilder.NETGEN_3D)
#hypo3d = algo3d.Parameters()
#faces = [ group for group in self.geom.groups if group.GetName() in ["inlet", "outlet"] ]
#hypo3dVL = algo3d.ViscousLayers(...)

View File

@ -3,6 +3,7 @@
# License: GNU GPL version 3, see the file "LICENSE" for details.
from anisotropy.salomepl.geometry import StructureGeometry
from anisotropy.salomepl.mesh import Mesh
from numpy import pi, sqrt, fix
import logging
@ -228,3 +229,27 @@ class FaceCentered(StructureGeometry):
self.groups.append(self.createGroup(self.shape, shapeShell, "strips", self.groups + [grainsOrigin]))
self.groups.append(self.geo.CutListOfGroups([groupAll], self.groups, theName = "wall"))
class FaceCenteredMesh(Mesh):
def build(self):
algo2d = self.mesh.Triangle(algo = self.smeshBuilder.NETGEN_1D2D)
hypo2d = algo2d.Parameters()
hypo2d.SetMaxSize(0.1)
hypo2d.SetMinSize(0.001)
hypo2d.SetFineness(5)
hypo2d.SetGrowthRate(0.3)
hypo2d.SetNbSegPerEdge(2)
hypo2d.SetNbSegPerRadius(3)
hypo2d.SetChordalErrorEnabled(True)
hypo2d.SetChordalError(0.05)
hypo2d.SetOptimize(True)
hypo2d.SetUseSurfaceCurvature(True)
algo3d = self.mesh.Tetrahedron(algo = self.smeshBuilder.NETGEN_3D)
#hypo3d = algo3d.Parameters()
#faces = [ group for group in self.geom.groups if group.GetName() in ["inlet", "outlet"] ]
#hypo3dVL = algo3d.ViscousLayers(...)

View File

@ -3,6 +3,7 @@
# License: GNU GPL version 3, see the file "LICENSE" for details.
from anisotropy.salomepl.geometry import StructureGeometry
from anisotropy.salomepl.mesh import Mesh
from numpy import pi, sqrt, fix
import logging
@ -211,3 +212,36 @@ class Simple(StructureGeometry):
self.groups.append(self.createGroup(self.shape, shapeShell, "strips", self.groups + [grainsOrigin]))
self.groups.append(self.geo.CutListOfGroups([groupAll], self.groups, theName = "wall"))
class SimpleMesh(Mesh):
def build(self):
algo2d = self.mesh.Triangle(algo = self.smeshBuilder.NETGEN_1D2D)
hypo2d = algo2d.Parameters()
hypo2d.SetMaxSize(0.1)
hypo2d.SetMinSize(0.001)
hypo2d.SetFineness(5)
hypo2d.SetGrowthRate(0.3)
hypo2d.SetNbSegPerEdge(2)
hypo2d.SetNbSegPerRadius(3)
hypo2d.SetChordalErrorEnabled(True)
hypo2d.SetChordalError(0.05)
hypo2d.SetOptimize(True)
hypo2d.SetUseSurfaceCurvature(True)
algo3d = self.mesh.Tetrahedron(algo = self.smeshBuilder.NETGEN_3D)
#hypo3d = algo3d.Parameters()
#faces = [ group for group in self.geom.groups if group.GetName() in ["inlet", "outlet"] ]
#hypo3dVL = algo3d.ViscousLayers(...)
from anisotropy.openfoam.foamcase import ControlDict
class SimpleFlow(object): # FoamCase
def __init__(self):
controlDict = ControlDict()
controlDict["startFrom"] = "latestTime"
controlDict["endTime"] = 5000
controlDict["writeInterval"] = 100

View File

@ -1,35 +1,36 @@
# -*- coding: utf-8 -*-
# This file is part of anisotropy.
# License: GNU GPL version 3, see the file "LICENSE" for details.
class MeshAlgorithm(object):
import logging
SMESH_IMPORTED = False
try:
import SMESH
from salome.smesh import smeshBuilder
SMESH_IMPORTED = True
except:
pass
class Netgen3D(MeshAlgorithm):
def __init__(self, **kwargs):
self.key = smeshBuilder.NETGEN_3D
def initialize(self, algo):
self.algo = algo
self.hypo = self.algo.Parameters()
@property
def minSize(self):
return self.hypo.GetMinSize()
@minSize.setter
def minSize(self, value):
self.hypo.SetMinSize(value)
class MEFISTO(MeshAlgorithm):
pass
class Mesh(object):
def __init__(self, geom):
self.smesh = smeshBuilder.New()
# Mesh module
if not SMESH_IMPORTED:
raise ImportError("Cannot find the salome mesh modules.")
else:
self.smesh = smeshBuilder.New()
self.smeshBuilder = smeshBuilder
# General attributes
self.geom = geom
self.mesh = self.smesh.Mesh(self.geom.shape, self.geom.name)
def algo3d(self, algo: MeshAlgorithm, type = "tetrahedron"):
def algo3d(self, algo, type = "tetrahedron"):
smeshAlgo = self.mesh.__dict__.get(type.capitalize())
self.meshAlgorithm3d = algo()
self.meshAlgorithm3d.initialize(smeshAlgo(algo = self.meshAlgorithm3d.key))
@ -37,7 +38,7 @@ class Mesh(object):
return self.meshAlgorithm3d
def algo2d(self, algo: MeshAlgorithm, type = "triangle"):
def algo2d(self, algo, type = "triangle"):
smeshAlgo = self.mesh.__dict__.get(type.capitalize())
self.meshAlgorithm2d = algo()
self.meshAlgorithm2d.initialize(smeshAlgo(algo = self.meshAlgorithm2d.key))
@ -45,7 +46,7 @@ class Mesh(object):
return self.meshAlgorithm2d
def algo1d(self, algo: MeshAlgorithm, type = "segment"):
def algo1d(self, algo, type = "segment"):
smeshAlgo = self.mesh.__dict__.get(type.capitalize())
self.meshAlgorithm1d = algo()
self.meshAlgorithm1d.initialize(smeshAlgo(algo = self.meshAlgorithm1d.key))
@ -83,7 +84,23 @@ class Mesh(object):
"prisms": self.mesh.NbPrisms(),
"pyramids": self.mesh.NbPyramids()
}
def removePyramids(self):
if self.mesh.NbPyramids() > 0:
pyramidCriterion = smesh.GetCriterion(
SMESH.VOLUME,
SMESH.FT_ElemGeomType,
SMESH.FT_Undefined,
SMESH.Geom_PYRAMID
)
pyramidGroup = self.mesh.MakeGroupByCriterion("pyramids", pyramidCriterion)
pyramidVolumes = self.mesh.GetIDSource(pyramidGroup.GetIDs(), SMESH.VOLUME)
self.mesh.SplitVolumesIntoTetra(pyramidVolumes, smesh.Hex_5Tet)
self.mesh.RemoveGroup(pyramidGroup)
self.mesh.RenumberElements()
def export(
filename: str
):
@ -117,3 +134,171 @@ class Mesh(object):
return out, err, returncode
class MeshAlgorithm(object):
pass
class AlgorithmHypothesis(object):
pass
class Netgen3D(MeshAlgorithm):
"""
MaxElementVolume
Parameters
ViscousLayers
"""
def __init__(self, **kwargs):
self.key = smeshBuilder.NETGEN_3D
def initialize(self, algo, hypo): #thesises: list):
self.algo = algo
#self.hypo = self.algo.Parameters()
#for hypo in hypothesises:
self.hypo = self.__dict__[hypo.__name__]()
class ViscousLayers(AlgorithmHypothesis):
def __init__(self,
algo,
thickness = 1,
numberOfLayers = 1,
stretchFactor = 0,
faces = [],
isFacesToIgnore = True,
extrMethod = "SURF_OFFSET_SMOOTH",
**kwargs
):
extrusionMethod = dict(
SURF_OFFSET_SMOOTH = smeshBuilder.SURF_OFFSET_SMOOTH,
FACE_OFFSET = smeshBuilder.FACE_OFFSET,
NODE_OFFSET = smeshBuilder.NODE_OFFSET,
).get(extrMethod, smeshBuilder.SURF_OFFSET_SMOOTH)
self.hypo = self.algo.ViscousLayers(
thickness,
numberOfLayers,
stretchFactor,
faces,
isFacesToIgnore,
extrusionMethod
)
class Parameters(AlgorithmHypothesis):
def __init__(self, algo):
self.hypo = self.algo.Parameters()
@property
def minSize(self):
return self.hypo.GetMinSize()
@minSize.setter
def minSize(self, value):
self.hypo.SetMinSize(value)
@property
def maxSize(self):
return self.hypo.GetMaxSize()
@maxSize.setter
def maxSize(self, value):
self.hypo.SetMaxSize(value)
@property
def fineness(self):
return self.hypo.GetFineness()
@fineness.setter
def fineness(self, value):
self.hypo.SetFineness(value)
@property
def growthRate(self):
return self.hypo.GetGrowthRate()
@growthRate.setter
def growthRate(self, value):
self.hypo.SetGrowthRate(value)
@property
def nbSegPerEdge(self):
return self.hypo.GetNbSegPerEdge()
@nbSegPerEdge.setter
def nbSegPerEdge(self, value):
self.hypo.SetNbSegPerEdge(value)
@property
def nbSegPerRadius(self):
return self.hypo.GetNbSegPerRadius()
@nbSegPerRadius.setter
def nbSegPerRadius(self, value):
self.hypo.SetNbSegPerRadius(value)
@property
def chordalErrorEnabled(self):
return self.hypo.GetChordalErrorEnabled()
@chordalErrorEnabled.setter
def chordalErrorEnabled(self, value):
self.hypo.SetChordalErrorEnabled(value)
@property
def chordalError(self):
return self.hypo.GetChordalError()
@chordalError.setter
def chordalError(self, value):
self.hypo.SetChordalError(value)
@property
def secondOrder(self):
return self.hypo.GetSecondOrder()
@secondOrder.setter
def secondOrder(self, value):
self.hypo.SetSecondOrder(value)
@property
def optimize(self):
return self.hypo.GetOptimize()
@optimize.setter
def optimize(self, value):
self.hypo.SetOptimize(value)
@property
def quadAllowed(self):
return self.hypo.GetQuadAllowed()
@quadAllowed.setter
def quadAllowed(self, value):
self.hypo.SetQuadAllowed(value)
@property
def useSurfaceCurvature(self):
return self.hypo.GetUseSurfaceCurvature()
@useSurfaceCurvature.setter
def useSurfaceCurvature(self, value):
self.hypo.SetUseSurfaceCurvature(value)
@property
def fuseEdges(self):
return self.hypo.GetFuseEdges()
@fuseEdges.setter
def fuseEdges(self, value):
self.hypo.SetFuseEdges(value)
@property
def checkChartBoundary(self):
return self.hypo.GetCheckChartBoundary()
@checkChartBoundary.setter
def GetCheckChartBoundary(self, value):
self.hypo.SetCheckChartBoundary(value)
class MEFISTO(MeshAlgorithm):
pass

View File

@ -1,5 +1,8 @@
# -*- coding: utf-8 -*-
import sys; path = "/home/nafaryus/projects/anisotropy"; sys.path.extend([path, path + "/env/lib/python3.10/site-packages"])
from anisotropy.samples import Simple, FaceCentered, BodyCentered
s = Simple([1, 0, 0], 0.28, filletsEnabled = True)
from anisotropy.samples.faceCentered import FaceCentered, FaceCenteredMesh
fc = FaceCentered([1, 0, 0], 0.12, filletsEnabled = True)
fc.build()
fcm = FaceCenteredMesh(fc)
fcm.build()

View File

@ -7,3 +7,4 @@ pandas
Click
matplotlib
pyqt5
PyFoam