FEM: reformat codebase
This commit is contained in:
@@ -29,19 +29,19 @@
|
||||
// Fem
|
||||
#ifndef FemExport
|
||||
#ifdef Fem_EXPORTS
|
||||
# define FemExport FREECAD_DECL_EXPORT
|
||||
#define FemExport FREECAD_DECL_EXPORT
|
||||
#else
|
||||
# define FemExport FREECAD_DECL_IMPORT
|
||||
#define FemExport FREECAD_DECL_IMPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// FemGui
|
||||
#ifndef FemGuiExport
|
||||
#ifdef FemGui_EXPORTS
|
||||
# define FemGuiExport FREECAD_DECL_EXPORT
|
||||
#define FemGuiExport FREECAD_DECL_EXPORT
|
||||
#else
|
||||
# define FemGuiExport FREECAD_DECL_IMPORT
|
||||
#define FemGuiExport FREECAD_DECL_IMPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif //FEM_GLOBAL_H
|
||||
#endif // FEM_GLOBAL_H
|
||||
|
||||
@@ -63,11 +63,10 @@ FreeCAD.addExportType("FEM mesh TetGen (*.poly)", "feminout.convert2TetGen")
|
||||
|
||||
# see FemMesh::read() and FemMesh::write() methods in src/Mod/Fem/App/FemMesh.cpp
|
||||
FreeCAD.addImportType(
|
||||
"FEM mesh formats (*.bdf *.BDF *.dat *.DAT *.inp *.INP *.med *.MED *.unv *.UNV *.vtk *.VTK *.vtu *.VTU *.pvtu *.PVTU *.z88 *.Z88)", "Fem"
|
||||
)
|
||||
FreeCAD.addExportType(
|
||||
"FEM mesh formats (*.dat *.inp *.med *.stl *.unv *.vtk *.vtu *.z88)", "Fem"
|
||||
"FEM mesh formats (*.bdf *.BDF *.dat *.DAT *.inp *.INP *.med *.MED *.unv *.UNV *.vtk *.VTK *.vtu *.VTU *.pvtu *.PVTU *.z88 *.Z88)",
|
||||
"Fem",
|
||||
)
|
||||
FreeCAD.addExportType("FEM mesh formats (*.dat *.inp *.med *.stl *.unv *.vtk *.vtu *.z88)", "Fem")
|
||||
|
||||
FreeCAD.addExportType("FEM mesh Nastran (*.bdf)", "feminout.exportNastranMesh")
|
||||
|
||||
@@ -77,17 +76,26 @@ FreeCAD.addImportType("FEM mesh Fenics (*.xml *.XML *.xdmf *.XDMF)", "feminout.i
|
||||
FreeCAD.addExportType("FEM mesh Fenics (*.xml *.xdmf)", "feminout.importFenicsMesh")
|
||||
|
||||
FreeCAD.addImportType(
|
||||
"FEM mesh YAML/JSON (*.meshyaml *.MESHYAML *.meshjson *.MESHJSON *.yaml *.YAML *.json *.JSON)", "feminout.importYamlJsonMesh"
|
||||
"FEM mesh YAML/JSON (*.meshyaml *.MESHYAML *.meshjson *.MESHJSON *.yaml *.YAML *.json *.JSON)",
|
||||
"feminout.importYamlJsonMesh",
|
||||
)
|
||||
FreeCAD.addExportType(
|
||||
"FEM mesh YAML/JSON (*.meshyaml *.meshjson *.yaml *.json)", "feminout.importYamlJsonMesh"
|
||||
"FEM mesh YAML/JSON (*.meshyaml *.meshjson *.yaml *.json)",
|
||||
"feminout.importYamlJsonMesh",
|
||||
)
|
||||
|
||||
FreeCAD.addImportType("FEM mesh Z88 (*i1.txt *I1.TXT)", "feminout.importZ88Mesh")
|
||||
FreeCAD.addExportType("FEM mesh Z88 (*i1.txt)", "feminout.importZ88Mesh")
|
||||
|
||||
FreeCAD.addImportType("FEM result Z88 displacements (*o2.txt *O2.TXT)", "feminout.importZ88O2Results")
|
||||
FreeCAD.addImportType(
|
||||
"FEM result Z88 displacements (*o2.txt *O2.TXT)", "feminout.importZ88O2Results"
|
||||
)
|
||||
|
||||
if "BUILD_FEM_VTK" in FreeCAD.__cmake__:
|
||||
FreeCAD.addImportType("FEM result VTK (*.vtk *.VTK *.vtu *.VTU *.pvtu *.PVTU)", "feminout.importVTKResults")
|
||||
FreeCAD.addExportType("FEM result VTK (*.vtu *.vtp *.vts *.vtr *.vti)", "feminout.importVTKResults")
|
||||
FreeCAD.addImportType(
|
||||
"FEM result VTK (*.vtk *.VTK *.vtu *.VTU *.pvtu *.PVTU)",
|
||||
"feminout.importVTKResults",
|
||||
)
|
||||
FreeCAD.addExportType(
|
||||
"FEM result VTK (*.vtu *.vtp *.vts *.vtr *.vti)", "feminout.importVTKResults"
|
||||
)
|
||||
|
||||
@@ -71,6 +71,7 @@ class FemWorkbench(Workbench):
|
||||
import Fem
|
||||
import FemGui
|
||||
import femcommands.commands
|
||||
|
||||
# dummy usage to get flake8 and lgtm quiet
|
||||
False if Fem.__name__ else True
|
||||
False if FemGui.__name__ else True
|
||||
|
||||
@@ -46,10 +46,7 @@ import FreeCAD
|
||||
|
||||
|
||||
# ********* analysis objects *********************************************************************
|
||||
def makeAnalysis(
|
||||
doc,
|
||||
name="Analysis"
|
||||
):
|
||||
def makeAnalysis(doc, name="Analysis"):
|
||||
"""makeAnalysis(document, [name]):
|
||||
makes a Fem Analysis object"""
|
||||
obj = doc.addObject("Fem::FemAnalysis", name)
|
||||
@@ -57,343 +54,281 @@ def makeAnalysis(
|
||||
|
||||
|
||||
# ********* constant objects *********************************************************************
|
||||
def makeConstantVacuumPermittivity(
|
||||
doc,
|
||||
name="ConstantVacuumPermittivity"
|
||||
):
|
||||
def makeConstantVacuumPermittivity(doc, name="ConstantVacuumPermittivity"):
|
||||
"""makeConstantVacuumPermittivity(document, [name]):
|
||||
makes a Fem ConstantVacuumPermittivity object"""
|
||||
obj = doc.addObject("Fem::ConstraintPython", name)
|
||||
from femobjects import constant_vacuumpermittivity
|
||||
|
||||
constant_vacuumpermittivity.ConstantVacuumPermittivity(obj)
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_constant_vacuumpermittivity
|
||||
|
||||
view_constant_vacuumpermittivity.VPConstantVacuumPermittivity(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
# ********* constraint objects *******************************************************************
|
||||
def makeConstraintBearing(
|
||||
doc,
|
||||
name="ConstraintBearing"
|
||||
):
|
||||
def makeConstraintBearing(doc, name="ConstraintBearing"):
|
||||
"""makeConstraintBearing(document, [name]):
|
||||
makes a Fem ConstraintBearing object"""
|
||||
obj = doc.addObject("Fem::ConstraintBearing", name)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintBodyHeatSource(
|
||||
doc,
|
||||
name="ConstraintBodyHeatSource"
|
||||
):
|
||||
def makeConstraintBodyHeatSource(doc, name="ConstraintBodyHeatSource"):
|
||||
"""makeConstraintBodyHeatSource(document, [name]):
|
||||
makes a Fem ConstraintBodyHeatSource object"""
|
||||
obj = doc.addObject("Fem::ConstraintPython", name)
|
||||
from femobjects import constraint_bodyheatsource
|
||||
|
||||
constraint_bodyheatsource.ConstraintBodyHeatSource(obj)
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_constraint_bodyheatsource as viewprov
|
||||
|
||||
viewprov.VPConstraintBodyHeatSource(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintCentrif(
|
||||
doc,
|
||||
name="ConstraintCentrif"
|
||||
):
|
||||
def makeConstraintCentrif(doc, name="ConstraintCentrif"):
|
||||
"""makeConstraintCentrif(document, [name]):
|
||||
creates a centrif object to define centrifugal body load constraint"""
|
||||
obj = doc.addObject("Fem::ConstraintPython", name)
|
||||
from femobjects import constraint_centrif
|
||||
|
||||
constraint_centrif.ConstraintCentrif(obj)
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_constraint_centrif
|
||||
|
||||
view_constraint_centrif.VPConstraintCentrif(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintCurrentDensity(
|
||||
doc,
|
||||
name="ConstraintCurrentDensity"
|
||||
):
|
||||
def makeConstraintCurrentDensity(doc, name="ConstraintCurrentDensity"):
|
||||
"""makeConstraintCurrentDensity(document, [name]):
|
||||
makes a Fem CurrentDensity object"""
|
||||
obj = doc.addObject("Fem::ConstraintPython", name)
|
||||
from femobjects import constraint_currentdensity
|
||||
|
||||
constraint_currentdensity.ConstraintCurrentDensity(obj)
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_constraint_currentdensity
|
||||
|
||||
view_constraint_currentdensity.VPConstraintCurrentDensity(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintContact(
|
||||
doc,
|
||||
name="ConstraintContact"
|
||||
):
|
||||
def makeConstraintContact(doc, name="ConstraintContact"):
|
||||
"""makeConstraintContact(document, [name]):
|
||||
makes a Fem ConstraintContact object"""
|
||||
obj = doc.addObject("Fem::ConstraintContact", name)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintDisplacement(
|
||||
doc,
|
||||
name="ConstraintDisplacement"
|
||||
):
|
||||
def makeConstraintDisplacement(doc, name="ConstraintDisplacement"):
|
||||
"""makeConstraintDisplacement(document, [name]):
|
||||
makes a Fem ConstraintDisplacement object"""
|
||||
obj = doc.addObject("Fem::ConstraintDisplacement", name)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintElectrostaticPotential(
|
||||
doc,
|
||||
name="ConstraintElectrostaticPotential"
|
||||
):
|
||||
def makeConstraintElectrostaticPotential(doc, name="ConstraintElectrostaticPotential"):
|
||||
"""makeConstraintElectrostaticPotential(document, [name]):
|
||||
makes a Fem ElectrostaticPotential object"""
|
||||
obj = doc.addObject("Fem::ConstraintPython", name)
|
||||
from femobjects import constraint_electrostaticpotential
|
||||
|
||||
constraint_electrostaticpotential.ConstraintElectrostaticPotential(obj)
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_constraint_electrostaticpotential
|
||||
|
||||
view_constraint_electrostaticpotential.VPConstraintElectroStaticPotential(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintFixed(
|
||||
doc,
|
||||
name="ConstraintFixed"
|
||||
):
|
||||
def makeConstraintFixed(doc, name="ConstraintFixed"):
|
||||
"""makeConstraintFixed(document, [name]):
|
||||
makes a Fem ConstraintFixed object"""
|
||||
obj = doc.addObject("Fem::ConstraintFixed", name)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintRigidBody(
|
||||
doc,
|
||||
name="ConstraintRigidBody"
|
||||
):
|
||||
def makeConstraintRigidBody(doc, name="ConstraintRigidBody"):
|
||||
"""makeConstraintRigidBody(document, [name]):
|
||||
makes a Fem ConstraintRigidBody object"""
|
||||
obj = doc.addObject("Fem::ConstraintRigidBody", name)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintFlowVelocity(
|
||||
doc,
|
||||
name="ConstraintFlowVelocity"
|
||||
):
|
||||
def makeConstraintFlowVelocity(doc, name="ConstraintFlowVelocity"):
|
||||
"""makeConstraintFlowVelocity(document, [name]):
|
||||
makes a Fem ConstraintFlowVelocity object"""
|
||||
obj = doc.addObject("Fem::ConstraintPython", name)
|
||||
from femobjects import constraint_flowvelocity
|
||||
|
||||
constraint_flowvelocity.ConstraintFlowVelocity(obj)
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_constraint_flowvelocity
|
||||
|
||||
view_constraint_flowvelocity.VPConstraintFlowVelocity(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintFluidBoundary(
|
||||
doc,
|
||||
name="ConstraintFluidBoundary"
|
||||
):
|
||||
def makeConstraintFluidBoundary(doc, name="ConstraintFluidBoundary"):
|
||||
"""makeConstraintFluidBoundary(document, name):
|
||||
makes a Fem ConstraintFluidBoundary object"""
|
||||
obj = doc.addObject("Fem::ConstraintFluidBoundary", name)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintForce(
|
||||
doc,
|
||||
name="ConstraintForce"
|
||||
):
|
||||
def makeConstraintForce(doc, name="ConstraintForce"):
|
||||
"""makeConstraintForce(document, [name]):
|
||||
makes a Fem ConstraintForce object"""
|
||||
obj = doc.addObject("Fem::ConstraintForce", name)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintGear(
|
||||
doc,
|
||||
name="ConstraintGear"
|
||||
):
|
||||
def makeConstraintGear(doc, name="ConstraintGear"):
|
||||
"""makeConstraintGear(document, [name]):
|
||||
makes a Fem ConstraintGear object"""
|
||||
obj = doc.addObject("Fem::ConstraintGear", name)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintHeatflux(
|
||||
doc,
|
||||
name="ConstraintHeatflux"
|
||||
):
|
||||
def makeConstraintHeatflux(doc, name="ConstraintHeatflux"):
|
||||
"""makeConstraintHeatflux(document, [name]):
|
||||
makes a Fem ConstraintHeatflux object"""
|
||||
obj = doc.addObject("Fem::ConstraintHeatflux", name)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintInitialFlowVelocity(
|
||||
doc,
|
||||
name="ConstraintInitialFlowVelocity"
|
||||
):
|
||||
def makeConstraintInitialFlowVelocity(doc, name="ConstraintInitialFlowVelocity"):
|
||||
"""makeConstraintInitialFlowVelocity(document, [name]):
|
||||
makes a Fem ConstraintInitialFlowVelocity object"""
|
||||
obj = doc.addObject("Fem::ConstraintPython", name)
|
||||
from femobjects import constraint_initialflowvelocity
|
||||
|
||||
constraint_initialflowvelocity.ConstraintInitialFlowVelocity(obj)
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_constraint_initialflowvelocity
|
||||
|
||||
view_constraint_initialflowvelocity.VPConstraintInitialFlowVelocity(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintInitialPressure(
|
||||
doc,
|
||||
name="ConstraintInitialPressure"
|
||||
):
|
||||
def makeConstraintInitialPressure(doc, name="ConstraintInitialPressure"):
|
||||
"""makeConstraintInitialPressure(document, [name]):
|
||||
makes a Fem ConstraintInitialPressure object"""
|
||||
obj = doc.addObject("Fem::ConstraintPython", name)
|
||||
from femobjects import constraint_initialpressure
|
||||
|
||||
constraint_initialpressure.ConstraintInitialPressure(obj)
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_constraint_initialpressure
|
||||
|
||||
view_constraint_initialpressure.VPConstraintInitialPressure(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintInitialTemperature(
|
||||
doc,
|
||||
name="ConstraintInitialTemperature"
|
||||
):
|
||||
def makeConstraintInitialTemperature(doc, name="ConstraintInitialTemperature"):
|
||||
"""makeConstraintInitialTemperature(document, name):
|
||||
makes a Fem ConstraintInitialTemperature object"""
|
||||
obj = doc.addObject("Fem::ConstraintInitialTemperature", name)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintMagnetization(
|
||||
doc,
|
||||
name="ConstraintMagnetization"
|
||||
):
|
||||
def makeConstraintMagnetization(doc, name="ConstraintMagnetization"):
|
||||
"""makeConstraintMagnetization(document, [name]):
|
||||
makes a Fem Magnetization object"""
|
||||
obj = doc.addObject("Fem::ConstraintPython", name)
|
||||
from femobjects import constraint_magnetization
|
||||
|
||||
constraint_magnetization.ConstraintMagnetization(obj)
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_constraint_magnetization
|
||||
|
||||
view_constraint_magnetization.VPConstraintMagnetization(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintPlaneRotation(
|
||||
doc,
|
||||
name="ConstraintPlaneRotation"
|
||||
):
|
||||
def makeConstraintPlaneRotation(doc, name="ConstraintPlaneRotation"):
|
||||
"""makeConstraintPlaneRotation(document, [name]):
|
||||
makes a Fem ConstraintPlaneRotation object"""
|
||||
obj = doc.addObject("Fem::ConstraintPlaneRotation", name)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintPressure(
|
||||
doc,
|
||||
name="ConstraintPressure"
|
||||
):
|
||||
def makeConstraintPressure(doc, name="ConstraintPressure"):
|
||||
"""makeConstraintPressure(document, [name]):
|
||||
makes a Fem ConstraintPressure object"""
|
||||
obj = doc.addObject("Fem::ConstraintPressure", name)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintPulley(
|
||||
doc,
|
||||
name="ConstraintPulley"
|
||||
):
|
||||
def makeConstraintPulley(doc, name="ConstraintPulley"):
|
||||
"""makeConstraintPulley(document, [name]):
|
||||
makes a Fem ConstraintPulley object"""
|
||||
obj = doc.addObject("Fem::ConstraintPulley", name)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintSelfWeight(
|
||||
doc,
|
||||
name="ConstraintSelfWeight"
|
||||
):
|
||||
def makeConstraintSelfWeight(doc, name="ConstraintSelfWeight"):
|
||||
"""makeConstraintSelfWeight(document, [name]):
|
||||
creates a self weight object to define a gravity load"""
|
||||
obj = doc.addObject("Fem::ConstraintPython", name)
|
||||
from femobjects import constraint_selfweight
|
||||
|
||||
constraint_selfweight.ConstraintSelfWeight(obj)
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_constraint_selfweight
|
||||
view_constraint_selfweight.VPConstraintSelfWeight(
|
||||
obj.ViewObject
|
||||
)
|
||||
|
||||
view_constraint_selfweight.VPConstraintSelfWeight(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintTemperature(
|
||||
doc,
|
||||
name="ConstraintTemperature"
|
||||
):
|
||||
def makeConstraintTemperature(doc, name="ConstraintTemperature"):
|
||||
"""makeConstraintTemperature(document, [name]):
|
||||
makes a Fem ConstraintTemperature object"""
|
||||
obj = doc.addObject("Fem::ConstraintTemperature", name)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintTie(
|
||||
doc,
|
||||
name="ConstraintTie"
|
||||
):
|
||||
def makeConstraintTie(doc, name="ConstraintTie"):
|
||||
"""makeConstraintTie(document, [name]):
|
||||
creates a tie object to define bonded faces constraint"""
|
||||
obj = doc.addObject("Fem::ConstraintPython", name)
|
||||
from femobjects import constraint_tie
|
||||
|
||||
constraint_tie.ConstraintTie(obj)
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_constraint_tie
|
||||
|
||||
view_constraint_tie.VPConstraintTie(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintTransform(
|
||||
doc,
|
||||
name="ConstraintTransform"
|
||||
):
|
||||
def makeConstraintTransform(doc, name="ConstraintTransform"):
|
||||
"""makeConstraintTransform(document, [name]):
|
||||
makes a Fem ConstraintTransform object"""
|
||||
obj = doc.addObject("Fem::ConstraintTransform", name)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintSectionPrint(
|
||||
doc,
|
||||
name="ConstraintSectionPrint"
|
||||
):
|
||||
def makeConstraintSectionPrint(doc, name="ConstraintSectionPrint"):
|
||||
"""makeConstraintSectionPrint(document, [name]):
|
||||
creates a section print object to evaluate forces and moments of defined face"""
|
||||
obj = doc.addObject("Fem::ConstraintPython", name)
|
||||
from femobjects import constraint_sectionprint
|
||||
|
||||
constraint_sectionprint.ConstraintSectionPrint(obj)
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_constraint_sectionprint
|
||||
|
||||
view_constraint_sectionprint.VPConstraintSectionPrint(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintSpring(
|
||||
doc,
|
||||
name="ConstraintSpring"
|
||||
):
|
||||
def makeConstraintSpring(doc, name="ConstraintSpring"):
|
||||
"""makeConstraintSpring(document, [name]):
|
||||
makes a Fem ConstraintSpring object"""
|
||||
obj = doc.addObject("Fem::ConstraintSpring", name)
|
||||
@@ -401,32 +336,28 @@ def makeConstraintSpring(
|
||||
|
||||
|
||||
# ********* element definition objects ***********************************************************
|
||||
def makeElementFluid1D(
|
||||
doc,
|
||||
name="ElementFluid1D"
|
||||
):
|
||||
def makeElementFluid1D(doc, name="ElementFluid1D"):
|
||||
"""makeElementFluid1D(document, [name]):
|
||||
creates a 1D fluid element object to define 1D flow"""
|
||||
obj = doc.addObject("Fem::FeaturePython", name)
|
||||
from femobjects import element_fluid1D
|
||||
|
||||
element_fluid1D.ElementFluid1D(obj)
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_element_fluid1D
|
||||
|
||||
view_element_fluid1D.VPElementFluid1D(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
def makeElementGeometry1D(
|
||||
doc,
|
||||
sectiontype="Rectangular",
|
||||
width=10.0,
|
||||
height=25.0,
|
||||
name="ElementGeometry1D"
|
||||
doc, sectiontype="Rectangular", width=10.0, height=25.0, name="ElementGeometry1D"
|
||||
):
|
||||
"""makeElementGeometry1D(document, [width], [height], [name]):
|
||||
creates a 1D geometry element object to define a cross section"""
|
||||
obj = doc.addObject("Fem::FeaturePython", name)
|
||||
from femobjects import element_geometry1D
|
||||
|
||||
element_geometry1D.ElementGeometry1D(obj)
|
||||
sec_types = element_geometry1D.ElementGeometry1D.known_beam_types
|
||||
if sectiontype not in sec_types:
|
||||
@@ -441,119 +372,107 @@ def makeElementGeometry1D(
|
||||
obj.PipeThickness = width
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_element_geometry1D
|
||||
|
||||
view_element_geometry1D.VPElementGeometry1D(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
def makeElementGeometry2D(
|
||||
doc,
|
||||
thickness=1.0,
|
||||
name="ElementGeometry2D"
|
||||
):
|
||||
def makeElementGeometry2D(doc, thickness=1.0, name="ElementGeometry2D"):
|
||||
"""makeElementGeometry2D(document, [thickness], [name]):
|
||||
creates a 2D geometry element object to define a plate thickness"""
|
||||
obj = doc.addObject("Fem::FeaturePython", name)
|
||||
from femobjects import element_geometry2D
|
||||
|
||||
element_geometry2D.ElementGeometry2D(obj)
|
||||
obj.Thickness = thickness
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_element_geometry2D
|
||||
|
||||
view_element_geometry2D.VPElementGeometry2D(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
def makeElementRotation1D(
|
||||
doc,
|
||||
name="ElementRotation1D"
|
||||
):
|
||||
def makeElementRotation1D(doc, name="ElementRotation1D"):
|
||||
"""makeElementRotation1D(document, [name]):
|
||||
creates a 1D geometry rotation element object to rotate a 1D cross section"""
|
||||
obj = doc.addObject("Fem::FeaturePython", name)
|
||||
from femobjects import element_rotation1D
|
||||
|
||||
element_rotation1D.ElementRotation1D(obj)
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_element_rotation1D
|
||||
|
||||
view_element_rotation1D.VPElementRotation1D(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
# ********* material objects *********************************************************************
|
||||
def makeMaterialFluid(
|
||||
doc,
|
||||
name="MaterialFluid"
|
||||
):
|
||||
def makeMaterialFluid(doc, name="MaterialFluid"):
|
||||
"""makeMaterialFluid(document, [name]):
|
||||
makes a FEM Material for fluid"""
|
||||
obj = doc.addObject("App::MaterialObjectPython", name)
|
||||
from femobjects import material_common
|
||||
|
||||
material_common.MaterialCommon(obj)
|
||||
obj.Category = "Fluid"
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_material_common
|
||||
|
||||
view_material_common.VPMaterialCommon(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
def makeMaterialMechanicalNonlinear(
|
||||
doc,
|
||||
base_material,
|
||||
name="MaterialMechanicalNonlinear"
|
||||
):
|
||||
def makeMaterialMechanicalNonlinear(doc, base_material, name="MaterialMechanicalNonlinear"):
|
||||
"""makeMaterialMechanicalNonlinear(document, base_material, [name]):
|
||||
creates a nonlinear material object"""
|
||||
obj = doc.addObject("Fem::FeaturePython", name)
|
||||
from femobjects import material_mechanicalnonlinear
|
||||
|
||||
material_mechanicalnonlinear.MaterialMechanicalNonlinear(obj)
|
||||
obj.LinearBaseMaterial = base_material
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_material_mechanicalnonlinear
|
||||
view_material_mechanicalnonlinear.VPMaterialMechanicalNonlinear(
|
||||
obj.ViewObject
|
||||
)
|
||||
|
||||
view_material_mechanicalnonlinear.VPMaterialMechanicalNonlinear(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
def makeMaterialReinforced(
|
||||
doc,
|
||||
name="MaterialReinforced"
|
||||
):
|
||||
def makeMaterialReinforced(doc, name="MaterialReinforced"):
|
||||
"""makeMaterialReinforced(document, [matrix_material], [reinforcement_material], [name]):
|
||||
creates a reinforced material object"""
|
||||
obj = doc.addObject("App::MaterialObjectPython", name)
|
||||
from femobjects import material_reinforced
|
||||
|
||||
material_reinforced.MaterialReinforced(obj)
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_material_reinforced
|
||||
|
||||
view_material_reinforced.VPMaterialReinforced(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
def makeMaterialSolid(
|
||||
doc,
|
||||
name="MaterialSolid"
|
||||
):
|
||||
def makeMaterialSolid(doc, name="MaterialSolid"):
|
||||
"""makeMaterialSolid(document, [name]):
|
||||
makes a FEM Material for solid"""
|
||||
obj = doc.addObject("App::MaterialObjectPython", name)
|
||||
from femobjects import material_common
|
||||
|
||||
material_common.MaterialCommon(obj)
|
||||
obj.Category = "Solid"
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_material_common
|
||||
|
||||
view_material_common.VPMaterialCommon(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
# ********* mesh objects *************************************************************************
|
||||
def makeMeshBoundaryLayer(
|
||||
doc,
|
||||
base_mesh,
|
||||
name="MeshBoundaryLayer"
|
||||
):
|
||||
def makeMeshBoundaryLayer(doc, base_mesh, name="MeshBoundaryLayer"):
|
||||
"""makeMeshBoundaryLayer(document, base_mesh, [name]):
|
||||
creates a FEM mesh BoundaryLayer object to define boundary layer properties"""
|
||||
obj = doc.addObject("Fem::FeaturePython", name)
|
||||
from femobjects import mesh_boundarylayer
|
||||
|
||||
mesh_boundarylayer.MeshBoundaryLayer(obj)
|
||||
# obj.BaseMesh = base_mesh
|
||||
# App::PropertyLinkList does not support append
|
||||
@@ -563,35 +482,32 @@ def makeMeshBoundaryLayer(
|
||||
base_mesh.MeshBoundaryLayerList = tmplist
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_mesh_boundarylayer
|
||||
|
||||
view_mesh_boundarylayer.VPMeshBoundaryLayer(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
def makeMeshGmsh(
|
||||
doc,
|
||||
name="MeshGmsh"
|
||||
):
|
||||
def makeMeshGmsh(doc, name="MeshGmsh"):
|
||||
"""makeMeshGmsh(document, [name]):
|
||||
makes a Gmsh FEM mesh object"""
|
||||
obj = doc.addObject("Fem::FemMeshObjectPython", name)
|
||||
from femobjects import mesh_gmsh
|
||||
|
||||
mesh_gmsh.MeshGmsh(obj)
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_mesh_gmsh
|
||||
|
||||
view_mesh_gmsh.VPMeshGmsh(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
def makeMeshGroup(
|
||||
doc,
|
||||
base_mesh,
|
||||
use_label=False,
|
||||
name="MeshGroup"
|
||||
):
|
||||
def makeMeshGroup(doc, base_mesh, use_label=False, name="MeshGroup"):
|
||||
"""makeMeshGroup(document, base_mesh, [use_label], [name]):
|
||||
creates a FEM mesh refinement object to define properties for a region of a FEM mesh"""
|
||||
creates a FEM mesh refinement object to define properties for a region of a FEM mesh
|
||||
"""
|
||||
obj = doc.addObject("Fem::FeaturePython", name)
|
||||
from femobjects import mesh_group
|
||||
|
||||
mesh_group.MeshGroup(obj)
|
||||
obj.UseLabel = use_label
|
||||
# obj.BaseMesh = base_mesh
|
||||
@@ -602,30 +518,25 @@ def makeMeshGroup(
|
||||
base_mesh.MeshGroupList = tmplist
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_mesh_group
|
||||
|
||||
view_mesh_group.VPMeshGroup(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
def makeMeshNetgen(
|
||||
doc,
|
||||
name="MeshNetgen"
|
||||
):
|
||||
def makeMeshNetgen(doc, name="MeshNetgen"):
|
||||
"""makeMeshNetgen(document, [name]):
|
||||
makes a Fem MeshShapeNetgenObject object"""
|
||||
obj = doc.addObject("Fem::FemMeshShapeNetgenObject", name)
|
||||
return obj
|
||||
|
||||
|
||||
def makeMeshRegion(
|
||||
doc,
|
||||
base_mesh,
|
||||
element_length=0.0,
|
||||
name="MeshRegion"
|
||||
):
|
||||
def makeMeshRegion(doc, base_mesh, element_length=0.0, name="MeshRegion"):
|
||||
"""makeMeshRegion(document, base_mesh, [element_length], [name]):
|
||||
creates a FEM mesh refinement object to define properties for a refinement of a FEM mesh"""
|
||||
creates a FEM mesh refinement object to define properties for a refinement of a FEM mesh
|
||||
"""
|
||||
obj = doc.addObject("Fem::FeaturePython", name)
|
||||
from femobjects import mesh_region
|
||||
|
||||
mesh_region.MeshRegion(obj)
|
||||
obj.CharacteristicLength = element_length
|
||||
# obj.BaseMesh = base_mesh
|
||||
@@ -636,45 +547,40 @@ def makeMeshRegion(
|
||||
base_mesh.MeshRegionList = tmplist
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_mesh_region
|
||||
|
||||
view_mesh_region.VPMeshRegion(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
def makeMeshResult(
|
||||
doc,
|
||||
name="MeshResult"
|
||||
):
|
||||
def makeMeshResult(doc, name="MeshResult"):
|
||||
"""makeMeshResult(document, name): makes a Fem MeshResult object"""
|
||||
obj = doc.addObject("Fem::FemMeshObjectPython", name)
|
||||
from femobjects import mesh_result
|
||||
|
||||
mesh_result.MeshResult(obj)
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_mesh_result
|
||||
|
||||
view_mesh_result.VPFemMeshResult(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
# ********* post processing objects **************************************************************
|
||||
def makeResultMechanical(
|
||||
doc,
|
||||
name="ResultMechanical"
|
||||
):
|
||||
def makeResultMechanical(doc, name="ResultMechanical"):
|
||||
"""makeResultMechanical(document, [name]):
|
||||
creates a mechanical result object to hold FEM results"""
|
||||
obj = doc.addObject("Fem::FemResultObjectPython", name)
|
||||
from femobjects import result_mechanical
|
||||
|
||||
result_mechanical.ResultMechanical(obj)
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_result_mechanical
|
||||
|
||||
view_result_mechanical.VPResultMechanical(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
def makePostVtkFilterClipRegion(
|
||||
doc,
|
||||
base_vtk_result,
|
||||
name="VtkFilterClipRegion"
|
||||
):
|
||||
def makePostVtkFilterClipRegion(doc, base_vtk_result, name="VtkFilterClipRegion"):
|
||||
"""makePostVtkFilterClipRegion(document, base_vtk_result, [name]):
|
||||
creates a FEM post processing region clip filter object (vtk based)"""
|
||||
obj = doc.addObject("Fem::FemPostClipFilter", name)
|
||||
@@ -685,11 +591,7 @@ def makePostVtkFilterClipRegion(
|
||||
return obj
|
||||
|
||||
|
||||
def makePostVtkFilterClipScalar(
|
||||
doc,
|
||||
base_vtk_result,
|
||||
name="VtkFilterClipScalar"
|
||||
):
|
||||
def makePostVtkFilterClipScalar(doc, base_vtk_result, name="VtkFilterClipScalar"):
|
||||
"""makePostVtkFilterClipScalar(document, base_vtk_result, [name]):
|
||||
creates a FEM post processing scalar clip filter object (vtk based)"""
|
||||
obj = doc.addObject("Fem::FemPostScalarClipFilter", name)
|
||||
@@ -700,11 +602,7 @@ def makePostVtkFilterClipScalar(
|
||||
return obj
|
||||
|
||||
|
||||
def makePostVtkFilterCutFunction(
|
||||
doc,
|
||||
base_vtk_result,
|
||||
name="VtkFilterCutFunction"
|
||||
):
|
||||
def makePostVtkFilterCutFunction(doc, base_vtk_result, name="VtkFilterCutFunction"):
|
||||
"""makePostVtkFilterCutFunction(document, base_vtk_result, [name]):
|
||||
creates a FEM post processing cut function filter object (vtk based)"""
|
||||
obj = doc.addObject("Fem::FemPostClipFilter", name)
|
||||
@@ -715,11 +613,7 @@ def makePostVtkFilterCutFunction(
|
||||
return obj
|
||||
|
||||
|
||||
def makePostVtkFilterWarp(
|
||||
doc,
|
||||
base_vtk_result,
|
||||
name="VtkFilterWarp"
|
||||
):
|
||||
def makePostVtkFilterWarp(doc, base_vtk_result, name="VtkFilterWarp"):
|
||||
"""makePostVtkFilterWarp(document, base_vtk_result, [name]):
|
||||
creates a FEM post processing warp filter object (vtk based)"""
|
||||
obj = doc.addObject("Fem::FemPostWarpVectorFilter", name)
|
||||
@@ -730,11 +624,7 @@ def makePostVtkFilterWarp(
|
||||
return obj
|
||||
|
||||
|
||||
def makePostVtkFilterContours(
|
||||
doc,
|
||||
base_vtk_result,
|
||||
name="VtkFilterContours"
|
||||
):
|
||||
def makePostVtkFilterContours(doc, base_vtk_result, name="VtkFilterContours"):
|
||||
"""makePostVtkFilterContours(document, base_vtk_result, [name]):
|
||||
creates a FEM post processing contours filter object (vtk based)"""
|
||||
obj = doc.addObject("Fem::FemPostContoursFilter", name)
|
||||
@@ -745,11 +635,7 @@ def makePostVtkFilterContours(
|
||||
return obj
|
||||
|
||||
|
||||
def makePostVtkResult(
|
||||
doc,
|
||||
base_result,
|
||||
name="VtkResult"
|
||||
):
|
||||
def makePostVtkResult(doc, base_result, name="VtkResult"):
|
||||
"""makePostVtkResult(document, base_result, [name]):
|
||||
creates a FEM post processing result object (vtk based) to hold FEM results"""
|
||||
Pipeline_Name = "Pipeline_" + name
|
||||
@@ -763,187 +649,151 @@ def makePostVtkResult(
|
||||
|
||||
|
||||
# ********* solver objects ***********************************************************************
|
||||
def makeEquationDeformation(
|
||||
doc,
|
||||
base_solver=None,
|
||||
name="Deformation"
|
||||
):
|
||||
def makeEquationDeformation(doc, base_solver=None, name="Deformation"):
|
||||
"""makeEquationDeformation(document, [base_solver], [name]):
|
||||
creates a FEM deformation (nonlinear elasticity) equation for a solver"""
|
||||
from femsolver.elmer.equations import deformation
|
||||
|
||||
obj = deformation.create(doc, name)
|
||||
if base_solver:
|
||||
base_solver.addObject(obj)
|
||||
return obj
|
||||
|
||||
|
||||
def makeEquationElasticity(
|
||||
doc,
|
||||
base_solver=None,
|
||||
name="Elasticity"
|
||||
):
|
||||
def makeEquationElasticity(doc, base_solver=None, name="Elasticity"):
|
||||
"""makeEquationElasticity(document, [base_solver], [name]):
|
||||
creates a FEM elasticity equation for a solver"""
|
||||
from femsolver.elmer.equations import elasticity
|
||||
|
||||
obj = elasticity.create(doc, name)
|
||||
if base_solver:
|
||||
base_solver.addObject(obj)
|
||||
return obj
|
||||
|
||||
|
||||
def makeEquationElectricforce(
|
||||
doc,
|
||||
base_solver=None,
|
||||
name="Electricforce"
|
||||
):
|
||||
def makeEquationElectricforce(doc, base_solver=None, name="Electricforce"):
|
||||
"""makeEquationElectricforce(document, [base_solver], [name]):
|
||||
creates a FEM Electricforce equation for a solver"""
|
||||
from femsolver.elmer.equations import electricforce
|
||||
|
||||
obj = electricforce.create(doc, name)
|
||||
if base_solver:
|
||||
base_solver.addObject(obj)
|
||||
return obj
|
||||
|
||||
|
||||
def makeEquationElectrostatic(
|
||||
doc,
|
||||
base_solver=None,
|
||||
name="Electrostatic"
|
||||
):
|
||||
def makeEquationElectrostatic(doc, base_solver=None, name="Electrostatic"):
|
||||
"""makeEquationElectrostatic(document, [base_solver], [name]):
|
||||
creates a FEM electrostatic equation for a solver"""
|
||||
from femsolver.elmer.equations import electrostatic
|
||||
|
||||
obj = electrostatic.create(doc, name)
|
||||
if base_solver:
|
||||
base_solver.addObject(obj)
|
||||
return obj
|
||||
|
||||
|
||||
def makeEquationFlow(
|
||||
doc,
|
||||
base_solver=None,
|
||||
name="Flow"
|
||||
):
|
||||
def makeEquationFlow(doc, base_solver=None, name="Flow"):
|
||||
"""makeEquationFlow(document, [base_solver], [name]):
|
||||
creates a FEM flow equation for a solver"""
|
||||
from femsolver.elmer.equations import flow
|
||||
|
||||
obj = flow.create(doc, name)
|
||||
if base_solver:
|
||||
base_solver.addObject(obj)
|
||||
return obj
|
||||
|
||||
|
||||
def makeEquationFlux(
|
||||
doc,
|
||||
base_solver=None,
|
||||
name="Flux"
|
||||
):
|
||||
def makeEquationFlux(doc, base_solver=None, name="Flux"):
|
||||
"""makeEquationFlux(document, [base_solver], [name]):
|
||||
creates a FEM flux equation for a solver"""
|
||||
from femsolver.elmer.equations import flux
|
||||
|
||||
obj = flux.create(doc, name)
|
||||
if base_solver:
|
||||
base_solver.addObject(obj)
|
||||
return obj
|
||||
|
||||
|
||||
def makeEquationHeat(
|
||||
doc,
|
||||
base_solver=None,
|
||||
name="Heat"
|
||||
):
|
||||
def makeEquationHeat(doc, base_solver=None, name="Heat"):
|
||||
"""makeEquationHeat(document, [base_solver], [name]):
|
||||
creates a FEM heat equation for a solver"""
|
||||
from femsolver.elmer.equations import heat
|
||||
|
||||
obj = heat.create(doc, name)
|
||||
if base_solver:
|
||||
base_solver.addObject(obj)
|
||||
return obj
|
||||
|
||||
|
||||
def makeEquationMagnetodynamic(
|
||||
doc,
|
||||
base_solver=None,
|
||||
name="Magnetodynamic"
|
||||
):
|
||||
def makeEquationMagnetodynamic(doc, base_solver=None, name="Magnetodynamic"):
|
||||
"""makeEquationMagnetodynamic(document, [base_solver], [name]):
|
||||
creates a FEM magnetodynamic equation for a solver"""
|
||||
from femsolver.elmer.equations import magnetodynamic
|
||||
|
||||
obj = magnetodynamic.create(doc, name)
|
||||
if base_solver:
|
||||
base_solver.addObject(obj)
|
||||
return obj
|
||||
|
||||
|
||||
def makeEquationMagnetodynamic2D(
|
||||
doc,
|
||||
base_solver=None,
|
||||
name="Magnetodynamic2D"
|
||||
):
|
||||
def makeEquationMagnetodynamic2D(doc, base_solver=None, name="Magnetodynamic2D"):
|
||||
"""makeEquationMagnetodynamic2D(document, [base_solver], [name]):
|
||||
creates a FEM magnetodynamic2D equation for a solver"""
|
||||
from femsolver.elmer.equations import magnetodynamic2D
|
||||
|
||||
obj = magnetodynamic2D.create(doc, name)
|
||||
if base_solver:
|
||||
base_solver.addObject(obj)
|
||||
return obj
|
||||
|
||||
|
||||
def makeSolverCalculiXCcxTools(
|
||||
doc,
|
||||
name="SolverCcxTools"
|
||||
):
|
||||
def makeSolverCalculiXCcxTools(doc, name="SolverCcxTools"):
|
||||
"""makeSolverCalculiXCcxTools(document, [name]):
|
||||
makes a Calculix solver object for the ccx tools module"""
|
||||
obj = doc.addObject("Fem::FemSolverObjectPython", name)
|
||||
from femobjects import solver_ccxtools
|
||||
|
||||
solver_ccxtools.SolverCcxTools(obj)
|
||||
if FreeCAD.GuiUp:
|
||||
from femviewprovider import view_solver_ccxtools
|
||||
|
||||
view_solver_ccxtools.VPSolverCcxTools(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
def makeSolverCalculix(
|
||||
doc,
|
||||
name="SolverCalculix"
|
||||
):
|
||||
def makeSolverCalculix(doc, name="SolverCalculix"):
|
||||
"""makeSolverCalculix(document, [name]):
|
||||
makes a Calculix solver object"""
|
||||
import femsolver.calculix.solver
|
||||
|
||||
obj = femsolver.calculix.solver.create(doc, name)
|
||||
return obj
|
||||
|
||||
|
||||
def makeSolverElmer(
|
||||
doc,
|
||||
name="SolverElmer"
|
||||
):
|
||||
def makeSolverElmer(doc, name="SolverElmer"):
|
||||
"""makeSolverElmer(document, [name]):
|
||||
makes a Elmer solver object"""
|
||||
import femsolver.elmer.solver
|
||||
|
||||
obj = femsolver.elmer.solver.create(doc, name)
|
||||
return obj
|
||||
|
||||
|
||||
def makeSolverMystran(
|
||||
doc,
|
||||
name="SolverMystran"
|
||||
):
|
||||
def makeSolverMystran(doc, name="SolverMystran"):
|
||||
"""makeSolverMystran(document, [name]):
|
||||
makes a Mystran solver object"""
|
||||
import femsolver.mystran.solver
|
||||
|
||||
obj = femsolver.mystran.solver.create(doc, name)
|
||||
return obj
|
||||
|
||||
|
||||
def makeSolverZ88(
|
||||
doc,
|
||||
name="SolverZ88"
|
||||
):
|
||||
def makeSolverZ88(doc, name="SolverZ88"):
|
||||
"""makeSolverZ88(document, [name]):
|
||||
makes a Z88 solver object"""
|
||||
import femsolver.z88.solver
|
||||
|
||||
obj = femsolver.z88.solver.create(doc, name)
|
||||
return obj
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ These coding rules apply to FEM module code only. Other modules or the base syst
|
||||
|
||||
## Spelling
|
||||
- Be mindful of spelling. Spell checks are quite often neglected.
|
||||
- Utilize [codespell](https://github.com/codespell-project/codespell) to discover and quickly correct spelling errors.
|
||||
- Utilize [codespell](https://github.com/codespell-project/codespell) to discover and quickly correct spelling errors.
|
||||
|
||||
```bash
|
||||
# Find typos
|
||||
@@ -14,9 +14,9 @@ These coding rules apply to FEM module code only. Other modules or the base syst
|
||||
codespell -i 3 -w -S *.ts -S *.dyn -S *.svg -L childs,dof,dum,freez,methode,nd,normaly,programm,som,uint,vertexes,inout src/Mod/Fem/
|
||||
```
|
||||
|
||||
**Notes:**
|
||||
1) We recommend running the dev version as it uses the most up to date typo dictionaries.
|
||||
2) To find the most amount of typos we recommend running a quick `pip install --upgrade`
|
||||
**Notes:**
|
||||
1) We recommend running the dev version as it uses the most up to date typo dictionaries.
|
||||
2) To find the most amount of typos we recommend running a quick `pip install --upgrade`
|
||||
See the [codespell docs](https://github.com/codespell-project/codespell#updating) for more info.
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ These coding rules apply to FEM module code only. Other modules or the base syst
|
||||
- One empty line
|
||||
- relative imports
|
||||
- One empty line
|
||||
- FreeCAD Gui imports:
|
||||
- FreeCAD Gui imports:
|
||||
- The import of Gui modules should be guarded by a 'if FreeCAD.GuiUp:'
|
||||
- On Gui only modules the guard is not needed
|
||||
- Same as above but without a empty line
|
||||
@@ -99,7 +99,7 @@ find src/Mod/Fem/ -name "*\.py" | xargs -I [] flake8 --ignore=E266,W503 --max-li
|
||||
- print() vs. FreeCAD.Console.PrintMessage()
|
||||
- `FreeCAD.Console.PrintMessage()` or Log or Error should be used
|
||||
- `print()` should be used for debugging only
|
||||
- [forum topic](https://forum.freecad.org/viewtopic.php?f=10&t=39110)
|
||||
- [forum topic](https://forum.freecad.org/viewtopic.php?f=10&t=39110)
|
||||
- BTW: Console prints need a new line where as print does not need one
|
||||
- type checking:
|
||||
- do not use hasattr(obj, "Proxy") and obj.Proxy.Type
|
||||
@@ -114,7 +114,7 @@ find src/Mod/Fem/ -name "*\.py" | xargs -I [] flake8 --ignore=E266,W503 --max-li
|
||||
- FreeCAD Python console
|
||||
- in code examples which will be copied in FreeCAD Python console
|
||||
- it is common to use App.ActiveDocument.some_obj or method
|
||||
|
||||
|
||||
### Documenting
|
||||
Python style is preferred over Doxygen style
|
||||
- see `ccx` tools module in fem tools package
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -41,7 +41,7 @@ if FreeCAD.GuiUp:
|
||||
import FemGui
|
||||
|
||||
|
||||
class CommandManager(object):
|
||||
class CommandManager:
|
||||
|
||||
def __init__(self):
|
||||
|
||||
@@ -49,7 +49,7 @@ class CommandManager(object):
|
||||
self.pixmap = self.command
|
||||
self.menutext = self.__class__.__name__.lstrip("_")
|
||||
self.accel = ""
|
||||
self.tooltip = "Creates a {}".format(self.menutext)
|
||||
self.tooltip = f"Creates a {self.menutext}"
|
||||
self.resources = None
|
||||
|
||||
self.is_active = None
|
||||
@@ -64,7 +64,7 @@ class CommandManager(object):
|
||||
"Pixmap": self.pixmap,
|
||||
"MenuText": QtCore.QT_TRANSLATE_NOOP(self.command, self.menutext),
|
||||
"Accel": self.accel,
|
||||
"ToolTip": QtCore.QT_TRANSLATE_NOOP(self.command, self.tooltip)
|
||||
"ToolTip": QtCore.QT_TRANSLATE_NOOP(self.command, self.tooltip),
|
||||
}
|
||||
return self.resources
|
||||
|
||||
@@ -76,10 +76,7 @@ class CommandManager(object):
|
||||
elif self.is_active == "with_document":
|
||||
active = FreeCADGui.ActiveDocument is not None
|
||||
elif self.is_active == "with_analysis":
|
||||
active = (
|
||||
FemGui.getActiveAnalysis() is not None
|
||||
and self.active_analysis_in_active_doc()
|
||||
)
|
||||
active = FemGui.getActiveAnalysis() is not None and self.active_analysis_in_active_doc()
|
||||
elif self.is_active == "with_results":
|
||||
active = (
|
||||
FemGui.getActiveAnalysis() is not None
|
||||
@@ -93,24 +90,14 @@ class CommandManager(object):
|
||||
and self.result_selected()
|
||||
)
|
||||
elif self.is_active == "with_part_feature":
|
||||
active = (
|
||||
FreeCADGui.ActiveDocument is not None
|
||||
and self.part_feature_selected()
|
||||
)
|
||||
active = FreeCADGui.ActiveDocument is not None and self.part_feature_selected()
|
||||
elif self.is_active == "with_femmesh":
|
||||
active = (
|
||||
FreeCADGui.ActiveDocument is not None
|
||||
and self.femmesh_selected()
|
||||
)
|
||||
active = FreeCADGui.ActiveDocument is not None and self.femmesh_selected()
|
||||
elif self.is_active == "with_gmsh_femmesh":
|
||||
active = (
|
||||
FreeCADGui.ActiveDocument is not None
|
||||
and self.gmsh_femmesh_selected()
|
||||
)
|
||||
active = FreeCADGui.ActiveDocument is not None and self.gmsh_femmesh_selected()
|
||||
elif self.is_active == "with_femmesh_andor_res":
|
||||
active = (
|
||||
FreeCADGui.ActiveDocument is not None
|
||||
and self.with_femmesh_andor_res_selected()
|
||||
FreeCADGui.ActiveDocument is not None and self.with_femmesh_andor_res_selected()
|
||||
)
|
||||
elif self.is_active == "with_material":
|
||||
active = (
|
||||
@@ -301,20 +288,12 @@ class CommandManager(object):
|
||||
# methods to add the objects to the document in FreeCADGui mode
|
||||
|
||||
def add_obj_on_gui_set_edit(self, objtype):
|
||||
FreeCAD.ActiveDocument.openTransaction(
|
||||
"Create Fem{}"
|
||||
.format(objtype)
|
||||
)
|
||||
FreeCADGui.addModule(
|
||||
"ObjectsFem"
|
||||
)
|
||||
FreeCADGui.addModule(
|
||||
"FemGui"
|
||||
)
|
||||
FreeCAD.ActiveDocument.openTransaction(f"Create Fem{objtype}")
|
||||
FreeCADGui.addModule("ObjectsFem")
|
||||
FreeCADGui.addModule("FemGui")
|
||||
FreeCADGui.doCommand(
|
||||
"FemGui.getActiveAnalysis().addObject(ObjectsFem."
|
||||
"make{}(FreeCAD.ActiveDocument))"
|
||||
.format(objtype)
|
||||
"make{}(FreeCAD.ActiveDocument))".format(objtype)
|
||||
)
|
||||
# no other obj should be selected if we go in task panel
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
@@ -324,20 +303,12 @@ class CommandManager(object):
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def add_obj_on_gui_noset_edit(self, objtype):
|
||||
FreeCAD.ActiveDocument.openTransaction(
|
||||
"Create Fem{}"
|
||||
.format(objtype)
|
||||
)
|
||||
FreeCADGui.addModule(
|
||||
"ObjectsFem"
|
||||
)
|
||||
FreeCADGui.addModule(
|
||||
"FemGui"
|
||||
)
|
||||
FreeCAD.ActiveDocument.openTransaction(f"Create Fem{objtype}")
|
||||
FreeCADGui.addModule("ObjectsFem")
|
||||
FreeCADGui.addModule("FemGui")
|
||||
FreeCADGui.doCommand(
|
||||
"FemGui.getActiveAnalysis().addObject(ObjectsFem."
|
||||
"make{}(FreeCAD.ActiveDocument))"
|
||||
.format(objtype)
|
||||
"make{}(FreeCAD.ActiveDocument))".format(objtype)
|
||||
)
|
||||
# FreeCAD.ActiveDocument.commitTransaction() # solver command class had this line
|
||||
# no clear selection is done
|
||||
@@ -347,23 +318,15 @@ class CommandManager(object):
|
||||
# like add_obj_on_gui_noset_edit but the parent object
|
||||
# is expanded in the tree to see the added obj
|
||||
# the added obj is also selected to enable direct additions to it
|
||||
FreeCAD.ActiveDocument.openTransaction(
|
||||
"Create Fem{}"
|
||||
.format(objtype)
|
||||
)
|
||||
FreeCADGui.addModule(
|
||||
"ObjectsFem"
|
||||
)
|
||||
FreeCADGui.addModule(
|
||||
"FemGui"
|
||||
)
|
||||
FreeCAD.ActiveDocument.openTransaction(f"Create Fem{objtype}")
|
||||
FreeCADGui.addModule("ObjectsFem")
|
||||
FreeCADGui.addModule("FemGui")
|
||||
# expand parent obj in tree view if selected
|
||||
expandParentObject()
|
||||
# add the object
|
||||
FreeCADGui.doCommand(
|
||||
"addedObj = FemGui.getActiveAnalysis().addObject(ObjectsFem."
|
||||
"make{}(FreeCAD.ActiveDocument))[0]"
|
||||
.format(objtype)
|
||||
"make{}(FreeCAD.ActiveDocument))[0]".format(objtype)
|
||||
)
|
||||
# select only added object
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
@@ -372,17 +335,11 @@ class CommandManager(object):
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def add_obj_on_gui_selobj_set_edit(self, objtype):
|
||||
FreeCAD.ActiveDocument.openTransaction(
|
||||
"Create Fem{}"
|
||||
.format(objtype)
|
||||
)
|
||||
FreeCADGui.addModule(
|
||||
"ObjectsFem"
|
||||
)
|
||||
FreeCAD.ActiveDocument.openTransaction(f"Create Fem{objtype}")
|
||||
FreeCADGui.addModule("ObjectsFem")
|
||||
FreeCADGui.doCommand(
|
||||
"ObjectsFem.make{}("
|
||||
"FreeCAD.ActiveDocument, FreeCAD.ActiveDocument.{})"
|
||||
.format(objtype, self.selobj.Name)
|
||||
"FreeCAD.ActiveDocument, FreeCAD.ActiveDocument.{})".format(objtype, self.selobj.Name)
|
||||
)
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
FreeCADGui.doCommand(
|
||||
@@ -391,17 +348,11 @@ class CommandManager(object):
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def add_obj_on_gui_selobj_noset_edit(self, objtype):
|
||||
FreeCAD.ActiveDocument.openTransaction(
|
||||
"Create Fem{}"
|
||||
.format(objtype)
|
||||
)
|
||||
FreeCADGui.addModule(
|
||||
"ObjectsFem"
|
||||
)
|
||||
FreeCAD.ActiveDocument.openTransaction(f"Create Fem{objtype}")
|
||||
FreeCADGui.addModule("ObjectsFem")
|
||||
FreeCADGui.doCommand(
|
||||
"ObjectsFem.make{}("
|
||||
"FreeCAD.ActiveDocument, FreeCAD.ActiveDocument.{})"
|
||||
.format(objtype, self.selobj.Name)
|
||||
"FreeCAD.ActiveDocument, FreeCAD.ActiveDocument.{})".format(objtype, self.selobj.Name)
|
||||
)
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
@@ -409,17 +360,11 @@ class CommandManager(object):
|
||||
def add_obj_on_gui_selobj_expand_noset_edit(self, objtype):
|
||||
# like add_obj_on_gui_selobj_noset_edit but the selection is kept
|
||||
# and the selobj is expanded in the tree to see the added obj
|
||||
FreeCAD.ActiveDocument.openTransaction(
|
||||
"Create Fem{}"
|
||||
.format(objtype)
|
||||
)
|
||||
FreeCADGui.addModule(
|
||||
"ObjectsFem"
|
||||
)
|
||||
FreeCAD.ActiveDocument.openTransaction(f"Create Fem{objtype}")
|
||||
FreeCADGui.addModule("ObjectsFem")
|
||||
FreeCADGui.doCommand(
|
||||
"ObjectsFem.make{}("
|
||||
"FreeCAD.ActiveDocument, FreeCAD.ActiveDocument.{})"
|
||||
.format(objtype, self.selobj.Name)
|
||||
"FreeCAD.ActiveDocument, FreeCAD.ActiveDocument.{})".format(objtype, self.selobj.Name)
|
||||
)
|
||||
# expand selobj in tree view
|
||||
expandParentObject()
|
||||
|
||||
@@ -63,6 +63,7 @@ def setup_boxanalysisbase(doc=None, solvertype="ccxtools"):
|
||||
|
||||
# mesh
|
||||
from .meshes.mesh_boxanalysis_tetra10 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
|
||||
@@ -37,12 +37,14 @@ def get_information():
|
||||
"constraints": [],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "solid",
|
||||
"equations": ["frequency"]
|
||||
"equations": ["frequency"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.boxanalysis_frequency import setup
|
||||
@@ -53,6 +55,7 @@ See forum topic post:
|
||||
...
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -72,7 +75,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj.AnalysisType = "frequency"
|
||||
solver_obj.GeometricalNonlinearity = "linear"
|
||||
|
||||
@@ -39,12 +39,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force", "pressure"],
|
||||
"solvers": ["ccxtools", "elmer"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.boxanalysis_static import setup
|
||||
@@ -55,6 +57,7 @@ See forum topic post:
|
||||
...
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -75,7 +78,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
elif solvertype == "elmer":
|
||||
solver_obj = ObjectsFem.makeSolverElmer(doc, "SolverElmer")
|
||||
ObjectsFem.makeEquationElasticity(doc, solver_obj)
|
||||
|
||||
@@ -39,12 +39,14 @@ def get_information():
|
||||
"constraints": ["displacement", "force"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "solid",
|
||||
"equations": ["buckling"]
|
||||
"equations": ["buckling"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.buckling_lateraltorsionalbuckling import setup
|
||||
@@ -65,6 +67,7 @@ flange load for a buckling factor of 1.00:
|
||||
43280000 Nmm / 278.6 mm = 155348 N
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -108,7 +111,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Unknown or unsupported solver type: {}. "
|
||||
@@ -125,10 +128,10 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
analysis.addObject(solver_obj)
|
||||
|
||||
# shell thicknesses
|
||||
thickness_flanges = ObjectsFem.makeElementGeometry2D(doc, 10.7, 'Thickness_Flanges')
|
||||
thickness_flanges = ObjectsFem.makeElementGeometry2D(doc, 10.7, "Thickness_Flanges")
|
||||
thickness_flanges.References = [(geom_obj, ("Face1", "Face2", "Face3", "Face4"))]
|
||||
analysis.addObject(thickness_flanges)
|
||||
thickness_web = ObjectsFem.makeElementGeometry2D(doc, 7.1, 'Thickness_Web')
|
||||
thickness_web = ObjectsFem.makeElementGeometry2D(doc, 7.1, "Thickness_Web")
|
||||
thickness_web.References = [(geom_obj, "Face5")]
|
||||
analysis.addObject(thickness_web)
|
||||
|
||||
@@ -173,6 +176,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:
|
||||
|
||||
@@ -39,12 +39,14 @@ def get_information():
|
||||
"constraints": ["displacement", "force"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "solid",
|
||||
"equations": ["buckling"]
|
||||
"equations": ["buckling"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.buckling_platebuckling import setup
|
||||
@@ -55,6 +57,7 @@ See forum topic post:
|
||||
https://forum.freecad.org/viewtopic.php?f=18&t=20217&start=110#p509935
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -82,7 +85,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Unknown or unsupported solver type: {}. "
|
||||
@@ -100,7 +103,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
analysis.addObject(solver_obj)
|
||||
|
||||
# shell thickness
|
||||
thickness_obj = ObjectsFem.makeElementGeometry2D(doc, 50, 'Thickness')
|
||||
thickness_obj = ObjectsFem.makeElementGeometry2D(doc, 50, "Thickness")
|
||||
analysis.addObject(thickness_obj)
|
||||
|
||||
# material
|
||||
@@ -146,6 +149,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:
|
||||
|
||||
@@ -40,12 +40,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "solid",
|
||||
"equations": ["buckling"]
|
||||
"equations": ["buckling"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.ccx_buckling_flexuralbuckling import setup
|
||||
@@ -59,6 +61,7 @@ This example is based on a CalculiX verification example.
|
||||
http://www.feacluster.com/CalculiX/ccx_2.13/doc/ccx/input_deck_viewer.php?input_deck=beam8b.inp
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -87,7 +90,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver,
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Unknown or unsupported solver type: {}. "
|
||||
@@ -126,6 +129,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:
|
||||
|
||||
@@ -69,7 +69,7 @@ def setup_cantilever_base_edge(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
elif solvertype == "mystran":
|
||||
solver_obj = ObjectsFem.makeSolverMystran(doc, "SolverMystran")
|
||||
else:
|
||||
@@ -92,7 +92,7 @@ def setup_cantilever_base_edge(doc=None, solvertype="ccxtools"):
|
||||
sectiontype="Rectangular",
|
||||
width=1000.0,
|
||||
height=1000.0,
|
||||
name="BeamCrossSection"
|
||||
name="BeamCrossSection",
|
||||
)
|
||||
analysis.addObject(beamsection_obj)
|
||||
|
||||
@@ -113,13 +113,14 @@ def setup_cantilever_base_edge(doc=None, solvertype="ccxtools"):
|
||||
# constraint force
|
||||
con_force = ObjectsFem.makeConstraintForce(doc, "ConstraintForce")
|
||||
con_force.References = [(geom_obj, "Vertex2")]
|
||||
con_force.Force = "9000000.0 N" # 9 MN
|
||||
con_force.Force = "9000000.0 N" # 9 MN
|
||||
con_force.Direction = (load_line, ["Edge1"])
|
||||
con_force.Reversed = False
|
||||
analysis.addObject(con_force)
|
||||
|
||||
# mesh
|
||||
from .meshes.mesh_canticcx_seg3 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
|
||||
@@ -58,7 +58,7 @@ def setup_cantilever_base_face(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
elif solvertype == "mystran":
|
||||
solver_obj = ObjectsFem.makeSolverMystran(doc, "SolverMystran")
|
||||
elif solvertype == "z88":
|
||||
@@ -78,7 +78,7 @@ def setup_cantilever_base_face(doc=None, solvertype="ccxtools"):
|
||||
analysis.addObject(solver_obj)
|
||||
|
||||
# shell thickness
|
||||
thickness_obj = ObjectsFem.makeElementGeometry2D(doc, 1000, 'Thickness')
|
||||
thickness_obj = ObjectsFem.makeElementGeometry2D(doc, 1000, "Thickness")
|
||||
analysis.addObject(thickness_obj)
|
||||
|
||||
# material
|
||||
@@ -105,6 +105,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:
|
||||
|
||||
@@ -54,7 +54,7 @@ def setup_cantilever_base_solid(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
elif solvertype == "elmer":
|
||||
solver_obj = ObjectsFem.makeSolverElmer(doc, "SolverElmer")
|
||||
ObjectsFem.makeEquationElasticity(doc, solver_obj)
|
||||
@@ -92,6 +92,7 @@ def setup_cantilever_base_solid(doc=None, solvertype="ccxtools"):
|
||||
|
||||
# mesh
|
||||
from .meshes.mesh_canticcx_tetra10 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
|
||||
@@ -36,12 +36,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.ccx_cantilever_beam_circle import setup
|
||||
@@ -73,6 +75,7 @@ CalculiX FEM max deflection:
|
||||
- Delta ca. 1.5 %
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
@@ -36,12 +36,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.ccx_cantilever_beam_pipe import setup
|
||||
@@ -77,6 +79,7 @@ CalculiX FEM max deflection:
|
||||
- Delta ca. 1.0 %
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
@@ -36,12 +36,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.ccx_cantilever_beam_rect import setup
|
||||
@@ -74,6 +76,7 @@ CalculiX FEM max deflection:
|
||||
- but the rotation seems 90 degree rotated (FIXME)
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
@@ -40,12 +40,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["ccxtools", "elmer", "z88"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.ccx_cantilever_ele_hexa20 import setup
|
||||
@@ -57,6 +59,7 @@ hexa20 elements and face load
|
||||
...
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -80,6 +83,7 @@ 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:
|
||||
|
||||
@@ -39,12 +39,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["ccxtools", "mystran"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.ccx_cantilever_ele_quad4 import setup
|
||||
@@ -57,6 +59,7 @@ See forum topic post:
|
||||
CalculiX cantilever modeled with quad4 face elements
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -76,6 +79,7 @@ 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:
|
||||
|
||||
@@ -39,12 +39,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.ccx_cantilever_ele_quad8 import setup
|
||||
@@ -57,6 +59,7 @@ See forum topic post:
|
||||
CalculiX cantilever modeled with quad8 face elements
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -76,6 +79,7 @@ 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:
|
||||
|
||||
@@ -39,12 +39,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["ccxtools", "mystran"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.ccx_cantilever_ele_seg2 import setup
|
||||
@@ -57,6 +59,7 @@ https://forum.freecad.org/viewtopic.php?f=18&t=16044
|
||||
CalculiX cantilever modeled with seg2 beam elements
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -76,6 +79,7 @@ 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:
|
||||
|
||||
@@ -34,12 +34,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.ccx_cantilever_ele_seg3 import setup
|
||||
@@ -52,6 +54,7 @@ https://forum.freecad.org/viewtopic.php?f=18&t=16044
|
||||
CalculiX cantilever modeled with seg3 beam elements
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
@@ -38,12 +38,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["ccxtools", "elmer", "mystran", "z88"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.ccx_cantilever_ele_tetra4 import setup
|
||||
@@ -55,6 +57,7 @@ Mesh before run the example.
|
||||
...
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
@@ -39,12 +39,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["ccxtools", "mystran"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.ccx_cantilever_ele_tria3 import setup
|
||||
@@ -57,6 +59,7 @@ See forum topic post:
|
||||
CalculiX cantilever modeled with tria3 face elements
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -76,6 +79,7 @@ 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:
|
||||
|
||||
@@ -34,12 +34,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["ccxtools", "z88"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.ccx_cantilever_ele_tria6 import setup
|
||||
@@ -51,6 +53,7 @@ See forum topic post:
|
||||
CalculiX cantilever modeled with face elements
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
@@ -37,12 +37,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["ccxtools", "elmer", "mystran", "z88"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.ccx_cantilever_faceload import setup
|
||||
@@ -53,6 +55,7 @@ See forum topic post:
|
||||
...
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
@@ -37,12 +37,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["ccxtools", "elmer", "mystran", "z88"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.ccx_cantilever_nodeload import setup
|
||||
@@ -53,6 +55,7 @@ See forum topic post:
|
||||
...
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -76,7 +79,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
(geom_obj, "Vertex5"),
|
||||
(geom_obj, "Vertex6"),
|
||||
(geom_obj, "Vertex7"),
|
||||
(geom_obj, "Vertex8")
|
||||
(geom_obj, "Vertex8"),
|
||||
]
|
||||
con_force.Force = "9000000.0 N"
|
||||
con_force.Direction = (doc.Box, ["Edge5"])
|
||||
|
||||
@@ -37,12 +37,14 @@ def get_information():
|
||||
"constraints": ["fixed", "displacement"],
|
||||
"solvers": ["ccxtools", "elmer"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.ccx_cantilever_prescribeddisplacement import setup
|
||||
@@ -53,6 +55,7 @@ See forum topic post:
|
||||
...
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
@@ -44,12 +44,14 @@ def get_information():
|
||||
"constraints": ["centrif", "fixed"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "multimaterial",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.constraint_centrif import setup
|
||||
@@ -62,6 +64,7 @@ https://forum.freecad.org/viewtopic.php?f=18&t=57770
|
||||
constraint centrif, concerning CENTRIF label from ccx's *DLOAD card
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -129,7 +132,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Unknown or unsupported solver type: {}. "
|
||||
@@ -178,6 +181,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:
|
||||
|
||||
@@ -43,12 +43,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force", "contact"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.constraint_contact_shell_shell import setup
|
||||
@@ -62,6 +64,7 @@ based on https://forum.freecad.org/viewtopic.php?f=18&t=42228#p359488
|
||||
contact example shell to shell elements
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -109,7 +112,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
force_point.ViewObject.PointColor = (1.0, 0.0, 0.0)
|
||||
|
||||
# boolean fragment of upper tubo and force point
|
||||
boolfrag = SplitFeatures.makeBooleanFragments(name='BooleanFragments')
|
||||
boolfrag = SplitFeatures.makeBooleanFragments(name="BooleanFragments")
|
||||
boolfrag.Objects = [upper_tube, force_point]
|
||||
if FreeCAD.GuiUp:
|
||||
upper_tube.ViewObject.hide()
|
||||
@@ -138,7 +141,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Unknown or unsupported solver type: {}. "
|
||||
@@ -156,7 +159,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
analysis.addObject(solver_obj)
|
||||
|
||||
# shell thickness
|
||||
shell_thick = ObjectsFem.makeElementGeometry2D(doc, 0.5, 'ShellThickness')
|
||||
shell_thick = ObjectsFem.makeElementGeometry2D(doc, 0.5, "ShellThickness")
|
||||
analysis.addObject(shell_thick)
|
||||
|
||||
# material
|
||||
@@ -197,6 +200,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:
|
||||
|
||||
@@ -44,12 +44,14 @@ def get_information():
|
||||
"constraints": ["fixed", "pressure", "contact"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.constraint_contact_solid_solid import setup
|
||||
@@ -61,6 +63,7 @@ https://forum.freecad.org/viewtopic.php?f=18&t=20276
|
||||
constraint contact for solid to solid mesh
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -91,7 +94,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
top_halfcyl_obj.Radius = 30
|
||||
top_halfcyl_obj.Height = 500
|
||||
top_halfcyl_obj.Angle = 180
|
||||
top_halfcyl_sh = Part.getShape(top_halfcyl_obj, '', needSubElement=False, refine=True)
|
||||
top_halfcyl_sh = Part.getShape(top_halfcyl_obj, "", needSubElement=False, refine=True)
|
||||
top_halfcyl_obj.Shape = top_halfcyl_sh
|
||||
top_halfcyl_obj.Placement = FreeCAD.Placement(
|
||||
Vector(0, -42, 0),
|
||||
@@ -118,7 +121,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Unknown or unsupported solver type: {}. "
|
||||
@@ -180,7 +183,11 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
analysis.addObject(con_contact)
|
||||
|
||||
# mesh
|
||||
from .meshes.mesh_contact_box_halfcylinder_tetra10 import create_nodes, create_elements
|
||||
from .meshes.mesh_contact_box_halfcylinder_tetra10 import (
|
||||
create_nodes,
|
||||
create_elements,
|
||||
)
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
|
||||
@@ -50,12 +50,14 @@ def get_information():
|
||||
"constraints": ["section_print", "fixed", "pressure"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.constraint_section_print import setup
|
||||
@@ -68,6 +70,7 @@ https://forum.freecad.org/viewtopic.php?t=43044
|
||||
constraint section print with volume elements
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -83,27 +86,20 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# geometric objects
|
||||
# the part sketch
|
||||
arc_sketch = doc.addObject("Sketcher::SketchObject", "Arc_Sketch")
|
||||
arc_sketch.Placement = FreeCAD.Placement(
|
||||
Vector(0, 0, 0),
|
||||
Rotation(0, 0, 0, 1)
|
||||
)
|
||||
arc_sketch.Placement = FreeCAD.Placement(Vector(0, 0, 0), Rotation(0, 0, 0, 1))
|
||||
arc_sketch.MapMode = "Deactivated"
|
||||
# not the exact geometry which makes a closed wire
|
||||
# exact geometry will be made by the constraints
|
||||
# the order is important for the constraints definition
|
||||
geoList = [
|
||||
Part.ArcOfCircle(
|
||||
Part.Circle(Vector(0, 0, 0), Vector(0, 0, 1), 47),
|
||||
0,
|
||||
math.pi
|
||||
),
|
||||
Part.ArcOfCircle(Part.Circle(Vector(0, 0, 0), Vector(0, 0, 1), 47), 0, math.pi),
|
||||
Part.ArcOfCircle(
|
||||
Part.Circle(Vector(-19, -22, 0), Vector(0, 0, 1), 89),
|
||||
math.pi / 12,
|
||||
math.pi / 1.1
|
||||
math.pi / 1.1,
|
||||
),
|
||||
Part.LineSegment(Vector(-105, 0, 0), Vector(-47, 0, 0)),
|
||||
Part.LineSegment(Vector(47, 0, 0), Vector(67, 0, 0))
|
||||
Part.LineSegment(Vector(47, 0, 0), Vector(67, 0, 0)),
|
||||
]
|
||||
arc_sketch.addGeometry(geoList, False)
|
||||
# https://wiki.freecad.org/Sketcher_ConstrainCoincident
|
||||
@@ -122,7 +118,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
Sketcher.Constraint("DistanceX", 2, 2, 2, 1, 58),
|
||||
Sketcher.Constraint("DistanceX", 3, 2, 3, 1, 20),
|
||||
Sketcher.Constraint("Radius", 0, 47),
|
||||
Sketcher.Constraint("Radius", 1, 89)
|
||||
Sketcher.Constraint("Radius", 1, 89),
|
||||
]
|
||||
arc_sketch.addConstraint(conList)
|
||||
|
||||
@@ -144,12 +140,12 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
section_sketch = doc.addObject("Sketcher::SketchObject", "Section_Sketch")
|
||||
section_sketch.Placement = FreeCAD.Placement(
|
||||
Vector(0.000000, 0.000000, 0.000000),
|
||||
Rotation(0.000000, 0.000000, 0.000000, 1.000000)
|
||||
Rotation(0.000000, 0.000000, 0.000000, 1.000000),
|
||||
)
|
||||
section_sketch.MapMode = "Deactivated"
|
||||
section_sketch.addGeometry(
|
||||
Part.LineSegment(Vector(-6.691961, -16.840161, 0), Vector(75.156087, 79.421394, 0)),
|
||||
False
|
||||
False,
|
||||
)
|
||||
# section_sketch.ExternalGeometry = extrude_part
|
||||
|
||||
@@ -223,7 +219,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Unknown or unsupported solver type: {}. "
|
||||
@@ -266,6 +262,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:
|
||||
|
||||
@@ -39,12 +39,14 @@ def get_information():
|
||||
"constraints": ["fixed", "self weight"],
|
||||
"solvers": ["ccxtools", "elmer"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.constraint_selfweight_cantilever import setup
|
||||
@@ -59,6 +61,7 @@ l = 32 m, yields just from self weight, means max sigma around 235 n/mm2
|
||||
max deformation = 576.8 mm
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -86,7 +89,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
elif solvertype == "elmer":
|
||||
solver_obj = ObjectsFem.makeSolverElmer(doc, "SolverElmer")
|
||||
eq_obj = ObjectsFem.makeEquationElasticity(doc, solver_obj)
|
||||
@@ -127,6 +130,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
# mesh
|
||||
from .meshes.mesh_selfweight_cantilever_tetra10 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
|
||||
@@ -44,12 +44,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force", "tie"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.constraint_tie import setup
|
||||
@@ -62,6 +64,7 @@ https://forum.freecad.org/viewtopic.php?f=18&t=42783
|
||||
constraint tie, bond two surfaces together (solid mesh only)
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -108,7 +111,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Unknown or unsupported solver type: {}. "
|
||||
@@ -156,6 +159,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:
|
||||
|
||||
@@ -44,12 +44,14 @@ def get_information():
|
||||
"constraints": ["pressure", "displacement", "transform"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.constraint_transform_beam_hinged import setup
|
||||
@@ -62,6 +64,7 @@ https://forum.freecad.org/viewtopic.php?f=18&t=20238#p157643
|
||||
Constraint transform on a beam
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -83,7 +86,9 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
cylinder.Height = "20 mm"
|
||||
cylinder.Radius = "6 mm"
|
||||
cylinder.Placement = FreeCAD.Placement(
|
||||
Vector(10, 12, 10), Rotation(0, 0, 90), Vector(0, 0, 0),
|
||||
Vector(10, 12, 10),
|
||||
Rotation(0, 0, 90),
|
||||
Vector(0, 0, 0),
|
||||
)
|
||||
cut = doc.addObject("Part::Cut", "Cut")
|
||||
cut.Base = cube
|
||||
@@ -102,9 +107,9 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
fusion.Refine = True
|
||||
|
||||
# compound filter
|
||||
geom_obj = CompoundFilter.makeCompoundFilter(name='CompoundFilter')
|
||||
geom_obj = CompoundFilter.makeCompoundFilter(name="CompoundFilter")
|
||||
geom_obj.Base = fusion
|
||||
geom_obj.FilterType = 'window-volume'
|
||||
geom_obj.FilterType = "window-volume"
|
||||
doc.recompute()
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
@@ -118,7 +123,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Unknown or unsupported solver type: {}. "
|
||||
@@ -169,6 +174,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:
|
||||
@@ -180,7 +186,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.CharacteristicLengthMax = '7 mm'
|
||||
femmesh_obj.CharacteristicLengthMax = "7 mm"
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -52,12 +52,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force", "transform"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.constraint_transform_torque import setup
|
||||
@@ -72,6 +74,7 @@ https://forum.freecad.org/viewtopic.php?t=18970
|
||||
constraint transform with a constraint force
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -115,7 +118,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Unknown or unsupported solver type: {}. "
|
||||
@@ -160,6 +163,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:
|
||||
|
||||
@@ -39,12 +39,14 @@ def get_information():
|
||||
"constraints": [],
|
||||
"solvers": ["ccxtools", "elmer"],
|
||||
"material": "solid",
|
||||
"equations": ["elasticity"] # "frequency", but list not allowed here
|
||||
"equations": ["elasticity"], # "frequency", but list not allowed here
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.elmer_nonguitutorial01_eigenvalue_of_elastic_beam import setup
|
||||
@@ -55,6 +57,7 @@ See forum topic post:
|
||||
https://forum.freecad.org/viewtopic.php?t=56590
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="elmer"):
|
||||
@@ -83,7 +86,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
elif solvertype == "elmer":
|
||||
solver_obj = ObjectsFem.makeSolverElmer(doc, "SolverElmer")
|
||||
eq_obj = ObjectsFem.makeEquationElasticity(doc, solver_obj)
|
||||
@@ -118,15 +121,13 @@ def setup(doc=None, solvertype="elmer"):
|
||||
|
||||
# constraint fixed
|
||||
con_fixed = ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed")
|
||||
con_fixed.References = [
|
||||
(geom_obj, "Face1"),
|
||||
(geom_obj, "Face2")
|
||||
]
|
||||
con_fixed.References = [(geom_obj, "Face1"), (geom_obj, "Face2")]
|
||||
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:
|
||||
|
||||
@@ -42,12 +42,14 @@ def get_information():
|
||||
"constraints": ["displacement", "spring"],
|
||||
"solvers": ["elmer"],
|
||||
"material": "solid",
|
||||
"equations": ["deformation"]
|
||||
"equations": ["deformation"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.equation_deformation_spring_elmer import setup
|
||||
@@ -56,6 +58,7 @@ setup()
|
||||
Deformation equation - Elmer solver
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="elmer"):
|
||||
@@ -75,18 +78,24 @@ def setup(doc=None, solvertype="elmer"):
|
||||
SketchPath = body.newObject("Sketcher::SketchObject", "Spring_Path")
|
||||
SketchPath.AttachmentSupport = (doc.getObject("XY_Plane"), [""])
|
||||
SketchPath.MapMode = "FlatFace"
|
||||
SketchPath.addGeometry(Part.LineSegment(Vector(
|
||||
-20.0, 30.0, 0.0), Vector(-20.0, 0.0, 0.0)), False)
|
||||
SketchPath.addConstraint(Sketcher.Constraint('PointOnObject', 0, 2, -1))
|
||||
SketchPath.addConstraint(Sketcher.Constraint('Vertical', 0))
|
||||
SketchPath.addGeometry(Part.ArcOfCircle(Part.Circle(
|
||||
Vector(0.0, 0.0, 0.0), Vector(0, 0, 1), 20.0), 3.141593, 6.283185), False)
|
||||
SketchPath.addConstraint(Sketcher.Constraint('Tangent', 0, 2, 1, 1))
|
||||
SketchPath.addConstraint(Sketcher.Constraint('PointOnObject', 1, 2, -1))
|
||||
SketchPath.addGeometry(Part.LineSegment(
|
||||
Vector(20.0, 0.0, 0.0), Vector(20.0, 30.0, 0.0)), False)
|
||||
SketchPath.addConstraint(Sketcher.Constraint('Tangent', 1, 2, 2, 1))
|
||||
SketchPath.addConstraint(Sketcher.Constraint('Equal', 2, 0))
|
||||
SketchPath.addGeometry(
|
||||
Part.LineSegment(Vector(-20.0, 30.0, 0.0), Vector(-20.0, 0.0, 0.0)), False
|
||||
)
|
||||
SketchPath.addConstraint(Sketcher.Constraint("PointOnObject", 0, 2, -1))
|
||||
SketchPath.addConstraint(Sketcher.Constraint("Vertical", 0))
|
||||
SketchPath.addGeometry(
|
||||
Part.ArcOfCircle(
|
||||
Part.Circle(Vector(0.0, 0.0, 0.0), Vector(0, 0, 1), 20.0),
|
||||
3.141593,
|
||||
6.283185,
|
||||
),
|
||||
False,
|
||||
)
|
||||
SketchPath.addConstraint(Sketcher.Constraint("Tangent", 0, 2, 1, 1))
|
||||
SketchPath.addConstraint(Sketcher.Constraint("PointOnObject", 1, 2, -1))
|
||||
SketchPath.addGeometry(Part.LineSegment(Vector(20.0, 0.0, 0.0), Vector(20.0, 30.0, 0.0)), False)
|
||||
SketchPath.addConstraint(Sketcher.Constraint("Tangent", 1, 2, 2, 1))
|
||||
SketchPath.addConstraint(Sketcher.Constraint("Equal", 2, 0))
|
||||
SketchPath.ViewObject.Visibility = False
|
||||
|
||||
# sketch defining the spring cross section
|
||||
@@ -94,11 +103,11 @@ def setup(doc=None, solvertype="elmer"):
|
||||
SketchCircle.AttachmentSupport = (doc.getObject("XZ_Plane"), [""])
|
||||
SketchCircle.MapMode = "FlatFace"
|
||||
SketchCircle.addGeometry(Part.Circle(Vector(-20.0, 0.0, 0.0), Vector(0, 0, 1), 7.5), False)
|
||||
SketchCircle.addConstraint(Sketcher.Constraint('PointOnObject', 0, 3, -1))
|
||||
SketchCircle.addConstraint(Sketcher.Constraint("PointOnObject", 0, 3, -1))
|
||||
SketchCircle.ViewObject.Visibility = False
|
||||
|
||||
# the spring object
|
||||
SpringObject = body.newObject('PartDesign::AdditivePipe', 'Spring')
|
||||
SpringObject = body.newObject("PartDesign::AdditivePipe", "Spring")
|
||||
SpringObject.Profile = SketchCircle
|
||||
SpringObject.Spine = SketchPath
|
||||
|
||||
@@ -112,6 +121,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
analysis = ObjectsFem.makeAnalysis(doc, "Analysis")
|
||||
if FreeCAD.GuiUp:
|
||||
import FemGui
|
||||
|
||||
FemGui.setActiveAnalysis(analysis)
|
||||
|
||||
# solver
|
||||
@@ -148,7 +158,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
DisplaceLeft = doc.addObject("Fem::ConstraintDisplacement", "DisplacementLeft")
|
||||
DisplaceLeft.xFree = False
|
||||
DisplaceLeft.hasXFormula = True
|
||||
DisplaceLeft.xDisplacementFormula = "Variable \"time\"; Real MATC \"0.006*tx\""
|
||||
DisplaceLeft.xDisplacementFormula = 'Variable "time"; Real MATC "0.006*tx"'
|
||||
DisplaceLeft.yFree = False
|
||||
DisplaceLeft.yFix = True
|
||||
DisplaceLeft.zFree = False
|
||||
@@ -159,7 +169,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
DisplaceRight = doc.addObject("Fem::ConstraintDisplacement", "DisplacementRight")
|
||||
DisplaceRight.xFree = False
|
||||
DisplaceRight.hasXFormula = True
|
||||
DisplaceRight.xDisplacementFormula = "Variable \"time\"; Real MATC \"-0.006*tx\""
|
||||
DisplaceRight.xDisplacementFormula = 'Variable "time"; Real MATC "-0.006*tx"'
|
||||
DisplaceRight.yFree = False
|
||||
DisplaceRight.yFix = True
|
||||
DisplaceRight.zFree = False
|
||||
@@ -189,15 +199,13 @@ def setup(doc=None, solvertype="elmer"):
|
||||
|
||||
# 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(
|
||||
"Unexpected error when creating mesh: {}\n"
|
||||
.format(error)
|
||||
)
|
||||
FreeCAD.Console.PrintError(f"Unexpected error when creating mesh: {error}\n")
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -43,12 +43,14 @@ def get_information():
|
||||
"constraints": ["electrostatic potential"],
|
||||
"solvers": ["elmer"],
|
||||
"material": "fluid",
|
||||
"equations": ["electrostatic"]
|
||||
"equations": ["electrostatic"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.equation_electrostatics_capacitance_two_balls import setup
|
||||
@@ -61,6 +63,7 @@ https://forum.freecad.org/viewtopic.php?f=18&t=41488&start=90#p412047
|
||||
Electrostatics equation in FreeCAD FEM-Elmer
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="elmer"):
|
||||
@@ -102,6 +105,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
analysis = ObjectsFem.makeAnalysis(doc, "Analysis")
|
||||
if FreeCAD.GuiUp:
|
||||
import FemGui
|
||||
|
||||
FemGui.setActiveAnalysis(analysis)
|
||||
|
||||
# solver
|
||||
@@ -174,18 +178,20 @@ def setup(doc=None, solvertype="elmer"):
|
||||
|
||||
# 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(
|
||||
"Unexpected error when creating mesh: {}\n"
|
||||
.format(error)
|
||||
)
|
||||
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
|
||||
from .meshes.mesh_capacitance_two_balls_tetra10 import (
|
||||
create_nodes,
|
||||
create_elements,
|
||||
)
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
|
||||
@@ -46,12 +46,14 @@ def get_information():
|
||||
"constraints": ["electrostatic potential"],
|
||||
"solvers": ["elmer"],
|
||||
"material": "fluid",
|
||||
"equations": ["electrostatic"]
|
||||
"equations": ["electrostatic"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.equation_electrostatics_electricforce_elmer_nongui6 import setup
|
||||
@@ -64,6 +66,7 @@ https://forum.freecad.org/viewtopic.php?f=18&t=41488&start=40#p373292
|
||||
Electrostatics equation in FreeCAD FEM-Elmer
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="elmer"):
|
||||
@@ -86,7 +89,8 @@ def setup(doc=None, solvertype="elmer"):
|
||||
Part.LineSegment(Vector(0.000000, 0.000000, 0), Vector(57.407921, 0.000000, 0)),
|
||||
Part.LineSegment(Vector(57.407921, 0.000000, 0), Vector(57.407921, 35.205284, 0)),
|
||||
Part.LineSegment(Vector(57.407921, 35.205284, 0), Vector(0.000000, 35.205284, 0)),
|
||||
Part.LineSegment(Vector(0.000000, 35.205284, 0), Vector(0.000000, 0.000000, 0))]
|
||||
Part.LineSegment(Vector(0.000000, 35.205284, 0), Vector(0.000000, 0.000000, 0)),
|
||||
]
|
||||
base_sketch.addGeometry(base_geoList, False)
|
||||
base_conList = [
|
||||
Sketcher.Constraint("Coincident", 0, 2, 1, 1),
|
||||
@@ -99,7 +103,8 @@ def setup(doc=None, solvertype="elmer"):
|
||||
Sketcher.Constraint("Vertical", 3),
|
||||
Sketcher.Constraint("Coincident", 0, 1, -1, 1),
|
||||
Sketcher.Constraint("DistanceY", 1, 1, 1, 2, 35.205284),
|
||||
Sketcher.Constraint("DistanceX", 0, 1, 0, 2, 57.407921)]
|
||||
Sketcher.Constraint("DistanceX", 0, 1, 0, 2, 57.407921),
|
||||
]
|
||||
base_sketch.addConstraint(base_conList)
|
||||
base_sketch.setDatum(9, Units.Quantity("5000.000000 mm"))
|
||||
base_sketch.setDatum(10, Units.Quantity("5000.000000 mm"))
|
||||
@@ -120,7 +125,8 @@ def setup(doc=None, solvertype="elmer"):
|
||||
Part.LineSegment(Vector(5037.082520, 0.000000, 0), Vector(1309.763672, -21.422216, 0)),
|
||||
Part.LineSegment(Vector(1309.763672, 0.000000, 0), Vector(1372.406982, 1544.678467, 0)),
|
||||
Part.LineSegment(Vector(1372.406982, 1544.678467, 0), Vector(-37.083382, 1544.678467, 0)),
|
||||
Part.LineSegment(Vector(0.000000, 1544.678467, 0), Vector(25.560951, 4958.778320, 0))]
|
||||
Part.LineSegment(Vector(0.000000, 1544.678467, 0), Vector(25.560951, 4958.778320, 0)),
|
||||
]
|
||||
upper_sketch.addGeometry(upper_geoList, False)
|
||||
upper_conList = [
|
||||
Sketcher.Constraint("Horizontal", 0),
|
||||
@@ -140,7 +146,8 @@ def setup(doc=None, solvertype="elmer"):
|
||||
Sketcher.Constraint("DistanceX", 0, 1, 0, 2, 5037.082520),
|
||||
Sketcher.Constraint("DistanceY", 1, 2, 1, 1, 4958.778320),
|
||||
Sketcher.Constraint("DistanceY", 3, 1, 3, 2, 1544.678467),
|
||||
Sketcher.Constraint("DistanceX", 4, 2, 4, 1, 1309.763672)]
|
||||
Sketcher.Constraint("DistanceX", 4, 2, 4, 1, 1309.763672),
|
||||
]
|
||||
upper_sketch.addConstraint(upper_conList)
|
||||
upper_sketch.setDatum(14, Units.Quantity("5000.000000 mm"))
|
||||
upper_sketch.setDatum(15, Units.Quantity("5000.000000 mm"))
|
||||
@@ -163,6 +170,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
analysis = ObjectsFem.makeAnalysis(doc, "Analysis")
|
||||
if FreeCAD.GuiUp:
|
||||
import FemGui
|
||||
|
||||
FemGui.setActiveAnalysis(analysis)
|
||||
|
||||
# solver
|
||||
@@ -209,7 +217,8 @@ def setup(doc=None, solvertype="elmer"):
|
||||
(geom_obj, "Face4"),
|
||||
(geom_obj, "Face5"),
|
||||
(geom_obj, "Face6"),
|
||||
(geom_obj, "Face11")]
|
||||
(geom_obj, "Face11"),
|
||||
]
|
||||
con_elect_pot2.Potential = "1 V"
|
||||
con_elect_pot2.CapacitanceBody = 2
|
||||
con_elect_pot2.CapacitanceBodyEnabled = True
|
||||
@@ -231,23 +240,26 @@ def setup(doc=None, solvertype="elmer"):
|
||||
(geom_obj, "Face4"),
|
||||
(geom_obj, "Face5"),
|
||||
(geom_obj, "Face6"),
|
||||
(geom_obj, "Face11")]
|
||||
(geom_obj, "Face11"),
|
||||
]
|
||||
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(
|
||||
"Unexpected error when creating mesh: {}\n"
|
||||
.format(error)
|
||||
)
|
||||
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
|
||||
from .meshes.mesh_electricforce_elmer_nongui6_tetra10 import (
|
||||
create_nodes,
|
||||
create_elements,
|
||||
)
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
|
||||
@@ -41,16 +41,22 @@ def get_information():
|
||||
"name": "Flow - Elmer 2D",
|
||||
"meshtype": "solid",
|
||||
"meshelement": "Tet10",
|
||||
"constraints": ["initial pressure", "initial temperature",
|
||||
"temperature", "velocity"],
|
||||
"constraints": [
|
||||
"initial pressure",
|
||||
"initial temperature",
|
||||
"temperature",
|
||||
"velocity",
|
||||
],
|
||||
"solvers": ["elmer"],
|
||||
"material": "fluid",
|
||||
"equations": ["flow", "heat"]
|
||||
"equations": ["flow", "heat"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.equation_flow_elmer_2D import setup
|
||||
@@ -59,6 +65,7 @@ setup()
|
||||
Flow and Heat equation - Elmer solver
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="elmer"):
|
||||
@@ -118,6 +125,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
analysis = ObjectsFem.makeAnalysis(doc, "Analysis")
|
||||
if FreeCAD.GuiUp:
|
||||
import FemGui
|
||||
|
||||
FemGui.setActiveAnalysis(analysis)
|
||||
|
||||
# solver
|
||||
@@ -185,7 +193,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
FlowVelocity_Inlet = ObjectsFem.makeConstraintFlowVelocity(doc, "FlowVelocity_Inlet")
|
||||
FlowVelocity_Inlet.References = [(BooleanFragments, "Edge5")]
|
||||
FlowVelocity_Inlet.VelocityXFormula = (
|
||||
"Variable Coordinate 2; Real MATC \"10*(tx+50e-3)*(50e-3-tx)\""
|
||||
'Variable Coordinate 2; Real MATC "10*(tx+50e-3)*(50e-3-tx)"'
|
||||
)
|
||||
FlowVelocity_Inlet.VelocityXUnspecified = False
|
||||
FlowVelocity_Inlet.VelocityXHasFormula = True
|
||||
@@ -198,7 +206,8 @@ def setup(doc=None, solvertype="elmer"):
|
||||
(BooleanFragments, "Edge2"),
|
||||
(BooleanFragments, "Edge3"),
|
||||
(BooleanFragments, "Edge4"),
|
||||
(BooleanFragments, "Edge7")]
|
||||
(BooleanFragments, "Edge7"),
|
||||
]
|
||||
FlowVelocity_Wall.VelocityXUnspecified = False
|
||||
FlowVelocity_Wall.VelocityYUnspecified = False
|
||||
analysis.addObject(FlowVelocity_Wall)
|
||||
@@ -216,7 +225,8 @@ def setup(doc=None, solvertype="elmer"):
|
||||
(BooleanFragments, "Edge2"),
|
||||
(BooleanFragments, "Edge3"),
|
||||
(BooleanFragments, "Edge4"),
|
||||
(BooleanFragments, "Edge7")]
|
||||
(BooleanFragments, "Edge7"),
|
||||
]
|
||||
analysis.addObject(Temperature_Wall)
|
||||
|
||||
# constraint inlet temperature
|
||||
@@ -254,20 +264,19 @@ def setup(doc=None, solvertype="elmer"):
|
||||
(BooleanFragments, "Edge1"),
|
||||
(BooleanFragments, "Vertex2"),
|
||||
(BooleanFragments, "Vertex4"),
|
||||
(BooleanFragments, "Vertex6")]
|
||||
(BooleanFragments, "Vertex6"),
|
||||
]
|
||||
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(
|
||||
"Unexpected error when creating mesh: {}\n"
|
||||
.format(error)
|
||||
)
|
||||
FreeCAD.Console.PrintError(f"Unexpected error when creating mesh: {error}\n")
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -41,16 +41,23 @@ def get_information():
|
||||
"name": "Initial Flow - Elmer 2D",
|
||||
"meshtype": "solid",
|
||||
"meshelement": "Tet10",
|
||||
"constraints": ["initial pressure", "initial temperature", "initial velocity",
|
||||
"temperature", "velocity"],
|
||||
"constraints": [
|
||||
"initial pressure",
|
||||
"initial temperature",
|
||||
"initial velocity",
|
||||
"temperature",
|
||||
"velocity",
|
||||
],
|
||||
"solvers": ["elmer"],
|
||||
"material": "fluid",
|
||||
"equations": ["flow", "heat"]
|
||||
"equations": ["flow", "heat"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.equation_flow_initial_elmer_2D import setup
|
||||
@@ -59,6 +66,7 @@ setup()
|
||||
Flow and Heat equation with initial velocity - Elmer solver
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="elmer"):
|
||||
@@ -118,6 +126,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
analysis = ObjectsFem.makeAnalysis(doc, "Analysis")
|
||||
if FreeCAD.GuiUp:
|
||||
import FemGui
|
||||
|
||||
FemGui.setActiveAnalysis(analysis)
|
||||
|
||||
# solver
|
||||
@@ -196,7 +205,8 @@ def setup(doc=None, solvertype="elmer"):
|
||||
(BooleanFragments, "Edge2"),
|
||||
(BooleanFragments, "Edge3"),
|
||||
(BooleanFragments, "Edge4"),
|
||||
(BooleanFragments, "Edge7")]
|
||||
(BooleanFragments, "Edge7"),
|
||||
]
|
||||
FlowVelocity_Wall.VelocityXUnspecified = False
|
||||
FlowVelocity_Wall.VelocityYUnspecified = False
|
||||
analysis.addObject(FlowVelocity_Wall)
|
||||
@@ -223,7 +233,8 @@ def setup(doc=None, solvertype="elmer"):
|
||||
(BooleanFragments, "Edge2"),
|
||||
(BooleanFragments, "Edge3"),
|
||||
(BooleanFragments, "Edge4"),
|
||||
(BooleanFragments, "Edge7")]
|
||||
(BooleanFragments, "Edge7"),
|
||||
]
|
||||
analysis.addObject(Temperature_Wall)
|
||||
|
||||
# constraint inlet temperature
|
||||
@@ -261,20 +272,19 @@ def setup(doc=None, solvertype="elmer"):
|
||||
(BooleanFragments, "Edge1"),
|
||||
(BooleanFragments, "Vertex2"),
|
||||
(BooleanFragments, "Vertex4"),
|
||||
(BooleanFragments, "Vertex6")]
|
||||
(BooleanFragments, "Vertex6"),
|
||||
]
|
||||
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(
|
||||
"Unexpected error when creating mesh: {}\n"
|
||||
.format(error)
|
||||
)
|
||||
FreeCAD.Console.PrintError(f"Unexpected error when creating mesh: {error}\n")
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -41,16 +41,22 @@ def get_information():
|
||||
"name": "Turbulent Flow - Elmer 2D",
|
||||
"meshtype": "solid",
|
||||
"meshelement": "Tet10",
|
||||
"constraints": ["initial pressure", "initial temperature",
|
||||
"temperature", "velocity"],
|
||||
"constraints": [
|
||||
"initial pressure",
|
||||
"initial temperature",
|
||||
"temperature",
|
||||
"velocity",
|
||||
],
|
||||
"solvers": ["elmer"],
|
||||
"material": "fluid",
|
||||
"equations": ["flow", "heat"]
|
||||
"equations": ["flow", "heat"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.equation_flow_turbulent_elmer_2D import setup
|
||||
@@ -59,6 +65,7 @@ setup()
|
||||
Flow and Heat equation in turbulent flow - Elmer solver
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="elmer"):
|
||||
@@ -118,6 +125,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
analysis = ObjectsFem.makeAnalysis(doc, "Analysis")
|
||||
if FreeCAD.GuiUp:
|
||||
import FemGui
|
||||
|
||||
FemGui.setActiveAnalysis(analysis)
|
||||
|
||||
# solver
|
||||
@@ -191,7 +199,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
FlowVelocity_Inlet = ObjectsFem.makeConstraintFlowVelocity(doc, "FlowVelocity_Inlet")
|
||||
FlowVelocity_Inlet.References = [(BooleanFragments, "Edge5")]
|
||||
FlowVelocity_Inlet.VelocityXFormula = (
|
||||
"Variable Coordinate 2; Real MATC \"10*(tx+50e-3)*(50e-3-tx)\""
|
||||
'Variable Coordinate 2; Real MATC "10*(tx+50e-3)*(50e-3-tx)"'
|
||||
)
|
||||
FlowVelocity_Inlet.VelocityXUnspecified = False
|
||||
FlowVelocity_Inlet.VelocityXHasFormula = True
|
||||
@@ -204,7 +212,8 @@ def setup(doc=None, solvertype="elmer"):
|
||||
(BooleanFragments, "Edge2"),
|
||||
(BooleanFragments, "Edge3"),
|
||||
(BooleanFragments, "Edge4"),
|
||||
(BooleanFragments, "Edge7")]
|
||||
(BooleanFragments, "Edge7"),
|
||||
]
|
||||
FlowVelocity_Wall.VelocityXUnspecified = False
|
||||
FlowVelocity_Wall.VelocityYUnspecified = False
|
||||
analysis.addObject(FlowVelocity_Wall)
|
||||
@@ -222,7 +231,8 @@ def setup(doc=None, solvertype="elmer"):
|
||||
(BooleanFragments, "Edge2"),
|
||||
(BooleanFragments, "Edge3"),
|
||||
(BooleanFragments, "Edge4"),
|
||||
(BooleanFragments, "Edge7")]
|
||||
(BooleanFragments, "Edge7"),
|
||||
]
|
||||
analysis.addObject(Temperature_Wall)
|
||||
|
||||
# constraint inlet temperature
|
||||
@@ -260,20 +270,19 @@ def setup(doc=None, solvertype="elmer"):
|
||||
(BooleanFragments, "Edge1"),
|
||||
(BooleanFragments, "Vertex2"),
|
||||
(BooleanFragments, "Vertex4"),
|
||||
(BooleanFragments, "Vertex6")]
|
||||
(BooleanFragments, "Vertex6"),
|
||||
]
|
||||
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(
|
||||
"Unexpected error when creating mesh: {}\n"
|
||||
.format(error)
|
||||
)
|
||||
FreeCAD.Console.PrintError(f"Unexpected error when creating mesh: {error}\n")
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -40,12 +40,14 @@ def get_information():
|
||||
"constraints": ["electrostatic potential", "temperature"],
|
||||
"solvers": ["elmer"],
|
||||
"material": "solid",
|
||||
"equations": ["electrostatic", "flux", "heat"]
|
||||
"equations": ["electrostatic", "flux", "heat"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.equation_flux_elmer import setup
|
||||
@@ -54,6 +56,7 @@ setup()
|
||||
Potential flux and heat flux - Elmer solver
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="elmer"):
|
||||
@@ -80,6 +83,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
analysis = ObjectsFem.makeAnalysis(doc, "Analysis")
|
||||
if FreeCAD.GuiUp:
|
||||
import FemGui
|
||||
|
||||
FemGui.setActiveAnalysis(analysis)
|
||||
|
||||
# solver
|
||||
@@ -155,15 +159,13 @@ def setup(doc=None, solvertype="elmer"):
|
||||
|
||||
# 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(
|
||||
"Unexpected error when creating mesh: {}\n"
|
||||
.format(error)
|
||||
)
|
||||
FreeCAD.Console.PrintError(f"Unexpected error when creating mesh: {error}\n")
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -43,12 +43,14 @@ def get_information():
|
||||
"constraints": ["current density"],
|
||||
"solvers": ["elmer"],
|
||||
"material": "solid",
|
||||
"equations": ["electromagnetic"]
|
||||
"equations": ["electromagnetic"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.equation_magnetodynamics_2D_elmer import setup
|
||||
@@ -57,6 +59,7 @@ setup()
|
||||
Magnetodynamic2D equation - Elmer solver
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="elmer"):
|
||||
@@ -120,8 +123,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
Powder.ViewObject.Visibility = False
|
||||
|
||||
# a half circle defining later the air volume
|
||||
Air_Circle = Part.makeCircle(
|
||||
140.0, Vector(0.0, 60.0, 0.0), Vector(0.0, 0.0, 1.0), -90.0, 90.0)
|
||||
Air_Circle = Part.makeCircle(140.0, Vector(0.0, 60.0, 0.0), Vector(0.0, 0.0, 1.0), -90.0, 90.0)
|
||||
Air_Line = Part.makeLine((0.0, -80.0, 0.0), (0.0, 200.0, 0.0))
|
||||
Air_Area = doc.addObject("Part::Feature", "Air_Area")
|
||||
Air_Area.Shape = Part.Face([Part.Wire([Air_Circle, Air_Line])])
|
||||
@@ -175,6 +177,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
analysis = ObjectsFem.makeAnalysis(doc, "Analysis")
|
||||
if FreeCAD.GuiUp:
|
||||
import FemGui
|
||||
|
||||
FemGui.setActiveAnalysis(analysis)
|
||||
|
||||
# solver
|
||||
@@ -212,7 +215,8 @@ def setup(doc=None, solvertype="elmer"):
|
||||
material_obj.References = [
|
||||
(BooleanFragments, "Face2"),
|
||||
(BooleanFragments, "Face5"),
|
||||
(BooleanFragments, "Face6")]
|
||||
(BooleanFragments, "Face6"),
|
||||
]
|
||||
analysis.addObject(material_obj)
|
||||
|
||||
# graphite of the crucible
|
||||
@@ -265,20 +269,19 @@ def setup(doc=None, solvertype="elmer"):
|
||||
(BooleanFragments, "Face1"),
|
||||
(BooleanFragments, "Face2"),
|
||||
(BooleanFragments, "Face3"),
|
||||
(BooleanFragments, "Face4")]
|
||||
(BooleanFragments, "Face4"),
|
||||
]
|
||||
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(
|
||||
"Unexpected error when creating mesh: {}\n"
|
||||
.format(error)
|
||||
)
|
||||
FreeCAD.Console.PrintError(f"Unexpected error when creating mesh: {error}\n")
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -42,12 +42,14 @@ def get_information():
|
||||
"constraints": ["electrostatic potential", "magnetization"],
|
||||
"solvers": ["elmer"],
|
||||
"material": "solid",
|
||||
"equations": ["electromagnetic"]
|
||||
"equations": ["electromagnetic"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.equation_magnetodynamics_elmer import setup
|
||||
@@ -56,6 +58,7 @@ setup()
|
||||
Magnetodynamic equation - Elmer solver
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="elmer"):
|
||||
@@ -99,6 +102,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
analysis = ObjectsFem.makeAnalysis(doc, "Analysis")
|
||||
if FreeCAD.GuiUp:
|
||||
import FemGui
|
||||
|
||||
FemGui.setActiveAnalysis(analysis)
|
||||
|
||||
# solver
|
||||
@@ -157,7 +161,8 @@ def setup(doc=None, solvertype="elmer"):
|
||||
AxialField.References = [
|
||||
(BooleanFragments, "Face4"),
|
||||
(BooleanFragments, "Face5"),
|
||||
(BooleanFragments, "Face6")]
|
||||
(BooleanFragments, "Face6"),
|
||||
]
|
||||
AxialField.PotentialEnabled = False
|
||||
AxialField.AV_im_1_Disabled = False
|
||||
AxialField.AV_im_2_Disabled = False
|
||||
@@ -209,18 +214,20 @@ def setup(doc=None, solvertype="elmer"):
|
||||
|
||||
# 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(
|
||||
"Unexpected error when creating mesh: {}\n"
|
||||
.format(error)
|
||||
)
|
||||
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
|
||||
from .meshes.mesh_capacitance_two_balls_tetra10 import (
|
||||
create_nodes,
|
||||
create_elements,
|
||||
)
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
|
||||
@@ -43,12 +43,14 @@ def get_information():
|
||||
"constraints": ["magnetization"],
|
||||
"solvers": ["elmer"],
|
||||
"material": "solid",
|
||||
"equations": ["magnetostatic"]
|
||||
"equations": ["magnetostatic"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.equation_magnetostatics_2D_elmer import setup
|
||||
@@ -57,6 +59,7 @@ setup()
|
||||
Magnetodynamic2D equation - Elmer solver
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="elmer"):
|
||||
@@ -93,25 +96,43 @@ def setup(doc=None, solvertype="elmer"):
|
||||
|
||||
# the U-part of the horse shoe
|
||||
# credits: https://forum.freecad.org/viewtopic.php?p=663051#p663051
|
||||
vpairs = [[Vector(340.0, 200.0, 0.0), Vector(200.0, 200.0, 0.0)],
|
||||
[Vector(200.0, 200.0, 0.0), Vector(200.0, 100.0, 0.0)],
|
||||
[Vector(200.0, 100.0, 0.0), Vector(325.0, 100.0, 0.0)],
|
||||
[Vector(325.0, 100.0, 0.0), Vector(325.0, -100.0, 0.0)],
|
||||
[Vector(325.0, -100.0, 0.0), Vector(200.0, -100.0, 0.0)],
|
||||
[Vector(200.0, -100.0, 0.0), Vector(200.0, -200.0, 0.0)],
|
||||
[Vector(200.0, -200.0, 0.0), Vector(340.0, -200.0, 0.0)],
|
||||
[Vector(340.0, 200.0, 0.0), Vector(340.0, -200.0, 0.0)]]
|
||||
typeId = ['Part::GeomLine', 'Part::GeomLine', 'Part::GeomLine', 'Part::GeomBSplineCurve',
|
||||
'Part::GeomLine', 'Part::GeomLine', 'Part::GeomLine', 'Part::GeomBSplineCurve']
|
||||
e3Poles = [Vector(325.0, 100.0, 0.0), Vector(400.0, 100.0, 0.0),
|
||||
Vector(400.0, 0.0, 0.0), Vector(400.0, -100.0, 0.0),
|
||||
Vector(325.0, -100.0, 0.0)]
|
||||
vpairs = [
|
||||
[Vector(340.0, 200.0, 0.0), Vector(200.0, 200.0, 0.0)],
|
||||
[Vector(200.0, 200.0, 0.0), Vector(200.0, 100.0, 0.0)],
|
||||
[Vector(200.0, 100.0, 0.0), Vector(325.0, 100.0, 0.0)],
|
||||
[Vector(325.0, 100.0, 0.0), Vector(325.0, -100.0, 0.0)],
|
||||
[Vector(325.0, -100.0, 0.0), Vector(200.0, -100.0, 0.0)],
|
||||
[Vector(200.0, -100.0, 0.0), Vector(200.0, -200.0, 0.0)],
|
||||
[Vector(200.0, -200.0, 0.0), Vector(340.0, -200.0, 0.0)],
|
||||
[Vector(340.0, 200.0, 0.0), Vector(340.0, -200.0, 0.0)],
|
||||
]
|
||||
typeId = [
|
||||
"Part::GeomLine",
|
||||
"Part::GeomLine",
|
||||
"Part::GeomLine",
|
||||
"Part::GeomBSplineCurve",
|
||||
"Part::GeomLine",
|
||||
"Part::GeomLine",
|
||||
"Part::GeomLine",
|
||||
"Part::GeomBSplineCurve",
|
||||
]
|
||||
e3Poles = [
|
||||
Vector(325.0, 100.0, 0.0),
|
||||
Vector(400.0, 100.0, 0.0),
|
||||
Vector(400.0, 0.0, 0.0),
|
||||
Vector(400.0, -100.0, 0.0),
|
||||
Vector(325.0, -100.0, 0.0),
|
||||
]
|
||||
e3Knots = [0.0, 0.5, 1.0]
|
||||
e3Mults = [4, 1, 4]
|
||||
e3Degree = 3
|
||||
e7Poles = [Vector(340.0, 200.0, 0.0), Vector(500.0, 200.0, 0.0),
|
||||
Vector(500.0, 0.0, 0.0), Vector(500.0, -200.0, 0.0),
|
||||
Vector(340.0, -200.0, 0.0)]
|
||||
e7Poles = [
|
||||
Vector(340.0, 200.0, 0.0),
|
||||
Vector(500.0, 200.0, 0.0),
|
||||
Vector(500.0, 0.0, 0.0),
|
||||
Vector(500.0, -200.0, 0.0),
|
||||
Vector(340.0, -200.0, 0.0),
|
||||
]
|
||||
e7Knots = [0.0, 0.5, 1.0]
|
||||
e7Mults = [4, 1, 4]
|
||||
e7Degree = 3
|
||||
@@ -121,7 +142,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
c7.buildFromPolesMultsKnots(e7Poles, e7Mults, e7Knots, False, e7Degree)
|
||||
edges = [c3.toShape(), c7.toShape()]
|
||||
for i in range(len(typeId)):
|
||||
if typeId[i] == 'Part::GeomLine':
|
||||
if typeId[i] == "Part::GeomLine":
|
||||
edges.append(Part.makeLine(*vpairs[i]))
|
||||
|
||||
sedges = Part.__sortEdges__(edges)
|
||||
@@ -175,6 +196,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
analysis = ObjectsFem.makeAnalysis(doc, "Analysis")
|
||||
if FreeCAD.GuiUp:
|
||||
import FemGui
|
||||
|
||||
FemGui.setActiveAnalysis(analysis)
|
||||
|
||||
# solver
|
||||
@@ -218,7 +240,8 @@ def setup(doc=None, solvertype="elmer"):
|
||||
material_obj.References = [
|
||||
(BooleanFragments, "Face1"),
|
||||
(BooleanFragments, "Face2"),
|
||||
(BooleanFragments, "Face3")]
|
||||
(BooleanFragments, "Face3"),
|
||||
]
|
||||
analysis.addObject(material_obj)
|
||||
|
||||
# magnetization lower
|
||||
@@ -247,20 +270,19 @@ def setup(doc=None, solvertype="elmer"):
|
||||
mesh_region.References = [
|
||||
(BooleanFragments, "Face1"),
|
||||
(BooleanFragments, "Face2"),
|
||||
(BooleanFragments, "Face3")]
|
||||
(BooleanFragments, "Face3"),
|
||||
]
|
||||
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(
|
||||
"Unexpected error when creating mesh: {}\n"
|
||||
.format(error)
|
||||
)
|
||||
FreeCAD.Console.PrintError(f"Unexpected error when creating mesh: {error}\n")
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -38,10 +38,12 @@ import FreeCADGui
|
||||
|
||||
class FemExamples(QtGui.QWidget):
|
||||
def __init__(self):
|
||||
super(FemExamples, self).__init__()
|
||||
super().__init__()
|
||||
self.init_ui()
|
||||
|
||||
def __del__(self,):
|
||||
def __del__(
|
||||
self,
|
||||
):
|
||||
# need as fix for qt event error
|
||||
# --> see https://forum.freecad.org/viewtopic.php?f=18&t=10732&start=10#p86493
|
||||
return
|
||||
@@ -205,9 +207,9 @@ class FemExamples(QtGui.QWidget):
|
||||
if grand_parent_name == "Solvers":
|
||||
solver = parent.text(0)
|
||||
# if done this way the Python commands are printed in Python console
|
||||
FreeCADGui.doCommand("from femexamples.{} import setup".format(str(example)))
|
||||
FreeCADGui.doCommand(f"from femexamples.{str(example)} import setup")
|
||||
if solver is not None:
|
||||
FreeCADGui.doCommand("setup(solvertype=\"{}\")".format(str(solver)))
|
||||
FreeCADGui.doCommand(f'setup(solvertype="{str(solver)}")')
|
||||
else:
|
||||
FreeCADGui.doCommand("setup()")
|
||||
QtGui.QApplication.restoreOverrideCursor()
|
||||
@@ -236,10 +238,11 @@ class FemExamples(QtGui.QWidget):
|
||||
# if done this way the Python commands are printed in Python console
|
||||
FreeCADGui.doCommand("from femexamples.manager import run_example")
|
||||
if solver is not None:
|
||||
FreeCADGui.doCommand("run_example(\"{}\", solver=\"{}\", run_solver=True)"
|
||||
.format(str(example), str(solver)))
|
||||
FreeCADGui.doCommand(
|
||||
f'run_example("{str(example)}", solver="{str(solver)}", run_solver=True)'
|
||||
)
|
||||
else:
|
||||
FreeCADGui.doCommand("run_example(\"{}\", run_solver=True)".format(str(example)))
|
||||
FreeCADGui.doCommand(f'run_example("{str(example)}", run_solver=True)')
|
||||
QtGui.QApplication.restoreOverrideCursor()
|
||||
|
||||
def enable_buttons(self):
|
||||
|
||||
@@ -39,12 +39,14 @@ def get_information():
|
||||
"constraints": ["fixed"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "solid",
|
||||
"equations": ["frequency"]
|
||||
"equations": ["frequency"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.frequency_beamsimple import setup
|
||||
@@ -57,6 +59,7 @@ https://forum.freecad.org/viewtopic.php?f=18&t=58959#p506565
|
||||
simple frequency analysis
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -85,7 +88,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Unknown or unsupported solver type: {}. "
|
||||
@@ -104,9 +107,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
analysis.addObject(solver_obj)
|
||||
|
||||
# material
|
||||
material_obj = analysis.addObject(
|
||||
ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterial")
|
||||
)[0]
|
||||
material_obj = analysis.addObject(ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterial"))[0]
|
||||
mat = material_obj.Material
|
||||
mat["Name"] = "Steel-Generic"
|
||||
mat["YoungsModulus"] = "200000 MPa"
|
||||
@@ -145,6 +146,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:
|
||||
|
||||
@@ -148,6 +148,7 @@ def run_analysis(doc, base_name, filepath="", run_solver=False):
|
||||
# find the first solver
|
||||
# thus ATM only one solver per analysis is supported
|
||||
from femtools.femutils import is_derived_from
|
||||
|
||||
for m in doc.Analysis.Group:
|
||||
if is_derived_from(m, "Fem::FemSolverObjectPython"):
|
||||
solver = m
|
||||
@@ -155,17 +156,17 @@ def run_analysis(doc, base_name, filepath="", run_solver=False):
|
||||
|
||||
# a file name is needed for the besides dir to work
|
||||
save_fc_file = join(filepath, (base_name + ".FCStd"))
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"Save FreeCAD file for {} analysis to {}\n.".format(base_name, save_fc_file)
|
||||
)
|
||||
FreeCAD.Console.PrintMessage(f"Save FreeCAD file for {base_name} analysis to {save_fc_file}\n.")
|
||||
doc.saveAs(save_fc_file)
|
||||
|
||||
# get analysis workig dir
|
||||
from femtools.femutils import get_beside_dir
|
||||
|
||||
working_dir = get_beside_dir(solver)
|
||||
|
||||
# run analysis
|
||||
from femsolver.run import run_fem_solver
|
||||
|
||||
if run_solver is True:
|
||||
run_fem_solver(solver, working_dir)
|
||||
|
||||
@@ -176,9 +177,10 @@ def run_analysis(doc, base_name, filepath="", run_solver=False):
|
||||
def run_example(example, solver=None, base_name=None, run_solver=False):
|
||||
|
||||
from importlib import import_module
|
||||
|
||||
module = import_module("femexamples." + example)
|
||||
if not hasattr(module, "setup"):
|
||||
FreeCAD.Console.PrintError("Setup method not found in {}\n".format(example))
|
||||
FreeCAD.Console.PrintError(f"Setup method not found in {example}\n")
|
||||
return None
|
||||
|
||||
if solver is None:
|
||||
@@ -215,7 +217,9 @@ def get_meshname():
|
||||
def get_header(information):
|
||||
return """{name}
|
||||
|
||||
{information}""".format(name=information["name"], information=print_info_dict(information))
|
||||
{information}""".format(
|
||||
name=information["name"], information=print_info_dict(information)
|
||||
)
|
||||
|
||||
|
||||
def print_info_dict(information):
|
||||
@@ -224,11 +228,11 @@ def print_info_dict(information):
|
||||
value_text = ""
|
||||
if isinstance(v, list):
|
||||
for j in v:
|
||||
value_text += "{}, ".format(j)
|
||||
value_text += f"{j}, "
|
||||
value_text = value_text.rstrip(", ")
|
||||
else:
|
||||
value_text = v
|
||||
the_text += "{} --> {}\n".format(k, value_text)
|
||||
the_text += f"{k} --> {value_text}\n"
|
||||
# print(the_text)
|
||||
return the_text
|
||||
|
||||
|
||||
@@ -42,12 +42,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "multimaterial",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.material_multiple_bendingbeam_fiveboxes import setup
|
||||
@@ -58,6 +60,7 @@ See forum topic post:
|
||||
...
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -124,7 +127,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Unknown or unsupported solver type: {}. "
|
||||
@@ -179,7 +182,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
(doc.Box2, "Face6"),
|
||||
(doc.Box3, "Face6"),
|
||||
(doc.Box4, "Face6"),
|
||||
(doc.Box5, "Face6")
|
||||
(doc.Box5, "Face6"),
|
||||
]
|
||||
con_force.Force = "10000.00 N"
|
||||
con_force.Direction = (doc.Box1, ["Edge1"])
|
||||
@@ -188,6 +191,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:
|
||||
|
||||
@@ -40,12 +40,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "multimaterial",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.material_multiple_bendingbeam_fivefaces import setup
|
||||
@@ -56,6 +58,7 @@ See forum topic post:
|
||||
...
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -113,7 +116,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Unknown or unsupported solver type: {}. "
|
||||
@@ -143,10 +146,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
analysis.addObject(material_obj1)
|
||||
|
||||
material_obj2 = ObjectsFem.makeMaterialSolid(doc, "FemMaterial2")
|
||||
material_obj2.References = [
|
||||
(doc.Face2, "Face1"),
|
||||
(doc.Face4, "Face1")
|
||||
]
|
||||
material_obj2.References = [(doc.Face2, "Face1"), (doc.Face4, "Face1")]
|
||||
mat = material_obj2.Material
|
||||
mat["Name"] = "PLA"
|
||||
mat["YoungsModulus"] = "3640 MPa"
|
||||
@@ -165,10 +165,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
# constraint fixed
|
||||
con_fixed = ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed")
|
||||
con_fixed.References = [
|
||||
(doc.Face1, "Edge1"),
|
||||
(doc.Face5, "Edge3")
|
||||
]
|
||||
con_fixed.References = [(doc.Face1, "Edge1"), (doc.Face5, "Edge3")]
|
||||
analysis.addObject(con_fixed)
|
||||
|
||||
# constraint force
|
||||
@@ -178,7 +175,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
(doc.Face2, "Edge4"),
|
||||
(doc.Face3, "Edge4"),
|
||||
(doc.Face4, "Edge4"),
|
||||
(doc.Face5, "Edge4")
|
||||
(doc.Face5, "Edge4"),
|
||||
]
|
||||
con_force.Force = "10000.00 N"
|
||||
con_force.Direction = (doc.Face1, ["Edge1"])
|
||||
@@ -187,6 +184,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:
|
||||
|
||||
@@ -43,12 +43,14 @@ def get_information():
|
||||
"constraints": ["fixed", "pressure"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "multimaterial",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.material_multiple_tensionrod_twoboxes import setup
|
||||
@@ -59,6 +61,7 @@ See forum topic post:
|
||||
...
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -109,7 +112,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Unknown or unsupported solver type: {}. "
|
||||
@@ -157,6 +160,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:
|
||||
|
||||
@@ -51,12 +51,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "nonlinear",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.material_nl_platewithhole import setup
|
||||
@@ -80,6 +82,7 @@ TODO nonlinear material: give more information, use values from harry
|
||||
TODO compare results with example from HarryvL
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -118,7 +121,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Unknown or unsupported solver type: {}. "
|
||||
@@ -131,8 +134,8 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
solver_obj.ThermoMechSteadyState = False
|
||||
solver_obj.MatrixSolverType = "default"
|
||||
solver_obj.IterationsControlParameterTimeUse = False
|
||||
solver_obj.GeometricalNonlinearity = 'nonlinear'
|
||||
solver_obj.MaterialNonlinearity = 'nonlinear'
|
||||
solver_obj.GeometricalNonlinearity = "nonlinear"
|
||||
solver_obj.MaterialNonlinearity = "nonlinear"
|
||||
analysis.addObject(solver_obj)
|
||||
|
||||
# linear material
|
||||
@@ -147,7 +150,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# nonlinear material
|
||||
name_nlm = "Material_nonlin"
|
||||
nonlinear_mat = ObjectsFem.makeMaterialMechanicalNonlinear(doc, material_obj, name_nlm)
|
||||
nonlinear_mat.YieldPoints = ['240.0, 0.0', '270.0, 0.025']
|
||||
nonlinear_mat.YieldPoints = ["240.0, 0.0", "270.0, 0.025"]
|
||||
analysis.addObject(nonlinear_mat)
|
||||
# check solver attributes, Nonlinearity needs to be set to nonlinear
|
||||
|
||||
@@ -165,6 +168,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:
|
||||
|
||||
@@ -266,129 +266,804 @@ def create_nodes(femmesh):
|
||||
|
||||
def create_elements(femmesh):
|
||||
# elements
|
||||
femmesh.addVolume([
|
||||
192, 61, 105, 222, 19, 1, 10, 95, 193, 104, 220, 221, 20, 9, 93, 94, 190, 62, 103, 219
|
||||
], 1)
|
||||
femmesh.addVolume([
|
||||
222, 105, 34, 134, 95, 10, 2, 13, 220, 106, 133, 223, 93, 11, 12, 96, 219, 103, 33, 132
|
||||
], 2)
|
||||
femmesh.addVolume([
|
||||
79, 192, 222, 163, 4, 19, 95, 16, 191, 221, 224, 164, 18, 94, 97, 17, 78, 190, 219, 161
|
||||
], 3)
|
||||
femmesh.addVolume([
|
||||
163, 222, 134, 64, 16, 95, 13, 3, 224, 223,
|
||||
135, 162, 97, 96, 14, 15, 161, 219, 132, 63
|
||||
], 4)
|
||||
femmesh.addVolume([
|
||||
196, 59, 109, 228, 192, 61, 105, 222, 197,
|
||||
108, 226, 227, 193, 104, 220, 221, 194, 60, 107, 225
|
||||
], 5)
|
||||
femmesh.addVolume([
|
||||
228, 109, 36, 138, 222, 105, 34, 134, 226,
|
||||
110, 137, 229, 220, 106, 133, 223, 225, 107, 35, 136
|
||||
], 6)
|
||||
femmesh.addVolume([
|
||||
81, 196, 228, 167, 79, 192, 222, 163, 195, 227,
|
||||
230, 168, 191, 221, 224, 164, 80, 194, 225, 165
|
||||
], 7)
|
||||
femmesh.addVolume([
|
||||
167, 228, 138, 66, 163, 222, 134, 64, 230, 229,
|
||||
139, 166, 224, 223, 135, 162, 165, 225, 136, 65
|
||||
], 8)
|
||||
femmesh.addVolume([
|
||||
200, 57, 113, 234, 196, 59, 109, 228, 201, 112,
|
||||
232, 233, 197, 108, 226, 227, 198, 58, 111, 231
|
||||
], 9)
|
||||
femmesh.addVolume([
|
||||
234, 113, 38, 142, 228, 109, 36, 138, 232, 114,
|
||||
141, 235, 226, 110, 137, 229, 231, 111, 37, 140
|
||||
], 10)
|
||||
femmesh.addVolume([
|
||||
83, 200, 234, 171, 81, 196, 228, 167, 199, 233,
|
||||
236, 172, 195, 227, 230, 168, 82, 198, 231, 169
|
||||
], 11)
|
||||
femmesh.addVolume([
|
||||
171, 234, 142, 68, 167, 228, 138, 66, 236, 235,
|
||||
143, 170, 230, 229, 139, 166, 169, 231, 140, 67
|
||||
], 12)
|
||||
femmesh.addVolume([
|
||||
204, 55, 117, 240, 200, 57, 113, 234, 205, 116,
|
||||
238, 239, 201, 112, 232, 233, 202, 56, 115, 237
|
||||
], 13)
|
||||
femmesh.addVolume([
|
||||
240, 117, 40, 146, 234, 113, 38, 142, 238, 118,
|
||||
145, 241, 232, 114, 141, 235, 237, 115, 39, 144
|
||||
], 14)
|
||||
femmesh.addVolume([
|
||||
85, 204, 240, 175, 83, 200, 234, 171, 203, 239,
|
||||
242, 176, 199, 233, 236, 172, 84, 202, 237, 173
|
||||
], 15)
|
||||
femmesh.addVolume([
|
||||
175, 240, 146, 70, 171, 234, 142, 68, 242, 241,
|
||||
147, 174, 236, 235, 143, 170, 173, 237, 144, 69
|
||||
], 16)
|
||||
femmesh.addVolume([
|
||||
208, 53, 121, 246, 204, 55, 117, 240, 209, 120,
|
||||
244, 245, 205, 116, 238, 239, 206, 54, 119, 243
|
||||
], 17)
|
||||
femmesh.addVolume([
|
||||
246, 121, 42, 150, 240, 117, 40, 146, 244, 122,
|
||||
149, 247, 238, 118, 145, 241, 243, 119, 41, 148
|
||||
], 18)
|
||||
femmesh.addVolume([
|
||||
87, 208, 246, 179, 85, 204, 240, 175, 207, 245,
|
||||
248, 180, 203, 239, 242, 176, 86, 206, 243, 177
|
||||
], 19)
|
||||
femmesh.addVolume([
|
||||
179, 246, 150, 72, 175, 240, 146, 70, 248, 247,
|
||||
151, 178, 242, 241, 147, 174, 177, 243, 148, 71
|
||||
], 20)
|
||||
femmesh.addVolume([
|
||||
212, 51, 125, 252, 208, 53, 121, 246, 213, 124,
|
||||
250, 251, 209, 120, 244, 245, 210, 52, 123, 249
|
||||
], 21)
|
||||
femmesh.addVolume([
|
||||
252, 125, 44, 154, 246, 121, 42, 150, 250, 126,
|
||||
153, 253, 244, 122, 149, 247, 249, 123, 43, 152
|
||||
], 22)
|
||||
femmesh.addVolume([
|
||||
89, 212, 252, 183, 87, 208, 246, 179, 211, 251,
|
||||
254, 184, 207, 245, 248, 180, 88, 210, 249, 181
|
||||
], 23)
|
||||
femmesh.addVolume([
|
||||
183, 252, 154, 74, 179, 246, 150, 72, 254, 253,
|
||||
155, 182, 248, 247, 151, 178, 181, 249, 152, 73
|
||||
], 24)
|
||||
femmesh.addVolume([
|
||||
216, 49, 129, 258, 212, 51, 125, 252, 217, 128,
|
||||
256, 257, 213, 124, 250, 251, 214, 50, 127, 255
|
||||
], 25)
|
||||
femmesh.addVolume([
|
||||
258, 129, 46, 158, 252, 125, 44, 154, 256, 130,
|
||||
157, 259, 250, 126, 153, 253, 255, 127, 45, 156
|
||||
], 26)
|
||||
femmesh.addVolume([
|
||||
91, 216, 258, 187, 89, 212, 252, 183, 215, 257,
|
||||
260, 188, 211, 251, 254, 184, 90, 214, 255, 185
|
||||
], 27)
|
||||
femmesh.addVolume([
|
||||
187, 258, 158, 76, 183, 252, 154, 74, 260, 259,
|
||||
159, 186, 254, 253, 155, 182, 185, 255, 156, 75
|
||||
], 28)
|
||||
femmesh.addVolume([
|
||||
31, 5, 22, 100, 216, 49, 129, 258, 32, 21,
|
||||
98, 99, 217, 128, 256, 257, 218, 48, 131, 261
|
||||
], 29)
|
||||
femmesh.addVolume([
|
||||
100, 22, 6, 25, 258, 129, 46, 158, 98, 23,
|
||||
24, 101, 256, 130, 157, 259, 261, 131, 47, 160
|
||||
], 30)
|
||||
femmesh.addVolume([
|
||||
8, 31, 100, 28, 91, 216, 258, 187, 30, 99,
|
||||
102, 29, 215, 257, 260, 188, 92, 218, 261, 189
|
||||
], 31)
|
||||
femmesh.addVolume([
|
||||
28, 100, 25, 7, 187, 258, 158, 76, 102, 101,
|
||||
26, 27, 260, 259, 159, 186, 189, 261, 160, 77
|
||||
], 32)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
192,
|
||||
61,
|
||||
105,
|
||||
222,
|
||||
19,
|
||||
1,
|
||||
10,
|
||||
95,
|
||||
193,
|
||||
104,
|
||||
220,
|
||||
221,
|
||||
20,
|
||||
9,
|
||||
93,
|
||||
94,
|
||||
190,
|
||||
62,
|
||||
103,
|
||||
219,
|
||||
],
|
||||
1,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
222,
|
||||
105,
|
||||
34,
|
||||
134,
|
||||
95,
|
||||
10,
|
||||
2,
|
||||
13,
|
||||
220,
|
||||
106,
|
||||
133,
|
||||
223,
|
||||
93,
|
||||
11,
|
||||
12,
|
||||
96,
|
||||
219,
|
||||
103,
|
||||
33,
|
||||
132,
|
||||
],
|
||||
2,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
79,
|
||||
192,
|
||||
222,
|
||||
163,
|
||||
4,
|
||||
19,
|
||||
95,
|
||||
16,
|
||||
191,
|
||||
221,
|
||||
224,
|
||||
164,
|
||||
18,
|
||||
94,
|
||||
97,
|
||||
17,
|
||||
78,
|
||||
190,
|
||||
219,
|
||||
161,
|
||||
],
|
||||
3,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
163,
|
||||
222,
|
||||
134,
|
||||
64,
|
||||
16,
|
||||
95,
|
||||
13,
|
||||
3,
|
||||
224,
|
||||
223,
|
||||
135,
|
||||
162,
|
||||
97,
|
||||
96,
|
||||
14,
|
||||
15,
|
||||
161,
|
||||
219,
|
||||
132,
|
||||
63,
|
||||
],
|
||||
4,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
196,
|
||||
59,
|
||||
109,
|
||||
228,
|
||||
192,
|
||||
61,
|
||||
105,
|
||||
222,
|
||||
197,
|
||||
108,
|
||||
226,
|
||||
227,
|
||||
193,
|
||||
104,
|
||||
220,
|
||||
221,
|
||||
194,
|
||||
60,
|
||||
107,
|
||||
225,
|
||||
],
|
||||
5,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
228,
|
||||
109,
|
||||
36,
|
||||
138,
|
||||
222,
|
||||
105,
|
||||
34,
|
||||
134,
|
||||
226,
|
||||
110,
|
||||
137,
|
||||
229,
|
||||
220,
|
||||
106,
|
||||
133,
|
||||
223,
|
||||
225,
|
||||
107,
|
||||
35,
|
||||
136,
|
||||
],
|
||||
6,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
81,
|
||||
196,
|
||||
228,
|
||||
167,
|
||||
79,
|
||||
192,
|
||||
222,
|
||||
163,
|
||||
195,
|
||||
227,
|
||||
230,
|
||||
168,
|
||||
191,
|
||||
221,
|
||||
224,
|
||||
164,
|
||||
80,
|
||||
194,
|
||||
225,
|
||||
165,
|
||||
],
|
||||
7,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
167,
|
||||
228,
|
||||
138,
|
||||
66,
|
||||
163,
|
||||
222,
|
||||
134,
|
||||
64,
|
||||
230,
|
||||
229,
|
||||
139,
|
||||
166,
|
||||
224,
|
||||
223,
|
||||
135,
|
||||
162,
|
||||
165,
|
||||
225,
|
||||
136,
|
||||
65,
|
||||
],
|
||||
8,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
200,
|
||||
57,
|
||||
113,
|
||||
234,
|
||||
196,
|
||||
59,
|
||||
109,
|
||||
228,
|
||||
201,
|
||||
112,
|
||||
232,
|
||||
233,
|
||||
197,
|
||||
108,
|
||||
226,
|
||||
227,
|
||||
198,
|
||||
58,
|
||||
111,
|
||||
231,
|
||||
],
|
||||
9,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
234,
|
||||
113,
|
||||
38,
|
||||
142,
|
||||
228,
|
||||
109,
|
||||
36,
|
||||
138,
|
||||
232,
|
||||
114,
|
||||
141,
|
||||
235,
|
||||
226,
|
||||
110,
|
||||
137,
|
||||
229,
|
||||
231,
|
||||
111,
|
||||
37,
|
||||
140,
|
||||
],
|
||||
10,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
83,
|
||||
200,
|
||||
234,
|
||||
171,
|
||||
81,
|
||||
196,
|
||||
228,
|
||||
167,
|
||||
199,
|
||||
233,
|
||||
236,
|
||||
172,
|
||||
195,
|
||||
227,
|
||||
230,
|
||||
168,
|
||||
82,
|
||||
198,
|
||||
231,
|
||||
169,
|
||||
],
|
||||
11,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
171,
|
||||
234,
|
||||
142,
|
||||
68,
|
||||
167,
|
||||
228,
|
||||
138,
|
||||
66,
|
||||
236,
|
||||
235,
|
||||
143,
|
||||
170,
|
||||
230,
|
||||
229,
|
||||
139,
|
||||
166,
|
||||
169,
|
||||
231,
|
||||
140,
|
||||
67,
|
||||
],
|
||||
12,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
204,
|
||||
55,
|
||||
117,
|
||||
240,
|
||||
200,
|
||||
57,
|
||||
113,
|
||||
234,
|
||||
205,
|
||||
116,
|
||||
238,
|
||||
239,
|
||||
201,
|
||||
112,
|
||||
232,
|
||||
233,
|
||||
202,
|
||||
56,
|
||||
115,
|
||||
237,
|
||||
],
|
||||
13,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
240,
|
||||
117,
|
||||
40,
|
||||
146,
|
||||
234,
|
||||
113,
|
||||
38,
|
||||
142,
|
||||
238,
|
||||
118,
|
||||
145,
|
||||
241,
|
||||
232,
|
||||
114,
|
||||
141,
|
||||
235,
|
||||
237,
|
||||
115,
|
||||
39,
|
||||
144,
|
||||
],
|
||||
14,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
85,
|
||||
204,
|
||||
240,
|
||||
175,
|
||||
83,
|
||||
200,
|
||||
234,
|
||||
171,
|
||||
203,
|
||||
239,
|
||||
242,
|
||||
176,
|
||||
199,
|
||||
233,
|
||||
236,
|
||||
172,
|
||||
84,
|
||||
202,
|
||||
237,
|
||||
173,
|
||||
],
|
||||
15,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
175,
|
||||
240,
|
||||
146,
|
||||
70,
|
||||
171,
|
||||
234,
|
||||
142,
|
||||
68,
|
||||
242,
|
||||
241,
|
||||
147,
|
||||
174,
|
||||
236,
|
||||
235,
|
||||
143,
|
||||
170,
|
||||
173,
|
||||
237,
|
||||
144,
|
||||
69,
|
||||
],
|
||||
16,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
208,
|
||||
53,
|
||||
121,
|
||||
246,
|
||||
204,
|
||||
55,
|
||||
117,
|
||||
240,
|
||||
209,
|
||||
120,
|
||||
244,
|
||||
245,
|
||||
205,
|
||||
116,
|
||||
238,
|
||||
239,
|
||||
206,
|
||||
54,
|
||||
119,
|
||||
243,
|
||||
],
|
||||
17,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
246,
|
||||
121,
|
||||
42,
|
||||
150,
|
||||
240,
|
||||
117,
|
||||
40,
|
||||
146,
|
||||
244,
|
||||
122,
|
||||
149,
|
||||
247,
|
||||
238,
|
||||
118,
|
||||
145,
|
||||
241,
|
||||
243,
|
||||
119,
|
||||
41,
|
||||
148,
|
||||
],
|
||||
18,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
87,
|
||||
208,
|
||||
246,
|
||||
179,
|
||||
85,
|
||||
204,
|
||||
240,
|
||||
175,
|
||||
207,
|
||||
245,
|
||||
248,
|
||||
180,
|
||||
203,
|
||||
239,
|
||||
242,
|
||||
176,
|
||||
86,
|
||||
206,
|
||||
243,
|
||||
177,
|
||||
],
|
||||
19,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
179,
|
||||
246,
|
||||
150,
|
||||
72,
|
||||
175,
|
||||
240,
|
||||
146,
|
||||
70,
|
||||
248,
|
||||
247,
|
||||
151,
|
||||
178,
|
||||
242,
|
||||
241,
|
||||
147,
|
||||
174,
|
||||
177,
|
||||
243,
|
||||
148,
|
||||
71,
|
||||
],
|
||||
20,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
212,
|
||||
51,
|
||||
125,
|
||||
252,
|
||||
208,
|
||||
53,
|
||||
121,
|
||||
246,
|
||||
213,
|
||||
124,
|
||||
250,
|
||||
251,
|
||||
209,
|
||||
120,
|
||||
244,
|
||||
245,
|
||||
210,
|
||||
52,
|
||||
123,
|
||||
249,
|
||||
],
|
||||
21,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
252,
|
||||
125,
|
||||
44,
|
||||
154,
|
||||
246,
|
||||
121,
|
||||
42,
|
||||
150,
|
||||
250,
|
||||
126,
|
||||
153,
|
||||
253,
|
||||
244,
|
||||
122,
|
||||
149,
|
||||
247,
|
||||
249,
|
||||
123,
|
||||
43,
|
||||
152,
|
||||
],
|
||||
22,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
89,
|
||||
212,
|
||||
252,
|
||||
183,
|
||||
87,
|
||||
208,
|
||||
246,
|
||||
179,
|
||||
211,
|
||||
251,
|
||||
254,
|
||||
184,
|
||||
207,
|
||||
245,
|
||||
248,
|
||||
180,
|
||||
88,
|
||||
210,
|
||||
249,
|
||||
181,
|
||||
],
|
||||
23,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
183,
|
||||
252,
|
||||
154,
|
||||
74,
|
||||
179,
|
||||
246,
|
||||
150,
|
||||
72,
|
||||
254,
|
||||
253,
|
||||
155,
|
||||
182,
|
||||
248,
|
||||
247,
|
||||
151,
|
||||
178,
|
||||
181,
|
||||
249,
|
||||
152,
|
||||
73,
|
||||
],
|
||||
24,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
216,
|
||||
49,
|
||||
129,
|
||||
258,
|
||||
212,
|
||||
51,
|
||||
125,
|
||||
252,
|
||||
217,
|
||||
128,
|
||||
256,
|
||||
257,
|
||||
213,
|
||||
124,
|
||||
250,
|
||||
251,
|
||||
214,
|
||||
50,
|
||||
127,
|
||||
255,
|
||||
],
|
||||
25,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
258,
|
||||
129,
|
||||
46,
|
||||
158,
|
||||
252,
|
||||
125,
|
||||
44,
|
||||
154,
|
||||
256,
|
||||
130,
|
||||
157,
|
||||
259,
|
||||
250,
|
||||
126,
|
||||
153,
|
||||
253,
|
||||
255,
|
||||
127,
|
||||
45,
|
||||
156,
|
||||
],
|
||||
26,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
91,
|
||||
216,
|
||||
258,
|
||||
187,
|
||||
89,
|
||||
212,
|
||||
252,
|
||||
183,
|
||||
215,
|
||||
257,
|
||||
260,
|
||||
188,
|
||||
211,
|
||||
251,
|
||||
254,
|
||||
184,
|
||||
90,
|
||||
214,
|
||||
255,
|
||||
185,
|
||||
],
|
||||
27,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
187,
|
||||
258,
|
||||
158,
|
||||
76,
|
||||
183,
|
||||
252,
|
||||
154,
|
||||
74,
|
||||
260,
|
||||
259,
|
||||
159,
|
||||
186,
|
||||
254,
|
||||
253,
|
||||
155,
|
||||
182,
|
||||
185,
|
||||
255,
|
||||
156,
|
||||
75,
|
||||
],
|
||||
28,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
31,
|
||||
5,
|
||||
22,
|
||||
100,
|
||||
216,
|
||||
49,
|
||||
129,
|
||||
258,
|
||||
32,
|
||||
21,
|
||||
98,
|
||||
99,
|
||||
217,
|
||||
128,
|
||||
256,
|
||||
257,
|
||||
218,
|
||||
48,
|
||||
131,
|
||||
261,
|
||||
],
|
||||
29,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
100,
|
||||
22,
|
||||
6,
|
||||
25,
|
||||
258,
|
||||
129,
|
||||
46,
|
||||
158,
|
||||
98,
|
||||
23,
|
||||
24,
|
||||
101,
|
||||
256,
|
||||
130,
|
||||
157,
|
||||
259,
|
||||
261,
|
||||
131,
|
||||
47,
|
||||
160,
|
||||
],
|
||||
30,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
8,
|
||||
31,
|
||||
100,
|
||||
28,
|
||||
91,
|
||||
216,
|
||||
258,
|
||||
187,
|
||||
30,
|
||||
99,
|
||||
102,
|
||||
29,
|
||||
215,
|
||||
257,
|
||||
260,
|
||||
188,
|
||||
92,
|
||||
218,
|
||||
261,
|
||||
189,
|
||||
],
|
||||
31,
|
||||
)
|
||||
femmesh.addVolume(
|
||||
[
|
||||
28,
|
||||
100,
|
||||
25,
|
||||
7,
|
||||
187,
|
||||
258,
|
||||
158,
|
||||
76,
|
||||
102,
|
||||
101,
|
||||
26,
|
||||
27,
|
||||
260,
|
||||
259,
|
||||
159,
|
||||
186,
|
||||
189,
|
||||
261,
|
||||
160,
|
||||
77,
|
||||
],
|
||||
32,
|
||||
)
|
||||
return True
|
||||
|
||||
@@ -41,12 +41,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["ccxtools", "elmer", "mystran"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.buckling_platebuckling import setup
|
||||
@@ -64,6 +66,7 @@ one each mesh node on one edge 100 N tension force
|
||||
Does not work on Z88 because Z88 does not support quad4 elements
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -95,7 +98,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
doc.recompute()
|
||||
|
||||
# all geom boolean fragment
|
||||
geom_obj = SplitFeatures.makeBooleanFragments(name='ThePointPlate')
|
||||
geom_obj = SplitFeatures.makeBooleanFragments(name="ThePointPlate")
|
||||
geom_obj.Objects = [plate, force_pt1, force_pt2, force_pt3, force_pt4]
|
||||
doc.recompute()
|
||||
if FreeCAD.GuiUp:
|
||||
@@ -117,7 +120,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
elif solvertype == "elmer":
|
||||
solver_obj = ObjectsFem.makeSolverElmer(doc, "SolverElmer")
|
||||
ObjectsFem.makeEquationElasticity(doc, solver_obj)
|
||||
@@ -141,7 +144,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
analysis.addObject(solver_obj)
|
||||
|
||||
# shell thickness
|
||||
thickness_obj = ObjectsFem.makeElementGeometry2D(doc, 0.3, 'Thickness')
|
||||
thickness_obj = ObjectsFem.makeElementGeometry2D(doc, 0.3, "Thickness")
|
||||
analysis.addObject(thickness_obj)
|
||||
|
||||
# material
|
||||
@@ -175,6 +178,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:
|
||||
|
||||
@@ -44,12 +44,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force", "displacement"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "reinforced",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.rc_wall_2d import setup
|
||||
@@ -62,6 +64,7 @@ https://forum.freecad.org/viewtopic.php?f=18&t=33106&start=80#p296469
|
||||
example from Harry's epic topic: Concrete branch ready for testing
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -104,7 +107,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Unknown or unsupported solver type: {}. "
|
||||
@@ -163,6 +166,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:
|
||||
|
||||
@@ -43,12 +43,14 @@ def get_information():
|
||||
"constraints": ["force", "fixed"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.square_pipe_end_twisted_edgeforces import setup
|
||||
@@ -59,6 +61,7 @@ See forum topic post:
|
||||
...
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -93,7 +96,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Unknown or unsupported solver type: {}. "
|
||||
@@ -127,7 +130,8 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
(doc.SquareTube, "Edge4"),
|
||||
(doc.SquareTube, "Edge7"),
|
||||
(doc.SquareTube, "Edge10"),
|
||||
(doc.SquareTube, "Edge12")]
|
||||
(doc.SquareTube, "Edge12"),
|
||||
]
|
||||
analysis.addObject(con_fixed)
|
||||
|
||||
# con_force1
|
||||
@@ -164,6 +168,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:
|
||||
|
||||
@@ -43,12 +43,14 @@ def get_information():
|
||||
"constraints": ["force", "fixed"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.square_pipe_end_twisted_nodeforces import setup
|
||||
@@ -59,6 +61,7 @@ See forum topic post:
|
||||
...
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -203,7 +206,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Unknown or unsupported solver type: {}. "
|
||||
@@ -281,7 +284,8 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
(geofixes_obj, "Vertex45"),
|
||||
(geofixes_obj, "Vertex27"),
|
||||
(geofixes_obj, "Vertex2"),
|
||||
(geofixes_obj, "Vertex25")]
|
||||
(geofixes_obj, "Vertex25"),
|
||||
]
|
||||
analysis.addObject(con_fixed)
|
||||
|
||||
# con_force1
|
||||
@@ -307,7 +311,8 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
(geoforces_obj, "Vertex21"),
|
||||
(geoforces_obj, "Vertex22"),
|
||||
(geoforces_obj, "Vertex23"),
|
||||
(geoforces_obj, "Vertex24"), ]
|
||||
(geoforces_obj, "Vertex24"),
|
||||
]
|
||||
con_force3.Force = "27777.78 N"
|
||||
con_force3.Direction = (geom_obj, ["Edge9"])
|
||||
con_force3.Reversed = False
|
||||
@@ -320,7 +325,8 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
(geoforces_obj, "Vertex10"),
|
||||
(geoforces_obj, "Vertex11"),
|
||||
(geoforces_obj, "Vertex12"),
|
||||
(geoforces_obj, "Vertex13"), ]
|
||||
(geoforces_obj, "Vertex13"),
|
||||
]
|
||||
con_force4.Force = "27777.78 N"
|
||||
con_force4.Direction = (geom_obj, ["Edge3"])
|
||||
con_force4.Reversed = False
|
||||
@@ -334,7 +340,8 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
(geoforces_obj, "Vertex45"),
|
||||
(geoforces_obj, "Vertex46"),
|
||||
(geoforces_obj, "Vertex47"),
|
||||
(geoforces_obj, "Vertex48"), ]
|
||||
(geoforces_obj, "Vertex48"),
|
||||
]
|
||||
con_force5.Force = "66666.67 N"
|
||||
con_force5.Direction = (geom_obj, ["Edge9"])
|
||||
con_force5.Reversed = False
|
||||
@@ -348,7 +355,8 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
(geoforces_obj, "Vertex33"),
|
||||
(geoforces_obj, "Vertex34"),
|
||||
(geoforces_obj, "Vertex35"),
|
||||
(geoforces_obj, "Vertex36"), ]
|
||||
(geoforces_obj, "Vertex36"),
|
||||
]
|
||||
con_force6.Force = "66666.67 N"
|
||||
con_force6.Direction = (geom_obj, ["Edge3"])
|
||||
con_force6.Reversed = False
|
||||
@@ -377,7 +385,8 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
(geoforces_obj, "Vertex4"),
|
||||
(geoforces_obj, "Vertex5"),
|
||||
(geoforces_obj, "Vertex6"),
|
||||
(geoforces_obj, "Vertex7"), ]
|
||||
(geoforces_obj, "Vertex7"),
|
||||
]
|
||||
con_force9.Force = "27777.78 N"
|
||||
con_force9.Direction = (geom_obj, ["Edge11"])
|
||||
con_force9.Reversed = False
|
||||
@@ -390,7 +399,8 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
(geoforces_obj, "Vertex16"),
|
||||
(geoforces_obj, "Vertex17"),
|
||||
(geoforces_obj, "Vertex18"),
|
||||
(geoforces_obj, "Vertex19"), ]
|
||||
(geoforces_obj, "Vertex19"),
|
||||
]
|
||||
con_force10.Force = "27777.78 N"
|
||||
con_force10.Direction = (geom_obj, ["Edge6"])
|
||||
con_force10.Reversed = False
|
||||
@@ -404,7 +414,8 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
(geoforces_obj, "Vertex27"),
|
||||
(geoforces_obj, "Vertex28"),
|
||||
(geoforces_obj, "Vertex29"),
|
||||
(geoforces_obj, "Vertex30"), ]
|
||||
(geoforces_obj, "Vertex30"),
|
||||
]
|
||||
con_force11.Force = "66666.67 N"
|
||||
con_force11.Direction = (geom_obj, ["Edge11"])
|
||||
con_force11.Reversed = False
|
||||
@@ -418,7 +429,8 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
(geoforces_obj, "Vertex39"),
|
||||
(geoforces_obj, "Vertex40"),
|
||||
(geoforces_obj, "Vertex41"),
|
||||
(geoforces_obj, "Vertex42"), ]
|
||||
(geoforces_obj, "Vertex42"),
|
||||
]
|
||||
con_force12.Force = "66666.67 N"
|
||||
con_force12.Direction = (geom_obj, ["Edge6"])
|
||||
con_force12.Reversed = False
|
||||
@@ -426,6 +438,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:
|
||||
|
||||
@@ -51,12 +51,14 @@ def get_information():
|
||||
"constraints": ["fixed", "initial temperature", "temperature"],
|
||||
"solvers": ["ccxtools", "elmer"],
|
||||
"material": "multimaterial",
|
||||
"equations": ["thermomechanical"]
|
||||
"equations": ["thermomechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.thermomech_bimetall import setup
|
||||
@@ -73,6 +75,7 @@ this file has 7.15 mm max deflection
|
||||
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -105,7 +108,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
doc.recompute()
|
||||
|
||||
# all geom boolean fragment
|
||||
geom_obj = SplitFeatures.makeBooleanFragments(name='BooleanFragments')
|
||||
geom_obj = SplitFeatures.makeBooleanFragments(name="BooleanFragments")
|
||||
geom_obj.Objects = [bottom_box_obj, top_box_obj]
|
||||
if FreeCAD.GuiUp:
|
||||
bottom_box_obj.ViewObject.hide()
|
||||
@@ -122,7 +125,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
elif solvertype == "elmer":
|
||||
solver_obj = analysis.addObject(ObjectsFem.makeSolverElmer(doc, "SolverElmer"))[0]
|
||||
solver_obj.SteadyStateMinIterations = 1
|
||||
@@ -189,25 +192,20 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
# constraint temperature
|
||||
con_temp = ObjectsFem.makeConstraintTemperature(doc, "ConstraintTemperatureHot")
|
||||
con_temp.References = [
|
||||
(geom_obj, "Face5"),
|
||||
(geom_obj, "Face11")
|
||||
]
|
||||
con_temp.References = [(geom_obj, "Face5"), (geom_obj, "Face11")]
|
||||
con_temp.Temperature = 373.0
|
||||
con_temp.CFlux = 0.0
|
||||
analysis.addObject(con_temp)
|
||||
|
||||
con_temp = ObjectsFem.makeConstraintTemperature(doc, "ConstraintTemperatureNormal")
|
||||
con_temp.References = [
|
||||
(geom_obj, "Face1"),
|
||||
(geom_obj, "Face7")
|
||||
]
|
||||
con_temp.References = [(geom_obj, "Face1"), (geom_obj, "Face7")]
|
||||
con_temp.Temperature = 273.0
|
||||
con_temp.CFlux = 0.0
|
||||
analysis.addObject(con_temp)
|
||||
|
||||
# mesh
|
||||
from .meshes.mesh_thermomech_bimetall_tetra10 import create_nodes, create_elements
|
||||
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
|
||||
@@ -38,7 +38,7 @@ def get_information():
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["z88"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,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:
|
||||
|
||||
@@ -43,12 +43,14 @@ def get_information():
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["ccxtools"],
|
||||
"material": "solid",
|
||||
"equations": ["mechanical"]
|
||||
"equations": ["mechanical"],
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
return (
|
||||
header
|
||||
+ """
|
||||
|
||||
# To run the example from Python console use,
|
||||
# (works even after an edit without restart of FreeCAD):
|
||||
@@ -69,6 +71,7 @@ Z88 official example 2, crane beam
|
||||
- max deflection Mystran : x.xx mm
|
||||
- max deflection Z88 : 8.19 mm # one seg2 truss element foreach bar
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
@@ -401,7 +404,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver
|
||||
if solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculiXCcxTools(doc, "CalculiXCcxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
solver_obj.WorkingDir = ""
|
||||
elif solvertype == "z88":
|
||||
solver_obj = ObjectsFem.makeSolverZ88(doc, "SolverZ88")
|
||||
else:
|
||||
@@ -420,10 +423,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
# beam section
|
||||
beamsection_obj = ObjectsFem.makeElementGeometry1D(
|
||||
doc,
|
||||
sectiontype="Circular",
|
||||
height=25.0,
|
||||
name="CrossSectionCircular"
|
||||
doc, sectiontype="Circular", height=25.0, name="CrossSectionCircular"
|
||||
)
|
||||
analysis.addObject(beamsection_obj)
|
||||
|
||||
@@ -451,6 +451,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:
|
||||
|
||||
@@ -31,7 +31,7 @@ __author__ = "Bernd Hahnebach"
|
||||
__url__ = "https://www.freecad.org"
|
||||
|
||||
|
||||
class FemMigrateGui(object):
|
||||
class FemMigrateGui:
|
||||
|
||||
def find_module(self, fullname, path):
|
||||
|
||||
@@ -168,220 +168,308 @@ class FemMigrateGui(object):
|
||||
module.__path__ = "femguiobjects"
|
||||
if module.__name__ == "femguiobjects._ViewProviderFemConstraintBodyHeatSource":
|
||||
import femviewprovider.view_constraint_bodyheatsource
|
||||
module.ViewProxy = \
|
||||
|
||||
module.ViewProxy = (
|
||||
femviewprovider.view_constraint_bodyheatsource.VPConstraintBodyHeatSource
|
||||
)
|
||||
if module.__name__ == "femguiobjects._ViewProviderFemConstraintElectrostaticPotential":
|
||||
import femviewprovider.view_constraint_electrostaticpotential
|
||||
module.ViewProxy = \
|
||||
|
||||
module.ViewProxy = (
|
||||
femviewprovider.view_constraint_electrostaticpotential.VPConstraintElectroStaticPotential
|
||||
)
|
||||
if module.__name__ == "femguiobjects._ViewProviderFemConstraintFlowVelocity":
|
||||
import femviewprovider.view_constraint_flowvelocity
|
||||
module.ViewProxy = \
|
||||
femviewprovider.view_constraint_flowvelocity.VPConstraintFlowVelocity
|
||||
|
||||
module.ViewProxy = femviewprovider.view_constraint_flowvelocity.VPConstraintFlowVelocity
|
||||
if module.__name__ == "femguiobjects._ViewProviderFemConstraintInitialFlowVelocity":
|
||||
import femviewprovider.view_constraint_initialflowvelocity
|
||||
module.ViewProxy = \
|
||||
|
||||
module.ViewProxy = (
|
||||
femviewprovider.view_constraint_initialflowvelocity.VPConstraintInitialFlowVelocity
|
||||
)
|
||||
if module.__name__ == "femguiobjects._ViewProviderFemConstraintSelfWeight":
|
||||
import femviewprovider.view_constraint_selfweight
|
||||
module._ViewProviderFemConstraintSelfWeight = \
|
||||
|
||||
module._ViewProviderFemConstraintSelfWeight = (
|
||||
femviewprovider.view_constraint_selfweight.VPConstraintSelfWeight
|
||||
)
|
||||
if module.__name__ == "femguiobjects._ViewProviderFemConstraintTie":
|
||||
import femviewprovider.view_constraint_tie
|
||||
module._ViewProviderFemConstraintTie = \
|
||||
|
||||
module._ViewProviderFemConstraintTie = (
|
||||
femviewprovider.view_constraint_tie.VPConstraintTie
|
||||
)
|
||||
if module.__name__ == "femguiobjects._ViewProviderFemElementFluid1D":
|
||||
import femviewprovider.view_element_fluid1D
|
||||
module._ViewProviderFemElementFluid1D = \
|
||||
|
||||
module._ViewProviderFemElementFluid1D = (
|
||||
femviewprovider.view_element_fluid1D.VPElementFluid1D
|
||||
)
|
||||
if module.__name__ == "femguiobjects._ViewProviderFemElementGeometry1D":
|
||||
import femviewprovider.view_element_geometry1D
|
||||
module._ViewProviderFemElementGeometry1D = \
|
||||
|
||||
module._ViewProviderFemElementGeometry1D = (
|
||||
femviewprovider.view_element_geometry1D.VPElementGeometry1D
|
||||
)
|
||||
if module.__name__ == "femguiobjects._ViewProviderFemElementGeometry2D":
|
||||
import femviewprovider.view_element_geometry2D
|
||||
module._ViewProviderFemElementGeometry2D = \
|
||||
|
||||
module._ViewProviderFemElementGeometry2D = (
|
||||
femviewprovider.view_element_geometry2D.VPElementGeometry2D
|
||||
)
|
||||
if module.__name__ == "femguiobjects._ViewProviderFemElementRotation1D":
|
||||
import femviewprovider.view_element_rotation1D
|
||||
module._ViewProviderFemElementRotation1D = \
|
||||
|
||||
module._ViewProviderFemElementRotation1D = (
|
||||
femviewprovider.view_element_rotation1D.VPElementRotation1D
|
||||
)
|
||||
if module.__name__ == "femguiobjects._ViewProviderFemMaterial":
|
||||
import femviewprovider.view_material_common
|
||||
|
||||
module._ViewProviderFemMaterial = femviewprovider.view_material_common.VPMaterialCommon
|
||||
if module.__name__ == "femguiobjects._ViewProviderFemMaterialMechanicalNonlinear":
|
||||
import femviewprovider.view_material_mechanicalnonlinear
|
||||
module._ViewProviderFemMaterialMechanicalNonlinear = \
|
||||
|
||||
module._ViewProviderFemMaterialMechanicalNonlinear = (
|
||||
femviewprovider.view_material_mechanicalnonlinear.VPMaterialMechanicalNonlinear
|
||||
)
|
||||
if module.__name__ == "femguiobjects._ViewProviderFemMaterialReinforced":
|
||||
import femviewprovider.view_material_reinforced
|
||||
module._ViewProviderFemMaterialReinforced = \
|
||||
|
||||
module._ViewProviderFemMaterialReinforced = (
|
||||
femviewprovider.view_material_reinforced.VPMaterialReinforced
|
||||
)
|
||||
if module.__name__ == "femguiobjects._ViewProviderFemMeshBoundaryLayer":
|
||||
import femviewprovider.view_mesh_boundarylayer
|
||||
module._ViewProviderFemMeshBoundaryLayer = \
|
||||
|
||||
module._ViewProviderFemMeshBoundaryLayer = (
|
||||
femviewprovider.view_mesh_boundarylayer.VPMeshBoundaryLayer
|
||||
)
|
||||
if module.__name__ == "femguiobjects._ViewProviderFemMeshGmsh":
|
||||
import femviewprovider.view_mesh_gmsh
|
||||
|
||||
module._ViewProviderFemMeshGmsh = femviewprovider.view_mesh_gmsh.VPMeshGmsh
|
||||
if module.__name__ == "femguiobjects._ViewProviderFemMeshGroup":
|
||||
import femviewprovider.view_mesh_group
|
||||
|
||||
module._ViewProviderFemMeshGroup = femviewprovider.view_mesh_group.VPMeshGroup
|
||||
if module.__name__ == "femguiobjects._ViewProviderFemMeshRegion":
|
||||
import femviewprovider.view_mesh_region
|
||||
|
||||
module._ViewProviderFemMeshRegion = femviewprovider.view_mesh_region.VPMeshRegion
|
||||
if module.__name__ == "femguiobjects._ViewProviderFemMeshResult":
|
||||
import femviewprovider.view_mesh_result
|
||||
|
||||
module._ViewProviderFemMeshResult = femviewprovider.view_mesh_result.VPFemMeshResult
|
||||
if module.__name__ == "femguiobjects._ViewProviderFemResultMechanical":
|
||||
import femviewprovider.view_result_mechanical
|
||||
module._ViewProviderFemResultMechanical = \
|
||||
|
||||
module._ViewProviderFemResultMechanical = (
|
||||
femviewprovider.view_result_mechanical.VPResultMechanical
|
||||
)
|
||||
if module.__name__ == "femguiobjects._ViewProviderFemSolverCalculix":
|
||||
import femviewprovider.view_solver_ccxtools
|
||||
module._ViewProviderFemSolverCalculix = \
|
||||
|
||||
module._ViewProviderFemSolverCalculix = (
|
||||
femviewprovider.view_solver_ccxtools.VPSolverCcxTools
|
||||
)
|
||||
|
||||
if module.__name__ == "PyGui":
|
||||
module.__path__ = "PyGui"
|
||||
if module.__name__ == "PyGui._ViewProviderFemConstraintBodyHeatSource":
|
||||
import femviewprovider.view_constraint_bodyheatsource
|
||||
module.ViewProxy = \
|
||||
|
||||
module.ViewProxy = (
|
||||
femviewprovider.view_constraint_bodyheatsource.VPConstraintBodyHeatSource
|
||||
)
|
||||
if module.__name__ == "PyGui._ViewProviderFemConstraintElectrostaticPotential":
|
||||
import femviewprovider.view_constraint_electrostaticpotential
|
||||
module.ViewProxy = \
|
||||
|
||||
module.ViewProxy = (
|
||||
femviewprovider.view_constraint_electrostaticpotential.VPConstraintElectroStaticPotential
|
||||
)
|
||||
if module.__name__ == "PyGui._ViewProviderFemConstraintFlowVelocity":
|
||||
import femviewprovider.view_constraint_flowvelocity
|
||||
module.ViewProxy = \
|
||||
femviewprovider.view_constraint_flowvelocity.VPConstraintFlowVelocity
|
||||
|
||||
module.ViewProxy = femviewprovider.view_constraint_flowvelocity.VPConstraintFlowVelocity
|
||||
if module.__name__ == "PyGui._ViewProviderFemConstraintInitialFlowVelocity":
|
||||
import femviewprovider.view_constraint_initialflowvelocity
|
||||
module.ViewProxy = \
|
||||
|
||||
module.ViewProxy = (
|
||||
femviewprovider.view_constraint_initialflowvelocity.VPConstraintInitialFlowVelocity
|
||||
)
|
||||
if module.__name__ == "PyGui._ViewProviderFemConstraintSelfWeight":
|
||||
import femviewprovider.view_constraint_selfweight
|
||||
module._ViewProviderFemConstraintSelfWeight = \
|
||||
|
||||
module._ViewProviderFemConstraintSelfWeight = (
|
||||
femviewprovider.view_constraint_selfweight.VPConstraintSelfWeight
|
||||
)
|
||||
if module.__name__ == "PyGui._ViewProviderFemElementFluid1D":
|
||||
import femviewprovider.view_element_fluid1D
|
||||
module._ViewProviderFemElementFluid1D = \
|
||||
|
||||
module._ViewProviderFemElementFluid1D = (
|
||||
femviewprovider.view_element_fluid1D.VPElementFluid1D
|
||||
)
|
||||
if module.__name__ == "PyGui._ViewProviderFemElementGeometry1D":
|
||||
import femviewprovider.view_element_geometry1D
|
||||
module._ViewProviderFemElementGeometry1D = \
|
||||
|
||||
module._ViewProviderFemElementGeometry1D = (
|
||||
femviewprovider.view_element_geometry1D.VPElementGeometry1D
|
||||
)
|
||||
if module.__name__ == "PyGui._ViewProviderFemElementGeometry2D":
|
||||
import femviewprovider.view_element_geometry2D
|
||||
module._ViewProviderFemElementGeometry2D = \
|
||||
|
||||
module._ViewProviderFemElementGeometry2D = (
|
||||
femviewprovider.view_element_geometry2D.VPElementGeometry2D
|
||||
)
|
||||
if module.__name__ == "PyGui._ViewProviderFemElementRotation1D":
|
||||
import femviewprovider.view_element_rotation1D
|
||||
module._ViewProviderFemElementRotation1D = \
|
||||
|
||||
module._ViewProviderFemElementRotation1D = (
|
||||
femviewprovider.view_element_rotation1D.VPElementRotation1D
|
||||
)
|
||||
if module.__name__ == "PyGui._ViewProviderFemMaterial":
|
||||
import femviewprovider.view_material_common
|
||||
module._ViewProviderFemMaterial = \
|
||||
femviewprovider.view_material_common.VPMaterialCommon
|
||||
|
||||
module._ViewProviderFemMaterial = femviewprovider.view_material_common.VPMaterialCommon
|
||||
if module.__name__ == "PyGui._ViewProviderFemMaterialMechanicalNonlinear":
|
||||
import femviewprovider.view_material_mechanicalnonlinear
|
||||
module._ViewProviderFemMaterialMechanicalNonlinear = \
|
||||
|
||||
module._ViewProviderFemMaterialMechanicalNonlinear = (
|
||||
femviewprovider.view_material_mechanicalnonlinear.VPMaterialMechanicalNonlinear
|
||||
)
|
||||
if module.__name__ == "PyGui._ViewProviderFemMeshBoundaryLayer":
|
||||
import femviewprovider.view_mesh_boundarylayer
|
||||
module._ViewProviderFemMeshBoundaryLayer = \
|
||||
|
||||
module._ViewProviderFemMeshBoundaryLayer = (
|
||||
femviewprovider.view_mesh_boundarylayer.VPMeshBoundaryLayer
|
||||
)
|
||||
if module.__name__ == "PyGui._ViewProviderFemMeshGmsh":
|
||||
import femviewprovider.view_mesh_gmsh
|
||||
|
||||
module._ViewProviderFemMeshGmsh = femviewprovider.view_mesh_gmsh.VPMeshGmsh
|
||||
if module.__name__ == "PyGui._ViewProviderFemMeshGroup":
|
||||
import femviewprovider.view_mesh_group
|
||||
|
||||
module._ViewProviderFemMeshGroup = femviewprovider.view_mesh_group.VPMeshGroup
|
||||
if module.__name__ == "PyGui._ViewProviderFemMeshRegion":
|
||||
import femviewprovider.view_mesh_region
|
||||
|
||||
module._ViewProviderFemMeshRegion = femviewprovider.view_mesh_region.VPMeshRegion
|
||||
if module.__name__ == "PyGui._ViewProviderFemMeshResult":
|
||||
import femviewprovider.view_mesh_result
|
||||
|
||||
module._ViewProviderFemMeshResult = femviewprovider.view_mesh_result.VPFemMeshResult
|
||||
if module.__name__ == "PyGui._ViewProviderFemResultMechanical":
|
||||
import femviewprovider.view_result_mechanical
|
||||
module._ViewProviderFemResultMechanical = \
|
||||
|
||||
module._ViewProviderFemResultMechanical = (
|
||||
femviewprovider.view_result_mechanical.VPResultMechanical
|
||||
)
|
||||
if module.__name__ == "PyGui._ViewProviderFemSolverCalculix":
|
||||
import femviewprovider.view_solver_ccxtools
|
||||
module._ViewProviderFemSolverCalculix = \
|
||||
|
||||
module._ViewProviderFemSolverCalculix = (
|
||||
femviewprovider.view_solver_ccxtools.VPSolverCcxTools
|
||||
)
|
||||
if module.__name__ == "PyGui._ViewProviderFemSolverZ88":
|
||||
import femsolver.z88.solver
|
||||
|
||||
module._ViewProviderFemSolverZ88 = femsolver.z88.solver.ViewProxy
|
||||
|
||||
if module.__name__ == "PyGui._ViewProviderFemBeamSection":
|
||||
import femviewprovider.view_element_geometry1D
|
||||
module._ViewProviderFemBeamSection = \
|
||||
|
||||
module._ViewProviderFemBeamSection = (
|
||||
femviewprovider.view_element_geometry1D.VPElementGeometry1D
|
||||
)
|
||||
if module.__name__ == "PyGui._ViewProviderFemFluidSection":
|
||||
import femviewprovider.view_element_fluid1D
|
||||
module._ViewProviderFemFluidSection = \
|
||||
|
||||
module._ViewProviderFemFluidSection = (
|
||||
femviewprovider.view_element_fluid1D.VPElementFluid1D
|
||||
)
|
||||
if module.__name__ == "PyGui._ViewProviderFemShellThickness":
|
||||
import femviewprovider.view_element_geometry2D
|
||||
module._ViewProviderFemShellThickness = \
|
||||
|
||||
module._ViewProviderFemShellThickness = (
|
||||
femviewprovider.view_element_geometry2D.VPElementGeometry2D
|
||||
)
|
||||
|
||||
if module.__name__ == "_ViewProviderFemBeamSection":
|
||||
import femviewprovider.view_element_geometry1D
|
||||
module._ViewProviderFemBeamSection = \
|
||||
|
||||
module._ViewProviderFemBeamSection = (
|
||||
femviewprovider.view_element_geometry1D.VPElementGeometry1D
|
||||
)
|
||||
if module.__name__ == "_ViewProviderFemConstraintSelfWeight":
|
||||
import femviewprovider.view_constraint_selfweight
|
||||
module._ViewProviderFemConstraintSelfWeight = \
|
||||
|
||||
module._ViewProviderFemConstraintSelfWeight = (
|
||||
femviewprovider.view_constraint_selfweight.VPConstraintSelfWeight
|
||||
)
|
||||
if module.__name__ == "_ViewProviderFemMaterial":
|
||||
import femviewprovider.view_material_common
|
||||
module._ViewProviderFemMaterial = \
|
||||
femviewprovider.view_material_common.VPMaterialCommon
|
||||
|
||||
module._ViewProviderFemMaterial = femviewprovider.view_material_common.VPMaterialCommon
|
||||
if module.__name__ == "_ViewProviderFemMaterialMechanicalNonlinear":
|
||||
import femviewprovider.view_material_mechanicalnonlinear
|
||||
module._ViewProviderFemMaterialMechanicalNonlinear = \
|
||||
|
||||
module._ViewProviderFemMaterialMechanicalNonlinear = (
|
||||
femviewprovider.view_material_mechanicalnonlinear.VPMaterialMechanicalNonlinear
|
||||
)
|
||||
if module.__name__ == "_ViewProviderFemMeshGmsh":
|
||||
import femviewprovider.view_mesh_gmsh
|
||||
|
||||
module._ViewProviderFemMeshGmsh = femviewprovider.view_mesh_gmsh.VPMeshGmsh
|
||||
if module.__name__ == "_ViewProviderFemMeshGroup":
|
||||
import femviewprovider.view_mesh_group
|
||||
|
||||
module._ViewProviderFemMeshGroup = femviewprovider.view_mesh_group.VPMeshGroup
|
||||
if module.__name__ == "_ViewProviderFemMeshRegion":
|
||||
import femviewprovider.view_mesh_region
|
||||
|
||||
module._ViewProviderFemMeshRegion = femviewprovider.view_mesh_region.VPMeshRegion
|
||||
if module.__name__ == "_ViewProviderFemResultMechanical":
|
||||
import femviewprovider.view_result_mechanical
|
||||
module._ViewProviderFemResultMechanical = \
|
||||
|
||||
module._ViewProviderFemResultMechanical = (
|
||||
femviewprovider.view_result_mechanical.VPResultMechanical
|
||||
)
|
||||
if module.__name__ == "_ViewProviderFemShellThickness":
|
||||
import femviewprovider.view_element_geometry2D
|
||||
module._ViewProviderFemShellThickness = \
|
||||
|
||||
module._ViewProviderFemShellThickness = (
|
||||
femviewprovider.view_element_geometry2D.VPElementGeometry2D
|
||||
)
|
||||
if module.__name__ == "_ViewProviderFemSolverCalculix":
|
||||
import femviewprovider.view_solver_ccxtools
|
||||
module._ViewProviderFemSolverCalculix = \
|
||||
|
||||
module._ViewProviderFemSolverCalculix = (
|
||||
femviewprovider.view_solver_ccxtools.VPSolverCcxTools
|
||||
)
|
||||
if module.__name__ == "_ViewProviderFemSolverZ88":
|
||||
import femsolver.z88.solver
|
||||
|
||||
module._ViewProviderFemSolverZ88 = femsolver.z88.solver.ViewProxy
|
||||
|
||||
if module.__name__ == "_ViewProviderFemMechanicalResult":
|
||||
import femviewprovider.view_result_mechanical
|
||||
module._ViewProviderFemMechanicalResult = \
|
||||
|
||||
module._ViewProviderFemMechanicalResult = (
|
||||
femviewprovider.view_result_mechanical.VPResultMechanical
|
||||
)
|
||||
if module.__name__ == "ViewProviderFemResult":
|
||||
import femviewprovider.view_result_mechanical
|
||||
module.ViewProviderFemResult = \
|
||||
femviewprovider.view_result_mechanical.VPResultMechanical
|
||||
|
||||
module.ViewProviderFemResult = femviewprovider.view_result_mechanical.VPResultMechanical
|
||||
if module.__name__ == "_ViewProviderMechanicalMaterial":
|
||||
import femviewprovider.view_material_common
|
||||
module._ViewProviderMechanicalMaterial = \
|
||||
|
||||
module._ViewProviderMechanicalMaterial = (
|
||||
femviewprovider.view_material_common.VPMaterialCommon
|
||||
)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ from femtools import geomtools
|
||||
class _Selector(QtGui.QWidget):
|
||||
|
||||
def __init__(self):
|
||||
super(_Selector, self).__init__()
|
||||
super().__init__()
|
||||
self._references = []
|
||||
self._register = dict()
|
||||
|
||||
@@ -92,7 +92,7 @@ class _Selector(QtGui.QWidget):
|
||||
obj, sub = self._register[identifier]
|
||||
refIndex = self._getIndex(obj)
|
||||
entry = self._references[refIndex]
|
||||
newSub = tuple((x for x in entry[1] if x != sub))
|
||||
newSub = tuple(x for x in entry[1] if x != sub)
|
||||
self._references[refIndex] = (obj, newSub)
|
||||
self._model.removeRow(index.row())
|
||||
|
||||
@@ -107,7 +107,7 @@ class _Selector(QtGui.QWidget):
|
||||
self._references[index] = newEntry
|
||||
|
||||
def _addToWidget(self, obj, sub):
|
||||
identifier = "%s::%s" % (obj.Name, sub)
|
||||
identifier = f"{obj.Name}::{sub}"
|
||||
item = QtGui.QStandardItem(identifier)
|
||||
self._model.appendRow(item)
|
||||
self._register[identifier] = (obj, sub)
|
||||
@@ -126,12 +126,9 @@ class _Selector(QtGui.QWidget):
|
||||
class BoundarySelector(_Selector):
|
||||
|
||||
def __init__(self):
|
||||
super(BoundarySelector, self).__init__()
|
||||
super().__init__()
|
||||
self.setWindowTitle(self.tr("Select Faces/Edges/Vertexes"))
|
||||
self.setHelpText(self.tr(
|
||||
"To add references: select them in the 3D view "
|
||||
' and click "Add".'
|
||||
))
|
||||
self.setHelpText(self.tr('To add references: select them in the 3D view and click "Add".'))
|
||||
|
||||
def getSelection(self):
|
||||
selection = []
|
||||
@@ -145,12 +142,14 @@ class BoundarySelector(_Selector):
|
||||
class SolidSelector(_Selector):
|
||||
|
||||
def __init__(self):
|
||||
super(SolidSelector, self).__init__()
|
||||
super().__init__()
|
||||
self.setWindowTitle(self.tr("Select Solids"))
|
||||
self.setHelpText(self.tr(
|
||||
"Select elements part of the solid that shall be added"
|
||||
' to the list. To add the solid click "Add".'
|
||||
))
|
||||
self.setHelpText(
|
||||
self.tr(
|
||||
"Select elements part of the solid that shall be added"
|
||||
' to the list. To add the solid click "Add".'
|
||||
)
|
||||
)
|
||||
|
||||
def getSelection(self):
|
||||
selection = []
|
||||
@@ -172,9 +171,7 @@ class SolidSelector(_Selector):
|
||||
def _getObjects(self, obj, names):
|
||||
objects = []
|
||||
if not hasattr(obj, "Shape"):
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"Selected object has no Shape.\n"
|
||||
)
|
||||
FreeCAD.Console.PrintMessage("Selected object has no Shape.\n")
|
||||
return objects
|
||||
shape = obj.Shape
|
||||
for n in names:
|
||||
@@ -227,7 +224,7 @@ class SmallListView(QtGui.QListView):
|
||||
class GeometryElementsSelection(QtGui.QWidget):
|
||||
|
||||
def __init__(self, ref, eltypes, multigeom, showHintEmptyList):
|
||||
super(GeometryElementsSelection, self).__init__()
|
||||
super().__init__()
|
||||
# init ui stuff
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
self.sel_server = None
|
||||
@@ -264,9 +261,9 @@ class GeometryElementsSelection(QtGui.QWidget):
|
||||
def initUI(self):
|
||||
# ArchPanel is coded without ui-file too
|
||||
# title
|
||||
self.setWindowTitle(self.tr(
|
||||
"Geometry reference selector for a {}"
|
||||
).format(self.sel_elem_text))
|
||||
self.setWindowTitle(
|
||||
self.tr("Geometry reference selector for a {}").format(self.sel_elem_text)
|
||||
)
|
||||
# button
|
||||
self.pushButton_Add = QtGui.QPushButton(self.tr("Add"))
|
||||
# label
|
||||
@@ -280,13 +277,9 @@ class GeometryElementsSelection(QtGui.QWidget):
|
||||
"{}If no geometry is added to the list, all remaining ones are used."
|
||||
).format("<br>")
|
||||
if self.showHintEmptyList is True:
|
||||
self._helpTextLbl.setText(
|
||||
helpTextPart1 + helpTextEmpty
|
||||
)
|
||||
self._helpTextLbl.setText(helpTextPart1 + helpTextEmpty)
|
||||
else:
|
||||
self._helpTextLbl.setText(
|
||||
helpTextPart1
|
||||
)
|
||||
self._helpTextLbl.setText(helpTextPart1)
|
||||
# list
|
||||
self.list_References = QtGui.QListWidget()
|
||||
# radiobutton down the list
|
||||
@@ -324,22 +317,14 @@ class GeometryElementsSelection(QtGui.QWidget):
|
||||
self.list_References.connect(
|
||||
self.list_References,
|
||||
QtCore.SIGNAL("customContextMenuRequested(QPoint)"),
|
||||
self.references_list_right_clicked
|
||||
self.references_list_right_clicked,
|
||||
)
|
||||
QtCore.QObject.connect(self.pushButton_Add, QtCore.SIGNAL("clicked()"), self.add_references)
|
||||
QtCore.QObject.connect(
|
||||
self.rb_standard, QtCore.SIGNAL("toggled(bool)"), self.choose_selection_mode_standard
|
||||
)
|
||||
QtCore.QObject.connect(
|
||||
self.pushButton_Add,
|
||||
QtCore.SIGNAL("clicked()"),
|
||||
self.add_references
|
||||
)
|
||||
QtCore.QObject.connect(
|
||||
self.rb_standard,
|
||||
QtCore.SIGNAL("toggled(bool)"),
|
||||
self.choose_selection_mode_standard
|
||||
)
|
||||
QtCore.QObject.connect(
|
||||
self.rb_solid,
|
||||
QtCore.SIGNAL("toggled(bool)"),
|
||||
self.choose_selection_mode_solid
|
||||
self.rb_solid, QtCore.SIGNAL("toggled(bool)"), self.choose_selection_mode_solid
|
||||
)
|
||||
|
||||
def get_references(self):
|
||||
@@ -408,8 +393,7 @@ class GeometryElementsSelection(QtGui.QWidget):
|
||||
FreeCADGui.Selection.addSelection(ref[0], ref[1])
|
||||
|
||||
def setback_listobj_visibility(self):
|
||||
"""set back Visibility of the list objects
|
||||
"""
|
||||
"""set back Visibility of the list objects"""
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
for obj in self.obj_notvisible:
|
||||
obj.ViewObject.Visibility = False
|
||||
@@ -423,15 +407,9 @@ class GeometryElementsSelection(QtGui.QWidget):
|
||||
menu_item_remove_selected.setDisabled(True)
|
||||
menu_item_remove_all.setDisabled(True)
|
||||
self.connect(
|
||||
menu_item_remove_selected,
|
||||
QtCore.SIGNAL("triggered()"),
|
||||
self.remove_selected_reference
|
||||
)
|
||||
self.connect(
|
||||
menu_item_remove_all,
|
||||
QtCore.SIGNAL("triggered()"),
|
||||
self.remove_all_references
|
||||
menu_item_remove_selected, QtCore.SIGNAL("triggered()"), self.remove_selected_reference
|
||||
)
|
||||
self.connect(menu_item_remove_all, QtCore.SIGNAL("triggered()"), self.remove_all_references)
|
||||
parentPosition = self.list_References.mapToGlobal(QtCore.QPoint(0, 0))
|
||||
self.contextMenu.move(parentPosition + QPos)
|
||||
self.contextMenu.show()
|
||||
@@ -479,11 +457,11 @@ class GeometryElementsSelection(QtGui.QWidget):
|
||||
|
||||
def selectionParser(self, selection):
|
||||
if hasattr(selection[0], "Shape") and selection[1]:
|
||||
FreeCAD.Console.PrintMessage("Selection: {} {} {}\n".format(
|
||||
selection[0].Shape.ShapeType,
|
||||
selection[0].Name,
|
||||
selection[1]
|
||||
))
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"Selection: {} {} {}\n".format(
|
||||
selection[0].Shape.ShapeType, selection[0].Name, selection[1]
|
||||
)
|
||||
)
|
||||
sobj = selection[0]
|
||||
elt = sobj.Shape.getElement(selection[1])
|
||||
ele_ShapeType = elt.ShapeType
|
||||
@@ -502,8 +480,7 @@ class GeometryElementsSelection(QtGui.QWidget):
|
||||
# could be more than two solids, think of polar pattern
|
||||
FreeCAD.Console.PrintMessage(
|
||||
" Edge belongs to at least two solids: "
|
||||
" Solid{}, Solid{}\n"
|
||||
.format(solid_to_add, str(i + 1))
|
||||
" Solid{}, Solid{}\n".format(solid_to_add, str(i + 1))
|
||||
)
|
||||
solid_to_add = None
|
||||
found_eltedge_in_other_solid = True
|
||||
@@ -517,8 +494,9 @@ class GeometryElementsSelection(QtGui.QWidget):
|
||||
else:
|
||||
# AFAIK (bernd) a face can only belong to two solids
|
||||
FreeCAD.Console.PrintMessage(
|
||||
" Face belongs to two solids: Solid{}, Solid{}\n"
|
||||
.format(solid_to_add, str(i + 1))
|
||||
" Face belongs to two solids: Solid{}, Solid{}\n".format(
|
||||
solid_to_add, str(i + 1)
|
||||
)
|
||||
)
|
||||
solid_to_add = None
|
||||
found_eltface_in_other_solid = True
|
||||
@@ -526,14 +504,16 @@ class GeometryElementsSelection(QtGui.QWidget):
|
||||
selection = (sobj, "Solid" + solid_to_add)
|
||||
ele_ShapeType = "Solid"
|
||||
FreeCAD.Console.PrintMessage(
|
||||
" Selection variable adapted to hold the Solid: {} {} {}\n"
|
||||
.format(sobj.Shape.ShapeType, sobj.Name, selection[1])
|
||||
" Selection variable adapted to hold the Solid: {} {} {}\n".format(
|
||||
sobj.Shape.ShapeType, sobj.Name, selection[1]
|
||||
)
|
||||
)
|
||||
else:
|
||||
return
|
||||
if ele_ShapeType in self.sel_elem_types:
|
||||
if (self.selection_mode_solid and ele_ShapeType == "Solid") \
|
||||
or self.selection_mode_solid is False:
|
||||
if (
|
||||
self.selection_mode_solid and ele_ShapeType == "Solid"
|
||||
) or self.selection_mode_solid is False:
|
||||
if selection not in self.references:
|
||||
# only equal shape types are allowed to add
|
||||
if self.allow_multiple_geom_types is False:
|
||||
@@ -553,15 +533,12 @@ class GeometryElementsSelection(QtGui.QWidget):
|
||||
else:
|
||||
# selected shape will not added to the list
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
message = (
|
||||
" Selection {} is in reference list already!\n"
|
||||
.format(self.get_item_text(selection))
|
||||
message = " Selection {} is in reference list already!\n".format(
|
||||
self.get_item_text(selection)
|
||||
)
|
||||
FreeCAD.Console.PrintMessage(message)
|
||||
QtGui.QMessageBox.critical(
|
||||
None,
|
||||
"Geometry already in list",
|
||||
message.lstrip(" ")
|
||||
None, "Geometry already in list", message.lstrip(" ")
|
||||
)
|
||||
else:
|
||||
# selected shape will not added to the list
|
||||
@@ -575,13 +552,12 @@ class GeometryElementsSelection(QtGui.QWidget):
|
||||
# the method getElement(element) does not return Solid elements
|
||||
r = geomtools.get_element(ref[0], ref[1])
|
||||
if not r:
|
||||
FreeCAD.Console.PrintError(
|
||||
"Problem in retrieving element: {} \n".format(ref[1])
|
||||
)
|
||||
FreeCAD.Console.PrintError(f"Problem in retrieving element: {ref[1]} \n")
|
||||
continue
|
||||
FreeCAD.Console.PrintLog(
|
||||
" ReferenceShape : {}, {}, {} --> {}\n"
|
||||
.format(r.ShapeType, ref[0].Name, ref[0].Label, ref[1])
|
||||
" ReferenceShape : {}, {}, {} --> {}\n".format(
|
||||
r.ShapeType, ref[0].Name, ref[0].Label, ref[1]
|
||||
)
|
||||
)
|
||||
if not ref_shty:
|
||||
ref_shty = r.ShapeType
|
||||
@@ -600,6 +576,7 @@ class GeometryElementsSelection(QtGui.QWidget):
|
||||
|
||||
class FemSelectionObserver:
|
||||
"""selection observer especially for the needs of geometry reference selection of FEM"""
|
||||
|
||||
def __init__(self, parseSelectionFunction, print_message=""):
|
||||
self.parseSelectionFunction = parseSelectionFunction
|
||||
FreeCADGui.Selection.addObserver(self)
|
||||
|
||||
@@ -37,6 +37,7 @@ import Mesh
|
||||
App = FreeCAD # shortcut
|
||||
if FreeCAD.GuiUp:
|
||||
import FreeCADGui
|
||||
|
||||
Gui = FreeCADGui # shortcut
|
||||
|
||||
## \addtogroup FEM
|
||||
@@ -54,23 +55,25 @@ def exportMeshToTetGenPoly(meshToExport, filePath, beVerbose=1):
|
||||
f.write("# Part 1 - node list\n")
|
||||
f.write(
|
||||
"TotalNumOfPoints: {}, NumOfDimensions; {}, "
|
||||
"NumOfProperties: {}, BoundaryMarkerExists: {}\n"
|
||||
.format(len(allVertices), 3, 0, 0)
|
||||
"NumOfProperties: {}, BoundaryMarkerExists: {}\n".format(len(allVertices), 3, 0, 0)
|
||||
)
|
||||
for PointIndex in range(len(allVertices)):
|
||||
f.write("%(PointIndex)5i %(x) e %(y) e %(z) e\n" % {
|
||||
"PointIndex": PointIndex,
|
||||
"x": allVertices[PointIndex].x,
|
||||
"y": allVertices[PointIndex].y,
|
||||
"z": allVertices[PointIndex].z
|
||||
})
|
||||
f.write(
|
||||
"%(PointIndex)5i %(x) e %(y) e %(z) e\n"
|
||||
% {
|
||||
"PointIndex": PointIndex,
|
||||
"x": allVertices[PointIndex].x,
|
||||
"y": allVertices[PointIndex].y,
|
||||
"z": allVertices[PointIndex].z,
|
||||
}
|
||||
)
|
||||
|
||||
# Find out BoundaryMarker for each facet. If edge connects only two facets,
|
||||
# then this facets should have the same BoundaryMarker
|
||||
BoundaryMarkerExists = 1
|
||||
PointList = [allFacets[0][1], allFacets[0][0]]
|
||||
PointList.sort()
|
||||
EdgeFacets = {(PointList[0], PointList[1]): set([0])}
|
||||
EdgeFacets = {(PointList[0], PointList[1]): {0}}
|
||||
Edge = []
|
||||
|
||||
# Find all facets for each edge
|
||||
@@ -85,7 +88,7 @@ def exportMeshToTetGenPoly(meshToExport, filePath, beVerbose=1):
|
||||
if EdgeIndex in EdgeFacets:
|
||||
EdgeFacets[EdgeIndex].add(FacetIndex)
|
||||
else:
|
||||
EdgeFacets[EdgeIndex] = set([FacetIndex])
|
||||
EdgeFacets[EdgeIndex] = {FacetIndex}
|
||||
Edge = []
|
||||
|
||||
# Find BoundaryMarker for each facet
|
||||
@@ -120,7 +123,7 @@ def exportMeshToTetGenPoly(meshToExport, filePath, beVerbose=1):
|
||||
if (BoundaryMarker[FacetPair[0]] != 0) and (BoundaryMarker[FacetPair[1]] != 0):
|
||||
removeEdge = 1
|
||||
break
|
||||
if (BoundaryMarker[FacetPair[0]] != 0):
|
||||
if BoundaryMarker[FacetPair[0]] != 0:
|
||||
BoundaryMarker[FacetPair[1]] = BoundaryMarker[FacetPair[0]]
|
||||
else:
|
||||
BoundaryMarker[FacetPair[0]] = BoundaryMarker[FacetPair[1]]
|
||||
@@ -156,10 +159,10 @@ def exportMeshToTetGenPoly(meshToExport, filePath, beVerbose=1):
|
||||
|
||||
# ********** Part 2 - write all facets to *.poly file
|
||||
f.write("# Part 2 - facet list\n")
|
||||
f.write("%(TotalNumOfFacets)i %(BoundaryMarkerExists)i\n" % {
|
||||
"TotalNumOfFacets": len(allFacets),
|
||||
"BoundaryMarkerExists": BoundaryMarkerExists
|
||||
})
|
||||
f.write(
|
||||
"%(TotalNumOfFacets)i %(BoundaryMarkerExists)i\n"
|
||||
% {"TotalNumOfFacets": len(allFacets), "BoundaryMarkerExists": BoundaryMarkerExists}
|
||||
)
|
||||
for FacetIndex in range(len(allFacets)):
|
||||
f.write("# FacetIndex = %(Index)i\n" % {"Index": FacetIndex})
|
||||
f.write("%(NumOfPolygons)3i " % {"NumOfPolygons": 1})
|
||||
@@ -215,14 +218,7 @@ def createMesh():
|
||||
AdsorbtionBox = AppPyDoc.addObject("Part::Box", AdsorbtionBoxName)
|
||||
pnMesh = AppPyDoc.addObject("Mesh::Feature", pnMeshName)
|
||||
|
||||
BoxList = [
|
||||
NSideBox,
|
||||
DepletionBox,
|
||||
PSideBox,
|
||||
OxideBox,
|
||||
AdsorbtionBox,
|
||||
SurfDepletionBox
|
||||
]
|
||||
BoxList = [NSideBox, DepletionBox, PSideBox, OxideBox, AdsorbtionBox, SurfDepletionBox]
|
||||
NSideBoxMesh = Mesh.Mesh()
|
||||
PSideBoxMesh = Mesh.Mesh()
|
||||
DepletionBoxMesh = Mesh.Mesh()
|
||||
@@ -235,7 +231,7 @@ def createMesh():
|
||||
PSideBoxMesh,
|
||||
OxideBoxMesh,
|
||||
AdsorbtionBoxMesh,
|
||||
SurfDepletionBoxMesh
|
||||
SurfDepletionBoxMesh,
|
||||
]
|
||||
if beVerbose == 1:
|
||||
if len(BoxList) != len(BoxMeshList):
|
||||
@@ -280,30 +276,14 @@ def createMesh():
|
||||
|
||||
# Object placement
|
||||
Rot = App.Rotation(0, 0, 0, 1)
|
||||
NSideBox.Placement = App.Placement(
|
||||
App.Vector(0, 0, -BulkHeight),
|
||||
Rot
|
||||
)
|
||||
NSideBox.Placement = App.Placement(App.Vector(0, 0, -BulkHeight), Rot)
|
||||
PSideBox.Placement = App.Placement(
|
||||
App.Vector(DepletionSize * 2 + BulkLength, 0, -BulkHeight),
|
||||
Rot
|
||||
)
|
||||
DepletionBox.Placement = App.Placement(
|
||||
App.Vector(BulkLength, 0, -BulkHeight),
|
||||
Rot
|
||||
)
|
||||
SurfDepletionBox.Placement = App.Placement(
|
||||
App.Vector(0, 0, 0),
|
||||
Rot
|
||||
)
|
||||
OxideBox.Placement = App.Placement(
|
||||
App.Vector(0, 0, DepletionSize),
|
||||
Rot
|
||||
)
|
||||
AdsorbtionBox.Placement = App.Placement(
|
||||
App.Vector(0, 0, DepletionSize + OxideThickness),
|
||||
Rot
|
||||
App.Vector(DepletionSize * 2 + BulkLength, 0, -BulkHeight), Rot
|
||||
)
|
||||
DepletionBox.Placement = App.Placement(App.Vector(BulkLength, 0, -BulkHeight), Rot)
|
||||
SurfDepletionBox.Placement = App.Placement(App.Vector(0, 0, 0), Rot)
|
||||
OxideBox.Placement = App.Placement(App.Vector(0, 0, DepletionSize), Rot)
|
||||
AdsorbtionBox.Placement = App.Placement(App.Vector(0, 0, DepletionSize + OxideThickness), Rot)
|
||||
|
||||
# Unite
|
||||
if beVerbose == 1:
|
||||
@@ -316,9 +296,7 @@ def createMesh():
|
||||
|
||||
# for index in range(len(BoxList)):
|
||||
for index in range(len(BoxList) - 1): # Manual hack
|
||||
BoxMeshList[index].addFacets(
|
||||
BoxList[index].Shape.tessellate(tessellationTollerance)
|
||||
)
|
||||
BoxMeshList[index].addFacets(BoxList[index].Shape.tessellate(tessellationTollerance))
|
||||
nmesh.addMesh(BoxMeshList[index])
|
||||
|
||||
nmesh.removeDuplicatedPoints()
|
||||
@@ -348,4 +326,5 @@ def createMesh():
|
||||
if beVerbose == 1:
|
||||
Console.PrintMessage("\nScript finished without errors.")
|
||||
|
||||
|
||||
## @}
|
||||
|
||||
@@ -49,10 +49,8 @@ from femmesh import meshtools
|
||||
# names are fix given from FreeCAD, these methods are called from FreeCAD
|
||||
# they are set in FEM modules Init.py
|
||||
|
||||
def export(
|
||||
objectslist,
|
||||
filename
|
||||
):
|
||||
|
||||
def export(objectslist, filename):
|
||||
"called when freecad exports a file"
|
||||
if len(objectslist) != 1:
|
||||
Console.PrintError("This exporter can only export one object.\n")
|
||||
@@ -72,10 +70,7 @@ def export(
|
||||
|
||||
|
||||
# ********* writer *******************************************************************************
|
||||
def write(
|
||||
fem_mesh,
|
||||
filename
|
||||
):
|
||||
def write(fem_mesh, filename):
|
||||
"""directly write a FemMesh to a pyNastran mesh file format
|
||||
fem_mesh: a FemMesh"""
|
||||
|
||||
@@ -91,17 +86,14 @@ def write(
|
||||
mesh_pynas_code += missing_code_pnynasmesh
|
||||
|
||||
# pynas file
|
||||
basefilename = filename[:len(filename) - 4] # TODO basename is more failsafe
|
||||
basefilename = filename[: len(filename) - 4] # TODO basename is more failsafe
|
||||
pynasf = open(basefilename + ".py", "w")
|
||||
pynasf.write("# written by FreeCAD\n\n\n")
|
||||
pynasf.write("from pyNastran.bdf.bdf import BDF\n")
|
||||
pynasf.write("model = BDF()\n\n\n")
|
||||
pynasf.write(mesh_pynas_code)
|
||||
|
||||
pynasf.write(
|
||||
"model.write_bdf('{}', enddata=True)\n"
|
||||
.format(basefilename + "_pyNas.bdf")
|
||||
)
|
||||
pynasf.write("model.write_bdf('{}', enddata=True)\n".format(basefilename + "_pyNas.bdf"))
|
||||
pynasf.close()
|
||||
|
||||
# execute pyNastran code to add grid to the model
|
||||
@@ -128,7 +120,7 @@ def get_pynastran_mesh(
|
||||
pynas_nodes = "# grid cards, geometric mesh points\n"
|
||||
for node in femnodes_mesh:
|
||||
vec = femnodes_mesh[node]
|
||||
pynas_nodes += "model.add_grid({}, [{}, {}, {}])\n".format(node, vec.x, vec.y, vec.z)
|
||||
pynas_nodes += f"model.add_grid({node}, [{vec.x}, {vec.y}, {vec.z}])\n"
|
||||
# print(pynas_nodes)
|
||||
|
||||
# elements
|
||||
@@ -142,14 +134,13 @@ def get_pynastran_mesh(
|
||||
if export_element_type == "cbar":
|
||||
pynas_elements += (
|
||||
"model.add_{ele_keyword}({eid}, {pid}, {nodes}, "
|
||||
"{orientation_vec}, {gnull})\n"
|
||||
.format(
|
||||
"{orientation_vec}, {gnull})\n".format(
|
||||
ele_keyword=export_element_type,
|
||||
eid=element,
|
||||
pid=1,
|
||||
nodes=nodes,
|
||||
orientation_vec="x=[0.0, 0.0, 1.0]",
|
||||
gnull="g0=None"
|
||||
gnull="g0=None",
|
||||
)
|
||||
)
|
||||
else:
|
||||
@@ -161,28 +152,31 @@ def get_pynastran_mesh(
|
||||
ele_keyword = "ctetra"
|
||||
# N1, N3, N2, N4, N7, N6, N5, N8, N10, N9
|
||||
the_nodes = [
|
||||
nodes[0], nodes[2], nodes[1], nodes[3],
|
||||
nodes[6], nodes[5], nodes[4],
|
||||
nodes[7], nodes[9], nodes[8],
|
||||
nodes[0],
|
||||
nodes[2],
|
||||
nodes[1],
|
||||
nodes[3],
|
||||
nodes[6],
|
||||
nodes[5],
|
||||
nodes[4],
|
||||
nodes[7],
|
||||
nodes[9],
|
||||
nodes[8],
|
||||
]
|
||||
else:
|
||||
ele_keyword = export_element_type
|
||||
the_nodes = nodes
|
||||
pynas_elements += (
|
||||
"model.add_{ele_keyword}({eid}, {pid}, {nodes})\n"
|
||||
.format(ele_keyword=ele_keyword, eid=element, pid=1, nodes=the_nodes)
|
||||
pynas_elements += "model.add_{ele_keyword}({eid}, {pid}, {nodes})\n".format(
|
||||
ele_keyword=ele_keyword, eid=element, pid=1, nodes=the_nodes
|
||||
)
|
||||
# print(pynas_elements)
|
||||
|
||||
mesh_pynas_code = "{}\n\n{}\n\n".format(pynas_nodes, pynas_elements)
|
||||
mesh_pynas_code = f"{pynas_nodes}\n\n{pynas_elements}\n\n"
|
||||
return mesh_pynas_code
|
||||
|
||||
|
||||
# Helper
|
||||
def get_export_element_type(
|
||||
femmesh,
|
||||
femelement_table=None
|
||||
):
|
||||
def get_export_element_type(femmesh, femelement_table=None):
|
||||
return nastran_ele_types[meshtools.get_femmesh_eletype(femmesh, femelement_table)]
|
||||
|
||||
|
||||
|
||||
@@ -43,19 +43,13 @@ EIGENVALUE_OUTPUT_SECTION = " E I G E N V A L U E O U T P U T"
|
||||
# ********* generic FreeCAD import and export methods *********
|
||||
|
||||
|
||||
|
||||
def open(
|
||||
filename
|
||||
):
|
||||
def open(filename):
|
||||
"called when freecad opens a file"
|
||||
docname = os.path.splitext(os.path.basename(filename))[0]
|
||||
insert(filename, docname)
|
||||
|
||||
|
||||
def insert(
|
||||
filename,
|
||||
docname
|
||||
):
|
||||
def insert(filename, docname):
|
||||
"called when freecad wants to import a file"
|
||||
try:
|
||||
doc = FreeCAD.getDocument(docname)
|
||||
@@ -66,19 +60,14 @@ def insert(
|
||||
|
||||
|
||||
# ********* module specific methods *********
|
||||
def import_dat(
|
||||
filename,
|
||||
Analysis=None
|
||||
):
|
||||
def import_dat(filename, Analysis=None):
|
||||
r = readResult(filename)
|
||||
return r
|
||||
|
||||
|
||||
# read a calculix result file and extract the data
|
||||
def readResult(
|
||||
dat_input
|
||||
):
|
||||
Console.PrintMessage("Read ccx results from dat file: {}\n".format(dat_input))
|
||||
def readResult(dat_input):
|
||||
Console.PrintMessage(f"Read ccx results from dat file: {dat_input}\n")
|
||||
dat_file = pyopen(dat_input, "r")
|
||||
eigenvalue_output_section_found = False
|
||||
mode_reading = False
|
||||
|
||||
@@ -41,17 +41,13 @@ from builtins import open as pyopen
|
||||
# ********* generic FreeCAD import and export methods *********
|
||||
|
||||
|
||||
|
||||
def open(filename):
|
||||
"called when freecad opens a file"
|
||||
docname = os.path.splitext(os.path.basename(filename))[0]
|
||||
insert(filename, docname)
|
||||
|
||||
|
||||
def insert(
|
||||
filename,
|
||||
docname
|
||||
):
|
||||
def insert(filename, docname):
|
||||
"called when freecad wants to import a file"
|
||||
try:
|
||||
doc = FreeCAD.getDocument(docname)
|
||||
@@ -62,12 +58,7 @@ def insert(
|
||||
|
||||
|
||||
# ********* module specific methods *********
|
||||
def importFrd(
|
||||
filename,
|
||||
analysis=None,
|
||||
result_name_prefix="",
|
||||
result_analysis_type=""
|
||||
):
|
||||
def importFrd(filename, analysis=None, result_name_prefix="", result_analysis_type=""):
|
||||
import ObjectsFem
|
||||
from . import importToolsFem
|
||||
|
||||
@@ -86,9 +77,7 @@ def importFrd(
|
||||
nodenumbers_for_compacted_mesh = []
|
||||
|
||||
number_of_increments = len(m["Results"])
|
||||
Console.PrintLog(
|
||||
"Increments: " + str(number_of_increments) + "\n"
|
||||
)
|
||||
Console.PrintLog("Increments: " + str(number_of_increments) + "\n")
|
||||
|
||||
def make_result_mesh(result_name):
|
||||
res_obj = ObjectsFem.makeResultMechanical(doc, results_name)
|
||||
@@ -107,26 +96,18 @@ def importFrd(
|
||||
step_time = result_set["time"]
|
||||
step_time = round(step_time, 2)
|
||||
if eigenmode_number > 0:
|
||||
results_name = (
|
||||
"{}EigenMode_{}_Results"
|
||||
.format(result_name_prefix, eigenmode_number)
|
||||
results_name = "{}EigenMode_{}_Results".format(
|
||||
result_name_prefix, eigenmode_number
|
||||
)
|
||||
elif number_of_increments > 1:
|
||||
if result_analysis_type == "buckling":
|
||||
results_name = (
|
||||
"{}BucklingFactor_{}_Results"
|
||||
.format(result_name_prefix, step_time)
|
||||
results_name = "{}BucklingFactor_{}_Results".format(
|
||||
result_name_prefix, step_time
|
||||
)
|
||||
else:
|
||||
results_name = (
|
||||
"{}Time_{}_Results"
|
||||
.format(result_name_prefix, step_time)
|
||||
)
|
||||
results_name = f"{result_name_prefix}Time_{step_time}_Results"
|
||||
else:
|
||||
results_name = (
|
||||
"{}Results"
|
||||
.format(result_name_prefix)
|
||||
)
|
||||
results_name = f"{result_name_prefix}Results"
|
||||
|
||||
res_obj = make_result_mesh(results_name)
|
||||
res_obj = importToolsFem.fill_femresult_mechanical(res_obj, result_set)
|
||||
@@ -138,6 +119,7 @@ def importFrd(
|
||||
# more result object calculations
|
||||
from femresult import resulttools
|
||||
from femtools import femutils
|
||||
|
||||
if not res_obj.MassFlowRate:
|
||||
# information 1:
|
||||
# only compact result if not Flow 1D results
|
||||
@@ -220,7 +202,7 @@ def importFrd(
|
||||
pipeline_obj.ViewObject.Visibility = pipeline_visibility
|
||||
|
||||
elif result_analysis_type == "check":
|
||||
results_name = "{}Check".format(result_name_prefix)
|
||||
results_name = f"{result_name_prefix}Check"
|
||||
res_obj = make_result_mesh(results_name)
|
||||
if analysis:
|
||||
analysis.addObject(res_obj)
|
||||
@@ -241,7 +223,7 @@ def importFrd(
|
||||
# see error message above for more information
|
||||
if not res_obj:
|
||||
if result_name_prefix:
|
||||
results_name = "{}_Results".format(result_name_prefix)
|
||||
results_name = f"{result_name_prefix}_Results"
|
||||
else:
|
||||
results_name = "Results"
|
||||
res_obj = ObjectsFem.makeResultMechanical(doc, results_name)
|
||||
@@ -253,13 +235,12 @@ def importFrd(
|
||||
if FreeCAD.GuiUp:
|
||||
if analysis:
|
||||
import FemGui
|
||||
|
||||
FemGui.setActiveAnalysis(analysis)
|
||||
doc.recompute()
|
||||
|
||||
else:
|
||||
Console.PrintError(
|
||||
"Problem on frd file import. No nodes found in frd file.\n"
|
||||
)
|
||||
Console.PrintError("Problem on frd file import. No nodes found in frd file.\n")
|
||||
# None will be returned
|
||||
# or would it be better to raise an exception if there are not even nodes in frd file?
|
||||
|
||||
@@ -268,26 +249,19 @@ def importFrd(
|
||||
|
||||
# read a calculix result file and extract the nodes
|
||||
# displacement vectors and stress values.
|
||||
def read_frd_result(
|
||||
frd_input
|
||||
):
|
||||
Console.PrintMessage(
|
||||
"Read ccx results from frd file: {}\n"
|
||||
.format(frd_input)
|
||||
)
|
||||
def read_frd_result(frd_input):
|
||||
Console.PrintMessage(f"Read ccx results from frd file: {frd_input}\n")
|
||||
inout_nodes = []
|
||||
inout_nodes_file = frd_input.rsplit(".", 1)[0] + "_inout_nodes.txt"
|
||||
if os.path.exists(inout_nodes_file):
|
||||
Console.PrintMessage(
|
||||
"Read special 1DFlow nodes data form: {}\n".format(inout_nodes_file)
|
||||
)
|
||||
Console.PrintMessage(f"Read special 1DFlow nodes data form: {inout_nodes_file}\n")
|
||||
f = pyopen(inout_nodes_file, "r")
|
||||
lines = f.readlines()
|
||||
for line in lines:
|
||||
a = line.split(",")
|
||||
inout_nodes.append(a)
|
||||
f.close()
|
||||
Console.PrintMessage("{}\n".format(inout_nodes))
|
||||
Console.PrintMessage(f"{inout_nodes}\n")
|
||||
frd_file = pyopen(frd_input, "r")
|
||||
nodes = {}
|
||||
elements_hexa8 = {}
|
||||
@@ -443,8 +417,26 @@ def read_frd_result(
|
||||
hexa20 import works with the following frd file node assignment
|
||||
"""
|
||||
elements_hexa20[elem] = (
|
||||
nd8, nd5, nd6, nd7, nd4, nd1, nd2, nd3, nd20, nd17,
|
||||
nd18, nd19, nd12, nd9, nd10, nd11, nd16, nd13, nd14, nd15
|
||||
nd8,
|
||||
nd5,
|
||||
nd6,
|
||||
nd7,
|
||||
nd4,
|
||||
nd1,
|
||||
nd2,
|
||||
nd3,
|
||||
nd20,
|
||||
nd17,
|
||||
nd18,
|
||||
nd19,
|
||||
nd12,
|
||||
nd9,
|
||||
nd10,
|
||||
nd11,
|
||||
nd16,
|
||||
nd13,
|
||||
nd14,
|
||||
nd15,
|
||||
)
|
||||
elif elemType == 5 and input_continues is False:
|
||||
# first line
|
||||
@@ -479,8 +471,21 @@ def read_frd_result(
|
||||
) # order of the *.inp file
|
||||
"""
|
||||
elements_penta15[elem] = (
|
||||
nd5, nd6, nd4, nd2, nd3, nd1, nd14, nd15, nd13, nd8,
|
||||
nd9, nd7, nd11, nd12, nd10
|
||||
nd5,
|
||||
nd6,
|
||||
nd4,
|
||||
nd2,
|
||||
nd3,
|
||||
nd1,
|
||||
nd14,
|
||||
nd15,
|
||||
nd13,
|
||||
nd8,
|
||||
nd9,
|
||||
nd7,
|
||||
nd11,
|
||||
nd12,
|
||||
nd10,
|
||||
)
|
||||
elif elemType == 6:
|
||||
# C3D10 Calculix --> tetra10 FreeCAD
|
||||
@@ -632,7 +637,7 @@ def read_frd_result(
|
||||
# we found an equivalent plastic strain line
|
||||
elem = int(line[4:13])
|
||||
peeq = float(line[13:25])
|
||||
mode_peeq[elem] = (peeq)
|
||||
mode_peeq[elem] = peeq
|
||||
|
||||
# Check if we found a temperature section
|
||||
if line[5:11] == "NDTEMP":
|
||||
@@ -641,7 +646,7 @@ def read_frd_result(
|
||||
# we found a temperature line
|
||||
elem = int(line[4:13])
|
||||
temperature = float(line[13:25])
|
||||
mode_temp[elem] = (temperature)
|
||||
mode_temp[elem] = temperature
|
||||
|
||||
# Check if we found heat flux section
|
||||
if line[5:9] == "FLUX":
|
||||
@@ -654,8 +659,6 @@ def read_frd_result(
|
||||
mode_heatflux_z = float(line[37:49])
|
||||
mode_heatflux[elem] = FreeCAD.Vector(mode_heatflux_x, mode_heatflux_y, mode_heatflux_z)
|
||||
|
||||
|
||||
|
||||
# Check if we found a mass flow section
|
||||
if line[5:11] == "MAFLOW":
|
||||
mode_massflow_found = True
|
||||
@@ -663,13 +666,13 @@ def read_frd_result(
|
||||
# we found a mass flow line
|
||||
elem = int(line[4:13])
|
||||
massflow = float(line[13:25])
|
||||
mode_massflow[elem] = (massflow * 1000) # convert units to kg/s from t/s
|
||||
mode_massflow[elem] = massflow * 1000 # convert units to kg/s from t/s
|
||||
if inout_nodes:
|
||||
for i in range(len(inout_nodes)):
|
||||
if elem == int(inout_nodes[i][1]):
|
||||
node = int(inout_nodes[i][2])
|
||||
# convert units to kg/s from t/s
|
||||
mode_massflow[node] = (massflow * 1000)
|
||||
mode_massflow[node] = massflow * 1000
|
||||
|
||||
# Check if we found a network pressure section
|
||||
if line[5:11] == "STPRES":
|
||||
@@ -678,12 +681,12 @@ def read_frd_result(
|
||||
# we found a network pressure line
|
||||
elem = int(line[4:13])
|
||||
networkpressure = float(line[13:25])
|
||||
mode_networkpressure[elem] = (networkpressure)
|
||||
mode_networkpressure[elem] = networkpressure
|
||||
if inout_nodes:
|
||||
for i in range(len(inout_nodes)):
|
||||
if elem == int(inout_nodes[i][1]):
|
||||
node = int(inout_nodes[i][2])
|
||||
mode_networkpressure[node] = (networkpressure)
|
||||
mode_networkpressure[node] = networkpressure
|
||||
|
||||
# Check if we found the end of a section
|
||||
if line[1:3] == "-3":
|
||||
@@ -760,9 +763,11 @@ def read_frd_result(
|
||||
if line[1:5] == "9999":
|
||||
end_of_frd_data_found = True
|
||||
|
||||
if (mode_eigen_changed or mode_time_changed or end_of_frd_data_found) \
|
||||
and end_of_section_found \
|
||||
and not node_element_section:
|
||||
if (
|
||||
(mode_eigen_changed or mode_time_changed or end_of_frd_data_found)
|
||||
and end_of_section_found
|
||||
and not node_element_section
|
||||
):
|
||||
|
||||
"""
|
||||
print("\n\n----Append mode_results to results")
|
||||
@@ -813,9 +818,7 @@ def read_frd_result(
|
||||
if not inout_nodes:
|
||||
if results:
|
||||
if "mflow" in results[0] or "npressure" in results[0]:
|
||||
Console.PrintError(
|
||||
"We have mflow or npressure, but no inout_nodes file.\n"
|
||||
)
|
||||
Console.PrintError("We have mflow or npressure, but no inout_nodes file.\n")
|
||||
if not nodes:
|
||||
Console.PrintError("FEM: No nodes found in Frd file.\n")
|
||||
|
||||
@@ -833,5 +836,5 @@ def read_frd_result(
|
||||
"Hexa20Elem": elements_hexa20,
|
||||
"Penta6Elem": elements_penta6,
|
||||
"Penta15Elem": elements_penta15,
|
||||
"Results": results
|
||||
"Results": results,
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ if FreeCAD.GuiUp:
|
||||
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
|
||||
class WriteXDMFTaskPanel:
|
||||
"""
|
||||
This task panel is used to write mesh groups with user defined values.
|
||||
@@ -57,10 +58,9 @@ if FreeCAD.GuiUp:
|
||||
"""
|
||||
|
||||
def __init__(self, fem_mesh_obj, fileString):
|
||||
self.form = FreeCADGui.PySideUic.loadUi(os.path.join(
|
||||
FreeCAD.getHomePath(),
|
||||
"Mod/Fem/Resources/ui/MeshGroupXDMFExport.ui"
|
||||
))
|
||||
self.form = FreeCADGui.PySideUic.loadUi(
|
||||
os.path.join(FreeCAD.getHomePath(), "Mod/Fem/Resources/ui/MeshGroupXDMFExport.ui")
|
||||
)
|
||||
self.result_dict = {}
|
||||
self.fem_mesh_obj = fem_mesh_obj
|
||||
self.fileString = fileString
|
||||
@@ -73,34 +73,27 @@ if FreeCAD.GuiUp:
|
||||
item.setFlags(~QtCore.Qt.ItemIsEditable & ~QtCore.Qt.ItemIsEnabled)
|
||||
return item
|
||||
|
||||
gmshgroups = importToolsFem.get_FemMeshObjectMeshGroups(
|
||||
self.fem_mesh_obj
|
||||
)
|
||||
gmshgroups = importToolsFem.get_FemMeshObjectMeshGroups(self.fem_mesh_obj)
|
||||
fem_mesh = self.fem_mesh_obj.FemMesh
|
||||
|
||||
self.form.tableGroups.setRowCount(0)
|
||||
self.form.tableGroups.setRowCount(len(gmshgroups))
|
||||
|
||||
for (ind, gind) in enumerate(gmshgroups):
|
||||
for ind, gind in enumerate(gmshgroups):
|
||||
# group number
|
||||
self.form.tableGroups.setItem(ind, 0,
|
||||
ro(QtGui.QTableWidgetItem(
|
||||
str(gind))))
|
||||
self.form.tableGroups.setItem(ind, 0, ro(QtGui.QTableWidgetItem(str(gind))))
|
||||
# group name
|
||||
self.form.tableGroups.setItem(ind, 1,
|
||||
ro(QtGui.QTableWidgetItem(
|
||||
fem_mesh.getGroupName(gind))))
|
||||
self.form.tableGroups.setItem(
|
||||
ind, 1, ro(QtGui.QTableWidgetItem(fem_mesh.getGroupName(gind)))
|
||||
)
|
||||
# group elements
|
||||
self.form.tableGroups.setItem(ind, 2,
|
||||
ro(QtGui.QTableWidgetItem(
|
||||
fem_mesh.getGroupElementType(
|
||||
gind))))
|
||||
self.form.tableGroups.setItem(
|
||||
ind, 2, ro(QtGui.QTableWidgetItem(fem_mesh.getGroupElementType(gind)))
|
||||
)
|
||||
# default value for not marked elements
|
||||
self.form.tableGroups.setItem(ind, 3,
|
||||
QtGui.QTableWidgetItem(str(0)))
|
||||
self.form.tableGroups.setItem(ind, 3, QtGui.QTableWidgetItem(str(0)))
|
||||
# default value for marked elements
|
||||
self.form.tableGroups.setItem(ind, 4,
|
||||
QtGui.QTableWidgetItem(str(1)))
|
||||
self.form.tableGroups.setItem(ind, 4, QtGui.QTableWidgetItem(str(1)))
|
||||
|
||||
header = self.form.tableGroups.horizontalHeader()
|
||||
header.setResizeMode(0, QtGui.QHeaderView.ResizeToContents)
|
||||
@@ -136,8 +129,8 @@ if FreeCAD.GuiUp:
|
||||
group_values_dict = self.convert_table_to_group_dict()
|
||||
|
||||
writeFenicsXDMF.write_fenics_mesh_xdmf(
|
||||
self.fem_mesh_obj, self.fileString,
|
||||
group_values_dict=group_values_dict)
|
||||
self.fem_mesh_obj, self.fileString, group_values_dict=group_values_dict
|
||||
)
|
||||
|
||||
FreeCADGui.Control.closeDialog()
|
||||
|
||||
@@ -165,8 +158,7 @@ def export(objectslist, fileString, group_values_dict_nogui=None):
|
||||
of (marked_value (default=1), default_value (default=0))
|
||||
"""
|
||||
if len(objectslist) != 1:
|
||||
Console.PrintError(
|
||||
"This exporter can only export one object.\n")
|
||||
Console.PrintError("This exporter can only export one object.\n")
|
||||
return
|
||||
obj = objectslist[0]
|
||||
if not obj.isDerivedFrom("Fem::FemMeshObject"):
|
||||
@@ -178,9 +170,10 @@ def export(objectslist, fileString, group_values_dict_nogui=None):
|
||||
if fileExtension.lower() == ".xml":
|
||||
if obj.ElementOrder != "1st":
|
||||
Console.PrintWarning(
|
||||
"XML is not designed to save higher order elements.\n" +
|
||||
"Reducing order for second order mesh.\n" +
|
||||
"Tri6 -> Tri3, Tet10 -> Tet4, etc.\n")
|
||||
"XML is not designed to save higher order elements.\n"
|
||||
+ "Reducing order for second order mesh.\n"
|
||||
+ "Tri6 -> Tri3, Tet10 -> Tet4, etc.\n"
|
||||
)
|
||||
writeFenicsXML.write_fenics_mesh_xml(obj, fileString)
|
||||
elif fileExtension.lower() == ".xdmf":
|
||||
mesh_groups = importToolsFem.get_FemMeshObjectMeshGroups(obj)
|
||||
@@ -192,19 +185,17 @@ def export(objectslist, fileString, group_values_dict_nogui=None):
|
||||
else:
|
||||
# create default dict if groupdict_nogui is not None
|
||||
if group_values_dict_nogui is None:
|
||||
group_values_dict_nogui = dict([(g, (1, 0))
|
||||
for g in mesh_groups])
|
||||
group_values_dict_nogui = {g: (1, 0) for g in mesh_groups}
|
||||
writeFenicsXDMF.write_fenics_mesh_xdmf(
|
||||
obj, fileString,
|
||||
group_values_dict=group_values_dict_nogui)
|
||||
obj, fileString, group_values_dict=group_values_dict_nogui
|
||||
)
|
||||
else:
|
||||
writeFenicsXDMF.write_fenics_mesh_xdmf(obj, fileString)
|
||||
|
||||
|
||||
# ********* module specific methods *********
|
||||
def import_fenics_mesh(filename, analysis=None):
|
||||
"""insert a FreeCAD FEM Mesh object in the ActiveDocument
|
||||
"""
|
||||
"""insert a FreeCAD FEM Mesh object in the ActiveDocument"""
|
||||
mesh_data = readFenicsXML.read_fenics_mesh_xml(filename)
|
||||
# xdmf not operational
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@ from builtins import open as pyopen
|
||||
# ********* generic FreeCAD import and export methods *********
|
||||
|
||||
|
||||
|
||||
def open(filename):
|
||||
"called when freecad opens a file"
|
||||
docname = os.path.splitext(os.path.basename(filename))[0]
|
||||
@@ -60,17 +59,16 @@ def insert(filename, docname):
|
||||
|
||||
# ********* module specific methods *********
|
||||
def read(filename):
|
||||
"""read a FemMesh from a inp mesh file and return the FemMesh
|
||||
"""
|
||||
"""read a FemMesh from a inp mesh file and return the FemMesh"""
|
||||
# no document object is created, just the FemMesh is returned
|
||||
mesh_data = read_inp(filename)
|
||||
from . import importToolsFem
|
||||
|
||||
return importToolsFem.make_femmesh(mesh_data)
|
||||
|
||||
|
||||
def import_inp(filename):
|
||||
"""read a FEM mesh from a Z88 mesh file and insert a FreeCAD FEM Mesh object in the ActiveDocument
|
||||
"""
|
||||
"""read a FEM mesh from a Z88 mesh file and insert a FreeCAD FEM Mesh object in the ActiveDocument"""
|
||||
femmesh = read(filename)
|
||||
mesh_name = os.path.splitext(os.path.basename(filename))[0]
|
||||
if femmesh:
|
||||
@@ -79,10 +77,10 @@ def import_inp(filename):
|
||||
|
||||
|
||||
def read_inp(file_name):
|
||||
"""read .inp file """
|
||||
"""read .inp file"""
|
||||
# ATM only mesh reading is supported (no boundary conditions)
|
||||
|
||||
class elements():
|
||||
class elements:
|
||||
|
||||
tria3 = {}
|
||||
tria6 = {}
|
||||
@@ -96,6 +94,7 @@ def read_inp(file_name):
|
||||
penta15 = {}
|
||||
seg2 = {}
|
||||
seg3 = {}
|
||||
|
||||
error_seg3 = False # to print "not supported"
|
||||
nodes = {}
|
||||
model_definition = True
|
||||
@@ -161,12 +160,10 @@ def read_inp(file_name):
|
||||
elif elm_type in ["S6", "CPS6", "CPE6", "CAX6"]:
|
||||
elm_category = elements.tria6
|
||||
number_of_nodes = 6
|
||||
elif elm_type in ["S4", "S4R", "CPS4", "CPS4R", "CPE4", "CPE4R",
|
||||
"CAX4", "CAX4R"]:
|
||||
elif elm_type in ["S4", "S4R", "CPS4", "CPS4R", "CPE4", "CPE4R", "CAX4", "CAX4R"]:
|
||||
elm_category = elements.quad4
|
||||
number_of_nodes = 4
|
||||
elif elm_type in ["S8", "S8R", "CPS8", "CPS8R", "CPE8", "CPE8R",
|
||||
"CAX8", "CAX8R"]:
|
||||
elif elm_type in ["S8", "S8R", "CPS8", "CPS8R", "CPE8", "CPE8R", "CAX8", "CAX8R"]:
|
||||
elm_category = elements.quad8
|
||||
number_of_nodes = 8
|
||||
elif elm_type == "C3D4":
|
||||
@@ -219,7 +216,7 @@ def read_inp(file_name):
|
||||
if error_seg3 is True: # to print "not supported"
|
||||
Console.PrintError("Error: seg3 (3-node beam element type) not supported, yet.\n")
|
||||
elif error_not_supported_elemtype is True:
|
||||
Console.PrintError("Error: {} not supported.\n".format(elm_type))
|
||||
Console.PrintError(f"Error: {elm_type} not supported.\n")
|
||||
f.close()
|
||||
|
||||
# switch from the CalculiX node numbering to the FreeCAD node numbering
|
||||
@@ -229,24 +226,56 @@ def read_inp(file_name):
|
||||
elements.tetra4[en] = [n[1], n[0], n[2], n[3]]
|
||||
for en in elements.tetra10:
|
||||
n = elements.tetra10[en]
|
||||
elements.tetra10[en] = [n[1], n[0], n[2], n[3], n[4], n[6], n[5],
|
||||
n[8], n[7], n[9]]
|
||||
elements.tetra10[en] = [n[1], n[0], n[2], n[3], n[4], n[6], n[5], n[8], n[7], n[9]]
|
||||
for en in elements.hexa8:
|
||||
n = elements.hexa8[en]
|
||||
elements.hexa8[en] = [n[5], n[6], n[7], n[4], n[1], n[2], n[3], n[0]]
|
||||
for en in elements.hexa20:
|
||||
n = elements.hexa20[en]
|
||||
elements.hexa20[en] = [n[5], n[6], n[7], n[4], n[1], n[2], n[3], n[0],
|
||||
n[13], n[14], n[15], n[12], n[9], n[10], n[11],
|
||||
n[8], n[17], n[18], n[19], n[16]]
|
||||
elements.hexa20[en] = [
|
||||
n[5],
|
||||
n[6],
|
||||
n[7],
|
||||
n[4],
|
||||
n[1],
|
||||
n[2],
|
||||
n[3],
|
||||
n[0],
|
||||
n[13],
|
||||
n[14],
|
||||
n[15],
|
||||
n[12],
|
||||
n[9],
|
||||
n[10],
|
||||
n[11],
|
||||
n[8],
|
||||
n[17],
|
||||
n[18],
|
||||
n[19],
|
||||
n[16],
|
||||
]
|
||||
for en in elements.penta6:
|
||||
n = elements.penta6[en]
|
||||
elements.penta6[en] = [n[4], n[5], n[3], n[1], n[2], n[0]]
|
||||
for en in elements.penta15:
|
||||
n = elements.penta15[en]
|
||||
elements.penta15[en] = [n[4], n[5], n[3], n[1], n[2], n[0],
|
||||
n[10], n[11], n[9], n[7], n[8], n[6], n[13],
|
||||
n[14], n[12]]
|
||||
elements.penta15[en] = [
|
||||
n[4],
|
||||
n[5],
|
||||
n[3],
|
||||
n[1],
|
||||
n[2],
|
||||
n[0],
|
||||
n[10],
|
||||
n[11],
|
||||
n[9],
|
||||
n[7],
|
||||
n[8],
|
||||
n[6],
|
||||
n[13],
|
||||
n[14],
|
||||
n[12],
|
||||
]
|
||||
for en in elements.seg3:
|
||||
n = elements.seg3[en]
|
||||
elements.seg3[en] = [n[0], n[2], n[1]]
|
||||
@@ -264,5 +293,5 @@ def read_inp(file_name):
|
||||
"Hexa8Elem": elements.hexa8,
|
||||
"Hexa20Elem": elements.hexa20,
|
||||
"Penta6Elem": elements.penta6,
|
||||
"Penta15Elem": elements.penta15
|
||||
"Penta15Elem": elements.penta15,
|
||||
}
|
||||
|
||||
@@ -40,13 +40,8 @@ from builtins import open as pyopen
|
||||
# they are set in FEM modules Init.py
|
||||
|
||||
|
||||
|
||||
|
||||
# export mesh to python
|
||||
def export(
|
||||
objectslist,
|
||||
filename
|
||||
):
|
||||
def export(objectslist, filename):
|
||||
"called when freecad exports a file"
|
||||
if len(objectslist) != 1:
|
||||
FreeCAD.Console.PrintError("This exporter can only export one object.\n")
|
||||
@@ -79,10 +74,8 @@ def export(
|
||||
|
||||
# ********* writer *******************************************************************************
|
||||
|
||||
def write(
|
||||
fem_mesh,
|
||||
filename
|
||||
):
|
||||
|
||||
def write(fem_mesh, filename):
|
||||
"""directly write a FemMesh to a Python mesh file
|
||||
fem_mesh: a FemMesh"""
|
||||
|
||||
@@ -115,10 +108,7 @@ def write_python_mesh_to_file(femnodes_mesh, femelement_table, fem_mesh_type, f)
|
||||
for node in femnodes_mesh:
|
||||
# print(node, ' --> ', femnodes_mesh[node])
|
||||
vec = femnodes_mesh[node]
|
||||
f.write(
|
||||
" {0}.addNode({1}, {2}, {3}, {4})\n"
|
||||
.format(mesh_name, vec.x, vec.y, vec.z, node)
|
||||
)
|
||||
f.write(f" {mesh_name}.addNode({vec.x}, {vec.y}, {vec.z}, {node})\n")
|
||||
f.write(" return True\n")
|
||||
f.write("\n\n")
|
||||
|
||||
@@ -129,17 +119,20 @@ def write_python_mesh_to_file(femnodes_mesh, femelement_table, fem_mesh_type, f)
|
||||
# print(element, ' --> ', femelement_table[element])
|
||||
if fem_mesh_type == "Solid":
|
||||
f.write(
|
||||
" {0}.addVolume({1}, {2})\n"
|
||||
.format(mesh_name, list(femelement_table[element]), element)
|
||||
" {}.addVolume({}, {})\n".format(
|
||||
mesh_name, list(femelement_table[element]), element
|
||||
)
|
||||
)
|
||||
elif fem_mesh_type == "Face":
|
||||
f.write(
|
||||
" {0}.addFace({1}, {2})\n"
|
||||
.format(mesh_name, list(femelement_table[element]), element)
|
||||
" {}.addFace({}, {})\n".format(
|
||||
mesh_name, list(femelement_table[element]), element
|
||||
)
|
||||
)
|
||||
elif fem_mesh_type == "Edge":
|
||||
f.write(
|
||||
" {0}.addEdge({1}, {2})\n"
|
||||
.format(mesh_name, list(femelement_table[element]), element)
|
||||
" {}.addEdge({}, {})\n".format(
|
||||
mesh_name, list(femelement_table[element]), element
|
||||
)
|
||||
)
|
||||
f.write(" return True\n")
|
||||
|
||||
@@ -33,11 +33,9 @@ import FreeCAD
|
||||
from FreeCAD import Console
|
||||
|
||||
|
||||
def get_FemMeshObjectMeshGroups(
|
||||
fem_mesh_obj
|
||||
):
|
||||
def get_FemMeshObjectMeshGroups(fem_mesh_obj):
|
||||
"""
|
||||
Get mesh groups from mesh.
|
||||
Get mesh groups from mesh.
|
||||
"""
|
||||
# this method is not really needed. It is used in Fenics mesh only.
|
||||
# there was an exception handling if there was no Group property, but
|
||||
@@ -47,16 +45,14 @@ def get_FemMeshObjectMeshGroups(
|
||||
return fem_mesh_obj.FemMesh.Groups
|
||||
|
||||
|
||||
def get_FemMeshObjectOrder(
|
||||
fem_mesh_obj
|
||||
):
|
||||
def get_FemMeshObjectOrder(fem_mesh_obj):
|
||||
"""
|
||||
Gets element order. Element order counting based on number of nodes on
|
||||
edges. Edge with 2 nodes -> linear elements, Edge with 3 nodes ->
|
||||
quadratic elements, and so on. No edges in mesh -> not determined.
|
||||
(Is this possible? Seems to be a very degenerate case.)
|
||||
If there are edges with different number of nodes appearing, return
|
||||
list of orders.
|
||||
Gets element order. Element order counting based on number of nodes on
|
||||
edges. Edge with 2 nodes -> linear elements, Edge with 3 nodes ->
|
||||
quadratic elements, and so on. No edges in mesh -> not determined.
|
||||
(Is this possible? Seems to be a very degenerate case.)
|
||||
If there are edges with different number of nodes appearing, return
|
||||
list of orders.
|
||||
"""
|
||||
presumable_order = None
|
||||
|
||||
@@ -78,11 +74,9 @@ def get_FemMeshObjectOrder(
|
||||
return presumable_order
|
||||
|
||||
|
||||
def get_FemMeshObjectDimension(
|
||||
fem_mesh_obj
|
||||
):
|
||||
""" Count all entities in an abstract sense, to distinguish which dimension the mesh is
|
||||
(i.e. linemesh, facemesh, volumemesh)
|
||||
def get_FemMeshObjectDimension(fem_mesh_obj):
|
||||
"""Count all entities in an abstract sense, to distinguish which dimension the mesh is
|
||||
(i.e. linemesh, facemesh, volumemesh)
|
||||
"""
|
||||
dim = None
|
||||
|
||||
@@ -98,21 +92,28 @@ def get_FemMeshObjectDimension(
|
||||
return dim
|
||||
|
||||
|
||||
def get_FemMeshObjectElementTypes(
|
||||
fem_mesh_obj,
|
||||
remove_zero_element_entries=True
|
||||
):
|
||||
def get_FemMeshObjectElementTypes(fem_mesh_obj, remove_zero_element_entries=True):
|
||||
"""
|
||||
Spit out all elements in the mesh with their appropriate dimension.
|
||||
Spit out all elements in the mesh with their appropriate dimension.
|
||||
"""
|
||||
FreeCAD_element_names_dims = {
|
||||
"Node": 0, "Edge": 1, "Hexa": 3, "Polygon": 2, "Polyhedron": 3,
|
||||
"Prism": 3, "Pyramid": 3, "Quadrangle": 2, "Tetra": 3, "Triangle": 2}
|
||||
"Node": 0,
|
||||
"Edge": 1,
|
||||
"Hexa": 3,
|
||||
"Polygon": 2,
|
||||
"Polyhedron": 3,
|
||||
"Prism": 3,
|
||||
"Pyramid": 3,
|
||||
"Quadrangle": 2,
|
||||
"Tetra": 3,
|
||||
"Triangle": 2,
|
||||
}
|
||||
|
||||
eval_dict = locals() # to access local variables from eval
|
||||
elements_list_with_zero = [(
|
||||
eval("fem_mesh_obj.FemMesh." + s + "Count", eval_dict), s, d
|
||||
) for (s, d) in FreeCAD_element_names_dims.items()]
|
||||
elements_list_with_zero = [
|
||||
(eval("fem_mesh_obj.FemMesh." + s + "Count", eval_dict), s, d)
|
||||
for (s, d) in FreeCAD_element_names_dims.items()
|
||||
]
|
||||
# ugly but necessary
|
||||
if remove_zero_element_entries:
|
||||
elements_list = [(num, s, d) for (num, s, d) in elements_list_with_zero if num > 0]
|
||||
@@ -122,22 +123,18 @@ def get_FemMeshObjectElementTypes(
|
||||
return elements_list
|
||||
|
||||
|
||||
def get_MaxDimElementFromList(
|
||||
elem_list
|
||||
):
|
||||
def get_MaxDimElementFromList(elem_list):
|
||||
"""
|
||||
Gets element with the maximal dimension in the mesh to determine cells.
|
||||
Gets element with the maximal dimension in the mesh to determine cells.
|
||||
"""
|
||||
elem_list.sort(key=lambda t: t[2])
|
||||
return elem_list[-1]
|
||||
|
||||
|
||||
def make_femmesh(
|
||||
mesh_data
|
||||
):
|
||||
""" makes an FreeCAD FEM Mesh object from FEM Mesh data
|
||||
"""
|
||||
def make_femmesh(mesh_data):
|
||||
"""makes an FreeCAD FEM Mesh object from FEM Mesh data"""
|
||||
import Fem
|
||||
|
||||
mesh = Fem.FemMesh()
|
||||
m = mesh_data
|
||||
if ("Nodes" in m) and (len(m["Nodes"]) > 0):
|
||||
@@ -181,15 +178,54 @@ def make_femmesh(
|
||||
elms_penta15 = m["Penta15Elem"]
|
||||
for i in elms_penta15:
|
||||
e = elms_penta15[i]
|
||||
mesh.addVolume([e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8], e[9],
|
||||
e[10], e[11], e[12], e[13], e[14]], i)
|
||||
mesh.addVolume(
|
||||
[
|
||||
e[0],
|
||||
e[1],
|
||||
e[2],
|
||||
e[3],
|
||||
e[4],
|
||||
e[5],
|
||||
e[6],
|
||||
e[7],
|
||||
e[8],
|
||||
e[9],
|
||||
e[10],
|
||||
e[11],
|
||||
e[12],
|
||||
e[13],
|
||||
e[14],
|
||||
],
|
||||
i,
|
||||
)
|
||||
elms_hexa20 = m["Hexa20Elem"]
|
||||
for i in elms_hexa20:
|
||||
e = elms_hexa20[i]
|
||||
mesh.addVolume([
|
||||
e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8], e[9],
|
||||
e[10], e[11], e[12], e[13], e[14], e[15], e[16], e[17], e[18], e[19]
|
||||
], i)
|
||||
mesh.addVolume(
|
||||
[
|
||||
e[0],
|
||||
e[1],
|
||||
e[2],
|
||||
e[3],
|
||||
e[4],
|
||||
e[5],
|
||||
e[6],
|
||||
e[7],
|
||||
e[8],
|
||||
e[9],
|
||||
e[10],
|
||||
e[11],
|
||||
e[12],
|
||||
e[13],
|
||||
e[14],
|
||||
e[15],
|
||||
e[16],
|
||||
e[17],
|
||||
e[18],
|
||||
e[19],
|
||||
],
|
||||
i,
|
||||
)
|
||||
elms_tria3 = m["Tria3Elem"]
|
||||
for i in elms_tria3:
|
||||
e = elms_tria3[i]
|
||||
@@ -215,27 +251,25 @@ def make_femmesh(
|
||||
e = elms_seg3[i]
|
||||
mesh.addEdge([e[0], e[1], e[2]], i)
|
||||
Console.PrintLog(
|
||||
"imported mesh: {} nodes, {} HEXA8, {} PENTA6, {} TETRA4, {} TETRA10, {} PENTA15\n"
|
||||
.format(
|
||||
"imported mesh: {} nodes, {} HEXA8, {} PENTA6, {} TETRA4, {} TETRA10, {} PENTA15\n".format(
|
||||
len(nds),
|
||||
len(elms_hexa8),
|
||||
len(elms_penta6),
|
||||
len(elms_tetra4),
|
||||
len(elms_tetra10),
|
||||
len(elms_penta15)
|
||||
len(elms_penta15),
|
||||
)
|
||||
)
|
||||
Console.PrintLog(
|
||||
"imported mesh: {} "
|
||||
"HEXA20, {} TRIA3, {} TRIA6, {} QUAD4, {} QUAD8, {} SEG2, {} SEG3\n"
|
||||
.format(
|
||||
"HEXA20, {} TRIA3, {} TRIA6, {} QUAD4, {} QUAD8, {} SEG2, {} SEG3\n".format(
|
||||
len(elms_hexa20),
|
||||
len(elms_tria3),
|
||||
len(elms_tria6),
|
||||
len(elms_quad4),
|
||||
len(elms_quad8),
|
||||
len(elms_seg2),
|
||||
len(elms_seg3)
|
||||
len(elms_seg3),
|
||||
)
|
||||
)
|
||||
else:
|
||||
@@ -245,9 +279,7 @@ def make_femmesh(
|
||||
return mesh
|
||||
|
||||
|
||||
def make_dict_from_femmesh(
|
||||
femmesh
|
||||
):
|
||||
def make_dict_from_femmesh(femmesh):
|
||||
"""
|
||||
Converts FemMesh into dictionary structure which can immediately used
|
||||
from importToolsFem.make_femmesh(mesh_data) to create a valid FEM mesh.
|
||||
@@ -277,14 +309,7 @@ def make_dict_from_femmesh(
|
||||
|
||||
len_to_edge = {2: seg2, 3: seg3}
|
||||
len_to_face = {3: tri3, 6: tri6, 4: quad4, 8: quad8}
|
||||
len_to_volume = {
|
||||
4: tet4,
|
||||
10: tet10,
|
||||
8: hex8,
|
||||
20: hex20,
|
||||
6: pent6,
|
||||
15: pent15
|
||||
}
|
||||
len_to_volume = {4: tet4, 10: tet10, 8: hex8, 20: hex20, 6: pent6, 15: pent15}
|
||||
|
||||
# analyze edges
|
||||
|
||||
@@ -305,42 +330,31 @@ def make_dict_from_femmesh(
|
||||
len_to_volume[len(t)].append((v, t))
|
||||
|
||||
mesh_data = {
|
||||
"Nodes": dict([(k, (v.x, v.y, v.z))
|
||||
for (k, v) in femmesh.Nodes.items()]),
|
||||
"Nodes": {k: (v.x, v.y, v.z) for (k, v) in femmesh.Nodes.items()},
|
||||
"Seg2Elem": dict(seg2),
|
||||
"Seg3Elem": dict(seg3),
|
||||
|
||||
"Tria3Elem": dict(tri3),
|
||||
"Tria6Elem": dict(tri6),
|
||||
"Quad4Elem": dict(quad4),
|
||||
"Quad8Elem": dict(quad8),
|
||||
|
||||
"Tetra4Elem": dict(tet4),
|
||||
"Tetra10Elem": dict(tet10),
|
||||
"Hexa8Elem": dict(hex8),
|
||||
"Hexa20Elem": dict(hex20),
|
||||
"Penta6Elem": dict(pent6),
|
||||
"Penta15Elem": dict(pent15),
|
||||
|
||||
"Groups": dict([(
|
||||
group_num, (
|
||||
femmesh.getGroupName(group_num),
|
||||
femmesh.getGroupElements(group_num)
|
||||
)
|
||||
) for group_num in femmesh.Groups])
|
||||
|
||||
"Groups": {
|
||||
group_num: (femmesh.getGroupName(group_num), femmesh.getGroupElements(group_num))
|
||||
for group_num in femmesh.Groups
|
||||
},
|
||||
}
|
||||
# no pyr5, pyr13?
|
||||
# no groups?
|
||||
return mesh_data
|
||||
|
||||
|
||||
def fill_femresult_mechanical(
|
||||
res_obj,
|
||||
result_set
|
||||
):
|
||||
""" fills a FreeCAD FEM mechanical result object with result data
|
||||
"""
|
||||
def fill_femresult_mechanical(res_obj, result_set):
|
||||
"""fills a FreeCAD FEM mechanical result object with result data"""
|
||||
if "number" in result_set:
|
||||
eigenmode_number = result_set["number"]
|
||||
else:
|
||||
|
||||
@@ -42,19 +42,13 @@ from builtins import open as pyopen
|
||||
# ********* generic FreeCAD import and export methods *********
|
||||
|
||||
|
||||
|
||||
def open(
|
||||
filename
|
||||
):
|
||||
def open(filename):
|
||||
"called when freecad opens a file"
|
||||
docname = os.path.splitext(os.path.basename(filename))[0]
|
||||
insert(filename, docname)
|
||||
|
||||
|
||||
def insert(
|
||||
filename,
|
||||
docname
|
||||
):
|
||||
def insert(filename, docname):
|
||||
"called when freecad wants to import a file"
|
||||
try:
|
||||
doc = FreeCAD.getDocument(docname)
|
||||
@@ -64,15 +58,10 @@ def insert(
|
||||
importVtk(filename)
|
||||
|
||||
|
||||
def export(
|
||||
objectslist,
|
||||
filename
|
||||
):
|
||||
def export(objectslist, filename):
|
||||
"called when freecad exports an object to vtk"
|
||||
if len(objectslist) > 1: # the case of no selected obj is caught by FreeCAD already
|
||||
Console.PrintError(
|
||||
"This exporter can only export one object at once\n"
|
||||
)
|
||||
Console.PrintError("This exporter can only export one object at once\n")
|
||||
return
|
||||
|
||||
obj = objectslist[0]
|
||||
@@ -80,29 +69,19 @@ def export(
|
||||
obj.writeVTK(filename)
|
||||
return
|
||||
elif obj.isDerivedFrom("Fem::FemMeshObject"):
|
||||
Console.PrintError(
|
||||
"Use export to FEM mesh formats to export a FEM mesh object to vtk!\n"
|
||||
)
|
||||
Console.PrintError("Use export to FEM mesh formats to export a FEM mesh object to vtk!\n")
|
||||
return
|
||||
elif obj.isDerivedFrom("Fem::FemResultObject"):
|
||||
Fem.writeResult(filename, obj)
|
||||
else:
|
||||
Console.PrintError(
|
||||
"Selected object is not supported by export to VTK.\n"
|
||||
)
|
||||
Console.PrintError("Selected object is not supported by export to VTK.\n")
|
||||
return
|
||||
|
||||
|
||||
# ********* module specific methods *********
|
||||
def importVtk(
|
||||
filename,
|
||||
object_name=None,
|
||||
object_type=None
|
||||
):
|
||||
def importVtk(filename, object_name=None, object_type=None):
|
||||
if not object_type:
|
||||
vtkinout_prefs = FreeCAD.ParamGet(
|
||||
"User parameter:BaseApp/Preferences/Mod/Fem/InOutVtk"
|
||||
)
|
||||
vtkinout_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/InOutVtk")
|
||||
object_type = vtkinout_prefs.GetInt("ImportObject", 0)
|
||||
if not object_name:
|
||||
object_name = os.path.splitext(os.path.basename(filename))[0]
|
||||
@@ -116,16 +95,10 @@ def importVtk(
|
||||
# FreeCAD result object
|
||||
importVtkFCResult(filename, object_name)
|
||||
else:
|
||||
Console.PrintError(
|
||||
"Error, wrong parameter in VTK import pref: {}\n"
|
||||
.format(object_type)
|
||||
)
|
||||
Console.PrintError(f"Error, wrong parameter in VTK import pref: {object_type}\n")
|
||||
|
||||
|
||||
def importVtkVtkResult(
|
||||
filename,
|
||||
resultname
|
||||
):
|
||||
def importVtkVtkResult(filename, resultname):
|
||||
vtk_result_obj = FreeCAD.ActiveDocument.addObject("Fem::FemPostPipeline", resultname)
|
||||
vtk_result_obj.read(filename)
|
||||
# set display mode to "Surface" like for any other new pipeline to assure the user sees
|
||||
@@ -136,10 +109,7 @@ def importVtkVtkResult(
|
||||
return vtk_result_obj
|
||||
|
||||
|
||||
def importVtkFemMesh(
|
||||
filename,
|
||||
meshname
|
||||
):
|
||||
def importVtkFemMesh(filename, meshname):
|
||||
meshobj = FreeCAD.ActiveDocument.addObject("Fem::FemMeshObject", meshname)
|
||||
meshobj.FemMesh = Fem.read(filename)
|
||||
meshobj.touch()
|
||||
@@ -147,16 +117,12 @@ def importVtkFemMesh(
|
||||
return meshobj
|
||||
|
||||
|
||||
def importVtkFCResult(
|
||||
filename,
|
||||
resultname,
|
||||
analysis=None,
|
||||
result_name_prefix=None
|
||||
):
|
||||
def importVtkFCResult(filename, resultname, analysis=None, result_name_prefix=None):
|
||||
# only fields from vtk are imported if they exactly named as the FreeCAD result properties
|
||||
# See _getFreeCADMechResultProperties() in FemVTKTools.cpp for the supported names
|
||||
|
||||
import ObjectsFem
|
||||
|
||||
if result_name_prefix is None:
|
||||
result_name_prefix = ""
|
||||
if analysis:
|
||||
@@ -170,6 +136,7 @@ def importVtkFCResult(
|
||||
# add missing DisplacementLengths (They should have been added by Fem.readResult)
|
||||
if not result_obj.DisplacementLengths:
|
||||
import femresult.resulttools as restools
|
||||
|
||||
result_obj = restools.add_disp_apps(result_obj) # DisplacementLengths
|
||||
|
||||
""" seems unused at the moment
|
||||
|
||||
@@ -42,10 +42,7 @@ has_yaml = True
|
||||
try:
|
||||
import yaml
|
||||
except ImportError:
|
||||
Console.PrintMessage(
|
||||
"No YAML available (import yaml failure), "
|
||||
"yaml import/export won't work\n"
|
||||
)
|
||||
Console.PrintMessage("No YAML available (import yaml failure), yaml import/export won't work\n")
|
||||
has_yaml = False
|
||||
|
||||
|
||||
@@ -55,11 +52,7 @@ except ImportError:
|
||||
# they are set in FEM modules Init.py
|
||||
|
||||
|
||||
|
||||
|
||||
def open(
|
||||
filename
|
||||
):
|
||||
def open(filename):
|
||||
"""called when freecad opens a file
|
||||
a FEM mesh object is created in a new document"""
|
||||
|
||||
@@ -67,10 +60,7 @@ def open(
|
||||
return insert(filename, docname)
|
||||
|
||||
|
||||
def insert(
|
||||
filename,
|
||||
docname
|
||||
):
|
||||
def insert(filename, docname):
|
||||
"""called when freecad wants to import a file"
|
||||
a FEM mesh object is created in a existing document"""
|
||||
|
||||
@@ -87,9 +77,7 @@ def insert(
|
||||
def export(objectslist, fileString):
|
||||
"called when freecad exports a file"
|
||||
if len(objectslist) != 1:
|
||||
Console.PrintError(
|
||||
"This exporter can only "
|
||||
"export one object.\n")
|
||||
Console.PrintError("This exporter can only export one object.\n")
|
||||
return
|
||||
obj = objectslist[0]
|
||||
if not obj.isDerivedFrom("Fem::FemMeshObject"):
|
||||
@@ -113,10 +101,9 @@ def export(objectslist, fileString):
|
||||
# writer:
|
||||
# - a method directly writes a FemMesh to the mesh file
|
||||
|
||||
|
||||
# ********* reader ***********************************************************
|
||||
def import_yaml_json_mesh(
|
||||
fileString
|
||||
):
|
||||
def import_yaml_json_mesh(fileString):
|
||||
"""
|
||||
read a FemMesh from a yaml/json mesh file
|
||||
insert a FreeCAD FEM Mesh object in the ActiveDocument
|
||||
@@ -127,43 +114,34 @@ def import_yaml_json_mesh(
|
||||
|
||||
femmesh = read(fileString)
|
||||
if femmesh:
|
||||
mesh_object = FreeCAD.ActiveDocument.addObject(
|
||||
"Fem::FemMeshObject",
|
||||
mesh_name
|
||||
)
|
||||
mesh_object = FreeCAD.ActiveDocument.addObject("Fem::FemMeshObject", mesh_name)
|
||||
mesh_object.FemMesh = femmesh
|
||||
|
||||
return mesh_object
|
||||
|
||||
|
||||
def read(
|
||||
fileString
|
||||
):
|
||||
"""read a FemMesh from a yaml/json mesh file and return the FemMesh
|
||||
"""
|
||||
def read(fileString):
|
||||
"""read a FemMesh from a yaml/json mesh file and return the FemMesh"""
|
||||
# no document object is created, just the FemMesh is returned
|
||||
|
||||
fileExtension = os.path.basename(os.path.splitext(fileString)[1])
|
||||
|
||||
raw_mesh_data = {}
|
||||
if fileExtension.lower() == ".meshjson" or\
|
||||
fileExtension.lower() == ".json":
|
||||
if fileExtension.lower() == ".meshjson" or fileExtension.lower() == ".json":
|
||||
fp = pyopen(fileString, "rt")
|
||||
raw_mesh_data = json.load(fp)
|
||||
fp.close()
|
||||
elif (
|
||||
fileExtension.lower() == ".meshyaml"
|
||||
or fileExtension.lower() == ".meshyml"
|
||||
or fileExtension.lower() == ".yaml"
|
||||
or fileExtension.lower() == ".yml"
|
||||
fileExtension.lower() == ".meshyaml"
|
||||
or fileExtension.lower() == ".meshyml"
|
||||
or fileExtension.lower() == ".yaml"
|
||||
or fileExtension.lower() == ".yml"
|
||||
) and has_yaml:
|
||||
fp = pyopen(fileString, "rt")
|
||||
raw_mesh_data = yaml.load(fp, Loader=yaml.SafeLoader)
|
||||
fp.close()
|
||||
else:
|
||||
Console.PrintError(
|
||||
"Unknown extension, "
|
||||
"please select other importer.\n")
|
||||
Console.PrintError("Unknown extension, please select other importer.\n")
|
||||
|
||||
Console.PrintMessage("Converting indices to integer numbers ...")
|
||||
mesh_data = convert_raw_data_to_mesh_data(raw_mesh_data)
|
||||
@@ -172,9 +150,7 @@ def read(
|
||||
return importToolsFem.make_femmesh(mesh_data)
|
||||
|
||||
|
||||
def convert_raw_data_to_mesh_data(
|
||||
raw_mesh_data
|
||||
):
|
||||
def convert_raw_data_to_mesh_data(raw_mesh_data):
|
||||
"""
|
||||
Converts raw dictionary data from JSON or YAML file to proper dict
|
||||
for importToolsFem.make_femmesh(mesh_data). This is necessary since
|
||||
@@ -183,19 +159,14 @@ def convert_raw_data_to_mesh_data(
|
||||
"""
|
||||
|
||||
mesh_data = {}
|
||||
for (type_key, type_dict) in raw_mesh_data.items():
|
||||
for type_key, type_dict in raw_mesh_data.items():
|
||||
if type_key.lower() != "groups":
|
||||
mesh_data[type_key] = dict([
|
||||
(int(k), v) for (k, v) in type_dict.items()
|
||||
])
|
||||
mesh_data[type_key] = {int(k): v for (k, v) in type_dict.items()}
|
||||
return mesh_data
|
||||
|
||||
|
||||
# ********* writer ***********************************************************
|
||||
def write(
|
||||
fileString,
|
||||
fem_mesh
|
||||
):
|
||||
def write(fileString, fem_mesh):
|
||||
"""directly write a FemMesh to a yaml/json mesh file
|
||||
fem_mesh: a FemMesh"""
|
||||
|
||||
@@ -203,8 +174,7 @@ def write(
|
||||
|
||||
if fileString != "":
|
||||
fileName, fileExtension = os.path.splitext(fileString)
|
||||
if fileExtension.lower() == ".json" \
|
||||
or fileExtension.lower() == ".meshjson":
|
||||
if fileExtension.lower() == ".json" or fileExtension.lower() == ".meshjson":
|
||||
fp = pyopen(fileString, "wt")
|
||||
json.dump(mesh_data, fp, indent=4)
|
||||
fp.close()
|
||||
|
||||
@@ -43,11 +43,7 @@ from builtins import open as pyopen
|
||||
# they are set in FEM modules Init.py
|
||||
|
||||
|
||||
|
||||
|
||||
def open(
|
||||
filename
|
||||
):
|
||||
def open(filename):
|
||||
"""called when freecad opens a file
|
||||
a FEM mesh object is created in a new document"""
|
||||
|
||||
@@ -55,10 +51,7 @@ def open(
|
||||
return insert(filename, docname)
|
||||
|
||||
|
||||
def insert(
|
||||
filename,
|
||||
docname
|
||||
):
|
||||
def insert(filename, docname):
|
||||
"""called when freecad wants to import a file
|
||||
a FEM mesh object is created in a existing document"""
|
||||
|
||||
@@ -72,10 +65,7 @@ def insert(
|
||||
return doc
|
||||
|
||||
|
||||
def export(
|
||||
objectslist,
|
||||
filename
|
||||
):
|
||||
def export(objectslist, filename):
|
||||
"called when freecad exports a file"
|
||||
if len(objectslist) != 1:
|
||||
Console.PrintError("This exporter can only export one object.\n")
|
||||
@@ -103,12 +93,9 @@ def export(
|
||||
# - a method directly writes a FemMesh to the mesh file
|
||||
# - a method takes a file handle, mesh data and writes to the file handle
|
||||
|
||||
|
||||
# ********* reader *******************************************************************************
|
||||
def import_z88_mesh(
|
||||
filename,
|
||||
analysis=None,
|
||||
docname=None
|
||||
):
|
||||
def import_z88_mesh(filename, analysis=None, docname=None):
|
||||
"""read a FEM mesh from a Z88 mesh file and
|
||||
insert a FreeCAD FEM Mesh object in the ActiveDocument
|
||||
"""
|
||||
@@ -132,11 +119,8 @@ def import_z88_mesh(
|
||||
return mesh_object
|
||||
|
||||
|
||||
def read(
|
||||
filename
|
||||
):
|
||||
"""read a FemMesh from a Z88 mesh file and return the FemMesh
|
||||
"""
|
||||
def read(filename):
|
||||
"""read a FemMesh from a Z88 mesh file and return the FemMesh"""
|
||||
# no document object is created, just the FemMesh is returned
|
||||
|
||||
mesh_data = read_z88_mesh(filename)
|
||||
@@ -145,11 +129,9 @@ def read(
|
||||
return importToolsFem.make_femmesh(mesh_data)
|
||||
|
||||
|
||||
def read_z88_mesh(
|
||||
z88_mesh_input
|
||||
):
|
||||
""" reads a z88 mesh file z88i1.txt (Z88OSV14) or z88structure.txt (Z88AuroraV3)
|
||||
and extracts the nodes and elements
|
||||
def read_z88_mesh(z88_mesh_input):
|
||||
"""reads a z88 mesh file z88i1.txt (Z88OSV14) or z88structure.txt (Z88AuroraV3)
|
||||
and extracts the nodes and elements
|
||||
"""
|
||||
nodes = {}
|
||||
elements_hexa8 = {}
|
||||
@@ -178,20 +160,18 @@ def read_z88_mesh(
|
||||
kflag = int(mesh_info[4])
|
||||
# for non rotational elements is --> kflag = 0 --> cartesian, kflag = 1 polar coordinates
|
||||
if kflag:
|
||||
Console.PrintError(
|
||||
"KFLAG = 1, Rotational coordinates not supported at the moment\n"
|
||||
)
|
||||
Console.PrintError("KFLAG = 1, Rotational coordinates not supported at the moment\n")
|
||||
return {}
|
||||
nodes_first_line = 2 # first line is mesh_info
|
||||
nodes_last_line = nodes_count + 1
|
||||
elemts_first_line = nodes_last_line + 1
|
||||
elements_last_line = elemts_first_line - 1 + elements_count * 2
|
||||
|
||||
Console.PrintLog("{}\n".format(nodes_count))
|
||||
Console.PrintLog("{}\n".format(elements_count))
|
||||
Console.PrintLog("{}\n".format(nodes_last_line))
|
||||
Console.PrintLog("{}\n".format(elemts_first_line))
|
||||
Console.PrintLog("{}\n".format(elements_last_line))
|
||||
Console.PrintLog(f"{nodes_count}\n")
|
||||
Console.PrintLog(f"{elements_count}\n")
|
||||
Console.PrintLog(f"{nodes_last_line}\n")
|
||||
Console.PrintLog(f"{elemts_first_line}\n")
|
||||
Console.PrintLog(f"{elements_last_line}\n")
|
||||
|
||||
z88_mesh_file.seek(0) # go back to the beginning of the file
|
||||
for no, line in enumerate(z88_mesh_file):
|
||||
@@ -221,66 +201,44 @@ def read_z88_mesh(
|
||||
# not supported elements
|
||||
if z88_element_type == 8:
|
||||
# torus8
|
||||
Console.PrintError(
|
||||
"Z88 Element No. 8, torus8\n"
|
||||
)
|
||||
Console.PrintError(
|
||||
"Rotational elements are not supported at the moment\n"
|
||||
)
|
||||
Console.PrintError("Z88 Element No. 8, torus8\n")
|
||||
Console.PrintError("Rotational elements are not supported at the moment\n")
|
||||
return {}
|
||||
elif z88_element_type == 12:
|
||||
# torus12
|
||||
Console.PrintError(
|
||||
"Z88 Element No. 12, torus12\n"
|
||||
)
|
||||
Console.PrintError(
|
||||
"Rotational elements are not supported at the moment\n"
|
||||
)
|
||||
Console.PrintError("Z88 Element No. 12, torus12\n")
|
||||
Console.PrintError("Rotational elements are not supported at the moment\n")
|
||||
return {}
|
||||
elif z88_element_type == 15:
|
||||
# torus6
|
||||
Console.PrintError(
|
||||
"Z88 Element No. 15, torus6\n"
|
||||
)
|
||||
Console.PrintError(
|
||||
"Rotational elements are not supported at the moment\n"
|
||||
)
|
||||
Console.PrintError("Z88 Element No. 15, torus6\n")
|
||||
Console.PrintError("Rotational elements are not supported at the moment\n")
|
||||
return {}
|
||||
elif z88_element_type == 19:
|
||||
# platte16
|
||||
Console.PrintError(
|
||||
"Z88 Element No. 19, platte16\n"
|
||||
)
|
||||
Console.PrintError(
|
||||
"Not supported at the moment\n"
|
||||
)
|
||||
Console.PrintError("Z88 Element No. 19, platte16\n")
|
||||
Console.PrintError("Not supported at the moment\n")
|
||||
return {}
|
||||
elif z88_element_type == 21:
|
||||
# schale16, mixture made from hexa8 and hexa20 (thickness is linear)
|
||||
Console.PrintError(
|
||||
"Z88 Element No. 21, schale16\n"
|
||||
)
|
||||
Console.PrintError(
|
||||
"Not supported at the moment\n"
|
||||
)
|
||||
Console.PrintError("Z88 Element No. 21, schale16\n")
|
||||
Console.PrintError("Not supported at the moment\n")
|
||||
return {}
|
||||
elif z88_element_type == 22:
|
||||
# schale12, mixtrue made from prism6 and prism15 (thickness is linear)
|
||||
Console.PrintError(
|
||||
"Z88 Element No. 22, schale12\n"
|
||||
)
|
||||
Console.PrintError(
|
||||
"Not supported at the moment\n"
|
||||
)
|
||||
Console.PrintError("Z88 Element No. 22, schale12\n")
|
||||
Console.PrintError("Not supported at the moment\n")
|
||||
return {}
|
||||
|
||||
# supported elements
|
||||
elif z88_element_type == 2 \
|
||||
or z88_element_type == 4 \
|
||||
or z88_element_type == 5 \
|
||||
or z88_element_type == 9 \
|
||||
or z88_element_type == 13 \
|
||||
or z88_element_type == 25:
|
||||
elif (
|
||||
z88_element_type == 2
|
||||
or z88_element_type == 4
|
||||
or z88_element_type == 5
|
||||
or z88_element_type == 9
|
||||
or z88_element_type == 13
|
||||
or z88_element_type == 25
|
||||
):
|
||||
# stab4 or stab5 or welle5 or beam13 or beam25 Z88 --> seg2 FreeCAD
|
||||
# N1, N2
|
||||
nd1 = int(linecolumns[0])
|
||||
@@ -334,9 +292,7 @@ def read_z88_mesh(
|
||||
nd8 = int(linecolumns[7])
|
||||
nd9 = int(linecolumns[8])
|
||||
nd10 = int(linecolumns[9])
|
||||
elements_tetra10[elem_no] = (
|
||||
nd1, nd2, nd4, nd3, nd5, nd8, nd10, nd7, nd6, nd9
|
||||
)
|
||||
elements_tetra10[elem_no] = (nd1, nd2, nd4, nd3, nd5, nd8, nd10, nd7, nd6, nd9)
|
||||
input_continues = False
|
||||
elif z88_element_type == 1:
|
||||
# volume1 Z88 --> hexa8 FreeCAD
|
||||
@@ -379,8 +335,26 @@ def read_z88_mesh(
|
||||
nd19 = int(linecolumns[18])
|
||||
nd20 = int(linecolumns[19])
|
||||
elements_hexa20[elem_no] = (
|
||||
nd1, nd2, nd3, nd4, nd5, nd6, nd7, nd8, nd9, nd10,
|
||||
nd11, nd12, nd13, nd14, nd15, nd16, nd17, nd18, nd19, nd20
|
||||
nd1,
|
||||
nd2,
|
||||
nd3,
|
||||
nd4,
|
||||
nd5,
|
||||
nd6,
|
||||
nd7,
|
||||
nd8,
|
||||
nd9,
|
||||
nd10,
|
||||
nd11,
|
||||
nd12,
|
||||
nd13,
|
||||
nd14,
|
||||
nd15,
|
||||
nd16,
|
||||
nd17,
|
||||
nd18,
|
||||
nd19,
|
||||
nd20,
|
||||
)
|
||||
input_continues = False
|
||||
|
||||
@@ -411,15 +385,12 @@ def read_z88_mesh(
|
||||
"Hexa8Elem": elements_hexa8,
|
||||
"Hexa20Elem": elements_hexa20,
|
||||
"Penta6Elem": elements_penta6,
|
||||
"Penta15Elem": elements_penta15
|
||||
"Penta15Elem": elements_penta15,
|
||||
}
|
||||
|
||||
|
||||
# ********* writer *******************************************************************************
|
||||
def write(
|
||||
fem_mesh,
|
||||
filename
|
||||
):
|
||||
def write(fem_mesh, filename):
|
||||
"""directly write a FemMesh to a Z88 mesh file format
|
||||
fem_mesh: a FemMesh"""
|
||||
|
||||
@@ -434,12 +405,7 @@ def write(
|
||||
f.close()
|
||||
|
||||
|
||||
def write_z88_mesh_to_file(
|
||||
femnodes_mesh,
|
||||
femelement_table,
|
||||
z88_element_type,
|
||||
f
|
||||
):
|
||||
def write_z88_mesh_to_file(femnodes_mesh, femelement_table, z88_element_type, f):
|
||||
node_dimension = 3 # 2 for 2D not supported
|
||||
if (
|
||||
z88_element_type == 4
|
||||
@@ -449,10 +415,7 @@ def write_z88_mesh_to_file(
|
||||
or z88_element_type == 10
|
||||
):
|
||||
node_dof = 3
|
||||
elif (
|
||||
z88_element_type == 23
|
||||
or z88_element_type == 24
|
||||
):
|
||||
elif z88_element_type == 23 or z88_element_type == 24:
|
||||
node_dof = 6 # schalenelemente
|
||||
else:
|
||||
Console.PrintError("Error: wrong z88_element_type.\n")
|
||||
@@ -464,16 +427,15 @@ def write_z88_mesh_to_file(
|
||||
written_by = "written by FreeCAD"
|
||||
|
||||
# first line, some z88 specific stuff
|
||||
f.write("{0} {1} {2} {3} {4} {5}\n".format(
|
||||
node_dimension, node_count, element_count, dofs, unknown_flag, written_by)
|
||||
f.write(
|
||||
"{} {} {} {} {} {}\n".format(
|
||||
node_dimension, node_count, element_count, dofs, unknown_flag, written_by
|
||||
)
|
||||
)
|
||||
# nodes
|
||||
for node in femnodes_mesh:
|
||||
vec = femnodes_mesh[node]
|
||||
f.write(
|
||||
"{0} {1} {2:.6f} {3:.6f} {4:.6f}\n"
|
||||
.format(node, node_dof, vec.x, vec.y, vec.z)
|
||||
)
|
||||
f.write(f"{node} {node_dof} {vec.x:.6f} {vec.y:.6f} {vec.z:.6f}\n")
|
||||
# elements
|
||||
for element in femelement_table:
|
||||
# z88_element_type is checked for every element
|
||||
@@ -489,39 +451,37 @@ def write_z88_mesh_to_file(
|
||||
):
|
||||
# seg2 FreeCAD --> stab4 Z88
|
||||
# N1, N2
|
||||
f.write("{0} {1}\n".format(element, z88_element_type))
|
||||
f.write("{0} {1}\n".format(
|
||||
n[0], n[1]))
|
||||
f.write(f"{element} {z88_element_type}\n")
|
||||
f.write(f"{n[0]} {n[1]}\n")
|
||||
elif z88_element_type == 3 or z88_element_type == 14 or z88_element_type == 24:
|
||||
# tria6 FreeCAD --> schale24 Z88
|
||||
# N1, N2, N3, N4, N5, N6
|
||||
f.write("{0} {1}\n".format(element, z88_element_type))
|
||||
f.write("{0} {1} {2} {3} {4} {5}\n".format(
|
||||
n[0], n[1], n[2], n[3], n[4], n[5]))
|
||||
f.write(f"{element} {z88_element_type}\n")
|
||||
f.write(f"{n[0]} {n[1]} {n[2]} {n[3]} {n[4]} {n[5]}\n")
|
||||
elif z88_element_type == 7 or z88_element_type == 20 or z88_element_type == 23:
|
||||
# quad8 FreeCAD --> schale23 Z88
|
||||
# N1, N2, N3, N4, N5, N6, N7, N8
|
||||
f.write("{0} {1}\n".format(element, z88_element_type))
|
||||
f.write("{0} {1} {2} {3} {4} {5} {6} {7}\n".format(
|
||||
n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7]))
|
||||
f.write(f"{element} {z88_element_type}\n")
|
||||
f.write(f"{n[0]} {n[1]} {n[2]} {n[3]} {n[4]} {n[5]} {n[6]} {n[7]}\n")
|
||||
elif z88_element_type == 17:
|
||||
# tetra4 FreeCAD --> volume17 Z88
|
||||
# N4, N2, N3, N1
|
||||
f.write("{0} {1}\n".format(element, z88_element_type))
|
||||
f.write("{0} {1} {2} {3}\n".format(
|
||||
n[3], n[1], n[2], n[0]))
|
||||
f.write(f"{element} {z88_element_type}\n")
|
||||
f.write(f"{n[3]} {n[1]} {n[2]} {n[0]}\n")
|
||||
elif z88_element_type == 16:
|
||||
# tetra10 FreeCAD --> volume16 Z88
|
||||
# N1, N2, N4, N3, N5, N9, N8, N6, N10, N7, FC to Z88 is different as Z88 to FC
|
||||
f.write("{0} {1}\n".format(element, z88_element_type))
|
||||
f.write("{0} {1} {2} {3} {4} {5} {6} {7} {8} {9}\n".format(
|
||||
n[0], n[1], n[3], n[2], n[4], n[8], n[7], n[5], n[9], n[6]))
|
||||
f.write(f"{element} {z88_element_type}\n")
|
||||
f.write(
|
||||
"{} {} {} {} {} {} {} {} {} {}\n".format(
|
||||
n[0], n[1], n[3], n[2], n[4], n[8], n[7], n[5], n[9], n[6]
|
||||
)
|
||||
)
|
||||
elif z88_element_type == 1:
|
||||
# hexa8 FreeCAD --> volume1 Z88
|
||||
# N1, N2, N3, N4, N5, N6, N7, N8
|
||||
f.write("{0} {1}\n".format(element, z88_element_type))
|
||||
f.write("{0} {1} {2} {3} {4} {5} {6} {7}\n".format(
|
||||
n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7]))
|
||||
f.write(f"{element} {z88_element_type}\n")
|
||||
f.write(f"{n[0]} {n[1]} {n[2]} {n[3]} {n[4]} {n[5]} {n[6]} {n[7]}\n")
|
||||
elif z88_element_type == 10:
|
||||
# hexa20 FreeCAD --> volume10 Z88
|
||||
# N2, N3, N4, N1, N6, N7, N8, N5, N10, N11
|
||||
@@ -529,28 +489,40 @@ def write_z88_mesh_to_file(
|
||||
# or turn by 90 degree and they match !
|
||||
# N1, N2, N3, N4, N5, N6, N7, N8, N9, N10
|
||||
# N11, N12, N13, N14, N15, N16, N17, N18, N19, N20
|
||||
f.write("{0} {1}\n".format(element, z88_element_type))
|
||||
f.write(f"{element} {z88_element_type}\n")
|
||||
f.write(
|
||||
"{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} "
|
||||
"{10} {11} {12} {13} {14} {15} {16} {17} {18} {19}\n"
|
||||
.format(
|
||||
n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9],
|
||||
n[10], n[11], n[12], n[13], n[14], n[15], n[16], n[17], n[18], n[19]
|
||||
"{} {} {} {} {} {} {} {} {} {} "
|
||||
"{} {} {} {} {} {} {} {} {} {}\n".format(
|
||||
n[0],
|
||||
n[1],
|
||||
n[2],
|
||||
n[3],
|
||||
n[4],
|
||||
n[5],
|
||||
n[6],
|
||||
n[7],
|
||||
n[8],
|
||||
n[9],
|
||||
n[10],
|
||||
n[11],
|
||||
n[12],
|
||||
n[13],
|
||||
n[14],
|
||||
n[15],
|
||||
n[16],
|
||||
n[17],
|
||||
n[18],
|
||||
n[19],
|
||||
)
|
||||
)
|
||||
else:
|
||||
Console.PrintError(
|
||||
"Writing of Z88 elementtype {0} not supported.\n".format(z88_element_type)
|
||||
)
|
||||
Console.PrintError(f"Writing of Z88 elementtype {z88_element_type} not supported.\n")
|
||||
# TODO support schale12 (made from prism15) and schale16 (made from hexa20)
|
||||
return
|
||||
|
||||
|
||||
# Helper
|
||||
def get_z88_element_type(
|
||||
femmesh,
|
||||
femelement_table=None
|
||||
):
|
||||
def get_z88_element_type(femmesh, femelement_table=None):
|
||||
return z88_ele_types[meshtools.get_femmesh_eletype(femmesh, femelement_table)]
|
||||
|
||||
|
||||
|
||||
@@ -39,19 +39,13 @@ from builtins import open as pyopen
|
||||
# ********* generic FreeCAD import and export methods *********
|
||||
|
||||
|
||||
|
||||
def open(
|
||||
filename
|
||||
):
|
||||
def open(filename):
|
||||
"called when freecad opens a file"
|
||||
docname = os.path.splitext(os.path.basename(filename))[0]
|
||||
insert(filename, docname)
|
||||
|
||||
|
||||
def insert(
|
||||
filename,
|
||||
docname
|
||||
):
|
||||
def insert(filename, docname):
|
||||
"called when freecad wants to import a file"
|
||||
try:
|
||||
doc = FreeCAD.getDocument(docname)
|
||||
@@ -62,11 +56,7 @@ def insert(
|
||||
|
||||
|
||||
# ********* module specific methods *********
|
||||
def import_z88_disp(
|
||||
filename,
|
||||
analysis=None,
|
||||
result_name_prefix=None
|
||||
):
|
||||
def import_z88_disp(filename, analysis=None, result_name_prefix=None):
|
||||
"""insert a FreeCAD FEM mechanical result object in the ActiveDocument
|
||||
pure usage:
|
||||
import feminout.importZ88O2Results as importZ88O2Results
|
||||
@@ -80,6 +70,7 @@ def import_z88_disp(
|
||||
from . import importZ88Mesh
|
||||
from . import importToolsFem
|
||||
from femresult import resulttools
|
||||
|
||||
if result_name_prefix is None:
|
||||
result_name_prefix = ""
|
||||
disp_read = read_z88_disp(filename)
|
||||
@@ -93,10 +84,7 @@ def import_z88_disp(
|
||||
mesh_file = filename.replace("o2", "i1")
|
||||
mesh_data = importZ88Mesh.read_z88_mesh(mesh_file)
|
||||
femmesh = importToolsFem.make_femmesh(mesh_data)
|
||||
result_mesh_object = ObjectsFem.makeMeshResult(
|
||||
FreeCAD.ActiveDocument,
|
||||
"Result_mesh"
|
||||
)
|
||||
result_mesh_object = ObjectsFem.makeMeshResult(FreeCAD.ActiveDocument, "Result_mesh")
|
||||
result_mesh_object.FemMesh = femmesh
|
||||
else:
|
||||
Console.PrintError("Z88 mesh file z88i1.txt not found.\n")
|
||||
@@ -118,6 +106,7 @@ def import_z88_disp(
|
||||
if FreeCAD.GuiUp:
|
||||
if analysis:
|
||||
import FemGui
|
||||
|
||||
FemGui.setActiveAnalysis(analysis_object)
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
@@ -129,9 +118,7 @@ def import_z88_disp(
|
||||
return res_obj
|
||||
|
||||
|
||||
def read_z88_disp(
|
||||
z88_disp_input
|
||||
):
|
||||
def read_z88_disp(z88_disp_input):
|
||||
"""
|
||||
read a z88 disp file and extract the nodes and elements
|
||||
z88 Displacement output file is z88o2.txt
|
||||
|
||||
@@ -48,5 +48,5 @@ def read_fenics_mesh_xdmf(xdmffilename):
|
||||
"Tria6Elem": {},
|
||||
"Quad4Elem": {},
|
||||
"Quad8Elem": {},
|
||||
"Seg2Elem": {}
|
||||
"Seg2Elem": {},
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ from FreeCAD import Console
|
||||
|
||||
def read_fenics_mesh_xml(xmlfilename):
|
||||
"""
|
||||
Returns element dictionary to be evaluated by make_femmesh later
|
||||
Returns element dictionary to be evaluated by make_femmesh later
|
||||
"""
|
||||
|
||||
Fenics_to_FreeCAD_dict = {
|
||||
@@ -51,8 +51,8 @@ def read_fenics_mesh_xml(xmlfilename):
|
||||
|
||||
def read_mesh_block(mesh_block):
|
||||
"""
|
||||
Reading mesh block from XML file.
|
||||
The mesh block only contains cells and vertices.
|
||||
Reading mesh block from XML file.
|
||||
The mesh block only contains cells and vertices.
|
||||
"""
|
||||
dim = int(mesh_block.get("dim"))
|
||||
cell_type = mesh_block.get("celltype")
|
||||
@@ -64,12 +64,14 @@ def read_fenics_mesh_xml(xmlfilename):
|
||||
|
||||
# every cell type contains a dict with key=dimension and value=number
|
||||
|
||||
cells_parts_dim = {"point": {0: 1},
|
||||
"interval": {0: 2, 1: 1},
|
||||
"triangle": {0: 3, 1: 3, 2: 1},
|
||||
"tetrahedron": {0: 4, 1: 6, 2: 4, 3: 1},
|
||||
"quadrilateral": {0: 4, 1: 4, 2: 1},
|
||||
"hexahedron": {0: 8, 1: 12, 2: 6, 3: 1}}
|
||||
cells_parts_dim = {
|
||||
"point": {0: 1},
|
||||
"interval": {0: 2, 1: 1},
|
||||
"triangle": {0: 3, 1: 3, 2: 1},
|
||||
"tetrahedron": {0: 4, 1: 6, 2: 4, 3: 1},
|
||||
"quadrilateral": {0: 4, 1: 4, 2: 1},
|
||||
"hexahedron": {0: 8, 1: 12, 2: 6, 3: 1},
|
||||
}
|
||||
|
||||
find_vertices = mesh_block.find("vertices")
|
||||
find_cells = mesh_block.find("cells")
|
||||
@@ -88,7 +90,7 @@ def read_fenics_mesh_xml(xmlfilename):
|
||||
|
||||
if vertex.tag.lower() == "vertex":
|
||||
[node_x, node_y, node_z] = [
|
||||
float(vertex.get(coord, 0.)) for coord in ["x", "y", "z"]
|
||||
float(vertex.get(coord, 0.0)) for coord in ["x", "y", "z"]
|
||||
]
|
||||
|
||||
nodes_dict[ind + 1] = FreeCAD.Vector(node_x, node_y, node_z)
|
||||
@@ -105,14 +107,14 @@ def read_fenics_mesh_xml(xmlfilename):
|
||||
ind = int(cell.get("index"))
|
||||
|
||||
if cell.tag.lower() != cell_type.lower():
|
||||
Console.PrintWarning("Strange mismatch between cell type " +
|
||||
f"{cell_type} and " +
|
||||
f"cell tag {cell.tag.lower()}\n")
|
||||
Console.PrintWarning(
|
||||
"Strange mismatch between cell type "
|
||||
+ f"{cell_type} and "
|
||||
+ f"cell tag {cell.tag.lower()}\n"
|
||||
)
|
||||
num_vertices = cells_parts_dim[cell_type][0]
|
||||
|
||||
vtupel = tuple([
|
||||
int(cell.get("v" + str(vnum))) + 1 for vnum in range(num_vertices)
|
||||
])
|
||||
vtupel = tuple([int(cell.get("v" + str(vnum))) + 1 for vnum in range(num_vertices)])
|
||||
# generate "v0", "v1", ... from dimension lookup table
|
||||
# increase numbers by one to match FC numbering convention
|
||||
|
||||
@@ -127,14 +129,14 @@ def read_fenics_mesh_xml(xmlfilename):
|
||||
|
||||
def correct_volume_det(element_dict):
|
||||
"""
|
||||
Checks whether the cell elements
|
||||
all have the same volume (<0?)
|
||||
sign (is necessary to avoid negative
|
||||
Jacobian errors).
|
||||
Works only with tet4 and tri3 elements at the moment
|
||||
Checks whether the cell elements
|
||||
all have the same volume (<0?)
|
||||
sign (is necessary to avoid negative
|
||||
Jacobian errors).
|
||||
Works only with tet4 and tri3 elements at the moment
|
||||
"""
|
||||
if dim == 3:
|
||||
for (ind, tet) in list(element_dict["tetra4"].items()):
|
||||
for ind, tet in list(element_dict["tetra4"].items()):
|
||||
v0 = nodes[tet[0]]
|
||||
v1 = nodes[tet[1]]
|
||||
v2 = nodes[tet[2]]
|
||||
@@ -145,8 +147,8 @@ def read_fenics_mesh_xml(xmlfilename):
|
||||
if a.dot(b.cross(c)) > 0:
|
||||
element_dict["tetra4"][ind] = (tet[1], tet[0], tet[2], tet[3])
|
||||
if dim == 2:
|
||||
nz = FreeCAD.Vector(0., 0., 1.)
|
||||
for (ind, tria) in list(element_dict["tria3"].items()):
|
||||
nz = FreeCAD.Vector(0.0, 0.0, 1.0)
|
||||
for ind, tria in list(element_dict["tria3"].items()):
|
||||
v0 = nodes[tria[0]]
|
||||
v1 = nodes[tria[1]]
|
||||
v2 = nodes[tria[2]]
|
||||
@@ -159,7 +161,7 @@ def read_fenics_mesh_xml(xmlfilename):
|
||||
element_counter = {}
|
||||
|
||||
# TODO: remove upper level lookup
|
||||
for (key, val) in list(Fenics_to_FreeCAD_dict.items()):
|
||||
for key, val in list(Fenics_to_FreeCAD_dict.items()):
|
||||
element_dict[val] = {}
|
||||
element_counter[key] = 0 # count every distinct element and sub element type
|
||||
|
||||
@@ -172,43 +174,46 @@ def read_fenics_mesh_xml(xmlfilename):
|
||||
|
||||
def invertdict(dic):
|
||||
invdic = {}
|
||||
for (key, it) in list(dic.items()):
|
||||
for key, it in list(dic.items()):
|
||||
invdic[it] = key
|
||||
return invdic
|
||||
|
||||
num_vert_dict = {"interval": 2,
|
||||
"triangle": 3,
|
||||
"tetrahedron": 4,
|
||||
"hexahedron": 8,
|
||||
"quadrilateral": 4}
|
||||
lower_dims_dict = {"interval": [],
|
||||
"triangle": ["interval"],
|
||||
"tetrahedron": ["triangle", "interval"],
|
||||
"hexahedron": ["quadrilateral", "interval"],
|
||||
"quadrilateral": ["interval"]}
|
||||
num_vert_dict = {
|
||||
"interval": 2,
|
||||
"triangle": 3,
|
||||
"tetrahedron": 4,
|
||||
"hexahedron": 8,
|
||||
"quadrilateral": 4,
|
||||
}
|
||||
lower_dims_dict = {
|
||||
"interval": [],
|
||||
"triangle": ["interval"],
|
||||
"tetrahedron": ["triangle", "interval"],
|
||||
"hexahedron": ["quadrilateral", "interval"],
|
||||
"quadrilateral": ["interval"],
|
||||
}
|
||||
|
||||
# generate cell list from file
|
||||
# read vertex list from cells
|
||||
# generate lower dimensional objects in mesh from cell
|
||||
|
||||
for (cell_index, cell) in list(cell_dict.items()):
|
||||
for cell_index, cell in list(cell_dict.items()):
|
||||
cell_lower_dims = lower_dims_dict[cell_type]
|
||||
element_counter[cell_type] += 1
|
||||
element_dict[Fenics_to_FreeCAD_dict[cell_type]][cell] = element_counter[cell_type]
|
||||
for ld in cell_lower_dims:
|
||||
for vertextuple in itertools.combinations(cell, num_vert_dict[ld]):
|
||||
element_counter[ld] = addtupletodict(
|
||||
element_dict[Fenics_to_FreeCAD_dict[ld]],
|
||||
vertextuple,
|
||||
element_counter[ld])
|
||||
element_dict[Fenics_to_FreeCAD_dict[ld]], vertextuple, element_counter[ld]
|
||||
)
|
||||
|
||||
length_counter = len(nodes) # maintain distinct counting values
|
||||
# print("nodes")
|
||||
# print("len & len counter", length_counter)
|
||||
for (key, val_dict) in list(element_dict.items()):
|
||||
for key, val_dict in list(element_dict.items()):
|
||||
# to ensure distinct indices for FreeCAD
|
||||
# print("key: ", key)
|
||||
for (vkey, it) in list(val_dict.items()):
|
||||
for vkey, it in list(val_dict.items()):
|
||||
val_dict[vkey] = it + length_counter # maintain distinct element numbers
|
||||
len_val_dict = len(val_dict)
|
||||
if len_val_dict > 0:
|
||||
@@ -240,7 +245,7 @@ def read_fenics_mesh_xml(xmlfilename):
|
||||
(nodes, cells_dict, cell_type, dim) = read_mesh_block(find_mesh)
|
||||
element_dict = generate_lower_dimensional_structures(nodes, cells_dict, cell_type, dim)
|
||||
Console.PrintMessage("Show min max element dict\n")
|
||||
for (elm, numbers) in list(element_dict.items()):
|
||||
for elm, numbers in list(element_dict.items()):
|
||||
lst = sorted(list(numbers.items()), key=lambda x: x[0])
|
||||
if lst != []:
|
||||
Console.PrintMessage(f"{elm} min: {lst[0]} max: {lst[-1]}\n")
|
||||
@@ -263,5 +268,5 @@ def read_fenics_mesh_xml(xmlfilename):
|
||||
"Hexa8Elem": {},
|
||||
"Hexa20Elem": {},
|
||||
"Penta6Elem": {},
|
||||
"Penta15Elem": {}
|
||||
"Penta15Elem": {},
|
||||
}
|
||||
|
||||
@@ -44,12 +44,7 @@ from .importToolsFem import get_MaxDimElementFromList
|
||||
ENCODING_ASCII = "ASCII"
|
||||
ENCODING_HDF5 = "HDF5"
|
||||
|
||||
FreeCAD_Group_Dimensions = {
|
||||
"Vertex": 0,
|
||||
"Edge": 1,
|
||||
"Face": 2,
|
||||
"Volume": 3
|
||||
}
|
||||
FreeCAD_Group_Dimensions = {"Vertex": 0, "Edge": 1, "Face": 2, "Volume": 3}
|
||||
|
||||
FreeCAD_to_Fenics_XDMF_dict = {
|
||||
("Node", 1): ("Polyvertex", 1),
|
||||
@@ -58,16 +53,14 @@ FreeCAD_to_Fenics_XDMF_dict = {
|
||||
("Triangle", 1): ("Triangle", 3),
|
||||
("Triangle", 2): ("Tri_6", 6),
|
||||
("Tetra", 1): ("Tetrahedron", 4),
|
||||
("Tetra", 2): ("Tet_10", 10)
|
||||
("Tetra", 2): ("Tet_10", 10),
|
||||
}
|
||||
|
||||
# we need numpy functions to later access and process large data sets in a fast manner
|
||||
# also the hd5 support works better together with numpy
|
||||
|
||||
|
||||
def numpy_array_to_str(
|
||||
npa
|
||||
):
|
||||
def numpy_array_to_str(npa):
|
||||
res = ""
|
||||
dt = str(npa.dtype)
|
||||
if "int" in dt:
|
||||
@@ -77,27 +70,17 @@ def numpy_array_to_str(
|
||||
return res
|
||||
|
||||
|
||||
def points_to_numpy(
|
||||
pts,
|
||||
dim=3
|
||||
):
|
||||
def points_to_numpy(pts, dim=3):
|
||||
return np.array([[p.x, p.y, p.z] for p in pts])[:, :dim]
|
||||
|
||||
|
||||
def tuples_to_numpy(
|
||||
tpls,
|
||||
numbers_per_line
|
||||
):
|
||||
def tuples_to_numpy(tpls, numbers_per_line):
|
||||
return np.array([list(t) for t in tpls])[:, :numbers_per_line]
|
||||
|
||||
|
||||
def write_fenics_mesh_points_xdmf(
|
||||
fem_mesh_obj,
|
||||
geometrynode,
|
||||
encoding=ENCODING_ASCII
|
||||
):
|
||||
def write_fenics_mesh_points_xdmf(fem_mesh_obj, geometrynode, encoding=ENCODING_ASCII):
|
||||
"""
|
||||
Writes either into hdf5 file or into open mesh file
|
||||
Writes either into hdf5 file or into open mesh file
|
||||
"""
|
||||
|
||||
numnodes = fem_mesh_obj.FemMesh.NodeCount
|
||||
@@ -114,13 +97,10 @@ def write_fenics_mesh_points_xdmf(
|
||||
|
||||
if encoding == ENCODING_ASCII:
|
||||
dataitem = ET.SubElement(
|
||||
geometrynode,
|
||||
"DataItem",
|
||||
Dimensions="%d %d" % (numnodes, effective_dim),
|
||||
Format="XML"
|
||||
geometrynode, "DataItem", Dimensions="%d %d" % (numnodes, effective_dim), Format="XML"
|
||||
)
|
||||
nodes = []
|
||||
for (ind, (key, node)) in enumerate(list(fem_mesh_obj.FemMesh.Nodes.items())):
|
||||
for ind, (key, node) in enumerate(list(fem_mesh_obj.FemMesh.Nodes.items())):
|
||||
nodes.append(node)
|
||||
recalc_nodes_ind_dict[key] = ind
|
||||
|
||||
@@ -132,11 +112,7 @@ def write_fenics_mesh_points_xdmf(
|
||||
|
||||
|
||||
def write_fenics_mesh_codim_xdmf(
|
||||
fem_mesh_obj,
|
||||
topologynode,
|
||||
nodes_dict,
|
||||
codim=0,
|
||||
encoding=ENCODING_ASCII
|
||||
fem_mesh_obj, topologynode, nodes_dict, codim=0, encoding=ENCODING_ASCII
|
||||
):
|
||||
mesh_dimension = get_FemMeshObjectDimension(fem_mesh_obj)
|
||||
|
||||
@@ -151,7 +127,7 @@ def write_fenics_mesh_codim_xdmf(
|
||||
writeout_element_dimension = mesh_dimension - codim
|
||||
|
||||
(num_topo, name_topo, dim_topo) = (0, "", 0)
|
||||
for (num, name, dim) in element_types:
|
||||
for num, name, dim in element_types:
|
||||
if writeout_element_dimension == dim:
|
||||
(num_topo, name_topo, dim_topo) = (num, name, dim)
|
||||
|
||||
@@ -171,19 +147,22 @@ def write_fenics_mesh_codim_xdmf(
|
||||
fc_topo = fem_mesh_obj.FemMesh.Nodes
|
||||
else:
|
||||
fc_topo = []
|
||||
Console.PrintError("Dimension of mesh incompatible with export" +
|
||||
f" XDMF function: {dim_topo}\n")
|
||||
Console.PrintError(
|
||||
"Dimension of mesh incompatible with export" + f" XDMF function: {dim_topo}\n"
|
||||
)
|
||||
|
||||
nodeindices = [(
|
||||
nodes_dict[ind] for ind in fem_mesh_obj.FemMesh.getElementNodes(fc_topo_ind)
|
||||
) for (fen_ind, fc_topo_ind) in enumerate(fc_topo)]
|
||||
nodeindices = [
|
||||
(nodes_dict[ind] for ind in fem_mesh_obj.FemMesh.getElementNodes(fc_topo_ind))
|
||||
for (fen_ind, fc_topo_ind) in enumerate(fc_topo)
|
||||
]
|
||||
|
||||
if encoding == ENCODING_ASCII:
|
||||
dataitem = ET.SubElement(
|
||||
topologynode, "DataItem",
|
||||
topologynode,
|
||||
"DataItem",
|
||||
NumberType="UInt",
|
||||
Dimensions="%d %d" % (num_topo, nodes_per_element),
|
||||
Format="XML"
|
||||
Format="XML",
|
||||
)
|
||||
dataitem.text = numpy_array_to_str(tuples_to_numpy(nodeindices, nodes_per_element))
|
||||
elif encoding == ENCODING_HDF5:
|
||||
@@ -193,9 +172,7 @@ def write_fenics_mesh_codim_xdmf(
|
||||
|
||||
|
||||
def write_fenics_mesh_scalar_cellfunctions(
|
||||
name, cell_array,
|
||||
attributenode,
|
||||
encoding=ENCODING_ASCII
|
||||
name, cell_array, attributenode, encoding=ENCODING_ASCII
|
||||
):
|
||||
attributenode.set("AttributeType", "Scalar")
|
||||
attributenode.set("Center", "Cell")
|
||||
@@ -205,9 +182,7 @@ def write_fenics_mesh_scalar_cellfunctions(
|
||||
|
||||
if encoding == ENCODING_ASCII:
|
||||
dataitem = ET.SubElement(
|
||||
attributenode, "DataItem",
|
||||
Dimensions="%d %d" % (num_cells, num_dims),
|
||||
Format="XML"
|
||||
attributenode, "DataItem", Dimensions="%d %d" % (num_cells, num_dims), Format="XML"
|
||||
)
|
||||
dataitem.text = numpy_array_to_str(cell_array)
|
||||
elif encoding == ENCODING_HDF5:
|
||||
@@ -253,14 +228,9 @@ Example: mesh with two topologies and one mesh function for the facet one
|
||||
"""
|
||||
|
||||
|
||||
def write_fenics_mesh_xdmf(
|
||||
fem_mesh_obj,
|
||||
outputfile,
|
||||
group_values_dict={},
|
||||
encoding=ENCODING_ASCII
|
||||
):
|
||||
def write_fenics_mesh_xdmf(fem_mesh_obj, outputfile, group_values_dict={}, encoding=ENCODING_ASCII):
|
||||
"""
|
||||
For the export of xdmf.
|
||||
For the export of xdmf.
|
||||
"""
|
||||
|
||||
Console.PrintMessage(f"Converting {fem_mesh_obj.Label} to fenics XDMF File\n")
|
||||
@@ -283,16 +253,9 @@ def write_fenics_mesh_xdmf(
|
||||
|
||||
# ***********************************
|
||||
# write base topo and geometry
|
||||
nodes_dict = write_fenics_mesh_points_xdmf(
|
||||
fem_mesh_obj,
|
||||
base_geometry,
|
||||
encoding=encoding
|
||||
)
|
||||
nodes_dict = write_fenics_mesh_points_xdmf(fem_mesh_obj, base_geometry, encoding=encoding)
|
||||
write_fenics_mesh_codim_xdmf(
|
||||
fem_mesh_obj, base_topology,
|
||||
nodes_dict,
|
||||
codim=0,
|
||||
encoding=encoding
|
||||
fem_mesh_obj, base_topology, nodes_dict, codim=0, encoding=encoding
|
||||
)
|
||||
# ***********************************
|
||||
|
||||
@@ -307,14 +270,14 @@ def write_fenics_mesh_xdmf(
|
||||
mesh_function_codim = dim_cell - FreeCAD_Group_Dimensions[mesh_function_type]
|
||||
mesh_function_name = fem_mesh.getGroupName(g)
|
||||
|
||||
Console.PrintMessage(f"group id: {g} (label: {mesh_function_name})" +
|
||||
f" with element type {mesh_function_type} and" +
|
||||
" codim {mesh_function_codim}\n")
|
||||
Console.PrintMessage(
|
||||
f"group id: {g} (label: {mesh_function_name})"
|
||||
+ f" with element type {mesh_function_type} and"
|
||||
+ " codim {mesh_function_codim}\n"
|
||||
)
|
||||
|
||||
mesh_function_grid = ET.SubElement(
|
||||
domain, "Grid",
|
||||
Name=mesh_function_name + "_mesh",
|
||||
GridType="Uniform"
|
||||
domain, "Grid", Name=mesh_function_name + "_mesh", GridType="Uniform"
|
||||
)
|
||||
mesh_function_topology = ET.SubElement(mesh_function_grid, "Topology")
|
||||
|
||||
@@ -322,11 +285,11 @@ def write_fenics_mesh_xdmf(
|
||||
fem_mesh_obj,
|
||||
mesh_function_topology,
|
||||
nodes_dict,
|
||||
codim=mesh_function_codim, encoding=encoding
|
||||
codim=mesh_function_codim,
|
||||
encoding=encoding,
|
||||
)
|
||||
|
||||
mesh_function_geometry = ET.SubElement(mesh_function_grid, "Geometry",
|
||||
Reference="XML")
|
||||
mesh_function_geometry = ET.SubElement(mesh_function_grid, "Geometry", Reference="XML")
|
||||
mesh_function_geometry.text = "/Xdmf/Domain/Grid/Geometry"
|
||||
mesh_function_attribute = ET.SubElement(mesh_function_grid, "Attribute")
|
||||
|
||||
@@ -341,21 +304,18 @@ def write_fenics_mesh_xdmf(
|
||||
for e in fem_mesh.getGroupElements(g):
|
||||
elem_dict[e] = elem_mark_group
|
||||
|
||||
val_array = np.array([
|
||||
elem_dict.get(e, elem_mark_default) for e in mesh_function_topology_description
|
||||
])
|
||||
val_array = np.array(
|
||||
[elem_dict.get(e, elem_mark_default) for e in mesh_function_topology_description]
|
||||
)
|
||||
topo_array = np.vstack((val_array,)).T
|
||||
write_fenics_mesh_scalar_cellfunctions(
|
||||
mesh_function_name,
|
||||
topo_array,
|
||||
mesh_function_attribute,
|
||||
encoding=ENCODING_ASCII
|
||||
mesh_function_name, topo_array, mesh_function_attribute, encoding=ENCODING_ASCII
|
||||
)
|
||||
|
||||
# TODO: improve cell functions support
|
||||
|
||||
fp = open(outputfile, "wb")
|
||||
fp.write(b'''<?xml version="1.0"?>\n<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>\n''')
|
||||
fp.write(b"""<?xml version="1.0"?>\n<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>\n""")
|
||||
fp.write(ET.tostring(root))
|
||||
# xml core functionality does not support pretty printing
|
||||
# so the output file looks quite ugly
|
||||
|
||||
@@ -41,9 +41,9 @@ from .importToolsFem import get_MaxDimElementFromList
|
||||
|
||||
def write_fenics_mesh_xml(fem_mesh_obj, outputfile):
|
||||
"""
|
||||
For the export, we only have to use the highest dimensional entities and their
|
||||
vertices to be exported.
|
||||
For second order elements, we have to delete the mid element nodes.
|
||||
For the export, we only have to use the highest dimensional entities and their
|
||||
vertices to be exported.
|
||||
For second order elements, we have to delete the mid element nodes.
|
||||
"""
|
||||
|
||||
# TODO: check for second order elements
|
||||
@@ -57,9 +57,10 @@ def write_fenics_mesh_xml(fem_mesh_obj, outputfile):
|
||||
"Edge": "interval",
|
||||
"Node": "point",
|
||||
"Quadrangle": "quadrilateral",
|
||||
|
||||
"Polygon": "unknown", "Polyhedron": "unknown",
|
||||
"Prism": "unknown", "Pyramid": "unknown",
|
||||
"Polygon": "unknown",
|
||||
"Polyhedron": "unknown",
|
||||
"Prism": "unknown",
|
||||
"Pyramid": "unknown",
|
||||
}
|
||||
|
||||
XML_Number_of_Nodes_dict = {
|
||||
@@ -68,7 +69,7 @@ def write_fenics_mesh_xml(fem_mesh_obj, outputfile):
|
||||
"triangle": 3,
|
||||
"quadrilateral": 4,
|
||||
"tetrahedron": 4,
|
||||
"hexahedron": 8
|
||||
"hexahedron": 8,
|
||||
}
|
||||
|
||||
Console.PrintMessage(f"Converting {fem_mesh_obj.Label} to fenics XML File\n")
|
||||
@@ -80,18 +81,25 @@ def write_fenics_mesh_xml(fem_mesh_obj, outputfile):
|
||||
(num_cells, cellname_fc, dim_cell) = celltype_in_mesh
|
||||
cellname_fenics = FreeCAD_to_Fenics_dict[cellname_fc]
|
||||
num_verts_cell = XML_Number_of_Nodes_dict[cellname_fenics]
|
||||
Console.PrintMessage(f"Celltype in mesh -> {str(celltype_in_mesh)} " +
|
||||
f"and its Fenics name: {cellname_fenics}\n")
|
||||
Console.PrintMessage(
|
||||
f"Celltype in mesh -> {str(celltype_in_mesh)} "
|
||||
+ f"and its Fenics name: {cellname_fenics}\n"
|
||||
)
|
||||
|
||||
root = ET.Element("dolfin", dolfin="http://fenicsproject.org")
|
||||
meshchild = ET.SubElement(root, "mesh", celltype=cellname_fenics, dim=str(dim_cell))
|
||||
vertices = ET.SubElement(meshchild, "vertices", size=str(fem_mesh_obj.FemMesh.NodeCount))
|
||||
|
||||
for (nodeind, fc_vec) in list(fem_mesh_obj.FemMesh.Nodes.items()):
|
||||
for nodeind, fc_vec in list(fem_mesh_obj.FemMesh.Nodes.items()):
|
||||
ET.SubElement(
|
||||
vertices, "vertex", index=str(nodeind - 1),
|
||||
vertices,
|
||||
"vertex",
|
||||
index=str(nodeind - 1),
|
||||
# FC starts from 1, fenics starts from 0 to size-1
|
||||
x=str(fc_vec[0]), y=str(fc_vec[1]), z=str(fc_vec[2]))
|
||||
x=str(fc_vec[0]),
|
||||
y=str(fc_vec[1]),
|
||||
z=str(fc_vec[2]),
|
||||
)
|
||||
|
||||
cells = ET.SubElement(meshchild, "cells", size=str(num_cells))
|
||||
if dim_cell == 3:
|
||||
@@ -103,12 +111,12 @@ def write_fenics_mesh_xml(fem_mesh_obj, outputfile):
|
||||
else:
|
||||
fc_cells = ()
|
||||
|
||||
for (fen_ind, fc_volume_ind) in enumerate(fc_cells):
|
||||
for fen_ind, fc_volume_ind in enumerate(fc_cells):
|
||||
# FC starts after all other entities, fenics start from 0 to size-1
|
||||
nodeindices = fem_mesh_obj.FemMesh.getElementNodes(fc_volume_ind)
|
||||
|
||||
cell_args = {}
|
||||
for (vi, ni) in enumerate(nodeindices):
|
||||
for vi, ni in enumerate(nodeindices):
|
||||
if vi < num_verts_cell: # XML only supports first order meshs
|
||||
cell_args["v" + str(vi)] = str(ni - 1)
|
||||
# generate as many v entries in dict as nodes are listed in cell
|
||||
|
||||
@@ -36,6 +36,7 @@ import time
|
||||
|
||||
import FreeCAD
|
||||
import Fem
|
||||
|
||||
# import Mesh
|
||||
|
||||
|
||||
@@ -55,33 +56,26 @@ Mesh.show(Mesh.Mesh(out_mesh))
|
||||
# These dictionaries list the nodes, that define faces of an element.
|
||||
# The key is the face number, used internally by FreeCAD.
|
||||
# The list contains the nodes in the element for each face.
|
||||
tetFaces = {
|
||||
1: [0, 1, 2],
|
||||
2: [0, 3, 1],
|
||||
3: [1, 3, 2],
|
||||
4: [2, 3, 0]}
|
||||
tetFaces = {1: [0, 1, 2], 2: [0, 3, 1], 3: [1, 3, 2], 4: [2, 3, 0]}
|
||||
|
||||
pentaFaces = {
|
||||
1: [0, 1, 2],
|
||||
2: [3, 5, 4],
|
||||
3: [0, 3, 4, 1],
|
||||
4: [1, 4, 5, 2],
|
||||
5: [0, 2, 5, 3]}
|
||||
pentaFaces = {1: [0, 1, 2], 2: [3, 5, 4], 3: [0, 3, 4, 1], 4: [1, 4, 5, 2], 5: [0, 2, 5, 3]}
|
||||
|
||||
hexaFaces = { # hexa8 or hexa20 (ignoring mid-nodes)
|
||||
hexaFaces = { # hexa8 or hexa20 (ignoring mid-nodes)
|
||||
1: [0, 1, 2, 3],
|
||||
2: [4, 7, 6, 5],
|
||||
3: [0, 4, 5, 1],
|
||||
4: [1, 5, 6, 2],
|
||||
5: [2, 6, 7, 3],
|
||||
6: [3, 7, 4, 0]}
|
||||
6: [3, 7, 4, 0],
|
||||
}
|
||||
|
||||
pyraFaces = { # pyra5 or pyra13 (ignoring mid-nodes)
|
||||
pyraFaces = { # pyra5 or pyra13 (ignoring mid-nodes)
|
||||
1: [0, 1, 2, 3],
|
||||
2: [0, 4, 1],
|
||||
3: [1, 4, 2],
|
||||
4: [2, 4, 3],
|
||||
5: [3, 4, 0]}
|
||||
5: [3, 4, 0],
|
||||
}
|
||||
|
||||
face_dicts = {
|
||||
4: tetFaces,
|
||||
@@ -91,7 +85,8 @@ face_dicts = {
|
||||
10: tetFaces,
|
||||
13: pyraFaces,
|
||||
15: pentaFaces,
|
||||
20: hexaFaces}
|
||||
20: hexaFaces,
|
||||
}
|
||||
|
||||
|
||||
def femmesh_2_mesh(myFemMesh, myResults=None, myDispScale=1):
|
||||
@@ -120,7 +115,7 @@ def femmesh_2_mesh(myFemMesh, myResults=None, myDispScale=1):
|
||||
codeList.append(element_nodes[nodeIdx])
|
||||
codeList.sort()
|
||||
for node in codeList:
|
||||
faceCode += (node << shifter)
|
||||
faceCode += node << shifter
|
||||
# x << n: x shifted left by n bits = Multiplication
|
||||
shifter += shiftBits
|
||||
# print("codeList: ", codeList)
|
||||
@@ -142,7 +137,7 @@ def femmesh_2_mesh(myFemMesh, myResults=None, myDispScale=1):
|
||||
codeList.append(element_nodes[nodeIdx])
|
||||
codeList.sort()
|
||||
for node in codeList:
|
||||
faceCode += (node << shifter)
|
||||
faceCode += node << shifter
|
||||
# x << n: x shifted left by n bits = Multiplication
|
||||
shifter += shiftBits
|
||||
# print("codeList: ", codeList)
|
||||
@@ -164,83 +159,90 @@ def femmesh_2_mesh(myFemMesh, myResults=None, myDispScale=1):
|
||||
singleFaces.append(faceCodeList[actFaceIdx])
|
||||
actFaceIdx += 1
|
||||
else:
|
||||
FreeCAD.Console.PrintMessage("Found a last Face: {}\n".format(faceCodeList[actFaceIdx]))
|
||||
FreeCAD.Console.PrintMessage(f"Found a last Face: {faceCodeList[actFaceIdx]}\n")
|
||||
singleFaces.append(faceCodeList[actFaceIdx])
|
||||
actFaceIdx += 1
|
||||
|
||||
output_mesh = []
|
||||
if myResults:
|
||||
FreeCAD.Console.PrintMessage("{}\n".format(myResults.Name))
|
||||
FreeCAD.Console.PrintMessage(f"{myResults.Name}\n")
|
||||
for myFace in singleFaces:
|
||||
face_nodes = faceCodeDict[myFace]
|
||||
dispVec0 = myResults.DisplacementVectors[myResults.NodeNumbers.index(face_nodes[0])]
|
||||
dispVec1 = myResults.DisplacementVectors[myResults.NodeNumbers.index(face_nodes[1])]
|
||||
dispVec2 = myResults.DisplacementVectors[myResults.NodeNumbers.index(face_nodes[2])]
|
||||
triangle = [myFemMesh.getNodeById(face_nodes[0]) + dispVec0 * myDispScale,
|
||||
myFemMesh.getNodeById(face_nodes[1]) + dispVec1 * myDispScale,
|
||||
myFemMesh.getNodeById(face_nodes[2]) + dispVec2 * myDispScale]
|
||||
triangle = [
|
||||
myFemMesh.getNodeById(face_nodes[0]) + dispVec0 * myDispScale,
|
||||
myFemMesh.getNodeById(face_nodes[1]) + dispVec1 * myDispScale,
|
||||
myFemMesh.getNodeById(face_nodes[2]) + dispVec2 * myDispScale,
|
||||
]
|
||||
output_mesh.extend(triangle)
|
||||
# print("my triangle: ", triangle)
|
||||
if len(face_nodes) == 4:
|
||||
dispVec3 = myResults.DisplacementVectors[myResults.NodeNumbers.index(face_nodes[3])]
|
||||
triangle = [myFemMesh.getNodeById(face_nodes[2]) + dispVec2 * myDispScale,
|
||||
myFemMesh.getNodeById(face_nodes[3]) + dispVec3 * myDispScale,
|
||||
myFemMesh.getNodeById(face_nodes[0]) + dispVec0 * myDispScale]
|
||||
triangle = [
|
||||
myFemMesh.getNodeById(face_nodes[2]) + dispVec2 * myDispScale,
|
||||
myFemMesh.getNodeById(face_nodes[3]) + dispVec3 * myDispScale,
|
||||
myFemMesh.getNodeById(face_nodes[0]) + dispVec0 * myDispScale,
|
||||
]
|
||||
output_mesh.extend(triangle)
|
||||
# print("my 2. triangle: ", triangle)
|
||||
|
||||
else:
|
||||
for myFace in singleFaces:
|
||||
face_nodes = faceCodeDict[myFace]
|
||||
triangle = [myFemMesh.getNodeById(face_nodes[0]),
|
||||
myFemMesh.getNodeById(face_nodes[1]),
|
||||
myFemMesh.getNodeById(face_nodes[2])]
|
||||
triangle = [
|
||||
myFemMesh.getNodeById(face_nodes[0]),
|
||||
myFemMesh.getNodeById(face_nodes[1]),
|
||||
myFemMesh.getNodeById(face_nodes[2]),
|
||||
]
|
||||
output_mesh.extend(triangle)
|
||||
# print("my triangle: ", triangle)
|
||||
if len(face_nodes) == 4:
|
||||
triangle = [myFemMesh.getNodeById(face_nodes[2]),
|
||||
myFemMesh.getNodeById(face_nodes[3]),
|
||||
myFemMesh.getNodeById(face_nodes[0])]
|
||||
triangle = [
|
||||
myFemMesh.getNodeById(face_nodes[2]),
|
||||
myFemMesh.getNodeById(face_nodes[3]),
|
||||
myFemMesh.getNodeById(face_nodes[0]),
|
||||
]
|
||||
output_mesh.extend(triangle)
|
||||
# print("my 2. triangle: ", triangle)
|
||||
|
||||
end_time = time.process_time()
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"Mesh by surface search method: {}\n".format(end_time - start_time)
|
||||
)
|
||||
# call to mesh_2_femmesh to convert mesh to femmesh before return statement
|
||||
FreeCAD.Console.PrintMessage(f"Mesh by surface search method: {end_time - start_time}\n")
|
||||
# call to mesh_2_femmesh to convert mesh to femmesh before return statement
|
||||
mesh2femmesh = mesh_2_femmesh(myFemMesh, singleFaces, faceCodeDict)
|
||||
return output_mesh
|
||||
|
||||
|
||||
# additional function to convert mesh to femmesh
|
||||
def mesh_2_femmesh(myFemMesh, singleFaces, faceCodeDict):
|
||||
start_time = time.process_time()
|
||||
femmesh = Fem.FemMesh()
|
||||
myfemmesh = myFemMesh.Nodes
|
||||
# nodes contains the nodes that are used
|
||||
# nodes contains the nodes that are used
|
||||
nodes = {}
|
||||
for myFace in singleFaces:
|
||||
face_nodes = faceCodeDict[myFace]
|
||||
for j in (0, 1, 2):
|
||||
try:
|
||||
nodes[face_nodes[j]] += 1
|
||||
except:
|
||||
nodes[face_nodes[j]] = 0
|
||||
try:
|
||||
nodes[face_nodes[j]] += 1
|
||||
except:
|
||||
nodes[face_nodes[j]] = 0
|
||||
if len(face_nodes) == 4:
|
||||
j = 3
|
||||
try:
|
||||
nodes[face_nodes[j]] += 1
|
||||
except:
|
||||
nodes[face_nodes[j]] = 0
|
||||
j = 3
|
||||
try:
|
||||
nodes[face_nodes[j]] += 1
|
||||
except:
|
||||
nodes[face_nodes[j]] = 0
|
||||
sfNode = femmesh.addNode
|
||||
sfFace = femmesh.addFace
|
||||
for key in myFemMesh.Nodes:
|
||||
mynode = myfemmesh[key]
|
||||
try:
|
||||
if(nodes[key] >= 0):
|
||||
sfNode(mynode[0], mynode[1], mynode[2], key)
|
||||
if nodes[key] >= 0:
|
||||
sfNode(mynode[0], mynode[1], mynode[2], key)
|
||||
except:
|
||||
pass
|
||||
pass
|
||||
|
||||
output_mesh = []
|
||||
|
||||
@@ -248,13 +250,12 @@ def mesh_2_femmesh(myFemMesh, singleFaces, faceCodeDict):
|
||||
face_nodes = faceCodeDict[myFace]
|
||||
sfFace(face_nodes[0], face_nodes[1], face_nodes[2])
|
||||
if len(face_nodes) == 4:
|
||||
sfFace(face_nodes[2], face_nodes[3], face_nodes[0])
|
||||
obj = FreeCAD.ActiveDocument.addObject(
|
||||
"Fem::FemMeshObject", "Mesh2Fem")
|
||||
sfFace(face_nodes[2], face_nodes[3], face_nodes[0])
|
||||
obj = FreeCAD.ActiveDocument.addObject("Fem::FemMeshObject", "Mesh2Fem")
|
||||
obj.FemMesh = femmesh
|
||||
end_time = time.process_time()
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"Convert to FemMesh: {}\n".format(end_time - start_time)
|
||||
)
|
||||
FreeCAD.Console.PrintMessage(f"Convert to FemMesh: {end_time - start_time}\n")
|
||||
return obj
|
||||
|
||||
|
||||
# end of mesh_2_femmesh
|
||||
|
||||
@@ -44,7 +44,7 @@ class GmshError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class GmshTools():
|
||||
class GmshTools:
|
||||
def __init__(self, gmsh_mesh_obj, analysis=None):
|
||||
|
||||
# mesh obj
|
||||
@@ -62,7 +62,7 @@ class GmshTools():
|
||||
# clmax, CharacteristicLengthMax: float, 0.0 = 1e+22
|
||||
self.clmax = Units.Quantity(self.mesh_obj.CharacteristicLengthMax).Value
|
||||
if self.clmax == 0.0:
|
||||
self.clmax = 1e+22
|
||||
self.clmax = 1e22
|
||||
|
||||
# clmin, CharacteristicLengthMin: float
|
||||
self.clmin = Units.Quantity(self.mesh_obj.CharacteristicLengthMin).Value
|
||||
@@ -210,14 +210,14 @@ class GmshTools():
|
||||
|
||||
def start_logs(self):
|
||||
Console.PrintLog("\nGmsh FEM mesh run is being started.\n")
|
||||
Console.PrintLog(" Part to mesh: Name --> {}, Label --> {}, ShapeType --> {}\n".format(
|
||||
self.part_obj.Name,
|
||||
self.part_obj.Label,
|
||||
self.part_obj.Shape.ShapeType
|
||||
))
|
||||
Console.PrintLog(" CharacteristicLengthMax: {}\n".format(self.clmax))
|
||||
Console.PrintLog(" CharacteristicLengthMin: {}\n".format(self.clmin))
|
||||
Console.PrintLog(" ElementOrder: {}\n".format(self.order))
|
||||
Console.PrintLog(
|
||||
" Part to mesh: Name --> {}, Label --> {}, ShapeType --> {}\n".format(
|
||||
self.part_obj.Name, self.part_obj.Label, self.part_obj.Shape.ShapeType
|
||||
)
|
||||
)
|
||||
Console.PrintLog(f" CharacteristicLengthMax: {self.clmax}\n")
|
||||
Console.PrintLog(f" CharacteristicLengthMin: {self.clmin}\n")
|
||||
Console.PrintLog(f" ElementOrder: {self.order}\n")
|
||||
|
||||
def get_dimension(self):
|
||||
# Dimension
|
||||
@@ -269,36 +269,26 @@ class GmshTools():
|
||||
if femutils.check_working_dir(self.working_dir) is not True:
|
||||
if create is True:
|
||||
Console.PrintMessage(
|
||||
"Dir given as parameter \'{}\' doesn't exist, "
|
||||
"Dir given as parameter '{}' doesn't exist, "
|
||||
"but parameter to create it is set to True. "
|
||||
"Dir will be created.\n".format(self.working_dir)
|
||||
)
|
||||
os.mkdir(param_working_dir)
|
||||
else:
|
||||
Console.PrintError(
|
||||
"Dir given as parameter \'{}\' doesn't exist "
|
||||
"and create parameter is set to False.\n"
|
||||
.format(self.working_dir)
|
||||
"Dir given as parameter '{}' doesn't exist "
|
||||
"and create parameter is set to False.\n".format(self.working_dir)
|
||||
)
|
||||
self.working_dir = femutils.get_pref_working_dir(self.mesh_obj)
|
||||
Console.PrintMessage(
|
||||
"Dir \'{}\' will be used instead.\n"
|
||||
.format(self.working_dir)
|
||||
)
|
||||
Console.PrintMessage(f"Dir '{self.working_dir}' will be used instead.\n")
|
||||
else:
|
||||
self.working_dir = femutils.get_pref_working_dir(self.mesh_obj)
|
||||
|
||||
# check working_dir exist, if not use a tmp dir and inform the user
|
||||
if femutils.check_working_dir(self.working_dir) is not True:
|
||||
Console.PrintError(
|
||||
"Dir \'{}\' doesn't exist or cannot be created.\n"
|
||||
.format(self.working_dir)
|
||||
)
|
||||
Console.PrintError(f"Dir '{self.working_dir}' doesn't exist or cannot be created.\n")
|
||||
self.working_dir = femutils.get_temp_dir(self.mesh_obj)
|
||||
Console.PrintMessage(
|
||||
"Dir \'{}\' will be used instead.\n"
|
||||
.format(self.working_dir)
|
||||
)
|
||||
Console.PrintMessage(f"Dir '{self.working_dir}' will be used instead.\n")
|
||||
|
||||
# file paths
|
||||
_geometry_name = self.part_obj.Name + "_Geometry"
|
||||
@@ -315,15 +305,16 @@ class GmshTools():
|
||||
|
||||
def get_gmsh_command(self):
|
||||
from platform import system
|
||||
|
||||
gmsh_std_location = FreeCAD.ParamGet(
|
||||
"User parameter:BaseApp/Preferences/Mod/Fem/Gmsh"
|
||||
).GetBool("UseStandardGmshLocation")
|
||||
if gmsh_std_location:
|
||||
if system() == "Windows":
|
||||
gmsh_path = FreeCAD.getHomePath() + "bin/gmsh.exe"
|
||||
FreeCAD.ParamGet(
|
||||
"User parameter:BaseApp/Preferences/Mod/Fem/Gmsh"
|
||||
).SetString("gmshBinaryPath", gmsh_path)
|
||||
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Gmsh").SetString(
|
||||
"gmshBinaryPath", gmsh_path
|
||||
)
|
||||
self.gmsh_bin = gmsh_path
|
||||
elif system() == "Linux":
|
||||
p1 = subprocess.Popen(["which", "gmsh"], stdout=subprocess.PIPE)
|
||||
@@ -343,9 +334,9 @@ class GmshTools():
|
||||
elif system() == "Darwin":
|
||||
# https://forum.freecad.org/viewtopic.php?f=13&t=73041&p=642026#p642022
|
||||
gmsh_path = "/Applications/Gmsh.app/Contents/MacOS/gmsh"
|
||||
FreeCAD.ParamGet(
|
||||
"User parameter:BaseApp/Preferences/Mod/Fem/Gmsh"
|
||||
).SetString("gmshBinaryPath", gmsh_path)
|
||||
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Gmsh").SetString(
|
||||
"gmshBinaryPath", gmsh_path
|
||||
)
|
||||
self.gmsh_bin = gmsh_path
|
||||
else:
|
||||
error_message = (
|
||||
@@ -396,10 +387,7 @@ class GmshTools():
|
||||
"Are you really sure about this? You could run into trouble!\n"
|
||||
)
|
||||
self.group_nodes_export = True
|
||||
new_group_elements = meshtools.get_analysis_group_elements(
|
||||
self.analysis,
|
||||
self.part_obj
|
||||
)
|
||||
new_group_elements = meshtools.get_analysis_group_elements(self.analysis, self.part_obj)
|
||||
for ge in new_group_elements:
|
||||
if ge not in self.group_elements:
|
||||
self.group_elements[ge] = new_group_elements[ge]
|
||||
@@ -428,7 +416,7 @@ class GmshTools():
|
||||
shell=False,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
universal_newlines=True
|
||||
universal_newlines=True,
|
||||
)
|
||||
except Exception as e:
|
||||
Console.PrintMessage(str(e) + "\n")
|
||||
@@ -440,6 +428,7 @@ class GmshTools():
|
||||
Console.PrintError("Gmsh: StdErr:\n" + gmsh_stderr + "\n")
|
||||
|
||||
from re import search
|
||||
|
||||
# use raw string mode to get pep8 quiet
|
||||
# https://stackoverflow.com/q/61497292
|
||||
# https://github.com/MathSci/fecon236/issues/6
|
||||
@@ -465,7 +454,8 @@ class GmshTools():
|
||||
# https://forum.freecad.org/viewtopic.php?f=18&t=18780&p=149520#p149520
|
||||
part = self.part_obj
|
||||
if (
|
||||
self.mesh_obj.MeshRegionList and part.Shape.ShapeType == "Compound"
|
||||
self.mesh_obj.MeshRegionList
|
||||
and part.Shape.ShapeType == "Compound"
|
||||
and (
|
||||
femutils.is_of_type(part, "FeatureBooleanFragments")
|
||||
or femutils.is_of_type(part, "FeatureSlice")
|
||||
@@ -490,8 +480,7 @@ class GmshTools():
|
||||
" One element of the mesh refinement {} is "
|
||||
"not an element of the Part to mesh.\n"
|
||||
"But we are going to try to find it in "
|
||||
"the Shape to mesh :-)\n"
|
||||
.format(mr_obj.Name)
|
||||
"the Shape to mesh :-)\n".format(mr_obj.Name)
|
||||
)
|
||||
search_ele_in_shape_to_mesh = True
|
||||
for elems in sub[1]:
|
||||
@@ -510,8 +499,9 @@ class GmshTools():
|
||||
else:
|
||||
Console.PrintError(
|
||||
"One element of the meshregion {} could not be found "
|
||||
"in the Part to mesh. It will be ignored.\n"
|
||||
.format(mr_obj.Name)
|
||||
"in the Part to mesh. It will be ignored.\n".format(
|
||||
mr_obj.Name
|
||||
)
|
||||
)
|
||||
# print(elems) # element
|
||||
if elems not in self.ele_length_map:
|
||||
@@ -521,20 +511,19 @@ class GmshTools():
|
||||
else:
|
||||
Console.PrintError(
|
||||
"The element {} of the mesh refinement {} has "
|
||||
"been added to another mesh region.\n"
|
||||
.format(elems, mr_obj.Name)
|
||||
"been added to another mesh region.\n".format(
|
||||
elems, mr_obj.Name
|
||||
)
|
||||
)
|
||||
else:
|
||||
Console.PrintError(
|
||||
"The mesh refinement: {} is not used to create the mesh "
|
||||
"because the reference list is empty.\n"
|
||||
.format(mr_obj.Name)
|
||||
"because the reference list is empty.\n".format(mr_obj.Name)
|
||||
)
|
||||
else:
|
||||
Console.PrintError(
|
||||
"The mesh refinement: {} is not used to create the "
|
||||
"mesh because the CharacteristicLength is 0.0 mm.\n"
|
||||
.format(mr_obj.Name)
|
||||
"mesh because the CharacteristicLength is 0.0 mm.\n".format(mr_obj.Name)
|
||||
)
|
||||
for eleml in self.ele_length_map:
|
||||
# the method getElement(element) does not return Solid elements
|
||||
@@ -574,8 +563,7 @@ class GmshTools():
|
||||
" One element of the mesh boundary layer {} is "
|
||||
"not an element of the Part to mesh.\n"
|
||||
"But we are going to try to find it in "
|
||||
"the Shape to mesh :-)\n"
|
||||
.format(mr_obj.Name)
|
||||
"the Shape to mesh :-)\n".format(mr_obj.Name)
|
||||
)
|
||||
search_ele_in_shape_to_mesh = True
|
||||
for elems in sub[1]:
|
||||
@@ -586,8 +574,7 @@ class GmshTools():
|
||||
# the method getElement(element) does not return Solid elements
|
||||
ele_shape = geomtools.get_element(sub[0], elems)
|
||||
found_element = geomtools.find_element_in_shape(
|
||||
self.part_obj.Shape,
|
||||
ele_shape
|
||||
self.part_obj.Shape, ele_shape
|
||||
)
|
||||
if found_element: # also
|
||||
elems = found_element
|
||||
@@ -595,8 +582,7 @@ class GmshTools():
|
||||
Console.PrintError(
|
||||
"One element of the mesh boundary layer {} could "
|
||||
"not be found in the Part to mesh. "
|
||||
"It will be ignored.\n"
|
||||
.format(mr_obj.Name)
|
||||
"It will be ignored.\n".format(mr_obj.Name)
|
||||
)
|
||||
# print(elems) # element
|
||||
if elems not in self.bl_boundary_list:
|
||||
@@ -608,24 +594,28 @@ class GmshTools():
|
||||
Console.PrintError(
|
||||
"The element {} of the mesh boundary "
|
||||
"layer {} has been added "
|
||||
"to another mesh boundary layer.\n"
|
||||
.format(elems, mr_obj.Name)
|
||||
"to another mesh boundary layer.\n".format(
|
||||
elems, mr_obj.Name
|
||||
)
|
||||
)
|
||||
setting = {}
|
||||
setting["hwall_n"] = Units.Quantity(mr_obj.MinimumThickness).Value
|
||||
setting["ratio"] = mr_obj.GrowthRate
|
||||
setting["thickness"] = sum([
|
||||
setting["hwall_n"] * setting["ratio"] ** i for i in range(
|
||||
mr_obj.NumberOfLayers
|
||||
)
|
||||
])
|
||||
setting["thickness"] = sum(
|
||||
[
|
||||
setting["hwall_n"] * setting["ratio"] ** i
|
||||
for i in range(mr_obj.NumberOfLayers)
|
||||
]
|
||||
)
|
||||
# setting["hwall_n"] * 5 # tangential cell dimension
|
||||
setting["hwall_t"] = setting["thickness"]
|
||||
|
||||
# hfar: cell dimension outside boundary
|
||||
# should be set later if some character length is set
|
||||
if self.clmax > setting["thickness"] * 0.8 \
|
||||
and self.clmax < setting["thickness"] * 1.6:
|
||||
if (
|
||||
self.clmax > setting["thickness"] * 0.8
|
||||
and self.clmax < setting["thickness"] * 1.6
|
||||
):
|
||||
setting["hfar"] = self.clmax
|
||||
else:
|
||||
# set a value for safety, it may works as background mesh cell size
|
||||
@@ -644,16 +634,14 @@ class GmshTools():
|
||||
else:
|
||||
Console.PrintError(
|
||||
"The mesh boundary layer: {} is not used to create "
|
||||
"the mesh because the reference list is empty.\n"
|
||||
.format(mr_obj.Name)
|
||||
"the mesh because the reference list is empty.\n".format(mr_obj.Name)
|
||||
)
|
||||
else:
|
||||
Console.PrintError(
|
||||
"The mesh boundary layer: {} is not used to create "
|
||||
"the mesh because the min thickness is 0.0 mm.\n"
|
||||
.format(mr_obj.Name)
|
||||
"the mesh because the min thickness is 0.0 mm.\n".format(mr_obj.Name)
|
||||
)
|
||||
Console.PrintMessage(" {}\n".format(self.bl_setting_list))
|
||||
Console.PrintMessage(f" {self.bl_setting_list}\n")
|
||||
|
||||
def write_groups(self, geo):
|
||||
if self.group_elements:
|
||||
@@ -670,19 +658,19 @@ class GmshTools():
|
||||
if gdata[0].startswith("Solid"):
|
||||
physical_type = "Volume"
|
||||
for ele in gdata:
|
||||
ele_nr += (ele.lstrip("Solid") + ", ")
|
||||
ele_nr += ele.lstrip("Solid") + ", "
|
||||
elif gdata[0].startswith("Face"):
|
||||
physical_type = "Surface"
|
||||
for ele in gdata:
|
||||
ele_nr += (ele.lstrip("Face") + ", ")
|
||||
ele_nr += ele.lstrip("Face") + ", "
|
||||
elif gdata[0].startswith("Edge"):
|
||||
physical_type = "Line"
|
||||
for ele in gdata:
|
||||
ele_nr += (ele.lstrip("Edge") + ", ")
|
||||
ele_nr += ele.lstrip("Edge") + ", "
|
||||
elif gdata[0].startswith("Vertex"):
|
||||
physical_type = "Point"
|
||||
for ele in gdata:
|
||||
ele_nr += (ele.lstrip("Vertex") + ", ")
|
||||
ele_nr += ele.lstrip("Vertex") + ", "
|
||||
if ele_nr:
|
||||
ele_nr = ele_nr.rstrip(", ")
|
||||
# print(ele_nr)
|
||||
@@ -690,8 +678,9 @@ class GmshTools():
|
||||
curly_br_e = "}"
|
||||
# explicit use double quotes in geo file
|
||||
geo.write(
|
||||
'Physical {}("{}") = {}{}{};\n'
|
||||
.format(physical_type, group, curly_br_s, ele_nr, curly_br_e)
|
||||
'Physical {}("{}") = {}{}{};\n'.format(
|
||||
physical_type, group, curly_br_s, ele_nr, curly_br_e
|
||||
)
|
||||
)
|
||||
geo.write("\n")
|
||||
|
||||
@@ -706,7 +695,7 @@ class GmshTools():
|
||||
geo.write(prefix + " = BoundaryLayer;\n")
|
||||
for k in item:
|
||||
v = item[k]
|
||||
if k in set(["EdgesList", "FacesList"]):
|
||||
if k in {"EdgesList", "FacesList"}:
|
||||
# the element name of FreeCAD which starts
|
||||
# with 1 (example: "Face1"), same as Gmsh
|
||||
# el_id = int(el[4:]) # FIXME: strip `face` or `edge` prefix
|
||||
@@ -716,7 +705,7 @@ class GmshTools():
|
||||
else:
|
||||
line = prefix + "." + str(k) + " = " + str(v) + ";\n"
|
||||
geo.write(line)
|
||||
Console.PrintMessage("{}\n".format(line))
|
||||
Console.PrintMessage(f"{line}\n")
|
||||
geo.write("BoundaryLayer Field = " + str(field_number) + ";\n")
|
||||
geo.write("// end of this boundary layer setup \n")
|
||||
field_number += 1
|
||||
@@ -749,7 +738,7 @@ class GmshTools():
|
||||
|
||||
geo.write("// open brep geometry\n")
|
||||
# explicit use double quotes in geo file
|
||||
geo.write('Merge "{}";\n'.format(os.path.relpath(self.temp_file_geometry, temp_dir)))
|
||||
geo.write(f'Merge "{os.path.relpath(self.temp_file_geometry, temp_dir)}";\n')
|
||||
geo.write("\n")
|
||||
|
||||
# groups
|
||||
@@ -762,19 +751,15 @@ class GmshTools():
|
||||
# we need to add 1 for the index in Gmsh
|
||||
geo.write("// Characteristic Length according CharacteristicLengthMap\n")
|
||||
for e in self.ele_length_map:
|
||||
ele_nodes = (
|
||||
"".join((str(n + 1) + ", ") for n in self.ele_node_map[e])
|
||||
).rstrip(", ")
|
||||
ele_nodes = ("".join((str(n + 1) + ", ") for n in self.ele_node_map[e])).rstrip(
|
||||
", "
|
||||
)
|
||||
geo.write("// " + e + "\n")
|
||||
elestr1 = "{"
|
||||
elestr2 = "}"
|
||||
geo.write(
|
||||
"Characteristic Length {} {} {} = {};\n"
|
||||
.format(
|
||||
elestr1,
|
||||
ele_nodes,
|
||||
elestr2,
|
||||
self.ele_length_map[e]
|
||||
"Characteristic Length {} {} {} = {};\n".format(
|
||||
elestr1, ele_nodes, elestr2, self.ele_length_map[e]
|
||||
)
|
||||
)
|
||||
geo.write("\n")
|
||||
@@ -795,8 +780,9 @@ class GmshTools():
|
||||
if hasattr(self.mesh_obj, "MeshSizeFromCurvature"):
|
||||
geo.write(
|
||||
"Mesh.MeshSizeFromCurvature = {}"
|
||||
"; // number of elements per 2*pi radians, 0 to deactivate\n"
|
||||
.format(self.mesh_obj.MeshSizeFromCurvature)
|
||||
"; // number of elements per 2*pi radians, 0 to deactivate\n".format(
|
||||
self.mesh_obj.MeshSizeFromCurvature
|
||||
)
|
||||
)
|
||||
geo.write("\n")
|
||||
if hasattr(self.mesh_obj, "RecombineAll") and self.mesh_obj.RecombineAll is True:
|
||||
@@ -805,9 +791,8 @@ class GmshTools():
|
||||
if hasattr(self.mesh_obj, "Recombine3DAll") and self.mesh_obj.Recombine3DAll is True:
|
||||
geo.write("// recombination for volumes\n")
|
||||
geo.write("Mesh.Recombine3DAll = 1;\n")
|
||||
if (
|
||||
(hasattr(self.mesh_obj, "RecombineAll") and self.mesh_obj.RecombineAll is True)
|
||||
or (hasattr(self.mesh_obj, "Recombine3DAll") and self.mesh_obj.Recombine3DAll is True)
|
||||
if (hasattr(self.mesh_obj, "RecombineAll") and self.mesh_obj.RecombineAll is True) or (
|
||||
hasattr(self.mesh_obj, "Recombine3DAll") and self.mesh_obj.Recombine3DAll is True
|
||||
):
|
||||
geo.write("// recombination algorithm\n")
|
||||
geo.write("Mesh.RecombinationAlgorithm = " + self.RecombinationAlgorithm + ";\n")
|
||||
@@ -874,9 +859,11 @@ class GmshTools():
|
||||
geo.write("\n")
|
||||
|
||||
geo.write("// incomplete second order elements\n")
|
||||
if (self.SubdivisionAlgorithm == "1"
|
||||
or self.SubdivisionAlgorithm == "2"
|
||||
or self.mesh_obj.RecombineAll):
|
||||
if (
|
||||
self.SubdivisionAlgorithm == "1"
|
||||
or self.SubdivisionAlgorithm == "2"
|
||||
or self.mesh_obj.RecombineAll
|
||||
):
|
||||
sec_order_inc = "1"
|
||||
else:
|
||||
sec_order_inc = "0"
|
||||
@@ -889,8 +876,7 @@ class GmshTools():
|
||||
if hasattr(self.mesh_obj, "CoherenceMesh") and self.mesh_obj.CoherenceMesh is True:
|
||||
geo.write(
|
||||
"Geometry.Tolerance = {}; // set geometrical "
|
||||
"tolerance (also used for merging nodes)\n"
|
||||
.format(self.geotol)
|
||||
"tolerance (also used for merging nodes)\n".format(self.geotol)
|
||||
)
|
||||
geo.write("Mesh " + self.dimension + ";\n")
|
||||
geo.write("Coherence Mesh; // Remove duplicate vertices\n")
|
||||
@@ -906,11 +892,12 @@ class GmshTools():
|
||||
# belongs to Mesh.SaveAll but only needed if there are groups
|
||||
geo.write(
|
||||
"// Needed for Group meshing too, because "
|
||||
"for one material there is no group defined;\n")
|
||||
"for one material there is no group defined;\n"
|
||||
)
|
||||
geo.write("// Ignore Physical definitions and save all elements;\n")
|
||||
geo.write("Mesh.SaveAll = 1;\n")
|
||||
# explicit use double quotes in geo file
|
||||
geo.write('Save "{}";\n'.format(os.path.relpath(self.temp_file_mesh, temp_dir)))
|
||||
geo.write(f'Save "{os.path.relpath(self.temp_file_mesh, temp_dir)}";\n')
|
||||
geo.write("\n\n")
|
||||
|
||||
# some useful information
|
||||
@@ -935,10 +922,7 @@ class GmshTools():
|
||||
# print(command_list)
|
||||
try:
|
||||
p = subprocess.Popen(
|
||||
command_list,
|
||||
shell=False,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE
|
||||
command_list, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
output, error = p.communicate()
|
||||
error = error.decode("utf-8")
|
||||
@@ -950,7 +934,7 @@ class GmshTools():
|
||||
if os.path.exists(self.gmsh_bin):
|
||||
error = "Error executing: {}\n".format(" ".join(command_list))
|
||||
else:
|
||||
error = "Gmsh executable not found: {}\n".format(self.gmsh_bin)
|
||||
error = f"Gmsh executable not found: {self.gmsh_bin}\n"
|
||||
Console.PrintError(error)
|
||||
self.error = True
|
||||
|
||||
@@ -986,6 +970,7 @@ class GmshTools():
|
||||
)
|
||||
Console.PrintWarning(error_message + "\n")
|
||||
|
||||
|
||||
## @}
|
||||
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ from femmesh import meshtools
|
||||
from femtools.femutils import type_of_obj
|
||||
|
||||
|
||||
class MeshSetsGetter():
|
||||
class MeshSetsGetter:
|
||||
def __init__(
|
||||
self,
|
||||
analysis_obj,
|
||||
@@ -74,12 +74,9 @@ class MeshSetsGetter():
|
||||
)
|
||||
# ATM only used in meshtools.get_femelement_direction1D_set
|
||||
# TODO somehow this is not smart, pur mesh objects might be used often
|
||||
if (
|
||||
self.member.geos_beamsection
|
||||
and (
|
||||
type_of_obj(self.solver_obj) == "Fem::SolverCcxTools"
|
||||
or type_of_obj(self.solver_obj) == "Fem::SolverCalculix"
|
||||
)
|
||||
if self.member.geos_beamsection and (
|
||||
type_of_obj(self.solver_obj) == "Fem::SolverCcxTools"
|
||||
or type_of_obj(self.solver_obj) == "Fem::SolverCalculix"
|
||||
):
|
||||
FreeCAD.Console.PrintError(
|
||||
"The mesh does not know the geometry it is made from. "
|
||||
@@ -156,9 +153,7 @@ class MeshSetsGetter():
|
||||
self.get_constraints_heatflux_faces()
|
||||
|
||||
setstime = round((time.process_time() - time_start), 3)
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"Getting mesh data time: {} seconds.\n".format(setstime)
|
||||
)
|
||||
FreeCAD.Console.PrintMessage(f"Getting mesh data time: {setstime} seconds.\n")
|
||||
|
||||
# ********************************************************************************************
|
||||
# ********************************************************************************************
|
||||
@@ -170,27 +165,18 @@ class MeshSetsGetter():
|
||||
for femobj in self.member.cons_fixed:
|
||||
# femobj --> dict, FreeCAD document object is femobj["Object"]
|
||||
print_obj_info(femobj["Object"])
|
||||
femobj["Nodes"] = meshtools.get_femnodes_by_femobj_with_references(
|
||||
self.femmesh,
|
||||
femobj
|
||||
)
|
||||
femobj["Nodes"] = meshtools.get_femnodes_by_femobj_with_references(self.femmesh, femobj)
|
||||
# add nodes to constraint_conflict_nodes, needed by constraint plane rotation
|
||||
for node in femobj["Nodes"]:
|
||||
self.constraint_conflict_nodes.append(node)
|
||||
# if mixed mesh with solids the node set needs to be split
|
||||
# because solid nodes do not have rotational degree of freedom
|
||||
if (
|
||||
self.femmesh.Volumes
|
||||
and (
|
||||
len(self.member.geos_shellthickness) > 0
|
||||
or len(self.member.geos_beamsection) > 0
|
||||
)
|
||||
if self.femmesh.Volumes and (
|
||||
len(self.member.geos_shellthickness) > 0 or len(self.member.geos_beamsection) > 0
|
||||
):
|
||||
FreeCAD.Console.PrintMessage("We need to find the solid nodes.\n")
|
||||
if not self.femelement_volumes_table:
|
||||
self.femelement_volumes_table = meshtools.get_femelement_volumes_table(
|
||||
self.femmesh
|
||||
)
|
||||
self.femelement_volumes_table = meshtools.get_femelement_volumes_table(self.femmesh)
|
||||
for femobj in self.member.cons_fixed:
|
||||
# femobj --> dict, FreeCAD document object is femobj["Object"]
|
||||
nds_solid = []
|
||||
@@ -214,10 +200,7 @@ class MeshSetsGetter():
|
||||
for femobj in self.member.cons_rigidbody:
|
||||
# femobj --> dict, FreeCAD document object is femobj["Object"]
|
||||
print_obj_info(femobj["Object"])
|
||||
femobj["Nodes"] = meshtools.get_femnodes_by_femobj_with_references(
|
||||
self.femmesh,
|
||||
femobj
|
||||
)
|
||||
femobj["Nodes"] = meshtools.get_femnodes_by_femobj_with_references(self.femmesh, femobj)
|
||||
# add nodes to constraint_conflict_nodes, needed by constraint plane rotation
|
||||
for node in femobj["Nodes"]:
|
||||
self.constraint_conflict_nodes.append(node)
|
||||
@@ -229,10 +212,7 @@ class MeshSetsGetter():
|
||||
for femobj in self.member.cons_displacement:
|
||||
# femobj --> dict, FreeCAD document object is femobj["Object"]
|
||||
print_obj_info(femobj["Object"])
|
||||
femobj["Nodes"] = meshtools.get_femnodes_by_femobj_with_references(
|
||||
self.femmesh,
|
||||
femobj
|
||||
)
|
||||
femobj["Nodes"] = meshtools.get_femnodes_by_femobj_with_references(self.femmesh, femobj)
|
||||
# add nodes to constraint_conflict_nodes, needed by constraint plane rotation
|
||||
for node in femobj["Nodes"]:
|
||||
self.constraint_conflict_nodes.append(node)
|
||||
@@ -244,10 +224,7 @@ class MeshSetsGetter():
|
||||
for femobj in self.member.cons_planerotation:
|
||||
# femobj --> dict, FreeCAD document object is femobj["Object"]
|
||||
print_obj_info(femobj["Object"])
|
||||
femobj["Nodes"] = meshtools.get_femnodes_by_femobj_with_references(
|
||||
self.femmesh,
|
||||
femobj
|
||||
)
|
||||
femobj["Nodes"] = meshtools.get_femnodes_by_femobj_with_references(self.femmesh, femobj)
|
||||
|
||||
def get_constraints_transform_nodes(self):
|
||||
if not self.member.cons_transform:
|
||||
@@ -256,10 +233,7 @@ class MeshSetsGetter():
|
||||
for femobj in self.member.cons_transform:
|
||||
# femobj --> dict, FreeCAD document object is femobj["Object"]
|
||||
print_obj_info(femobj["Object"])
|
||||
femobj["Nodes"] = meshtools.get_femnodes_by_femobj_with_references(
|
||||
self.femmesh,
|
||||
femobj
|
||||
)
|
||||
femobj["Nodes"] = meshtools.get_femnodes_by_femobj_with_references(self.femmesh, femobj)
|
||||
|
||||
def get_constraints_temperature_nodes(self):
|
||||
if not self.member.cons_temperature:
|
||||
@@ -268,10 +242,7 @@ class MeshSetsGetter():
|
||||
for femobj in self.member.cons_temperature:
|
||||
# femobj --> dict, FreeCAD document object is femobj["Object"]
|
||||
print_obj_info(femobj["Object"])
|
||||
femobj["Nodes"] = meshtools.get_femnodes_by_femobj_with_references(
|
||||
self.femmesh,
|
||||
femobj
|
||||
)
|
||||
femobj["Nodes"] = meshtools.get_femnodes_by_femobj_with_references(self.femmesh, femobj)
|
||||
|
||||
def get_constraints_fluidsection_nodes(self):
|
||||
if not self.member.geos_fluidsection:
|
||||
@@ -280,10 +251,7 @@ class MeshSetsGetter():
|
||||
for femobj in self.member.geos_fluidsection:
|
||||
# femobj --> dict, FreeCAD document object is femobj["Object"]
|
||||
print_obj_info(femobj["Object"])
|
||||
femobj["Nodes"] = meshtools.get_femnodes_by_femobj_with_references(
|
||||
self.femmesh,
|
||||
femobj
|
||||
)
|
||||
femobj["Nodes"] = meshtools.get_femnodes_by_femobj_with_references(self.femmesh, femobj)
|
||||
|
||||
def get_constraints_force_nodeloads(self):
|
||||
if not self.member.cons_force:
|
||||
@@ -297,9 +265,11 @@ class MeshSetsGetter():
|
||||
" load on vertices --> The femelement_table "
|
||||
"and femnodes_mesh are not needed for node load calculation.\n"
|
||||
)
|
||||
elif femobj["RefShapeType"] == "Face" \
|
||||
and meshtools.is_solid_femmesh(self.femmesh) \
|
||||
and not meshtools.has_no_face_data(self.femmesh):
|
||||
elif (
|
||||
femobj["RefShapeType"] == "Face"
|
||||
and meshtools.is_solid_femmesh(self.femmesh)
|
||||
and not meshtools.has_no_face_data(self.femmesh)
|
||||
):
|
||||
FreeCAD.Console.PrintLog(
|
||||
" solid_mesh with face data --> The femelement_table is not "
|
||||
"needed but the femnodes_mesh is needed for node load calculation.\n"
|
||||
@@ -314,9 +284,7 @@ class MeshSetsGetter():
|
||||
if not self.femnodes_mesh:
|
||||
self.femnodes_mesh = self.femmesh.Nodes
|
||||
if not self.femelement_table:
|
||||
self.femelement_table = meshtools.get_femelement_table(
|
||||
self.femmesh
|
||||
)
|
||||
self.femelement_table = meshtools.get_femelement_table(self.femmesh)
|
||||
# get node loads
|
||||
FreeCAD.Console.PrintLog(
|
||||
" Finite element mesh nodes will be retrieved by searching "
|
||||
@@ -334,20 +302,15 @@ class MeshSetsGetter():
|
||||
FreeCAD.Console.PrintMessage(" Warning --> Force = 0\n")
|
||||
if femobj["RefShapeType"] == "Vertex": # point load on vertices
|
||||
femobj["NodeLoadTable"] = meshtools.get_force_obj_vertex_nodeload_table(
|
||||
self.femmesh,
|
||||
frc_obj
|
||||
self.femmesh, frc_obj
|
||||
)
|
||||
elif femobj["RefShapeType"] == "Edge": # line load on edges
|
||||
femobj["NodeLoadTable"] = meshtools.get_force_obj_edge_nodeload_table(
|
||||
self.femmesh,
|
||||
self.femelement_table,
|
||||
self.femnodes_mesh, frc_obj
|
||||
self.femmesh, self.femelement_table, self.femnodes_mesh, frc_obj
|
||||
)
|
||||
elif femobj["RefShapeType"] == "Face": # area load on faces
|
||||
femobj["NodeLoadTable"] = meshtools.get_force_obj_face_nodeload_table(
|
||||
self.femmesh,
|
||||
self.femelement_table,
|
||||
self.femnodes_mesh, frc_obj
|
||||
self.femmesh, self.femelement_table, self.femnodes_mesh, frc_obj
|
||||
)
|
||||
|
||||
# ********************************************************************************************
|
||||
@@ -377,17 +340,14 @@ class MeshSetsGetter():
|
||||
self.femelement_table = meshtools.get_femelement_table(self.femmesh)
|
||||
if not self.femnodes_ele_table:
|
||||
self.femnodes_ele_table = meshtools.get_femnodes_ele_table(
|
||||
self.femnodes_mesh,
|
||||
self.femelement_table
|
||||
self.femnodes_mesh, self.femelement_table
|
||||
)
|
||||
|
||||
for femobj in self.member.cons_pressure:
|
||||
# femobj --> dict, FreeCAD document object is femobj["Object"]
|
||||
print_obj_info(femobj["Object"])
|
||||
pressure_faces = meshtools.get_pressure_obj_faces(
|
||||
self.femmesh,
|
||||
self.femelement_table,
|
||||
self.femnodes_ele_table, femobj
|
||||
self.femmesh, self.femelement_table, self.femnodes_ele_table, femobj
|
||||
)
|
||||
# the data model is for compatibility reason with deprecated version
|
||||
# get_pressure_obj_faces_depreciated returns the face ids in a tuple per ref_shape
|
||||
@@ -406,17 +366,14 @@ class MeshSetsGetter():
|
||||
self.femelement_table = meshtools.get_femelement_table(self.femmesh)
|
||||
if not self.femnodes_ele_table:
|
||||
self.femnodes_ele_table = meshtools.get_femnodes_ele_table(
|
||||
self.femnodes_mesh,
|
||||
self.femelement_table
|
||||
self.femnodes_mesh, self.femelement_table
|
||||
)
|
||||
|
||||
for femobj in self.member.cons_contact:
|
||||
# femobj --> dict, FreeCAD document object is femobj["Object"]
|
||||
print_obj_info(femobj["Object"])
|
||||
contact_slave_faces, contact_master_faces = meshtools.get_contact_obj_faces(
|
||||
self.femmesh,
|
||||
self.femelement_table,
|
||||
self.femnodes_ele_table, femobj
|
||||
self.femmesh, self.femelement_table, self.femnodes_ele_table, femobj
|
||||
)
|
||||
# [ele_id, ele_face_id], [ele_id, ele_face_id], ...]
|
||||
# whereas the ele_face_id might be ccx specific
|
||||
@@ -441,17 +398,14 @@ class MeshSetsGetter():
|
||||
self.femelement_table = meshtools.get_femelement_table(self.femmesh)
|
||||
if not self.femnodes_ele_table:
|
||||
self.femnodes_ele_table = meshtools.get_femnodes_ele_table(
|
||||
self.femnodes_mesh,
|
||||
self.femelement_table
|
||||
self.femnodes_mesh, self.femelement_table
|
||||
)
|
||||
|
||||
for femobj in self.member.cons_tie:
|
||||
# femobj --> dict, FreeCAD document object is femobj["Object"]
|
||||
print_obj_info(femobj["Object"])
|
||||
slave_faces, master_faces = meshtools.get_tie_obj_faces(
|
||||
self.femmesh,
|
||||
self.femelement_table,
|
||||
self.femnodes_ele_table, femobj
|
||||
self.femmesh, self.femelement_table, self.femnodes_ele_table, femobj
|
||||
)
|
||||
# [ele_id, ele_face_id], [ele_id, ele_face_id], ...]
|
||||
# whereas the ele_face_id might be ccx specific
|
||||
@@ -471,8 +425,9 @@ class MeshSetsGetter():
|
||||
if len(sectionprint_obj.References) > 1:
|
||||
FreeCAD.Console.PrintError(
|
||||
"Only one reference shape allowed for a section print "
|
||||
"but {} found: {}\n"
|
||||
.format(len(sectionprint_obj.References), sectionprint_obj.References)
|
||||
"but {} found: {}\n".format(
|
||||
len(sectionprint_obj.References), sectionprint_obj.References
|
||||
)
|
||||
)
|
||||
for o, elem_tup in sectionprint_obj.References:
|
||||
for elem in elem_tup:
|
||||
@@ -485,22 +440,25 @@ class MeshSetsGetter():
|
||||
femobj["SectionPrintFaces"] = v
|
||||
# volume elements found
|
||||
FreeCAD.Console.PrintLog(
|
||||
"{}, surface {}, {} touching volume elements found\n"
|
||||
.format(sectionprint_obj.Label, sectionprint_obj.Name, len(v))
|
||||
"{}, surface {}, {} touching volume elements found\n".format(
|
||||
sectionprint_obj.Label, sectionprint_obj.Name, len(v)
|
||||
)
|
||||
)
|
||||
else:
|
||||
# no volume elements found, shell elements not allowed
|
||||
FreeCAD.Console.PrintError(
|
||||
"{}, surface {}, Error: "
|
||||
"No volume elements found!\n"
|
||||
.format(sectionprint_obj.Label, sectionprint_obj.Name)
|
||||
"No volume elements found!\n".format(
|
||||
sectionprint_obj.Label, sectionprint_obj.Name
|
||||
)
|
||||
)
|
||||
else:
|
||||
# in Gui only Faces can be added
|
||||
FreeCAD.Console.PrintError(
|
||||
"Wrong reference shape type for {} "
|
||||
"Only Faces are allowed, but a {} was found.\n"
|
||||
.format(sectionprint_obj.Name, ref_shape.ShapeType)
|
||||
"Only Faces are allowed, but a {} was found.\n".format(
|
||||
sectionprint_obj.Name, ref_shape.ShapeType
|
||||
)
|
||||
)
|
||||
|
||||
def get_constraints_heatflux_faces(self):
|
||||
@@ -522,7 +480,7 @@ class MeshSetsGetter():
|
||||
for elem in elem_tup:
|
||||
ho = o.Shape.getElement(elem)
|
||||
if ho.ShapeType == "Face":
|
||||
elem_info = "{}:{}".format(o.Name, elem)
|
||||
elem_info = f"{o.Name}:{elem}"
|
||||
face_table = self.mesh_object.FemMesh.getccxVolumesByFace(ho)
|
||||
femobj["HeatFluxFaceTable"].append((elem_info, face_table))
|
||||
|
||||
@@ -560,10 +518,7 @@ class MeshSetsGetter():
|
||||
# get element ids and write them into the femobj
|
||||
all_found = False
|
||||
if self.femmesh.GroupCount:
|
||||
all_found = meshtools.get_femelement_sets_from_group_data(
|
||||
self.femmesh,
|
||||
femobjs
|
||||
)
|
||||
all_found = meshtools.get_femelement_sets_from_group_data(self.femmesh, femobjs)
|
||||
FreeCAD.Console.PrintMessage(all_found)
|
||||
FreeCAD.Console.PrintMessage("\n")
|
||||
if all_found is False:
|
||||
@@ -575,14 +530,10 @@ class MeshSetsGetter():
|
||||
self.femnodes_mesh = self.femmesh.Nodes
|
||||
if not self.femnodes_ele_table:
|
||||
self.femnodes_ele_table = meshtools.get_femnodes_ele_table(
|
||||
self.femnodes_mesh,
|
||||
self.femelement_table
|
||||
self.femnodes_mesh, self.femelement_table
|
||||
)
|
||||
control = meshtools.get_femelement_sets(
|
||||
self.femmesh,
|
||||
self.femelement_table,
|
||||
femobjs,
|
||||
self.femnodes_ele_table
|
||||
self.femmesh, self.femelement_table, femobjs, self.femnodes_ele_table
|
||||
)
|
||||
# we only need to set it, if it is still True
|
||||
if (self.femelement_count_test is True) and (control is False):
|
||||
@@ -592,26 +543,18 @@ class MeshSetsGetter():
|
||||
# get element ids and write them into the objects
|
||||
FreeCAD.Console.PrintMessage("Shell thicknesses\n")
|
||||
if not self.femelement_faces_table:
|
||||
self.femelement_faces_table = meshtools.get_femelement_faces_table(
|
||||
self.femmesh
|
||||
)
|
||||
self.femelement_faces_table = meshtools.get_femelement_faces_table(self.femmesh)
|
||||
meshtools.get_femelement_sets(
|
||||
self.femmesh,
|
||||
self.femelement_faces_table,
|
||||
self.member.geos_shellthickness
|
||||
self.femmesh, self.femelement_faces_table, self.member.geos_shellthickness
|
||||
)
|
||||
|
||||
def get_element_geometry1D_elements(self):
|
||||
# get element ids and write them into the objects
|
||||
FreeCAD.Console.PrintMessage("Beam sections\n")
|
||||
if not self.femelement_edges_table:
|
||||
self.femelement_edges_table = meshtools.get_femelement_edges_table(
|
||||
self.femmesh
|
||||
)
|
||||
self.femelement_edges_table = meshtools.get_femelement_edges_table(self.femmesh)
|
||||
meshtools.get_femelement_sets(
|
||||
self.femmesh,
|
||||
self.femelement_edges_table,
|
||||
self.member.geos_beamsection
|
||||
self.femmesh, self.femelement_edges_table, self.member.geos_beamsection
|
||||
)
|
||||
|
||||
def get_element_rotation1D_elements(self):
|
||||
@@ -624,27 +567,18 @@ class MeshSetsGetter():
|
||||
)
|
||||
return
|
||||
if not self.femelement_edges_table:
|
||||
self.femelement_edges_table = meshtools.get_femelement_edges_table(
|
||||
self.femmesh
|
||||
)
|
||||
self.femelement_edges_table = meshtools.get_femelement_edges_table(self.femmesh)
|
||||
meshtools.get_femelement_direction1D_set(
|
||||
self.femmesh,
|
||||
self.femelement_edges_table,
|
||||
self.member.geos_beamrotation,
|
||||
self.theshape
|
||||
self.femmesh, self.femelement_edges_table, self.member.geos_beamrotation, self.theshape
|
||||
)
|
||||
|
||||
def get_element_fluid1D_elements(self):
|
||||
# get element ids and write them into the objects
|
||||
FreeCAD.Console.PrintMessage("Fluid sections\n")
|
||||
if not self.femelement_edges_table:
|
||||
self.femelement_edges_table = meshtools.get_femelement_edges_table(
|
||||
self.femmesh
|
||||
)
|
||||
self.femelement_edges_table = meshtools.get_femelement_edges_table(self.femmesh)
|
||||
meshtools.get_femelement_sets(
|
||||
self.femmesh,
|
||||
self.femelement_edges_table,
|
||||
self.member.geos_fluidsection
|
||||
self.femmesh, self.femelement_edges_table, self.member.geos_fluidsection
|
||||
)
|
||||
|
||||
def get_material_elements(self):
|
||||
@@ -665,23 +599,15 @@ class MeshSetsGetter():
|
||||
self.get_solid_element_sets(self.member.mats_linear)
|
||||
if self.member.geos_shellthickness:
|
||||
if not self.femelement_faces_table:
|
||||
self.femelement_faces_table = meshtools.get_femelement_faces_table(
|
||||
self.femmesh
|
||||
)
|
||||
self.femelement_faces_table = meshtools.get_femelement_faces_table(self.femmesh)
|
||||
meshtools.get_femelement_sets(
|
||||
self.femmesh,
|
||||
self.femelement_faces_table,
|
||||
self.member.mats_linear
|
||||
self.femmesh, self.femelement_faces_table, self.member.mats_linear
|
||||
)
|
||||
if self.member.geos_beamsection or self.member.geos_fluidsection:
|
||||
if not self.femelement_edges_table:
|
||||
self.femelement_edges_table = meshtools.get_femelement_edges_table(
|
||||
self.femmesh
|
||||
)
|
||||
self.femelement_edges_table = meshtools.get_femelement_edges_table(self.femmesh)
|
||||
meshtools.get_femelement_sets(
|
||||
self.femmesh,
|
||||
self.femelement_edges_table,
|
||||
self.member.mats_linear
|
||||
self.femmesh, self.femelement_edges_table, self.member.mats_linear
|
||||
)
|
||||
|
||||
def get_element_sets_material_and_femelement_geometry(self):
|
||||
@@ -777,7 +703,7 @@ class MeshSetsGetter():
|
||||
{"short": "M0"},
|
||||
{"short": "B0"},
|
||||
{"short": beamrot_data["ShortName"]},
|
||||
{"short": "D" + str(i)}
|
||||
{"short": "D" + str(i)},
|
||||
]
|
||||
matgeoset = {}
|
||||
matgeoset["ccx_elset"] = elset_data
|
||||
@@ -804,7 +730,7 @@ class MeshSetsGetter():
|
||||
{"short": "M0"},
|
||||
{"short": beamsec_data["ShortName"]},
|
||||
{"short": beamrot_data["ShortName"]},
|
||||
{"short": "D" + str(i)}
|
||||
{"short": "D" + str(i)},
|
||||
]
|
||||
matgeoset = {}
|
||||
matgeoset["ccx_elset"] = elset_data
|
||||
@@ -830,7 +756,7 @@ class MeshSetsGetter():
|
||||
{"short": mat_data["ShortName"]},
|
||||
{"short": "B0"},
|
||||
{"short": beamrot_data["ShortName"]},
|
||||
{"short": "D" + str(i)}
|
||||
{"short": "D" + str(i)},
|
||||
]
|
||||
matgeoset = {}
|
||||
matgeoset["ccx_elset"] = elset_data
|
||||
@@ -853,15 +779,15 @@ class MeshSetsGetter():
|
||||
for i, beamdirection in enumerate(beamrot_data["FEMRotations1D"]):
|
||||
beamdir_ids = set(beamdirection["ids"])
|
||||
# empty intersection sets possible
|
||||
elset_data = list(sorted(
|
||||
beamsec_ids.intersection(mat_ids).intersection(beamdir_ids)
|
||||
))
|
||||
elset_data = list(
|
||||
sorted(beamsec_ids.intersection(mat_ids).intersection(beamdir_ids))
|
||||
)
|
||||
if elset_data:
|
||||
names = [
|
||||
{"short": mat_data["ShortName"]},
|
||||
{"short": beamsec_data["ShortName"]},
|
||||
{"short": beamrot_data["ShortName"]},
|
||||
{"short": "D" + str(i)}
|
||||
{"short": "D" + str(i)},
|
||||
]
|
||||
matgeoset = {}
|
||||
matgeoset["ccx_elset"] = elset_data
|
||||
@@ -927,7 +853,7 @@ class MeshSetsGetter():
|
||||
if elset_data:
|
||||
names = [
|
||||
{"short": mat_data["ShortName"]},
|
||||
{"short": fluidsec_data["ShortName"]}
|
||||
{"short": fluidsec_data["ShortName"]},
|
||||
]
|
||||
matgeoset = {}
|
||||
matgeoset["ccx_elset"] = elset_data
|
||||
@@ -942,10 +868,7 @@ class MeshSetsGetter():
|
||||
mat_obj = self.member.mats_linear[0]["Object"]
|
||||
shellth_obj = self.member.geos_shellthickness[0]["Object"]
|
||||
elset_data = self.ccx_efaces
|
||||
names = [
|
||||
{"long": mat_obj.Name, "short": "M0"},
|
||||
{"long": shellth_obj.Name, "short": "S0"}
|
||||
]
|
||||
names = [{"long": mat_obj.Name, "short": "M0"}, {"long": shellth_obj.Name, "short": "S0"}]
|
||||
matgeoset = {}
|
||||
matgeoset["ccx_elset"] = elset_data
|
||||
matgeoset["ccx_elset_name"] = get_elset_name_standard(names)
|
||||
@@ -961,7 +884,7 @@ class MeshSetsGetter():
|
||||
elset_data = shellth_data["FEMElements"]
|
||||
names = [
|
||||
{"long": mat_obj.Name, "short": "M0"},
|
||||
{"long": shellth_obj.Name, "short": shellth_data["ShortName"]}
|
||||
{"long": shellth_obj.Name, "short": shellth_data["ShortName"]},
|
||||
]
|
||||
matgeoset = {}
|
||||
matgeoset["ccx_elset"] = elset_data
|
||||
@@ -978,7 +901,7 @@ class MeshSetsGetter():
|
||||
elset_data = mat_data["FEMElements"]
|
||||
names = [
|
||||
{"long": mat_obj.Name, "short": mat_data["ShortName"]},
|
||||
{"long": shellth_obj.Name, "short": "S0"}
|
||||
{"long": shellth_obj.Name, "short": "S0"},
|
||||
]
|
||||
matgeoset = {}
|
||||
matgeoset["ccx_elset"] = elset_data
|
||||
@@ -1000,7 +923,7 @@ class MeshSetsGetter():
|
||||
if elset_data:
|
||||
names = [
|
||||
{"long": mat_obj.Name, "short": mat_data["ShortName"]},
|
||||
{"long": shellth_obj.Name, "short": shellth_data["ShortName"]}
|
||||
{"long": shellth_obj.Name, "short": shellth_data["ShortName"]},
|
||||
]
|
||||
matgeoset = {}
|
||||
matgeoset["ccx_elset"] = elset_data
|
||||
@@ -1014,10 +937,7 @@ class MeshSetsGetter():
|
||||
def get_mat_geo_sets_single_mat_solid(self):
|
||||
mat_obj = self.member.mats_linear[0]["Object"]
|
||||
elset_data = self.ccx_evolumes
|
||||
names = [
|
||||
{"long": mat_obj.Name, "short": "M0"},
|
||||
{"long": "Solid", "short": "Solid"}
|
||||
]
|
||||
names = [{"long": mat_obj.Name, "short": "M0"}, {"long": "Solid", "short": "Solid"}]
|
||||
matgeoset = {}
|
||||
matgeoset["ccx_elset"] = elset_data
|
||||
matgeoset["ccx_elset_name"] = get_elset_name_standard(names)
|
||||
@@ -1032,7 +952,7 @@ class MeshSetsGetter():
|
||||
elset_data = mat_data["FEMElements"]
|
||||
names = [
|
||||
{"long": mat_obj.Name, "short": mat_data["ShortName"]},
|
||||
{"long": "Solid", "short": "Solid"}
|
||||
{"long": "Solid", "short": "Solid"},
|
||||
]
|
||||
matgeoset = {}
|
||||
matgeoset["ccx_elset"] = elset_data
|
||||
@@ -1072,8 +992,7 @@ def get_elset_name_standard(names):
|
||||
else:
|
||||
error = (
|
||||
"FEM: Trouble in elset name, because an "
|
||||
"elset name is longer than 80 character! {}\n"
|
||||
.format(elset_name)
|
||||
"elset name is longer than 80 character! {}\n".format(elset_name)
|
||||
)
|
||||
raise Exception(error)
|
||||
|
||||
@@ -1089,22 +1008,18 @@ def get_elset_name_short(names):
|
||||
else:
|
||||
error = (
|
||||
"FEM: Trouble in elset name, because an"
|
||||
"short elset name is longer than 20 characters! {}\n"
|
||||
.format(elset_name)
|
||||
"short elset name is longer than 20 characters! {}\n".format(elset_name)
|
||||
)
|
||||
raise Exception(error)
|
||||
|
||||
|
||||
def print_obj_info(obj, log=False):
|
||||
if log is False:
|
||||
FreeCAD.Console.PrintMessage("{}:\n".format(obj.Label))
|
||||
FreeCAD.Console.PrintMessage(
|
||||
" Type: {}, Name: {}\n".format(type_of_obj(obj), obj.Name)
|
||||
)
|
||||
FreeCAD.Console.PrintMessage(f"{obj.Label}:\n")
|
||||
FreeCAD.Console.PrintMessage(f" Type: {type_of_obj(obj)}, Name: {obj.Name}\n")
|
||||
else:
|
||||
FreeCAD.Console.PrintLog("{}:\n".format(obj.Label))
|
||||
FreeCAD.Console.PrintLog(
|
||||
" Type: {}, Name: {}\n".format(type_of_obj(obj), obj.Name)
|
||||
)
|
||||
FreeCAD.Console.PrintLog(f"{obj.Label}:\n")
|
||||
FreeCAD.Console.PrintLog(f" Type: {type_of_obj(obj)}, Name: {obj.Name}\n")
|
||||
|
||||
|
||||
## @}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#/***************************************************************************
|
||||
# /***************************************************************************
|
||||
# * Copyright (c) 2024 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
|
||||
# * *
|
||||
# * This file is part of FreeCAD. *
|
||||
@@ -34,6 +34,7 @@ from . import base_fempythonobject
|
||||
|
||||
_PropHelper = base_fempythonobject._PropHelper
|
||||
|
||||
|
||||
class BaseFemElement(base_fempythonobject.BaseFemPythonObject):
|
||||
|
||||
BaseType = "Fem::BaseFemElement"
|
||||
@@ -44,16 +45,16 @@ class BaseFemElement(base_fempythonobject.BaseFemPythonObject):
|
||||
for prop in self._get_properties():
|
||||
prop.add_to_object(obj)
|
||||
|
||||
|
||||
def _get_properties(self):
|
||||
prop = []
|
||||
|
||||
prop.append(_PropHelper(
|
||||
type = "App::PropertyLinkSubList",
|
||||
name = "References",
|
||||
group = "Element",
|
||||
doc = "List of element shapes",
|
||||
value = []
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyLinkSubList",
|
||||
name="References",
|
||||
group="Element",
|
||||
doc="List of element shapes",
|
||||
value=[],
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#/***************************************************************************
|
||||
# /***************************************************************************
|
||||
# * Copyright (c) 2024 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
|
||||
# * *
|
||||
# * This file is part of FreeCAD. *
|
||||
@@ -34,6 +34,7 @@ from . import base_fempythonobject
|
||||
|
||||
_PropHelper = base_fempythonobject._PropHelper
|
||||
|
||||
|
||||
class BaseFemMeshElement(base_fempythonobject.BaseFemPythonObject):
|
||||
|
||||
BaseType = "Fem::BaseFemMeshElement"
|
||||
@@ -44,16 +45,16 @@ class BaseFemMeshElement(base_fempythonobject.BaseFemPythonObject):
|
||||
for prop in self._get_properties():
|
||||
prop.add_to_object(obj)
|
||||
|
||||
|
||||
def _get_properties(self):
|
||||
prop = []
|
||||
|
||||
prop.append(_PropHelper(
|
||||
type = "App::PropertyLinkSubList",
|
||||
name = "References",
|
||||
group = "Mesh Element",
|
||||
doc = "List of reference shapes",
|
||||
value = []
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyLinkSubList",
|
||||
name="References",
|
||||
group="Mesh Element",
|
||||
doc="List of reference shapes",
|
||||
value=[],
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ __url__ = "https://www.freecad.org"
|
||||
# \brief base object for FEM Python Features
|
||||
|
||||
|
||||
class BaseFemPythonObject(object):
|
||||
class BaseFemPythonObject:
|
||||
|
||||
BaseType = "Fem::BaseFemPythonObject"
|
||||
|
||||
@@ -55,6 +55,7 @@ class _PropHelper:
|
||||
Initialization keywords are the same used with PropertyContainer
|
||||
to add dynamics properties plus "value" for the initial value.
|
||||
"""
|
||||
|
||||
def __init__(self, **kwds):
|
||||
self.value = kwds.pop("value")
|
||||
self.info = kwds
|
||||
|
||||
@@ -40,12 +40,12 @@ class ConstantVacuumPermittivity(base_fempythonobject.BaseFemPythonObject):
|
||||
Type = "Fem::ConstantVacuumPermittivity"
|
||||
|
||||
def __init__(self, obj):
|
||||
super(ConstantVacuumPermittivity, self).__init__(obj)
|
||||
super().__init__(obj)
|
||||
obj.addProperty(
|
||||
"App::PropertyVacuumPermittivity",
|
||||
"VacuumPermittivity",
|
||||
"Constants",
|
||||
"Overwrites default permittivity of vacuum"
|
||||
"Overwrites default permittivity of vacuum",
|
||||
)
|
||||
obj.setPropertyStatus("VacuumPermittivity", "LockDynamic")
|
||||
# we must set an expression so that the small value can actually be entered
|
||||
|
||||
@@ -43,43 +43,44 @@ class ConstraintBodyHeatSource(base_fempythonobject.BaseFemPythonObject):
|
||||
Type = "Fem::ConstraintBodyHeatSource"
|
||||
|
||||
def __init__(self, obj):
|
||||
super(ConstraintBodyHeatSource, self).__init__(obj)
|
||||
super().__init__(obj)
|
||||
|
||||
for prop in self._get_properties():
|
||||
prop.add_to_object(obj)
|
||||
|
||||
|
||||
def _get_properties(self):
|
||||
prop = []
|
||||
|
||||
prop.append(_PropHelper(
|
||||
type = "App::PropertyDissipationRate",
|
||||
name = "DissipationRate",
|
||||
group = "Constraint Body Heat Source",
|
||||
doc = "Power dissipated per unit mass",
|
||||
value = "0 W/kg"
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyDissipationRate",
|
||||
name="DissipationRate",
|
||||
group="Constraint Body Heat Source",
|
||||
doc="Power dissipated per unit mass",
|
||||
value="0 W/kg",
|
||||
)
|
||||
)
|
||||
prop.append(_PropHelper(
|
||||
type = "App::PropertyPower",
|
||||
name = "TotalPower",
|
||||
group = "Constraint Body Heat Source",
|
||||
doc = "Total power dissipated",
|
||||
value = "0 W"
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyPower",
|
||||
name="TotalPower",
|
||||
group="Constraint Body Heat Source",
|
||||
doc="Total power dissipated",
|
||||
value="0 W",
|
||||
)
|
||||
)
|
||||
prop.append(_PropHelper(
|
||||
type = "App::PropertyEnumeration",
|
||||
name = "Mode",
|
||||
group = "Constraint Body Heat Source",
|
||||
doc = "Switch quantity input mode",
|
||||
value = ["Dissipation Rate", "Total Power"]
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="Mode",
|
||||
group="Constraint Body Heat Source",
|
||||
doc="Switch quantity input mode",
|
||||
value=["Dissipation Rate", "Total Power"],
|
||||
)
|
||||
)
|
||||
|
||||
return prop
|
||||
|
||||
|
||||
def onDocumentRestored(self, obj):
|
||||
# update old project with new properties
|
||||
for prop in self._get_properties():
|
||||
|
||||
@@ -40,13 +40,13 @@ class ConstraintCentrif(base_fempythonobject.BaseFemPythonObject):
|
||||
Type = "Fem::ConstraintCentrif"
|
||||
|
||||
def __init__(self, obj):
|
||||
super(ConstraintCentrif, self).__init__(obj)
|
||||
super().__init__(obj)
|
||||
|
||||
obj.addProperty(
|
||||
"App::PropertyFrequency",
|
||||
"RotationFrequency",
|
||||
"Constraint CENTRIF",
|
||||
"set rotation frequency f<sub>rot"
|
||||
"set rotation frequency f<sub>rot",
|
||||
)
|
||||
obj.setPropertyStatus("RotationFrequency", "LockDynamic")
|
||||
|
||||
@@ -54,6 +54,6 @@ class ConstraintCentrif(base_fempythonobject.BaseFemPythonObject):
|
||||
"App::PropertyLinkSubList",
|
||||
"RotationAxis",
|
||||
"Constraint CENTRIF",
|
||||
"set line as axis of rotation"
|
||||
"set line as axis of rotation",
|
||||
)
|
||||
obj.setPropertyStatus("RotationAxis", "LockDynamic")
|
||||
|
||||
@@ -37,7 +37,7 @@ class ConstraintCurrentDensity(base_fempythonobject.BaseFemPythonObject):
|
||||
Type = "Fem::ConstraintCurrentDensity"
|
||||
|
||||
def __init__(self, obj):
|
||||
super(ConstraintCurrentDensity, self).__init__(obj)
|
||||
super().__init__(obj)
|
||||
self.add_properties(obj)
|
||||
|
||||
def onDocumentRestored(self, obj):
|
||||
@@ -49,7 +49,7 @@ class ConstraintCurrentDensity(base_fempythonobject.BaseFemPythonObject):
|
||||
"App::PropertyCurrentDensity",
|
||||
"CurrentDensity_re_1",
|
||||
"Vector Potential",
|
||||
"Real part of current density x-component"
|
||||
"Real part of current density x-component",
|
||||
)
|
||||
obj.setPropertyStatus("CurrentDensity_re_1", "LockDynamic")
|
||||
obj.CurrentDensity_re_1 = "0 A/m^2"
|
||||
@@ -58,7 +58,7 @@ class ConstraintCurrentDensity(base_fempythonobject.BaseFemPythonObject):
|
||||
"App::PropertyCurrentDensity",
|
||||
"CurrentDensity_re_2",
|
||||
"Vector Potential",
|
||||
"Real part of current density y-component"
|
||||
"Real part of current density y-component",
|
||||
)
|
||||
obj.setPropertyStatus("CurrentDensity_re_2", "LockDynamic")
|
||||
obj.CurrentDensity_re_2 = "0 A/m^2"
|
||||
@@ -67,7 +67,7 @@ class ConstraintCurrentDensity(base_fempythonobject.BaseFemPythonObject):
|
||||
"App::PropertyCurrentDensity",
|
||||
"CurrentDensity_re_3",
|
||||
"Vector Potential",
|
||||
"Real part of current density z-component"
|
||||
"Real part of current density z-component",
|
||||
)
|
||||
obj.setPropertyStatus("CurrentDensity_re_3", "LockDynamic")
|
||||
obj.CurrentDensity_re_3 = "0 A/m^2"
|
||||
@@ -76,7 +76,7 @@ class ConstraintCurrentDensity(base_fempythonobject.BaseFemPythonObject):
|
||||
"App::PropertyCurrentDensity",
|
||||
"CurrentDensity_im_1",
|
||||
"Vector Potential",
|
||||
"Imaginary part of current density x-component"
|
||||
"Imaginary part of current density x-component",
|
||||
)
|
||||
obj.setPropertyStatus("CurrentDensity_im_1", "LockDynamic")
|
||||
obj.CurrentDensity_im_1 = "0 A/m^2"
|
||||
@@ -85,7 +85,7 @@ class ConstraintCurrentDensity(base_fempythonobject.BaseFemPythonObject):
|
||||
"App::PropertyCurrentDensity",
|
||||
"CurrentDensity_im_2",
|
||||
"Vector Potential",
|
||||
"Imaginary part of current density y-component"
|
||||
"Imaginary part of current density y-component",
|
||||
)
|
||||
obj.setPropertyStatus("CurrentDensity_im_2", "LockDynamic")
|
||||
obj.CurrentDensity_im_2 = "0 A/m^2"
|
||||
@@ -94,7 +94,7 @@ class ConstraintCurrentDensity(base_fempythonobject.BaseFemPythonObject):
|
||||
"App::PropertyCurrentDensity",
|
||||
"CurrentDensity_im_3",
|
||||
"Vector Potential",
|
||||
"Imaginary part of current density z-component"
|
||||
"Imaginary part of current density z-component",
|
||||
)
|
||||
obj.setPropertyStatus("CurrentDensity_im_3", "LockDynamic")
|
||||
obj.CurrentDensity_im_3 = "0 A/m^2"
|
||||
@@ -102,55 +102,37 @@ class ConstraintCurrentDensity(base_fempythonobject.BaseFemPythonObject):
|
||||
# now the enable bools
|
||||
if not hasattr(obj, "CurrentDensity_re_1_Disabled"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"CurrentDensity_re_1_Disabled",
|
||||
"Vector Potential",
|
||||
""
|
||||
"App::PropertyBool", "CurrentDensity_re_1_Disabled", "Vector Potential", ""
|
||||
)
|
||||
obj.setPropertyStatus("CurrentDensity_re_1_Disabled", "LockDynamic")
|
||||
obj.CurrentDensity_re_1_Disabled = True
|
||||
if not hasattr(obj, "CurrentDensity_re_2_Disabled"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"CurrentDensity_re_2_Disabled",
|
||||
"Vector Potential",
|
||||
""
|
||||
"App::PropertyBool", "CurrentDensity_re_2_Disabled", "Vector Potential", ""
|
||||
)
|
||||
obj.setPropertyStatus("CurrentDensity_re_2_Disabled", "LockDynamic")
|
||||
obj.CurrentDensity_re_2_Disabled = True
|
||||
if not hasattr(obj, "CurrentDensity_re_3_Disabled"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"CurrentDensity_re_3_Disabled",
|
||||
"Vector Potential",
|
||||
""
|
||||
"App::PropertyBool", "CurrentDensity_re_3_Disabled", "Vector Potential", ""
|
||||
)
|
||||
obj.setPropertyStatus("CurrentDensity_re_3_Disabled", "LockDynamic")
|
||||
obj.CurrentDensity_re_3_Disabled = True
|
||||
if not hasattr(obj, "CurrentDensity_im_1_Disabled"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"CurrentDensity_im_1_Disabled",
|
||||
"Vector Potential",
|
||||
""
|
||||
"App::PropertyBool", "CurrentDensity_im_1_Disabled", "Vector Potential", ""
|
||||
)
|
||||
obj.setPropertyStatus("CurrentDensity_im_1_Disabled", "LockDynamic")
|
||||
obj.CurrentDensity_im_1_Disabled = True
|
||||
if not hasattr(obj, "CurrentDensity_im_2_Disabled"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"CurrentDensity_im_2_Disabled",
|
||||
"Vector Potential",
|
||||
""
|
||||
"App::PropertyBool", "CurrentDensity_im_2_Disabled", "Vector Potential", ""
|
||||
)
|
||||
obj.setPropertyStatus("CurrentDensity_im_2_Disabled", "LockDynamic")
|
||||
obj.CurrentDensity_im_2_Disabled = True
|
||||
if not hasattr(obj, "CurrentDensity_im_3_Disabled"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"CurrentDensity_im_3_Disabled",
|
||||
"Vector Potential",
|
||||
""
|
||||
"App::PropertyBool", "CurrentDensity_im_3_Disabled", "Vector Potential", ""
|
||||
)
|
||||
obj.setPropertyStatus("CurrentDensity_im_3_Disabled", "LockDynamic")
|
||||
obj.CurrentDensity_im_3_Disabled = True
|
||||
|
||||
@@ -39,7 +39,7 @@ class ConstraintElectrostaticPotential(base_fempythonobject.BaseFemPythonObject)
|
||||
Type = "Fem::ConstraintElectrostaticPotential"
|
||||
|
||||
def __init__(self, obj):
|
||||
super(ConstraintElectrostaticPotential, self).__init__(obj)
|
||||
super().__init__(obj)
|
||||
self.add_properties(obj)
|
||||
|
||||
def onDocumentRestored(self, obj):
|
||||
@@ -48,10 +48,7 @@ class ConstraintElectrostaticPotential(base_fempythonobject.BaseFemPythonObject)
|
||||
def add_properties(self, obj):
|
||||
if not hasattr(obj, "Potential"):
|
||||
obj.addProperty(
|
||||
"App::PropertyElectricPotential",
|
||||
"Potential",
|
||||
"Parameter",
|
||||
"Electric Potential"
|
||||
"App::PropertyElectricPotential", "Potential", "Parameter", "Electric Potential"
|
||||
)
|
||||
obj.setPropertyStatus("Potential", "LockDynamic")
|
||||
# setting 1 V assures that the unit does not switch to mV
|
||||
@@ -63,7 +60,7 @@ class ConstraintElectrostaticPotential(base_fempythonobject.BaseFemPythonObject)
|
||||
"App::PropertyElectricPotential",
|
||||
"AV_re_1",
|
||||
"Vector Potential",
|
||||
"Real part of potential x-component"
|
||||
"Real part of potential x-component",
|
||||
)
|
||||
obj.setPropertyStatus("AV_re_1", "LockDynamic")
|
||||
obj.AV_re_1 = "0 V"
|
||||
@@ -72,7 +69,7 @@ class ConstraintElectrostaticPotential(base_fempythonobject.BaseFemPythonObject)
|
||||
"App::PropertyElectricPotential",
|
||||
"AV_re_2",
|
||||
"Vector Potential",
|
||||
"Real part of potential y-component"
|
||||
"Real part of potential y-component",
|
||||
)
|
||||
obj.setPropertyStatus("AV_re_2", "LockDynamic")
|
||||
obj.AV_re_2 = "0 V"
|
||||
@@ -81,7 +78,7 @@ class ConstraintElectrostaticPotential(base_fempythonobject.BaseFemPythonObject)
|
||||
"App::PropertyElectricPotential",
|
||||
"AV_re_3",
|
||||
"Vector Potential",
|
||||
"Real part of potential z-component"
|
||||
"Real part of potential z-component",
|
||||
)
|
||||
obj.setPropertyStatus("AV_re_3", "LockDynamic")
|
||||
obj.AV_re_3 = "0 V"
|
||||
@@ -90,7 +87,7 @@ class ConstraintElectrostaticPotential(base_fempythonobject.BaseFemPythonObject)
|
||||
"App::PropertyElectricPotential",
|
||||
"AV_im",
|
||||
"Vector Potential",
|
||||
"Imaginary part of scalar potential"
|
||||
"Imaginary part of scalar potential",
|
||||
)
|
||||
obj.setPropertyStatus("AV_im", "LockDynamic")
|
||||
obj.AV_im = "0 V"
|
||||
@@ -99,7 +96,7 @@ class ConstraintElectrostaticPotential(base_fempythonobject.BaseFemPythonObject)
|
||||
"App::PropertyElectricPotential",
|
||||
"AV_im_1",
|
||||
"Vector Potential",
|
||||
"Imaginary part of potential x-component"
|
||||
"Imaginary part of potential x-component",
|
||||
)
|
||||
obj.setPropertyStatus("AV_im_1", "LockDynamic")
|
||||
obj.AV_im_1 = "0 V"
|
||||
@@ -108,7 +105,7 @@ class ConstraintElectrostaticPotential(base_fempythonobject.BaseFemPythonObject)
|
||||
"App::PropertyElectricPotential",
|
||||
"AV_im_2",
|
||||
"Vector Potential",
|
||||
"Imaginary part of potential y-component"
|
||||
"Imaginary part of potential y-component",
|
||||
)
|
||||
obj.setPropertyStatus("AV_im_2", "LockDynamic")
|
||||
obj.AV_im_2 = "0 V"
|
||||
@@ -117,7 +114,7 @@ class ConstraintElectrostaticPotential(base_fempythonobject.BaseFemPythonObject)
|
||||
"App::PropertyElectricPotential",
|
||||
"AV_im_3",
|
||||
"Vector Potential",
|
||||
"Imaginary part of potential z-component"
|
||||
"Imaginary part of potential z-component",
|
||||
)
|
||||
obj.setPropertyStatus("AV_im_3", "LockDynamic")
|
||||
obj.AV_im_3 = "0 V"
|
||||
@@ -125,93 +122,49 @@ class ConstraintElectrostaticPotential(base_fempythonobject.BaseFemPythonObject)
|
||||
# now the enable bools
|
||||
if not hasattr(obj, "PotentialEnabled"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"PotentialEnabled",
|
||||
"Parameter",
|
||||
"Potential Enabled"
|
||||
"App::PropertyBool", "PotentialEnabled", "Parameter", "Potential Enabled"
|
||||
)
|
||||
obj.setPropertyStatus("PotentialEnabled", "LockDynamic")
|
||||
obj.PotentialEnabled = True
|
||||
if not hasattr(obj, "AV_re_1_Disabled"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"AV_re_1_Disabled",
|
||||
"Vector Potential",
|
||||
""
|
||||
)
|
||||
obj.addProperty("App::PropertyBool", "AV_re_1_Disabled", "Vector Potential", "")
|
||||
obj.setPropertyStatus("AV_re_1_Disabled", "LockDynamic")
|
||||
obj.AV_re_1_Disabled = True
|
||||
if not hasattr(obj, "AV_re_2_Disabled"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"AV_re_2_Disabled",
|
||||
"Vector Potential",
|
||||
""
|
||||
)
|
||||
obj.addProperty("App::PropertyBool", "AV_re_2_Disabled", "Vector Potential", "")
|
||||
obj.setPropertyStatus("AV_re_2_Disabled", "LockDynamic")
|
||||
obj.AV_re_2_Disabled = True
|
||||
if not hasattr(obj, "AV_re_3_Disabled"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"AV_re_3_Disabled",
|
||||
"Vector Potential",
|
||||
""
|
||||
)
|
||||
obj.addProperty("App::PropertyBool", "AV_re_3_Disabled", "Vector Potential", "")
|
||||
obj.setPropertyStatus("AV_re_3_Disabled", "LockDynamic")
|
||||
obj.AV_re_3_Disabled = True
|
||||
if not hasattr(obj, "AV_im_Disabled"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"AV_im_Disabled",
|
||||
"Vector Potential",
|
||||
""
|
||||
)
|
||||
obj.addProperty("App::PropertyBool", "AV_im_Disabled", "Vector Potential", "")
|
||||
obj.setPropertyStatus("AV_im_Disabled", "LockDynamic")
|
||||
obj.AV_im_Disabled = True
|
||||
if not hasattr(obj, "AV_im_1_Disabled"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"AV_im_1_Disabled",
|
||||
"Vector Potential",
|
||||
""
|
||||
)
|
||||
obj.addProperty("App::PropertyBool", "AV_im_1_Disabled", "Vector Potential", "")
|
||||
obj.setPropertyStatus("AV_im_1_Disabled", "LockDynamic")
|
||||
obj.AV_im_1_Disabled = True
|
||||
if not hasattr(obj, "AV_im_2_Disabled"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"AV_im_2_Disabled",
|
||||
"Vector Potential",
|
||||
""
|
||||
)
|
||||
obj.addProperty("App::PropertyBool", "AV_im_2_Disabled", "Vector Potential", "")
|
||||
obj.setPropertyStatus("AV_im_2_Disabled", "LockDynamic")
|
||||
obj.AV_im_2_Disabled = True
|
||||
if not hasattr(obj, "AV_im_3_Disabled"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"AV_im_3_Disabled",
|
||||
"Vector Potential",
|
||||
""
|
||||
)
|
||||
obj.addProperty("App::PropertyBool", "AV_im_3_Disabled", "Vector Potential", "")
|
||||
obj.setPropertyStatus("AV_im_3_Disabled", "LockDynamic")
|
||||
obj.AV_im_3_Disabled = True
|
||||
|
||||
if not hasattr(obj, "PotentialConstant"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"PotentialConstant",
|
||||
"Parameter",
|
||||
"Potential Constant"
|
||||
"App::PropertyBool", "PotentialConstant", "Parameter", "Potential Constant"
|
||||
)
|
||||
obj.setPropertyStatus("PotentialConstant", "LockDynamic")
|
||||
obj.PotentialConstant = False
|
||||
|
||||
if not hasattr(obj, "ElectricInfinity"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"ElectricInfinity",
|
||||
"Parameter",
|
||||
"Electric Infinity"
|
||||
"App::PropertyBool", "ElectricInfinity", "Parameter", "Electric Infinity"
|
||||
)
|
||||
obj.setPropertyStatus("ElectricInfinity", "LockDynamic")
|
||||
obj.ElectricInfinity = False
|
||||
@@ -221,17 +174,14 @@ class ConstraintElectrostaticPotential(base_fempythonobject.BaseFemPythonObject)
|
||||
"App::PropertyBool",
|
||||
"ElectricForcecalculation",
|
||||
"Parameter",
|
||||
"Electric Force Calculation"
|
||||
"Electric Force Calculation",
|
||||
)
|
||||
obj.setPropertyStatus("ElectricForcecalculation", "LockDynamic")
|
||||
obj.ElectricForcecalculation = False
|
||||
|
||||
if not hasattr(obj, "CapacitanceBody"):
|
||||
obj.addProperty(
|
||||
"App::PropertyInteger",
|
||||
"CapacitanceBody",
|
||||
"Parameter",
|
||||
"Capacitance Body"
|
||||
"App::PropertyInteger", "CapacitanceBody", "Parameter", "Capacitance Body"
|
||||
)
|
||||
obj.setPropertyStatus("CapacitanceBody", "LockDynamic")
|
||||
obj.CapacitanceBody = 0
|
||||
@@ -241,7 +191,7 @@ class ConstraintElectrostaticPotential(base_fempythonobject.BaseFemPythonObject)
|
||||
"App::PropertyBool",
|
||||
"CapacitanceBodyEnabled",
|
||||
"Parameter",
|
||||
"Capacitance Body Enabled"
|
||||
"Capacitance Body Enabled",
|
||||
)
|
||||
obj.setPropertyStatus("CapacitanceBodyEnabled", "LockDynamic")
|
||||
obj.CapacitanceBodyEnabled = False
|
||||
|
||||
@@ -39,26 +39,20 @@ class ConstraintFlowVelocity(base_fempythonobject.BaseFemPythonObject):
|
||||
Type = "Fem::ConstraintFlowVelocity"
|
||||
|
||||
def __init__(self, obj):
|
||||
super(ConstraintFlowVelocity, self).__init__(obj)
|
||||
super().__init__(obj)
|
||||
obj.addProperty(
|
||||
"App::PropertyVelocity",
|
||||
"VelocityX",
|
||||
"Parameter",
|
||||
"Velocity in x-direction"
|
||||
"App::PropertyVelocity", "VelocityX", "Parameter", "Velocity in x-direction"
|
||||
)
|
||||
obj.setPropertyStatus("VelocityX", "LockDynamic")
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"VelocityXFormula",
|
||||
"Parameter",
|
||||
"Velocity formula in x-direction"
|
||||
"Velocity formula in x-direction",
|
||||
)
|
||||
obj.setPropertyStatus("VelocityXFormula", "LockDynamic")
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"VelocityXUnspecified",
|
||||
"Parameter",
|
||||
"Use velocity in x-direction"
|
||||
"App::PropertyBool", "VelocityXUnspecified", "Parameter", "Use velocity in x-direction"
|
||||
)
|
||||
obj.setPropertyStatus("VelocityXUnspecified", "LockDynamic")
|
||||
obj.VelocityXUnspecified = True
|
||||
@@ -66,29 +60,23 @@ class ConstraintFlowVelocity(base_fempythonobject.BaseFemPythonObject):
|
||||
"App::PropertyBool",
|
||||
"VelocityXHasFormula",
|
||||
"Parameter",
|
||||
"Use formula for velocity in x-direction"
|
||||
"Use formula for velocity in x-direction",
|
||||
)
|
||||
obj.setPropertyStatus("VelocityXHasFormula", "LockDynamic")
|
||||
|
||||
obj.addProperty(
|
||||
"App::PropertyVelocity",
|
||||
"VelocityY",
|
||||
"Parameter",
|
||||
"Velocity in y-direction"
|
||||
"App::PropertyVelocity", "VelocityY", "Parameter", "Velocity in y-direction"
|
||||
)
|
||||
obj.setPropertyStatus("VelocityY", "LockDynamic")
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"VelocityYFormula",
|
||||
"Parameter",
|
||||
"Velocity formula in y-direction"
|
||||
"Velocity formula in y-direction",
|
||||
)
|
||||
obj.setPropertyStatus("VelocityYFormula", "LockDynamic")
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"VelocityYUnspecified",
|
||||
"Parameter",
|
||||
"Use velocity in y-direction"
|
||||
"App::PropertyBool", "VelocityYUnspecified", "Parameter", "Use velocity in y-direction"
|
||||
)
|
||||
obj.setPropertyStatus("VelocityYUnspecified", "LockDynamic")
|
||||
obj.VelocityYUnspecified = True
|
||||
@@ -96,29 +84,23 @@ class ConstraintFlowVelocity(base_fempythonobject.BaseFemPythonObject):
|
||||
"App::PropertyBool",
|
||||
"VelocityYHasFormula",
|
||||
"Parameter",
|
||||
"Use formula for velocity in y-direction"
|
||||
"Use formula for velocity in y-direction",
|
||||
)
|
||||
obj.setPropertyStatus("VelocityYHasFormula", "LockDynamic")
|
||||
|
||||
obj.addProperty(
|
||||
"App::PropertyVelocity",
|
||||
"VelocityZ",
|
||||
"Parameter",
|
||||
"Velocity in z-direction"
|
||||
"App::PropertyVelocity", "VelocityZ", "Parameter", "Velocity in z-direction"
|
||||
)
|
||||
obj.setPropertyStatus("VelocityZ", "LockDynamic")
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"VelocityZFormula",
|
||||
"Parameter",
|
||||
"Velocity formula in z-direction"
|
||||
"Velocity formula in z-direction",
|
||||
)
|
||||
obj.setPropertyStatus("VelocityZFormula", "LockDynamic")
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"VelocityZUnspecified",
|
||||
"Parameter",
|
||||
"Use velocity in z-direction"
|
||||
"App::PropertyBool", "VelocityZUnspecified", "Parameter", "Use velocity in z-direction"
|
||||
)
|
||||
obj.setPropertyStatus("VelocityZUnspecified", "LockDynamic")
|
||||
obj.VelocityZUnspecified = True
|
||||
@@ -126,14 +108,11 @@ class ConstraintFlowVelocity(base_fempythonobject.BaseFemPythonObject):
|
||||
"App::PropertyBool",
|
||||
"VelocityZHasFormula",
|
||||
"Parameter",
|
||||
"Use formula for velocity in z-direction"
|
||||
"Use formula for velocity in z-direction",
|
||||
)
|
||||
obj.setPropertyStatus("VelocityZHasFormula", "LockDynamic")
|
||||
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"NormalToBoundary",
|
||||
"Parameter",
|
||||
"Flow is in normal direction"
|
||||
"App::PropertyBool", "NormalToBoundary", "Parameter", "Flow is in normal direction"
|
||||
)
|
||||
obj.setPropertyStatus("NormalToBoundary", "LockDynamic")
|
||||
|
||||
@@ -38,26 +38,20 @@ class ConstraintInitialFlowVelocity(base_fempythonobject.BaseFemPythonObject):
|
||||
Type = "Fem::ConstraintInitialFlowVelocity"
|
||||
|
||||
def __init__(self, obj):
|
||||
super(ConstraintInitialFlowVelocity, self).__init__(obj)
|
||||
super().__init__(obj)
|
||||
obj.addProperty(
|
||||
"App::PropertyVelocity",
|
||||
"VelocityX",
|
||||
"Parameter",
|
||||
"Velocity in x-direction"
|
||||
"App::PropertyVelocity", "VelocityX", "Parameter", "Velocity in x-direction"
|
||||
)
|
||||
obj.setPropertyStatus("VelocityX", "LockDynamic")
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"VelocityXFormula",
|
||||
"Parameter",
|
||||
"Velocity formula in x-direction"
|
||||
"Velocity formula in x-direction",
|
||||
)
|
||||
obj.setPropertyStatus("VelocityXFormula", "LockDynamic")
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"VelocityXUnspecified",
|
||||
"Parameter",
|
||||
"Use velocity in x-direction"
|
||||
"App::PropertyBool", "VelocityXUnspecified", "Parameter", "Use velocity in x-direction"
|
||||
)
|
||||
obj.setPropertyStatus("VelocityXUnspecified", "LockDynamic")
|
||||
obj.VelocityXUnspecified = True
|
||||
@@ -65,29 +59,23 @@ class ConstraintInitialFlowVelocity(base_fempythonobject.BaseFemPythonObject):
|
||||
"App::PropertyBool",
|
||||
"VelocityXHasFormula",
|
||||
"Parameter",
|
||||
"Use formula for velocity in x-direction"
|
||||
"Use formula for velocity in x-direction",
|
||||
)
|
||||
obj.setPropertyStatus("VelocityXHasFormula", "LockDynamic")
|
||||
|
||||
obj.addProperty(
|
||||
"App::PropertyVelocity",
|
||||
"VelocityY",
|
||||
"Parameter",
|
||||
"Velocity in y-direction"
|
||||
"App::PropertyVelocity", "VelocityY", "Parameter", "Velocity in y-direction"
|
||||
)
|
||||
obj.setPropertyStatus("VelocityY", "LockDynamic")
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"VelocityYFormula",
|
||||
"Parameter",
|
||||
"Velocity formula in y-direction"
|
||||
"Velocity formula in y-direction",
|
||||
)
|
||||
obj.setPropertyStatus("VelocityYFormula", "LockDynamic")
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"VelocityYUnspecified",
|
||||
"Parameter",
|
||||
"Use velocity in y-direction"
|
||||
"App::PropertyBool", "VelocityYUnspecified", "Parameter", "Use velocity in y-direction"
|
||||
)
|
||||
obj.setPropertyStatus("VelocityYUnspecified", "LockDynamic")
|
||||
obj.VelocityYUnspecified = True
|
||||
@@ -95,29 +83,23 @@ class ConstraintInitialFlowVelocity(base_fempythonobject.BaseFemPythonObject):
|
||||
"App::PropertyBool",
|
||||
"VelocityYHasFormula",
|
||||
"Parameter",
|
||||
"Use formula for velocity in y-direction"
|
||||
"Use formula for velocity in y-direction",
|
||||
)
|
||||
obj.setPropertyStatus("VelocityYHasFormula", "LockDynamic")
|
||||
|
||||
obj.addProperty(
|
||||
"App::PropertyVelocity",
|
||||
"VelocityZ",
|
||||
"Parameter",
|
||||
"Velocity in z-direction"
|
||||
"App::PropertyVelocity", "VelocityZ", "Parameter", "Velocity in z-direction"
|
||||
)
|
||||
obj.setPropertyStatus("VelocityZ", "LockDynamic")
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"VelocityZFormula",
|
||||
"Parameter",
|
||||
"Velocity formula in z-direction"
|
||||
"Velocity formula in z-direction",
|
||||
)
|
||||
obj.setPropertyStatus("VelocityZFormula", "LockDynamic")
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"VelocityZUnspecified",
|
||||
"Parameter",
|
||||
"Use velocity in z-direction"
|
||||
"App::PropertyBool", "VelocityZUnspecified", "Parameter", "Use velocity in z-direction"
|
||||
)
|
||||
obj.setPropertyStatus("VelocityZUnspecified", "LockDynamic")
|
||||
obj.VelocityZUnspecified = True
|
||||
@@ -125,6 +107,6 @@ class ConstraintInitialFlowVelocity(base_fempythonobject.BaseFemPythonObject):
|
||||
"App::PropertyBool",
|
||||
"VelocityZHasFormula",
|
||||
"Parameter",
|
||||
"Use formula for velocity in z-direction"
|
||||
"Use formula for velocity in z-direction",
|
||||
)
|
||||
obj.setPropertyStatus("VelocityZHasFormula", "LockDynamic")
|
||||
|
||||
@@ -37,7 +37,7 @@ class ConstraintInitialPressure(base_fempythonobject.BaseFemPythonObject):
|
||||
Type = "Fem::ConstraintInitialPressure"
|
||||
|
||||
def __init__(self, obj):
|
||||
super(ConstraintInitialPressure, self).__init__(obj)
|
||||
super().__init__(obj)
|
||||
self.add_properties(obj)
|
||||
|
||||
def onDocumentRestored(self, obj):
|
||||
@@ -45,12 +45,7 @@ class ConstraintInitialPressure(base_fempythonobject.BaseFemPythonObject):
|
||||
|
||||
def add_properties(self, obj):
|
||||
if not hasattr(obj, "Pressure"):
|
||||
obj.addProperty(
|
||||
"App::PropertyPressure",
|
||||
"Pressure",
|
||||
"Parameter",
|
||||
"Initial Pressure"
|
||||
)
|
||||
obj.addProperty("App::PropertyPressure", "Pressure", "Parameter", "Initial Pressure")
|
||||
obj.setPropertyStatus("Pressure", "LockDynamic")
|
||||
# we initialize 1 bar
|
||||
obj.Pressure = "100 kPa"
|
||||
|
||||
@@ -37,7 +37,7 @@ class ConstraintMagnetization(base_fempythonobject.BaseFemPythonObject):
|
||||
Type = "Fem::ConstraintMagnetization"
|
||||
|
||||
def __init__(self, obj):
|
||||
super(ConstraintMagnetization, self).__init__(obj)
|
||||
super().__init__(obj)
|
||||
self.add_properties(obj)
|
||||
|
||||
def onDocumentRestored(self, obj):
|
||||
@@ -49,7 +49,7 @@ class ConstraintMagnetization(base_fempythonobject.BaseFemPythonObject):
|
||||
"App::PropertyMagnetization",
|
||||
"Magnetization_re_1",
|
||||
"Vector Potential",
|
||||
"Real part of magnetization x-component"
|
||||
"Real part of magnetization x-component",
|
||||
)
|
||||
obj.setPropertyStatus("Magnetization_re_1", "LockDynamic")
|
||||
obj.Magnetization_re_1 = "0 A/m"
|
||||
@@ -58,7 +58,7 @@ class ConstraintMagnetization(base_fempythonobject.BaseFemPythonObject):
|
||||
"App::PropertyMagnetization",
|
||||
"Magnetization_re_2",
|
||||
"Vector Potential",
|
||||
"Real part of magnetization y-component"
|
||||
"Real part of magnetization y-component",
|
||||
)
|
||||
obj.setPropertyStatus("Magnetization_re_2", "LockDynamic")
|
||||
obj.Magnetization_re_2 = "0 A/m"
|
||||
@@ -67,7 +67,7 @@ class ConstraintMagnetization(base_fempythonobject.BaseFemPythonObject):
|
||||
"App::PropertyMagnetization",
|
||||
"Magnetization_re_3",
|
||||
"Vector Potential",
|
||||
"Real part of magnetization z-component"
|
||||
"Real part of magnetization z-component",
|
||||
)
|
||||
obj.setPropertyStatus("Magnetization_re_3", "LockDynamic")
|
||||
obj.Magnetization_re_3 = "0 A/m"
|
||||
@@ -76,7 +76,7 @@ class ConstraintMagnetization(base_fempythonobject.BaseFemPythonObject):
|
||||
"App::PropertyMagnetization",
|
||||
"Magnetization_im_1",
|
||||
"Vector Potential",
|
||||
"Imaginary part of magnetization x-component"
|
||||
"Imaginary part of magnetization x-component",
|
||||
)
|
||||
obj.setPropertyStatus("Magnetization_im_1", "LockDynamic")
|
||||
obj.Magnetization_im_1 = "0 A/m"
|
||||
@@ -85,7 +85,7 @@ class ConstraintMagnetization(base_fempythonobject.BaseFemPythonObject):
|
||||
"App::PropertyMagnetization",
|
||||
"Magnetization_im_2",
|
||||
"Vector Potential",
|
||||
"Imaginary part of magnetization y-component"
|
||||
"Imaginary part of magnetization y-component",
|
||||
)
|
||||
obj.setPropertyStatus("Magnetization_im_2", "LockDynamic")
|
||||
obj.Magnetization_im_2 = "0 A/m"
|
||||
@@ -94,7 +94,7 @@ class ConstraintMagnetization(base_fempythonobject.BaseFemPythonObject):
|
||||
"App::PropertyMagnetization",
|
||||
"Magnetization_im_3",
|
||||
"Vector Potential",
|
||||
"Imaginary part of magnetization z-component"
|
||||
"Imaginary part of magnetization z-component",
|
||||
)
|
||||
obj.setPropertyStatus("Magnetization_im_3", "LockDynamic")
|
||||
obj.Magnetization_im_3 = "0 A/m"
|
||||
@@ -102,55 +102,37 @@ class ConstraintMagnetization(base_fempythonobject.BaseFemPythonObject):
|
||||
# now the enable bools
|
||||
if not hasattr(obj, "Magnetization_re_1_Disabled"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"Magnetization_re_1_Disabled",
|
||||
"Vector Potential",
|
||||
""
|
||||
"App::PropertyBool", "Magnetization_re_1_Disabled", "Vector Potential", ""
|
||||
)
|
||||
obj.setPropertyStatus("Magnetization_re_1_Disabled", "LockDynamic")
|
||||
obj.Magnetization_re_1_Disabled = True
|
||||
if not hasattr(obj, "Magnetization_re_2_Disabled"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"Magnetization_re_2_Disabled",
|
||||
"Vector Potential",
|
||||
""
|
||||
"App::PropertyBool", "Magnetization_re_2_Disabled", "Vector Potential", ""
|
||||
)
|
||||
obj.setPropertyStatus("Magnetization_re_2_Disabled", "LockDynamic")
|
||||
obj.Magnetization_re_2_Disabled = True
|
||||
if not hasattr(obj, "Magnetization_re_3_Disabled"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"Magnetization_re_3_Disabled",
|
||||
"Vector Potential",
|
||||
""
|
||||
"App::PropertyBool", "Magnetization_re_3_Disabled", "Vector Potential", ""
|
||||
)
|
||||
obj.setPropertyStatus("Magnetization_re_3_Disabled", "LockDynamic")
|
||||
obj.Magnetization_re_3_Disabled = True
|
||||
if not hasattr(obj, "Magnetization_im_1_Disabled"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"Magnetization_im_1_Disabled",
|
||||
"Vector Potential",
|
||||
""
|
||||
"App::PropertyBool", "Magnetization_im_1_Disabled", "Vector Potential", ""
|
||||
)
|
||||
obj.setPropertyStatus("Magnetization_im_1_Disabled", "LockDynamic")
|
||||
obj.Magnetization_im_1_Disabled = True
|
||||
if not hasattr(obj, "Magnetization_im_2_Disabled"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"Magnetization_im_2_Disabled",
|
||||
"Vector Potential",
|
||||
""
|
||||
"App::PropertyBool", "Magnetization_im_2_Disabled", "Vector Potential", ""
|
||||
)
|
||||
obj.setPropertyStatus("Magnetization_im_2_Disabled", "LockDynamic")
|
||||
obj.Magnetization_im_2_Disabled = True
|
||||
if not hasattr(obj, "Magnetization_im_3_Disabled"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"Magnetization_im_3_Disabled",
|
||||
"Vector Potential",
|
||||
""
|
||||
"App::PropertyBool", "Magnetization_im_3_Disabled", "Vector Potential", ""
|
||||
)
|
||||
obj.setPropertyStatus("Magnetization_im_3_Disabled", "LockDynamic")
|
||||
obj.Magnetization_im_3_Disabled = True
|
||||
|
||||
@@ -33,6 +33,7 @@ from . import base_fempythonobject
|
||||
|
||||
_PropHelper = base_fempythonobject._PropHelper
|
||||
|
||||
|
||||
class ConstraintSectionPrint(base_fempythonobject.BaseFemPythonObject):
|
||||
"""
|
||||
The FemConstraintSectionPrint object
|
||||
@@ -41,27 +42,26 @@ class ConstraintSectionPrint(base_fempythonobject.BaseFemPythonObject):
|
||||
Type = "Fem::ConstraintSectionPrint"
|
||||
|
||||
def __init__(self, obj):
|
||||
super(ConstraintSectionPrint, self).__init__(obj)
|
||||
super().__init__(obj)
|
||||
|
||||
for prop in self._get_properties():
|
||||
prop.add_to_object(obj)
|
||||
|
||||
|
||||
def _get_properties(self):
|
||||
prop = []
|
||||
|
||||
prop.append(_PropHelper(
|
||||
type = "App::PropertyEnumeration",
|
||||
name = "Variable",
|
||||
group = "Constraint Section Print",
|
||||
doc = "Set facial variable",
|
||||
value = ["Section Force", "Heat Flux", "Drag Stress"]
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="Variable",
|
||||
group="Constraint Section Print",
|
||||
doc="Set facial variable",
|
||||
value=["Section Force", "Heat Flux", "Drag Stress"],
|
||||
)
|
||||
)
|
||||
|
||||
return prop
|
||||
|
||||
|
||||
def onDocumentRestored(self, obj):
|
||||
# update old project with new properties
|
||||
for prop in self._get_properties():
|
||||
|
||||
@@ -42,7 +42,7 @@ class ConstraintSelfWeight(base_fempythonobject.BaseFemPythonObject):
|
||||
Type = "Fem::ConstraintSelfWeight"
|
||||
|
||||
def __init__(self, obj):
|
||||
super(ConstraintSelfWeight, self).__init__(obj)
|
||||
super().__init__(obj)
|
||||
|
||||
self.addProperty(obj)
|
||||
|
||||
@@ -53,17 +53,15 @@ class ConstraintSelfWeight(base_fempythonobject.BaseFemPythonObject):
|
||||
obj.setEditorMode("References", 2) # do not show in Editor
|
||||
|
||||
def addProperty(self, obj):
|
||||
obj.addProperty("App::PropertyAcceleration",
|
||||
"GravityAcceleration",
|
||||
"Gravity",
|
||||
"Gravity acceleration")
|
||||
obj.addProperty(
|
||||
"App::PropertyAcceleration", "GravityAcceleration", "Gravity", "Gravity acceleration"
|
||||
)
|
||||
obj.setPropertyStatus("GravityAcceleration", "LockDynamic")
|
||||
obj.GravityAcceleration = constants.gravity()
|
||||
|
||||
obj.addProperty("App::PropertyVector",
|
||||
"GravityDirection",
|
||||
"Gravity",
|
||||
"Normalized gravity direction")
|
||||
obj.addProperty(
|
||||
"App::PropertyVector", "GravityDirection", "Gravity", "Normalized gravity direction"
|
||||
)
|
||||
obj.setPropertyStatus("GravityDirection", "LockDynamic")
|
||||
obj.GravityDirection = FreeCAD.Vector(0, 0, -1)
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user