Fem: Netgen meshing parameters improvements
This commit is contained in:
@@ -837,6 +837,7 @@ class _MeshNetgenFromShape(CommandManager):
|
||||
)
|
||||
)
|
||||
FreeCADGui.doCommand("FreeCAD.ActiveDocument.ActiveObject.Fineness = 'Moderate'")
|
||||
FreeCADGui.doCommand("FreeCAD.ActiveDocument.ActiveObject.EndStep = 'OptimizeVolume'")
|
||||
# Netgen mesh object could be added without an active analysis
|
||||
# but if there is an active analysis move it in there
|
||||
import FemGui
|
||||
|
||||
@@ -35,7 +35,8 @@ import FreeCAD
|
||||
import Fem
|
||||
|
||||
try:
|
||||
from netgen import occ, config as ng_config
|
||||
from netgen import occ, meshing, config as ng_config
|
||||
import pyngcore as ngcore
|
||||
except ModuleNotFoundError:
|
||||
FreeCAD.Console.PrintError("To use FemMesh Netgen objects, install the Netgen Python bindings")
|
||||
|
||||
@@ -64,6 +65,15 @@ class NetgenTools:
|
||||
15: [0, 1, 2, 3, 4, 5, 6, 8, 7, 12, 14, 13, 9, 10, 11, 15, 16, 17, 18, 19], # penta15
|
||||
}
|
||||
|
||||
meshing_step = {
|
||||
"AnalizeGeometry": 1, # MESHCONST_ANALYSE
|
||||
"MeshEdges": 2, # MESHCONST_MESHEDGES
|
||||
"MeshSurface": 3, # MESHCONST_MESHSURFACE
|
||||
"OptimizeSurface": 4, # MESHCONST_OPTSURFACE
|
||||
"MeshVolume": 5, # MESHCONST_MESHVOLUME
|
||||
"OptimizeVolume": 6, # MESHCONST_OPTVOLUME
|
||||
}
|
||||
|
||||
name = "Netgen"
|
||||
|
||||
def __init__(self, obj):
|
||||
@@ -97,7 +107,6 @@ NetgenTools.run_netgen(**{params})
|
||||
"brep_file": self.brep_file,
|
||||
"threads": self.obj.Threads,
|
||||
"heal": self.obj.HealShape,
|
||||
"fineness": self.obj.Fineness,
|
||||
"params": self.get_meshing_parameters(),
|
||||
"second_order": self.obj.SecondOrder,
|
||||
"result_file": self.result_file,
|
||||
@@ -118,30 +127,15 @@ NetgenTools.run_netgen(**{params})
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def run_netgen(brep_file, threads, heal, fineness, params, second_order, result_file):
|
||||
import pyngcore as ngcore
|
||||
from netgen import meshing
|
||||
def run_netgen(brep_file, threads, heal, params, second_order, result_file):
|
||||
|
||||
geom = occ.OCCGeometry(brep_file)
|
||||
ngcore.SetNumThreads(threads)
|
||||
|
||||
if fineness == "UserDefined":
|
||||
mp = meshing.MeshingParameters(**params)
|
||||
elif fineness == "VeryCoarse":
|
||||
mp = meshing.meshsize.very_coarse
|
||||
elif fineness == "Coarse":
|
||||
mp = meshing.meshsize.coarse
|
||||
elif fineness == "Moderate":
|
||||
mp = meshing.meshsize.moderate
|
||||
elif fineness == "Fine":
|
||||
mp = meshing.meshsize.fine
|
||||
elif fineness == "VeryFine":
|
||||
mp = meshing.meshsize.very_fine
|
||||
|
||||
with ngcore.TaskManager():
|
||||
if heal:
|
||||
geom.Heal()
|
||||
mesh = geom.GenerateMesh(mp=mp)
|
||||
mesh = geom.GenerateMesh(mp=meshing.MeshingParameters(**params))
|
||||
|
||||
if second_order:
|
||||
mesh.SecondOrder()
|
||||
@@ -256,8 +250,8 @@ NetgenTools.run_netgen(**{params})
|
||||
"segmentsperedge": self.obj.SegmentsPerEdge,
|
||||
"elsizeweight": self.obj.ElementSizeWeight,
|
||||
"parthread": self.obj.ParallelMeshing,
|
||||
"perfstepsstart": self.obj.StartStep,
|
||||
"perfstepsend": self.obj.EndStep,
|
||||
"perfstepsstart": NetgenTools.meshing_step[self.obj.StartStep],
|
||||
"perfstepsend": NetgenTools.meshing_step[self.obj.EndStep],
|
||||
"giveuptol2d": self.obj.GiveUpTolerance2d,
|
||||
"giveuptol": self.obj.GiveUpTolerance,
|
||||
"giveuptolopenquads": self.obj.GiveUpToleranceOpenQuads,
|
||||
@@ -280,6 +274,42 @@ NetgenTools.run_netgen(**{params})
|
||||
"closeedgefac": self.obj.CloseEdgeFactor,
|
||||
}
|
||||
|
||||
# set specific parameters by fineness
|
||||
if self.obj.Fineness == "VeryCoarse":
|
||||
params["curvaturesafety"] = 1
|
||||
params["segmentsperedge"] = 0.3
|
||||
params["grading"] = 0.7
|
||||
params["closeedgefac"] = 0.5
|
||||
params["optsteps3d"] = 5
|
||||
|
||||
elif self.obj.Fineness == "Coarse":
|
||||
params["curvaturesafety"] = 1.5
|
||||
params["segmentsperedge"] = 0.5
|
||||
params["grading"] = 0.5
|
||||
params["closeedgefac"] = 1
|
||||
params["optsteps3d"] = 5
|
||||
|
||||
elif self.obj.Fineness == "Moderate":
|
||||
params["curvaturesafety"] = 2
|
||||
params["segmentsperedge"] = 1
|
||||
params["grading"] = 0.3
|
||||
params["closeedgefac"] = 2
|
||||
params["optsteps3d"] = 5
|
||||
|
||||
elif self.obj.Fineness == "Fine":
|
||||
params["curvaturesafety"] = 3
|
||||
params["segmentsperedge"] = 2
|
||||
params["grading"] = 0.2
|
||||
params["closeedgefac"] = 3.5
|
||||
params["optsteps3d"] = 5
|
||||
|
||||
elif self.obj.Fineness == "VeryFine":
|
||||
params["curvaturesafety"] = 5
|
||||
params["segmentsperedge"] = 3
|
||||
params["grading"] = 0.1
|
||||
params["closeedgefac"] = 5
|
||||
params["optsteps3d"] = 5
|
||||
|
||||
return params
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -65,15 +65,6 @@ class MeshNetgen(base_fempythonobject.BaseFemPythonObject):
|
||||
value="cmdDmustm",
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="Fineness",
|
||||
group="Mesh Parameters",
|
||||
doc="Fineness",
|
||||
value=["VeryCoarse", "Coarse", "Moderate", "Fine", "VeryFine", "UserDefined"],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyInteger",
|
||||
@@ -284,22 +275,33 @@ class MeshNetgen(base_fempythonobject.BaseFemPythonObject):
|
||||
value=0.2,
|
||||
)
|
||||
)
|
||||
|
||||
# Netgen meshing steps
|
||||
meshing_step = [
|
||||
"AnalizeGeometry",
|
||||
"MeshEdges",
|
||||
"MeshSurface",
|
||||
"OptimizeSurface",
|
||||
"MeshVolume",
|
||||
"OptimizeVolume",
|
||||
]
|
||||
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyInteger",
|
||||
type="App::PropertyEnumeration",
|
||||
name="StartStep",
|
||||
group="Mesh Parameters",
|
||||
doc="Start at step",
|
||||
value=0,
|
||||
doc="First step",
|
||||
value=meshing_step,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyInteger",
|
||||
type="App::PropertyEnumeration",
|
||||
name="EndStep",
|
||||
group="Mesh Parameters",
|
||||
doc="EndStep",
|
||||
value=6,
|
||||
doc="Last step",
|
||||
value=meshing_step,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
@@ -482,5 +484,95 @@ class MeshNetgen(base_fempythonobject.BaseFemPythonObject):
|
||||
value=False,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="Fineness",
|
||||
group="Mesh Parameters",
|
||||
doc="Mesh granularity.\n"
|
||||
+ "If differs from UserDefined, uses specific values\n"
|
||||
+ "for CurvatureSafety, SegmentsPerEdge, GrowthRate,\n"
|
||||
+ "CloseEdgeFactor and OptimizationSteps3d",
|
||||
value=["VeryCoarse", "Coarse", "Moderate", "Fine", "VeryFine", "UserDefined"],
|
||||
)
|
||||
)
|
||||
|
||||
return prop
|
||||
|
||||
def onChanged(self, obj, prop):
|
||||
if prop == "Fineness":
|
||||
if obj.Fineness != "UserDefined":
|
||||
p = self.get_predef_fineness_params(obj.Fineness)
|
||||
obj.CurvatureSafety = p["curvaturesafety"]
|
||||
obj.SegmentsPerEdge = p["segmentsperedge"]
|
||||
obj.GrowthRate = p["grading"]
|
||||
obj.CloseEdgeFactor = p["closeedgefac"]
|
||||
obj.OptimizationSteps3d = p["optsteps3d"]
|
||||
|
||||
obj.setPropertyStatus("CurvatureSafety", "ReadOnly")
|
||||
obj.setPropertyStatus("SegmentsPerEdge", "ReadOnly")
|
||||
obj.setPropertyStatus("GrowthRate", "ReadOnly")
|
||||
obj.setPropertyStatus("CloseEdgeFactor", "ReadOnly")
|
||||
obj.setPropertyStatus("OptimizationSteps3d", "ReadOnly")
|
||||
else:
|
||||
obj.setPropertyStatus("CurvatureSafety", "-ReadOnly")
|
||||
obj.setPropertyStatus("SegmentsPerEdge", "-ReadOnly")
|
||||
obj.setPropertyStatus("GrowthRate", "-ReadOnly")
|
||||
obj.setPropertyStatus("CloseEdgeFactor", "-ReadOnly")
|
||||
obj.setPropertyStatus("OptimizationSteps3d", "-ReadOnly")
|
||||
|
||||
def onDocumentRestored(self, obj):
|
||||
# update old project with new properties
|
||||
for prop in self._get_properties():
|
||||
try:
|
||||
obj.getPropertyByName(prop.name)
|
||||
except Base.PropertyError:
|
||||
prop.add_to_object(obj)
|
||||
|
||||
# for StartStep and EndStep set enumeration index from old integer value
|
||||
if prop.name == "StartStep" or prop.name == "EndStep":
|
||||
prop.handle_change_type(
|
||||
obj, "App::PropertyInteger", lambda x: 0 if x <= 1 else 5 if x >= 6 else x - 1
|
||||
)
|
||||
|
||||
def get_predef_fineness_params(self, fineness):
|
||||
# set specific parameters by fineness
|
||||
params = {}
|
||||
if fineness == "VeryCoarse":
|
||||
params["curvaturesafety"] = 1
|
||||
params["segmentsperedge"] = 0.3
|
||||
params["grading"] = 0.7
|
||||
params["closeedgefac"] = 0.5
|
||||
params["optsteps3d"] = 5
|
||||
elif fineness == "Coarse":
|
||||
params["curvaturesafety"] = 1.5
|
||||
params["segmentsperedge"] = 0.5
|
||||
params["grading"] = 0.5
|
||||
params["closeedgefac"] = 1
|
||||
params["optsteps3d"] = 5
|
||||
elif fineness == "Moderate":
|
||||
params["curvaturesafety"] = 2
|
||||
params["segmentsperedge"] = 1
|
||||
params["grading"] = 0.3
|
||||
params["closeedgefac"] = 2
|
||||
params["optsteps3d"] = 5
|
||||
elif fineness == "Fine":
|
||||
params["curvaturesafety"] = 3
|
||||
params["segmentsperedge"] = 2
|
||||
params["grading"] = 0.2
|
||||
params["closeedgefac"] = 3.5
|
||||
params["optsteps3d"] = 5
|
||||
elif fineness == "VeryFine":
|
||||
params["curvaturesafety"] = 5
|
||||
params["segmentsperedge"] = 3
|
||||
params["grading"] = 0.1
|
||||
params["closeedgefac"] = 5
|
||||
params["optsteps3d"] = 5
|
||||
elif fineness == "UserDefined":
|
||||
params["curvaturesafety"] = 2
|
||||
params["segmentsperedge"] = 2
|
||||
params["grading"] = 0.3
|
||||
params["closeedgefac"] = 2
|
||||
params["optsteps3d"] = 3
|
||||
|
||||
return params
|
||||
|
||||
@@ -102,6 +102,7 @@ class _TaskPanel(base_femmeshtaskpanel._BaseMeshTaskPanel):
|
||||
self.curvature_safety = self.obj.CurvatureSafety
|
||||
self.seg_per_edge = self.obj.SegmentsPerEdge
|
||||
self.second_order = self.obj.SecondOrder
|
||||
self.user_p = self.get_user_fineness_params(self.obj)
|
||||
|
||||
def set_mesh_params(self):
|
||||
self.obj.MinSize = self.min_size
|
||||
@@ -155,18 +156,41 @@ class _TaskPanel(base_femmeshtaskpanel._BaseMeshTaskPanel):
|
||||
|
||||
def fineness_changed(self, index):
|
||||
self.fineness = self.fineness_enum[index]
|
||||
self.obj.Fineness = self.fineness
|
||||
if self.fineness == "UserDefined":
|
||||
self.form.qsb_min_size.setEnabled(True)
|
||||
self.form.qsb_max_size.setEnabled(True)
|
||||
self.form.dsb_seg_per_edge.setEnabled(True)
|
||||
self.form.dsb_growth_rate.setEnabled(True)
|
||||
self.form.dsb_curvature_safety.setEnabled(True)
|
||||
self.form.dsb_seg_per_edge.setProperty("value", self.user_p["segmentsperedge"])
|
||||
self.form.dsb_growth_rate.setProperty("value", self.user_p["grading"])
|
||||
self.form.dsb_curvature_safety.setProperty("value", self.user_p["curvaturesafety"])
|
||||
# set properties
|
||||
self.obj.SegmentsPerEdge = self.user_p["segmentsperedge"]
|
||||
self.obj.GrowthRate = self.user_p["grading"]
|
||||
self.obj.CurvatureSafety = self.user_p["curvaturesafety"]
|
||||
self.obj.OptimizationSteps3d = self.user_p["optsteps3d"]
|
||||
self.obj.CloseEdgeFactor = self.user_p["closeedgefac"]
|
||||
else:
|
||||
self.form.qsb_min_size.setEnabled(False)
|
||||
self.form.qsb_max_size.setEnabled(False)
|
||||
p = self.obj.Proxy.get_predef_fineness_params(self.fineness)
|
||||
self.form.dsb_seg_per_edge.setEnabled(False)
|
||||
self.form.dsb_growth_rate.setEnabled(False)
|
||||
self.form.dsb_curvature_safety.setEnabled(False)
|
||||
self.form.dsb_growth_rate.setProperty("value", p["grading"])
|
||||
self.form.dsb_seg_per_edge.setProperty("value", p["segmentsperedge"])
|
||||
self.form.dsb_curvature_safety.setProperty("value", p["curvaturesafety"])
|
||||
|
||||
def second_order_changed(self, bool_value):
|
||||
self.second_order = bool_value
|
||||
|
||||
def get_user_fineness_params(self, obj):
|
||||
# parameters affected by the fineness value. If initial fineness is "UserDefined"
|
||||
# use current values otherwise use predefined values
|
||||
p = obj.Proxy.get_predef_fineness_params("UserDefined")
|
||||
if obj.Fineness == "UserDefined":
|
||||
p["curvaturesafety"] = obj.CurvatureSafety
|
||||
p["grading"] = obj.GrowthRate
|
||||
p["segmentsperedge"] = obj.SegmentsPerEdge
|
||||
p["optsteps3d"] = obj.OptimizationSteps3d
|
||||
p["closeedgefac"] = obj.CloseEdgeFactor
|
||||
|
||||
return p
|
||||
|
||||
Reference in New Issue
Block a user