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: 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 import_z88_disp( filename, analysis=None, result_name_prefix=None ): '''insert a FreeCAD FEM mechanical result object in the ActiveDocument pure usage: import feminout.importZ88O2Results as importZ88O2Results disp_file = '/pathtofile/z88o2.txt' importZ88O2Results.import_z88_disp(disp_file) the z888i1.txt FEMMesh file needs to be in the same directory as z88o2.txt # ahh, make a new document first ;-) ''' from . import importZ88Mesh from . import importToolsFem import ObjectsFem if result_name_prefix is None: result_name_prefix = '' disp_read = read_z88_disp(filename) result_mesh_object = None if len(disp_read['Nodes']) > 0: if analysis: analysis_object = analysis # read result mesh if filename.endswith('z88o2.txt'): mesh_file = filename.replace('o2', 'i1') mesh_data = importZ88Mesh.read_z88_mesh(mesh_file) femmesh = importToolsFem.make_femmesh(mesh_data) result_mesh_object = ObjectsFem.makeMeshResult( FreeCAD.ActiveDocument, 'Result_mesh' ) result_mesh_object.FemMesh = femmesh else: FreeCAD.Console.PrintError('Z88 mesh file z88i1.txt not found!') # create result obj for result_set in disp_read['Results']: results_name = result_name_prefix + 'results' res_obj = ObjectsFem.makeResultMechanical(FreeCAD.ActiveDocument, results_name) res_obj.Mesh = result_mesh_object res_obj = importToolsFem.fill_femresult_mechanical(res_obj, result_set) if analysis: analysis_object.addObject(res_obj) if FreeCAD.GuiUp: if analysis: import FemGui FemGui.setActiveAnalysis(analysis_object) FreeCAD.ActiveDocument.recompute() else: FreeCAD.Console.PrintError( 'Problem on Z88 result file import. No nodes found in Z88 result file.\n' ) return res_obj
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 importFrd(filename, analysis=None, result_name_prefix=None): from . import importToolsFem import ObjectsFem if result_name_prefix is None: result_name_prefix = '' m = readResult(filename) result_mesh_object = None if len(m['Nodes']) > 0: if analysis: analysis_object = analysis mesh = importToolsFem.make_femmesh(m) result_mesh_object = ObjectsFem.makeMeshResult(FreeCAD.ActiveDocument, 'Result_mesh') result_mesh_object.FemMesh = mesh 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) number_of_increments = len(m['Results']) for result_set in m['Results']: if 'number' in result_set: eigenmode_number = result_set['number'] else: eigenmode_number = 0 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(FreeCAD.ActiveDocument, results_name) results.Mesh = result_mesh_object results = importToolsFem.fill_femresult_mechanical(results, result_set, span) if analysis: analysis_object.addObject(results) if FreeCAD.GuiUp: if analysis: import FemGui FemGui.setActiveAnalysis(analysis_object) FreeCAD.ActiveDocument.recompute() else: FreeCAD.Console.PrintError('Problem on frd file import. No nodes found in frd file.\n')
def importVtkFCResult(filename, resultname, analysis=None, result_name_prefix=None): # only fields from vtk are imported if they exactly named as the FreeCAD result properties # See _getFreeCADMechResultProperties() in FemVTKTools.cpp for the supported names import ObjectsFem from . import importToolsFem if result_name_prefix is None: result_name_prefix = '' if analysis: analysis_object = analysis results_name = result_name_prefix + 'results' result_obj = ObjectsFem.makeResultMechanical(FreeCAD.ActiveDocument, 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 = importToolsFem.calculate_disp_abs(result_obj.DisplacementVectors) FreeCAD.Console.PrintMessage('Recalculated DisplacementLengths.\n') ''' seems unused at the moment filenamebase = '.'.join(filename.split('.')[:-1]) # pattern: filebase_timestamp.vtk ts = filenamebase.split('_')[-1] try: time_step = float(ts) except: time_step = 0.0 ''' if analysis: analysis_object.addObject(result_obj) result_obj.touch() FreeCAD.ActiveDocument.recompute()
def setup_cantilevernodeload(doc=None, solver='ccxtools'): # setup CalculiX cantilever, apply 9 MN on the 4 nodes of the front end face doc = setup_cantileverbase(doc, solver) # force_constraint force_constraint = doc.Analysis.addObject(ObjectsFem.makeConstraintForce(doc, name="ConstraintForce"))[0] force_constraint.References = [(doc.Box, "Vertex5"), (doc.Box, "Vertex6"), (doc.Box, "Vertex7"), (doc.Box, "Vertex8")] # should be possible in one tuple too force_constraint.Force = 9000000.0 force_constraint.Direction = (doc.Box, ["Edge5"]) force_constraint.Reversed = True doc.recompute() return doc
def setup_cantileverfaceload(doc=None, solver='ccxtools'): # setup CalculiX cantilever, apply 9 MN on surface of front end face doc = setup_cantileverbase(doc, solver) # force_constraint force_constraint = doc.Analysis.addObject(ObjectsFem.makeConstraintForce(doc, name="ConstraintForce"))[0] force_constraint.References = [(doc.Box, "Face2")] force_constraint.Force = 9000000.0 force_constraint.Direction = (doc.Box, ["Edge5"]) force_constraint.Reversed = True doc.recompute() return doc
def setup_cantileverprescribeddisplacement(doc=None, solver='ccxtools'): # setup CalculiX cantilever, apply a prescribed displacement of 250 mm in -z on the front end face doc = setup_cantileverbase(doc, solver) # displacement_constraint displacement_constraint = doc.Analysis.addObject(ObjectsFem.makeConstraintDisplacement(doc, name="ConstraintDisplacmentPrescribed"))[0] displacement_constraint.References = [(doc.Box, "Face2")] displacement_constraint.zFix = False displacement_constraint.zFree = False displacement_constraint.zDisplacement = -250.0 doc.recompute() return doc
def test_adding_refshaps(self): doc = self.active_doc slab = doc.addObject("Part::Plane", "Face") slab.Length = 500.00 slab.Width = 500.00 cf = ObjectsFem.makeConstraintFixed(doc) ref_eles = [] # FreeCAD list property seam not to support append, thus we need some workaround, which is on many elements even much faster for i, face in enumerate(slab.Shape.Edges): ref_eles.append("Edge%d" % (i + 1)) cf.References = [(slab, ref_eles)] doc.recompute() expected_reflist = [(slab, ('Edge1', 'Edge2', 'Edge3', 'Edge4'))] assert_err_message = 'Adding reference shapes did not result in expected list ' + str(cf.References) + ' != ' + str(expected_reflist) self.assertEqual(cf.References, expected_reflist, assert_err_message)
def importVTK(filename, analysis=None, result_name_prefix=None): import ObjectsFem if result_name_prefix is None: result_name_prefix = '' if analysis: 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) 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) if analysis: analysis_object.Member = analysis_object.Member + [result_obj] ''' seams not used at the moment
def importVtkFCResult( filename, resultname, analysis=None, result_name_prefix=None ): # only fields from vtk are imported if they exactly named as the FreeCAD result properties # See _getFreeCADMechResultProperties() in FemVTKTools.cpp for the supported names import ObjectsFem if result_name_prefix is None: result_name_prefix = '' if analysis: analysis_object = analysis results_name = result_name_prefix + 'results' result_obj = ObjectsFem.makeResultMechanical(FreeCAD.ActiveDocument, results_name) # readResult always creates a new femmesh named ResultMesh Fem.readResult(filename, result_obj.Name) # add missing DisplacementLengths (They should have been added by Fem.readResult) if not result_obj.DisplacementLengths: import femresult.resulttools as restools result_obj = restools.add_disp_apps(result_obj) # DisplacementLengths ''' seems unused at the moment filenamebase = '.'.join(filename.split('.')[:-1]) # pattern: filebase_timestamp.vtk ts = filenamebase.split('_')[-1] try: time_step = float(ts) except: time_step = 0.0 ''' if analysis: analysis_object.addObject(result_obj) result_obj.touch() FreeCAD.ActiveDocument.recompute() return result_obj
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] 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 create_analysis(self): self.analysis = ObjectsFem.makeAnalysis(self.doc, "Analysis")
def pasteResults(doc, elnodes, nocoord, interface_elements, dis, tet10stress, contactpressurevector, contactpressurevalue, contactshearvector): analysis = doc.getObject("Analysis") if analysis == None: print("No Analysis object. Please create one first") raise SystemExit() resVol = analysis.addObject(ObjectsFem.makeResultMechanical(doc))[0] resInt = analysis.addObject(ObjectsFem.makeResultMechanical(doc))[0] # VOLUME MESH START volnodes = {} mode_disp_vol = {} elements_tetra10 = {} mode_results_vol = {} results = [] for index, coord in enumerate(nocoord): n3 = 3 * index volnodes[index + 1] = App.Vector(coord[0], coord[1], coord[2]) mode_disp_vol[index + 1] = App.Vector(dis[n3], dis[n3 + 1], dis[n3 + 2]) for index, elem in enumerate(elnodes): elements_tetra10[index + 1] = (elem[0], elem[2], elem[1], elem[3], elem[6], elem[5], elem[4], elem[7], elem[9], elem[8]) mode_results_vol['disp'] = mode_disp_vol results.append(mode_results_vol) mvol = { 'Nodes': volnodes, 'Seg2Elem': {}, 'Seg3Elem': {}, 'Tria3Elem': {}, 'Tria6Elem': {}, 'Quad4Elem': {}, 'Quad8Elem': {}, 'Tetra4Elem': {}, 'Tetra10Elem': elements_tetra10, 'Hexa8Elem': {}, 'Hexa20Elem': {}, 'Penta6Elem': {}, 'Penta15Elem': {}, 'Results': results } meshvol = itf.make_femmesh(mvol) result_mesh_object_1 = ObjectsFem.makeMeshResult(doc, 'Result_Mesh_Volume') result_mesh_object_1.FemMesh = meshvol numnodes = len(nocoord) resVol.DisplacementVectors = [ App.Vector(dis[3 * n], dis[3 * n + 1], dis[3 * n + 2]) for n in range(numnodes) ] resVol.DisplacementLengths = [ np.linalg.norm([dis[3 * n], dis[3 * n + 1], dis[3 * n + 2]]) for n in range(numnodes) ] resVol.NodeStressXX = tet10stress.T[0].T.tolist() resVol.NodeStressYY = tet10stress.T[1].T.tolist() resVol.NodeStressZZ = tet10stress.T[2].T.tolist() resVol.NodeStressXY = tet10stress.T[3].T.tolist() resVol.NodeStressXZ = tet10stress.T[4].T.tolist() resVol.NodeStressYZ = tet10stress.T[5].T.tolist() resVol.Mesh = result_mesh_object_1 resVol.NodeNumbers = [int(key) for key in resVol.Mesh.FemMesh.Nodes.keys()] resVol = itf.fill_femresult_mechanical(resVol, results) # VOLUME MESH FINISH # INTERFACE MESH START if interface_elements != []: intnodes = {} mode_disp_int = {} intconnect = {} newnode = {} oldnode = {} elements_tria6 = {} mode_results_int = {} results = [] index = 0 for i, intel in enumerate(interface_elements): for nd in intel[:6]: if nd not in intconnect: index += 1 intconnect[nd] = index intnodes[index] = App.Vector(nocoord[nd - 1][0], nocoord[nd - 1][1], nocoord[nd - 1][2]) mode_disp_int[index] = App.Vector( contactpressurevector[nd - 1][0], contactpressurevector[nd - 1][1], contactpressurevector[nd - 1][2]) newnode[nd] = index oldnode[index] = nd elements_tria6[i + 1] = (newnode[intel[0]], newnode[intel[1]], newnode[intel[2]], newnode[intel[3]], newnode[intel[4]], newnode[intel[5]]) mode_results_int['disp'] = mode_disp_int results.append(mode_results_int) mint = { 'Nodes': intnodes, 'Seg2Elem': {}, 'Seg3Elem': {}, 'Tria3Elem': {}, 'Tria6Elem': elements_tria6, 'Quad4Elem': {}, 'Quad8Elem': {}, 'Tetra4Elem': {}, 'Tetra10Elem': {}, 'Hexa8Elem': {}, 'Hexa20Elem': {}, 'Penta6Elem': {}, 'Penta15Elem': {}, 'Results': results } meshint = itf.make_femmesh(mint) result_mesh_object_2 = ObjectsFem.makeMeshResult( doc, 'Result_Mesh_Interface') result_mesh_object_2.FemMesh = meshint resInt.DisplacementVectors = [ App.Vector(dis[3 * (oldnode[n + 1] - 1)], dis[3 * (oldnode[n + 1] - 1) + 1], dis[3 * (oldnode[n + 1] - 1) + 2]) for n in range(len(oldnode)) ] resInt.DisplacementLengths = [ contactpressurevalue[nd - 1] for nd in oldnode.values() ] # TODO: This is a dirty hack. move contact pressure to its own result object attribute resInt.Mesh = result_mesh_object_2 resInt.NodeNumbers = [ int(key) for key in resInt.Mesh.FemMesh.Nodes.keys() ] resInt = itf.fill_femresult_mechanical(resInt, results) # INTERFACE MESH FINISH doc.recompute() return resInt, resVol
def setup(doc=None, solvertype="ccxtools"): # setup model if doc is None: doc = init_doc() # parts # bottom box bottom_box_obj = doc.addObject("Part::Box", "BottomBox") bottom_box_obj.Length = 100 bottom_box_obj.Width = 25 bottom_box_obj.Height = 500 bottom_box_obj.Placement = FreeCAD.Placement( Vector(186, 0, -247), Rotation(0, 0, 0), Vector(0, 0, 0), ) doc.recompute() # top half cylinder, https://forum.freecadweb.org/viewtopic.php?f=18&t=43001#p366111 top_halfcyl_obj = doc.addObject("Part::Cylinder", "TopHalfCylinder") top_halfcyl_obj.Radius = 30 top_halfcyl_obj.Height = 500 top_halfcyl_obj.Angle = 180 top_halfcyl_sh = Part.getShape(top_halfcyl_obj, '', needSubElement=False, refine=True) top_halfcyl_obj.Shape = top_halfcyl_sh top_halfcyl_obj.Placement = FreeCAD.Placement( Vector(0, -42, 0), Rotation(0, 90, 0), Vector(0, 0, 0), ) doc.recompute() # all geom fusion all_geom_fusion_obj = doc.addObject("Part::MultiFuse", "AllGeomFusion") all_geom_fusion_obj.Shapes = [bottom_box_obj, top_halfcyl_obj] if FreeCAD.GuiUp: bottom_box_obj.ViewObject.hide() top_halfcyl_obj.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.AnalysisType = "static" solver_object.GeometricalNonlinearity = "linear" solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = "default" solver_object.IterationsControlParameterTimeUse = False solver_object.SplitInputWriter = False """ # solver parameter from fandaL, but they are not needed (see forum topic) solver_object.IterationsControlParameterTimeUse = True solver_object.IterationsControlParameterCutb = '0.25,0.5,0.75,0.85,,,1.5,' solver_object.IterationsControlParameterIter = '4,8,9,200,10,400,,200,,' solver_object.IterationsUserDefinedTimeStepLength = True solver_object.TimeInitialStep = 0.1 solver_object.TimeEnd = 1.0 solver_object.IterationsUserDefinedIncrementations = True # parameter DIRECT """ # material material_obj = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterial"))[0] mat = material_obj.Material mat["Name"] = "Steel-Generic" mat["YoungsModulus"] = "200000 MPa" mat["PoissonRatio"] = "0.30" material_obj.Material = mat analysis.addObject(material_obj) # constraint fixed con_fixed = analysis.addObject( ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed"))[0] con_fixed.References = [ (all_geom_fusion_obj, "Face5"), (all_geom_fusion_obj, "Face6"), (all_geom_fusion_obj, "Face8"), (all_geom_fusion_obj, "Face9"), ] # constraint pressure con_pressure = analysis.addObject( ObjectsFem.makeConstraintPressure(doc, name="ConstraintPressure"))[0] con_pressure.References = [(all_geom_fusion_obj, "Face10")] con_pressure.Pressure = 100.0 # Pa ? = 100 Mpa ? con_pressure.Reversed = False # constraint contact con_contact = doc.Analysis.addObject( ObjectsFem.makeConstraintContact(doc, name="ConstraintContact"))[0] con_contact.References = [ (all_geom_fusion_obj, "Face7"), # first seams slave face, TODO proof in writer code! (all_geom_fusion_obj, "Face3"), # second seams master face, TODO proof in writer code! ] con_contact.Friction = 0.0 con_contact.Slope = 1000000.0 # contact stiffness 1000000.0 kg/(mm*s^2) # mesh from .meshes.mesh_contact_box_halfcylinder_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 importFrd( filename, analysis=None, result_name_prefix=None ): from . import importToolsFem import ObjectsFem if result_name_prefix is None: result_name_prefix = '' m = read_frd_result(filename) result_mesh_object = None if len(m['Nodes']) > 0: if analysis: analysis_object = analysis mesh = importToolsFem.make_femmesh(m) result_mesh_object = ObjectsFem.makeMeshResult( FreeCAD.ActiveDocument, 'Result_mesh' ) result_mesh_object.FemMesh = mesh number_of_increments = len(m['Results']) FreeCAD.Console.PrintLog( 'Increments: ' + str(number_of_increments) + '\n' ) if len(m['Results']) > 0: for result_set in m['Results']: if 'number' in result_set: eigenmode_number = result_set['number'] else: eigenmode_number = 0 step_time = result_set['time'] step_time = round(step_time, 2) if eigenmode_number > 0: results_name = ( '{}mode_{}_results' .format(result_name_prefix, eigenmode_number) ) elif number_of_increments > 1: results_name = ( '{}time_{}_results' .format(result_name_prefix, step_time) ) else: results_name = ( '{}results' .format(result_name_prefix) ) res_obj = ObjectsFem.makeResultMechanical(FreeCAD.ActiveDocument, results_name) res_obj.Mesh = result_mesh_object res_obj = importToolsFem.fill_femresult_mechanical(res_obj, result_set) if analysis: analysis_object.addObject(res_obj) # complementary result object calculations import femresult.resulttools as restools if not res_obj.MassFlowRate: # only compact result if not Flow 1D results # compact result object, workaround for bug 2873 # https://www.freecadweb.org/tracker/view.php?id=2873 res_obj = restools.compact_result(res_obj) # fill DisplacementLengths res_obj = restools.add_disp_apps(res_obj) # fill StressValues res_obj = restools.add_von_mises(res_obj) # fill PrincipalMax, PrincipalMed, PrincipalMin, MaxShear res_obj = restools.add_principal_stress(res_obj) # fill Stats res_obj = restools.fill_femresult_stats(res_obj) else: error_message = ( "We have nodes but no results in frd file, " "which means we only have a mesh in frd file. " "Usually this happens for analysis type 'NOANALYSIS' " "or if CalculiX returned no results because " "of nonpositive jacobian determinant in at least one element.\n" ) FreeCAD.Console.PrintMessage(error_message) if analysis: analysis_object.addObject(result_mesh_object) if FreeCAD.GuiUp: if analysis: import FemGui FemGui.setActiveAnalysis(analysis_object) FreeCAD.ActiveDocument.recompute() else: FreeCAD.Console.PrintError( 'Problem on frd file import. No nodes found in frd file.\n' ) return res_obj
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_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 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_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_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_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_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 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_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 setup(doc=None, solvertype="ccxtools"): # setup model if doc is None: doc = init_doc() # geometry object geom_obj = doc.addObject("Part::Box", "Box") geom_obj.Height = 25.4 geom_obj.Width = 25.4 geom_obj.Length = 203.2 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"" # should be possible with elmer too # elif solvertype == "elmer": # analysis.addObject(ObjectsFem.makeSolverElmer(doc, "SolverElmer")) if solvertype == "calculix" or solvertype == "ccxtools": solver_object.SplitInputWriter = False solver_object.AnalysisType = "thermomech" solver_object.GeometricalNonlinearity = "linear" solver_object.ThermoMechSteadyState = True solver_object.MatrixSolverType = "default" solver_object.IterationsThermoMechMaximum = 2000 solver_object.IterationsControlParameterTimeUse = True # 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" 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 # fixed_constraint fixed_constraint = analysis.addObject( ObjectsFem.makeConstraintFixed(doc, "FemConstraintFixed") )[0] fixed_constraint.References = [(geom_obj, "Face1")] # initialtemperature_constraint initialtemperature_constraint = analysis.addObject( ObjectsFem.makeConstraintInitialTemperature(doc, "FemConstraintInitialTemperature") )[0] initialtemperature_constraint.initialTemperature = 300.0 # temperature_constraint temperature_constraint = analysis.addObject( ObjectsFem.makeConstraintTemperature(doc, "FemConstraintTemperature") )[0] temperature_constraint.References = [(geom_obj, "Face1")] temperature_constraint.Temperature = 310.93 # heatflux_constraint heatflux_constraint = analysis.addObject( ObjectsFem.makeConstraintHeatflux(doc, "FemConstraintHeatflux") )[0] heatflux_constraint.References = [ (geom_obj, "Face3"), (geom_obj, "Face4"), (geom_obj, "Face5"), (geom_obj, "Face6") ] heatflux_constraint.AmbientTemp = 255.3722 heatflux_constraint.FilmCoef = 5.678 # mesh from .meshes.mesh_thermomech_spine_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 importFrd(filename, analysis=None, result_name_prefix=None): from . import importToolsFem import ObjectsFem if result_name_prefix is None: result_name_prefix = '' m = readResult(filename) result_mesh_object = None if len(m['Nodes']) > 0: if analysis: analysis_object = analysis mesh = importToolsFem.make_femmesh(m) result_mesh_object = ObjectsFem.makeMeshResult(FreeCAD.ActiveDocument, 'Result_mesh') result_mesh_object.FemMesh = mesh 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) number_of_increments = len(m['Results']) if len(m['Results']) > 0: for result_set in m['Results']: if 'number' in result_set: eigenmode_number = result_set['number'] else: eigenmode_number = 0 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(FreeCAD.ActiveDocument, results_name) results.Mesh = result_mesh_object results = importToolsFem.fill_femresult_mechanical(results, result_set, span) if analysis: analysis_object.addObject(results) else: error_message = ( "We have nodes but no results in frd file, which means we only have a mesh in frd file. " "Usually this happens for analysis type 'NOANALYSIS' or if CalculiX returned no results because " "of nonpositive jacobian determinant in at least one element.\n" ) FreeCAD.Console.PrintMessage(error_message) if analysis: analysis_object.addObject(result_mesh_object) if FreeCAD.GuiUp: if analysis: import FemGui FemGui.setActiveAnalysis(analysis_object) FreeCAD.ActiveDocument.recompute() else: FreeCAD.Console.PrintError('Problem on frd file import. No nodes found in frd file.\n')
def setup(doc=None, solvertype="ccxtools"): # setup model if doc is None: doc = init_doc() # geom objects # bottom box bottom_box_obj = doc.addObject("Part::Box", "BottomBox") bottom_box_obj.Length = 100 bottom_box_obj.Width = 5 bottom_box_obj.Height = 1 # top box top_box_obj = doc.addObject("Part::Box", "TopBox") top_box_obj.Length = 100 top_box_obj.Width = 5 top_box_obj.Height = 1 top_box_obj.Placement = FreeCAD.Placement( Vector(0, 0, 1), Rotation(0, 0, 0), Vector(0, 0, 0), ) doc.recompute() # all geom boolean fragment geom_obj = SplitFeatures.makeBooleanFragments(name='BooleanFragments') geom_obj.Objects = [bottom_box_obj, top_box_obj] if FreeCAD.GuiUp: bottom_box_obj.ViewObject.hide() top_box_obj.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"" elif solvertype == "elmer": solver_object = analysis.addObject( ObjectsFem.makeSolverElmer(doc, "SolverElmer"))[0] solver_object.SteadyStateMinIterations = 1 solver_object.SteadyStateMaxIterations = 10 eq_heat = ObjectsFem.makeEquationHeat(doc, solver_object) eq_heat.Bubbles = True eq_heat.Priority = 2 eq_elasticity = ObjectsFem.makeEquationElasticity(doc, solver_object) eq_elasticity.Bubbles = True eq_elasticity.Priority = 1 eq_elasticity.LinearSolverType = "Direct" 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.AnalysisType = "thermomech" solver_object.GeometricalNonlinearity = "linear" solver_object.ThermoMechSteadyState = True # solver_object.MatrixSolverType = "default" solver_object.MatrixSolverType = "spooles" # thomas solver_object.SplitInputWriter = False solver_object.IterationsThermoMechMaximum = 2000 # solver_object.IterationsControlParameterTimeUse = True # thermomech spine # material material_obj_bottom = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, "MaterialCopper"))[0] mat = material_obj_bottom.Material mat["Name"] = "Copper" mat["YoungsModulus"] = "130000 MPa" mat["PoissonRatio"] = "0.354" mat["SpecificHeat"] = "385 J/kg/K" mat["ThermalConductivity"] = "200 W/m/K" mat["ThermalExpansionCoefficient"] = "0.00002 m/m/K" mat["Density"] = "1.00 kg/m^3" material_obj_bottom.Material = mat material_obj_bottom.References = [(geom_obj, "Solid1")] analysis.addObject(material_obj_bottom) material_obj_top = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, "MaterialInvar"))[0] mat = material_obj_top.Material mat["Name"] = "Invar" mat["YoungsModulus"] = "137000 MPa" mat["PoissonRatio"] = "0.28" mat["SpecificHeat"] = "510 J/kg/K" mat["ThermalConductivity"] = "13 W/m/K" mat["ThermalExpansionCoefficient"] = "0.0000012 m/m/K" mat["Density"] = "1.00 kg/m^3" material_obj_top.Material = mat material_obj_top.References = [(geom_obj, "Solid2")] analysis.addObject(material_obj_top) # constraint fixed con_fixed = analysis.addObject( ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed"))[0] con_fixed.References = [ (geom_obj, "Face1"), (geom_obj, "Face7"), ] # constraint initial temperature constraint_initialtemp = analysis.addObject( ObjectsFem.makeConstraintInitialTemperature( doc, "ConstraintInitialTemperature"))[0] constraint_initialtemp.initialTemperature = 273.0 # constraint temperature constraint_temperature = analysis.addObject( ObjectsFem.makeConstraintTemperature(doc, "ConstraintTemperature"))[0] constraint_temperature.References = [ (geom_obj, "Face1"), (geom_obj, "Face2"), (geom_obj, "Face3"), (geom_obj, "Face4"), (geom_obj, "Face5"), (geom_obj, "Face7"), (geom_obj, "Face8"), (geom_obj, "Face9"), (geom_obj, "Face10"), (geom_obj, "Face11"), ] constraint_temperature.Temperature = 373.0 constraint_temperature.CFlux = 0.0 # mesh from .meshes.mesh_thermomech_bimetall_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_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="elmer"): # 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 objects small_sphere1 = doc.addObject("Part::Sphere", "Small_Sphere1") small_sphere1.Placement = FreeCAD.Placement(Vector(-1000, 0, 0), Rotation(Vector(0, 0, 1), 0)) small_sphere1.Radius = "500 mm" small_sphere2 = doc.addObject("Part::Sphere", "Small_Sphere2") small_sphere2.Placement = FreeCAD.Placement(Vector(1000, 0, 0), Rotation(Vector(0, 0, 1), 0)) small_sphere2.Radius = "500 mm" fusion = doc.addObject("Part::MultiFuse", "Fusion") fusion.Shapes = [small_sphere1, small_sphere2] large_sphere = doc.addObject("Part::Sphere", "Large_Sphere") large_sphere.Radius = "5000 mm" geom_obj = doc.addObject("Part::Cut", "Cut") geom_obj.Base = large_sphere geom_obj.Tool = fusion doc.recompute() if FreeCAD.GuiUp: geom_obj.ViewObject.Transparency = 75 geom_obj.ViewObject.Document.activeView().viewAxonometric() geom_obj.ViewObject.Document.activeView().fitAll() # analysis analysis = ObjectsFem.makeAnalysis(doc, "Analysis") # solver if solvertype == "elmer": solver_obj = ObjectsFem.makeSolverElmer(doc, "SolverElmer") eq_electrostatic = ObjectsFem.makeEquationElectrostatic( doc, solver_obj) eq_electrostatic.CalculateCapacitanceMatrix = True eq_electrostatic.CalculateElectricEnergy = True eq_electrostatic.CalculateElectricField = True else: FreeCAD.Console.PrintWarning( "Not known or not supported solver type: {}. " "No solver object was created.\n".format(solvertype)) analysis.addObject(solver_obj) # material material_obj = ObjectsFem.makeMaterialFluid(doc, "FemMaterial") mat = material_obj.Material mat["Name"] = "Air-Generic" mat["Density"] = "1.20 kg/m^3" mat["KinematicViscosity"] = "15.11 mm^2/s" mat["VolumetricThermalExpansionCoefficient"] = "0.00 mm/m/K" mat["ThermalConductivity"] = "0.03 W/m/K" mat["ThermalExpansionCoefficient"] = "0.0034/K" mat["SpecificHeat"] = "1.00 J/kg/K" mat["RelativePermittivity"] = "1.00" material_obj.Material = mat analysis.addObject(material_obj) # constraint potential 1st name_pot1 = "ElectrostaticPotential1" con_elect_pot1 = ObjectsFem.makeConstraintElectrostaticPotential( doc, name_pot1) con_elect_pot1.References = [(geom_obj, "Face1")] con_elect_pot1.ElectricInfinity = True analysis.addObject(con_elect_pot1) # constraint potential 2nd name_pot2 = "ElectrostaticPotential2" con_elect_pot2 = ObjectsFem.makeConstraintElectrostaticPotential( doc, name_pot2) con_elect_pot2.References = [(geom_obj, "Face2")] con_elect_pot2.CapacitanceBody = 1 con_elect_pot2.CapacitanceBodyEnabled = True analysis.addObject(con_elect_pot2) # constraint potential 3rd name_pot3 = "ElectrostaticPotential3" con_elect_pot3 = ObjectsFem.makeConstraintElectrostaticPotential( doc, name_pot3) con_elect_pot3.References = [(geom_obj, "Face3")] con_elect_pot3.CapacitanceBody = 2 con_elect_pot3.CapacitanceBodyEnabled = True analysis.addObject(con_elect_pot3) # mesh from .meshes.mesh_capacitance_two_balls_tetra10 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") femmesh_obj = analysis.addObject( ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0] femmesh_obj.FemMesh = fem_mesh femmesh_obj.Part = geom_obj femmesh_obj.SecondOrderLinear = False # mesh_region mesh_region = ObjectsFem.makeMeshRegion(doc, femmesh_obj, name="MeshRegion") mesh_region.CharacteristicLength = "300 mm" mesh_region.References = [(geom_obj, "Face2"), (geom_obj, "Face3")] 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::Box", "Beam") geom_obj.Length = 1 geom_obj.Width = 1.5 geom_obj.Height = 8 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 analysis.addObject(solver_obj) # material material_obj = ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterial") mat = material_obj.Material mat["Name"] = "CalculiX-Steel" mat["YoungsModulus"] = "210000 MPa" mat["PoissonRatio"] = "0.30" material_obj.Material = mat analysis.addObject(material_obj) # constraint fixed con_fixed = ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed") con_fixed.References = [(geom_obj, "Face5")] analysis.addObject(con_fixed) # constraint force con_force = ObjectsFem.makeConstraintForce(doc, "ConstraintForce") con_force.References = [(geom_obj, "Face6")] con_force.Force = 21 con_force.Reversed = True analysis.addObject(con_force) # mesh from .meshes.mesh_flexural_buckling import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") femmesh_obj = analysis.addObject( ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0] femmesh_obj.FemMesh = fem_mesh femmesh_obj.Part = geom_obj doc.recompute() return doc
def setup(doc=None, solvertype="elmer"): # setup 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") # 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": solver_object = analysis.addObject( ObjectsFem.makeSolverElmer(doc, "SolverElmer"))[0] eq_obj = ObjectsFem.makeEquationElasticity(doc, solver_object) eq_obj.LinearSolverType = "Direct" # direct solver was used in the tutorial, thus used here too # the iterative is much faster and gives the same results eq_obj.DoFrequencyAnalysis = True eq_obj.CalculateStresses = True 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.AnalysisType = "frequency" solver_object.GeometricalNonlinearity = "linear" solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = "default" solver_object.IterationsControlParameterTimeUse = False solver_object.EigenmodesCount = 5 solver_object.EigenmodeHighLimit = 1000000.0 solver_object.EigenmodeLowLimit = 0.01 # 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 # fixed_constraint fixed_constraint = analysis.addObject( ObjectsFem.makeConstraintFixed(doc, name="FemConstraintFixed"))[0] fixed_constraint.References = [(geom_obj, "Face1"), (geom_obj, "Face2")] # 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(doc=None, solvertype="ccxtools"): # setup model if doc is None: doc = init_doc() # parts # cones cut cone_outer_sh = Part.makeCone(1100, 1235, 1005, Vector(0, 0, 0), Vector(0, 0, 1), 359) cone_inner_sh = Part.makeCone(1050, 1185, 1005, Vector(0, 0, 0), Vector(0, 0, 1), 359) cone_cut_sh = cone_outer_sh.cut(cone_inner_sh) cone_cut_obj = doc.addObject("Part::Feature", "Cone_Cut") cone_cut_obj.Shape = cone_cut_sh # lines line_fix_sh = Part.Edge(Part.LineSegment(Vector(0, -1235, 1005), Vector(0, -1185, 1005))) line_fix_obj = doc.addObject("Part::Feature", "Line_Fix") line_fix_obj.Shape = line_fix_sh line_force_sh = Part.Edge(Part.LineSegment(Vector(0, 1185, 1005), Vector(0, 1235, 1005))) line_force_obj = doc.addObject("Part::Feature", "Line_Force") line_force_obj.Shape = line_force_sh geom_all_obj = BOPTools.SplitFeatures.makeBooleanFragments(name='BooleanFragments') geom_all_obj.Objects = [cone_cut_obj, line_fix_obj, line_force_obj] if FreeCAD.GuiUp: cone_cut_obj.ViewObject.hide() line_fix_obj.ViewObject.hide() line_force_obj.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.AnalysisType = "static" solver_object.GeometricalNonlinearity = "linear" solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = "default" solver_object.IterationsControlParameterTimeUse = False solver_object.SplitInputWriter = False # material material_obj = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterial") )[0] mat = material_obj.Material mat["Name"] = "Calculix-Steel" mat["YoungsModulus"] = "210000 MPa" mat["PoissonRatio"] = "0.30" material_obj.Material = mat analysis.addObject(material_obj) # constraint fixed con_fixed = analysis.addObject( ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed") )[0] con_fixed.References = [(geom_all_obj, "Edge1")] # constraint force con_force = doc.Analysis.addObject( ObjectsFem.makeConstraintForce(doc, name="ConstraintForce") )[0] con_force.References = [(geom_all_obj, "Edge2")] con_force.Force = 10000.0 # 10000 N = 10 kN con_force.Direction = (geom_all_obj, ["Edge2"]) con_force.Reversed = False # constraint tie con_tie = doc.Analysis.addObject( ObjectsFem.makeConstraintTie(doc, name="ConstraintTie") )[0] con_tie.References = [ (geom_all_obj, "Face5"), (geom_all_obj, "Face7"), ] con_tie.Tolerance = 25.0 # mesh from .meshes.mesh_constraint_tie_tetra10 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") 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, solvertype="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 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"" 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.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 = [(doc.Box, "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 setup(doc=None, solvertype="ccxtools"): """ Nonlinear material example, plate with hole. https://forum.freecadweb.org/viewtopic.php?f=24&t=31997&start=30 https://forum.freecadweb.org/viewtopic.php?t=33974&start=90 https://forum.freecadweb.org/viewtopic.php?t=35893 plate: 400x200x10 mm hole: diameter 100 mm (half cross section) load: 130 MPa tension linear material: Steel, E = 210000 MPa, my = 0.3 nonlinear material: '240.0, 0.0' to '270.0, 0.025' TODO nonlinear material: give more information, use values from harry TODO compare results with example from HarryvL """ if doc is None: doc = init_doc() # part import Part from FreeCAD import Vector as vec from Part import makeLine as ln from Part import makeCircle as ci v1 = vec(-200, -100, 0) v2 = vec(200, -100, 0) v3 = vec(200, 100, 0) v4 = vec(-200, 100, 0) l1 = ln(v1, v2) l2 = ln(v2, v3) l3 = ln(v3, v4) l4 = ln(v4, v1) v5 = vec(0, 0, 0) c1 = ci(50, v5) face = Part.makeFace([Part.Wire([l1, l2, l3, l4]), c1], "Part::FaceMakerBullseye") partfem = doc.addObject("Part::Feature", "Hole_Plate") partfem.Shape = face.extrude(vec(0, 0, 10)) 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 solver.GeometricalNonlinearity = 'nonlinear' solver.MaterialNonlinearity = 'nonlinear' # linear material matprop = {} matprop["Name"] = "CalculiX-Steel" matprop["YoungsModulus"] = "210000 MPa" matprop["PoissonRatio"] = "0.30" matprop["Density"] = "7900 kg/m^3" material = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, "Material_lin"))[0] material.Material = matprop # nonlinear material nonlinear_material = analysis.addObject( ObjectsFem.makeMaterialMechanicalNonlinear(doc, material, "Material_nonlin"))[0] nonlinear_material.YieldPoint1 = '240.0, 0.0' nonlinear_material.YieldPoint2 = '270.0, 0.025' # check solver attributes, Nonlinearity needs to be set to nonlinear # fixed_constraint fixed_constraint = analysis.addObject( ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed"))[0] fixed_constraint.References = [(partfem, "Face4")] # force constraint pressure_constraint = doc.Analysis.addObject( ObjectsFem.makeConstraintPressure(doc, "ConstraintPressure"))[0] pressure_constraint.References = [(partfem, "Face2")] pressure_constraint.Pressure = 130.0 pressure_constraint.Reversed = True # mesh from .meshes.mesh_platewithhole_tetra10 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") femmesh_obj = analysis.addObject( doc.addObject("Fem::FemMeshObject", mesh_name))[0] femmesh_obj.FemMesh = fem_mesh doc.recompute() return doc
def setup_cantilever_base_edge(doc=None, solvertype="ccxtools"): # init FreeCAD document if doc is None: doc = init_doc() # geometric objects # load line load_line = doc.addObject("Part::Line", "LoadLine") load_line.X1 = 0 load_line.Y1 = 0 load_line.Z1 = 1000 load_line.X2 = 0 load_line.Y2 = 0 load_line.Z2 = 0 # cantilever line geom_obj = doc.addObject("Part::Line", "CantileverLine") geom_obj.X1 = 0 geom_obj.Y1 = 500 geom_obj.Z1 = 500 geom_obj.X2 = 8000 geom_obj.Y2 = 500 geom_obj.Z2 = 500 doc.recompute() if FreeCAD.GuiUp: load_line.ViewObject.Visibility = False 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"" elif solvertype == "mystran": solver_obj = ObjectsFem.makeSolverMystran(doc, "SolverMystran") 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.AnalysisType = "static" solver_obj.GeometricalNonlinearity = "linear" solver_obj.ThermoMechSteadyState = False solver_obj.MatrixSolverType = "default" solver_obj.IterationsControlParameterTimeUse = False solver_obj.SplitInputWriter = False analysis.addObject(solver_obj) # beam section beamsection_obj = ObjectsFem.makeElementGeometry1D( doc, sectiontype="Rectangular", width=1000.0, height=1000.0, name="BeamCrossSection") analysis.addObject(beamsection_obj) # material material_obj = ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterial") mat = material_obj.Material mat["Name"] = "Calculix-Steel" mat["YoungsModulus"] = "210000 MPa" mat["PoissonRatio"] = "0.30" material_obj.Material = mat analysis.addObject(material_obj) # constraint fixed con_fixed = ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed") con_fixed.References = [(geom_obj, "Vertex1")] analysis.addObject(con_fixed) # constraint force con_force = ObjectsFem.makeConstraintForce(doc, "ConstraintForce") con_force.References = [(geom_obj, "Vertex2")] con_force.Force = 9000000.0 # 9'000'000 N = 9 MN con_force.Direction = (load_line, ["Edge1"]) con_force.Reversed = False analysis.addObject(con_force) # mesh from .meshes.mesh_canticcx_seg3 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: 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.ElementDimension = "1D" femmesh_obj.CharacteristicLengthMax = "1750.0 mm" femmesh_obj.CharacteristicLengthMin = "1750.0 mm" doc.recompute() return doc
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": solver_object = analysis.addObject( ObjectsFem.makeSolverElmer(doc, "SolverElmer"))[0] ObjectsFem.makeEquationElasticity(doc, solver_object) elif solvertype == "z88": analysis.addObject(ObjectsFem.makeSolverZ88(doc, "SolverZ88")) 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 # 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" 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(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"): if doc is None: doc = init_doc() # geometry 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 points_forces = [] points_forces.append(Part.Vertex(-142.5, 142.5, 0.0)) points_forces.append(Part.Vertex(-142.5, -142.5, 0.0)) points_forces.append(Part.Vertex(-142.5, 95.0, 0.0)) points_forces.append(Part.Vertex(-142.5, 47.5, 0.0)) points_forces.append(Part.Vertex(-142.5, 0.0, 0.0)) points_forces.append(Part.Vertex(-142.5, -47.5, 0.0)) points_forces.append(Part.Vertex(-142.5, -95.0, 0.0)) points_forces.append(Part.Vertex(142.5, -142.5, 0.0)) points_forces.append(Part.Vertex(-95.0, -142.5, 0.0)) points_forces.append(Part.Vertex(-47.5, -142.5, 0.0)) points_forces.append(Part.Vertex(0.0, -142.5, 0.0)) points_forces.append(Part.Vertex(47.5, -142.5, 0.0)) points_forces.append(Part.Vertex(95.0, -142.5, 0.0)) points_forces.append(Part.Vertex(142.5, 142.5, 0.0)) points_forces.append(Part.Vertex(142.5, -95.0, 0.0)) points_forces.append(Part.Vertex(142.5, -47.5, 0.0)) points_forces.append(Part.Vertex(142.5, 0.0, 0.0)) points_forces.append(Part.Vertex(142.5, 47.5, 0.0)) points_forces.append(Part.Vertex(142.5, 95.0, 0.0)) points_forces.append(Part.Vertex(95.0, 142.5, 0.0)) points_forces.append(Part.Vertex(47.5, 142.5, 0.0)) points_forces.append(Part.Vertex(0.0, 142.5, 0.0)) points_forces.append(Part.Vertex(-47.5, 142.5, 0.0)) points_forces.append(Part.Vertex(-95.0, 142.5, 0.0)) points_forces.append(Part.Vertex(-142.5, 118.75, 0.0)) points_forces.append(Part.Vertex(-142.5, -118.75, 0.0)) points_forces.append(Part.Vertex(-142.5, 71.25, 0.0)) points_forces.append(Part.Vertex(-142.5, 23.75, 0.0)) points_forces.append(Part.Vertex(-142.5, -23.75, 0.0)) points_forces.append(Part.Vertex(-142.5, -71.25, 0.0)) points_forces.append(Part.Vertex(118.75, -142.5, 0.0)) points_forces.append(Part.Vertex(-71.25, -142.5, 0.0)) points_forces.append(Part.Vertex(-118.75, -142.5, 0.0)) points_forces.append(Part.Vertex(-23.75, -142.5, 0.0)) points_forces.append(Part.Vertex(23.75, -142.5, 0.0)) points_forces.append(Part.Vertex(71.25, -142.5, 0.0)) points_forces.append(Part.Vertex(142.5, 118.75, 0.0)) points_forces.append(Part.Vertex(142.5, -71.25, 0.0)) points_forces.append(Part.Vertex(142.5, -118.75, 0.0)) points_forces.append(Part.Vertex(142.5, -23.75, 0.0)) points_forces.append(Part.Vertex(142.5, 23.75, 0.0)) points_forces.append(Part.Vertex(142.5, 71.25, 0.0)) points_forces.append(Part.Vertex(71.25, 142.5, 0.0)) points_forces.append(Part.Vertex(118.75, 142.5, 0.0)) points_forces.append(Part.Vertex(23.75, 142.5, 0.0)) points_forces.append(Part.Vertex(-23.75, 142.5, 0.0)) points_forces.append(Part.Vertex(-71.25, 142.5, 0.0)) points_forces.append(Part.Vertex(-118.75, 142.5, 0.0)) points_fixes = [] points_fixes.append(Part.Vertex(-142.5, 142.5, 1000.0)) points_fixes.append(Part.Vertex(-142.5, -142.5, 1000.0)) points_fixes.append(Part.Vertex(-142.5, 95.0, 1000.0)) points_fixes.append(Part.Vertex(-142.5, 47.5, 1000.0)) points_fixes.append(Part.Vertex(-142.5, 0.0, 1000.0)) points_fixes.append(Part.Vertex(-142.5, -47.5, 1000.0)) points_fixes.append(Part.Vertex(-142.5, -95.0, 1000.0)) points_fixes.append(Part.Vertex(142.5, -142.5, 1000.0)) points_fixes.append(Part.Vertex(-95.0, -142.5, 1000.0)) points_fixes.append(Part.Vertex(-47.5, -142.5, 1000.0)) points_fixes.append(Part.Vertex(0.0, -142.5, 1000.0)) points_fixes.append(Part.Vertex(47.5, -142.5, 1000.0)) points_fixes.append(Part.Vertex(95.0, -142.5, 1000.0)) points_fixes.append(Part.Vertex(142.5, 142.5, 1000.0)) points_fixes.append(Part.Vertex(142.5, -95.0, 1000.0)) points_fixes.append(Part.Vertex(142.5, -47.5, 1000.0)) points_fixes.append(Part.Vertex(142.5, 0.0, 1000.0)) points_fixes.append(Part.Vertex(142.5, 47.5, 1000.0)) points_fixes.append(Part.Vertex(142.5, 95.0, 1000.0)) points_fixes.append(Part.Vertex(95.0, 142.5, 1000.0)) points_fixes.append(Part.Vertex(47.5, 142.5, 1000.0)) points_fixes.append(Part.Vertex(0.0, 142.5, 1000.0)) points_fixes.append(Part.Vertex(-47.5, 142.5, 1000.0)) points_fixes.append(Part.Vertex(-95.0, 142.5, 1000.0)) points_fixes.append(Part.Vertex(-142.5, 118.75, 1000.0)) points_fixes.append(Part.Vertex(-142.5, -118.75, 1000.0)) points_fixes.append(Part.Vertex(-142.5, 71.25, 1000.0)) points_fixes.append(Part.Vertex(-142.5, 23.75, 1000.0)) points_fixes.append(Part.Vertex(-142.5, -23.75, 1000.0)) points_fixes.append(Part.Vertex(-142.5, -71.25, 1000.0)) points_fixes.append(Part.Vertex(118.75, -142.5, 1000.0)) points_fixes.append(Part.Vertex(-71.25, -142.5, 1000.0)) points_fixes.append(Part.Vertex(-118.75, -142.5, 1000.0)) points_fixes.append(Part.Vertex(-23.75, -142.5, 1000.0)) points_fixes.append(Part.Vertex(23.75, -142.5, 1000.0)) points_fixes.append(Part.Vertex(71.25, -142.5, 1000.0)) points_fixes.append(Part.Vertex(142.5, 118.75, 1000.0)) points_fixes.append(Part.Vertex(142.5, -71.25, 1000.0)) points_fixes.append(Part.Vertex(142.5, -118.75, 1000.0)) points_fixes.append(Part.Vertex(142.5, -23.75, 1000.0)) points_fixes.append(Part.Vertex(142.5, 23.75, 1000.0)) points_fixes.append(Part.Vertex(142.5, 71.25, 1000.0)) points_fixes.append(Part.Vertex(71.25, 142.5, 1000.0)) points_fixes.append(Part.Vertex(118.75, 142.5, 1000.0)) points_fixes.append(Part.Vertex(23.75, 142.5, 1000.0)) points_fixes.append(Part.Vertex(-23.75, 142.5, 1000.0)) points_fixes.append(Part.Vertex(-71.25, 142.5, 1000.0)) points_fixes.append(Part.Vertex(-118.75, 142.5, 1000.0)) forces_obj = doc.addObject('Part::Feature', 'Forces') forces_obj.Shape = Part.makeCompound(points_forces) fixes_obj = doc.addObject('Part::Feature', 'Fixes') fixes_obj.Shape = Part.makeCompound(points_fixes) doc.recompute() if FreeCAD.GuiUp: forces_obj.ViewObject.PointColor = (1.0, 0.0, 0.0, 0.0) forces_obj.ViewObject.PointSize = 10.0 fixes_obj.ViewObject.PointColor = (1.0, 0.0, 0.0, 0.0) fixes_obj.ViewObject.PointSize = 10.0 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 thickness = analysis.addObject( ObjectsFem.makeElementGeometry2D(doc, 0, "ShellThickness"))[0] thickness.Thickness = 15.0 # material material_object = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, "FemMaterial"))[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 # fixed_constraint fixed_constraint = analysis.addObject( ObjectsFem.makeConstraintFixed(doc, name="ConstraintFixed"))[0] fixed_constraint.References = [(doc.Fixes, 'Vertex6'), (doc.Fixes, 'Vertex15'), (doc.Fixes, 'Vertex5'), (doc.Fixes, 'Vertex29'), (doc.Fixes, 'Vertex42'), (doc.Fixes, 'Vertex30'), (doc.Fixes, 'Vertex9'), (doc.Fixes, 'Vertex31'), (doc.Fixes, 'Vertex33'), (doc.Fixes, 'Vertex32'), (doc.Fixes, 'Vertex3'), (doc.Fixes, 'Vertex34'), (doc.Fixes, 'Vertex46'), (doc.Fixes, 'Vertex1'), (doc.Fixes, 'Vertex36'), (doc.Fixes, 'Vertex11'), (doc.Fixes, 'Vertex38'), (doc.Fixes, 'Vertex12'), (doc.Fixes, 'Vertex39'), (doc.Fixes, 'Vertex13'), (doc.Fixes, 'Vertex40'), (doc.Fixes, 'Vertex16'), (doc.Fixes, 'Vertex35'), (doc.Fixes, 'Vertex14'), (doc.Fixes, 'Vertex47'), (doc.Fixes, 'Vertex20'), (doc.Fixes, 'Vertex37'), (doc.Fixes, 'Vertex18'), (doc.Fixes, 'Vertex41'), (doc.Fixes, 'Vertex17'), (doc.Fixes, 'Vertex10'), (doc.Fixes, 'Vertex26'), (doc.Fixes, 'Vertex43'), (doc.Fixes, 'Vertex21'), (doc.Fixes, 'Vertex44'), (doc.Fixes, 'Vertex19'), (doc.Fixes, 'Vertex4'), (doc.Fixes, 'Vertex28'), (doc.Fixes, 'Vertex48'), (doc.Fixes, 'Vertex22'), (doc.Fixes, 'Vertex8'), (doc.Fixes, 'Vertex23'), (doc.Fixes, 'Vertex7'), (doc.Fixes, 'Vertex24'), (doc.Fixes, 'Vertex45'), (doc.Fixes, 'Vertex27'), (doc.Fixes, 'Vertex2'), (doc.Fixes, 'Vertex25')] # force_constraint1 force_constraint1 = analysis.addObject( ObjectsFem.makeConstraintForce(doc, name="ConstraintForce1"))[0] force_constraint1.References = [(forces_obj, 'Vertex1'), (forces_obj, 'Vertex14')] force_constraint1.Force = 5555.56 force_constraint1.Direction = (doc.SquareTube, ["Edge9"]) force_constraint1.Reversed = False # force_constraint2 force_constraint2 = analysis.addObject( ObjectsFem.makeConstraintForce(doc, name="ConstraintForce2"))[0] force_constraint2.References = [(forces_obj, 'Vertex2'), (forces_obj, 'Vertex8')] force_constraint2.Force = 5555.56 force_constraint2.Direction = (doc.SquareTube, ["Edge3"]) force_constraint2.Reversed = False # force_constraint3 force_constraint3 = analysis.addObject( ObjectsFem.makeConstraintForce(doc, name="ConstraintForce3"))[0] force_constraint3.References = [ (forces_obj, 'Vertex20'), (forces_obj, 'Vertex21'), (forces_obj, 'Vertex22'), (forces_obj, 'Vertex23'), (forces_obj, 'Vertex24'), ] force_constraint3.Force = 27777.78 force_constraint3.Direction = (doc.SquareTube, ["Edge9"]) force_constraint3.Reversed = False # force_constraint4 force_constraint4 = analysis.addObject( ObjectsFem.makeConstraintForce(doc, name="ConstraintForce4"))[0] force_constraint4.References = [ (forces_obj, 'Vertex9'), (forces_obj, 'Vertex10'), (forces_obj, 'Vertex11'), (forces_obj, 'Vertex12'), (forces_obj, 'Vertex13'), ] force_constraint4.Force = 27777.78 force_constraint4.Direction = (doc.SquareTube, ["Edge3"]) force_constraint4.Reversed = False # force_constraint5 force_constraint5 = analysis.addObject( ObjectsFem.makeConstraintForce(doc, name="ConstraintForce5"))[0] force_constraint5.References = [ (forces_obj, 'Vertex43'), (forces_obj, 'Vertex44'), (forces_obj, 'Vertex45'), (forces_obj, 'Vertex46'), (forces_obj, 'Vertex47'), (forces_obj, 'Vertex48'), ] force_constraint5.Force = 66666.67 force_constraint5.Direction = (doc.SquareTube, ["Edge9"]) force_constraint5.Reversed = False # force_constraint6 force_constraint6 = analysis.addObject( ObjectsFem.makeConstraintForce(doc, name="ConstraintForce6"))[0] force_constraint6.References = [ (forces_obj, 'Vertex31'), (forces_obj, 'Vertex32'), (forces_obj, 'Vertex33'), (forces_obj, 'Vertex34'), (forces_obj, 'Vertex35'), (forces_obj, 'Vertex36'), ] force_constraint6.Force = 66666.67 force_constraint6.Direction = (doc.SquareTube, ["Edge3"]) force_constraint6.Reversed = False # force_constraint7 force_constraint7 = analysis.addObject( ObjectsFem.makeConstraintForce(doc, name="ConstraintForce7"))[0] force_constraint7.References = [(forces_obj, 'Vertex1'), (forces_obj, 'Vertex2')] force_constraint7.Force = 5555.56 force_constraint7.Direction = (doc.SquareTube, ["Edge11"]) force_constraint7.Reversed = False # force_constraint8 force_constraint8 = analysis.addObject( ObjectsFem.makeConstraintForce(doc, name="ConstraintForce8"))[0] force_constraint8.References = [(forces_obj, 'Vertex8'), (forces_obj, 'Vertex14')] force_constraint8.Force = 5555.56 force_constraint8.Direction = (doc.SquareTube, ["Edge6"]) force_constraint8.Reversed = False # force_constraint9 force_constraint9 = analysis.addObject( ObjectsFem.makeConstraintForce(doc, name="ConstraintForce9"))[0] force_constraint9.References = [ (forces_obj, 'Vertex3'), (forces_obj, 'Vertex4'), (forces_obj, 'Vertex5'), (forces_obj, 'Vertex6'), (forces_obj, 'Vertex7'), ] force_constraint9.Force = 27777.78 force_constraint9.Direction = (doc.SquareTube, ["Edge11"]) force_constraint9.Reversed = False # force_constraint10 force_constraint10 = analysis.addObject( ObjectsFem.makeConstraintForce(doc, name="ConstraintForce10"))[0] force_constraint10.References = [ (forces_obj, 'Vertex15'), (forces_obj, 'Vertex16'), (forces_obj, 'Vertex17'), (forces_obj, 'Vertex18'), (forces_obj, 'Vertex19'), ] force_constraint10.Force = 27777.78 force_constraint10.Direction = (doc.SquareTube, ["Edge6"]) force_constraint10.Reversed = False # force_constraint11 force_constraint11 = analysis.addObject( ObjectsFem.makeConstraintForce(doc, name="ConstraintForce11"))[0] force_constraint11.References = [ (forces_obj, 'Vertex25'), (forces_obj, 'Vertex26'), (forces_obj, 'Vertex27'), (forces_obj, 'Vertex28'), (forces_obj, 'Vertex29'), (forces_obj, 'Vertex30'), ] force_constraint11.Force = 66666.67 force_constraint11.Direction = (doc.SquareTube, ["Edge11"]) force_constraint11.Reversed = False # force_constraint12 force_constraint12 = analysis.addObject( ObjectsFem.makeConstraintForce(doc, name="ConstraintForce12"))[0] force_constraint12.References = [ (forces_obj, 'Vertex37'), (forces_obj, 'Vertex38'), (forces_obj, 'Vertex39'), (forces_obj, 'Vertex40'), (forces_obj, 'Vertex41'), (forces_obj, 'Vertex42'), ] force_constraint12.Force = 66666.67 force_constraint12.Direction = (doc.SquareTube, ["Edge6"]) force_constraint12.Reversed = False # 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, 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::Box", "Box") geom_obj.Length = 3000 geom_obj.Width = 100 geom_obj.Height = 50 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 = "frequency" solver_obj.GeometricalNonlinearity = "linear" solver_obj.ThermoMechSteadyState = False solver_obj.MatrixSolverType = "default" solver_obj.IterationsControlParameterTimeUse = False solver_obj.EigenmodesCount = 10 solver_obj.EigenmodeHighLimit = 1000000.0 solver_obj.EigenmodeLowLimit = 0.01 analysis.addObject(solver_obj) # material material_obj = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterial"))[0] 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 displacement xyz con_disp_xyz = ObjectsFem.makeConstraintDisplacement(doc, "Fix_XYZ") con_disp_xyz.References = [(doc.Box, "Edge4")] con_disp_xyz.xFix = True con_disp_xyz.xFree = False con_disp_xyz.xDisplacement = 0.0 con_disp_xyz.yFix = True con_disp_xyz.yFree = False con_disp_xyz.yDisplacement = 0.0 con_disp_xyz.zFix = True con_disp_xyz.zFree = False con_disp_xyz.zDisplacement = 0.0 analysis.addObject(con_disp_xyz) # constraint displacement yz con_disp_yz = ObjectsFem.makeConstraintDisplacement(doc, "Fix_YZ") con_disp_yz.References = [(doc.Box, "Edge8")] con_disp_yz.xFix = False con_disp_yz.xFree = True con_disp_yz.xDisplacement = 0.0 con_disp_yz.yFix = True con_disp_yz.yFree = False con_disp_yz.yDisplacement = 0.0 con_disp_yz.zFix = True con_disp_yz.zFree = False con_disp_yz.zDisplacement = 0.0 analysis.addObject(con_disp_yz) # mesh from .meshes.mesh_beamsimple_tetra10 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") 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 = "25.0 mm" doc.recompute() return doc
def create_mesh(self): self.mesh = ObjectsFem.makeMeshGmsh(self.doc, "Mesh") self.doc.Mesh.Part = self.doc.Geometry g = gmshtools.GmshTools(self.doc.Mesh) g.create_mesh() self.analysis.addObject(self.mesh)
def test_solver_elmer( self ): fcc_print("\n--------------- Start of FEM tests solver framework solver Elmer ---------") # set up the Elmer static analysis example from femexamples import boxanalysis as box box.setup_static(self.document, "elmer") analysis_obj = self.document.Analysis solver_obj = self.document.SolverElmer material_obj = self.document.MechanicalMaterial mesh_obj = self.document.Mesh box_object = self.document.Box base_name = "cube_static" analysis_dir = testtools.get_unit_test_tmp_dir(self.temp_dir, solver_obj.Name) # TODO move to elmer solver of femexample code ObjectsFem.makeEquationElasticity(self.document, solver_obj) # set ThermalExpansionCoefficient # FIXME elmer elasticity needs the dictionary key "ThermalExpansionCoefficient" # even on simple elasticity analysis, otherwise it fails mat = material_obj.Material mat["ThermalExpansionCoefficient"] = "0 um/m/K" material_obj.Material = mat # elmer needs a GMHS mesh object # FIXME error message on Python solver run mesh_gmsh = ObjectsFem.makeMeshGmsh(self.document) mesh_gmsh.CharacteristicLengthMin = "9 mm" mesh_gmsh.FemMesh = mesh_obj.FemMesh mesh_gmsh.Part = box_object analysis_obj.addObject(mesh_gmsh) self.document.removeObject(mesh_obj.Name) # remove original mesh object # save the file save_fc_file = join(analysis_dir, solver_obj.Name + "_" + base_name + ".FCStd") fcc_print("Save FreeCAD file to {}...".format(save_fc_file)) self.document.saveAs(save_fc_file) # write input files fcc_print("Checking FEM input file writing for Elmer solver framework solver ...") machine_elmer = solver_obj.Proxy.createMachine( solver_obj, analysis_dir, True ) machine_elmer.target = femsolver.run.PREPARE machine_elmer.start() machine_elmer.join() # wait for the machine to finish. # compare startinfo, case and gmsh input files test_file_dir_elmer = join(testtools.get_fem_test_home_dir(), "elmer") fcc_print(test_file_dir_elmer) fcc_print("Test writing STARTINFO file") startinfo_given = join(test_file_dir_elmer, "ELMERSOLVER_STARTINFO") startinfo_totest = join(analysis_dir, "ELMERSOLVER_STARTINFO") fcc_print("Comparing {} to {}".format(startinfo_given, startinfo_totest)) ret = testtools.compare_files(startinfo_given, startinfo_totest) self.assertFalse(ret, "STARTINFO write file test failed.\n{}".format(ret)) fcc_print("Test writing case file") casefile_given = join(test_file_dir_elmer, "case.sif") casefile_totest = join(analysis_dir, "case.sif") fcc_print("Comparing {} to {}".format(casefile_given, casefile_totest)) ret = testtools.compare_files(casefile_given, casefile_totest) self.assertFalse(ret, "case write file test failed.\n{}".format(ret)) fcc_print("Test writing GMSH geo file") gmshgeofile_given = join(test_file_dir_elmer, "group_mesh.geo") gmshgeofile_totest = join(analysis_dir, "group_mesh.geo") fcc_print("Comparing {} to {}".format(gmshgeofile_given, gmshgeofile_totest)) ret = testtools.compare_files(gmshgeofile_given, gmshgeofile_totest) self.assertFalse(ret, "GMSH geo write file test failed.\n{}".format(ret)) fcc_print("--------------- End of FEM tests solver framework solver Elmer -----------")
def create_material(self, material): material_obj = ObjectsFem.makeMaterialSolid(self.doc, "Material") material_obj.Material = material self.analysis.addObject(material_obj)
def setup(doc=None, solvertype="ccxtools"): # setup model if doc is None: doc = init_doc() # geometry objects p1 = vec(0, 0, 50) p2 = vec(0, 0, -50) p3 = vec(0, 0, -4300) p4 = vec(4950, 0, -4300) p5 = vec(5000, 0, -4300) p6 = vec(8535.53, 0, -7835.53) p7 = vec(8569.88, 0, -7870.88) p8 = vec(12105.41, 0, -11406.41) p9 = vec(12140.76, 0, -11441.76) p10 = vec(13908.53, 0, -13209.53) p11 = vec(13943.88, 0, -13244.88) p12 = vec(15046.97, 0, -14347.97) p13 = vec(15046.97, 0, -7947.97) p14 = vec(15046.97, 0, -7847.97) p15 = vec(0, 0, 0) p16 = vec(0, 0, -2175) p17 = vec(2475, 0, -4300) p18 = vec(4975, 0, -4300) p19 = vec(6767.765, 0, -6067.765) p20 = vec(8552.705, 0, -7853.205) p21 = vec(10337.645, 0, -9638.645) p22 = vec(12123.085, 0, -11424.085) p23 = vec(13024.645, 0, -12325.645) p24 = vec(13926.205, 0, -13227.205) p25 = vec(14495.425, 0, -13796.425) p26 = vec(15046.97, 0, -11147.97) p27 = vec(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 ] geom_obj = makeWire(points, closed=False, face=False, support=None) 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") # CalculiX )[0] solver_object.WorkingDir = u"" if solvertype == "calculix" or solvertype == "ccxtools": solver_object.SplitInputWriter = False solver_object.AnalysisType = "thermomech" solver_object.GeometricalNonlinearity = "linear" solver_object.ThermoMechSteadyState = True solver_object.MatrixSolverType = "default" solver_object.IterationsThermoMechMaximum = 2000 solver_object.IterationsControlParameterTimeUse = False # material material_object = analysis.addObject( ObjectsFem.makeMaterialFluid(doc, "FluidMaterial"))[0] 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 inlet = analysis.addObject( ObjectsFem.makeElementFluid1D(doc, "ElementFluid1D"))[0] inlet.SectionType = "Liquid" inlet.LiquidSectionType = "PIPE INLET" inlet.InletPressure = 0.1 inlet.References = [(geom_obj, "Edge1")] entrance = analysis.addObject( ObjectsFem.makeElementFluid1D(doc, "ElementFluid1D"))[0] entrance.SectionType = "Liquid" entrance.LiquidSectionType = "PIPE ENTRANCE" entrance.EntrancePipeArea = 31416.00 entrance.EntranceArea = 25133.00 entrance.References = [(geom_obj, "Edge2")] manning1 = analysis.addObject( ObjectsFem.makeElementFluid1D(doc, "ElementFluid1D"))[0] manning1.SectionType = "Liquid" manning1.LiquidSectionType = "PIPE MANNING" manning1.ManningArea = 31416 manning1.ManningRadius = 50 manning1.ManningCoefficient = 0.002 manning1.References = [(geom_obj, "Edge3"), (geom_obj, "Edge5")] bend = analysis.addObject( ObjectsFem.makeElementFluid1D(doc, "ElementFluid1D"))[0] bend.SectionType = "Liquid" bend.LiquidSectionType = "PIPE BEND" bend.BendPipeArea = 31416 bend.BendRadiusDiameter = 1.5 bend.BendAngle = 45 bend.BendLossCoefficient = 0.4 bend.References = [(geom_obj, "Edge4")] enlargement1 = analysis.addObject( ObjectsFem.makeElementFluid1D(doc, "ElementFluid1D"))[0] enlargement1.SectionType = "Liquid" enlargement1.LiquidSectionType = "PIPE ENLARGEMENT" enlargement1.EnlargeArea1 = 31416.00 enlargement1.EnlargeArea2 = 70686.00 enlargement1.References = [(geom_obj, "Edge6")] manning2 = analysis.addObject( ObjectsFem.makeElementFluid1D(doc, "ElementFluid1D"))[0] manning2.SectionType = "Liquid" manning2.LiquidSectionType = "PIPE MANNING" manning2.ManningArea = 70686.00 manning2.ManningRadius = 75 manning2.ManningCoefficient = 0.002 manning2.References = [(geom_obj, "Edge7")] contraction = analysis.addObject( ObjectsFem.makeElementFluid1D(doc, "ElementFluid1D"))[0] contraction.SectionType = "Liquid" contraction.LiquidSectionType = "PIPE CONTRACTION" contraction.ContractArea1 = 70686 contraction.ContractArea2 = 17671 contraction.References = [(geom_obj, "Edge8")] manning3 = analysis.addObject( ObjectsFem.makeElementFluid1D(doc, "ElementFluid1D"))[0] manning3.SectionType = "Liquid" manning3.LiquidSectionType = "PIPE MANNING" manning3.ManningArea = 17671.00 manning3.ManningRadius = 37.5 manning3.ManningCoefficient = 0.002 manning3.References = [(geom_obj, "Edge11"), (geom_obj, "Edge9")] gate_valve = analysis.addObject( ObjectsFem.makeElementFluid1D(doc, "ElementFluid1D"))[0] gate_valve.SectionType = "Liquid" gate_valve.LiquidSectionType = "PIPE GATE VALVE" gate_valve.GateValvePipeArea = 17671 gate_valve.GateValveClosingCoeff = 0.5 gate_valve.References = [(geom_obj, "Edge10")] enlargement2 = analysis.addObject( ObjectsFem.makeElementFluid1D(doc, "ElementFluid1D"))[0] enlargement2.SectionType = "Liquid" enlargement2.LiquidSectionType = "PIPE ENLARGEMENT" enlargement2.EnlargeArea1 = 17671 enlargement2.EnlargeArea2 = 1e12 enlargement2.References = [(geom_obj, "Edge12")] outlet = analysis.addObject( ObjectsFem.makeElementFluid1D(doc, "ElementFluid1D"))[0] outlet.SectionType = "Liquid" outlet.LiquidSectionType = "PIPE OUTLET" outlet.OutletPressure = 0.1 outlet.References = [(geom_obj, "Edge13")] self_weight = analysis.addObject( ObjectsFem.makeConstraintSelfWeight(doc, "ConstraintSelfWeight"))[0] self_weight.Gravity_x = 0.0 self_weight.Gravity_y = 0.0 self_weight.Gravity_z = -1.0 # mesh from .meshes.mesh_thermomech_flow1d_seg3 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") 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"): # 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 points_forces = [] points_forces.append(Part.Vertex(-142.5, 142.5, 0.0)) points_forces.append(Part.Vertex(-142.5, -142.5, 0.0)) points_forces.append(Part.Vertex(-142.5, 95.0, 0.0)) points_forces.append(Part.Vertex(-142.5, 47.5, 0.0)) points_forces.append(Part.Vertex(-142.5, 0.0, 0.0)) points_forces.append(Part.Vertex(-142.5, -47.5, 0.0)) points_forces.append(Part.Vertex(-142.5, -95.0, 0.0)) points_forces.append(Part.Vertex(142.5, -142.5, 0.0)) points_forces.append(Part.Vertex(-95.0, -142.5, 0.0)) points_forces.append(Part.Vertex(-47.5, -142.5, 0.0)) points_forces.append(Part.Vertex(0.0, -142.5, 0.0)) points_forces.append(Part.Vertex(47.5, -142.5, 0.0)) points_forces.append(Part.Vertex(95.0, -142.5, 0.0)) points_forces.append(Part.Vertex(142.5, 142.5, 0.0)) points_forces.append(Part.Vertex(142.5, -95.0, 0.0)) points_forces.append(Part.Vertex(142.5, -47.5, 0.0)) points_forces.append(Part.Vertex(142.5, 0.0, 0.0)) points_forces.append(Part.Vertex(142.5, 47.5, 0.0)) points_forces.append(Part.Vertex(142.5, 95.0, 0.0)) points_forces.append(Part.Vertex(95.0, 142.5, 0.0)) points_forces.append(Part.Vertex(47.5, 142.5, 0.0)) points_forces.append(Part.Vertex(0.0, 142.5, 0.0)) points_forces.append(Part.Vertex(-47.5, 142.5, 0.0)) points_forces.append(Part.Vertex(-95.0, 142.5, 0.0)) points_forces.append(Part.Vertex(-142.5, 118.75, 0.0)) points_forces.append(Part.Vertex(-142.5, -118.75, 0.0)) points_forces.append(Part.Vertex(-142.5, 71.25, 0.0)) points_forces.append(Part.Vertex(-142.5, 23.75, 0.0)) points_forces.append(Part.Vertex(-142.5, -23.75, 0.0)) points_forces.append(Part.Vertex(-142.5, -71.25, 0.0)) points_forces.append(Part.Vertex(118.75, -142.5, 0.0)) points_forces.append(Part.Vertex(-71.25, -142.5, 0.0)) points_forces.append(Part.Vertex(-118.75, -142.5, 0.0)) points_forces.append(Part.Vertex(-23.75, -142.5, 0.0)) points_forces.append(Part.Vertex(23.75, -142.5, 0.0)) points_forces.append(Part.Vertex(71.25, -142.5, 0.0)) points_forces.append(Part.Vertex(142.5, 118.75, 0.0)) points_forces.append(Part.Vertex(142.5, -71.25, 0.0)) points_forces.append(Part.Vertex(142.5, -118.75, 0.0)) points_forces.append(Part.Vertex(142.5, -23.75, 0.0)) points_forces.append(Part.Vertex(142.5, 23.75, 0.0)) points_forces.append(Part.Vertex(142.5, 71.25, 0.0)) points_forces.append(Part.Vertex(71.25, 142.5, 0.0)) points_forces.append(Part.Vertex(118.75, 142.5, 0.0)) points_forces.append(Part.Vertex(23.75, 142.5, 0.0)) points_forces.append(Part.Vertex(-23.75, 142.5, 0.0)) points_forces.append(Part.Vertex(-71.25, 142.5, 0.0)) points_forces.append(Part.Vertex(-118.75, 142.5, 0.0)) points_fixes = [] points_fixes.append(Part.Vertex(-142.5, 142.5, 1000.0)) points_fixes.append(Part.Vertex(-142.5, -142.5, 1000.0)) points_fixes.append(Part.Vertex(-142.5, 95.0, 1000.0)) points_fixes.append(Part.Vertex(-142.5, 47.5, 1000.0)) points_fixes.append(Part.Vertex(-142.5, 0.0, 1000.0)) points_fixes.append(Part.Vertex(-142.5, -47.5, 1000.0)) points_fixes.append(Part.Vertex(-142.5, -95.0, 1000.0)) points_fixes.append(Part.Vertex(142.5, -142.5, 1000.0)) points_fixes.append(Part.Vertex(-95.0, -142.5, 1000.0)) points_fixes.append(Part.Vertex(-47.5, -142.5, 1000.0)) points_fixes.append(Part.Vertex(0.0, -142.5, 1000.0)) points_fixes.append(Part.Vertex(47.5, -142.5, 1000.0)) points_fixes.append(Part.Vertex(95.0, -142.5, 1000.0)) points_fixes.append(Part.Vertex(142.5, 142.5, 1000.0)) points_fixes.append(Part.Vertex(142.5, -95.0, 1000.0)) points_fixes.append(Part.Vertex(142.5, -47.5, 1000.0)) points_fixes.append(Part.Vertex(142.5, 0.0, 1000.0)) points_fixes.append(Part.Vertex(142.5, 47.5, 1000.0)) points_fixes.append(Part.Vertex(142.5, 95.0, 1000.0)) points_fixes.append(Part.Vertex(95.0, 142.5, 1000.0)) points_fixes.append(Part.Vertex(47.5, 142.5, 1000.0)) points_fixes.append(Part.Vertex(0.0, 142.5, 1000.0)) points_fixes.append(Part.Vertex(-47.5, 142.5, 1000.0)) points_fixes.append(Part.Vertex(-95.0, 142.5, 1000.0)) points_fixes.append(Part.Vertex(-142.5, 118.75, 1000.0)) points_fixes.append(Part.Vertex(-142.5, -118.75, 1000.0)) points_fixes.append(Part.Vertex(-142.5, 71.25, 1000.0)) points_fixes.append(Part.Vertex(-142.5, 23.75, 1000.0)) points_fixes.append(Part.Vertex(-142.5, -23.75, 1000.0)) points_fixes.append(Part.Vertex(-142.5, -71.25, 1000.0)) points_fixes.append(Part.Vertex(118.75, -142.5, 1000.0)) points_fixes.append(Part.Vertex(-71.25, -142.5, 1000.0)) points_fixes.append(Part.Vertex(-118.75, -142.5, 1000.0)) points_fixes.append(Part.Vertex(-23.75, -142.5, 1000.0)) points_fixes.append(Part.Vertex(23.75, -142.5, 1000.0)) points_fixes.append(Part.Vertex(71.25, -142.5, 1000.0)) points_fixes.append(Part.Vertex(142.5, 118.75, 1000.0)) points_fixes.append(Part.Vertex(142.5, -71.25, 1000.0)) points_fixes.append(Part.Vertex(142.5, -118.75, 1000.0)) points_fixes.append(Part.Vertex(142.5, -23.75, 1000.0)) points_fixes.append(Part.Vertex(142.5, 23.75, 1000.0)) points_fixes.append(Part.Vertex(142.5, 71.25, 1000.0)) points_fixes.append(Part.Vertex(71.25, 142.5, 1000.0)) points_fixes.append(Part.Vertex(118.75, 142.5, 1000.0)) points_fixes.append(Part.Vertex(23.75, 142.5, 1000.0)) points_fixes.append(Part.Vertex(-23.75, 142.5, 1000.0)) points_fixes.append(Part.Vertex(-71.25, 142.5, 1000.0)) points_fixes.append(Part.Vertex(-118.75, 142.5, 1000.0)) geoforces_obj = doc.addObject('Part::Feature', 'Forces') geoforces_obj.Shape = Part.makeCompound(points_forces) geofixes_obj = doc.addObject('Part::Feature', 'Fixes') geofixes_obj.Shape = Part.makeCompound(points_fixes) doc.recompute() if FreeCAD.GuiUp: geoforces_obj.ViewObject.PointColor = (1.0, 0.0, 0.0, 0.0) geoforces_obj.ViewObject.PointSize = 10.0 geofixes_obj.ViewObject.PointColor = (1.0, 0.0, 0.0, 0.0) geofixes_obj.ViewObject.PointSize = 10.0 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 = [(geofixes_obj, 'Vertex6'), (geofixes_obj, 'Vertex15'), (geofixes_obj, 'Vertex5'), (geofixes_obj, 'Vertex29'), (geofixes_obj, 'Vertex42'), (geofixes_obj, 'Vertex30'), (geofixes_obj, 'Vertex9'), (geofixes_obj, 'Vertex31'), (geofixes_obj, 'Vertex33'), (geofixes_obj, 'Vertex32'), (geofixes_obj, 'Vertex3'), (geofixes_obj, 'Vertex34'), (geofixes_obj, 'Vertex46'), (geofixes_obj, 'Vertex1'), (geofixes_obj, 'Vertex36'), (geofixes_obj, 'Vertex11'), (geofixes_obj, 'Vertex38'), (geofixes_obj, 'Vertex12'), (geofixes_obj, 'Vertex39'), (geofixes_obj, 'Vertex13'), (geofixes_obj, 'Vertex40'), (geofixes_obj, 'Vertex16'), (geofixes_obj, 'Vertex35'), (geofixes_obj, 'Vertex14'), (geofixes_obj, 'Vertex47'), (geofixes_obj, 'Vertex20'), (geofixes_obj, 'Vertex37'), (geofixes_obj, 'Vertex18'), (geofixes_obj, 'Vertex41'), (geofixes_obj, 'Vertex17'), (geofixes_obj, 'Vertex10'), (geofixes_obj, 'Vertex26'), (geofixes_obj, 'Vertex43'), (geofixes_obj, 'Vertex21'), (geofixes_obj, 'Vertex44'), (geofixes_obj, 'Vertex19'), (geofixes_obj, 'Vertex4'), (geofixes_obj, 'Vertex28'), (geofixes_obj, 'Vertex48'), (geofixes_obj, 'Vertex22'), (geofixes_obj, 'Vertex8'), (geofixes_obj, 'Vertex23'), (geofixes_obj, 'Vertex7'), (geofixes_obj, 'Vertex24'), (geofixes_obj, 'Vertex45'), (geofixes_obj, 'Vertex27'), (geofixes_obj, 'Vertex2'), (geofixes_obj, 'Vertex25')] analysis.addObject(con_fixed) # con_force1 con_force1 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce1") con_force1.References = [(geoforces_obj, 'Vertex1'), (geoforces_obj, 'Vertex14')] con_force1.Force = 5555.56 con_force1.Direction = (geom_obj, ["Edge9"]) con_force1.Reversed = False analysis.addObject(con_force1) # con_force2 con_force2 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce2") con_force2.References = [(geoforces_obj, 'Vertex2'), (geoforces_obj, 'Vertex8')] con_force2.Force = 5555.56 con_force2.Direction = (geom_obj, ["Edge3"]) con_force2.Reversed = False analysis.addObject(con_force2) # con_force3 con_force3 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce3") con_force3.References = [ (geoforces_obj, 'Vertex20'), (geoforces_obj, 'Vertex21'), (geoforces_obj, 'Vertex22'), (geoforces_obj, 'Vertex23'), (geoforces_obj, 'Vertex24'), ] con_force3.Force = 27777.78 con_force3.Direction = (geom_obj, ["Edge9"]) con_force3.Reversed = False analysis.addObject(con_force3) # con_force4 con_force4 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce4") con_force4.References = [ (geoforces_obj, 'Vertex9'), (geoforces_obj, 'Vertex10'), (geoforces_obj, 'Vertex11'), (geoforces_obj, 'Vertex12'), (geoforces_obj, 'Vertex13'), ] con_force4.Force = 27777.78 con_force4.Direction = (geom_obj, ["Edge3"]) con_force4.Reversed = False analysis.addObject(con_force4) # con_force5 con_force5 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce5") con_force5.References = [ (geoforces_obj, 'Vertex43'), (geoforces_obj, 'Vertex44'), (geoforces_obj, 'Vertex45'), (geoforces_obj, 'Vertex46'), (geoforces_obj, 'Vertex47'), (geoforces_obj, 'Vertex48'), ] con_force5.Force = 66666.67 con_force5.Direction = (geom_obj, ["Edge9"]) con_force5.Reversed = False analysis.addObject(con_force5) # con_force6 con_force6 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce6") con_force6.References = [ (geoforces_obj, 'Vertex31'), (geoforces_obj, 'Vertex32'), (geoforces_obj, 'Vertex33'), (geoforces_obj, 'Vertex34'), (geoforces_obj, 'Vertex35'), (geoforces_obj, 'Vertex36'), ] con_force6.Force = 66666.67 con_force6.Direction = (geom_obj, ["Edge3"]) con_force6.Reversed = False analysis.addObject(con_force6) # con_force7 con_force7 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce7") con_force7.References = [(geoforces_obj, 'Vertex1'), (geoforces_obj, 'Vertex2')] con_force7.Force = 5555.56 con_force7.Direction = (geom_obj, ["Edge11"]) con_force7.Reversed = False analysis.addObject(con_force7) # con_force8 con_force8 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce8") con_force8.References = [(geoforces_obj, 'Vertex8'), (geoforces_obj, 'Vertex14')] con_force8.Force = 5555.56 con_force8.Direction = (geom_obj, ["Edge6"]) con_force8.Reversed = False analysis.addObject(con_force8) # con_force9 con_force9 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce9") con_force9.References = [ (geoforces_obj, 'Vertex3'), (geoforces_obj, 'Vertex4'), (geoforces_obj, 'Vertex5'), (geoforces_obj, 'Vertex6'), (geoforces_obj, 'Vertex7'), ] con_force9.Force = 27777.78 con_force9.Direction = (geom_obj, ["Edge11"]) con_force9.Reversed = False analysis.addObject(con_force9) # con_force10 con_force10 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce10") con_force10.References = [ (geoforces_obj, 'Vertex15'), (geoforces_obj, 'Vertex16'), (geoforces_obj, 'Vertex17'), (geoforces_obj, 'Vertex18'), (geoforces_obj, 'Vertex19'), ] con_force10.Force = 27777.78 con_force10.Direction = (geom_obj, ["Edge6"]) con_force10.Reversed = False analysis.addObject(con_force10) # con_force11 con_force11 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce11") con_force11.References = [ (geoforces_obj, 'Vertex25'), (geoforces_obj, 'Vertex26'), (geoforces_obj, 'Vertex27'), (geoforces_obj, 'Vertex28'), (geoforces_obj, 'Vertex29'), (geoforces_obj, 'Vertex30'), ] con_force11.Force = 66666.67 con_force11.Direction = (geom_obj, ["Edge11"]) con_force11.Reversed = False analysis.addObject(con_force11) # con_force12 con_force12 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce12") con_force12.References = [ (geoforces_obj, 'Vertex37'), (geoforces_obj, 'Vertex38'), (geoforces_obj, 'Vertex39'), (geoforces_obj, 'Vertex40'), (geoforces_obj, 'Vertex41'), (geoforces_obj, 'Vertex42'), ] con_force12.Force = 66666.67 con_force12.Direction = (geom_obj, ["Edge6"]) con_force12.Reversed = False analysis.addObject(con_force12) # 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() # geometry objects v1 = vec(-200, -100, 0) v2 = vec(200, -100, 0) v3 = vec(200, 100, 0) v4 = vec(-200, 100, 0) l1 = ln(v1, v2) l2 = ln(v2, v3) l3 = ln(v3, v4) l4 = ln(v4, v1) v5 = vec(0, 0, 0) c1 = ci(50, v5) face = Part.makeFace([Part.Wire([l1, l2, l3, l4]), c1], "Part::FaceMakerBullseye") geom_obj = doc.addObject("Part::Feature", "Hole_Plate") geom_obj.Shape = face.extrude(vec(0, 0, 10)) 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 = 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.SplitInputWriter = False solver.AnalysisType = "static" solver.GeometricalNonlinearity = "linear" solver.ThermoMechSteadyState = False solver.MatrixSolverType = "default" solver.IterationsControlParameterTimeUse = False solver.GeometricalNonlinearity = 'nonlinear' solver.MaterialNonlinearity = 'nonlinear' # linear material matprop = {} matprop["Name"] = "CalculiX-Steel" matprop["YoungsModulus"] = "210000 MPa" matprop["PoissonRatio"] = "0.30" matprop["Density"] = "7900 kg/m^3" material = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, "Material_lin"))[0] material.Material = matprop # nonlinear material nonlinear_material = analysis.addObject( ObjectsFem.makeMaterialMechanicalNonlinear(doc, material, "Material_nonlin"))[0] nonlinear_material.YieldPoint1 = '240.0, 0.0' nonlinear_material.YieldPoint2 = '270.0, 0.025' # check solver attributes, Nonlinearity needs to be set to nonlinear # fixed_constraint fixed_constraint = analysis.addObject( ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed"))[0] fixed_constraint.References = [(geom_obj, "Face4")] # force constraint pressure_constraint = doc.Analysis.addObject( ObjectsFem.makeConstraintPressure(doc, "ConstraintPressure"))[0] pressure_constraint.References = [(geom_obj, "Face2")] pressure_constraint.Pressure = 130.0 pressure_constraint.Reversed = True # mesh from .meshes.mesh_platewithhole_tetra10 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") 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 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')) self.assertTrue( is_of_type(ObjectsFem.makeMaterialReinforced(doc), 'Fem::MaterialReinforced')) 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_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 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 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')) self.assertTrue( ObjectsFem.makeMaterialReinforced(doc).isDerivedFrom( 'App::MaterialObjectPython')) 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 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 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)) 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 self.assertEqual(len(analysis.Group), testtools.get_defmake_count(fem_vtk_post) - 1) # because of the analysis itself count -1
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 ---------------')