def import_z88_disp(filename, analysis=None, result_name_prefix=None): '''insert a FreeCAD FEM mechanical result object in the ActiveDocument ''' import importToolsFem import ObjectsFem if result_name_prefix is None: result_name_prefix = '' m = read_z88_disp(filename) if(len(m['Nodes']) > 0): if analysis is None: analysis_name = os.path.splitext(os.path.basename(filename))[0] analysis_object = ObjectsFem.makeAnalysis('Analysis') analysis_object.Label = analysis_name else: analysis_object = analysis # see if statement few lines later, if not analysis -> no FemMesh object is created ! for result_set in m['Results']: results_name = result_name_prefix + 'results' results = ObjectsFem.makeResultMechanical(results_name) for m in analysis_object.Member: # TODO analysis could have multiple mesh objects in the future if m.isDerivedFrom("Fem::FemMeshObject"): results.Mesh = m break results = importToolsFem.fill_femresult_mechanical(results, result_set, 0) analysis_object.Member = analysis_object.Member + [results] if(FreeCAD.GuiUp): import FemGui FemGui.setActiveAnalysis(analysis_object)
def importVTK(filename, analysis=None, result_name_prefix=None): import ObjectsFem if result_name_prefix is None: result_name_prefix = '' if analysis is None: analysis_name = os.path.splitext(os.path.basename(filename))[0] analysis_object = ObjectsFem.makeAnalysis('Analysis') analysis_object.Label = analysis_name else: analysis_object = analysis # if properties can be added in FemVTKTools importCfdResult(), this file can be used for CFD workbench results_name = result_name_prefix + 'results' result_obj = ObjectsFem.makeResultMechanical(results_name) # result_obj = FreeCAD.ActiveDocument.addObject('Fem::FemResultObject', results_name) Fem.readResult( filename, result_obj.Name ) # readResult always creates a new femmesh named ResultMesh # workaround for the DisplacementLengths (They should have been calculated by Fem.readResult) if not result_obj.DisplacementLengths: result_obj.DisplacementLengths = calculate_disp_abs( result_obj.DisplacementVectors) analysis_object.Member = analysis_object.Member + [result_obj] # FIXME move the ResultMesh in the analysis ''' seams not used at the moment
def importVTK(filename, analysis=None, result_name_prefix=None): import ObjectsFem if result_name_prefix is None: result_name_prefix = '' if analysis is None: analysis_name = os.path.splitext(os.path.basename(filename))[0] analysis_object = ObjectsFem.makeAnalysis('Analysis') analysis_object.Label = analysis_name else: analysis_object = analysis # if properties can be added in FemVTKTools importCfdResult(), this file can be used for CFD workbench results_name = result_name_prefix + 'results' result_obj = ObjectsFem.makeResultMechanical(results_name) # result_obj = FreeCAD.ActiveDocument.addObject('Fem::FemResultObject', results_name) Fem.readResult(filename, result_obj.Name) # readResult always creates a new femmesh named ResultMesh # workaround for the DisplacementLengths (They should have been calculated by Fem.readResult) if not result_obj.DisplacementLengths: import importToolsFem result_obj.DisplacementLengths = importToolsFem.calculate_disp_abs(result_obj.DisplacementVectors) analysis_object.Member = analysis_object.Member + [result_obj] # FIXME move the ResultMesh in the analysis ''' seams not used at the moment
def test_femobjects_make(self): doc = self.active_doc analysis = ObjectsFem.makeAnalysis(doc) analysis.addObject(ObjectsFem.makeConstraintBearing(doc)) analysis.addObject(ObjectsFem.makeConstraintBodyHeatSource(doc)) analysis.addObject(ObjectsFem.makeConstraintContact(doc)) analysis.addObject(ObjectsFem.makeConstraintDisplacement(doc)) analysis.addObject( ObjectsFem.makeConstraintElectrostaticPotential(doc)) analysis.addObject(ObjectsFem.makeConstraintFixed(doc)) analysis.addObject(ObjectsFem.makeConstraintFlowVelocity(doc)) analysis.addObject(ObjectsFem.makeConstraintFluidBoundary(doc)) analysis.addObject(ObjectsFem.makeConstraintForce(doc)) analysis.addObject(ObjectsFem.makeConstraintGear(doc)) analysis.addObject(ObjectsFem.makeConstraintHeatflux(doc)) analysis.addObject(ObjectsFem.makeConstraintInitialFlowVelocity(doc)) analysis.addObject(ObjectsFem.makeConstraintInitialTemperature(doc)) analysis.addObject(ObjectsFem.makeConstraintPlaneRotation(doc)) analysis.addObject(ObjectsFem.makeConstraintPressure(doc)) analysis.addObject(ObjectsFem.makeConstraintPulley(doc)) analysis.addObject(ObjectsFem.makeConstraintSelfWeight(doc)) analysis.addObject(ObjectsFem.makeConstraintTemperature(doc)) analysis.addObject(ObjectsFem.makeConstraintTransform(doc)) analysis.addObject(ObjectsFem.makeElementFluid1D(doc)) analysis.addObject(ObjectsFem.makeElementGeometry1D(doc)) analysis.addObject(ObjectsFem.makeElementGeometry2D(doc)) analysis.addObject(ObjectsFem.makeElementRotation1D(doc)) analysis.addObject(ObjectsFem.makeMaterialFluid(doc)) mat = analysis.addObject(ObjectsFem.makeMaterialSolid(doc))[0] analysis.addObject(ObjectsFem.makeMaterialMechanicalNonlinear( doc, mat)) msh = analysis.addObject(ObjectsFem.makeMeshGmsh(doc))[0] analysis.addObject(ObjectsFem.makeMeshBoundaryLayer(doc, msh)) analysis.addObject(ObjectsFem.makeMeshGroup(doc, msh)) analysis.addObject(ObjectsFem.makeMeshRegion(doc, msh)) analysis.addObject(ObjectsFem.makeMeshNetgen(doc)) analysis.addObject(ObjectsFem.makeMeshResult(doc)) analysis.addObject(ObjectsFem.makeResultMechanical(doc)) analysis.addObject(ObjectsFem.makeSolverCalculixCcxTools(doc)) analysis.addObject(ObjectsFem.makeSolverCalculix(doc)) sol = analysis.addObject(ObjectsFem.makeSolverElmer(doc))[0] analysis.addObject(ObjectsFem.makeSolverZ88(doc)) analysis.addObject(ObjectsFem.makeEquationElasticity(doc, sol)) analysis.addObject(ObjectsFem.makeEquationElectrostatic(doc, sol)) analysis.addObject(ObjectsFem.makeEquationFlow(doc, sol)) analysis.addObject(ObjectsFem.makeEquationFluxsolver(doc, sol)) analysis.addObject(ObjectsFem.makeEquationHeat(doc, sol)) # TODO the equations show up twice on Tree (on solver and on analysis), if they are added to the analysis group doc.recompute() self.assertEqual(len(analysis.Group), testtools.get_defmake_count() - 1) # because of the analysis itself count -1
def test_femobjects_make(self): doc = self.active_doc analysis = ObjectsFem.makeAnalysis(doc) analysis.addObject(ObjectsFem.makeConstraintBearing(doc)) analysis.addObject(ObjectsFem.makeConstraintBodyHeatSource(doc)) analysis.addObject(ObjectsFem.makeConstraintContact(doc)) analysis.addObject(ObjectsFem.makeConstraintDisplacement(doc)) analysis.addObject(ObjectsFem.makeConstraintElectrostaticPotential(doc)) analysis.addObject(ObjectsFem.makeConstraintFixed(doc)) analysis.addObject(ObjectsFem.makeConstraintFlowVelocity(doc)) analysis.addObject(ObjectsFem.makeConstraintFluidBoundary(doc)) analysis.addObject(ObjectsFem.makeConstraintForce(doc)) analysis.addObject(ObjectsFem.makeConstraintGear(doc)) analysis.addObject(ObjectsFem.makeConstraintHeatflux(doc)) analysis.addObject(ObjectsFem.makeConstraintInitialFlowVelocity(doc)) analysis.addObject(ObjectsFem.makeConstraintInitialTemperature(doc)) analysis.addObject(ObjectsFem.makeConstraintPlaneRotation(doc)) analysis.addObject(ObjectsFem.makeConstraintPressure(doc)) analysis.addObject(ObjectsFem.makeConstraintPulley(doc)) analysis.addObject(ObjectsFem.makeConstraintSelfWeight(doc)) analysis.addObject(ObjectsFem.makeConstraintTemperature(doc)) analysis.addObject(ObjectsFem.makeConstraintTransform(doc)) analysis.addObject(ObjectsFem.makeElementFluid1D(doc)) analysis.addObject(ObjectsFem.makeElementGeometry1D(doc)) analysis.addObject(ObjectsFem.makeElementGeometry2D(doc)) analysis.addObject(ObjectsFem.makeElementRotation1D(doc)) analysis.addObject(ObjectsFem.makeMaterialFluid(doc)) mat = analysis.addObject(ObjectsFem.makeMaterialSolid(doc))[0] analysis.addObject(ObjectsFem.makeMaterialMechanicalNonlinear(doc, mat)) msh = analysis.addObject(ObjectsFem.makeMeshGmsh(doc))[0] analysis.addObject(ObjectsFem.makeMeshBoundaryLayer(doc, msh)) analysis.addObject(ObjectsFem.makeMeshGroup(doc, msh)) analysis.addObject(ObjectsFem.makeMeshRegion(doc, msh)) analysis.addObject(ObjectsFem.makeMeshNetgen(doc)) analysis.addObject(ObjectsFem.makeMeshResult(doc)) analysis.addObject(ObjectsFem.makeResultMechanical(doc)) analysis.addObject(ObjectsFem.makeSolverCalculixCcxTools(doc)) analysis.addObject(ObjectsFem.makeSolverCalculix(doc)) sol = analysis.addObject(ObjectsFem.makeSolverElmer(doc))[0] analysis.addObject(ObjectsFem.makeSolverZ88(doc)) analysis.addObject(ObjectsFem.makeEquationElasticity(doc, sol)) analysis.addObject(ObjectsFem.makeEquationElectrostatic(doc, sol)) analysis.addObject(ObjectsFem.makeEquationFlow(doc, sol)) analysis.addObject(ObjectsFem.makeEquationFluxsolver(doc, sol)) analysis.addObject(ObjectsFem.makeEquationHeat(doc, sol)) # is = 43 (just copy in empty file to test, or run unit test case, it is printed) # TODO if the equations and gmsh mesh childs are added to the analysis, # they show up twice on Tree (on solver resp. gemsh mesh obj and on analysis) # https://forum.freecadweb.org/viewtopic.php?t=25283 doc.recompute() self.assertEqual(len(analysis.Group), testtools.get_defmake_count() - 1) # because of the analysis itself count -1
def importFrd(filename, analysis=None, result_name_prefix=None): import importToolsFem import ObjectsFem if result_name_prefix is None: result_name_prefix = '' m = readResult(filename) mesh_object = None if(len(m['Nodes']) > 0): if analysis is None: analysis_name = os.path.splitext(os.path.basename(filename))[0] analysis_object = ObjectsFem.makeAnalysis('Analysis') analysis_object.Label = analysis_name else: analysis_object = analysis # see if statement few lines later, if not analysis -> no FemMesh object is created ! if 'Nodes' in m: positions = [] for k, v in m['Nodes'].items(): positions.append(v) p_x_max, p_y_max, p_z_max = map(max, zip(*positions)) p_x_min, p_y_min, p_z_min = map(min, zip(*positions)) x_span = abs(p_x_max - p_x_min) y_span = abs(p_y_max - p_y_min) z_span = abs(p_z_max - p_z_min) span = max(x_span, y_span, z_span) if (not analysis): mesh = importToolsFem.make_femmesh(m) if len(m['Nodes']) > 0: mesh_object = FreeCAD.ActiveDocument.addObject('Fem::FemMeshObject', 'ResultMesh') mesh_object.FemMesh = mesh analysis_object.Member = analysis_object.Member + [mesh_object] number_of_increments = len(m['Results']) for result_set in m['Results']: eigenmode_number = result_set['number'] step_time = result_set['time'] step_time = round(step_time, 2) if eigenmode_number > 0: results_name = result_name_prefix + 'mode_' + str(eigenmode_number) + '_results' elif number_of_increments > 1: results_name = result_name_prefix + 'time_' + str(step_time) + '_results' else: results_name = result_name_prefix + 'results' results = ObjectsFem.makeResultMechanical(results_name) for m in analysis_object.Member: # TODO analysis could have multiple mesh objects in the future if m.isDerivedFrom("Fem::FemMeshObject"): results.Mesh = m break results = importToolsFem.fill_femresult_mechanical(results, result_set, span) analysis_object.Member = analysis_object.Member + [results] if(FreeCAD.GuiUp): import FemGui FemGui.setActiveAnalysis(analysis_object)
def test_femobjects_make(self): doc = self.active_doc analysis = ObjectsFem.makeAnalysis(doc) analysis.addObject(ObjectsFem.makeConstraintBearing(doc)) analysis.addObject(ObjectsFem.makeConstraintBodyHeatSource(doc)) analysis.addObject(ObjectsFem.makeConstraintContact(doc)) analysis.addObject(ObjectsFem.makeConstraintDisplacement(doc)) analysis.addObject(ObjectsFem.makeConstraintElectrostaticPotential(doc)) analysis.addObject(ObjectsFem.makeConstraintFixed(doc)) analysis.addObject(ObjectsFem.makeConstraintFlowVelocity(doc)) analysis.addObject(ObjectsFem.makeConstraintFluidBoundary(doc)) analysis.addObject(ObjectsFem.makeConstraintForce(doc)) analysis.addObject(ObjectsFem.makeConstraintGear(doc)) analysis.addObject(ObjectsFem.makeConstraintHeatflux(doc)) analysis.addObject(ObjectsFem.makeConstraintInitialFlowVelocity(doc)) analysis.addObject(ObjectsFem.makeConstraintInitialTemperature(doc)) analysis.addObject(ObjectsFem.makeConstraintPlaneRotation(doc)) analysis.addObject(ObjectsFem.makeConstraintPressure(doc)) analysis.addObject(ObjectsFem.makeConstraintPulley(doc)) analysis.addObject(ObjectsFem.makeConstraintSelfWeight(doc)) analysis.addObject(ObjectsFem.makeConstraintTemperature(doc)) analysis.addObject(ObjectsFem.makeConstraintTransform(doc)) analysis.addObject(ObjectsFem.makeElementFluid1D(doc)) analysis.addObject(ObjectsFem.makeElementGeometry1D(doc)) analysis.addObject(ObjectsFem.makeElementGeometry2D(doc)) analysis.addObject(ObjectsFem.makeElementRotation1D(doc)) analysis.addObject(ObjectsFem.makeMaterialFluid(doc)) mat = analysis.addObject(ObjectsFem.makeMaterialSolid(doc))[0] analysis.addObject(ObjectsFem.makeMaterialMechanicalNonlinear(doc, mat)) msh = analysis.addObject(ObjectsFem.makeMeshGmsh(doc))[0] analysis.addObject(ObjectsFem.makeMeshBoundaryLayer(doc, msh)) analysis.addObject(ObjectsFem.makeMeshGroup(doc, msh)) analysis.addObject(ObjectsFem.makeMeshRegion(doc, msh)) analysis.addObject(ObjectsFem.makeMeshNetgen(doc)) analysis.addObject(ObjectsFem.makeMeshResult(doc)) analysis.addObject(ObjectsFem.makeResultMechanical(doc)) analysis.addObject(ObjectsFem.makeSolverCalculixCcxTools(doc)) analysis.addObject(ObjectsFem.makeSolverCalculix(doc)) sol = analysis.addObject(ObjectsFem.makeSolverElmer(doc))[0] analysis.addObject(ObjectsFem.makeSolverZ88(doc)) analysis.addObject(ObjectsFem.makeEquationElasticity(doc, sol)) analysis.addObject(ObjectsFem.makeEquationElectrostatic(doc, sol)) analysis.addObject(ObjectsFem.makeEquationFlow(doc, sol)) analysis.addObject(ObjectsFem.makeEquationFluxsolver(doc, sol)) analysis.addObject(ObjectsFem.makeEquationHeat(doc, sol)) # TODO the equations show up twice on Tree (on solver and on analysis), if they are added to the analysis group doc.recompute() self.assertEqual(len(analysis.Group), testtools.get_defmake_count() - 1) # because of the analysis itself count -1
def setup_base(doc=None, solvertype="ccxtools"): # setup box base model if doc is None: doc = init_doc() # geometry object geom_obj = doc.addObject("Part::Box", "Box") geom_obj.Height = geom_obj.Width = geom_obj.Length = 10 doc.recompute() if FreeCAD.GuiUp: geom_obj.ViewObject.Document.activeView().viewAxonometric() geom_obj.ViewObject.Document.activeView().fitAll() # analysis analysis = ObjectsFem.makeAnalysis(doc, "Analysis") # material material_object = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterial"))[0] mat = material_object.Material mat["Name"] = "Steel-Generic" mat["YoungsModulus"] = "200000 MPa" mat["PoissonRatio"] = "0.30" mat["Density"] = "7900 kg/m^3" if solvertype == "elmer": # set ThermalExpansionCoefficient # FIXME elmer elasticity needs the dictionary key "ThermalExpansionCoefficient" mat["ThermalExpansionCoefficient"] = "0.012 mm/m/K" material_object.Material = mat # mesh from .meshes.mesh_boxanalysis_tetra10 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, mesh_name))[0] femmesh_obj.FemMesh = fem_mesh femmesh_obj.Part = geom_obj femmesh_obj.SecondOrderLinear = False femmesh_obj.CharacteristicLengthMin = "8.0 mm" doc.recompute() return doc
def test_femobjects_isoftype(self): doc = self.active_doc from femtools.femutils import is_of_type self.assertTrue(is_of_type(ObjectsFem.makeAnalysis(doc), 'Fem::FemAnalysis')) self.assertTrue(is_of_type(ObjectsFem.makeConstraintBearing(doc), 'Fem::ConstraintBearing')) self.assertTrue(is_of_type(ObjectsFem.makeConstraintBodyHeatSource(doc), 'Fem::ConstraintBodyHeatSource')) self.assertTrue(is_of_type(ObjectsFem.makeConstraintContact(doc), 'Fem::ConstraintContact')) self.assertTrue(is_of_type(ObjectsFem.makeConstraintDisplacement(doc), 'Fem::ConstraintDisplacement')) self.assertTrue(is_of_type(ObjectsFem.makeConstraintElectrostaticPotential(doc), 'Fem::ConstraintElectrostaticPotential')) self.assertTrue(is_of_type(ObjectsFem.makeConstraintFixed(doc), 'Fem::ConstraintFixed')) self.assertTrue(is_of_type(ObjectsFem.makeConstraintFlowVelocity(doc), 'Fem::ConstraintFlowVelocity')) self.assertTrue(is_of_type(ObjectsFem.makeConstraintFluidBoundary(doc), 'Fem::ConstraintFluidBoundary')) self.assertTrue(is_of_type(ObjectsFem.makeConstraintForce(doc), 'Fem::ConstraintForce')) self.assertTrue(is_of_type(ObjectsFem.makeConstraintGear(doc), 'Fem::ConstraintGear')) self.assertTrue(is_of_type(ObjectsFem.makeConstraintHeatflux(doc), 'Fem::ConstraintHeatflux')) self.assertTrue(is_of_type(ObjectsFem.makeConstraintInitialFlowVelocity(doc), 'Fem::ConstraintInitialFlowVelocity')) self.assertTrue(is_of_type(ObjectsFem.makeConstraintInitialTemperature(doc), 'Fem::ConstraintInitialTemperature')) self.assertTrue(is_of_type(ObjectsFem.makeConstraintPlaneRotation(doc), 'Fem::ConstraintPlaneRotation')) self.assertTrue(is_of_type(ObjectsFem.makeConstraintPressure(doc), 'Fem::ConstraintPressure')) self.assertTrue(is_of_type(ObjectsFem.makeConstraintPulley(doc), 'Fem::ConstraintPulley')) self.assertTrue(is_of_type(ObjectsFem.makeConstraintSelfWeight(doc), 'Fem::ConstraintSelfWeight')) self.assertTrue(is_of_type(ObjectsFem.makeConstraintTemperature(doc), 'Fem::ConstraintTemperature')) self.assertTrue(is_of_type(ObjectsFem.makeConstraintTransform(doc), 'Fem::ConstraintTransform')) self.assertTrue(is_of_type(ObjectsFem.makeElementFluid1D(doc), 'Fem::FemElementFluid1D')) self.assertTrue(is_of_type(ObjectsFem.makeElementGeometry1D(doc), 'Fem::FemElementGeometry1D')) self.assertTrue(is_of_type(ObjectsFem.makeElementGeometry2D(doc), 'Fem::FemElementGeometry2D')) self.assertTrue(is_of_type(ObjectsFem.makeElementRotation1D(doc), 'Fem::FemElementRotation1D')) materialsolid = ObjectsFem.makeMaterialSolid(doc) self.assertTrue(is_of_type(ObjectsFem.makeMaterialFluid(doc), 'Fem::Material')) self.assertTrue(is_of_type(materialsolid, 'Fem::Material')) self.assertTrue(is_of_type(ObjectsFem.makeMaterialMechanicalNonlinear(doc, materialsolid), 'Fem::MaterialMechanicalNonlinear')) mesh = ObjectsFem.makeMeshGmsh(doc) self.assertTrue(is_of_type(mesh, 'Fem::FemMeshGmsh')) self.assertTrue(is_of_type(ObjectsFem.makeMeshBoundaryLayer(doc, mesh), 'Fem::FemMeshBoundaryLayer')) self.assertTrue(is_of_type(ObjectsFem.makeMeshGroup(doc, mesh), 'Fem::FemMeshGroup')) self.assertTrue(is_of_type(ObjectsFem.makeMeshRegion(doc, mesh), 'Fem::FemMeshRegion')) self.assertTrue(is_of_type(ObjectsFem.makeMeshNetgen(doc), 'Fem::FemMeshShapeNetgenObject')) self.assertTrue(is_of_type(ObjectsFem.makeMeshResult(doc), 'Fem::FemMeshResult')) self.assertTrue(is_of_type(ObjectsFem.makeResultMechanical(doc), 'Fem::FemResultMechanical')) solverelmer = ObjectsFem.makeSolverElmer(doc) self.assertTrue(is_of_type(ObjectsFem.makeSolverCalculixCcxTools(doc), 'Fem::FemSolverCalculixCcxTools')) self.assertTrue(is_of_type(ObjectsFem.makeSolverCalculix(doc), 'Fem::FemSolverObjectCalculix')) self.assertTrue(is_of_type(solverelmer, 'Fem::FemSolverObjectElmer')) self.assertTrue(is_of_type(ObjectsFem.makeSolverZ88(doc), 'Fem::FemSolverObjectZ88')) self.assertTrue(is_of_type(ObjectsFem.makeEquationElasticity(doc, solverelmer), 'Fem::FemEquationElmerElasticity')) self.assertTrue(is_of_type(ObjectsFem.makeEquationElectrostatic(doc, solverelmer), 'Fem::FemEquationElmerElectrostatic')) self.assertTrue(is_of_type(ObjectsFem.makeEquationFlow(doc, solverelmer), 'Fem::FemEquationElmerFlow')) self.assertTrue(is_of_type(ObjectsFem.makeEquationFluxsolver(doc, solverelmer), 'Fem::FemEquationElmerFluxsolver')) self.assertTrue(is_of_type(ObjectsFem.makeEquationHeat(doc, solverelmer), 'Fem::FemEquationElmerHeat'))
def test_femobjects_derivedfromstd(self): # only the last True type is used doc = self.active_doc self.assertTrue(ObjectsFem.makeAnalysis(doc).isDerivedFrom('Fem::FemAnalysis')) self.assertTrue(ObjectsFem.makeConstraintBearing(doc).isDerivedFrom('Fem::ConstraintBearing')) self.assertTrue(ObjectsFem.makeConstraintBodyHeatSource(doc).isDerivedFrom('Fem::ConstraintPython')) self.assertTrue(ObjectsFem.makeConstraintContact(doc).isDerivedFrom('Fem::ConstraintContact')) self.assertTrue(ObjectsFem.makeConstraintDisplacement(doc).isDerivedFrom('Fem::ConstraintDisplacement')) self.assertTrue(ObjectsFem.makeConstraintElectrostaticPotential(doc).isDerivedFrom('Fem::ConstraintPython')) self.assertTrue(ObjectsFem.makeConstraintFixed(doc).isDerivedFrom('Fem::ConstraintFixed')) self.assertTrue(ObjectsFem.makeConstraintFlowVelocity(doc).isDerivedFrom('Fem::ConstraintPython')) self.assertTrue(ObjectsFem.makeConstraintFluidBoundary(doc).isDerivedFrom('Fem::ConstraintFluidBoundary')) self.assertTrue(ObjectsFem.makeConstraintForce(doc).isDerivedFrom('Fem::ConstraintForce')) self.assertTrue(ObjectsFem.makeConstraintGear(doc).isDerivedFrom('Fem::ConstraintGear')) self.assertTrue(ObjectsFem.makeConstraintHeatflux(doc).isDerivedFrom('Fem::ConstraintHeatflux')) self.assertTrue(ObjectsFem.makeConstraintInitialFlowVelocity(doc).isDerivedFrom('Fem::ConstraintPython')) self.assertTrue(ObjectsFem.makeConstraintInitialTemperature(doc).isDerivedFrom('Fem::ConstraintInitialTemperature')) self.assertTrue(ObjectsFem.makeConstraintPlaneRotation(doc).isDerivedFrom('Fem::ConstraintPlaneRotation')) self.assertTrue(ObjectsFem.makeConstraintPressure(doc).isDerivedFrom('Fem::ConstraintPressure')) self.assertTrue(ObjectsFem.makeConstraintPulley(doc).isDerivedFrom('Fem::ConstraintPulley')) self.assertTrue(ObjectsFem.makeConstraintSelfWeight(doc).isDerivedFrom('Fem::ConstraintPython')) self.assertTrue(ObjectsFem.makeConstraintTemperature(doc).isDerivedFrom('Fem::ConstraintTemperature')) self.assertTrue(ObjectsFem.makeConstraintTransform(doc).isDerivedFrom('Fem::ConstraintTransform')) self.assertTrue(ObjectsFem.makeElementFluid1D(doc).isDerivedFrom('Fem::FeaturePython')) self.assertTrue(ObjectsFem.makeElementGeometry1D(doc).isDerivedFrom('Fem::FeaturePython')) self.assertTrue(ObjectsFem.makeElementGeometry2D(doc).isDerivedFrom('Fem::FeaturePython')) self.assertTrue(ObjectsFem.makeElementRotation1D(doc).isDerivedFrom('Fem::FeaturePython')) materialsolid = ObjectsFem.makeMaterialSolid(doc) self.assertTrue(ObjectsFem.makeMaterialFluid(doc).isDerivedFrom('App::MaterialObjectPython')) self.assertTrue(materialsolid.isDerivedFrom('App::MaterialObjectPython')) self.assertTrue(ObjectsFem.makeMaterialMechanicalNonlinear(doc, materialsolid).isDerivedFrom('Fem::FeaturePython')) mesh = ObjectsFem.makeMeshGmsh(doc) self.assertTrue(mesh.isDerivedFrom('Fem::FemMeshObjectPython')) self.assertTrue(ObjectsFem.makeMeshBoundaryLayer(doc, mesh).isDerivedFrom('Fem::FeaturePython')) self.assertTrue(ObjectsFem.makeMeshGroup(doc, mesh).isDerivedFrom('Fem::FeaturePython')) self.assertTrue(ObjectsFem.makeMeshRegion(doc, mesh).isDerivedFrom('Fem::FeaturePython')) self.assertTrue(ObjectsFem.makeMeshNetgen(doc).isDerivedFrom('Fem::FemMeshShapeNetgenObject')) self.assertTrue(ObjectsFem.makeMeshResult(doc).isDerivedFrom('Fem::FemMeshObjectPython')) self.assertTrue(ObjectsFem.makeResultMechanical(doc).isDerivedFrom('Fem::FemResultObjectPython')) solverelmer = ObjectsFem.makeSolverElmer(doc) self.assertTrue(ObjectsFem.makeSolverCalculixCcxTools(doc).isDerivedFrom('Fem::FemSolverObjectPython')) self.assertTrue(ObjectsFem.makeSolverCalculix(doc).isDerivedFrom('Fem::FemSolverObjectPython')) self.assertTrue(solverelmer.isDerivedFrom('Fem::FemSolverObjectPython')) self.assertTrue(ObjectsFem.makeSolverZ88(doc).isDerivedFrom('Fem::FemSolverObjectPython')) self.assertTrue(ObjectsFem.makeEquationElasticity(doc, solverelmer).isDerivedFrom('App::FeaturePython')) self.assertTrue(ObjectsFem.makeEquationElectrostatic(doc, solverelmer).isDerivedFrom('App::FeaturePython')) self.assertTrue(ObjectsFem.makeEquationFlow(doc, solverelmer).isDerivedFrom('App::FeaturePython')) self.assertTrue(ObjectsFem.makeEquationFluxsolver(doc, solverelmer).isDerivedFrom('App::FeaturePython')) self.assertTrue(ObjectsFem.makeEquationHeat(doc, solverelmer).isDerivedFrom('App::FeaturePython'))
def setup_base(doc=None, solvertype="ccxtools"): # setup box base model if doc is None: doc = init_doc() # geometry object geom_obj = doc.addObject("Part::Box", "Box") geom_obj.Length = 1000 geom_obj.Width = 200 geom_obj.Height = 100 doc.recompute() if FreeCAD.GuiUp: geom_obj.ViewObject.Document.activeView().viewAxonometric() geom_obj.ViewObject.Document.activeView().fitAll() # analysis analysis = ObjectsFem.makeAnalysis(doc, "Analysis") # material material_object = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterial") )[0] mat = material_object.Material mat["Name"] = "Steel-Generic" mat["YoungsModulus"] = "100 GPa" mat["PoissonRatio"] = "0.30" mat["Density"] = "2330 kg/m^3" material_object.Material = mat # mesh from .meshes.mesh_eigenvalue_of_elastic_beam_tetra10 import create_nodes from .meshes.mesh_eigenvalue_of_elastic_beam_tetra10 import create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, mesh_name))[0] femmesh_obj.FemMesh = fem_mesh femmesh_obj.Part = geom_obj femmesh_obj.SecondOrderLinear = False femmesh_obj.CharacteristicLengthMax = "40.80 mm" doc.recompute() return doc
def setup_boxanalysisbase(doc=None, solvertype="ccxtools"): # init FreeCAD document if doc is None: doc = init_doc() # geometric objects # object name is important in this base setup method # all module which use this base setup, use the object name to find the object geom_obj = doc.addObject("Part::Box", "Box") geom_obj.Height = geom_obj.Width = geom_obj.Length = 10 doc.recompute() if FreeCAD.GuiUp: geom_obj.ViewObject.Document.activeView().viewAxonometric() geom_obj.ViewObject.Document.activeView().fitAll() # analysis analysis = ObjectsFem.makeAnalysis(doc, "Analysis") # material material_obj = ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterial") mat = material_obj.Material mat["Name"] = "Steel-Generic" mat["YoungsModulus"] = "200000 MPa" mat["PoissonRatio"] = "0.30" mat["Density"] = "7900 kg/m^3" material_obj.Material = mat analysis.addObject(material_obj) # mesh from .meshes.mesh_boxanalysis_tetra10 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") femmesh_obj = analysis.addObject( ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0] femmesh_obj.FemMesh = fem_mesh femmesh_obj.Part = geom_obj femmesh_obj.SecondOrderLinear = False femmesh_obj.CharacteristicLengthMin = "8.0 mm" doc.recompute() return doc
def setup_base(doc=None, solvertype="ccxtools"): # setup box base model if doc is None: doc = init_doc() # part box_obj = doc.addObject("Part::Box", "Box") box_obj.Height = box_obj.Width = box_obj.Length = 10 doc.recompute() if FreeCAD.GuiUp: import FreeCADGui FreeCADGui.ActiveDocument.activeView().viewAxonometric() FreeCADGui.SendMsgToActiveView("ViewFit") # analysis analysis = ObjectsFem.makeAnalysis(doc, "Analysis") # material material_object = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterial") )[0] mat = material_object.Material mat["Name"] = "Steel-Generic" mat["YoungsModulus"] = "200000 MPa" mat["PoissonRatio"] = "0.30" mat["Density"] = "7900 kg/m^3" material_object.Material = mat # mesh from .meshes.mesh_boxanalysis_tetra10 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") femmesh_obj = analysis.addObject( doc.addObject("Fem::FemMeshObject", mesh_name) )[0] femmesh_obj.FemMesh = fem_mesh doc.recompute() return doc
def myaddCompound(obj, count): # count == 0 World Volume print("Add Compound " + obj.Label) volList = [] matList = [] addToList(volList, matList, obj) if count == 0: del volList[0] del matList[0] # DO not delete World Material as it may be repeat print('vol List') print(volList) print('Material List') print(matList) doc = FreeCAD.activeDocument() analysis_object = ObjectsFem.makeAnalysis(doc, "Analysis") materials = FreeCAD.ActiveDocument.Materials for m in matList: allocateMaterial(doc, analysis_object, materials, m) comp = obj.newObject("Part::Compound", "Compound") comp.Links = volList FreeCAD.ActiveDocument.recompute()
def test_5_Flow1D_thermomech_analysis(self): fcc_print('--------------- Start of 1D Flow FEM tests ---------------') import Draft p1 = FreeCAD.Vector(0, 0, 50) p2 = FreeCAD.Vector(0, 0, -50) p3 = FreeCAD.Vector(0, 0, -4300) p4 = FreeCAD.Vector(4950, 0, -4300) p5 = FreeCAD.Vector(5000, 0, -4300) p6 = FreeCAD.Vector(8535.53, 0, -7835.53) p7 = FreeCAD.Vector(8569.88, 0, -7870.88) p8 = FreeCAD.Vector(12105.41, 0, -11406.41) p9 = FreeCAD.Vector(12140.76, 0, -11441.76) p10 = FreeCAD.Vector(13908.53, 0, -13209.53) p11 = FreeCAD.Vector(13943.88, 0, -13244.88) p12 = FreeCAD.Vector(15046.97, 0, -14347.97) p13 = FreeCAD.Vector(15046.97, 0, -7947.97) p14 = FreeCAD.Vector(15046.97, 0, -7847.97) p15 = FreeCAD.Vector(0, 0, 0) p16 = FreeCAD.Vector(0, 0, -2175) p17 = FreeCAD.Vector(2475, 0, -4300) p18 = FreeCAD.Vector(4975, 0, -4300) p19 = FreeCAD.Vector(6767.765, 0, -6067.765) p20 = FreeCAD.Vector(8552.705, 0, -7853.205) p21 = FreeCAD.Vector(10337.645, 0, -9638.645) p22 = FreeCAD.Vector(12123.085, 0, -11424.085) p23 = FreeCAD.Vector(13024.645, 0, -12325.645) p24 = FreeCAD.Vector(13926.205, 0, -13227.205) p25 = FreeCAD.Vector(14495.425, 0, -13796.425) p26 = FreeCAD.Vector(15046.97, 0, -11147.97) p27 = FreeCAD.Vector(15046.97, 0, -7897.97) points = [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27] line = Draft.makeWire(points, closed=False, face=False, support=None) fcc_print('Checking FEM new analysis...') analysis = ObjectsFem.makeAnalysis(self.active_doc, 'Analysis') self.assertTrue(analysis, "FemTest of new analysis failed") fcc_print('Checking FEM new solver...') solver_object = ObjectsFem.makeSolverCalculixCcxTools(self.active_doc, 'CalculiX') solver_object.AnalysisType = 'thermomech' solver_object.GeometricalNonlinearity = 'linear' solver_object.ThermoMechSteadyState = True solver_object.MatrixSolverType = 'default' solver_object.IterationsThermoMechMaximum = 2000 solver_object.IterationsControlParameterTimeUse = False self.assertTrue(solver_object, "FemTest of new solver failed") analysis.addObject(solver_object) fcc_print('Checking FEM new material...') material_object = ObjectsFem.makeMaterialFluid(self.active_doc, 'FluidMaterial') mat = material_object.Material mat['Name'] = "Water" mat['Density'] = "998 kg/m^3" mat['SpecificHeat'] = "4.182 J/kg/K" mat['DynamicViscosity'] = "1.003e-3 kg/m/s" mat['VolumetricThermalExpansionCoefficient'] = "2.07e-4 m/m/K" mat['ThermalConductivity'] = "0.591 W/m/K" material_object.Material = mat self.assertTrue(material_object, "FemTest of new material failed") analysis.addObject(material_object) fcc_print('Checking FEM Flow1D inlet constraint...') Flow1d_inlet = ObjectsFem.makeElementFluid1D(self.active_doc, "ElementFluid1D") Flow1d_inlet.SectionType = 'Liquid' Flow1d_inlet.LiquidSectionType = 'PIPE INLET' Flow1d_inlet.InletPressure = 0.1 Flow1d_inlet.References = [(line, "Edge1")] self.assertTrue(Flow1d_inlet, "FemTest of new Flow1D inlet constraint failed") analysis.addObject(Flow1d_inlet) fcc_print('Checking FEM new Flow1D entrance constraint...') Flow1d_entrance = ObjectsFem.makeElementFluid1D(self.active_doc, "ElementFluid1D") Flow1d_entrance.SectionType = 'Liquid' Flow1d_entrance.LiquidSectionType = 'PIPE ENTRANCE' Flow1d_entrance.EntrancePipeArea = 31416.00 Flow1d_entrance.EntranceArea = 25133.00 Flow1d_entrance.References = [(line, "Edge2")] self.assertTrue(Flow1d_entrance, "FemTest of new Flow1D entrance constraint failed") analysis.addObject(Flow1d_entrance) fcc_print('Checking FEM new Flow1D manning constraint...') Flow1d_manning = ObjectsFem.makeElementFluid1D(self.active_doc, "ElementFluid1D") Flow1d_manning.SectionType = 'Liquid' Flow1d_manning.LiquidSectionType = 'PIPE MANNING' Flow1d_manning.ManningArea = 31416 Flow1d_manning.ManningRadius = 50 Flow1d_manning.ManningCoefficient = 0.002 Flow1d_manning.References = [(line, "Edge3"), (line, "Edge5")] self.assertTrue(Flow1d_manning, "FemTest of new Flow1D manning constraint failed") analysis.addObject(Flow1d_manning) fcc_print('Checking FEM new Flow1D bend constraint...') Flow1d_bend = ObjectsFem.makeElementFluid1D(self.active_doc, "ElementFluid1D") Flow1d_bend.SectionType = 'Liquid' Flow1d_bend.LiquidSectionType = 'PIPE BEND' Flow1d_bend.BendPipeArea = 31416 Flow1d_bend.BendRadiusDiameter = 1.5 Flow1d_bend.BendAngle = 45 Flow1d_bend.BendLossCoefficient = 0.4 Flow1d_bend.References = [(line, "Edge4")] self.assertTrue(Flow1d_bend, "FemTest of new Flow1D bend constraint failed") analysis.addObject(Flow1d_bend) fcc_print('Checking FEM new Flow1D enlargement constraint...') Flow1d_enlargement = ObjectsFem.makeElementFluid1D(self.active_doc, "ElementFluid1D") Flow1d_enlargement.SectionType = 'Liquid' Flow1d_enlargement.LiquidSectionType = 'PIPE ENLARGEMENT' Flow1d_enlargement.EnlargeArea1 = 31416.00 Flow1d_enlargement.EnlargeArea2 = 70686.00 Flow1d_enlargement.References = [(line, "Edge6")] self.assertTrue(Flow1d_enlargement, "FemTest of new Flow1D enlargement constraint failed") analysis.addObject(Flow1d_enlargement) fcc_print('Checking FEM new Flow1D manning constraint...') Flow1d_manning1 = ObjectsFem.makeElementFluid1D(self.active_doc, "ElementFluid1D") Flow1d_manning1.SectionType = 'Liquid' Flow1d_manning1.LiquidSectionType = 'PIPE MANNING' Flow1d_manning1.ManningArea = 70686.00 Flow1d_manning1.ManningRadius = 75 Flow1d_manning1.ManningCoefficient = 0.002 Flow1d_manning1.References = [(line, "Edge7")] self.assertTrue(Flow1d_manning1, "FemTest of new Flow1D manning constraint failed") analysis.addObject(Flow1d_manning1) fcc_print('Checking FEM new Flow1D contraction constraint...') Flow1d_contraction = ObjectsFem.makeElementFluid1D(self.active_doc, "ElementFluid1D") Flow1d_contraction.SectionType = 'Liquid' Flow1d_contraction.LiquidSectionType = 'PIPE CONTRACTION' Flow1d_contraction.ContractArea1 = 70686 Flow1d_contraction.ContractArea2 = 17671 Flow1d_contraction.References = [(line, "Edge8")] self.assertTrue(Flow1d_contraction, "FemTest of new Flow1D contraction constraint failed") analysis.addObject(Flow1d_contraction) fcc_print('Checking FEM new Flow1D manning constraint...') Flow1d_manning2 = ObjectsFem.makeElementFluid1D(self.active_doc, "ElementFluid1D") Flow1d_manning2.SectionType = 'Liquid' Flow1d_manning2.LiquidSectionType = 'PIPE MANNING' Flow1d_manning2.ManningArea = 17671.00 Flow1d_manning2.ManningRadius = 37.5 Flow1d_manning2.ManningCoefficient = 0.002 Flow1d_manning2.References = [(line, "Edge11"), (line, "Edge9")] self.assertTrue(Flow1d_manning2, "FemTest of new Flow1D manning constraint failed") analysis.addObject(Flow1d_manning2) fcc_print('Checking FEM new Flow1D gate valve constraint...') Flow1d_gate_valve = ObjectsFem.makeElementFluid1D(self.active_doc, "ElementFluid1D") Flow1d_gate_valve.SectionType = 'Liquid' Flow1d_gate_valve.LiquidSectionType = 'PIPE GATE VALVE' Flow1d_gate_valve.GateValvePipeArea = 17671 Flow1d_gate_valve.GateValveClosingCoeff = 0.5 Flow1d_gate_valve.References = [(line, "Edge10")] self.assertTrue(Flow1d_gate_valve, "FemTest of new Flow1D gate valve constraint failed") analysis.addObject(Flow1d_gate_valve) fcc_print('Checking FEM new Flow1D enlargement constraint...') Flow1d_enlargement1 = ObjectsFem.makeElementFluid1D(self.active_doc, "ElementFluid1D") Flow1d_enlargement1.SectionType = 'Liquid' Flow1d_enlargement1.LiquidSectionType = 'PIPE ENLARGEMENT' Flow1d_enlargement1.EnlargeArea1 = 17671 Flow1d_enlargement1.EnlargeArea2 = 1e12 Flow1d_enlargement1.References = [(line, "Edge12")] self.assertTrue(Flow1d_enlargement1, "FemTest of new Flow1D enlargement constraint failed") analysis.addObject(Flow1d_enlargement1) fcc_print('Checking FEM Flow1D outlet constraint...') Flow1d_outlet = ObjectsFem.makeElementFluid1D(self.active_doc, "ElementFluid1D") Flow1d_outlet.SectionType = 'Liquid' Flow1d_outlet.LiquidSectionType = 'PIPE OUTLET' Flow1d_outlet.OutletPressure = 0.1 Flow1d_outlet.References = [(line, "Edge13")] self.assertTrue(Flow1d_outlet, "FemTest of new Flow1D inlet constraint failed") analysis.addObject(Flow1d_outlet) fcc_print('Checking FEM self weight constraint...') Flow1d_self_weight = ObjectsFem.makeConstraintSelfWeight(self.active_doc, "ConstraintSelfWeight") Flow1d_self_weight.Gravity_x = 0.0 Flow1d_self_weight.Gravity_y = 0.0 Flow1d_self_weight.Gravity_z = -1.0 self.assertTrue(Flow1d_outlet, "FemTest of new Flow1D self weight constraint failed") analysis.addObject(Flow1d_self_weight) fcc_print('Checking FEM new mesh...') from .testfiles.ccx.Flow1D_mesh import create_nodes_Flow1D from .testfiles.ccx.Flow1D_mesh import create_elements_Flow1D mesh = Fem.FemMesh() ret = create_nodes_Flow1D(mesh) self.assertTrue(ret, "Import of mesh nodes failed") ret = create_elements_Flow1D(mesh) self.assertTrue(ret, "Import of mesh volumes failed") mesh_object = self.active_doc.addObject('Fem::FemMeshObject', self.mesh_name) mesh_object.FemMesh = mesh self.assertTrue(mesh, "FemTest of new mesh failed") analysis.addObject(mesh_object) self.active_doc.recompute() Flow1D_thermomech_analysis_dir = self.temp_dir + 'FEM_ccx_Flow1D_thermomech/' fea = ccxtools.FemToolsCcx(analysis, test_mode=True) fcc_print('Setting up working directory {}'.format(Flow1D_thermomech_analysis_dir)) fea.setup_working_dir(Flow1D_thermomech_analysis_dir) self.assertTrue(True if fea.working_dir == Flow1D_thermomech_analysis_dir else False, "Setting working directory {} failed".format(Flow1D_thermomech_analysis_dir)) fcc_print('Checking FEM inp file prerequisites for thermo-mechanical analysis...') error = fea.check_prerequisites() self.assertFalse(error, "ccxtools check_prerequisites returned error message: {}".format(error)) fcc_print('Checking FEM inp file write...') fcc_print('Writing {}/{}.inp for thermomech analysis'.format(Flow1D_thermomech_analysis_dir, self.mesh_name)) error = fea.write_inp_file() self.assertFalse(error, "Writing failed") Flow1D_thermomech_base_name = 'Flow1D_thermomech' Flow1D_thermomech_analysis_inp_file = self.test_file_dir + Flow1D_thermomech_base_name + '.inp' fcc_print('Comparing {} to {}/{}.inp'.format(Flow1D_thermomech_analysis_inp_file, Flow1D_thermomech_analysis_dir, self.mesh_name)) ret = testtools.compare_inp_files(Flow1D_thermomech_analysis_inp_file, Flow1D_thermomech_analysis_dir + self.mesh_name + '.inp') self.assertFalse(ret, "ccxtools write_inp_file test failed.\n{}".format(ret)) fcc_print('Setting up working directory to {} in order to read simulated calculations'.format(self.test_file_dir)) fea.setup_working_dir(self.test_file_dir) self.assertTrue(True if fea.working_dir == self.test_file_dir else False, "Setting working directory {} failed".format(self.test_file_dir)) fcc_print('Setting base name to read test {}.frd file...'.format('Flow1D_thermomech')) fea.set_base_name(Flow1D_thermomech_base_name) self.assertTrue(True if fea.base_name == Flow1D_thermomech_base_name else False, "Setting base name to {} failed".format(Flow1D_thermomech_base_name)) fcc_print('Setting inp file name to read test {}.frd file...'.format('Flow1D_thermomech')) fea.set_inp_file_name() self.assertTrue(True if fea.inp_file_name == Flow1D_thermomech_analysis_inp_file else False, "Setting inp file name to {} failed".format(Flow1D_thermomech_analysis_inp_file)) fcc_print('Checking FEM frd file read from Flow1D thermomech analysis...') fea.load_results() self.assertTrue(fea.results_present, "Cannot read results from {}.frd frd file".format(fea.base_name)) fcc_print('Reading stats from result object for Flow1D thermomech analysis...') Flow1D_thermomech_expected_values = self.test_file_dir + "Flow1D_thermomech_expected_values" stat_types = ["U1", "U2", "U3", "Uabs", "Sabs", "MaxPrin", "MidPrin", "MinPrin", "MaxShear", "Peeq", "Temp", "MFlow", "NPress"] ret = testtools.compare_stats(fea, Flow1D_thermomech_expected_values, stat_types, 'CalculiX_thermomech_time_1_0_results') self.assertFalse(ret, "Invalid results read from .frd file") Flow1D_thermomech_save_fc_file = Flow1D_thermomech_analysis_dir + Flow1D_thermomech_base_name + '.fcstd' fcc_print('Save FreeCAD file for thermomech analysis to {}...'.format(Flow1D_thermomech_save_fc_file)) self.active_doc.saveAs(Flow1D_thermomech_save_fc_file) fcc_print('--------------- End of FEM tests FLow 1D thermomech analysis ---------------')
def test_1_static_analysis(self): fcc_print('--------------- Start of FEM tests ---------------') box = self.active_doc.addObject("Part::Box", "Box") fcc_print('Checking FEM new analysis...') analysis = ObjectsFem.makeAnalysis(self.active_doc, 'Analysis') self.assertTrue(analysis, "FemTest of new analysis failed") fcc_print('Checking FEM new solver...') solver_object = ObjectsFem.makeSolverCalculixCcxTools(self.active_doc, 'CalculiX') solver_object.AnalysisType = 'static' solver_object.GeometricalNonlinearity = 'linear' solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = 'default' solver_object.IterationsControlParameterTimeUse = False solver_object.EigenmodesCount = 10 solver_object.EigenmodeHighLimit = 1000000.0 solver_object.EigenmodeLowLimit = 0.0 self.assertTrue(solver_object, "FemTest of new solver failed") analysis.addObject(solver_object) fcc_print('Checking FEM new material...') material_object = ObjectsFem.makeMaterialSolid(self.active_doc, 'MechanicalMaterial') mat = material_object.Material mat['Name'] = "Steel-Generic" mat['YoungsModulus'] = "200000 MPa" mat['PoissonRatio'] = "0.30" mat['Density'] = "7900 kg/m^3" material_object.Material = mat self.assertTrue(material_object, "FemTest of new material failed") analysis.addObject(material_object) fcc_print('Checking FEM new fixed constraint...') fixed_constraint = self.active_doc.addObject("Fem::ConstraintFixed", "FemConstraintFixed") fixed_constraint.References = [(box, "Face1")] self.assertTrue(fixed_constraint, "FemTest of new fixed constraint failed") analysis.addObject(fixed_constraint) fcc_print('Checking FEM new force constraint...') force_constraint = self.active_doc.addObject("Fem::ConstraintForce", "FemConstraintForce") force_constraint.References = [(box, "Face6")] force_constraint.Force = 40000.0 force_constraint.Direction = (box, ["Edge5"]) self.active_doc.recompute() force_constraint.Reversed = True self.active_doc.recompute() self.assertTrue(force_constraint, "FemTest of new force constraint failed") analysis.addObject(force_constraint) fcc_print('Checking FEM new pressure constraint...') pressure_constraint = self.active_doc.addObject("Fem::ConstraintPressure", "FemConstraintPressure") pressure_constraint.References = [(box, "Face2")] pressure_constraint.Pressure = 1000.0 pressure_constraint.Reversed = False self.assertTrue(pressure_constraint, "FemTest of new pressure constraint failed") analysis.addObject(pressure_constraint) fcc_print('Checking FEM new mesh...') from .testfiles.ccx.cube_mesh import create_nodes_cube from .testfiles.ccx.cube_mesh import create_elements_cube mesh = Fem.FemMesh() ret = create_nodes_cube(mesh) self.assertTrue(ret, "Import of mesh nodes failed") ret = create_elements_cube(mesh) self.assertTrue(ret, "Import of mesh volumes failed") mesh_object = self.active_doc.addObject('Fem::FemMeshObject', self.mesh_name) mesh_object.FemMesh = mesh self.assertTrue(mesh, "FemTest of new mesh failed") analysis.addObject(mesh_object) self.active_doc.recompute() static_analysis_dir = testtools.get_unit_test_tmp_dir(self.temp_dir, 'FEM_ccx_static/') fea = ccxtools.FemToolsCcx(analysis, solver_object, test_mode=True) fcc_print('Setting up working directory {}'.format(static_analysis_dir)) fea.setup_working_dir(static_analysis_dir) self.assertTrue(True if fea.working_dir == static_analysis_dir else False, "Setting working directory {} failed".format(static_analysis_dir)) fcc_print('Checking FEM inp file prerequisites for static analysis...') error = fea.check_prerequisites() self.assertFalse(error, "ccxtools check_prerequisites returned error message: {}".format(error)) fcc_print('Checking FEM inp file write...') fcc_print('Writing {}/{}.inp for static analysis'.format(static_analysis_dir, self.mesh_name)) error = fea.write_inp_file() self.assertFalse(error, "Writing failed") static_base_name = 'cube_static' static_analysis_inp_file = self.test_file_dir + static_base_name + '.inp' fcc_print('Comparing {} to {}/{}.inp'.format(static_analysis_inp_file, static_analysis_dir, self.mesh_name)) ret = testtools.compare_inp_files(static_analysis_inp_file, static_analysis_dir + self.mesh_name + '.inp') self.assertFalse(ret, "ccxtools write_inp_file test failed.\n{}".format(ret)) fcc_print('Setting up working directory to {} in order to read simulated calculations'.format(self.test_file_dir)) fea.setup_working_dir(self.test_file_dir) self.assertTrue(True if fea.working_dir == self.test_file_dir else False, "Setting working directory {} failed".format(self.test_file_dir)) fcc_print('Setting base name to read test {}.frd file...'.format('cube_static')) fea.set_base_name(static_base_name) self.assertTrue(True if fea.base_name == static_base_name else False, "Setting base name to {} failed".format(static_base_name)) fcc_print('Setting inp file name to read test {}.frd file...'.format('cube_static')) fea.set_inp_file_name() self.assertTrue(True if fea.inp_file_name == static_analysis_inp_file else False, "Setting inp file name to {} failed".format(static_analysis_inp_file)) fcc_print('Checking FEM frd file read from static analysis...') fea.load_results() self.assertTrue(fea.results_present, "Cannot read results from {}.frd frd file".format(fea.base_name)) fcc_print('Reading stats from result object for static analysis...') static_expected_values = self.test_file_dir + "cube_static_expected_values" ret = testtools.compare_stats(fea, static_expected_values, 'CalculiX_static_results') self.assertFalse(ret, "Invalid results read from .frd file") static_save_fc_file = static_analysis_dir + static_base_name + '.fcstd' fcc_print('Save FreeCAD file for static analysis to {}...'.format(static_save_fc_file)) self.active_doc.saveAs(static_save_fc_file) fcc_print('--------------- End of FEM tests static and analysis ---------------')
def test_4_thermomech_analysis(self): fcc_print('--------------- Start of FEM tests ---------------') box = self.active_doc.addObject("Part::Box", "Box") box.Height = 25.4 box.Width = 25.4 box.Length = 203.2 fcc_print('Checking FEM new analysis...') analysis = ObjectsFem.makeAnalysis(self.active_doc, 'Analysis') self.assertTrue(analysis, "FemTest of new analysis failed") fcc_print('Checking FEM new solver...') solver_object = ObjectsFem.makeSolverCalculixCcxTools(self.active_doc, 'CalculiX') solver_object.AnalysisType = 'thermomech' solver_object.GeometricalNonlinearity = 'linear' solver_object.ThermoMechSteadyState = True solver_object.MatrixSolverType = 'default' solver_object.IterationsThermoMechMaximum = 2000 solver_object.IterationsControlParameterTimeUse = True self.assertTrue(solver_object, "FemTest of new solver failed") analysis.addObject(solver_object) fcc_print('Checking FEM new material...') material_object = ObjectsFem.makeMaterialSolid(self.active_doc, 'MechanicalMaterial') mat = material_object.Material mat['Name'] = "Steel-Generic" mat['YoungsModulus'] = "200000 MPa" mat['PoissonRatio'] = "0.30" mat['Density'] = "7900 kg/m^3" mat['ThermalConductivity'] = "43.27 W/m/K" # SvdW: Change to Ansys model values mat['ThermalExpansionCoefficient'] = "12 um/m/K" mat['SpecificHeat'] = "500 J/kg/K" # SvdW: Change to Ansys model values material_object.Material = mat self.assertTrue(material_object, "FemTest of new material failed") analysis.addObject(material_object) fcc_print('Checking FEM new fixed constraint...') fixed_constraint = self.active_doc.addObject("Fem::ConstraintFixed", "FemConstraintFixed") fixed_constraint.References = [(box, "Face1")] self.assertTrue(fixed_constraint, "FemTest of new fixed constraint failed") analysis.addObject(fixed_constraint) fcc_print('Checking FEM new initial temperature constraint...') initialtemperature_constraint = self.active_doc.addObject("Fem::ConstraintInitialTemperature", "FemConstraintInitialTemperature") initialtemperature_constraint.initialTemperature = 300.0 self.assertTrue(initialtemperature_constraint, "FemTest of new initial temperature constraint failed") analysis.addObject(initialtemperature_constraint) fcc_print('Checking FEM new temperature constraint...') temperature_constraint = self.active_doc.addObject("Fem::ConstraintTemperature", "FemConstraintTemperature") temperature_constraint.References = [(box, "Face1")] temperature_constraint.Temperature = 310.93 self.assertTrue(temperature_constraint, "FemTest of new temperature constraint failed") analysis.addObject(temperature_constraint) fcc_print('Checking FEM new heatflux constraint...') heatflux_constraint = self.active_doc.addObject("Fem::ConstraintHeatflux", "FemConstraintHeatflux") heatflux_constraint.References = [(box, "Face3"), (box, "Face4"), (box, "Face5"), (box, "Face6")] heatflux_constraint.AmbientTemp = 255.3722 heatflux_constraint.FilmCoef = 5.678 self.assertTrue(heatflux_constraint, "FemTest of new heatflux constraint failed") analysis.addObject(heatflux_constraint) fcc_print('Checking FEM new mesh...') from .testfiles.ccx.spine_mesh import create_nodes_spine from .testfiles.ccx.spine_mesh import create_elements_spine mesh = Fem.FemMesh() ret = create_nodes_spine(mesh) self.assertTrue(ret, "Import of mesh nodes failed") ret = create_elements_spine(mesh) self.assertTrue(ret, "Import of mesh volumes failed") mesh_object = self.active_doc.addObject('Fem::FemMeshObject', self.mesh_name) mesh_object.FemMesh = mesh self.assertTrue(mesh, "FemTest of new mesh failed") analysis.addObject(mesh_object) self.active_doc.recompute() thermomech_analysis_dir = self.temp_dir + 'FEM_ccx_thermomech/' fea = ccxtools.FemToolsCcx(analysis, test_mode=True) fcc_print('Setting up working directory {}'.format(thermomech_analysis_dir)) fea.setup_working_dir(thermomech_analysis_dir) self.assertTrue(True if fea.working_dir == thermomech_analysis_dir else False, "Setting working directory {} failed".format(thermomech_analysis_dir)) fcc_print('Checking FEM inp file prerequisites for thermo-mechanical analysis...') error = fea.check_prerequisites() self.assertFalse(error, "ccxtools check_prerequisites returned error message: {}".format(error)) fcc_print('Checking FEM inp file write...') fcc_print('Writing {}/{}.inp for thermomech analysis'.format(thermomech_analysis_dir, self.mesh_name)) error = fea.write_inp_file() self.assertFalse(error, "Writing failed") thermomech_base_name = 'spine_thermomech' thermomech_analysis_inp_file = self.test_file_dir + thermomech_base_name + '.inp' fcc_print('Comparing {} to {}/{}.inp'.format(thermomech_analysis_inp_file, thermomech_analysis_dir, self.mesh_name)) ret = testtools.compare_inp_files(thermomech_analysis_inp_file, thermomech_analysis_dir + self.mesh_name + '.inp') self.assertFalse(ret, "ccxtools write_inp_file test failed.\n{}".format(ret)) fcc_print('Setting up working directory to {} in order to read simulated calculations'.format(self.test_file_dir)) fea.setup_working_dir(self.test_file_dir) self.assertTrue(True if fea.working_dir == self.test_file_dir else False, "Setting working directory {} failed".format(self.test_file_dir)) fcc_print('Setting base name to read test {}.frd file...'.format('spine_thermomech')) fea.set_base_name(thermomech_base_name) self.assertTrue(True if fea.base_name == thermomech_base_name else False, "Setting base name to {} failed".format(thermomech_base_name)) fcc_print('Setting inp file name to read test {}.frd file...'.format('spine_thermomech')) fea.set_inp_file_name() self.assertTrue(True if fea.inp_file_name == thermomech_analysis_inp_file else False, "Setting inp file name to {} failed".format(thermomech_analysis_inp_file)) fcc_print('Checking FEM frd file read from thermomech analysis...') fea.load_results() self.assertTrue(fea.results_present, "Cannot read results from {}.frd frd file".format(fea.base_name)) fcc_print('Reading stats from result object for thermomech analysis...') thermomech_expected_values = self.test_file_dir + "spine_thermomech_expected_values" ret = testtools.compare_stats(fea, thermomech_expected_values, 'CalculiX_thermomech_results') self.assertFalse(ret, "Invalid results read from .frd file") thermomech_save_fc_file = thermomech_analysis_dir + thermomech_base_name + '.fcstd' fcc_print('Save FreeCAD file for thermomech analysis to {}...'.format(thermomech_save_fc_file)) self.active_doc.saveAs(thermomech_save_fc_file) fcc_print('--------------- End of FEM tests thermomech analysis ---------------')
def test_2_static_multiple_material(self): fcc_print('--------------- Start of FEM ccxtools multiple material test ---------------') # create a CompSolid of two Boxes extract the CompSolid (we are able to remesh if needed) boxlow = self.active_doc.addObject("Part::Box", "BoxLower") boxupp = self.active_doc.addObject("Part::Box", "BoxUpper") boxupp.Placement.Base = (0, 0, 10) # for BooleanFragments Occt >=6.9 is needed ''' import BOPTools.SplitFeatures bf = BOPTools.SplitFeatures.makeBooleanFragments(name='BooleanFragments') bf.Objects = [boxlow, boxupp] bf.Mode = "CompSolid" self.active_doc.recompute() bf.Proxy.execute(bf) bf.purgeTouched() for obj in bf.ViewObject.Proxy.claimChildren(): obj.ViewObject.hide() self.active_doc.recompute() import CompoundTools.CompoundFilter cf = CompoundTools.CompoundFilter.makeCompoundFilter(name='MultiMatCompSolid') cf.Base = bf cf.FilterType = 'window-volume' cf.Proxy.execute(cf) cf.purgeTouched() cf.Base.ViewObject.hide() ''' self.active_doc.recompute() if FreeCAD.GuiUp: import FreeCADGui FreeCADGui.ActiveDocument.activeView().viewAxonometric() FreeCADGui.SendMsgToActiveView("ViewFit") analysis = ObjectsFem.makeAnalysis(self.active_doc, 'Analysis') solver_object = ObjectsFem.makeSolverCalculixCcxTools(self.active_doc, 'CalculiXccxTools') solver_object.AnalysisType = 'static' solver_object.GeometricalNonlinearity = 'linear' solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = 'default' solver_object.IterationsControlParameterTimeUse = False analysis.addObject(solver_object) material_object_low = ObjectsFem.makeMaterialSolid(self.active_doc, 'MechanicalMaterialLow') mat = material_object_low.Material mat['Name'] = "Aluminium-Generic" mat['YoungsModulus'] = "70000 MPa" mat['PoissonRatio'] = "0.35" mat['Density'] = "2700 kg/m^3" material_object_low.Material = mat material_object_low.References = [(boxlow, 'Solid1')] analysis.addObject(material_object_low) material_object_upp = ObjectsFem.makeMaterialSolid(self.active_doc, 'MechanicalMaterialUpp') mat = material_object_upp.Material mat['Name'] = "Steel-Generic" mat['YoungsModulus'] = "200000 MPa" mat['PoissonRatio'] = "0.30" mat['Density'] = "7980 kg/m^3" material_object_upp.Material = mat material_object_upp.References = [(boxupp, 'Solid1')] analysis.addObject(material_object_upp) fixed_constraint = self.active_doc.addObject("Fem::ConstraintFixed", "ConstraintFixed") # fixed_constraint.References = [(cf, "Face3")] fixed_constraint.References = [(boxlow, "Face5")] analysis.addObject(fixed_constraint) pressure_constraint = self.active_doc.addObject("Fem::ConstraintPressure", "ConstraintPressure") # pressure_constraint.References = [(cf, "Face9")] pressure_constraint.References = [(boxupp, "Face6")] pressure_constraint.Pressure = 1000.0 pressure_constraint.Reversed = False analysis.addObject(pressure_constraint) mesh = Fem.FemMesh() import femtest.testfiles.ccx.multimat_mesh as multimatmesh multimatmesh.create_nodes(mesh) multimatmesh.create_elements(mesh) mesh_object = self.active_doc.addObject('Fem::FemMeshObject', self.mesh_name) mesh_object.FemMesh = mesh analysis.addObject(mesh_object) self.active_doc.recompute() static_multiplemat_dir = testtools.get_unit_test_tmp_dir(self.temp_dir, 'FEM_ccx_multimat/') fea = ccxtools.FemToolsCcx(analysis, solver_object, test_mode=True) fea.setup_working_dir(static_multiplemat_dir) fcc_print('Checking FEM inp file prerequisites for ccxtools multimat analysis...') error = fea.check_prerequisites() self.assertFalse(error, "ccxtools check_prerequisites returned error message: {}".format(error)) fcc_print('Checking FEM inp file write...') fcc_print('Writing {}/{}.inp for static multiple material'.format(static_multiplemat_dir, self.mesh_name)) error = fea.write_inp_file() self.assertFalse(error, "Writing failed") static_base_name = 'multimat' static_analysis_inp_file = self.test_file_dir + static_base_name + '.inp' fcc_print('Comparing {} to {}/{}.inp'.format(static_analysis_inp_file, static_multiplemat_dir, self.mesh_name)) ret = testtools.compare_inp_files(static_analysis_inp_file, static_multiplemat_dir + self.mesh_name + '.inp') self.assertFalse(ret, "ccxtools write_inp_file test failed.\n{}".format(ret)) static_save_fc_file = static_multiplemat_dir + static_base_name + '.fcstd' fcc_print('Save FreeCAD file for static analysis to {}...'.format(static_save_fc_file)) self.active_doc.saveAs(static_save_fc_file) fcc_print('--------------- End of FEM ccxtools multiple material test ---------------')
def create_new_analysis(self): self.analysis = ObjectsFem.makeAnalysis('Analysis') self.active_doc.recompute()
def setup(doc=None, solvertype="ccxtools"): # init FreeCAD document if doc is None: doc = init_doc() # explanation object # just keep the following line and change text string in get_explanation method manager.add_explanation_obj( doc, get_explanation(manager.get_header(get_information()))) # geometric object # name is important because the other method in this module use obj name l1 = Part.makeLine((-142.5, -142.5, 0), (142.5, -142.5, 0)) l2 = Part.makeLine((142.5, -142.5, 0), (142.5, 142.5, 0)) l3 = Part.makeLine((142.5, 142.5, 0), (-142.5, 142.5, 0)) l4 = Part.makeLine((-142.5, 142.5, 0), (-142.5, -142.5, 0)) wire = Part.Wire([l1, l2, l3, l4]) shape = wire.extrude(Vector(0, 0, 1000)) geom_obj = doc.addObject('Part::Feature', 'SquareTube') geom_obj.Shape = shape doc.recompute() if FreeCAD.GuiUp: geom_obj.ViewObject.Document.activeView().viewAxonometric() geom_obj.ViewObject.Document.activeView().fitAll() # analysis analysis = ObjectsFem.makeAnalysis(doc, "Analysis") # solver if solvertype == "calculix": solver_obj = ObjectsFem.makeSolverCalculix(doc, "SolverCalculiX") elif solvertype == "ccxtools": solver_obj = ObjectsFem.makeSolverCalculixCcxTools( doc, "CalculiXccxTools") solver_obj.WorkingDir = u"" else: FreeCAD.Console.PrintWarning( "Not known or not supported solver type: {}. " "No solver object was created.\n".format(solvertype)) if solvertype == "calculix" or solvertype == "ccxtools": solver_obj.SplitInputWriter = False solver_obj.AnalysisType = "static" solver_obj.GeometricalNonlinearity = "linear" solver_obj.ThermoMechSteadyState = False solver_obj.MatrixSolverType = "default" solver_obj.IterationsControlParameterTimeUse = False analysis.addObject(solver_obj) # shell thickness thickness_obj = ObjectsFem.makeElementGeometry2D(doc, 15.0, "ShellThickness") analysis.addObject(thickness_obj) # material material_obj = ObjectsFem.makeMaterialSolid(doc, "FemMaterial") mat = material_obj.Material mat["Name"] = "Steel-Generic" mat["YoungsModulus"] = "200000 MPa" mat["PoissonRatio"] = "0.30" mat["Density"] = "7900 kg/m^3" material_obj.Material = mat analysis.addObject(material_obj) # constraint fixed con_fixed = ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed") con_fixed.References = [(doc.SquareTube, "Edge4"), (doc.SquareTube, "Edge7"), (doc.SquareTube, "Edge10"), (doc.SquareTube, "Edge12")] analysis.addObject(con_fixed) # con_force1 con_force1 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce1") con_force1.References = [(geom_obj, "Edge9")] con_force1.Force = 100000.00 con_force1.Direction = (geom_obj, ["Edge9"]) con_force1.Reversed = True analysis.addObject(con_force1) # con_force2 con_force2 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce2") con_force2.References = [(geom_obj, "Edge3")] con_force2.Force = 100000.00 con_force2.Direction = (geom_obj, ["Edge3"]) con_force2.Reversed = True analysis.addObject(con_force2) # con_force3 con_force3 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce3") con_force3.References = [(geom_obj, "Edge11")] con_force3.Force = 100000.00 con_force3.Direction = (geom_obj, ["Edge11"]) con_force3.Reversed = True analysis.addObject(con_force3) # con_force4 con_force4 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce4") con_force4.References = [(geom_obj, "Edge6")] con_force4.Force = 100000.00 con_force4.Direction = (geom_obj, ["Edge6"]) con_force4.Reversed = True analysis.addObject(con_force4) # mesh from .meshes.mesh_square_pipe_end_twisted_tria6 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") femmesh_obj = analysis.addObject( ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0] femmesh_obj.FemMesh = fem_mesh femmesh_obj.Part = geom_obj femmesh_obj.SecondOrderLinear = False doc.recompute() return doc
def setup(doc=None, solvertype="ccxtools"): # setup model if doc is None: doc = init_doc() # parts # TODO turn circle of upper tube to have the line on the other side # make a boolean fragment of them to be sure there is a mesh point on remesh # but as long as we do not remesh it works without the boolean fragment too # tubes tube_radius = 25 tube_length = 500 sh_lower_circle = Part.Wire(Part.makeCircle(tube_radius)) sh_lower_tube = sh_lower_circle.extrude(FreeCAD.Vector(0, 0, tube_length)) sh_lower_tube.reverse() lower_tube = doc.addObject("Part::Feature", "Lower_tube") lower_tube.Shape = sh_lower_tube sh_upper_circle = Part.Wire(Part.makeCircle(tube_radius)) sh_upper_tube = sh_upper_circle.extrude(FreeCAD.Vector(0, 0, tube_length)) sh_upper_tube.reverse() upper_tube = doc.addObject("Part::Feature", "Upper_tube") upper_tube.Shape = sh_upper_tube upper_tube.Placement = FreeCAD.Placement( FreeCAD.Vector(-25, 51, 475), FreeCAD.Rotation(90, 0, 90), FreeCAD.Vector(0, 0, 0), ) # point for load v_force_pt = FreeCAD.Vector(0, 76, 475) sh_force_point = Part.Vertex(v_force_pt) force_point = doc.addObject("Part::Feature", "Load_place_point") force_point.Shape = sh_force_point if FreeCAD.GuiUp: force_point.ViewObject.PointSize = 10.0 force_point.ViewObject.PointColor = (1.0, 0.0, 0.0) BooleanFrag = BOPTools.SplitFeatures.makeBooleanFragments( name='BooleanFragments') BooleanFrag.Objects = [upper_tube, force_point] if FreeCAD.GuiUp: upper_tube.ViewObject.hide() compound = doc.addObject("Part::Compound", "Compound") compound.Links = [BooleanFrag, lower_tube] # line for load direction sh_load_line = Part.makeLine(v_force_pt, FreeCAD.Vector(0, 150, 475)) load_line = doc.addObject("Part::Feature", "Load_direction_line") load_line.Shape = sh_load_line if FreeCAD.GuiUp: load_line.ViewObject.LineWidth = 5.0 load_line.ViewObject.LineColor = (1.0, 0.0, 0.0) doc.recompute() if FreeCAD.GuiUp: import FreeCADGui FreeCADGui.ActiveDocument.activeView().viewAxonometric() FreeCADGui.SendMsgToActiveView("ViewFit") # analysis analysis = ObjectsFem.makeAnalysis(doc, "Analysis") # solver if solvertype == "calculix": solver_object = analysis.addObject( ObjectsFem.makeSolverCalculix(doc, "SolverCalculiX"))[0] elif solvertype == "ccxtools": solver_object = analysis.addObject( ObjectsFem.makeSolverCalculixCcxTools(doc, "CalculiXccxTools"))[0] solver_object.WorkingDir = u"" if solvertype == "calculix" or solvertype == "ccxtools": solver_object.AnalysisType = "static" solver_object.BeamShellResultOutput3D = True solver_object.GeometricalNonlinearity = "linear" # really? # TODO iterations parameter !!! solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = "default" solver_object.IterationsControlParameterTimeUse = False solver_object.SplitInputWriter = False # shell thickness analysis.addObject( ObjectsFem.makeElementGeometry2D(doc, 0.5, 'ShellThickness')) # material material_obj = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterial"))[0] mat = material_obj.Material mat["Name"] = "AlCuMgPb" mat["YoungsModulus"] = "72000 MPa" mat["PoissonRatio"] = "0.30" material_obj.Material = mat analysis.addObject(material_obj) # fixed_constraint fixed_constraint = analysis.addObject( ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed"))[0] fixed_constraint.References = [ (lower_tube, "Edge2"), (upper_tube, "Edge3"), ] # force_constraint force_constraint = doc.Analysis.addObject( ObjectsFem.makeConstraintForce(doc, name="ConstraintForce"))[0] # TODO use point of tube boolean fragment force_constraint.References = [(force_point, "Vertex1")] force_constraint.Force = 5000.0 force_constraint.Direction = (load_line, ["Edge1"]) force_constraint.Reversed = True # contact constraint contact_constraint = doc.Analysis.addObject( ObjectsFem.makeConstraintContact(doc, name="ConstraintContact"))[0] contact_constraint.References = [ (lower_tube, "Face1"), (upper_tube, "Face1"), ] contact_constraint.Friction = 0.0 # contact_constrsh_aint.Slope = "1000000.0 kg/(mm*s^2)" # contact stiffness contact_constraint.Slope = 1000000.0 # should be 1000000.0 kg/(mm*s^2) # mesh from .meshes.mesh_contact_tube_tube_tria3 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") femmesh_obj = analysis.addObject( doc.addObject("Fem::FemMeshObject", mesh_name))[0] femmesh_obj.FemMesh = fem_mesh doc.recompute() return doc
def setup(doc=None, solvertype="ccxtools"): if doc is None: doc = init_doc() # geometry object # name is important because the other method in this module use obj name # parts face_obj1 = doc.addObject('Part::Plane', 'Face1') face_obj1.Width = 10 face_obj1.Length = 20 face_obj2 = doc.addObject('Part::Plane', 'Face2') face_obj2.Width = 10 face_obj2.Length = 20 face_obj2.Placement.Base = (20, 0, 0) face_obj3 = doc.addObject('Part::Plane', 'Face3') face_obj3.Width = 10 face_obj3.Length = 20 face_obj3.Placement.Base = (40, 0, 0) face_obj4 = doc.addObject('Part::Plane', 'Face4') face_obj4.Width = 10 face_obj4.Length = 20 face_obj4.Placement.Base = (60, 0, 0) face_obj5 = doc.addObject('Part::Plane', 'Face5') face_obj5.Width = 10 face_obj5.Length = 20 face_obj5.Placement.Base = (80, 0, 0) doc.recompute() # make a Shell out of the facees, to be able to remesh with GUI geom_obj = doc.addObject("Part::MultiFuse", "Fusion") geom_obj.Shapes = [face_obj1, face_obj2, face_obj3, face_obj4, face_obj5] if FreeCAD.GuiUp: face_obj1.ViewObject.hide() face_obj2.ViewObject.hide() face_obj3.ViewObject.hide() face_obj4.ViewObject.hide() face_obj5.ViewObject.hide() doc.recompute() if FreeCAD.GuiUp: geom_obj.ViewObject.Document.activeView().viewAxonometric() geom_obj.ViewObject.Document.activeView().fitAll() # analysis analysis = ObjectsFem.makeAnalysis(doc, "Analysis") # solver if solvertype == "calculix": solver_object = analysis.addObject( ObjectsFem.makeSolverCalculix(doc, "SolverCalculiX"))[0] elif solvertype == "ccxtools": solver_object = analysis.addObject( ObjectsFem.makeSolverCalculixCcxTools(doc, "CalculiXccxTools"))[0] solver_object.WorkingDir = u"" else: FreeCAD.Console.PrintWarning( "Not known or not supported solver type: {}. " "No solver object was created.\n".format(solvertype)) if solvertype == "calculix" or solvertype == "ccxtools": solver_object.SplitInputWriter = False solver_object.AnalysisType = "static" solver_object.GeometricalNonlinearity = "linear" solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = "default" solver_object.IterationsControlParameterTimeUse = False # shell thickness analysis.addObject( ObjectsFem.makeElementGeometry2D(doc, 10, 'ShellThickness')) # materials # material1 material_object1 = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, 'FemMaterial1'))[0] material_object1.References = [(doc.Face3, "Face1")] mat = material_object1.Material mat['Name'] = "Concrete-Generic" mat['YoungsModulus'] = "32000 MPa" mat['PoissonRatio'] = "0.17" mat['Density'] = "0 kg/m^3" material_object1.Material = mat # material2 material_object2 = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, 'FemMaterial2'))[0] material_object2.References = [(doc.Face2, "Face1"), (doc.Face4, "Face1")] mat = material_object2.Material mat['Name'] = "PLA" mat['YoungsModulus'] = "3640 MPa" mat['PoissonRatio'] = "0.36" mat['Density'] = "0 kg/m^3" material_object2.Material = mat # material3 material_object3 = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, 'FemMaterial3'))[0] material_object3.References = [] mat = material_object3.Material mat['Name'] = "Steel-Generic" mat['YoungsModulus'] = "200000 MPa" mat['PoissonRatio'] = "0.30" mat['Density'] = "7900 kg/m^3" material_object3.Material = mat # fixed_constraint fixed_constraint = analysis.addObject( ObjectsFem.makeConstraintFixed(doc, name="ConstraintFixed"))[0] fixed_constraint.References = [(doc.Face1, "Edge1"), (doc.Face5, "Edge3")] # force_constraint force_constraint = analysis.addObject( ObjectsFem.makeConstraintForce(doc, name="ConstraintForce"))[0] force_constraint.References = [(doc.Face1, "Edge4"), (doc.Face2, "Edge4"), (doc.Face3, "Edge4"), (doc.Face4, "Edge4"), (doc.Face5, "Edge4")] force_constraint.Force = 10000.00 force_constraint.Direction = (doc.Face1, ["Edge1"]) force_constraint.Reversed = True # mesh from .meshes.mesh_multibodybeam_tria6 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, mesh_name))[0] femmesh_obj.FemMesh = fem_mesh femmesh_obj.Part = geom_obj femmesh_obj.SecondOrderLinear = False doc.recompute() return doc
def setup_cantileverbase(doc=None, solver="ccxtools"): # setup CalculiX cantilever base model if doc is None: doc = init_doc() # part box_obj = doc.addObject("Part::Box", "Box") box_obj.Height = box_obj.Width = 1000 box_obj.Length = 8000 # analysis analysis = ObjectsFem.makeAnalysis(doc, "Analysis") # solver # TODO How to pass multiple solver for one analysis in one doc if solver == "calculix": solver_object = analysis.addObject( ObjectsFem.makeSolverCalculix(doc, "SolverCalculiX") )[0] solver_object.AnalysisType = "static" solver_object.GeometricalNonlinearity = "linear" solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = "default" solver_object.IterationsControlParameterTimeUse = False elif solver == "ccxtools": solver_object = analysis.addObject( ObjectsFem.makeSolverCalculixCcxTools(doc, "CalculiXccxTools") )[0] solver_object.AnalysisType = "static" solver_object.GeometricalNonlinearity = "linear" solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = "default" solver_object.IterationsControlParameterTimeUse = False solver_object.WorkingDir = u"" elif solver == "elmer": analysis.addObject(ObjectsFem.makeSolverElmer(doc, "SolverElmer")) elif solver == "z88": analysis.addObject(ObjectsFem.makeSolverZ88(doc, "SolverZ88")) # material material_object = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, "FemMaterial") )[0] mat = material_object.Material mat["Name"] = "CalculiX-Steel" mat["YoungsModulus"] = "210000 MPa" mat["PoissonRatio"] = "0.30" mat["Density"] = "7900 kg/m^3" mat["ThermalExpansionCoefficient"] = "0.012 mm/m/K" material_object.Material = mat # fixed_constraint fixed_constraint = analysis.addObject( ObjectsFem.makeConstraintFixed(doc, name="ConstraintFixed") )[0] fixed_constraint.References = [(doc.Box, "Face1")] # mesh from femexamples.meshes.mesh_canticcx_tetra10 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") femmesh_obj = analysis.addObject( doc.addObject("Fem::FemMeshObject", mesh_name) )[0] femmesh_obj.FemMesh = fem_mesh doc.recompute() return doc
def setup_cantileverbase(doc=None, solver='ccxtools'): # setup CalculiX cantilever base model if doc is None: doc = init_doc() # part box_obj = doc.addObject('Part::Box', 'Box') box_obj.Height = box_obj.Width = 1000 box_obj.Length = 8000 # analysis analysis = ObjectsFem.makeAnalysis(doc, 'Analysis') solver # TODO How to pass multiple solver for one analysis in one doc if solver is None: pass # no solver is added elif solver is 'calculix': solver_object = analysis.addObject(ObjectsFem.makeSolverCalculix(doc, 'SolverCalculiX'))[0] solver_object.AnalysisType = 'static' solver_object.GeometricalNonlinearity = 'linear' solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = 'default' solver_object.IterationsControlParameterTimeUse = False elif solver is 'ccxtools': solver_object = analysis.addObject(ObjectsFem.makeSolverCalculixCcxTools(doc, 'CalculiXccxTools'))[0] solver_object.AnalysisType = 'static' solver_object.GeometricalNonlinearity = 'linear' solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = 'default' solver_object.IterationsControlParameterTimeUse = False solver_object.WorkingDir = u'' elif solver is 'elmer': analysis.addObject(ObjectsFem.makeSolverElmer(doc, 'SolverElmer')) elif solver is 'z88': analysis.addObject(ObjectsFem.makeSolverZ88(doc, 'SolverZ88')) # material material_object = analysis.addObject(ObjectsFem.makeMaterialSolid(doc, 'FemMaterial'))[0] mat = material_object.Material mat['Name'] = "CalculiX-Steel" mat['YoungsModulus'] = "210000 MPa" mat['PoissonRatio'] = "0.30" mat['Density'] = "7900 kg/m^3" mat['ThermalExpansionCoefficient'] = "0.012 mm/m/K" material_object.Material = mat # fixed_constraint fixed_constraint = analysis.addObject(ObjectsFem.makeConstraintFixed(doc, name="ConstraintFixed"))[0] fixed_constraint.References = [(doc.Box, "Face1")] # mesh from femexamples.meshes.mesh_canticcx_tetra10 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: print('ERROR on creating nodes') control = create_elements(fem_mesh) if not control: print('ERROR on creating elements') femmesh_obj = analysis.addObject(doc.addObject('Fem::FemMeshObject', mesh_name))[0] femmesh_obj.FemMesh = fem_mesh doc.recompute() return doc
def test_solver_framework(self): fcc_print('\n--------------- Start of FEM tests solver frame work ---------------') box = self.active_doc.addObject("Part::Box", "Box") fcc_print('Checking FEM new analysis...') analysis = ObjectsFem.makeAnalysis(self.active_doc, 'Analysis') self.assertTrue(analysis, "FemTest of new analysis failed") fcc_print('Checking FEM new material...') material_object = ObjectsFem.makeMaterialSolid(self.active_doc, 'MechanicalMaterial') mat = material_object.Material mat['Name'] = "Steel-Generic" mat['YoungsModulus'] = "200000 MPa" mat['PoissonRatio'] = "0.30" mat['Density'] = "7900 kg/m^3" material_object.Material = mat self.assertTrue(material_object, "FemTest of new material failed") analysis.addObject(material_object) fcc_print('Checking FEM new fixed constraint...') fixed_constraint = self.active_doc.addObject("Fem::ConstraintFixed", "FemConstraintFixed") fixed_constraint.References = [(box, "Face1")] self.assertTrue(fixed_constraint, "FemTest of new fixed constraint failed") analysis.addObject(fixed_constraint) fcc_print('Checking FEM new force constraint...') force_constraint = self.active_doc.addObject("Fem::ConstraintForce", "FemConstraintForce") force_constraint.References = [(box, "Face6")] force_constraint.Force = 40000.0 force_constraint.Direction = (box, ["Edge5"]) self.active_doc.recompute() force_constraint.Reversed = True self.active_doc.recompute() self.assertTrue(force_constraint, "FemTest of new force constraint failed") analysis.addObject(force_constraint) fcc_print('Checking FEM new pressure constraint...') pressure_constraint = self.active_doc.addObject("Fem::ConstraintPressure", "FemConstraintPressure") pressure_constraint.References = [(box, "Face2")] pressure_constraint.Pressure = 1000.0 pressure_constraint.Reversed = False self.assertTrue(pressure_constraint, "FemTest of new pressure constraint failed") analysis.addObject(pressure_constraint) fcc_print('Checking FEM new mesh...') from .testfiles.ccx.cube_mesh import create_nodes_cube from .testfiles.ccx.cube_mesh import create_elements_cube mesh = Fem.FemMesh() ret = create_nodes_cube(mesh) self.assertTrue(ret, "Import of mesh nodes failed") ret = create_elements_cube(mesh) self.assertTrue(ret, "Import of mesh volumes failed") mesh_object = self.active_doc.addObject('Fem::FemMeshObject', self.mesh_name) mesh_object.FemMesh = mesh self.assertTrue(mesh, "FemTest of new mesh failed") analysis.addObject(mesh_object) self.active_doc.recompute() # solver frame work ccx solver fcc_print('\nChecking FEM CalculiX solver for solver frame work...') solver_ccx_object = ObjectsFem.makeSolverCalculix(self.active_doc, 'SolverCalculiX') solver_ccx_object.AnalysisType = 'static' solver_ccx_object.GeometricalNonlinearity = 'linear' solver_ccx_object.ThermoMechSteadyState = False solver_ccx_object.MatrixSolverType = 'default' solver_ccx_object.IterationsControlParameterTimeUse = False solver_ccx_object.EigenmodesCount = 10 solver_ccx_object.EigenmodeHighLimit = 1000000.0 solver_ccx_object.EigenmodeLowLimit = 0.0 self.assertTrue(solver_ccx_object, "FemTest of new ccx solver failed") analysis.addObject(solver_ccx_object) static_base_name = 'cube_static' solverframework_analysis_dir = testtools.get_unit_test_tmp_dir(testtools.get_fem_test_tmp_dir(), 'FEM_solverframework/') fcc_print('Checking FEM Elmer solver for solver frame work......') fcc_print('machine_ccx') machine_ccx = solver_ccx_object.Proxy.createMachine(solver_ccx_object, solverframework_analysis_dir) fcc_print('Machine testmode: ' + str(machine_ccx.testmode)) machine_ccx.target = femsolver.run.PREPARE machine_ccx.start() machine_ccx.join() # wait for the machine to finish. static_analysis_inp_file = testtools.get_fem_test_home_dir() + 'ccx/' + static_base_name + '.inp' fcc_print('Comparing {} to {}/{}.inp'.format(static_analysis_inp_file, solverframework_analysis_dir, self.mesh_name)) ret = testtools.compare_inp_files(static_analysis_inp_file, solverframework_analysis_dir + self.mesh_name + '.inp') self.assertFalse(ret, "ccxtools write_inp_file test failed.\n{}".format(ret)) # use solver frame work elmer solver solver_elmer_object = ObjectsFem.makeSolverElmer(self.active_doc, 'SolverElmer') self.assertTrue(solver_elmer_object, "FemTest of elmer solver failed") analysis.addObject(solver_elmer_object) solver_elmer_eqobj = ObjectsFem.makeEquationElasticity(self.active_doc, solver_elmer_object) self.assertTrue(solver_elmer_eqobj, "FemTest of elmer elasticity equation failed") # set ThermalExpansionCoefficient, current elmer seems to need it even on simple elasticity analysis mat = material_object.Material mat['ThermalExpansionCoefficient'] = "0 um/m/K" # FIXME elmer elasticity needs the dictionary key, otherwise it fails material_object.Material = mat mesh_gmsh = ObjectsFem.makeMeshGmsh(self.active_doc) mesh_gmsh.CharacteristicLengthMin = "9 mm" mesh_gmsh.FemMesh = mesh_object.FemMesh # elmer needs a GMHS mesh object, FIXME error message on Python solver run mesh_gmsh.Part = box analysis.addObject(mesh_gmsh) self.active_doc.removeObject(mesh_object.Name) # solver frame work Elmer solver fcc_print('\nChecking FEM Elmer solver for solver frame work...') machine_elmer = solver_elmer_object.Proxy.createMachine(solver_elmer_object, solverframework_analysis_dir, True) fcc_print('Machine testmode: ' + str(machine_elmer.testmode)) machine_elmer.target = femsolver.run.PREPARE machine_elmer.start() machine_elmer.join() # wait for the machine to finish. test_file_dir_elmer = testtools.get_fem_test_home_dir() + 'elmer/' fcc_print('Test writing STARTINFO file') fcc_print('Comparing {} to {}'.format(test_file_dir_elmer + 'ELMERSOLVER_STARTINFO', solverframework_analysis_dir + 'ELMERSOLVER_STARTINFO')) ret = testtools.compare_files(test_file_dir_elmer + 'ELMERSOLVER_STARTINFO', solverframework_analysis_dir + 'ELMERSOLVER_STARTINFO') self.assertFalse(ret, "STARTINFO write file test failed.\n{}".format(ret)) fcc_print('Test writing case file') fcc_print('Comparing {} to {}'.format(test_file_dir_elmer + 'case.sif', solverframework_analysis_dir + 'case.sif')) ret = testtools.compare_files(test_file_dir_elmer + 'case.sif', solverframework_analysis_dir + 'case.sif') self.assertFalse(ret, "case write file test failed.\n{}".format(ret)) fcc_print('Test writing GMSH geo file') fcc_print('Comparing {} to {}'.format(test_file_dir_elmer + 'group_mesh.geo', solverframework_analysis_dir + 'group_mesh.geo')) ret = testtools.compare_files(test_file_dir_elmer + 'group_mesh.geo', solverframework_analysis_dir + 'group_mesh.geo') self.assertFalse(ret, "GMSH geo write file test failed.\n{}".format(ret)) save_fc_file = solverframework_analysis_dir + static_base_name + '.fcstd' fcc_print('Save FreeCAD file for static2 analysis to {}...'.format(save_fc_file)) self.active_doc.saveAs(save_fc_file) fcc_print('--------------- End of FEM tests solver frame work ---------------')
def test_femobjects_make(self): doc = self.active_doc analysis = ObjectsFem.makeAnalysis(doc) analysis.addObject(ObjectsFem.makeConstraintBearing(doc)) analysis.addObject(ObjectsFem.makeConstraintBodyHeatSource(doc)) analysis.addObject(ObjectsFem.makeConstraintContact(doc)) analysis.addObject(ObjectsFem.makeConstraintDisplacement(doc)) analysis.addObject( ObjectsFem.makeConstraintElectrostaticPotential(doc)) analysis.addObject(ObjectsFem.makeConstraintFixed(doc)) analysis.addObject(ObjectsFem.makeConstraintFlowVelocity(doc)) analysis.addObject(ObjectsFem.makeConstraintFluidBoundary(doc)) analysis.addObject(ObjectsFem.makeConstraintForce(doc)) analysis.addObject(ObjectsFem.makeConstraintGear(doc)) analysis.addObject(ObjectsFem.makeConstraintHeatflux(doc)) analysis.addObject(ObjectsFem.makeConstraintInitialFlowVelocity(doc)) analysis.addObject(ObjectsFem.makeConstraintInitialTemperature(doc)) analysis.addObject(ObjectsFem.makeConstraintPlaneRotation(doc)) analysis.addObject(ObjectsFem.makeConstraintPressure(doc)) analysis.addObject(ObjectsFem.makeConstraintPulley(doc)) analysis.addObject(ObjectsFem.makeConstraintSelfWeight(doc)) analysis.addObject(ObjectsFem.makeConstraintTemperature(doc)) analysis.addObject(ObjectsFem.makeConstraintTransform(doc)) analysis.addObject(ObjectsFem.makeElementFluid1D(doc)) analysis.addObject(ObjectsFem.makeElementGeometry1D(doc)) analysis.addObject(ObjectsFem.makeElementGeometry2D(doc)) analysis.addObject(ObjectsFem.makeElementRotation1D(doc)) analysis.addObject(ObjectsFem.makeMaterialFluid(doc)) mat = analysis.addObject(ObjectsFem.makeMaterialSolid(doc))[0] analysis.addObject(ObjectsFem.makeMaterialMechanicalNonlinear( doc, mat)) analysis.addObject(ObjectsFem.makeMaterialReinforced(doc)) msh = analysis.addObject(ObjectsFem.makeMeshGmsh(doc))[0] analysis.addObject(ObjectsFem.makeMeshBoundaryLayer(doc, msh)) analysis.addObject(ObjectsFem.makeMeshGroup(doc, msh)) analysis.addObject(ObjectsFem.makeMeshRegion(doc, msh)) analysis.addObject(ObjectsFem.makeMeshNetgen(doc)) analysis.addObject(ObjectsFem.makeMeshResult(doc)) res = analysis.addObject(ObjectsFem.makeResultMechanical(doc))[0] if "BUILD_FEM_VTK" in FreeCAD.__cmake__: vres = analysis.addObject(ObjectsFem.makePostVtkResult(doc, res))[0] analysis.addObject( ObjectsFem.makePostVtkFilterClipRegion(doc, vres)) analysis.addObject( ObjectsFem.makePostVtkFilterClipScalar(doc, vres)) analysis.addObject( ObjectsFem.makePostVtkFilterCutFunction(doc, vres)) analysis.addObject(ObjectsFem.makePostVtkFilterWarp(doc, vres)) analysis.addObject(ObjectsFem.makeSolverCalculixCcxTools(doc)) analysis.addObject(ObjectsFem.makeSolverCalculix(doc)) sol = analysis.addObject(ObjectsFem.makeSolverElmer(doc))[0] analysis.addObject(ObjectsFem.makeSolverZ88(doc)) analysis.addObject(ObjectsFem.makeEquationElasticity(doc, sol)) analysis.addObject(ObjectsFem.makeEquationElectrostatic(doc, sol)) analysis.addObject(ObjectsFem.makeEquationFlow(doc, sol)) analysis.addObject(ObjectsFem.makeEquationFluxsolver(doc, sol)) analysis.addObject(ObjectsFem.makeEquationHeat(doc, sol)) # is = 48 (just copy in empty file to test, or run unit test case, it is printed) # TODO if the equations and gmsh mesh childs are added to the analysis, # they show up twice on Tree (on solver resp. gemsh mesh obj and on analysis) # https://forum.freecadweb.org/viewtopic.php?t=25283 doc.recompute() # if FEM VTK post processing is disabled, we are not able to create VTK post objects if "BUILD_FEM_VTK" in FreeCAD.__cmake__: fem_vtk_post = True else: fem_vtk_post = False # because of the analysis itself count -1 self.assertEqual(len(analysis.Group), testtools.get_defmake_count(fem_vtk_post) - 1)
def setup_cantileverbase(doc=None, solvertype="ccxtools"): # setup CalculiX cantilever base model if doc is None: doc = init_doc() # geometry object # name is important because the other method in this module use obj name geom_obj = doc.addObject("Part::Box", "Box") geom_obj.Height = geom_obj.Width = 1000 geom_obj.Length = 8000 doc.recompute() if FreeCAD.GuiUp: geom_obj.ViewObject.Document.activeView().viewAxonometric() geom_obj.ViewObject.Document.activeView().fitAll() # analysis analysis = ObjectsFem.makeAnalysis(doc, "Analysis") # solver if solvertype == "calculix": solver_object = analysis.addObject( ObjectsFem.makeSolverCalculix(doc, "SolverCalculiX"))[0] elif solvertype == "ccxtools": solver_object = analysis.addObject( ObjectsFem.makeSolverCalculixCcxTools(doc, "CalculiXccxTools"))[0] solver_object.WorkingDir = u"" elif solvertype == "elmer": analysis.addObject(ObjectsFem.makeSolverElmer(doc, "SolverElmer")) elif solvertype == "z88": analysis.addObject(ObjectsFem.makeSolverZ88(doc, "SolverZ88")) if solvertype == "calculix" or solvertype == "ccxtools": solver_object.SplitInputWriter = False solver_object.AnalysisType = "static" solver_object.GeometricalNonlinearity = "linear" solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = "default" solver_object.IterationsControlParameterTimeUse = False # material material_object = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, "FemMaterial"))[0] mat = material_object.Material mat["Name"] = "CalculiX-Steel" mat["YoungsModulus"] = "210000 MPa" mat["PoissonRatio"] = "0.30" mat["Density"] = "7900 kg/m^3" mat["ThermalExpansionCoefficient"] = "0.012 mm/m/K" material_object.Material = mat # fixed_constraint fixed_constraint = analysis.addObject( ObjectsFem.makeConstraintFixed(doc, name="ConstraintFixed"))[0] fixed_constraint.References = [(geom_obj, "Face1")] # mesh from .meshes.mesh_canticcx_tetra10 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") femmesh_obj = analysis.addObject( doc.addObject("Fem::FemMeshObject", mesh_name))[0] femmesh_obj.FemMesh = fem_mesh doc.recompute() return doc
def test_static_analysis(self): fcc_print('--------------- Start of FEM tests ---------------') box = self.active_doc.addObject("Part::Box", "Box") fcc_print('Checking FEM new analysis...') analysis = ObjectsFem.makeAnalysis(self.active_doc, 'Analysis') self.assertTrue(analysis, "FemTest of new analysis failed") fcc_print('Checking FEM new solver...') solver_object = ObjectsFem.makeSolverCalculixCcxTools( self.active_doc, 'CalculiX') solver_object.AnalysisType = 'static' solver_object.GeometricalNonlinearity = 'linear' solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = 'default' solver_object.IterationsControlParameterTimeUse = False solver_object.EigenmodesCount = 10 solver_object.EigenmodeHighLimit = 1000000.0 solver_object.EigenmodeLowLimit = 0.0 self.assertTrue(solver_object, "FemTest of new solver failed") analysis.addObject(solver_object) fcc_print('Checking FEM new material...') material_object = ObjectsFem.makeMaterialSolid(self.active_doc, 'MechanicalMaterial') mat = material_object.Material mat['Name'] = "Steel-Generic" mat['YoungsModulus'] = "200000 MPa" mat['PoissonRatio'] = "0.30" mat['Density'] = "7900 kg/m^3" material_object.Material = mat self.assertTrue(material_object, "FemTest of new material failed") analysis.addObject(material_object) fcc_print('Checking FEM new fixed constraint...') fixed_constraint = self.active_doc.addObject("Fem::ConstraintFixed", "FemConstraintFixed") fixed_constraint.References = [(box, "Face1")] self.assertTrue(fixed_constraint, "FemTest of new fixed constraint failed") analysis.addObject(fixed_constraint) fcc_print('Checking FEM new force constraint...') force_constraint = self.active_doc.addObject("Fem::ConstraintForce", "FemConstraintForce") force_constraint.References = [(box, "Face6")] force_constraint.Force = 40000.0 force_constraint.Direction = (box, ["Edge5"]) self.active_doc.recompute() force_constraint.Reversed = True self.active_doc.recompute() self.assertTrue(force_constraint, "FemTest of new force constraint failed") analysis.addObject(force_constraint) fcc_print('Checking FEM new pressure constraint...') pressure_constraint = self.active_doc.addObject( "Fem::ConstraintPressure", "FemConstraintPressure") pressure_constraint.References = [(box, "Face2")] pressure_constraint.Pressure = 1000.0 pressure_constraint.Reversed = False self.assertTrue(pressure_constraint, "FemTest of new pressure constraint failed") analysis.addObject(pressure_constraint) fcc_print('Checking FEM new mesh...') from .testfiles.ccx.cube_mesh import create_nodes_cube from .testfiles.ccx.cube_mesh import create_elements_cube mesh = Fem.FemMesh() ret = create_nodes_cube(mesh) self.assertTrue(ret, "Import of mesh nodes failed") ret = create_elements_cube(mesh) self.assertTrue(ret, "Import of mesh volumes failed") mesh_object = self.active_doc.addObject('Fem::FemMeshObject', self.mesh_name) mesh_object.FemMesh = mesh self.assertTrue(mesh, "FemTest of new mesh failed") analysis.addObject(mesh_object) self.active_doc.recompute() static_analysis_dir = testtools.get_unit_test_tmp_dir( self.temp_dir, 'FEM_ccx_static/') fea = ccxtools.FemToolsCcx(analysis, solver_object, test_mode=True) fcc_print( 'Setting up working directory {}'.format(static_analysis_dir)) fea.setup_working_dir(static_analysis_dir) self.assertTrue( True if fea.working_dir == static_analysis_dir else False, "Setting working directory {} failed".format(static_analysis_dir)) fcc_print('Checking FEM inp file prerequisites for static analysis...') error = fea.check_prerequisites() self.assertFalse( error, "ccxtools check_prerequisites returned error message: {}".format( error)) fcc_print('Checking FEM inp file write...') fcc_print('Writing {}/{}.inp for static analysis'.format( static_analysis_dir, self.mesh_name)) error = fea.write_inp_file() self.assertFalse(error, "Writing failed") static_base_name = 'cube_static' static_analysis_inp_file = self.test_file_dir + static_base_name + '.inp' fcc_print('Comparing {} to {}/{}.inp'.format(static_analysis_inp_file, static_analysis_dir, self.mesh_name)) ret = testtools.compare_inp_files( static_analysis_inp_file, static_analysis_dir + self.mesh_name + '.inp') self.assertFalse( ret, "ccxtools write_inp_file test failed.\n{}".format(ret)) fcc_print( 'Setting up working directory to {} in order to read simulated calculations' .format(self.test_file_dir)) fea.setup_working_dir(self.test_file_dir) self.assertTrue( True if fea.working_dir == self.test_file_dir else False, "Setting working directory {} failed".format(self.test_file_dir)) fcc_print('Setting base name to read test {}.frd file...'.format( 'cube_static')) fea.set_base_name(static_base_name) self.assertTrue( True if fea.base_name == static_base_name else False, "Setting base name to {} failed".format(static_base_name)) fcc_print('Setting inp file name to read test {}.frd file...'.format( 'cube_static')) fea.set_inp_file_name() self.assertTrue( True if fea.inp_file_name == static_analysis_inp_file else False, "Setting inp file name to {} failed".format( static_analysis_inp_file)) fcc_print('Checking FEM frd file read from static analysis...') fea.load_results() self.assertTrue( fea.results_present, "Cannot read results from {}.frd frd file".format(fea.base_name)) fcc_print('Reading stats from result object for static analysis...') static_expected_values = self.test_file_dir + "cube_static_expected_values" ret = testtools.compare_stats(fea, static_expected_values, 'CalculiX_static_results') self.assertFalse(ret, "Invalid results read from .frd file") static_save_fc_file = static_analysis_dir + static_base_name + '.fcstd' fcc_print('Save FreeCAD file for static analysis to {}...'.format( static_save_fc_file)) self.active_doc.saveAs(static_save_fc_file) fcc_print( '--------------- End of FEM tests static and analysis ---------------' )
def test_thermomech_analysis(self): fcc_print('--------------- Start of FEM tests ---------------') box = self.active_doc.addObject("Part::Box", "Box") box.Height = 25.4 box.Width = 25.4 box.Length = 203.2 fcc_print('Checking FEM new analysis...') analysis = ObjectsFem.makeAnalysis(self.active_doc, 'Analysis') self.assertTrue(analysis, "FemTest of new analysis failed") fcc_print('Checking FEM new solver...') solver_object = ObjectsFem.makeSolverCalculixCcxTools( self.active_doc, 'CalculiX') solver_object.AnalysisType = 'thermomech' solver_object.GeometricalNonlinearity = 'linear' solver_object.ThermoMechSteadyState = True solver_object.MatrixSolverType = 'default' solver_object.IterationsThermoMechMaximum = 2000 solver_object.IterationsControlParameterTimeUse = True self.assertTrue(solver_object, "FemTest of new solver failed") analysis.addObject(solver_object) fcc_print('Checking FEM new material...') material_object = ObjectsFem.makeMaterialSolid(self.active_doc, 'MechanicalMaterial') mat = material_object.Material mat['Name'] = "Steel-Generic" mat['YoungsModulus'] = "200000 MPa" mat['PoissonRatio'] = "0.30" mat['Density'] = "7900 kg/m^3" mat['ThermalConductivity'] = "43.27 W/m/K" # SvdW: Change to Ansys model values mat['ThermalExpansionCoefficient'] = "12 um/m/K" mat['SpecificHeat'] = "500 J/kg/K" # SvdW: Change to Ansys model values material_object.Material = mat self.assertTrue(material_object, "FemTest of new material failed") analysis.addObject(material_object) fcc_print('Checking FEM new fixed constraint...') fixed_constraint = self.active_doc.addObject("Fem::ConstraintFixed", "FemConstraintFixed") fixed_constraint.References = [(box, "Face1")] self.assertTrue(fixed_constraint, "FemTest of new fixed constraint failed") analysis.addObject(fixed_constraint) fcc_print('Checking FEM new initial temperature constraint...') initialtemperature_constraint = self.active_doc.addObject( "Fem::ConstraintInitialTemperature", "FemConstraintInitialTemperature") initialtemperature_constraint.initialTemperature = 300.0 self.assertTrue( initialtemperature_constraint, "FemTest of new initial temperature constraint failed") analysis.addObject(initialtemperature_constraint) fcc_print('Checking FEM new temperature constraint...') temperature_constraint = self.active_doc.addObject( "Fem::ConstraintTemperature", "FemConstraintTemperature") temperature_constraint.References = [(box, "Face1")] temperature_constraint.Temperature = 310.93 self.assertTrue(temperature_constraint, "FemTest of new temperature constraint failed") analysis.addObject(temperature_constraint) fcc_print('Checking FEM new heatflux constraint...') heatflux_constraint = self.active_doc.addObject( "Fem::ConstraintHeatflux", "FemConstraintHeatflux") heatflux_constraint.References = [(box, "Face3"), (box, "Face4"), (box, "Face5"), (box, "Face6")] heatflux_constraint.AmbientTemp = 255.3722 heatflux_constraint.FilmCoef = 5.678 self.assertTrue(heatflux_constraint, "FemTest of new heatflux constraint failed") analysis.addObject(heatflux_constraint) fcc_print('Checking FEM new mesh...') from .testfiles.ccx.spine_mesh import create_nodes_spine from .testfiles.ccx.spine_mesh import create_elements_spine mesh = Fem.FemMesh() ret = create_nodes_spine(mesh) self.assertTrue(ret, "Import of mesh nodes failed") ret = create_elements_spine(mesh) self.assertTrue(ret, "Import of mesh volumes failed") mesh_object = self.active_doc.addObject('Fem::FemMeshObject', self.mesh_name) mesh_object.FemMesh = mesh self.assertTrue(mesh, "FemTest of new mesh failed") analysis.addObject(mesh_object) self.active_doc.recompute() thermomech_analysis_dir = self.temp_dir + 'FEM_ccx_thermomech/' fea = ccxtools.FemToolsCcx(analysis, test_mode=True) fcc_print( 'Setting up working directory {}'.format(thermomech_analysis_dir)) fea.setup_working_dir(thermomech_analysis_dir) self.assertTrue( True if fea.working_dir == thermomech_analysis_dir else False, "Setting working directory {} failed".format( thermomech_analysis_dir)) fcc_print( 'Checking FEM inp file prerequisites for thermo-mechanical analysis...' ) error = fea.check_prerequisites() self.assertFalse( error, "ccxtools check_prerequisites returned error message: {}".format( error)) fcc_print('Checking FEM inp file write...') fcc_print('Writing {}/{}.inp for thermomech analysis'.format( thermomech_analysis_dir, self.mesh_name)) error = fea.write_inp_file() self.assertFalse(error, "Writing failed") thermomech_base_name = 'spine_thermomech' thermomech_analysis_inp_file = self.test_file_dir + thermomech_base_name + '.inp' fcc_print('Comparing {} to {}/{}.inp'.format( thermomech_analysis_inp_file, thermomech_analysis_dir, self.mesh_name)) ret = testtools.compare_inp_files( thermomech_analysis_inp_file, thermomech_analysis_dir + self.mesh_name + '.inp') self.assertFalse( ret, "ccxtools write_inp_file test failed.\n{}".format(ret)) fcc_print( 'Setting up working directory to {} in order to read simulated calculations' .format(self.test_file_dir)) fea.setup_working_dir(self.test_file_dir) self.assertTrue( True if fea.working_dir == self.test_file_dir else False, "Setting working directory {} failed".format(self.test_file_dir)) fcc_print('Setting base name to read test {}.frd file...'.format( 'spine_thermomech')) fea.set_base_name(thermomech_base_name) self.assertTrue( True if fea.base_name == thermomech_base_name else False, "Setting base name to {} failed".format(thermomech_base_name)) fcc_print('Setting inp file name to read test {}.frd file...'.format( 'spine_thermomech')) fea.set_inp_file_name() self.assertTrue( True if fea.inp_file_name == thermomech_analysis_inp_file else False, "Setting inp file name to {} failed".format( thermomech_analysis_inp_file)) fcc_print('Checking FEM frd file read from thermomech analysis...') fea.load_results() self.assertTrue( fea.results_present, "Cannot read results from {}.frd frd file".format(fea.base_name)) fcc_print( 'Reading stats from result object for thermomech analysis...') thermomech_expected_values = self.test_file_dir + "spine_thermomech_expected_values" ret = testtools.compare_stats(fea, thermomech_expected_values, 'CalculiX_thermomech_results') self.assertFalse(ret, "Invalid results read from .frd file") thermomech_save_fc_file = thermomech_analysis_dir + thermomech_base_name + '.fcstd' fcc_print('Save FreeCAD file for thermomech analysis to {}...'.format( thermomech_save_fc_file)) self.active_doc.saveAs(thermomech_save_fc_file) fcc_print( '--------------- End of FEM tests thermomech analysis ---------------' )
def test_2_static_multiple_material(self): fcc_print('--------------- Start of FEM ccxtools multiple material test ---------------') # create a CompSolid of two Boxes extract the CompSolid (we are able to remesh if needed) boxlow = self.active_doc.addObject("Part::Box", "BoxLower") boxupp = self.active_doc.addObject("Part::Box", "BoxUpper") boxupp.Placement.Base = (0, 0, 10) # for BooleanFragments Occt >=6.9 is needed ''' import BOPTools.SplitFeatures bf = BOPTools.SplitFeatures.makeBooleanFragments(name='BooleanFragments') bf.Objects = [boxlow, boxupp] bf.Mode = "CompSolid" self.active_doc.recompute() bf.Proxy.execute(bf) bf.purgeTouched() for obj in bf.ViewObject.Proxy.claimChildren(): obj.ViewObject.hide() self.active_doc.recompute() import CompoundTools.CompoundFilter cf = CompoundTools.CompoundFilter.makeCompoundFilter(name='MultiMatCompSolid') cf.Base = bf cf.FilterType = 'window-volume' cf.Proxy.execute(cf) cf.purgeTouched() cf.Base.ViewObject.hide() ''' self.active_doc.recompute() if FreeCAD.GuiUp: import FreeCADGui FreeCADGui.ActiveDocument.activeView().viewAxonometric() FreeCADGui.SendMsgToActiveView("ViewFit") analysis = ObjectsFem.makeAnalysis(self.active_doc, 'Analysis') solver_object = ObjectsFem.makeSolverCalculixCcxTools(self.active_doc, 'CalculiXccxTools') solver_object.AnalysisType = 'static' solver_object.GeometricalNonlinearity = 'linear' solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = 'default' solver_object.IterationsControlParameterTimeUse = False analysis.addObject(solver_object) material_object_low = ObjectsFem.makeMaterialSolid(self.active_doc, 'MechanicalMaterialLow') mat = material_object_low.Material mat['Name'] = "Aluminium-Generic" mat['YoungsModulus'] = "70000 MPa" mat['PoissonRatio'] = "0.35" mat['Density'] = "2700 kg/m^3" material_object_low.Material = mat material_object_low.References = [(boxlow, 'Solid1')] analysis.addObject(material_object_low) material_object_upp = ObjectsFem.makeMaterialSolid(self.active_doc, 'MechanicalMaterialUpp') mat = material_object_upp.Material mat['Name'] = "Steel-Generic" mat['YoungsModulus'] = "200000 MPa" mat['PoissonRatio'] = "0.30" mat['Density'] = "7980 kg/m^3" material_object_upp.Material = mat material_object_upp.References = [(boxupp, 'Solid1')] analysis.addObject(material_object_upp) fixed_constraint = self.active_doc.addObject("Fem::ConstraintFixed", "ConstraintFixed") # fixed_constraint.References = [(cf, "Face3")] fixed_constraint.References = [(boxlow, "Face5")] analysis.addObject(fixed_constraint) pressure_constraint = self.active_doc.addObject("Fem::ConstraintPressure", "ConstraintPressure") # pressure_constraint.References = [(cf, "Face9")] pressure_constraint.References = [(boxupp, "Face6")] pressure_constraint.Pressure = 1000.0 pressure_constraint.Reversed = False analysis.addObject(pressure_constraint) mesh = Fem.FemMesh() import femtest.testfiles.ccx.multimat_mesh as multimatmesh multimatmesh.create_nodes(mesh) multimatmesh.create_elements(mesh) mesh_object = self.active_doc.addObject('Fem::FemMeshObject', self.mesh_name) mesh_object.FemMesh = mesh analysis.addObject(mesh_object) self.active_doc.recompute() static_multiplemat_dir = testtools.get_unit_test_tmp_dir(self.temp_dir, 'FEM_ccx_multimat/') fea = ccxtools.FemToolsCcx(analysis, solver_object, test_mode=True) fea.update_objects() fea.setup_working_dir(static_multiplemat_dir) fcc_print('Checking FEM inp file prerequisites for ccxtools multimat analysis...') error = fea.check_prerequisites() self.assertFalse(error, "ccxtools check_prerequisites returned error message: {}".format(error)) static_base_name = 'multimat' inpfile_given = join(self.test_file_dir, (static_base_name + '.inp')) inpfile_totest = join(static_multiplemat_dir, (self.mesh_name + '.inp')) fcc_print('Checking FEM inp file write...') fcc_print('Writing {} for static multiple material'.format(inpfile_totest)) error = fea.write_inp_file() self.assertFalse(error, "Writing failed") fcc_print('Comparing {} to {}'.format(inpfile_given, inpfile_totest)) ret = testtools.compare_inp_files(inpfile_given, inpfile_totest) self.assertFalse(ret, "ccxtools write_inp_file test failed.\n{}".format(ret)) static_save_fc_file = static_multiplemat_dir + static_base_name + '.FCStd' fcc_print('Save FreeCAD file for static analysis to {}...'.format(static_save_fc_file)) self.active_doc.saveAs(static_save_fc_file) fcc_print('--------------- End of FEM ccxtools multiple material test ---------------')
def test_Flow1D_thermomech_analysis(self): fcc_print('--------------- Start of 1D Flow FEM tests ---------------') import Draft p1 = FreeCAD.Vector(0, 0, 50) p2 = FreeCAD.Vector(0, 0, -50) p3 = FreeCAD.Vector(0, 0, -4300) p4 = FreeCAD.Vector(4950, 0, -4300) p5 = FreeCAD.Vector(5000, 0, -4300) p6 = FreeCAD.Vector(8535.53, 0, -7835.53) p7 = FreeCAD.Vector(8569.88, 0, -7870.88) p8 = FreeCAD.Vector(12105.41, 0, -11406.41) p9 = FreeCAD.Vector(12140.76, 0, -11441.76) p10 = FreeCAD.Vector(13908.53, 0, -13209.53) p11 = FreeCAD.Vector(13943.88, 0, -13244.88) p12 = FreeCAD.Vector(15046.97, 0, -14347.97) p13 = FreeCAD.Vector(15046.97, 0, -7947.97) p14 = FreeCAD.Vector(15046.97, 0, -7847.97) p15 = FreeCAD.Vector(0, 0, 0) p16 = FreeCAD.Vector(0, 0, -2175) p17 = FreeCAD.Vector(2475, 0, -4300) p18 = FreeCAD.Vector(4975, 0, -4300) p19 = FreeCAD.Vector(6767.765, 0, -6067.765) p20 = FreeCAD.Vector(8552.705, 0, -7853.205) p21 = FreeCAD.Vector(10337.645, 0, -9638.645) p22 = FreeCAD.Vector(12123.085, 0, -11424.085) p23 = FreeCAD.Vector(13024.645, 0, -12325.645) p24 = FreeCAD.Vector(13926.205, 0, -13227.205) p25 = FreeCAD.Vector(14495.425, 0, -13796.425) p26 = FreeCAD.Vector(15046.97, 0, -11147.97) p27 = FreeCAD.Vector(15046.97, 0, -7897.97) points = [ p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27 ] line = Draft.makeWire(points, closed=False, face=False, support=None) fcc_print('Checking FEM new analysis...') analysis = ObjectsFem.makeAnalysis(self.active_doc, 'Analysis') self.assertTrue(analysis, "FemTest of new analysis failed") fcc_print('Checking FEM new solver...') solver_object = ObjectsFem.makeSolverCalculixCcxTools( self.active_doc, 'CalculiX') solver_object.AnalysisType = 'thermomech' solver_object.GeometricalNonlinearity = 'linear' solver_object.ThermoMechSteadyState = True solver_object.MatrixSolverType = 'default' solver_object.IterationsThermoMechMaximum = 2000 solver_object.IterationsControlParameterTimeUse = False self.assertTrue(solver_object, "FemTest of new solver failed") analysis.addObject(solver_object) fcc_print('Checking FEM new material...') material_object = ObjectsFem.makeMaterialFluid(self.active_doc, 'FluidMaterial') mat = material_object.Material mat['Name'] = "Water" mat['Density'] = "998 kg/m^3" mat['SpecificHeat'] = "4.182 J/kg/K" mat['DynamicViscosity'] = "1.003e-3 kg/m/s" mat['VolumetricThermalExpansionCoefficient'] = "2.07e-4 m/m/K" mat['ThermalConductivity'] = "0.591 W/m/K" material_object.Material = mat self.assertTrue(material_object, "FemTest of new material failed") analysis.addObject(material_object) fcc_print('Checking FEM Flow1D inlet constraint...') Flow1d_inlet = ObjectsFem.makeElementFluid1D(self.active_doc, "ElementFluid1D") Flow1d_inlet.SectionType = 'Liquid' Flow1d_inlet.LiquidSectionType = 'PIPE INLET' Flow1d_inlet.InletPressure = 0.1 Flow1d_inlet.References = [(line, "Edge1")] self.assertTrue(Flow1d_inlet, "FemTest of new Flow1D inlet constraint failed") analysis.addObject(Flow1d_inlet) fcc_print('Checking FEM new Flow1D entrance constraint...') Flow1d_entrance = ObjectsFem.makeElementFluid1D( self.active_doc, "ElementFluid1D") Flow1d_entrance.SectionType = 'Liquid' Flow1d_entrance.LiquidSectionType = 'PIPE ENTRANCE' Flow1d_entrance.EntrancePipeArea = 31416.00 Flow1d_entrance.EntranceArea = 25133.00 Flow1d_entrance.References = [(line, "Edge2")] self.assertTrue(Flow1d_entrance, "FemTest of new Flow1D entrance constraint failed") analysis.addObject(Flow1d_entrance) fcc_print('Checking FEM new Flow1D manning constraint...') Flow1d_manning = ObjectsFem.makeElementFluid1D(self.active_doc, "ElementFluid1D") Flow1d_manning.SectionType = 'Liquid' Flow1d_manning.LiquidSectionType = 'PIPE MANNING' Flow1d_manning.ManningArea = 31416 Flow1d_manning.ManningRadius = 50 Flow1d_manning.ManningCoefficient = 0.002 Flow1d_manning.References = [(line, "Edge3"), (line, "Edge5")] self.assertTrue(Flow1d_manning, "FemTest of new Flow1D manning constraint failed") analysis.addObject(Flow1d_manning) fcc_print('Checking FEM new Flow1D bend constraint...') Flow1d_bend = ObjectsFem.makeElementFluid1D(self.active_doc, "ElementFluid1D") Flow1d_bend.SectionType = 'Liquid' Flow1d_bend.LiquidSectionType = 'PIPE BEND' Flow1d_bend.BendPipeArea = 31416 Flow1d_bend.BendRadiusDiameter = 1.5 Flow1d_bend.BendAngle = 45 Flow1d_bend.BendLossCoefficient = 0.4 Flow1d_bend.References = [(line, "Edge4")] self.assertTrue(Flow1d_bend, "FemTest of new Flow1D bend constraint failed") analysis.addObject(Flow1d_bend) fcc_print('Checking FEM new Flow1D enlargement constraint...') Flow1d_enlargement = ObjectsFem.makeElementFluid1D( self.active_doc, "ElementFluid1D") Flow1d_enlargement.SectionType = 'Liquid' Flow1d_enlargement.LiquidSectionType = 'PIPE ENLARGEMENT' Flow1d_enlargement.EnlargeArea1 = 31416.00 Flow1d_enlargement.EnlargeArea2 = 70686.00 Flow1d_enlargement.References = [(line, "Edge6")] self.assertTrue(Flow1d_enlargement, "FemTest of new Flow1D enlargement constraint failed") analysis.addObject(Flow1d_enlargement) fcc_print('Checking FEM new Flow1D manning constraint...') Flow1d_manning1 = ObjectsFem.makeElementFluid1D( self.active_doc, "ElementFluid1D") Flow1d_manning1.SectionType = 'Liquid' Flow1d_manning1.LiquidSectionType = 'PIPE MANNING' Flow1d_manning1.ManningArea = 70686.00 Flow1d_manning1.ManningRadius = 75 Flow1d_manning1.ManningCoefficient = 0.002 Flow1d_manning1.References = [(line, "Edge7")] self.assertTrue(Flow1d_manning1, "FemTest of new Flow1D manning constraint failed") analysis.addObject(Flow1d_manning1) fcc_print('Checking FEM new Flow1D contraction constraint...') Flow1d_contraction = ObjectsFem.makeElementFluid1D( self.active_doc, "ElementFluid1D") Flow1d_contraction.SectionType = 'Liquid' Flow1d_contraction.LiquidSectionType = 'PIPE CONTRACTION' Flow1d_contraction.ContractArea1 = 70686 Flow1d_contraction.ContractArea2 = 17671 Flow1d_contraction.References = [(line, "Edge8")] self.assertTrue(Flow1d_contraction, "FemTest of new Flow1D contraction constraint failed") analysis.addObject(Flow1d_contraction) fcc_print('Checking FEM new Flow1D manning constraint...') Flow1d_manning2 = ObjectsFem.makeElementFluid1D( self.active_doc, "ElementFluid1D") Flow1d_manning2.SectionType = 'Liquid' Flow1d_manning2.LiquidSectionType = 'PIPE MANNING' Flow1d_manning2.ManningArea = 17671.00 Flow1d_manning2.ManningRadius = 37.5 Flow1d_manning2.ManningCoefficient = 0.002 Flow1d_manning2.References = [(line, "Edge11"), (line, "Edge9")] self.assertTrue(Flow1d_manning2, "FemTest of new Flow1D manning constraint failed") analysis.addObject(Flow1d_manning2) fcc_print('Checking FEM new Flow1D gate valve constraint...') Flow1d_gate_valve = ObjectsFem.makeElementFluid1D( self.active_doc, "ElementFluid1D") Flow1d_gate_valve.SectionType = 'Liquid' Flow1d_gate_valve.LiquidSectionType = 'PIPE GATE VALVE' Flow1d_gate_valve.GateValvePipeArea = 17671 Flow1d_gate_valve.GateValveClosingCoeff = 0.5 Flow1d_gate_valve.References = [(line, "Edge10")] self.assertTrue(Flow1d_gate_valve, "FemTest of new Flow1D gate valve constraint failed") analysis.addObject(Flow1d_gate_valve) fcc_print('Checking FEM new Flow1D enlargement constraint...') Flow1d_enlargement1 = ObjectsFem.makeElementFluid1D( self.active_doc, "ElementFluid1D") Flow1d_enlargement1.SectionType = 'Liquid' Flow1d_enlargement1.LiquidSectionType = 'PIPE ENLARGEMENT' Flow1d_enlargement1.EnlargeArea1 = 17671 Flow1d_enlargement1.EnlargeArea2 = 1e12 Flow1d_enlargement1.References = [(line, "Edge12")] self.assertTrue(Flow1d_enlargement1, "FemTest of new Flow1D enlargement constraint failed") analysis.addObject(Flow1d_enlargement1) fcc_print('Checking FEM Flow1D outlet constraint...') Flow1d_outlet = ObjectsFem.makeElementFluid1D(self.active_doc, "ElementFluid1D") Flow1d_outlet.SectionType = 'Liquid' Flow1d_outlet.LiquidSectionType = 'PIPE OUTLET' Flow1d_outlet.OutletPressure = 0.1 Flow1d_outlet.References = [(line, "Edge13")] self.assertTrue(Flow1d_outlet, "FemTest of new Flow1D inlet constraint failed") analysis.addObject(Flow1d_outlet) fcc_print('Checking FEM self weight constraint...') Flow1d_self_weight = ObjectsFem.makeConstraintSelfWeight( self.active_doc, "ConstraintSelfWeight") Flow1d_self_weight.Gravity_x = 0.0 Flow1d_self_weight.Gravity_y = 0.0 Flow1d_self_weight.Gravity_z = -1.0 self.assertTrue(Flow1d_outlet, "FemTest of new Flow1D self weight constraint failed") analysis.addObject(Flow1d_self_weight) fcc_print('Checking FEM new mesh...') from .testfiles.ccx.Flow1D_mesh import create_nodes_Flow1D from .testfiles.ccx.Flow1D_mesh import create_elements_Flow1D mesh = Fem.FemMesh() ret = create_nodes_Flow1D(mesh) self.assertTrue(ret, "Import of mesh nodes failed") ret = create_elements_Flow1D(mesh) self.assertTrue(ret, "Import of mesh volumes failed") mesh_object = self.active_doc.addObject('Fem::FemMeshObject', self.mesh_name) mesh_object.FemMesh = mesh self.assertTrue(mesh, "FemTest of new mesh failed") analysis.addObject(mesh_object) self.active_doc.recompute() Flow1D_thermomech_analysis_dir = self.temp_dir + 'FEM_ccx_Flow1D_thermomech/' fea = ccxtools.FemToolsCcx(analysis, test_mode=True) fcc_print('Setting up working directory {}'.format( Flow1D_thermomech_analysis_dir)) fea.setup_working_dir(Flow1D_thermomech_analysis_dir) self.assertTrue( True if fea.working_dir == Flow1D_thermomech_analysis_dir else False, "Setting working directory {} failed".format( Flow1D_thermomech_analysis_dir)) fcc_print( 'Checking FEM inp file prerequisites for thermo-mechanical analysis...' ) error = fea.check_prerequisites() self.assertFalse( error, "ccxtools check_prerequisites returned error message: {}".format( error)) fcc_print('Checking FEM inp file write...') fcc_print('Writing {}/{}.inp for thermomech analysis'.format( Flow1D_thermomech_analysis_dir, self.mesh_name)) error = fea.write_inp_file() self.assertFalse(error, "Writing failed") Flow1D_thermomech_base_name = 'Flow1D_thermomech' Flow1D_thermomech_analysis_inp_file = self.test_file_dir + Flow1D_thermomech_base_name + '.inp' fcc_print('Comparing {} to {}/{}.inp'.format( Flow1D_thermomech_analysis_inp_file, Flow1D_thermomech_analysis_dir, self.mesh_name)) ret = testtools.compare_inp_files( Flow1D_thermomech_analysis_inp_file, Flow1D_thermomech_analysis_dir + self.mesh_name + '.inp') self.assertFalse( ret, "ccxtools write_inp_file test failed.\n{}".format(ret)) fcc_print( 'Setting up working directory to {} in order to read simulated calculations' .format(self.test_file_dir)) fea.setup_working_dir(self.test_file_dir) self.assertTrue( True if fea.working_dir == self.test_file_dir else False, "Setting working directory {} failed".format(self.test_file_dir)) fcc_print('Setting base name to read test {}.frd file...'.format( 'Flow1D_thermomech')) fea.set_base_name(Flow1D_thermomech_base_name) self.assertTrue( True if fea.base_name == Flow1D_thermomech_base_name else False, "Setting base name to {} failed".format( Flow1D_thermomech_base_name)) fcc_print('Setting inp file name to read test {}.frd file...'.format( 'Flow1D_thermomech')) fea.set_inp_file_name() self.assertTrue( True if fea.inp_file_name == Flow1D_thermomech_analysis_inp_file else False, "Setting inp file name to {} failed".format( Flow1D_thermomech_analysis_inp_file)) fcc_print( 'Checking FEM frd file read from Flow1D thermomech analysis...') fea.load_results() self.assertTrue( fea.results_present, "Cannot read results from {}.frd frd file".format(fea.base_name)) fcc_print( 'Reading stats from result object for Flow1D thermomech analysis...' ) Flow1D_thermomech_expected_values = self.test_file_dir + "Flow1D_thermomech_expected_values" stat_types = [ "U1", "U2", "U3", "Uabs", "Sabs", "MaxPrin", "MidPrin", "MinPrin", "MaxShear", "Peeq", "Temp", "MFlow", "NPress" ] ret = testtools.compare_stats(fea, Flow1D_thermomech_expected_values, stat_types, 'CalculiX_thermomech_time_1_0_results') self.assertFalse(ret, "Invalid results read from .frd file") Flow1D_thermomech_save_fc_file = Flow1D_thermomech_analysis_dir + Flow1D_thermomech_base_name + '.fcstd' fcc_print('Save FreeCAD file for thermomech analysis to {}...'.format( Flow1D_thermomech_save_fc_file)) self.active_doc.saveAs(Flow1D_thermomech_save_fc_file) fcc_print( '--------------- End of FEM tests FLow 1D thermomech analysis ---------------' )
def test_3_freq_analysis(self): fcc_print('--------------- Start of FEM tests ---------------') self.active_doc.addObject("Part::Box", "Box") fcc_print('Checking FEM new analysis...') analysis = ObjectsFem.makeAnalysis(self.active_doc, 'Analysis') self.assertTrue(analysis, "FemTest of new analysis failed") fcc_print('Checking FEM new solver...') solver_object = ObjectsFem.makeSolverCalculixCcxTools(self.active_doc, 'CalculiX') solver_object.AnalysisType = 'frequency' solver_object.GeometricalNonlinearity = 'linear' solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = 'default' solver_object.IterationsControlParameterTimeUse = False solver_object.EigenmodesCount = 10 solver_object.EigenmodeHighLimit = 1000000.0 solver_object.EigenmodeLowLimit = 0.01 self.assertTrue(solver_object, "FemTest of new solver failed") analysis.addObject(solver_object) fcc_print('Checking FEM new material...') material_object = ObjectsFem.makeMaterialSolid(self.active_doc, 'MechanicalMaterial') mat = material_object.Material mat['Name'] = "Steel-Generic" mat['YoungsModulus'] = "200000 MPa" mat['PoissonRatio'] = "0.30" mat['Density'] = "7900 kg/m^3" material_object.Material = mat self.assertTrue(material_object, "FemTest of new material failed") analysis.addObject(material_object) fcc_print('Checking FEM new mesh...') from .testfiles.ccx.cube_mesh import create_nodes_cube from .testfiles.ccx.cube_mesh import create_elements_cube mesh = Fem.FemMesh() ret = create_nodes_cube(mesh) self.assertTrue(ret, "Import of mesh nodes failed") ret = create_elements_cube(mesh) self.assertTrue(ret, "Import of mesh volumes failed") mesh_object = self.active_doc.addObject('Fem::FemMeshObject', self.mesh_name) mesh_object.FemMesh = mesh self.assertTrue(mesh, "FemTest of new mesh failed") analysis.addObject(mesh_object) self.active_doc.recompute() frequency_analysis_dir = testtools.get_unit_test_tmp_dir(self.temp_dir, 'FEM_ccx_frequency') fea = ccxtools.FemToolsCcx(analysis, solver_object, test_mode=True) fea.update_objects() fcc_print('Setting up working directory {}'.format(frequency_analysis_dir)) fea.setup_working_dir(frequency_analysis_dir) self.assertTrue(True if fea.working_dir == frequency_analysis_dir else False, "Setting working directory {} failed".format(frequency_analysis_dir)) fcc_print('Checking FEM inp file prerequisites for frequency analysis...') error = fea.check_prerequisites() self.assertFalse(error, "ccxtools check_prerequisites returned error message: {}".format(error)) frequency_base_name = 'cube_frequency' inpfile_given = join(self.test_file_dir, (frequency_base_name + '.inp')) inpfile_totest = join(frequency_analysis_dir, (self.mesh_name + '.inp')) fcc_print('Checking FEM inp file write...') fcc_print('Writing {} for frequency analysis'.format(inpfile_totest)) error = fea.write_inp_file() self.assertFalse(error, "Writing failed") fcc_print('Comparing {} to {}'.format(inpfile_given, inpfile_totest)) ret = testtools.compare_inp_files(inpfile_given, inpfile_totest) self.assertFalse(ret, "ccxtools write_inp_file test failed.\n{}".format(ret)) fcc_print('Setting up working directory to {} in order to read simulated calculations'.format(self.test_file_dir)) fea.setup_working_dir(self.test_file_dir) self.assertTrue(True if fea.working_dir == self.test_file_dir else False, "Setting working directory {} failed".format(self.test_file_dir)) fcc_print('Setting base name to read test {}.frd file...'.format(frequency_base_name)) fea.set_base_name(frequency_base_name) self.assertTrue(True if fea.base_name == frequency_base_name else False, "Setting base name to {} failed".format(frequency_base_name)) fcc_print('Setting inp file name to read test {}.frd file...'.format('cube_frequency')) fea.set_inp_file_name() self.assertTrue(True if fea.inp_file_name == inpfile_given else False, "Setting inp file name to {} failed".format(inpfile_given)) fcc_print('Checking FEM frd file read from frequency analysis...') fea.load_results() self.assertTrue(fea.results_present, "Cannot read results from {}.frd frd file".format(fea.base_name)) fcc_print('Reading stats from result object for frequency analysis...') frequency_expected_values = join(self.test_file_dir, "cube_frequency_expected_values") ret = testtools.compare_stats(fea, frequency_expected_values, 'CalculiX_frequency_mode_1_results') self.assertFalse(ret, "Invalid results read from .frd file") frequency_save_fc_file = frequency_analysis_dir + frequency_base_name + '.FCStd' fcc_print('Save FreeCAD file for frequency analysis to {}...'.format(frequency_save_fc_file)) self.active_doc.saveAs(frequency_save_fc_file) fcc_print('--------------- End of FEM tests frequency analysis ---------------')
def test_femobjects_derivedfromfem(self): # try to add all possible True types from inheritance chain see # https://forum.freecadweb.org/viewtopic.php?f=10&t=32625 doc = self.active_doc from femtools.femutils import is_derived_from materialsolid = ObjectsFem.makeMaterialSolid(doc) mesh = ObjectsFem.makeMeshGmsh(doc) solverelmer = ObjectsFem.makeSolverElmer(doc) # FemAnalysis self.assertTrue( is_derived_from(ObjectsFem.makeAnalysis(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeAnalysis(doc), 'Fem::FemAnalysis')) # ConstraintBearing self.assertTrue( is_derived_from(ObjectsFem.makeConstraintBearing(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintBearing(doc), 'Fem::Constraint')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintBearing(doc), 'Fem::ConstraintBearing')) # ConstraintBodyHeatSource self.assertTrue( is_derived_from(ObjectsFem.makeConstraintBodyHeatSource(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintBodyHeatSource(doc), 'Fem::ConstraintPython')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintBodyHeatSource(doc), 'Fem::ConstraintBodyHeatSource')) # ConstraintContact self.assertTrue( is_derived_from(ObjectsFem.makeConstraintContact(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintContact(doc), 'Fem::Constraint')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintContact(doc), 'Fem::ConstraintContact')) # ConstraintDisplacement self.assertTrue( is_derived_from(ObjectsFem.makeConstraintDisplacement(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintDisplacement(doc), 'Fem::Constraint')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintDisplacement(doc), 'Fem::ConstraintDisplacement')) # ConstraintElectrostaticPotential self.assertTrue( is_derived_from( ObjectsFem.makeConstraintElectrostaticPotential(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from( ObjectsFem.makeConstraintElectrostaticPotential(doc), 'Fem::ConstraintPython')) self.assertTrue( is_derived_from( ObjectsFem.makeConstraintElectrostaticPotential(doc), 'Fem::ConstraintElectrostaticPotential')) # ConstraintFixed self.assertTrue( is_derived_from(ObjectsFem.makeConstraintFixed(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintFixed(doc), 'Fem::Constraint')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintFixed(doc), 'Fem::ConstraintFixed')) # ConstraintFlowVelocity self.assertTrue( is_derived_from(ObjectsFem.makeConstraintFlowVelocity(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintFlowVelocity(doc), 'Fem::ConstraintPython')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintFlowVelocity(doc), 'Fem::ConstraintFlowVelocity')) # ConstraintFluidBoundary self.assertTrue( is_derived_from(ObjectsFem.makeConstraintFluidBoundary(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintFluidBoundary(doc), 'Fem::Constraint')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintFluidBoundary(doc), 'Fem::ConstraintFluidBoundary')) # ConstraintForce self.assertTrue( is_derived_from(ObjectsFem.makeConstraintForce(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintForce(doc), 'Fem::Constraint')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintForce(doc), 'Fem::ConstraintForce')) # ConstraintGear self.assertTrue( is_derived_from(ObjectsFem.makeConstraintGear(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintGear(doc), 'Fem::Constraint')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintGear(doc), 'Fem::ConstraintGear')) # ConstraintHeatflux self.assertTrue( is_derived_from(ObjectsFem.makeConstraintHeatflux(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintHeatflux(doc), 'Fem::Constraint')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintHeatflux(doc), 'Fem::ConstraintHeatflux')) # ConstraintInitialFlowVelocity self.assertTrue( is_derived_from(ObjectsFem.makeConstraintInitialFlowVelocity(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintInitialFlowVelocity(doc), 'Fem::ConstraintPython')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintInitialFlowVelocity(doc), 'Fem::ConstraintInitialFlowVelocity')) # ConstraintInitialTemperature self.assertTrue( is_derived_from(ObjectsFem.makeConstraintInitialTemperature(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintInitialTemperature(doc), 'Fem::Constraint')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintInitialTemperature(doc), 'Fem::ConstraintInitialTemperature')) # ConstraintPlaneRotation self.assertTrue( is_derived_from(ObjectsFem.makeConstraintPlaneRotation(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintPlaneRotation(doc), 'Fem::Constraint')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintPlaneRotation(doc), 'Fem::ConstraintPlaneRotation')) # ConstraintPressure self.assertTrue( is_derived_from(ObjectsFem.makeConstraintPressure(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintPressure(doc), 'Fem::Constraint')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintPressure(doc), 'Fem::ConstraintPressure')) # ConstraintPulley self.assertTrue( is_derived_from(ObjectsFem.makeConstraintPulley(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintPulley(doc), 'Fem::Constraint')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintPulley(doc), 'Fem::ConstraintPulley')) # ConstraintSelfWeight self.assertTrue( is_derived_from(ObjectsFem.makeConstraintSelfWeight(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintSelfWeight(doc), 'Fem::ConstraintPython')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintSelfWeight(doc), 'Fem::ConstraintSelfWeight')) # ConstraintTemperature self.assertTrue( is_derived_from(ObjectsFem.makeConstraintTemperature(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintTemperature(doc), 'Fem::Constraint')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintTemperature(doc), 'Fem::ConstraintTemperature')) # ConstraintTransform self.assertTrue( is_derived_from(ObjectsFem.makeConstraintTransform(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeConstraintTransform(doc), 'Fem::ConstraintTransform')) # FemElementFluid1D self.assertTrue( is_derived_from(ObjectsFem.makeElementFluid1D(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeElementFluid1D(doc), 'Fem::FeaturePython')) self.assertTrue( is_derived_from(ObjectsFem.makeElementFluid1D(doc), 'Fem::FemElementFluid1D')) # FemElementGeometry1D self.assertTrue( is_derived_from(ObjectsFem.makeElementGeometry1D(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeElementGeometry1D(doc), 'Fem::FeaturePython')) self.assertTrue( is_derived_from(ObjectsFem.makeElementGeometry1D(doc), 'Fem::FemElementGeometry1D')) # FemElementGeometry2D self.assertTrue( is_derived_from(ObjectsFem.makeElementGeometry2D(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeElementGeometry2D(doc), 'Fem::FeaturePython')) self.assertTrue( is_derived_from(ObjectsFem.makeElementGeometry2D(doc), 'Fem::FemElementGeometry2D')) # FemElementRotation1D self.assertTrue( is_derived_from(ObjectsFem.makeElementRotation1D(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeElementRotation1D(doc), 'Fem::FeaturePython')) self.assertTrue( is_derived_from(ObjectsFem.makeElementRotation1D(doc), 'Fem::FemElementRotation1D')) # Material self.assertTrue( is_derived_from(ObjectsFem.makeMaterialFluid(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeMaterialFluid(doc), 'App::MaterialObjectPython')) self.assertTrue( is_derived_from(ObjectsFem.makeMaterialFluid(doc), 'Fem::Material')) # Material self.assertTrue(is_derived_from(materialsolid, 'App::DocumentObject')) self.assertTrue( is_derived_from(materialsolid, 'App::MaterialObjectPython')) self.assertTrue(is_derived_from(materialsolid, 'Fem::Material')) # MaterialMechanicalNonlinear self.assertTrue( is_derived_from( ObjectsFem.makeMaterialMechanicalNonlinear(doc, materialsolid), 'App::DocumentObject')) self.assertTrue( is_derived_from( ObjectsFem.makeMaterialMechanicalNonlinear(doc, materialsolid), 'Fem::FeaturePython')) self.assertTrue( is_derived_from( ObjectsFem.makeMaterialMechanicalNonlinear(doc, materialsolid), 'Fem::MaterialMechanicalNonlinear')) # MaterialReinforced self.assertTrue( is_derived_from(ObjectsFem.makeMaterialReinforced(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeMaterialReinforced(doc), 'App::MaterialObjectPython')) self.assertTrue( is_derived_from(ObjectsFem.makeMaterialReinforced(doc), 'Fem::MaterialReinforced')) # FemMeshGmsh self.assertTrue(is_derived_from(mesh, 'App::DocumentObject')) self.assertTrue(is_derived_from(mesh, 'Fem::FemMeshObjectPython')) self.assertTrue(is_derived_from(mesh, 'Fem::FemMeshGmsh')) # FemMeshBoundaryLayer self.assertTrue( is_derived_from(ObjectsFem.makeMeshBoundaryLayer(doc, mesh), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeMeshBoundaryLayer(doc, mesh), 'Fem::FeaturePython')) self.assertTrue( is_derived_from(ObjectsFem.makeMeshBoundaryLayer(doc, mesh), 'Fem::FemMeshBoundaryLayer')) # FemMeshGroup self.assertTrue( is_derived_from(ObjectsFem.makeMeshGroup(doc, mesh), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeMeshGroup(doc, mesh), 'Fem::FeaturePython')) self.assertTrue( is_derived_from(ObjectsFem.makeMeshGroup(doc, mesh), 'Fem::FemMeshGroup')) # FemMeshRegion self.assertTrue( is_derived_from(ObjectsFem.makeMeshRegion(doc, mesh), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeMeshRegion(doc, mesh), 'Fem::FeaturePython')) self.assertTrue( is_derived_from(ObjectsFem.makeMeshRegion(doc, mesh), 'Fem::FemMeshRegion')) # FemMeshShapeNetgenObject self.assertTrue( is_derived_from(ObjectsFem.makeMeshNetgen(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeMeshNetgen(doc), 'Fem::FemMeshShapeNetgenObject')) # FemMeshResult self.assertTrue( is_derived_from(ObjectsFem.makeMeshResult(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeMeshResult(doc), 'Fem::FemMeshObjectPython')) self.assertTrue( is_derived_from(ObjectsFem.makeMeshResult(doc), 'Fem::FemMeshResult')) # FemResultMechanical self.assertTrue( is_derived_from(ObjectsFem.makeResultMechanical(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeResultMechanical(doc), 'Fem::FemResultObjectPython')) self.assertTrue( is_derived_from(ObjectsFem.makeResultMechanical(doc), 'Fem::FemResultMechanical')) # FemSolverCalculixCcxTools self.assertTrue( is_derived_from(ObjectsFem.makeSolverCalculixCcxTools(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeSolverCalculixCcxTools(doc), 'Fem::FemSolverObject')) self.assertTrue( is_derived_from(ObjectsFem.makeSolverCalculixCcxTools(doc), 'Fem::FemSolverObjectPython')) self.assertTrue( is_derived_from(ObjectsFem.makeSolverCalculixCcxTools(doc), 'Fem::FemSolverCalculixCcxTools')) # FemSolverObjectCalculix self.assertTrue( is_derived_from(ObjectsFem.makeSolverCalculix(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeSolverCalculix(doc), 'Fem::FemSolverObject')) self.assertTrue( is_derived_from(ObjectsFem.makeSolverCalculix(doc), 'Fem::FemSolverObjectPython')) self.assertTrue( is_derived_from(ObjectsFem.makeSolverCalculix(doc), 'Fem::FemSolverObjectCalculix')) # FemSolverObjectElmer self.assertTrue(is_derived_from(solverelmer, 'App::DocumentObject')) self.assertTrue(is_derived_from(solverelmer, 'Fem::FemSolverObject')) self.assertTrue( is_derived_from(solverelmer, 'Fem::FemSolverObjectPython')) self.assertTrue( is_derived_from(solverelmer, 'Fem::FemSolverObjectElmer')) # FemSolverObjectZ88 self.assertTrue( is_derived_from(ObjectsFem.makeSolverZ88(doc), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeSolverZ88(doc), 'Fem::FemSolverObject')) self.assertTrue( is_derived_from(ObjectsFem.makeSolverZ88(doc), 'Fem::FemSolverObjectPython')) self.assertTrue( is_derived_from(ObjectsFem.makeSolverZ88(doc), 'Fem::FemSolverObjectZ88')) # FemEquationElmerElasticity self.assertTrue( is_derived_from( ObjectsFem.makeEquationElasticity(doc, solverelmer), 'App::DocumentObject')) self.assertTrue( is_derived_from( ObjectsFem.makeEquationElasticity(doc, solverelmer), 'App::FeaturePython')) self.assertTrue( is_derived_from( ObjectsFem.makeEquationElasticity(doc, solverelmer), 'Fem::FemEquationElmerElasticity')) # FemEquationElmerElectrostatic self.assertTrue( is_derived_from( ObjectsFem.makeEquationElectrostatic(doc, solverelmer), 'App::DocumentObject')) self.assertTrue( is_derived_from( ObjectsFem.makeEquationElectrostatic(doc, solverelmer), 'App::FeaturePython')) self.assertTrue( is_derived_from( ObjectsFem.makeEquationElectrostatic(doc, solverelmer), 'Fem::FemEquationElmerElectrostatic')) # FemEquationElmerFlow self.assertTrue( is_derived_from(ObjectsFem.makeEquationFlow(doc, solverelmer), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeEquationFlow(doc, solverelmer), 'App::FeaturePython')) self.assertTrue( is_derived_from(ObjectsFem.makeEquationFlow(doc, solverelmer), 'Fem::FemEquationElmerFlow')) # FemEquationElmerFluxsolver self.assertTrue( is_derived_from( ObjectsFem.makeEquationFluxsolver(doc, solverelmer), 'App::DocumentObject')) self.assertTrue( is_derived_from( ObjectsFem.makeEquationFluxsolver(doc, solverelmer), 'App::FeaturePython')) self.assertTrue( is_derived_from( ObjectsFem.makeEquationFluxsolver(doc, solverelmer), 'Fem::FemEquationElmerFluxsolver')) # FemEquationElmerHeat self.assertTrue( is_derived_from(ObjectsFem.makeEquationHeat(doc, solverelmer), 'App::DocumentObject')) self.assertTrue( is_derived_from(ObjectsFem.makeEquationHeat(doc, solverelmer), 'App::FeaturePython')) self.assertTrue( is_derived_from(ObjectsFem.makeEquationHeat(doc, solverelmer), 'Fem::FemEquationElmerHeat'))
def setup(doc=None, solvertype="ccxtools"): # setup model if doc is None: doc = init_doc() # geometry objects # two boxes boxlow = doc.addObject("Part::Box", "BoxLower") boxupp = doc.addObject("Part::Box", "BoxUpper") boxupp.Placement.Base = (0, 0, 10) # boolean fragment of the two boxes bf = SplitFeatures.makeBooleanFragments(name="BooleanFragments") bf.Objects = [boxlow, boxupp] bf.Mode = "CompSolid" doc.recompute() bf.Proxy.execute(bf) bf.purgeTouched() if FreeCAD.GuiUp: for child in bf.ViewObject.Proxy.claimChildren(): child.ViewObject.hide() doc.recompute() # extract CompSolid by compound filter tool geom_obj = CompoundFilter.makeCompoundFilter(name="MultiMatCompSolid") geom_obj.Base = bf geom_obj.FilterType = "window-volume" geom_obj.Proxy.execute(geom_obj) geom_obj.purgeTouched() if FreeCAD.GuiUp: geom_obj.Base.ViewObject.hide() doc.recompute() if FreeCAD.GuiUp: geom_obj.ViewObject.Document.activeView().viewAxonometric() geom_obj.ViewObject.Document.activeView().fitAll() # analysis analysis = ObjectsFem.makeAnalysis(doc, "Analysis") # solver if solvertype == "calculix": solver_object = analysis.addObject( ObjectsFem.makeSolverCalculix(doc, "SolverCalculiX"))[0] elif solvertype == "ccxtools": solver_object = analysis.addObject( ObjectsFem.makeSolverCalculixCcxTools(doc, "CalculiXccxTools"))[0] solver_object.WorkingDir = u"" if solvertype == "calculix" or solvertype == "ccxtools": solver_object.SplitInputWriter = False solver_object.AnalysisType = "static" solver_object.GeometricalNonlinearity = "linear" solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = "default" solver_object.IterationsControlParameterTimeUse = False # material material_object_low = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterialLow"))[0] mat = material_object_low.Material mat["Name"] = "Aluminium-Generic" mat["YoungsModulus"] = "70000 MPa" mat["PoissonRatio"] = "0.35" mat["Density"] = "2700 kg/m^3" material_object_low.Material = mat material_object_low.References = [(boxlow, "Solid1")] analysis.addObject(material_object_low) material_object_upp = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterialUpp"))[0] mat = material_object_upp.Material mat["Name"] = "Steel-Generic" mat["YoungsModulus"] = "200000 MPa" mat["PoissonRatio"] = "0.30" mat["Density"] = "7980 kg/m^3" material_object_upp.Material = mat material_object_upp.References = [(boxupp, "Solid1")] # fixed_constraint fixed_constraint = analysis.addObject( ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed"))[0] fixed_constraint.References = [(geom_obj, "Face5")] # pressure_constraint pressure_constraint = analysis.addObject( ObjectsFem.makeConstraintPressure(doc, "ConstraintPressure"))[0] pressure_constraint.References = [(geom_obj, "Face11")] pressure_constraint.Pressure = 1000.0 pressure_constraint.Reversed = False # mesh from .meshes.mesh_boxes_2_vertikal_tetra10 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, mesh_name))[0] femmesh_obj.FemMesh = fem_mesh femmesh_obj.Part = geom_obj femmesh_obj.SecondOrderLinear = False doc.recompute() return doc
def setup(doc=None, solvertype="ccxtools"): # init FreeCAD document if doc is None: doc = init_doc() # explanation object # just keep the following line and change text string in get_explanation method manager.add_explanation_obj( doc, get_explanation(manager.get_header(get_information()))) # geometric object geom_obj = doc.addObject("Part::Plane", "Plate") geom_obj.Width = 6000 geom_obj.Length = 8000 doc.recompute() if FreeCAD.GuiUp: geom_obj.ViewObject.Document.activeView().viewAxonometric() geom_obj.ViewObject.Document.activeView().fitAll() # analysis analysis = ObjectsFem.makeAnalysis(doc, "Analysis") # solver if solvertype == "calculix": solver_obj = ObjectsFem.makeSolverCalculix(doc, "SolverCalculiX") elif solvertype == "ccxtools": solver_obj = ObjectsFem.makeSolverCalculixCcxTools( doc, "CalculiXccxTools") solver_obj.WorkingDir = u"" else: FreeCAD.Console.PrintWarning( "Not known or not supported solver type: {}. " "No solver object was created.\n".format(solvertype)) if solvertype == "calculix" or solvertype == "ccxtools": solver_obj.SplitInputWriter = False solver_obj.AnalysisType = "buckling" solver_obj.BucklingFactors = 10 solver_obj.GeometricalNonlinearity = "linear" solver_obj.ThermoMechSteadyState = False solver_obj.MatrixSolverType = "default" solver_obj.IterationsControlParameterTimeUse = False solver_obj.BucklingFactors = 1 analysis.addObject(solver_obj) # shell thickness thickness_obj = ObjectsFem.makeElementGeometry2D(doc, 50, 'Thickness') analysis.addObject(thickness_obj) # material material_obj = ObjectsFem.makeMaterialSolid(doc, "Steel") mat = material_obj.Material mat["Name"] = "CalculiX-Steel" mat["YoungsModulus"] = "210000 MPa" mat["PoissonRatio"] = "0.30" material_obj.Material = mat analysis.addObject(material_obj) # constraints displacement con_disp_x = ObjectsFem.makeConstraintDisplacement( doc, "ConstraintDisplacement_X") con_disp_x.References = [(geom_obj, "Edge1")] con_disp_x.xFix = True con_disp_x.xFree = False analysis.addObject(con_disp_x) con_disp_y = ObjectsFem.makeConstraintDisplacement( doc, "ConstraintDisplacement_Y") con_disp_y.References = [(geom_obj, "Vertex1")] con_disp_y.yFix = True con_disp_y.yFree = False analysis.addObject(con_disp_y) con_disp_z = ObjectsFem.makeConstraintDisplacement( doc, "ConstraintDisplacement_Z") con_disp_z.References = [ (geom_obj, "Edge1"), (geom_obj, "Edge2"), (geom_obj, "Edge3"), (geom_obj, "Edge4"), ] con_disp_z.zFix = True con_disp_z.zFree = False analysis.addObject(con_disp_z) # constraint force con_force = ObjectsFem.makeConstraintForce(doc, "ConstraintForce") con_force.References = [(geom_obj, "Edge3")] con_force.Force = 17162160 # 17'162.16 N con_force.Reversed = True con_force.Direction = (geom_obj, ["Edge2"]) analysis.addObject(con_force) # mesh from .meshes.mesh_buckling_plate_tria6 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") femmesh_obj = analysis.addObject( ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0] femmesh_obj.FemMesh = fem_mesh femmesh_obj.Part = geom_obj femmesh_obj.SecondOrderLinear = False femmesh_obj.CharacteristicLengthMax = "300.0 mm" femmesh_obj.ElementDimension = "2D" doc.recompute() return doc
def setup(doc=None, solvertype="ccxtools"): # setup reinfoced wall in 2D if doc is None: doc = init_doc() # part from FreeCAD import Vector as vec import Part from Part import makeLine as ln v1 = vec(0, -2000, 0) v2 = vec(500, -2000, 0) v3 = vec(500, 0, 0) v4 = vec(3500, 0, 0) v5 = vec(3500, -2000, 0) v6 = vec(4000, -2000, 0) v7 = vec(4000, 2000, 0) v8 = vec(0, 2000, 0) l1 = ln(v1, v2) l2 = ln(v2, v3) l3 = ln(v3, v4) l4 = ln(v4, v5) l5 = ln(v5, v6) l6 = ln(v6, v7) l7 = ln(v7, v8) l8 = ln(v8, v1) rcwall = doc.addObject("Part::Feature", "FIB_Wall") rcwall.Shape = Part.Face(Part.Wire([l1, l2, l3, l4, l5, l6, l7, l8])) doc.recompute() if FreeCAD.GuiUp: import FreeCADGui FreeCADGui.ActiveDocument.activeView().viewAxonometric() FreeCADGui.SendMsgToActiveView("ViewFit") # analysis analysis = ObjectsFem.makeAnalysis(doc, "Analysis") # solver if solvertype == "calculix": solver = analysis.addObject( ObjectsFem.makeSolverCalculix(doc, "SolverCalculiX"))[0] elif solvertype == "ccxtools": solver = analysis.addObject( ObjectsFem.makeSolverCalculixCcxTools(doc, "CalculiXccxTools"))[0] solver.WorkingDir = u"" if solvertype == "calculix" or solvertype == "ccxtools": solver.AnalysisType = "static" solver.GeometricalNonlinearity = "linear" solver.ThermoMechSteadyState = False solver.MatrixSolverType = "default" solver.IterationsControlParameterTimeUse = False # shell thickness thickness = analysis.addObject( ObjectsFem.makeElementGeometry2D(doc, 0, "ShellThickness"))[0] thickness.Thickness = 150.0 # material matrixprop = {} matrixprop["Name"] = "Concrete-EN-C35/45" matrixprop["YoungsModulus"] = "32000 MPa" matrixprop["PoissonRatio"] = "0.17" matrixprop["CompressiveStrength"] = "15.75 MPa" # make some hint on the possible angle units in material system matrixprop["AngleOfFriction"] = "30 deg" matrixprop["Density"] = "2500 kg/m^3" reinfoprop = {} reinfoprop["Name"] = "Reinforcement-FIB-B500" reinfoprop["YieldStrength"] = "315 MPa" # not an official FreeCAD material property reinfoprop["ReinforcementRatio"] = "0.0" material_reinforced = analysis.addObject( ObjectsFem.makeMaterialReinforced(doc, "MaterialReinforced"))[0] material_reinforced.Material = matrixprop material_reinforced.Reinforcement = reinfoprop # fixed_constraint fixed_constraint = analysis.addObject( ObjectsFem.makeConstraintFixed(doc, name="ConstraintFixed"))[0] fixed_constraint.References = [(rcwall, "Edge1"), (rcwall, "Edge5")] # force constraint force_constraint = doc.Analysis.addObject( ObjectsFem.makeConstraintForce(doc, name="ConstraintForce"))[0] force_constraint.References = [(rcwall, "Edge7")] force_constraint.Force = 1000000.0 force_constraint.Direction = (rcwall, ["Edge8"]) force_constraint.Reversed = False # displacement_constraint displacement_constraint = doc.Analysis.addObject( ObjectsFem.makeConstraintDisplacement( doc, name="ConstraintDisplacmentPrescribed"))[0] displacement_constraint.References = [(rcwall, "Face1")] displacement_constraint.zFix = True # mesh from .meshes.mesh_rc_wall_2d_tria6 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") femmesh_obj = analysis.addObject( doc.addObject("Fem::FemMeshObject", mesh_name))[0] femmesh_obj.FemMesh = fem_mesh doc.recompute() return doc
def test_femobjects_derivedfromfem(self): # try to add all possible True types from inheritance chain see https://forum.freecadweb.org/viewtopic.php?f=10&t=32625 doc = self.active_doc from femtools.femutils import is_derived_from materialsolid = ObjectsFem.makeMaterialSolid(doc) mesh = ObjectsFem.makeMeshGmsh(doc) solverelmer = ObjectsFem.makeSolverElmer(doc) self.assertTrue(is_derived_from(ObjectsFem.makeAnalysis(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeAnalysis(doc), 'Fem::FemAnalysis')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintBearing(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintBearing(doc), 'Fem::Constraint')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintBearing(doc), 'Fem::ConstraintBearing')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintBodyHeatSource(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintBodyHeatSource(doc), 'Fem::ConstraintPython')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintBodyHeatSource(doc), 'Fem::ConstraintBodyHeatSource')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintContact(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintContact(doc), 'Fem::Constraint')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintContact(doc), 'Fem::ConstraintContact')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintDisplacement(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintDisplacement(doc), 'Fem::Constraint')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintDisplacement(doc), 'Fem::ConstraintDisplacement')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintElectrostaticPotential(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintElectrostaticPotential(doc), 'Fem::ConstraintPython')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintElectrostaticPotential(doc), 'Fem::ConstraintElectrostaticPotential')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintFixed(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintFixed(doc), 'Fem::Constraint')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintFixed(doc), 'Fem::ConstraintFixed')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintFlowVelocity(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintFlowVelocity(doc), 'Fem::ConstraintPython')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintFlowVelocity(doc), 'Fem::ConstraintFlowVelocity')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintFluidBoundary(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintFluidBoundary(doc), 'Fem::Constraint')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintFluidBoundary(doc), 'Fem::ConstraintFluidBoundary')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintForce(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintForce(doc), 'Fem::Constraint')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintForce(doc), 'Fem::ConstraintForce')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintGear(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintGear(doc), 'Fem::Constraint')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintGear(doc), 'Fem::ConstraintGear')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintHeatflux(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintHeatflux(doc), 'Fem::Constraint')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintHeatflux(doc), 'Fem::ConstraintHeatflux')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintInitialFlowVelocity(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintInitialFlowVelocity(doc), 'Fem::ConstraintPython')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintInitialFlowVelocity(doc), 'Fem::ConstraintInitialFlowVelocity')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintInitialTemperature(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintInitialTemperature(doc), 'Fem::Constraint')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintInitialTemperature(doc), 'Fem::ConstraintInitialTemperature')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintPlaneRotation(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintPlaneRotation(doc), 'Fem::Constraint')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintPlaneRotation(doc), 'Fem::ConstraintPlaneRotation')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintPressure(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintPressure(doc), 'Fem::Constraint')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintPressure(doc), 'Fem::ConstraintPressure')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintPulley(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintPulley(doc), 'Fem::Constraint')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintPulley(doc), 'Fem::ConstraintPulley')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintSelfWeight(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintSelfWeight(doc), 'Fem::ConstraintPython')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintSelfWeight(doc), 'Fem::ConstraintSelfWeight')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintTemperature(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintTemperature(doc), 'Fem::Constraint')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintTemperature(doc), 'Fem::ConstraintTemperature')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintTransform(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeConstraintTransform(doc), 'Fem::ConstraintTransform')) self.assertTrue(is_derived_from(ObjectsFem.makeElementFluid1D(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeElementFluid1D(doc), 'Fem::FeaturePython')) self.assertTrue(is_derived_from(ObjectsFem.makeElementFluid1D(doc), 'Fem::FemElementFluid1D')) self.assertTrue(is_derived_from(ObjectsFem.makeElementGeometry1D(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeElementGeometry1D(doc), 'Fem::FeaturePython')) self.assertTrue(is_derived_from(ObjectsFem.makeElementGeometry1D(doc), 'Fem::FemElementGeometry1D')) self.assertTrue(is_derived_from(ObjectsFem.makeElementGeometry2D(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeElementGeometry2D(doc), 'Fem::FeaturePython')) self.assertTrue(is_derived_from(ObjectsFem.makeElementGeometry2D(doc), 'Fem::FemElementGeometry2D')) self.assertTrue(is_derived_from(ObjectsFem.makeElementRotation1D(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeElementRotation1D(doc), 'Fem::FeaturePython')) self.assertTrue(is_derived_from(ObjectsFem.makeElementRotation1D(doc), 'Fem::FemElementRotation1D')) self.assertTrue(is_derived_from(ObjectsFem.makeMaterialFluid(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeMaterialFluid(doc), 'App::MaterialObjectPython')) self.assertTrue(is_derived_from(ObjectsFem.makeMaterialFluid(doc), 'Fem::Material')) self.assertTrue(is_derived_from(materialsolid, 'App::DocumentObject')) self.assertTrue(is_derived_from(materialsolid, 'App::MaterialObjectPython')) self.assertTrue(is_derived_from(materialsolid, 'Fem::Material')) self.assertTrue(is_derived_from(ObjectsFem.makeMaterialMechanicalNonlinear(doc, materialsolid), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeMaterialMechanicalNonlinear(doc, materialsolid), 'Fem::FeaturePython')) self.assertTrue(is_derived_from(ObjectsFem.makeMaterialMechanicalNonlinear(doc, materialsolid), 'Fem::MaterialMechanicalNonlinear')) self.assertTrue(is_derived_from(mesh, 'App::DocumentObject')) self.assertTrue(is_derived_from(mesh, 'Fem::FemMeshObjectPython')) self.assertTrue(is_derived_from(mesh, 'Fem::FemMeshGmsh')) self.assertTrue(is_derived_from(ObjectsFem.makeMeshBoundaryLayer(doc, mesh), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeMeshBoundaryLayer(doc, mesh), 'Fem::FeaturePython')) self.assertTrue(is_derived_from(ObjectsFem.makeMeshBoundaryLayer(doc, mesh), 'Fem::FemMeshBoundaryLayer')) self.assertTrue(is_derived_from(ObjectsFem.makeMeshGroup(doc, mesh), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeMeshGroup(doc, mesh), 'Fem::FeaturePython')) self.assertTrue(is_derived_from(ObjectsFem.makeMeshGroup(doc, mesh), 'Fem::FemMeshGroup')) self.assertTrue(is_derived_from(ObjectsFem.makeMeshRegion(doc, mesh), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeMeshRegion(doc, mesh), 'Fem::FeaturePython')) self.assertTrue(is_derived_from(ObjectsFem.makeMeshRegion(doc, mesh), 'Fem::FemMeshRegion')) self.assertTrue(is_derived_from(ObjectsFem.makeMeshNetgen(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeMeshNetgen(doc), 'Fem::FemMeshShapeNetgenObject')) self.assertTrue(is_derived_from(ObjectsFem.makeMeshResult(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeMeshResult(doc), 'Fem::FemMeshObjectPython')) self.assertTrue(is_derived_from(ObjectsFem.makeMeshResult(doc), 'Fem::FemMeshResult')) self.assertTrue(is_derived_from(ObjectsFem.makeResultMechanical(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeResultMechanical(doc), 'Fem::FemResultObjectPython')) self.assertTrue(is_derived_from(ObjectsFem.makeResultMechanical(doc), 'Fem::FemResultMechanical')) self.assertTrue(is_derived_from(ObjectsFem.makeSolverCalculixCcxTools(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeSolverCalculixCcxTools(doc), 'Fem::FemSolverObject')) self.assertTrue(is_derived_from(ObjectsFem.makeSolverCalculixCcxTools(doc), 'Fem::FemSolverObjectPython')) self.assertTrue(is_derived_from(ObjectsFem.makeSolverCalculixCcxTools(doc), 'Fem::FemSolverCalculixCcxTools')) self.assertTrue(is_derived_from(ObjectsFem.makeSolverCalculix(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeSolverCalculix(doc), 'Fem::FemSolverObject')) self.assertTrue(is_derived_from(ObjectsFem.makeSolverCalculix(doc), 'Fem::FemSolverObjectPython')) self.assertTrue(is_derived_from(ObjectsFem.makeSolverCalculix(doc), 'Fem::FemSolverObjectCalculix')) self.assertTrue(is_derived_from(solverelmer, 'App::DocumentObject')) self.assertTrue(is_derived_from(solverelmer, 'Fem::FemSolverObject')) self.assertTrue(is_derived_from(solverelmer, 'Fem::FemSolverObjectPython')) self.assertTrue(is_derived_from(solverelmer, 'Fem::FemSolverObjectElmer')) self.assertTrue(is_derived_from(ObjectsFem.makeSolverZ88(doc), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeSolverZ88(doc), 'Fem::FemSolverObject')) self.assertTrue(is_derived_from(ObjectsFem.makeSolverZ88(doc), 'Fem::FemSolverObjectPython')) self.assertTrue(is_derived_from(ObjectsFem.makeSolverZ88(doc), 'Fem::FemSolverObjectZ88')) self.assertTrue(is_derived_from(ObjectsFem.makeEquationElasticity(doc, solverelmer), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeEquationElasticity(doc, solverelmer), 'App::FeaturePython')) self.assertTrue(is_derived_from(ObjectsFem.makeEquationElasticity(doc, solverelmer), 'Fem::FemEquationElmerElasticity')) self.assertTrue(is_derived_from(ObjectsFem.makeEquationElectrostatic(doc, solverelmer), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeEquationElectrostatic(doc, solverelmer), 'App::FeaturePython')) self.assertTrue(is_derived_from(ObjectsFem.makeEquationElectrostatic(doc, solverelmer), 'Fem::FemEquationElmerElectrostatic')) self.assertTrue(is_derived_from(ObjectsFem.makeEquationFlow(doc, solverelmer), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeEquationFlow(doc, solverelmer), 'App::FeaturePython')) self.assertTrue(is_derived_from(ObjectsFem.makeEquationFlow(doc, solverelmer), 'Fem::FemEquationElmerFlow')) self.assertTrue(is_derived_from(ObjectsFem.makeEquationFluxsolver(doc, solverelmer), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeEquationFluxsolver(doc, solverelmer), 'App::FeaturePython')) self.assertTrue(is_derived_from(ObjectsFem.makeEquationFluxsolver(doc, solverelmer), 'Fem::FemEquationElmerFluxsolver')) self.assertTrue(is_derived_from(ObjectsFem.makeEquationHeat(doc, solverelmer), 'App::DocumentObject')) self.assertTrue(is_derived_from(ObjectsFem.makeEquationHeat(doc, solverelmer), 'App::FeaturePython')) self.assertTrue(is_derived_from(ObjectsFem.makeEquationHeat(doc, solverelmer), 'Fem::FemEquationElmerHeat'))
def setup_cantileverbase(doc=None, solver='ccxtools'): # setup CalculiX cantilever base model if doc is None: doc = init_doc() # part box_obj = doc.addObject('Part::Box', 'Box') box_obj.Height = box_obj.Width = 1000 box_obj.Length = 8000 # analysis analysis = ObjectsFem.makeAnalysis(doc, 'Analysis') solver # TODO How to pass multiple solver for one analysis in one doc if solver is None: pass # no solver is added elif solver is 'calculix': solver_object = analysis.addObject( ObjectsFem.makeSolverCalculix(doc, 'SolverCalculiX'))[0] solver_object.AnalysisType = 'static' solver_object.GeometricalNonlinearity = 'linear' solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = 'default' solver_object.IterationsControlParameterTimeUse = False elif solver is 'ccxtools': solver_object = analysis.addObject( ObjectsFem.makeSolverCalculixCcxTools(doc, 'CalculiXccxTools'))[0] solver_object.AnalysisType = 'static' solver_object.GeometricalNonlinearity = 'linear' solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = 'default' solver_object.IterationsControlParameterTimeUse = False solver_object.WorkingDir = u'' elif solver is 'elmer': analysis.addObject(ObjectsFem.makeSolverElmer(doc, 'SolverElmer')) elif solver is 'z88': analysis.addObject(ObjectsFem.makeSolverZ88(doc, 'SolverZ88')) # material material_object = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, 'FemMaterial'))[0] mat = material_object.Material mat['Name'] = "CalculiX-Steel" mat['YoungsModulus'] = "210000 MPa" mat['PoissonRatio'] = "0.30" mat['Density'] = "7900 kg/m^3" mat['ThermalExpansionCoefficient'] = "0.012 mm/m/K" material_object.Material = mat # fixed_constraint fixed_constraint = analysis.addObject( ObjectsFem.makeConstraintFixed(doc, name="ConstraintFixed"))[0] fixed_constraint.References = [(doc.Box, "Face1")] # mesh from femexamples.meshes.mesh_canticcx_tetra10 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: print('ERROR on creating nodes') control = create_elements(fem_mesh) if not control: print('ERROR on creating elements') femmesh_obj = analysis.addObject( doc.addObject('Fem::FemMeshObject', mesh_name))[0] femmesh_obj.FemMesh = fem_mesh doc.recompute() return doc
def setup(doc=None, solvertype="ccxtools"): # setup model if doc is None: doc = init_doc() # part # create a CompSolid of two Boxes extract the CompSolid # we are able to remesh if needed boxlow = doc.addObject("Part::Box", "BoxLower") boxupp = doc.addObject("Part::Box", "BoxUpper") boxupp.Placement.Base = (0, 0, 10) # for BooleanFragments Occt >=6.9 is needed """ import BOPTools.SplitFeatures bf = BOPTools.SplitFeatures.makeBooleanFragments(name="BooleanFragments") bf.Objects = [boxlow, boxupp] bf.Mode = "CompSolid" self.active_doc.recompute() bf.Proxy.execute(bf) bf.purgeTouched() for obj in bf.ViewObject.Proxy.claimChildren(): obj.ViewObject.hide() self.active_doc.recompute() import CompoundTools.CompoundFilter cf = CompoundTools.CompoundFilter.makeCompoundFilter(name="MultiMatCompSolid") cf.Base = bf cf.FilterType = "window-volume" cf.Proxy.execute(cf) cf.purgeTouched() cf.Base.ViewObject.hide() """ doc.recompute() if FreeCAD.GuiUp: import FreeCADGui FreeCADGui.ActiveDocument.activeView().viewAxonometric() FreeCADGui.SendMsgToActiveView("ViewFit") # analysis analysis = ObjectsFem.makeAnalysis(doc, "Analysis") # solver if solvertype == "calculix": solver_object = analysis.addObject( ObjectsFem.makeSolverCalculix(doc, "SolverCalculiX") )[0] elif solvertype == "ccxtools": solver_object = analysis.addObject( ObjectsFem.makeSolverCalculixCcxTools(doc, "CalculiXccxTools") )[0] solver_object.WorkingDir = u"" if solvertype == "calculix" or solvertype == "ccxtools": solver_object.SplitInputWriter = False solver_object.AnalysisType = "static" solver_object.GeometricalNonlinearity = "linear" solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = "default" solver_object.IterationsControlParameterTimeUse = False # material material_object_low = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterialLow") )[0] mat = material_object_low.Material mat["Name"] = "Aluminium-Generic" mat["YoungsModulus"] = "70000 MPa" mat["PoissonRatio"] = "0.35" mat["Density"] = "2700 kg/m^3" material_object_low.Material = mat material_object_low.References = [(boxlow, "Solid1")] analysis.addObject(material_object_low) material_object_upp = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterialUpp") )[0] mat = material_object_upp.Material mat["Name"] = "Steel-Generic" mat["YoungsModulus"] = "200000 MPa" mat["PoissonRatio"] = "0.30" mat["Density"] = "7980 kg/m^3" material_object_upp.Material = mat material_object_upp.References = [(boxupp, "Solid1")] # fixed_constraint fixed_constraint = analysis.addObject( ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed") )[0] # fixed_constraint.References = [(cf, "Face3")] fixed_constraint.References = [(boxlow, "Face5")] # pressure_constraint pressure_constraint = analysis.addObject( ObjectsFem.makeConstraintPressure(doc, "ConstraintPressure") )[0] # pressure_constraint.References = [(cf, "Face3")] pressure_constraint.References = [(boxlow, "Face5")] # pressure_constraint.References = [(cf, "Face9")] pressure_constraint.References = [(boxupp, "Face6")] pressure_constraint.Pressure = 1000.0 pressure_constraint.Reversed = False # mesh from .meshes.mesh_boxes_2_vertikal_tetra10 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") femmesh_obj = analysis.addObject( doc.addObject("Fem::FemMeshObject", mesh_name) )[0] femmesh_obj.FemMesh = fem_mesh doc.recompute() return doc
def test_static_freq_analysis(self): # static fcc_print('--------------- Start of FEM tests ---------------') box = self.active_doc.addObject("Part::Box", "Box") fcc_print('Checking FEM new analysis...') analysis = ObjectsFem.makeAnalysis('Analysis') self.assertTrue(analysis, "FemTest of new analysis failed") fcc_print('Checking FEM new solver...') solver_object = ObjectsFem.makeSolverCalculix('CalculiX') solver_object.GeometricalNonlinearity = 'linear' solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = 'default' solver_object.IterationsControlParameterTimeUse = False solver_object.EigenmodesCount = 10 solver_object.EigenmodeHighLimit = 1000000.0 solver_object.EigenmodeLowLimit = 0.0 self.assertTrue(solver_object, "FemTest of new solver failed") analysis.Member = analysis.Member + [solver_object] fcc_print('Checking FEM new material...') new_material_object = ObjectsFem.makeMaterialSolid('MechanicalMaterial') mat = new_material_object.Material mat['Name'] = "Steel-Generic" mat['YoungsModulus'] = "200000 MPa" mat['PoissonRatio'] = "0.30" mat['Density'] = "7900 kg/m^3" new_material_object.Material = mat self.assertTrue(new_material_object, "FemTest of new material failed") analysis.Member = analysis.Member + [new_material_object] fcc_print('Checking FEM new fixed constraint...') fixed_constraint = self.active_doc.addObject("Fem::ConstraintFixed", "FemConstraintFixed") fixed_constraint.References = [(box, "Face1")] self.assertTrue(fixed_constraint, "FemTest of new fixed constraint failed") analysis.Member = analysis.Member + [fixed_constraint] fcc_print('Checking FEM new force constraint...') force_constraint = self.active_doc.addObject("Fem::ConstraintForce", "FemConstraintForce") force_constraint.References = [(box, "Face6")] force_constraint.Force = 40000.0 force_constraint.Direction = (box, ["Edge5"]) self.active_doc.recompute() force_constraint.Reversed = True self.active_doc.recompute() self.assertTrue(force_constraint, "FemTest of new force constraint failed") analysis.Member = analysis.Member + [force_constraint] fcc_print('Checking FEM new pressure constraint...') pressure_constraint = self.active_doc.addObject("Fem::ConstraintPressure", "FemConstraintPressure") pressure_constraint.References = [(box, "Face2")] pressure_constraint.Pressure = 1000.0 pressure_constraint.Reversed = False self.assertTrue(pressure_constraint, "FemTest of new pressure constraint failed") analysis.Member = analysis.Member + [pressure_constraint] fcc_print('Checking FEM new mesh...') mesh = import_csv_mesh(mesh_points_file, mesh_volumes_file) mesh_object = self.active_doc.addObject('Fem::FemMeshObject', mesh_name) mesh_object.FemMesh = mesh self.assertTrue(mesh, "FemTest of new mesh failed") analysis.Member = analysis.Member + [mesh_object] self.active_doc.recompute() fea = FemToolsCcx.FemToolsCcx(analysis, solver_object, test_mode=True) fcc_print('Setting up working directory {}'.format(static_analysis_dir)) fea.setup_working_dir(static_analysis_dir) self.assertTrue(True if fea.working_dir == static_analysis_dir else False, "Setting working directory {} failed".format(static_analysis_dir)) fcc_print('Checking FEM inp file prerequisites for static analysis...') error = fea.check_prerequisites() self.assertFalse(error, "FemToolsCcx check_prerequisites returned error message: {}".format(error)) fcc_print('Checking FEM inp file write...') fcc_print('Setting analysis type to \'static\"') fea.set_analysis_type("static") self.assertTrue(True if fea.analysis_type == 'static' else False, "Setting anlysis type to \'static\' failed") fcc_print('Writing {}/{}.inp for static analysis'.format(static_analysis_dir, mesh_name)) error = fea.write_inp_file() self.assertFalse(error, "Writing failed") fcc_print('Comparing {} to {}/{}.inp'.format(static_analysis_inp_file, static_analysis_dir, mesh_name)) ret = compare_inp_files(static_analysis_inp_file, static_analysis_dir + "/" + mesh_name + '.inp') self.assertFalse(ret, "FemToolsCcx write_inp_file test failed.\n{}".format(ret)) fcc_print('Setting up working directory to {} in order to read simulated calculations'.format(test_file_dir)) fea.setup_working_dir(test_file_dir) self.assertTrue(True if fea.working_dir == test_file_dir else False, "Setting working directory {} failed".format(test_file_dir)) fcc_print('Setting base name to read test {}.frd file...'.format('cube_static')) fea.set_base_name(static_base_name) self.assertTrue(True if fea.base_name == static_base_name else False, "Setting base name to {} failed".format(static_base_name)) fcc_print('Setting inp file name to read test {}.frd file...'.format('cube_static')) fea.set_inp_file_name() self.assertTrue(True if fea.inp_file_name == static_analysis_inp_file else False, "Setting inp file name to {} failed".format(static_analysis_inp_file)) fcc_print('Checking FEM frd file read from static analysis...') fea.load_results() self.assertTrue(fea.results_present, "Cannot read results from {}.frd frd file".format(fea.base_name)) fcc_print('Reading stats from result object for static analysis...') ret = compare_stats(fea, static_expected_values) self.assertFalse(ret, "Invalid results read from .frd file") fcc_print('Save FreeCAD file for static analysis to {}...'.format(static_save_fc_file)) self.active_doc.saveAs(static_save_fc_file) # frequency fcc_print('Setting analysis type to \'frequency\"') fea.set_analysis_type("frequency") self.assertTrue(True if fea.analysis_type == 'frequency' else False, "Setting anlysis type to \'frequency\' failed") fcc_print('Setting up working directory to {} in order to write frequency calculations'.format(frequency_analysis_dir)) fea.setup_working_dir(frequency_analysis_dir) self.assertTrue(True if fea.working_dir == frequency_analysis_dir else False, "Setting working directory {} failed".format(frequency_analysis_dir)) fcc_print('Checking FEM inp file prerequisites for frequency analysis...') error = fea.check_prerequisites() self.assertFalse(error, "FemToolsCcx check_prerequisites returned error message: {}".format(error)) fcc_print('Writing {}/{}.inp for frequency analysis'.format(frequency_analysis_dir, mesh_name)) error = fea.write_inp_file() self.assertFalse(error, "Writing failed") fcc_print('Comparing {} to {}/{}.inp'.format(frequency_analysis_inp_file, frequency_analysis_dir, mesh_name)) ret = compare_inp_files(frequency_analysis_inp_file, frequency_analysis_dir + "/" + mesh_name + '.inp') self.assertFalse(ret, "FemToolsCcx write_inp_file test failed.\n{}".format(ret)) fcc_print('Setting up working directory to {} in order to read simulated calculations'.format(test_file_dir)) fea.setup_working_dir(test_file_dir) self.assertTrue(True if fea.working_dir == test_file_dir else False, "Setting working directory {} failed".format(test_file_dir)) fcc_print('Setting base name to read test {}.frd file...'.format(frequency_base_name)) fea.set_base_name(frequency_base_name) self.assertTrue(True if fea.base_name == frequency_base_name else False, "Setting base name to {} failed".format(frequency_base_name)) fcc_print('Setting inp file name to read test {}.frd file...'.format('cube_frequency')) fea.set_inp_file_name() self.assertTrue(True if fea.inp_file_name == frequency_analysis_inp_file else False, "Setting inp file name to {} failed".format(frequency_analysis_inp_file)) fcc_print('Checking FEM frd file read from frequency analysis...') fea.load_results() self.assertTrue(fea.results_present, "Cannot read results from {}.frd frd file".format(fea.base_name)) fcc_print('Reading stats from result object for frequency analysis...') ret = compare_stats(fea, frequency_expected_values) self.assertFalse(ret, "Invalid results read from .frd file") fcc_print('Save FreeCAD file for frequency analysis to {}...'.format(frequency_save_fc_file)) self.active_doc.saveAs(frequency_save_fc_file) fcc_print('--------------- End of FEM tests static and frequency analysis ---------------')