Merge pull request #27749 from marioalexis84/fem-elmer_examples_run
Fem: Run Elmer examples - fixes #27547
This commit is contained in:
@@ -46,6 +46,22 @@ FemMeshShapeBaseObject::FemMeshShapeBaseObject()
|
||||
Prop_None,
|
||||
"Geometry object, the mesh is made from. The geometry object has to have a Shape."
|
||||
);
|
||||
ADD_PROPERTY_TYPE(
|
||||
Tool,
|
||||
(Py::Object()),
|
||||
"FEM Mesh",
|
||||
App::PropertyType(
|
||||
App::Prop_Transient | App::Prop_Hidden | App::Prop_ReadOnly | App::Prop_Output
|
||||
),
|
||||
"Tool object for run the mesher"
|
||||
);
|
||||
ADD_PROPERTY_TYPE(
|
||||
WorkingDirectory,
|
||||
(""),
|
||||
"FEM Mesh",
|
||||
App::PropertyType(App::Prop_Transient | App::Prop_Hidden | App::Prop_Output),
|
||||
"Mesher working directory"
|
||||
);
|
||||
|
||||
Shape.setScope(LinkScope::Global);
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ public:
|
||||
~FemMeshShapeBaseObject() override;
|
||||
|
||||
App::PropertyLink Shape;
|
||||
App::PropertyPythonObject Tool;
|
||||
App::PropertyPath WorkingDirectory;
|
||||
|
||||
/// returns the type name of the ViewProvider
|
||||
const char* getViewProviderName() const override
|
||||
|
||||
@@ -50,6 +50,15 @@ FemSolverObject::FemSolverObject()
|
||||
App::PropertyType(App::Prop_Transient | App::Prop_Hidden | App::Prop_Output),
|
||||
"Solver working directory"
|
||||
);
|
||||
ADD_PROPERTY_TYPE(
|
||||
Tool,
|
||||
(Py::Object()),
|
||||
"Solver",
|
||||
App::PropertyType(
|
||||
App::Prop_Transient | App::Prop_Hidden | App::Prop_ReadOnly | App::Prop_Output
|
||||
),
|
||||
"Tool for run the solver"
|
||||
);
|
||||
}
|
||||
|
||||
FemSolverObject::~FemSolverObject() = default;
|
||||
|
||||
@@ -42,6 +42,7 @@ public:
|
||||
~FemSolverObject() override;
|
||||
|
||||
App::PropertyLinkList Results;
|
||||
App::PropertyPythonObject Tool;
|
||||
App::PropertyPath WorkingDirectory;
|
||||
// Attributes are implemented in the FemSolverObjectPython
|
||||
|
||||
|
||||
@@ -116,6 +116,7 @@ SET(FemExamples_SRCS
|
||||
|
||||
SET(FemExampleMeshes_SRCS
|
||||
femexamples/meshes/__init__.py
|
||||
femexamples/meshes/generate_mesh.py
|
||||
femexamples/meshes/mesh_beamsimple_tetra10.py
|
||||
femexamples/meshes/mesh_boxanalysis_tetra10.py
|
||||
femexamples/meshes/mesh_boxes_2_vertikal_tetra10.py
|
||||
@@ -517,6 +518,7 @@ SET(FemTools_SRCS
|
||||
femtools/geomtools.py
|
||||
femtools/membertools.py
|
||||
femtools/migrate_app.py
|
||||
femtools/objecttools.py
|
||||
femtools/tokrules.py
|
||||
)
|
||||
|
||||
|
||||
@@ -29,9 +29,6 @@ __url__ = "https://www.freecad.org"
|
||||
# \ingroup FEM
|
||||
# \brief FreeCAD FEM command definitions
|
||||
|
||||
from PySide import QtCore
|
||||
from PySide import QtGui
|
||||
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
from FreeCAD import Qt
|
||||
@@ -1184,51 +1181,11 @@ class _SolverRun(CommandManager):
|
||||
self.tool = None
|
||||
|
||||
def Activated(self):
|
||||
if self.selobj.Proxy.Type in ["Fem::SolverCalculiX", "Fem::SolverElmer"]:
|
||||
try:
|
||||
QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor)
|
||||
self._set_tool()
|
||||
self._conn(self.tool)
|
||||
self.tool.prepare()
|
||||
self.tool.compute()
|
||||
except Exception as e:
|
||||
QtGui.QApplication.restoreOverrideCursor()
|
||||
FreeCAD.Console.PrintError(e)
|
||||
return
|
||||
from femsolver.run import run_fem_solver
|
||||
|
||||
else:
|
||||
from femsolver.run import run_fem_solver
|
||||
|
||||
run_fem_solver(self.selobj)
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def _set_tool(self):
|
||||
match self.selobj.Proxy.Type:
|
||||
case "Fem::SolverCalculiX":
|
||||
from femsolver.calculix.calculixtools import CalculiXTools
|
||||
|
||||
self.tool = CalculiXTools(self.selobj)
|
||||
case "Fem::SolverElmer":
|
||||
from femsolver.elmer.elmertools import ElmerTools
|
||||
|
||||
self.tool = ElmerTools(self.selobj)
|
||||
|
||||
def _conn(self, tool):
|
||||
QtCore.QObject.connect(
|
||||
tool.process,
|
||||
QtCore.SIGNAL("finished(int, QProcess::ExitStatus)"),
|
||||
self._process_finished,
|
||||
)
|
||||
|
||||
def _process_finished(self, code, status):
|
||||
if status == QtCore.QProcess.ExitStatus.NormalExit and code == 0:
|
||||
self.tool.update_properties()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
QtGui.QApplication.restoreOverrideCursor()
|
||||
else:
|
||||
QtGui.QApplication.restoreOverrideCursor()
|
||||
FreeCAD.Console.PrintError("Process finished with errors. Result not updated\n")
|
||||
run_fem_solver(self.selobj)
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
|
||||
class _SolverZ88(CommandManager):
|
||||
|
||||
@@ -29,9 +29,10 @@ import ObjectsFem
|
||||
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def setup_boxanalysisbase(doc=None, solvertype="ccxtools"):
|
||||
def setup_boxanalysisbase(doc=None, solvertype="ccxtools", test_mode=False):
|
||||
|
||||
# init FreeCAD document
|
||||
if doc is None:
|
||||
@@ -62,21 +63,22 @@ def setup_boxanalysisbase(doc=None, solvertype="ccxtools"):
|
||||
analysis.addObject(material_obj)
|
||||
|
||||
# mesh
|
||||
from .meshes.mesh_boxanalysis_tetra10 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.CharacteristicLengthMin = "8.0 mm"
|
||||
femmesh_obj.ElementOrder = "2nd"
|
||||
|
||||
# generate the mesh
|
||||
success = False
|
||||
if not test_mode:
|
||||
success = generate_mesh.mesh_from_mesher(femmesh_obj, "gmsh")
|
||||
if not success:
|
||||
# try to create from existing rough mesh
|
||||
from .meshes.mesh_boxanalysis_tetra10 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -58,7 +58,7 @@ See forum topic post:
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
def setup(doc=None, solvertype="ccxtools", test_mode=False):
|
||||
|
||||
# init FreeCAD document
|
||||
if doc is None:
|
||||
@@ -69,7 +69,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
manager.add_explanation_obj(doc, get_explanation(manager.get_header(get_information())))
|
||||
|
||||
# setup box frequency, change solver attributes
|
||||
doc = setup_boxanalysisbase(doc, solvertype)
|
||||
doc = setup_boxanalysisbase(doc, solvertype, test_mode)
|
||||
analysis = doc.Analysis
|
||||
|
||||
# solver
|
||||
|
||||
@@ -60,7 +60,7 @@ See forum topic post:
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
def setup(doc=None, solvertype="ccxtools", test_mode=False):
|
||||
|
||||
# init FreeCAD document
|
||||
if doc is None:
|
||||
@@ -71,7 +71,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
manager.add_explanation_obj(doc, get_explanation(manager.get_header(get_information())))
|
||||
|
||||
# setup box static, add a fixed, force and a pressure constraint
|
||||
doc = setup_boxanalysisbase(doc, solvertype)
|
||||
doc = setup_boxanalysisbase(doc, solvertype, test_mode)
|
||||
geom_obj = doc.Box
|
||||
analysis = doc.Analysis
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -177,13 +178,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# mesh
|
||||
from .meshes.mesh_buckling_ibeam_tria6 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -29,6 +29,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -150,13 +151,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# mesh
|
||||
from .meshes.mesh_buckling_plate_tria6 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -30,6 +30,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -130,13 +131,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# mesh
|
||||
from .meshes.mesh_flexural_buckling import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -29,6 +29,7 @@ import ObjectsFem
|
||||
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def setup_cantilever_base_edge(doc=None, solvertype="ccxtools"):
|
||||
@@ -121,13 +122,7 @@ def setup_cantilever_base_edge(doc=None, solvertype="ccxtools"):
|
||||
# mesh
|
||||
from .meshes.mesh_canticcx_seg3 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -28,6 +28,7 @@ import ObjectsFem
|
||||
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def setup_cantilever_base_face(doc=None, solvertype="ccxtools"):
|
||||
@@ -106,13 +107,7 @@ def setup_cantilever_base_face(doc=None, solvertype="ccxtools"):
|
||||
# mesh
|
||||
from .meshes.mesh_canticcx_tria6 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -29,9 +29,10 @@ import ObjectsFem
|
||||
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def setup_cantilever_base_solid(doc=None, solvertype="ccxtools"):
|
||||
def setup_cantilever_base_solid(doc=None, solvertype="ccxtools", test_mode=False):
|
||||
|
||||
# init FreeCAD document
|
||||
if doc is None:
|
||||
@@ -91,19 +92,20 @@ def setup_cantilever_base_solid(doc=None, solvertype="ccxtools"):
|
||||
analysis.addObject(con_fixed)
|
||||
|
||||
# mesh
|
||||
from .meshes.mesh_canticcx_tetra10 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
|
||||
# generate the mesh
|
||||
success = False
|
||||
if not test_mode:
|
||||
success = generate_mesh.mesh_from_mesher(femmesh_obj, "gmsh")
|
||||
if not success:
|
||||
# try to create from existing rough mesh
|
||||
from .meshes.mesh_canticcx_tetra10 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -30,6 +30,7 @@ from . import manager
|
||||
from .ccx_cantilever_faceload import setup as setup_with_faceload
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -38,7 +39,7 @@ def get_information():
|
||||
"meshtype": "solid",
|
||||
"meshelement": "Hexa20",
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["ccxtools", "elmer", "z88"],
|
||||
"solvers": ["ccxtools", "z88"], # elmer disabled until mesh has groups
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
@@ -84,16 +85,8 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# load the hexa20 mesh
|
||||
from .meshes.mesh_canticcx_hexa20 import create_nodes, create_elements
|
||||
|
||||
new_fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(new_fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(new_fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
|
||||
# overwrite mesh with the hexa20 mesh
|
||||
femmesh_obj.FemMesh = new_fem_mesh
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -29,6 +29,7 @@ from . import manager
|
||||
from .ccx_cantilever_base_face import setup_cantilever_base_face
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -80,16 +81,10 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# load the quad4 mesh
|
||||
from .meshes.mesh_canticcx_quad4 import create_nodes, create_elements
|
||||
|
||||
new_fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(new_fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(new_fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
|
||||
# overwrite mesh with the quad4 mesh
|
||||
femmesh_obj.FemMesh = new_fem_mesh
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
|
||||
# set mesh obj parameter
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -29,6 +29,7 @@ from . import manager
|
||||
from .ccx_cantilever_base_face import setup_cantilever_base_face
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -80,16 +81,10 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# load the quad8 mesh
|
||||
from .meshes.mesh_canticcx_quad8 import create_nodes, create_elements
|
||||
|
||||
new_fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(new_fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(new_fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
|
||||
# overwrite mesh with the quad8 mesh
|
||||
femmesh_obj.FemMesh = new_fem_mesh
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
|
||||
# set mesh obj parameter
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -29,6 +29,7 @@ from . import manager
|
||||
from .ccx_cantilever_base_edge import setup_cantilever_base_edge
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -80,16 +81,10 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# load the seg2 mesh
|
||||
from .meshes.mesh_canticcx_seg2 import create_nodes, create_elements
|
||||
|
||||
new_fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(new_fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(new_fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
|
||||
# overwrite mesh with the seg2 mesh
|
||||
femmesh_obj.FemMesh = new_fem_mesh
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
|
||||
# set mesh obj parameter
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -28,6 +28,7 @@ from . import manager
|
||||
from .ccx_cantilever_faceload import setup as setup_with_faceload
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -52,8 +53,7 @@ from femexamples.ccx_cantilever_ele_tetra4 import setup
|
||||
setup()
|
||||
|
||||
|
||||
Tetra4 elements. There are really a lot needed thus mesh is cleared.
|
||||
Mesh before run the example.
|
||||
Cantilever modeled with tetra4 volume elements
|
||||
...
|
||||
|
||||
"""
|
||||
@@ -89,5 +89,8 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
femmesh_obj.CharacteristicLengthMax = "150.0 mm"
|
||||
femmesh_obj.CharacteristicLengthMin = "150.0 mm"
|
||||
|
||||
# generate the mesh
|
||||
generate_mesh.mesh_from_mesher(femmesh_obj, "gmsh")
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -29,6 +29,7 @@ from . import manager
|
||||
from .ccx_cantilever_base_face import setup_cantilever_base_face
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -80,16 +81,10 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# load the tria3 mesh
|
||||
from .meshes.mesh_canticcx_tria3 import create_nodes, create_elements
|
||||
|
||||
new_fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(new_fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(new_fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
|
||||
# overwrite mesh with the tria3 mesh
|
||||
femmesh_obj.FemMesh = new_fem_mesh
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
|
||||
# set mesh obj parameter
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -58,7 +58,7 @@ See forum topic post:
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
def setup(doc=None, solvertype="ccxtools", test_mode=False):
|
||||
|
||||
# init FreeCAD document
|
||||
if doc is None:
|
||||
@@ -69,7 +69,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
manager.add_explanation_obj(doc, get_explanation(manager.get_header(get_information())))
|
||||
|
||||
# setup CalculiX cantilever
|
||||
doc = setup_cantilever_base_solid(doc, solvertype)
|
||||
doc = setup_cantilever_base_solid(doc, solvertype, test_mode)
|
||||
analysis = doc.Analysis
|
||||
geom_obj = doc.Box
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ See forum topic post:
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
def setup(doc=None, solvertype="ccxtools", test_mode=False):
|
||||
|
||||
# init FreeCAD document
|
||||
if doc is None:
|
||||
@@ -69,7 +69,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
manager.add_explanation_obj(doc, get_explanation(manager.get_header(get_information())))
|
||||
|
||||
# setup CalculiX cantilever, apply 9 MN on the 4 nodes of the front end face
|
||||
doc = setup_cantilever_base_solid(doc, solvertype)
|
||||
doc = setup_cantilever_base_solid(doc, solvertype, test_mode)
|
||||
analysis = doc.Analysis
|
||||
geom_obj = doc.Box
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ See forum topic post:
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
def setup(doc=None, solvertype="ccxtools", test_mode=False):
|
||||
|
||||
if solvertype == "z88":
|
||||
# constraint displacement is not supported for Z88
|
||||
@@ -75,7 +75,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
# setup CalculiX cantilever
|
||||
# apply a prescribed displacement of 250 mm in -z on the front end face
|
||||
doc = setup_cantilever_base_solid(doc, solvertype)
|
||||
doc = setup_cantilever_base_solid(doc, solvertype, test_mode)
|
||||
analysis = doc.Analysis
|
||||
geom_obj = doc.Box
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -169,10 +170,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
femmesh_obj.ViewObject.Visibility = False
|
||||
|
||||
# generate the mesh
|
||||
from femmesh import gmshtools
|
||||
|
||||
gmsh_mesh = gmshtools.GmshTools(femmesh_obj, analysis)
|
||||
gmsh_mesh.create_mesh()
|
||||
generate_mesh.mesh_from_mesher(femmesh_obj, "gmsh")
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -29,6 +29,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -144,10 +145,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
femmesh_obj.ViewObject.Visibility = False
|
||||
|
||||
# generate the mesh
|
||||
from femmesh import gmshtools
|
||||
|
||||
gmsh_mesh = gmshtools.GmshTools(femmesh_obj, analysis)
|
||||
gmsh_mesh.create_mesh()
|
||||
generate_mesh.mesh_from_mesher(femmesh_obj, "gmsh")
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -30,6 +30,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -138,14 +139,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
femmesh_obj.ViewObject.Visibility = False
|
||||
|
||||
# generate the mesh
|
||||
from femmesh import gmshtools
|
||||
|
||||
gmsh_mesh = gmshtools.GmshTools(femmesh_obj, analysis)
|
||||
try:
|
||||
error = gmsh_mesh.create_mesh()
|
||||
except Exception:
|
||||
error = sys.exc_info()[1]
|
||||
FreeCAD.Console.PrintError(f"Unexpected error when creating mesh: {error}\n")
|
||||
generate_mesh.mesh_from_mesher(femmesh_obj, "gmsh")
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -34,6 +34,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -184,13 +185,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# mesh
|
||||
from .meshes.mesh_constraint_centrif_tetra10 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -33,6 +33,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -204,13 +205,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# mesh
|
||||
from .meshes.mesh_contact_tube_tube_tria3 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -34,6 +34,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -189,13 +190,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
create_elements,
|
||||
)
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -40,6 +40,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -263,13 +264,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# mesh
|
||||
from .meshes.mesh_section_print_tetra10 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -29,6 +29,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -64,7 +65,7 @@ max deformation = 576.8 mm
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
def setup(doc=None, solvertype="ccxtools", test_mode=False):
|
||||
|
||||
# init FreeCAD document
|
||||
if doc is None:
|
||||
@@ -116,6 +117,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
mat["PoissonRatio"] = "0.30"
|
||||
mat["Density"] = "7900 kg/m^3"
|
||||
material_obj.Material = mat
|
||||
material_obj.References = [(geom_obj, "Solid1")]
|
||||
analysis.addObject(material_obj)
|
||||
|
||||
# constraint fixed
|
||||
@@ -129,19 +131,20 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
analysis.addObject(con_selfweight)
|
||||
|
||||
# mesh
|
||||
from .meshes.mesh_selfweight_cantilever_tetra10 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
|
||||
# generate the mesh
|
||||
success = False
|
||||
if not test_mode:
|
||||
success = generate_mesh.mesh_from_mesher(femmesh_obj, "gmsh")
|
||||
if not success:
|
||||
# try to create from existing rough mesh
|
||||
from .meshes.mesh_selfweight_cantilever_tetra10 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -34,6 +34,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -160,13 +161,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# mesh
|
||||
from .meshes.mesh_constraint_tie_tetra10 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -34,6 +34,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -175,13 +176,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# mesh
|
||||
from .meshes.mesh_transform_beam_hinged_tetra10 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -42,6 +42,7 @@ from Part import makeLine
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -164,13 +165,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# mesh
|
||||
from .meshes.mesh_transform_torque_tetra10 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -29,6 +29,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -125,21 +126,19 @@ def setup(doc=None, solvertype="elmer"):
|
||||
analysis.addObject(con_fixed)
|
||||
|
||||
# mesh
|
||||
from .meshes.mesh_eigenvalue_of_elastic_beam_tetra10 import create_nodes
|
||||
from .meshes.mesh_eigenvalue_of_elastic_beam_tetra10 import create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.CharacteristicLengthMax = "40.80 mm"
|
||||
|
||||
# generate the mesh
|
||||
success = generate_mesh.mesh_from_mesher(femmesh_obj, "gmsh")
|
||||
if not success:
|
||||
# try to create from existing mesh
|
||||
from .meshes.mesh_eigenvalue_of_elastic_beam_tetra10 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -32,6 +32,7 @@ import Sketcher
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -198,14 +199,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
femmesh_obj.ViewObject.Visibility = False
|
||||
|
||||
# generate the mesh
|
||||
from femmesh import gmshtools
|
||||
|
||||
gmsh_mesh = gmshtools.GmshTools(femmesh_obj, analysis)
|
||||
try:
|
||||
error = gmsh_mesh.create_mesh()
|
||||
except Exception:
|
||||
error = sys.exc_info()[1]
|
||||
FreeCAD.Console.PrintError(f"Unexpected error when creating mesh: {error}\n")
|
||||
generate_mesh.mesh_from_mesher(femmesh_obj, "gmsh")
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -33,6 +33,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -177,28 +178,15 @@ def setup(doc=None, solvertype="elmer"):
|
||||
mesh_region.ViewObject.Visibility = False
|
||||
|
||||
# generate the mesh
|
||||
from femmesh import gmshtools
|
||||
|
||||
gmsh_mesh = gmshtools.GmshTools(femmesh_obj, analysis)
|
||||
try:
|
||||
error = gmsh_mesh.create_mesh()
|
||||
except Exception:
|
||||
error = sys.exc_info()[1]
|
||||
FreeCAD.Console.PrintError(f"Unexpected error when creating mesh: {error}\n")
|
||||
if error:
|
||||
success = generate_mesh.mesh_from_mesher(femmesh_obj, "gmsh")
|
||||
if not success:
|
||||
# try to create from existing rough mesh
|
||||
from .meshes.mesh_capacitance_two_balls_tetra10 import (
|
||||
create_nodes,
|
||||
create_elements,
|
||||
)
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
|
||||
doc.recompute()
|
||||
|
||||
@@ -34,6 +34,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -182,28 +183,15 @@ def setup(doc=None, solvertype="calculix"):
|
||||
mesh_region.ViewObject.Visibility = False
|
||||
|
||||
# generate the mesh
|
||||
from femmesh import gmshtools
|
||||
|
||||
gmsh_mesh = gmshtools.GmshTools(femmesh_obj, analysis)
|
||||
try:
|
||||
error = gmsh_mesh.create_mesh()
|
||||
except Exception:
|
||||
error = sys.exc_info()[1]
|
||||
FreeCAD.Console.PrintError(f"Unexpected error when creating mesh: {error}\n")
|
||||
if error:
|
||||
success = generate_mesh.mesh_from_mesher(femmesh_obj, "gmsh")
|
||||
if not success:
|
||||
# try to create from existing rough mesh
|
||||
from .meshes.mesh_capacitance_two_balls_tetra10 import (
|
||||
create_nodes,
|
||||
create_elements,
|
||||
)
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
|
||||
doc.recompute()
|
||||
|
||||
@@ -36,6 +36,7 @@ import Sketcher
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -44,7 +45,7 @@ def get_information():
|
||||
"meshtype": "solid",
|
||||
"meshelement": "Tet10",
|
||||
"constraints": ["electrostatic potential"],
|
||||
"solvers": ["elmer"],
|
||||
"solvers": ["calculix", "elmer"],
|
||||
"material": "fluid",
|
||||
"equations": ["electrostatic"],
|
||||
}
|
||||
@@ -178,6 +179,9 @@ def setup(doc=None, solvertype="elmer"):
|
||||
solver_obj = ObjectsFem.makeSolverElmer(doc, "SolverElmer")
|
||||
ObjectsFem.makeEquationElectrostatic(doc, solver_obj)
|
||||
ObjectsFem.makeEquationElectricforce(doc, solver_obj)
|
||||
elif solvertype == "calculix":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiX(doc, "SolverCalculiX")
|
||||
solver_obj.AnalysisType = "electromagnetic"
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Unknown or unsupported solver type: {}. "
|
||||
@@ -213,12 +217,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
# constraint potential 1V
|
||||
name_pot2 = "ElectrostaticPotential2"
|
||||
con_elect_pot2 = ObjectsFem.makeConstraintElectrostaticPotential(doc, name_pot2)
|
||||
con_elect_pot2.References = [
|
||||
(geom_obj, "Face4"),
|
||||
(geom_obj, "Face5"),
|
||||
(geom_obj, "Face6"),
|
||||
(geom_obj, "Face11"),
|
||||
]
|
||||
con_elect_pot2.References = [(geom_obj, "Face4")]
|
||||
con_elect_pot2.Potential = "1 V"
|
||||
con_elect_pot2.CapacitanceBody = 2
|
||||
con_elect_pot2.CapacitanceBodyEnabled = True
|
||||
@@ -245,29 +244,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
mesh_region.ViewObject.Visibility = False
|
||||
|
||||
# generate the mesh
|
||||
from femmesh import gmshtools
|
||||
|
||||
gmsh_mesh = gmshtools.GmshTools(femmesh_obj, analysis)
|
||||
try:
|
||||
error = gmsh_mesh.create_mesh()
|
||||
except Exception:
|
||||
error = sys.exc_info()[1]
|
||||
FreeCAD.Console.PrintError(f"Unexpected error when creating mesh: {error}\n")
|
||||
if error:
|
||||
# try to create from existing rough mesh
|
||||
from .meshes.mesh_electricforce_elmer_nongui6_tetra10 import (
|
||||
create_nodes,
|
||||
create_elements,
|
||||
)
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
generate_mesh.mesh_from_mesher(femmesh_obj, "gmsh")
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -34,6 +34,7 @@ from BOPTools import SplitFeatures
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -269,14 +270,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
mesh_region.ViewObject.Visibility = False
|
||||
|
||||
# generate the mesh
|
||||
from femmesh import gmshtools
|
||||
|
||||
gmsh_mesh = gmshtools.GmshTools(femmesh_obj, analysis)
|
||||
try:
|
||||
error = gmsh_mesh.create_mesh()
|
||||
except Exception:
|
||||
error = sys.exc_info()[1]
|
||||
FreeCAD.Console.PrintError(f"Unexpected error when creating mesh: {error}\n")
|
||||
generate_mesh.mesh_from_mesher(femmesh_obj, "gmsh")
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -34,6 +34,7 @@ from BOPTools import SplitFeatures
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -277,14 +278,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
mesh_region.ViewObject.Visibility = False
|
||||
|
||||
# generate the mesh
|
||||
from femmesh import gmshtools
|
||||
|
||||
gmsh_mesh = gmshtools.GmshTools(femmesh_obj, analysis)
|
||||
try:
|
||||
error = gmsh_mesh.create_mesh()
|
||||
except Exception:
|
||||
error = sys.exc_info()[1]
|
||||
FreeCAD.Console.PrintError(f"Unexpected error when creating mesh: {error}\n")
|
||||
generate_mesh.mesh_from_mesher(femmesh_obj, "gmsh")
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -34,6 +34,7 @@ from BOPTools import SplitFeatures
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -275,14 +276,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
mesh_region.ViewObject.Visibility = False
|
||||
|
||||
# generate the mesh
|
||||
from femmesh import gmshtools
|
||||
|
||||
gmsh_mesh = gmshtools.GmshTools(femmesh_obj, analysis)
|
||||
try:
|
||||
error = gmsh_mesh.create_mesh()
|
||||
except Exception:
|
||||
error = sys.exc_info()[1]
|
||||
FreeCAD.Console.PrintError(f"Unexpected error when creating mesh: {error}\n")
|
||||
generate_mesh.mesh_from_mesher(femmesh_obj, "gmsh")
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -30,6 +30,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -158,14 +159,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
femmesh_obj.ViewObject.Visibility = False
|
||||
|
||||
# generate the mesh
|
||||
from femmesh import gmshtools
|
||||
|
||||
gmsh_mesh = gmshtools.GmshTools(femmesh_obj, analysis)
|
||||
try:
|
||||
error = gmsh_mesh.create_mesh()
|
||||
except Exception:
|
||||
error = sys.exc_info()[1]
|
||||
FreeCAD.Console.PrintError(f"Unexpected error when creating mesh: {error}\n")
|
||||
generate_mesh.mesh_from_mesher(femmesh_obj, "gmsh")
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -33,6 +33,7 @@ from BOPTools import SplitFeatures
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -274,14 +275,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
mesh_region.ViewObject.Visibility = False
|
||||
|
||||
# generate the mesh
|
||||
from femmesh import gmshtools
|
||||
|
||||
gmsh_mesh = gmshtools.GmshTools(femmesh_obj, analysis)
|
||||
try:
|
||||
error = gmsh_mesh.create_mesh()
|
||||
except Exception:
|
||||
error = sys.exc_info()[1]
|
||||
FreeCAD.Console.PrintError(f"Unexpected error when creating mesh: {error}\n")
|
||||
generate_mesh.mesh_from_mesher(femmesh_obj, "gmsh")
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -32,6 +32,7 @@ from BasicShapes import Shapes
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -211,29 +212,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
mesh_region.ViewObject.Visibility = False
|
||||
|
||||
# generate the mesh
|
||||
from femmesh import gmshtools
|
||||
|
||||
gmsh_mesh = gmshtools.GmshTools(femmesh_obj, analysis)
|
||||
try:
|
||||
error = gmsh_mesh.create_mesh()
|
||||
except Exception:
|
||||
error = sys.exc_info()[1]
|
||||
FreeCAD.Console.PrintError(f"Unexpected error when creating mesh: {error}\n")
|
||||
if error:
|
||||
# try to create from existing rough mesh
|
||||
from .meshes.mesh_capacitance_two_balls_tetra10 import (
|
||||
create_nodes,
|
||||
create_elements,
|
||||
)
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
generate_mesh.mesh_from_mesher(femmesh_obj, "gmsh")
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -25,7 +25,6 @@ import sys
|
||||
import FreeCAD
|
||||
from FreeCAD import Vector
|
||||
|
||||
import Draft
|
||||
import ObjectsFem
|
||||
import Part
|
||||
|
||||
@@ -33,6 +32,7 @@ from BOPTools import SplitFeatures
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -79,9 +79,8 @@ def setup(doc=None, solvertype="elmer"):
|
||||
p2 = Vector(200.0, -200.0, 0.0)
|
||||
p3 = Vector(200.0, -100.0, 0.0)
|
||||
p4 = Vector(0.0, -100.0, 0.0)
|
||||
Horseshoe_lower = Draft.make_wire([p1, p2, p3, p4], closed=True)
|
||||
Horseshoe_lower.MakeFace = True
|
||||
Horseshoe_lower.Label = "Lower_End"
|
||||
Horseshoe_lower = doc.addObject("Part::Feature", "Lower_End")
|
||||
Horseshoe_lower.Shape = Part.makeFace(Part.makePolygon([p1, p2, p3, p4, p1]))
|
||||
Horseshoe_lower.ViewObject.Visibility = False
|
||||
|
||||
# wire defining the upper horse shoe end
|
||||
@@ -89,9 +88,8 @@ def setup(doc=None, solvertype="elmer"):
|
||||
p2 = Vector(200.0, 100.0, 0.0)
|
||||
p3 = Vector(200.0, 200.0, 0.0)
|
||||
p4 = Vector(0.0, 200.0, 0.0)
|
||||
Horseshoe_upper = Draft.make_wire([p1, p2, p3, p4], closed=True)
|
||||
Horseshoe_upper.MakeFace = True
|
||||
Horseshoe_upper.Label = "Upper_End"
|
||||
Horseshoe_upper = doc.addObject("Part::Feature", "Upper_End")
|
||||
Horseshoe_upper.Shape = Part.makeFace(Part.makePolygon([p1, p2, p3, p4, p1]))
|
||||
Horseshoe_upper.ViewObject.Visibility = False
|
||||
|
||||
# the U-part of the horse shoe
|
||||
@@ -275,14 +273,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
mesh_region.ViewObject.Visibility = False
|
||||
|
||||
# generate the mesh
|
||||
from femmesh import gmshtools
|
||||
|
||||
gmsh_mesh = gmshtools.GmshTools(femmesh_obj, analysis)
|
||||
try:
|
||||
error = gmsh_mesh.create_mesh()
|
||||
except Exception:
|
||||
error = sys.exc_info()[1]
|
||||
FreeCAD.Console.PrintError(f"Unexpected error when creating mesh: {error}\n")
|
||||
generate_mesh.mesh_from_mesher(femmesh_obj, "gmsh")
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -38,6 +38,7 @@ from BasicShapes import Shapes
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -159,14 +160,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
femmesh_obj.ViewObject.Visibility = False
|
||||
|
||||
# generate the mesh
|
||||
from femmesh import gmshtools
|
||||
|
||||
gmsh_mesh = gmshtools.GmshTools(femmesh_obj, analysis)
|
||||
try:
|
||||
error = gmsh_mesh.create_mesh()
|
||||
except Exception:
|
||||
error = sys.exc_info()[1]
|
||||
FreeCAD.Console.PrintError(f"Unexpected error when creating mesh: {error}\n")
|
||||
generate_mesh.mesh_from_mesher(femmesh_obj, "gmsh")
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -239,7 +239,7 @@ class FemExamples(QtGui.QWidget):
|
||||
FreeCADGui.doCommand("from femexamples.manager import run_example")
|
||||
if solver is not None:
|
||||
FreeCADGui.doCommand(
|
||||
f'run_example("{str(example)}", solver="{str(solver)}", run_solver=True)'
|
||||
f'run_example("{str(example)}", solver="{str(solver)}", run_solver=True, blocking=False)'
|
||||
)
|
||||
else:
|
||||
FreeCADGui.doCommand(f'run_example("{str(example)}", run_solver=True)')
|
||||
|
||||
@@ -29,6 +29,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -141,13 +142,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# mesh
|
||||
from .meshes.mesh_beamsimple_tetra10 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -36,6 +36,7 @@ import Materials
|
||||
import Part
|
||||
|
||||
from . import manager
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -150,14 +151,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
mesh_region.ViewObject.Visibility = False
|
||||
|
||||
# generate the mesh
|
||||
from femmesh import gmshtools
|
||||
|
||||
gmsh_mesh = gmshtools.GmshTools(femmesh_obj, analysis)
|
||||
try:
|
||||
gmsh_mesh.create_mesh()
|
||||
except Exception:
|
||||
error = sys.exc_info()[1]
|
||||
FreeCAD.Console.PrintError(f"Unexpected error when creating mesh: {error}\n")
|
||||
generate_mesh.mesh_from_mesher(femmesh_obj, "gmsh")
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -127,7 +127,7 @@ def setup_all():
|
||||
run_example("thermomech_bimetal")
|
||||
|
||||
|
||||
def run_analysis(doc, base_name, filepath="", run_solver=False):
|
||||
def run_analysis(doc, base_name, filepath="", run_solver=False, blocking=True):
|
||||
|
||||
from os.path import join, exists
|
||||
from os import makedirs
|
||||
@@ -168,13 +168,13 @@ def run_analysis(doc, base_name, filepath="", run_solver=False):
|
||||
from femsolver.run import run_fem_solver
|
||||
|
||||
if run_solver is True:
|
||||
run_fem_solver(solver, working_dir)
|
||||
run_fem_solver(solver, working_dir, blocking=blocking)
|
||||
|
||||
# save doc once again with results
|
||||
doc.save()
|
||||
|
||||
|
||||
def run_example(example, solver=None, base_name=None, run_solver=False):
|
||||
def run_example(example, solver=None, base_name=None, run_solver=False, blocking=True):
|
||||
|
||||
from importlib import import_module
|
||||
|
||||
@@ -192,7 +192,7 @@ def run_example(example, solver=None, base_name=None, run_solver=False):
|
||||
base_name = example
|
||||
if solver is not None:
|
||||
base_name += "_" + solver
|
||||
run_analysis(doc, base_name, run_solver=run_solver)
|
||||
run_analysis(doc, base_name, run_solver=run_solver, blocking=blocking)
|
||||
doc.recompute()
|
||||
|
||||
return doc
|
||||
|
||||
@@ -32,6 +32,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -192,13 +193,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# mesh
|
||||
from .meshes.mesh_multibodybeam_tetra10 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -30,6 +30,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -185,13 +186,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# mesh
|
||||
from .meshes.mesh_multibodybeam_tria6 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -33,6 +33,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -161,13 +162,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# mesh
|
||||
from .meshes.mesh_boxes_2_vertikal_tetra10 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -41,6 +41,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -169,13 +170,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# mesh
|
||||
from .meshes.mesh_platewithhole_tetra10 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2026 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
|
||||
# * *
|
||||
# * This file is part of FreeCAD. *
|
||||
# * *
|
||||
# * FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
# * under the terms of the GNU Lesser General Public License as *
|
||||
# * published by the Free Software Foundation, either version 2.1 of the *
|
||||
# * License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * FreeCAD is distributed in the hope that it will be useful, but *
|
||||
# * WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
# * Lesser General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Lesser General Public *
|
||||
# * License along with FreeCAD. If not, see *
|
||||
# * <https://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
import sys
|
||||
from FreeCAD import Console
|
||||
import Fem
|
||||
|
||||
|
||||
def mesh_from_mesher(femmesh_obj, mesher=""):
|
||||
tool = None
|
||||
success = False
|
||||
match mesher:
|
||||
case "netgen":
|
||||
from femmesh import netgentools
|
||||
tool = netgentools.NetgenTools(femmesh_obj)
|
||||
case "gmsh" | "":
|
||||
from femmesh import gmshtools
|
||||
tool = gmshtools.GmshTools(femmesh_obj)
|
||||
case _:
|
||||
raise ValueError(f"Invalid mesher: {mesher}")
|
||||
|
||||
# Redirect process error to report view
|
||||
print_error = lambda: Console.PrintError(
|
||||
tool.process.readAllStandardError().data().decode("utf-8")
|
||||
)
|
||||
tool.process.readyReadStandardError.connect(print_error)
|
||||
|
||||
# generate the mesh
|
||||
try:
|
||||
success = tool.run(blocking=True)
|
||||
except Exception as e:
|
||||
error = sys.exc_info()[1]
|
||||
Console.PrintError(f"Unexpected error when creating mesh: {error}\n")
|
||||
|
||||
return success
|
||||
|
||||
def mesh_from_existing(create_nodes, create_elements):
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
Console.PrintError("Error on creating elements.\n")
|
||||
|
||||
return fem_mesh
|
||||
@@ -31,6 +31,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -39,7 +40,7 @@ def get_information():
|
||||
"meshtype": "face",
|
||||
"meshelement": "Quad4",
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["ccxtools", "elmer", "mystran"],
|
||||
"solvers": ["ccxtools", "mystran"], # elmer disabled until mesh has groups
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
@@ -179,13 +180,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# mesh
|
||||
from .meshes.mesh_plate_mystran_quad4 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -34,6 +34,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -167,13 +168,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# mesh
|
||||
from .meshes.mesh_rc_wall_2d_tria6 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -33,6 +33,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -169,13 +170,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# mesh
|
||||
from .meshes.mesh_square_pipe_end_twisted_tria6 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -33,6 +33,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -439,13 +440,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# mesh
|
||||
from .meshes.mesh_square_pipe_end_twisted_tria6 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -41,6 +41,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -78,7 +79,7 @@ this file has 7.15 mm max deflection
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
def setup(doc=None, solvertype="ccxtools", test_mode=False):
|
||||
|
||||
# init FreeCAD document
|
||||
if doc is None:
|
||||
@@ -206,19 +207,21 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
analysis.addObject(con_temp)
|
||||
|
||||
# mesh
|
||||
from .meshes.mesh_thermomech_bimetal_tetra10 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.CharacteristicLengthMax = "2 mm"
|
||||
|
||||
# generate the mesh
|
||||
success = False
|
||||
if not test_mode:
|
||||
success = generate_mesh.mesh_from_mesher(femmesh_obj, "gmsh")
|
||||
if not success:
|
||||
# try to create from existing rough mesh
|
||||
from .meshes.mesh_thermomech_bimetal_tetra10 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -28,6 +28,7 @@ import Fem
|
||||
from .truss_3d_cs_circle_ele_seg3 import setup as setup_truss_seg3
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -59,13 +60,7 @@ def setup(doc=None, solvertype="z88"):
|
||||
# mesh
|
||||
from .meshes.mesh_truss_crane_seg2 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
|
||||
# overwrite mesh with the hexa20 mesh
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
|
||||
@@ -33,6 +33,7 @@ import ObjectsFem
|
||||
from . import manager
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
from .meshes import generate_mesh
|
||||
|
||||
|
||||
def get_information():
|
||||
@@ -452,13 +453,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# mesh
|
||||
from .meshes.mesh_truss_crane_seg3 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
fem_mesh = generate_mesh.mesh_from_existing(create_nodes, create_elements)
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
@@ -41,32 +41,21 @@ import Fem
|
||||
from . import meshtools
|
||||
from femtools import femutils
|
||||
from femtools import geomtools
|
||||
from femtools.objecttools import ObjectTools
|
||||
|
||||
|
||||
class GmshError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class GmshTools:
|
||||
class GmshTools(ObjectTools):
|
||||
|
||||
name = "Gmsh"
|
||||
|
||||
def __init__(self, gmsh_mesh_obj, analysis=None):
|
||||
|
||||
# mesh obj
|
||||
self.mesh_obj = gmsh_mesh_obj
|
||||
|
||||
self.process = QProcess()
|
||||
# analysis
|
||||
self.analysis = None
|
||||
if analysis:
|
||||
self.analysis = analysis
|
||||
else:
|
||||
for i in self.mesh_obj.InList:
|
||||
if i.isDerivedFrom("Fem::FemAnalysis"):
|
||||
self.analysis = i
|
||||
break
|
||||
|
||||
def __init__(self, obj):
|
||||
super().__init__(obj)
|
||||
self.mesh_obj = obj
|
||||
self.analysis = obj.getParentGroup()
|
||||
self.load_properties()
|
||||
self.error = False
|
||||
|
||||
@@ -232,10 +221,8 @@ class GmshTools:
|
||||
self.rename_groups()
|
||||
|
||||
def create_mesh(self):
|
||||
self.prepare()
|
||||
p = self.compute()
|
||||
p.waitForFinished()
|
||||
self.update_properties()
|
||||
# for backward compatibility only
|
||||
self.run(True)
|
||||
|
||||
def start_logs(self):
|
||||
Console.PrintLog("\nGmsh FEM mesh run is being started.\n")
|
||||
|
||||
@@ -34,9 +34,10 @@ from PySide.QtCore import QProcess, QThread, QProcessEnvironment
|
||||
import FreeCAD
|
||||
import Fem
|
||||
from freecad import utils
|
||||
from femtools.objecttools import ObjectTools
|
||||
|
||||
|
||||
class NetgenTools:
|
||||
class NetgenTools(ObjectTools):
|
||||
|
||||
# to change order of nodes from netgen to smesh
|
||||
order_edge = {
|
||||
@@ -73,11 +74,9 @@ class NetgenTools:
|
||||
__param_grp = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Netgen")
|
||||
|
||||
def __init__(self, obj):
|
||||
self.obj = obj
|
||||
super().__init__(obj)
|
||||
self.fem_mesh = None
|
||||
self.process = None
|
||||
self.tmpdir = ""
|
||||
self.process = QProcess()
|
||||
self.mesh_params = {}
|
||||
|
||||
def write_geom(self):
|
||||
@@ -267,6 +266,9 @@ def run_netgen(
|
||||
|
||||
np.save(result_file, [result, groups])
|
||||
|
||||
# remove traceback
|
||||
sys.excepthook = lambda type, value, traceback: print(value)
|
||||
|
||||
run_netgen(**{kwds})
|
||||
"""
|
||||
|
||||
|
||||
@@ -37,42 +37,18 @@ import Fem
|
||||
from . import writer
|
||||
from .. import settings
|
||||
|
||||
# from feminout import importCcxDatResults
|
||||
from femmesh import meshsetsgetter
|
||||
from femtools import membertools
|
||||
from femtools.objecttools import ObjectTools
|
||||
|
||||
|
||||
class CalculiXTools:
|
||||
class CalculiXTools(ObjectTools):
|
||||
|
||||
name = "CalculiX"
|
||||
|
||||
def __init__(self, obj):
|
||||
self.obj = obj
|
||||
self.process = QProcess()
|
||||
super().__init__(obj)
|
||||
self.model_file = ""
|
||||
self.analysis = obj.getParentGroup()
|
||||
self.fem_param = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem")
|
||||
self._create_working_directory(obj)
|
||||
|
||||
def _create_working_directory(self, obj):
|
||||
"""
|
||||
Create working directory according to preferences
|
||||
"""
|
||||
if not os.path.isdir(obj.WorkingDirectory):
|
||||
gen_param = self.fem_param.GetGroup("General")
|
||||
if gen_param.GetBool("UseTempDirectory"):
|
||||
self.obj.WorkingDirectory = tempfile.mkdtemp(prefix="fem_")
|
||||
elif gen_param.GetBool("UseBesideDirectory"):
|
||||
root, ext = os.path.splitext(obj.Document.FileName)
|
||||
if root:
|
||||
self.obj.WorkingDirectory = os.path.join(root, obj.Label)
|
||||
os.makedirs(self.obj.WorkingDirectory, exist_ok=True)
|
||||
else:
|
||||
# file not saved, use temporary
|
||||
self.obj.WorkingDirectory = tempfile.mkdtemp(prefix="fem_")
|
||||
elif gen_param.GetBool("UseCustomDirectory"):
|
||||
self.obj.WorkingDirectory = gen_param.GetString("CustomDirectoryPath")
|
||||
os.makedirs(self.obj.WorkingDirectory, exist_ok=True)
|
||||
|
||||
def prepare(self):
|
||||
from femtools.checksanalysis import check_member_for_solver_calculix
|
||||
|
||||
@@ -27,7 +27,6 @@ __url__ = "https://www.freecad.org"
|
||||
|
||||
|
||||
from PySide.QtCore import QProcess, QProcessEnvironment
|
||||
import tempfile
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
@@ -38,41 +37,18 @@ from . import writer
|
||||
from .. import settings
|
||||
|
||||
from femtools import membertools
|
||||
from femtools.objecttools import ObjectTools
|
||||
|
||||
|
||||
class ElmerTools:
|
||||
class ElmerTools(ObjectTools):
|
||||
|
||||
name = "Elmer"
|
||||
|
||||
def __init__(self, obj):
|
||||
self.obj = obj
|
||||
self.process = QProcess()
|
||||
super().__init__(obj)
|
||||
self.model_file = ""
|
||||
self.analysis = obj.getParentGroup()
|
||||
self.fem_param = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem")
|
||||
self._create_working_directory(obj)
|
||||
self._result_format = ""
|
||||
|
||||
def _create_working_directory(self, obj):
|
||||
"""
|
||||
Create working directory according to preferences
|
||||
"""
|
||||
if not os.path.isdir(obj.WorkingDirectory):
|
||||
gen_param = self.fem_param.GetGroup("General")
|
||||
if gen_param.GetBool("UseTempDirectory"):
|
||||
self.obj.WorkingDirectory = tempfile.mkdtemp(prefix="fem_")
|
||||
elif gen_param.GetBool("UseBesideDirectory"):
|
||||
root, ext = os.path.splitext(obj.Document.FileName)
|
||||
if root:
|
||||
self.obj.WorkingDirectory = os.path.join(root, obj.Label)
|
||||
os.makedirs(self.obj.WorkingDirectory, exist_ok=True)
|
||||
else:
|
||||
# file not saved, use temporary
|
||||
self.obj.WorkingDirectory = tempfile.mkdtemp(prefix="fem_")
|
||||
elif gen_param.GetBool("UseCustomDirectory"):
|
||||
self.obj.WorkingDirectory = gen_param.GetString("CustomDirectoryPath")
|
||||
os.makedirs(self.obj.WorkingDirectory, exist_ok=True)
|
||||
|
||||
def prepare(self):
|
||||
w = writer.Writer(self.obj, self.obj.WorkingDirectory)
|
||||
w.write_solver_input()
|
||||
@@ -91,7 +67,7 @@ class ElmerTools:
|
||||
p.setWorkingDirectory(self.obj.WorkingDirectory)
|
||||
grid_args = ["8", "2", mesh_file, "-out", self.obj.WorkingDirectory]
|
||||
p.start(grid_bin, grid_args)
|
||||
p.waitForFinished()
|
||||
p.waitForFinished(-1)
|
||||
num_proc = self.fem_param.GetGroup("Elmer").GetInt("NumberOfTasks", 1)
|
||||
if num_proc > 1:
|
||||
# MPI parallel computing version
|
||||
|
||||
@@ -40,6 +40,7 @@ import os
|
||||
import os.path
|
||||
import shutil
|
||||
import tempfile
|
||||
from PySide import QtCore
|
||||
|
||||
# import threading # not used ATM
|
||||
|
||||
@@ -48,6 +49,8 @@ import FreeCAD as App
|
||||
from . import settings
|
||||
from . import signal
|
||||
from . import task
|
||||
from femsolver.elmer import elmertools
|
||||
from femsolver.calculix import calculixtools
|
||||
from femtools import femutils
|
||||
from femtools import membertools
|
||||
from femtools.errors import DirectoryDoesNotExistError
|
||||
@@ -69,7 +72,7 @@ _machines = {}
|
||||
_dirTypes = {}
|
||||
|
||||
|
||||
def run_fem_solver(solver, working_dir=None):
|
||||
def run_fem_solver(solver, working_dir=None, blocking=False):
|
||||
"""Execute *solver* of the solver framework.
|
||||
|
||||
Uses :meth:`getMachine <femsolver.solverbase.Proxy.getMachine>` to obtain a
|
||||
@@ -100,6 +103,35 @@ def run_fem_solver(solver, working_dir=None):
|
||||
use a :class:`Machine`.
|
||||
"""
|
||||
|
||||
tool = None
|
||||
if working_dir:
|
||||
solver.WorkingDirectory = working_dir
|
||||
|
||||
match solver.Proxy.Type:
|
||||
case "Fem::SolverElmer":
|
||||
tool = elmertools.ElmerTools(solver)
|
||||
case "Fem::SolverCalculiX":
|
||||
tool = calculixtools.CalculiXTools(solver)
|
||||
|
||||
if tool is not None:
|
||||
# Redirect process error to report view
|
||||
print_error = lambda: App.Console.PrintError(
|
||||
tool.process.readAllStandardError().data().decode("utf-8")
|
||||
)
|
||||
tool.process.readyReadStandardError.connect(print_error)
|
||||
tool.process.finished.connect(_solver_finish(solver))
|
||||
try:
|
||||
if App.GuiUp:
|
||||
QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor)
|
||||
tool.run(blocking)
|
||||
except Exception as e:
|
||||
if App.GuiUp:
|
||||
QtGui.QApplication.restoreOverrideCursor()
|
||||
raise e
|
||||
return
|
||||
|
||||
# code for old solver implementations
|
||||
|
||||
if solver.Proxy.Type == "Fem::SolverCcxTools":
|
||||
from femtools.ccxtools import CcxTools as ccx
|
||||
|
||||
@@ -192,6 +224,17 @@ def getMachine(solver, path=None):
|
||||
return m
|
||||
|
||||
|
||||
def _solver_finish(obj):
|
||||
def receiver(code, status):
|
||||
if status != QtCore.QProcess.ExitStatus.NormalExit or code != 0:
|
||||
App.Console.PrintError("Solver finished with errors. Result not updated\n")
|
||||
if App.GuiUp:
|
||||
QtGui.QApplication.restoreOverrideCursor()
|
||||
obj.Document.recompute()
|
||||
|
||||
return receiver
|
||||
|
||||
|
||||
def _isPathValid(m, path):
|
||||
t = _dirTypes.get(m.directory) # setting default None
|
||||
setting = settings.get_dir_setting()
|
||||
|
||||
@@ -138,7 +138,6 @@ class _BaseLogTaskPanel(base_femtaskpanel._BaseTaskPanel, ABC):
|
||||
QtGui.QColor(getOutputWinColor("Error")),
|
||||
)
|
||||
return
|
||||
self.tool.update_properties()
|
||||
self.write_log("Process finished\n", QtGui.QColor(getOutputWinColor("Text")))
|
||||
|
||||
def process_started(self):
|
||||
|
||||
@@ -76,7 +76,7 @@ class TestCcxTools(unittest.TestCase):
|
||||
# set up
|
||||
from femexamples.boxanalysis_frequency import setup
|
||||
|
||||
setup(self.document, "ccxtools")
|
||||
setup(self.document, "ccxtools", test_mode=True)
|
||||
base_name = get_namefromdef("test_")
|
||||
res_obj_name = "CCX_EigenMode_1_Results"
|
||||
analysis_dir = testtools.get_fem_test_tmp_dir(self.pre_dir_name + base_name)
|
||||
@@ -100,7 +100,7 @@ class TestCcxTools(unittest.TestCase):
|
||||
# set up
|
||||
from femexamples.boxanalysis_static import setup
|
||||
|
||||
setup(self.document, "ccxtools")
|
||||
setup(self.document, "ccxtools", test_mode=True)
|
||||
base_name = get_namefromdef("test_")
|
||||
res_obj_name = "CCX_Results"
|
||||
analysis_dir = testtools.get_fem_test_tmp_dir(self.pre_dir_name + base_name)
|
||||
@@ -201,21 +201,21 @@ class TestCcxTools(unittest.TestCase):
|
||||
def test_ccx_cantilever_faceload(self):
|
||||
from femexamples.ccx_cantilever_faceload import setup
|
||||
|
||||
setup(self.document, "ccxtools")
|
||||
setup(self.document, "ccxtools", test_mode=True)
|
||||
self.input_file_writing_test(get_namefromdef("test_"))
|
||||
|
||||
# ********************************************************************************************
|
||||
def test_ccx_cantilever_nodeload(self):
|
||||
from femexamples.ccx_cantilever_nodeload import setup
|
||||
|
||||
setup(self.document, "ccxtools")
|
||||
setup(self.document, "ccxtools", test_mode=True)
|
||||
self.input_file_writing_test(get_namefromdef("test_"))
|
||||
|
||||
# ********************************************************************************************
|
||||
def test_ccx_cantilever_prescribeddisplacement(self):
|
||||
from femexamples.ccx_cantilever_prescribeddisplacement import setup
|
||||
|
||||
setup(self.document, "ccxtools")
|
||||
setup(self.document, "ccxtools", test_mode=True)
|
||||
self.input_file_writing_test(get_namefromdef("test_"))
|
||||
|
||||
# ********************************************************************************************
|
||||
@@ -256,7 +256,7 @@ class TestCcxTools(unittest.TestCase):
|
||||
def test_constraint_selfweight_cantilever(self):
|
||||
from femexamples.constraint_selfweight_cantilever import setup
|
||||
|
||||
setup(self.document, "ccxtools")
|
||||
setup(self.document, "ccxtools", test_mode=True)
|
||||
self.input_file_writing_test(get_namefromdef("test_"))
|
||||
|
||||
# ********************************************************************************************
|
||||
@@ -333,7 +333,7 @@ class TestCcxTools(unittest.TestCase):
|
||||
def test_thermomech_bimetal(self):
|
||||
from femexamples.thermomech_bimetal import setup
|
||||
|
||||
setup(self.document, "ccxtools")
|
||||
setup(self.document, "ccxtools", test_mode=True)
|
||||
self.input_file_writing_test(get_namefromdef("test_"))
|
||||
|
||||
# ********************************************************************************************
|
||||
|
||||
@@ -89,14 +89,14 @@ class TestSolverZ88(unittest.TestCase):
|
||||
def test_ccx_cantilever_faceload(self):
|
||||
from femexamples.ccx_cantilever_faceload import setup
|
||||
|
||||
setup(self.document, "z88")
|
||||
setup(self.document, "z88", test_mode=True)
|
||||
self.inputfile_writing_test(get_namefromdef("test_"))
|
||||
|
||||
# ********************************************************************************************
|
||||
def test_ccx_cantilever_nodeload(self):
|
||||
from femexamples.ccx_cantilever_nodeload import setup
|
||||
|
||||
setup(self.document, "z88")
|
||||
setup(self.document, "z88", test_mode=True)
|
||||
self.inputfile_writing_test(get_namefromdef("test_"))
|
||||
|
||||
# ********************************************************************************************
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2026 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
|
||||
# * *
|
||||
# * This file is part of FreeCAD. *
|
||||
# * *
|
||||
# * FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
# * under the terms of the GNU Lesser General Public License as *
|
||||
# * published by the Free Software Foundation, either version 2.1 of the *
|
||||
# * License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * FreeCAD is distributed in the hope that it will be useful, but *
|
||||
# * WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
# * Lesser General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Lesser General Public *
|
||||
# * License along with FreeCAD. If not, see *
|
||||
# * <https://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
__title__ = "Abstract base class for the work with solvers and meshers"
|
||||
__author__ = "Mario Passaglia"
|
||||
__url__ = "https://www.freecad.org"
|
||||
|
||||
|
||||
from PySide.QtCore import QProcess
|
||||
from abc import ABC, abstractmethod
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
import FreeCAD
|
||||
|
||||
|
||||
class ObjectTools(ABC):
|
||||
"""Abstract base class for the work with solvers and meshers"""
|
||||
|
||||
def __init__(self, obj):
|
||||
obj.Tool = self
|
||||
self.obj = obj
|
||||
self.process = QProcess()
|
||||
self.analysis = obj.getParentGroup()
|
||||
self.fem_param = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem")
|
||||
self._create_working_directory(obj)
|
||||
|
||||
self.process.finished.connect(self._process_finished)
|
||||
|
||||
def _create_working_directory(self, obj):
|
||||
"""
|
||||
Create working directory according to preferences
|
||||
"""
|
||||
if not os.path.isdir(obj.WorkingDirectory):
|
||||
gen_param = self.fem_param.GetGroup("General")
|
||||
if gen_param.GetBool("UseTempDirectory"):
|
||||
self.obj.WorkingDirectory = tempfile.mkdtemp(prefix="fem_")
|
||||
elif gen_param.GetBool("UseBesideDirectory"):
|
||||
root, ext = os.path.splitext(obj.Document.FileName)
|
||||
if root:
|
||||
self.obj.WorkingDirectory = os.path.join(root, obj.Label)
|
||||
os.makedirs(self.obj.WorkingDirectory, exist_ok=True)
|
||||
else:
|
||||
# file not saved, use temporary
|
||||
self.obj.WorkingDirectory = tempfile.mkdtemp(prefix="fem_")
|
||||
elif gen_param.GetBool("UseCustomDirectory"):
|
||||
self.obj.WorkingDirectory = gen_param.GetString("CustomDirectoryPath")
|
||||
os.makedirs(self.obj.WorkingDirectory, exist_ok=True)
|
||||
|
||||
@abstractmethod
|
||||
def prepare(self):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def compute(self):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def update_properties(self):
|
||||
pass
|
||||
|
||||
def run(self, blocking=False):
|
||||
self.prepare()
|
||||
self.compute()
|
||||
if blocking:
|
||||
return self.process.waitForFinished(-1)
|
||||
return None
|
||||
|
||||
def _process_finished(self, code, status):
|
||||
if status == QProcess.ExitStatus.NormalExit and code == 0:
|
||||
self.update_properties()
|
||||
Reference in New Issue
Block a user