def importFrd(filename, Analysis=None): m = readResult(filename) MeshObject = None if (len(m) > 0): import Fem if Analysis == None: AnalysisName = os.path.splitext(os.path.basename(filename))[0] AnalysisObject = FreeCAD.ActiveDocument.addObject( 'Fem::FemAnalysis', 'Analysis') AnalysisObject.Label = AnalysisName else: AnalysisObject = Analysis if (m.has_key('Tet10Elem') and m.has_key('Nodes') and not Analysis): mesh = Fem.FemMesh() nds = m['Nodes'] for i in nds: n = nds[i] mesh.addNode(n[0], n[1], n[2], i) elms = m['Tet10Elem'] for i in elms: e = elms[i] mesh.addVolume([ e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8], e[9] ], i) if len(nds) > 0: MeshObject = FreeCAD.ActiveDocument.addObject( 'Fem::FemMeshObject', 'ResultMesh') MeshObject.FemMesh = mesh AnalysisObject.Member = AnalysisObject.Member + [MeshObject] if (m.has_key('Displacement')): disp = m['Displacement'] if len(disp) > 0: o = FreeCAD.ActiveDocument.addObject('Fem::FemResultVector', 'Displacement') o.Values = disp.values() o.DataType = 'Displacement' o.ElementNumbers = disp.keys() if (MeshObject): o.Mesh = MeshObject AnalysisObject.Member = AnalysisObject.Member + [o] if (m.has_key('Stress')): stress = m['Stress'] if len(stress) > 0: o = FreeCAD.ActiveDocument.addObject('Fem::FemResultValue', 'MisesStress') mstress = [] for i in stress.values(): # van mises stress (http://en.wikipedia.org/wiki/Von_Mises_yield_criterion) mstress.append( sqrt( pow(i[0] - i[1], 2) + pow(i[1] - i[2], 2) + pow(i[2] - i[0], 2) + 6 * (pow(i[3], 2) + pow(i[4], 2) + pow(i[5], 2)))) o.Values = mstress o.DataType = 'VanMisesStress' o.ElementNumbers = stress.keys() if (MeshObject): o.Mesh = MeshObject AnalysisObject.Member = AnalysisObject.Member + [o] if (FreeCAD.GuiUp): import FemGui, FreeCADGui if FreeCADGui.activeWorkbench().name() != 'FemWorkbench': FreeCADGui.activateWorkbench("FemWorkbench") FemGui.setActiveAnalysis(AnalysisObject)
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 objects # name is important because the other method in this module use obj name box_obj1 = doc.addObject("Part::Box", "Box1") box_obj1.Height = 10 box_obj1.Width = 10 box_obj1.Length = 20 box_obj2 = doc.addObject("Part::Box", "Box2") box_obj2.Height = 10 box_obj2.Width = 10 box_obj2.Length = 20 box_obj2.Placement.Base = (20, 0, 0) box_obj3 = doc.addObject("Part::Box", "Box3") box_obj3.Height = 10 box_obj3.Width = 10 box_obj3.Length = 20 box_obj3.Placement.Base = (40, 0, 0) box_obj4 = doc.addObject("Part::Box", "Box4") box_obj4.Height = 10 box_obj4.Width = 10 box_obj4.Length = 20 box_obj4.Placement.Base = (60, 0, 0) box_obj5 = doc.addObject("Part::Box", "Box5") box_obj5.Height = 10 box_obj5.Width = 10 box_obj5.Length = 20 box_obj5.Placement.Base = (80, 0, 0) # make a CompSolid out of the boxes, to be able to remesh with GUI j = BOPTools.SplitFeatures.makeBooleanFragments(name="BooleanFragments") j.Objects = [box_obj1, box_obj2, box_obj3, box_obj4, box_obj5] j.Mode = "CompSolid" j.Proxy.execute(j) j.purgeTouched() doc.recompute() if FreeCAD.GuiUp: for obj in j.ViewObject.Proxy.claimChildren(): obj.ViewObject.hide() geom_obj = doc.addObject("Part::Feature", "CompSolid") geom_obj.Shape = j.Shape.CompSolids[0] if FreeCAD.GuiUp: j.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_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) # material material_obj1 = ObjectsFem.makeMaterialSolid(doc, "FemMaterial1") material_obj1.References = [(doc.Box3, "Solid1")] mat = material_obj1.Material mat["Name"] = "Concrete-Generic" mat["YoungsModulus"] = "32000 MPa" mat["PoissonRatio"] = "0.17" material_obj1.Material = mat analysis.addObject(material_obj1) material_obj2 = ObjectsFem.makeMaterialSolid(doc, "FemMaterial2") material_obj2.References = [(doc.Box2, "Solid1"), (doc.Box4, "Solid1")] mat = material_obj2.Material mat["Name"] = "PLA" mat["YoungsModulus"] = "3640 MPa" mat["PoissonRatio"] = "0.36" material_obj2.Material = mat analysis.addObject(material_obj2) material_obj3 = ObjectsFem.makeMaterialSolid(doc, "FemMaterial3") material_obj3.References = [] mat = material_obj3.Material mat["Name"] = "Steel-Generic" mat["YoungsModulus"] = "200000 MPa" mat["PoissonRatio"] = "0.30" material_obj3.Material = mat analysis.addObject(material_obj3) # constraint fixed con_fixed = ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed") con_fixed.References = [(doc.Box1, "Face1"), (doc.Box5, "Face2")] analysis.addObject(con_fixed) # constraint force con_force = ObjectsFem.makeConstraintForce(doc, "ConstraintForce") con_force.References = [(doc.Box1, "Face6"), (doc.Box2, "Face6"), (doc.Box3, "Face6"), (doc.Box4, "Face6"), (doc.Box5, "Face6")] con_force.Force = 10000.00 con_force.Direction = (doc.Box1, ["Edge1"]) con_force.Reversed = True analysis.addObject(con_force) # mesh from .meshes.mesh_multibodybeam_tetra10 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") 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"): # 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 v1 = vec(0, -2000, 0) v2 = vec(500, -2000, 0) v3 = vec(500, 0, 0) v4 = vec(3500, 0, 0) v5 = vec(3500, -2000, 0) v6 = vec(4000, -2000, 0) v7 = vec(4000, 2000, 0) v8 = vec(0, 2000, 0) l1 = ln(v1, v2) l2 = ln(v2, v3) l3 = ln(v3, v4) l4 = ln(v4, v5) l5 = ln(v5, v6) l6 = ln(v6, v7) l7 = ln(v7, v8) l8 = ln(v8, v1) geom_obj = doc.addObject("Part::Feature", "FIB_Wall") geom_obj.Shape = Part.Face(Part.Wire([l1, l2, l3, l4, l5, l6, l7, l8])) doc.recompute() if FreeCAD.GuiUp: geom_obj.ViewObject.Document.activeView().viewAxonometric() geom_obj.ViewObject.Document.activeView().fitAll() # analysis analysis = ObjectsFem.makeAnalysis(doc, "Analysis") # solver if solvertype == "calculix": solver_obj = ObjectsFem.makeSolverCalculix(doc, "SolverCalculiX") elif solvertype == "ccxtools": solver_obj = ObjectsFem.makeSolverCalculixCcxTools(doc, "CalculiXccxTools") solver_obj.WorkingDir = u"" else: FreeCAD.Console.PrintWarning( "Not known or not supported solver type: {}. " "No solver object was created.\n".format(solvertype) ) if solvertype == "calculix" or solvertype == "ccxtools": solver_obj.SplitInputWriter = False solver_obj.AnalysisType = "static" solver_obj.GeometricalNonlinearity = "linear" solver_obj.ThermoMechSteadyState = False solver_obj.MatrixSolverType = "default" solver_obj.IterationsControlParameterTimeUse = False analysis.addObject(solver_obj) # shell thickness thickness_obj = ObjectsFem.makeElementGeometry2D(doc, 150.0, "ShellThickness") analysis.addObject(thickness_obj) # material matrixprop = {} matrixprop["Name"] = "Concrete-EN-C35/45" matrixprop["YoungsModulus"] = "32000 MPa" matrixprop["PoissonRatio"] = "0.17" matrixprop["CompressiveStrength"] = "15.75 MPa" # make some hint on the possible angle units in material system matrixprop["AngleOfFriction"] = "30 deg" reinfoprop = {} reinfoprop["Name"] = "Reinforcement-FIB-B500" reinfoprop["YieldStrength"] = "315 MPa" # not an official FreeCAD material property reinfoprop["ReinforcementRatio"] = "0.0" material_reinforced = ObjectsFem.makeMaterialReinforced(doc, "MaterialReinforced") material_reinforced.Material = matrixprop material_reinforced.Reinforcement = reinfoprop analysis.addObject(material_reinforced) # constraint fixed con_fixed = ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed") con_fixed.References = [(geom_obj, "Edge1"), (geom_obj, "Edge5")] analysis.addObject(con_fixed) # constraint force con_force = ObjectsFem.makeConstraintForce(doc, "ConstraintForce") con_force.References = [(geom_obj, "Edge7")] con_force.Force = 1000000.0 con_force.Direction = (geom_obj, ["Edge8"]) con_force.Reversed = False analysis.addObject(con_force) # constraint displacement con_disp = ObjectsFem.makeConstraintDisplacement(doc, "ConstraintDisplacmentPrescribed") con_disp.References = [(geom_obj, "Face1")] con_disp.zFree = False con_disp.zFix = True analysis.addObject(con_disp) # mesh from .meshes.mesh_rc_wall_2d_tria6 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") femmesh_obj = analysis.addObject(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 make_femmesh(mesh_data): ''' makes an FreeCAD FEM Mesh object from FEM Mesh data ''' import Fem mesh = Fem.FemMesh() m = mesh_data if ('Nodes' in m) and (len(m['Nodes']) > 0): if (('Hexa8Elem' in m) or ('Penta6Elem' in m) or ('Tetra4Elem' in m) or ('Tetra10Elem' in m) or ('Penta6Elem' in m) or ('Hexa20Elem' in m) or ('Tria3Elem' in m) or ('Tria6Elem' in m) or ('Quad4Elem' in m) or ('Quad8Elem' in m) or ('Seg2Elem' in m)): nds = m['Nodes'] for i in nds: n = nds[i] mesh.addNode(n[0], n[1], n[2], i) elms_hexa8 = m['Hexa8Elem'] for i in elms_hexa8: e = elms_hexa8[i] mesh.addVolume( [e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7]], i) elms_penta6 = m['Penta6Elem'] for i in elms_penta6: e = elms_penta6[i] mesh.addVolume([e[0], e[1], e[2], e[3], e[4], e[5]], i) elms_tetra4 = m['Tetra4Elem'] for i in elms_tetra4: e = elms_tetra4[i] mesh.addVolume([e[0], e[1], e[2], e[3]], i) elms_tetra10 = m['Tetra10Elem'] for i in elms_tetra10: e = elms_tetra10[i] mesh.addVolume([ e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8], e[9] ], i) elms_penta15 = m['Penta15Elem'] for i in elms_penta15: e = elms_penta15[i] mesh.addVolume([ e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8], e[9], e[10], e[11], e[12], e[13], e[14] ], i) elms_hexa20 = m['Hexa20Elem'] for i in elms_hexa20: e = elms_hexa20[i] mesh.addVolume([ e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8], e[9], e[10], e[11], e[12], e[13], e[14], e[15], e[16], e[17], e[18], e[19] ], i) elms_tria3 = m['Tria3Elem'] for i in elms_tria3: e = elms_tria3[i] mesh.addFace([e[0], e[1], e[2]], i) elms_tria6 = m['Tria6Elem'] for i in elms_tria6: e = elms_tria6[i] mesh.addFace([e[0], e[1], e[2], e[3], e[4], e[5]], i) elms_quad4 = m['Quad4Elem'] for i in elms_quad4: e = elms_quad4[i] mesh.addFace([e[0], e[1], e[2], e[3]], i) elms_quad8 = m['Quad8Elem'] for i in elms_quad8: e = elms_quad8[i] mesh.addFace([e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7]], i) elms_seg2 = m['Seg2Elem'] for i in elms_seg2: e = elms_seg2[i] mesh.addEdge(e[0], e[1]) print( "imported mesh: {} nodes, {} HEXA8, {} PENTA6, {} TETRA4, {} TETRA10, {} PENTA15" .format(len(nds), len(elms_hexa8), len(elms_penta6), len(elms_tetra4), len(elms_tetra10), len(elms_penta15))) print( "imported mesh: {} HEXA20, {} TRIA3, {} TRIA6, {} QUAD4, {} QUAD8, {} SEG2" .format(len(elms_hexa20), len(elms_tria3), len(elms_tria6), len(elms_quad4), len(elms_quad8), len(elms_seg2))) else: FreeCAD.Console.PrintError("No Nodes found!\n") return mesh
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 objects bottom_flange = doc.addObject("Part::Plane", "Bottom_Flange") bottom_flange.Length = 10000 bottom_flange.Width = 150 top_flange = doc.addObject("Part::Plane", "Top_Flange") top_flange.Length = 10000 top_flange.Width = 150 top_flange.Placement.Base = (0, 0, 278.6) web = doc.addObject("Part::Plane", "Top_Flange") web.Length = 10000 web.Width = 278.6 web.Placement = FreeCAD.Placement( FreeCAD.Vector(0, 75, 0), FreeCAD.Rotation(0, 0, 90), FreeCAD.Vector(0, 0, 0), ) geom_obj = doc.addObject("Part::MultiFuse", "Fusion") geom_obj.Shapes = [bottom_flange, top_flange, web] 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.GeometricalNonlinearity = "linear" solver_obj.ThermoMechSteadyState = False solver_obj.MatrixSolverType = "default" solver_obj.IterationsControlParameterTimeUse = False solver_obj.BucklingFactors = 1 analysis.addObject(solver_obj) # shell thicknesses thickness_flanges = ObjectsFem.makeElementGeometry2D(doc, 10.7, 'Thickness_Flanges') thickness_flanges.References = [(geom_obj, ("Face1", "Face2", "Face3", "Face4"))] analysis.addObject(thickness_flanges) thickness_web = ObjectsFem.makeElementGeometry2D(doc, 7.1, 'Thickness_Web') thickness_web.References = [(geom_obj, "Face5")] analysis.addObject(thickness_web) # material material_obj = ObjectsFem.makeMaterialSolid(doc, "Steel") mat = material_obj.Material mat["Name"] = "CalculiX-Steel" mat["YoungsModulus"] = "210000 MPa" mat["PoissonRatio"] = "0.30" material_obj.Material = mat analysis.addObject(material_obj) # constraints displacement con_disp_x = ObjectsFem.makeConstraintDisplacement(doc, "ConstraintDisplacement_X") con_disp_x.References = [(geom_obj, "Vertex2")] con_disp_x.xFix = True con_disp_x.xFree = False analysis.addObject(con_disp_x) con_disp_yz = ObjectsFem.makeConstraintDisplacement(doc, "ConstraintDisplacement_YZ") con_disp_yz.References = [(geom_obj, ("Edge15", "Edge16"))] con_disp_yz.yFix = True con_disp_yz.yFree = False con_disp_yz.zFix = True con_disp_yz.zFree = False analysis.addObject(con_disp_yz) # constraints force con_force_in_x = ObjectsFem.makeConstraintForce(doc, "Force_in_X") con_force_in_x.References = [(geom_obj, ("Edge3", "Edge7", "Edge8", "Edge12"))] con_force_in_x.Force = 155350 con_force_in_x.Reversed = False con_force_in_x.Direction = (geom_obj, ["Edge4"]) analysis.addObject(con_force_in_x) con_force_rev_x = ObjectsFem.makeConstraintForce(doc, "Force_rev_X") con_force_rev_x.References = [(geom_obj, ("Edge1", "Edge5", "Edge10", "Edge14"))] con_force_rev_x.Force = 155350 con_force_rev_x.Reversed = True con_force_rev_x.Direction = (geom_obj, ["Edge4"]) analysis.addObject(con_force_rev_x) # mesh from .meshes.mesh_buckling_ibeam_tria6 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") 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 = "50.0 mm" femmesh_obj.ElementDimension = "2D" 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 plate = doc.addObject("Part::Plane", "Plate") plate.Width = 10 plate.Length = 10 force_pt1 = doc.addObject("Part::Vertex", "ForcePT1") force_pt1.X = 10 force_pt1.Y = 2 force_pt2 = doc.addObject("Part::Vertex", "ForcePT2") force_pt2.X = 10 force_pt2.Y = 4 force_pt3 = doc.addObject("Part::Vertex", "ForcePT3") force_pt3.X = 10 force_pt3.Y = 6 force_pt4 = doc.addObject("Part::Vertex", "ForcePT4") force_pt4.X = 10 force_pt4.Y = 8 doc.recompute() # all geom boolean fragment geom_obj = SplitFeatures.makeBooleanFragments(name='ThePointPlate') geom_obj.Objects = [plate, force_pt1, force_pt2, force_pt3, force_pt4] doc.recompute() if FreeCAD.GuiUp: plate.ViewObject.hide() force_pt1.ViewObject.hide() force_pt2.ViewObject.hide() force_pt3.ViewObject.hide() force_pt4.ViewObject.hide() doc.recompute() if FreeCAD.GuiUp: geom_obj.ViewObject.PointSize = 10 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 == "elmer": solver_obj = ObjectsFem.makeSolverElmer(doc, "SolverElmer") ObjectsFem.makeEquationElasticity(doc, solver_obj) elif solvertype == "mystran": solver_obj = ObjectsFem.makeSolverMystran(doc, "SolverMystran") elif solvertype == "z88": solver_obj = 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_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, 0.3, 'Thickness') analysis.addObject(thickness_obj) # material material_obj = ObjectsFem.makeMaterialSolid(doc, "FemMaterial") 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, "Edge1")] analysis.addObject(con_fixed) # constraint force con_force = ObjectsFem.makeConstraintForce(doc, "ConstraintForce") con_force.References = [ (geom_obj, "Vertex7"), (geom_obj, "Vertex1"), (geom_obj, "Vertex2"), (geom_obj, "Vertex3"), (geom_obj, "Vertex4"), (geom_obj, "Vertex8"), ] con_force.Force = 600 # 600 N on six nodes == 100 N/Node con_force.Reversed = False con_force.Direction = (geom_obj, ["Edge2"]) analysis.addObject(con_force) # mesh from .meshes.mesh_plate_mystran_quad4 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") 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 = "1.0 mm" femmesh_obj.ElementDimension = "2D" femmesh_obj.ElementOrder = "1st" doc.recompute() return doc
def setup(doc=None, solvertype="ccxtools"): # setup model if doc is None: doc = init_doc() # geometry objects # 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_obj = SplitFeatures.makeBooleanFragments(name='BooleanFragments') geom_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: geom_obj.ViewObject.Document.activeView().viewAxonometric() geom_obj.ViewObject.Document.activeView().fitAll() # analysis analysis = ObjectsFem.makeAnalysis(doc, "Analysis") # solver if solvertype == "calculix": solver_object = analysis.addObject( ObjectsFem.makeSolverCalculix(doc, "SolverCalculiX"))[0] elif solvertype == "ccxtools": solver_object = analysis.addObject( ObjectsFem.makeSolverCalculixCcxTools(doc, "CalculiXccxTools"))[0] solver_object.WorkingDir = u"" if solvertype == "calculix" or solvertype == "ccxtools": solver_object.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_obj, "Edge1")] # constraint force con_force = doc.Analysis.addObject( ObjectsFem.makeConstraintForce(doc, name="ConstraintForce"))[0] con_force.References = [(geom_obj, "Edge2")] con_force.Force = 10000.0 # 10000 N = 10 kN con_force.Direction = (geom_obj, ["Edge2"]) con_force.Reversed = False # constraint tie con_tie = doc.Analysis.addObject( ObjectsFem.makeConstraintTie(doc, name="ConstraintTie"))[0] con_tie.References = [ (geom_obj, "Face5"), (geom_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 importFrd(filename, Analysis=None): m = readResult(filename) result_set_number = len(m['Results']) MeshObject = None if(len(m) > 0): import Fem if Analysis is None: AnalysisName = os.path.splitext(os.path.basename(filename))[0] AnalysisObject = FreeCAD.ActiveDocument.addObject('Fem::FemAnalysis', 'Analysis') AnalysisObject.Label = AnalysisName else: AnalysisObject = Analysis if 'Nodes' in m: positions = [] for k, v in m['Nodes'].iteritems(): 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 ('Tet10Elem' in m) and ('Nodes' in m) and (not Analysis): mesh = Fem.FemMesh() nds = m['Nodes'] for i in nds: n = nds[i] mesh.addNode(n[0], n[1], n[2], i) elms = m['Tet10Elem'] for i in elms: e = elms[i] mesh.addVolume([e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8], e[9]], i) if len(nds) > 0: MeshObject = FreeCAD.ActiveDocument.addObject('Fem::FemMeshObject', 'ResultMesh') MeshObject.FemMesh = mesh AnalysisObject.Member = AnalysisObject.Member + [MeshObject] for result_set in m['Results']: eigenmode_number = result_set['number'] if result_set_number > 1: results_name = 'Mode_' + str(eigenmode_number) + '_results' else: results_name = 'Results' results = FreeCAD.ActiveDocument.addObject('Fem::FemResultObject', results_name) disp = result_set['disp'] l = len(disp) displacement = [] for k, v in disp.iteritems(): displacement.append(v) x_max, y_max, z_max = map(max, zip(*displacement)) if result_set_number > 1: max_disp = max(x_max, y_max, z_max) # Allow for max displacement to be 0.1% of the span # FIXME - add to Preferences max_allowed_disp = 0.001 * span scale = max_allowed_disp / max_disp else: scale = 1.0 if len(disp) > 0: results.DisplacementVectors = map((lambda x: x * scale), disp.values()) results.ElementNumbers = disp.keys() if(MeshObject): results.Mesh = MeshObject stress = result_set['stress'] if len(stress) > 0: mstress = [] for i in stress.values(): mstress.append(calculate_von_mises(i)) if result_set_number > 1: results.StressValues = map((lambda x: x * scale), mstress) else: results.StressValues = mstress if (results.ElementNumbers != 0 and results.ElementNumbers != stress.keys()): print ("Inconsistent FEM results: element number for Stress doesn't equal element number for Displacement {} != {}" .format(results.ElementNumbers, len(results.StressValues))) results.ElementNumbers = stress.keys() x_min, y_min, z_min = map(min, zip(*displacement)) sum_list = map(sum, zip(*displacement)) x_avg, y_avg, z_avg = [i / l for i in sum_list] s_max = max(results.StressValues) s_min = min(results.StressValues) s_avg = sum(results.StressValues) / l disp_abs = [] for d in displacement: disp_abs.append(sqrt(pow(d[0], 2) + pow(d[1], 2) + pow(d[2], 2))) results.DisplacementLengths = disp_abs a_max = max(disp_abs) a_min = min(disp_abs) a_avg = sum(disp_abs) / l results.Stats = [x_min, x_avg, x_max, y_min, y_avg, y_max, z_min, z_avg, z_max, a_min, a_avg, a_max, s_min, s_avg, s_max] AnalysisObject.Member = AnalysisObject.Member + [results] if(FreeCAD.GuiUp): import FemGui import FreeCADGui if FreeCADGui.activeWorkbench().name() != 'FemWorkbench': FreeCADGui.activateWorkbench("FemWorkbench") FemGui.setActiveAnalysis(AnalysisObject)
def importFrd(filename, analysis=None): m = readResult(filename) mesh_object = None if (len(m['Nodes']) > 0): import Fem if analysis is None: analysis_name = os.path.splitext(os.path.basename(filename))[0] import FemAnalysis analysis_object = FemAnalysis.makeFemAnalysis('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'].iteritems(): 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) and ('Nodes' in m) and \ (('Hexa8Elem' in m) or ('Penta6Elem' in m) or ('Tetra4Elem' in m) or ('Tetra10Elem' in m) or ('Penta6Elem' in m) or ('Hexa20Elem' in m) or ('Tria3Elem' in m) or ('Tria6Elem' in m) or ('Quad4Elem' in m) or ('Quad8Elem' in m) or ('Seg2Elem' in m)): mesh = Fem.FemMesh() nds = m['Nodes'] for i in nds: n = nds[i] mesh.addNode(n[0], n[1], n[2], i) elms_hexa8 = m['Hexa8Elem'] for i in elms_hexa8: e = elms_hexa8[i] mesh.addVolume( [e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7]], i) elms_penta6 = m['Penta6Elem'] for i in elms_penta6: e = elms_penta6[i] mesh.addVolume([e[0], e[1], e[2], e[3], e[4], e[5]], i) elms_tetra4 = m['Tetra4Elem'] for i in elms_tetra4: e = elms_tetra4[i] mesh.addVolume([e[0], e[1], e[2], e[3]], i) elms_tetra10 = m['Tetra10Elem'] for i in elms_tetra10: e = elms_tetra10[i] mesh.addVolume([ e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8], e[9] ], i) elms_penta15 = m['Penta15Elem'] for i in elms_penta15: e = elms_penta15[i] mesh.addVolume([ e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8], e[9], e[10], e[11], e[12], e[13], e[14] ], i) elms_hexa20 = m['Hexa20Elem'] for i in elms_hexa20: e = elms_hexa20[i] mesh.addVolume([ e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8], e[9], e[10], e[11], e[12], e[13], e[14], e[15], e[16], e[17], e[18], e[19] ], i) elms_tria3 = m['Tria3Elem'] for i in elms_tria3: e = elms_tria3[i] mesh.addFace([e[0], e[1], e[2]], i) elms_tria6 = m['Tria6Elem'] for i in elms_tria6: e = elms_tria6[i] mesh.addFace([e[0], e[1], e[2], e[3], e[4], e[5]], i) elms_quad4 = m['Quad4Elem'] for i in elms_quad4: e = elms_quad4[i] mesh.addFace([e[0], e[1], e[2], e[3]], i) elms_quad8 = m['Quad8Elem'] for i in elms_quad8: e = elms_quad8[i] mesh.addFace([e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7]], i) elms_seg2 = m['Seg2Elem'] for i in elms_seg2: e = elms_seg2[i] mesh.addEdge(e[0], e[1]) print( "imported mesh: {} nodes, {} HEXA8, {} PENTA6, {} TETRA4, {} TETRA10, {} PENTA15" .format(len(nds), len(elms_hexa8), len(elms_penta6), len(elms_tetra4), len(elms_tetra10), len(elms_penta15))) print( "imported mesh: {} HEXA20, {} TRIA3, {} TRIA6, {} QUAD4, {} QUAD8, {} SEG2" .format(len(elms_hexa20), len(elms_tria3), len(elms_tria6), len(elms_quad4), len(elms_quad8), len(elms_seg2))) if len(nds) > 0: mesh_object = FreeCAD.ActiveDocument.addObject( 'Fem::FemMeshObject', 'ResultMesh') mesh_object.FemMesh = mesh analysis_object.Member = analysis_object.Member + [mesh_object] for result_set in m['Results']: eigenmode_number = result_set['number'] if eigenmode_number > 0: results_name = 'Mode_' + str(eigenmode_number) + '_results' else: results_name = 'Results' results = FreeCAD.ActiveDocument.addObject('Fem::FemResultObject', results_name) for m in analysis_object.Member: if m.isDerivedFrom("Fem::FemMeshObject"): results.Mesh = m break disp = result_set['disp'] l = len(disp) displacement = [] for k, v in disp.iteritems(): displacement.append(v) x_max, y_max, z_max = map(max, zip(*displacement)) if eigenmode_number > 0: max_disp = max(x_max, y_max, z_max) # Allow for max displacement to be 0.1% of the span # FIXME - add to Preferences max_allowed_disp = 0.001 * span scale = max_allowed_disp / max_disp else: scale = 1.0 if len(disp) > 0: results.DisplacementVectors = map((lambda x: x * scale), disp.values()) results.NodeNumbers = disp.keys() if (mesh_object): results.Mesh = mesh_object stress = result_set['stress'] if len(stress) > 0: mstress = [] for i in stress.values(): mstress.append(calculate_von_mises(i)) if eigenmode_number > 0: results.StressValues = map((lambda x: x * scale), mstress) results.Eigenmode = eigenmode_number results.setEditorMode("Eigenmode", 1) else: results.StressValues = mstress if (results.NodeNumbers != 0 and results.NodeNumbers != stress.keys()): print( "Inconsistent FEM results: element number for Stress doesn't equal element number for Displacement {} != {}" .format(results.NodeNumbers, len(results.StressValues))) results.NodeNumbers = stress.keys() x_min, y_min, z_min = map(min, zip(*displacement)) sum_list = map(sum, zip(*displacement)) x_avg, y_avg, z_avg = [i / l for i in sum_list] s_max = max(results.StressValues) s_min = min(results.StressValues) s_avg = sum(results.StressValues) / l disp_abs = [] for d in displacement: disp_abs.append( sqrt(pow(d[0], 2) + pow(d[1], 2) + pow(d[2], 2))) results.DisplacementLengths = disp_abs a_max = max(disp_abs) a_min = min(disp_abs) a_avg = sum(disp_abs) / l results.Stats = [ x_min, x_avg, x_max, y_min, y_avg, y_max, z_min, z_avg, z_max, a_min, a_avg, a_max, s_min, s_avg, s_max ] analysis_object.Member = analysis_object.Member + [results] if (FreeCAD.GuiUp): import FemGui FemGui.setActiveAnalysis(analysis_object)
def setup_rcwall2d(doc=None, solver='ccxtools'): # setup reinfoced wall in 2D if doc is None: doc = init_doc() # part from FreeCAD import Vector as vec import Part from Part import makeLine as ln v1 = vec(0, -2000, 0) v2 = vec(500, -2000, 0) v3 = vec(500, 0, 0) v4 = vec(3500, 0, 0) v5 = vec(3500, -2000, 0) v6 = vec(4000, -2000, 0) v7 = vec(4000, 2000, 0) v8 = vec(0, 2000, 0) l1 = ln(v1, v2) l2 = ln(v2, v3) l3 = ln(v3, v4) l4 = ln(v4, v5) l5 = ln(v5, v6) l6 = ln(v6, v7) l7 = ln(v7, v8) l8 = ln(v8, v1) rcwall = doc.addObject("Part::Feature", "FIB_Wall") rcwall.Shape = Part.Face(Part.Wire([l1, l2, l3, l4, l5, l6, l7, l8])) # 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 = analysis.addObject( ObjectsFem.makeSolverCalculix(doc, 'SolverCalculiX'))[0] solver.AnalysisType = 'static' solver.GeometricalNonlinearity = 'linear' solver.ThermoMechSteadyState = False solver.MatrixSolverType = 'default' solver.IterationsControlParameterTimeUse = False elif solver is 'ccxtools': solver = analysis.addObject( ObjectsFem.makeSolverCalculixCcxTools(doc, 'CalculiXccxTools'))[0] solver.AnalysisType = 'static' solver.GeometricalNonlinearity = 'linear' solver.ThermoMechSteadyState = False solver.MatrixSolverType = 'default' solver.IterationsControlParameterTimeUse = False solver.WorkingDir = u'' # shell thickness thickness = analysis.addObject( ObjectsFem.makeElementGeometry2D(doc, 0, 'ShellThickness'))[0] thickness.Thickness = 150.0 # material matrixprop = {} matrixprop['Name'] = "Concrete-EN-C35/45" matrixprop['YoungsModulus'] = "32000 MPa" matrixprop['PoissonRatio'] = "0.17" matrixprop['CompressiveStrength'] = "15.75 MPa" # make some hint on the possible angle units in material system matrixprop['AngleOfFriction'] = "30 deg" matrixprop['Density'] = '2500 kg/m^3' reinfoprop = {} reinfoprop['Name'] = "Reinforcement-FIB-B500" reinfoprop['YieldStrength'] = "315 MPa" # not an official FreeCAD material property reinfoprop['ReinforcementRatio'] = "0.0" material_reinforced = analysis.addObject( ObjectsFem.makeMaterialReinforced(doc, 'MaterialReinforced'))[0] material_reinforced.Material = matrixprop material_reinforced.Reinforcement = reinfoprop # fixed_constraint fixed_constraint = analysis.addObject( ObjectsFem.makeConstraintFixed(doc, name="ConstraintFixed"))[0] fixed_constraint.References = [(rcwall, "Edge1"), (rcwall, "Edge5")] # force constraint force_constraint = doc.Analysis.addObject( ObjectsFem.makeConstraintForce(doc, name="ConstraintForce"))[0] force_constraint.References = [(rcwall, "Edge7")] force_constraint.Force = 1000000.0 force_constraint.Direction = (rcwall, ["Edge8"]) force_constraint.Reversed = False # displacement_constraint displacement_constraint = doc.Analysis.addObject( ObjectsFem.makeConstraintDisplacement( doc, name="ConstraintDisplacmentPrescribed"))[0] displacement_constraint.References = [(rcwall, "Face1")] displacement_constraint.zFix = True # mesh from femexamples.meshes.mesh_rc_wall_2d_tria6 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 Activated(self): import ObjectsFem isMystran = 1 ininame = "Mod/hfcMystran/hfcMystran.ini" inifile = FreeCAD.getHomePath() + ininame if os.path.exists(inifile): iniF = open(inifile, "r") path = iniF.readline() iniF.close() else: path = FreeCAD.getHomePath() try: fName = QFileDialog.getOpenFileName( None, QString.fromLocal8Bit("Read a Mystarn's Dat/bdf file"), path, "*.Dat *.bdf") # PyQt4 except Exception: fName, Filter = PySide.QtGui.QFileDialog.getOpenFileName( None, "Read a Mystran's Dat/bdf file", path, "*.Dat *.bdf") #PySide print("src: " + fName) DesName = FreeCAD.getHomePath() + "bin/hfcMystran.Dat" print("Des: " + DesName) shutil.copyfile(fName, DesName) data = fName.split("/") n = len(data) path = "" for i in range(n - 1): path = path + data[i] + "/" inifileOut = FreeCAD.getHomePath() + ininame iniFout = open(inifileOut, "w") iniFout.writelines(path) iniFout.close() #print (path) iHfc = FreeCAD.ActiveDocument.getObject('hfc') if iHfc == None: iHfc = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", 'hfc') hfc(iHfc) #iHfc.ViewObject.Proxy=0 #ViewProviderCFG(iHfc.ViewObject) iHfc.DatPath = path iHfc.DatFile = fName numNode = 0 numMember = 0 nodes_x = [] nodes_y = [] nodes_z = [] NodeList = {} MemberList = {} DisplacementList = {} NodeEndList = {} MemberEndList = {} ProjectDescription = '' nodes = {} results = [] mode_results = {} mode_disp = {} iFilled = [] mode_disp_x = [] mode_disp_y = [] mode_disp_z = [] nDisp = 0 mDisp = 0 isDebug = 1 #factor = 25.42 factor = 1 factorZoom = 100 #000000000000000000000000000000000000000000000000000000000000000000 fpDat = open(fName) tline = [] for line in fpDat: aline = line.strip() if len(aline) == 0 or aline[0] == '$': continue else: tline.append(line.strip()) fpDat.close() for id in range(len(tline)): aline = tline[id].strip() data = aline.split() data1 = aline.split(",") #print (data) # Node 22222222222222222222222222222222222222222222222222222222222222222222 if data[0] == 'GRID': # gid cp x1 #GRID 10101 0 0.000 0.000 0.000 0 gid = aline[8:16].strip() #cid1=aline[16:24].strip() x = aline[24:32].strip() y = aline[32:40].strip() z = aline[40:48].strip() NodeList[gid] = Node(gid, float(x), float(y), float(z)) numNode = numNode + 1 if data[0] == 'GRID*': #GRID* 1 0.00000E+00 0.00000E+00 gid = aline[8:24].strip() #cid1=aline[24:40].strip() x = aline[40:56].strip() y = aline[56:72].strip() bline = tline[id + 1].strip() z = bline[8:24].strip() NodeList[gid] = Node(gid, float(x), float(y), float(z)) numNode = numNode + 1 # Member 33333333333333333333333333333333333333333333333333333333333333333333333333333333333333 #CBAR 201 2 11 21 0.0 0.0 1.0 if data[0] == 'CBAR': MemberList[data[1].strip()] = MemberCBAR( data[1].strip(), data[3], data[4], data[0].strip()) numMember += 1 #CBEAM 9400 9401 9401 9402 0. 0. 1. if data[0] == 'CBEAM': MemberList[data[1].strip()] = MemberCBEAM( data[1].strip(), data[3], data[4], data[0].strip()) numMember += 1 #CROD, 418,418,8,3 if data[0] == 'CROD': MemberList[data[1].strip()] = MemberCROD( data[1].strip(), data[3], data[4], data[0].strip()) numMember += 1 #CROD, 418,418,8,3 if data1[0] == 'CROD': MemberList[data1[1].strip()] = MemberCROD( data1[1].strip(), data1[3], data1[4], data1[0].strip()) numMember += 1 #CTRIA3 24 91 1033 1032 1023 if data[0] == 'CTRIA3': MemberList[data[1].strip()] = MemberCTRIA3( data[1].strip(), data[3], data[4], data[5], data[0].strip()) numMember += 1 #CQUAD4 1001 1 1001 1002 2002 2001 if data[0] == 'CQUAD4': MemberList[data[1].strip()] = MemberCQUAD4( data[1].strip(), data[3], data[4], data[5], data[6], data[0].strip()) numMember += 1 #CQUAD8 16004 1 16007 16009 18009 18007 16008 17009 #18008 17007 if data[0] == 'CQUAD8': MemberList[data[1].strip()] = MemberCQUAD8( data[1].strip(), data[3], data[4], data[5], data[6], data[0].strip()) numMember += 1 #CTETRA 1 1 8 13 67 33 if data[0] == 'CTETRA': MemberList[data[1].strip()] = MemberCQUAD4( data[1].strip(), data[3], data[4], data[5], data[6], data[0].strip()) numMember += 1 # #CHEXA 10101 100 10101 10103 10303 10301 30101 30103+E 1 #+E 1 30303 30301 if data[0] == 'CHEXA': bline = tline[id + 1].strip() if len(aline) == 80: eid = aline[9:16].strip() pid = aline[17:24].strip() g1 = aline[25:32].strip() g2 = aline[33:40].strip() g3 = aline[41:48].strip() g4 = aline[49:56].strip() g5 = aline[57:64].strip() g6 = aline[65:72].strip() if aline[73:80] == bline[1:8]: g7 = bline[9:16].strip() g8 = bline[17:24].strip() #print (eid+" "+g1+" "+g2+" "+g3+" "+g4+" "+g5+" "+g6+" "+g7+" "+g8) MemberList[eid] = MemberCHEXA(eid, g1, g2, g3, g4, g5, g6, g7, g8, data[0].strip()) numMember += 1 #print (NodeList) #print (MemberList) print('numNode = ' + str(numNode)) print('numMember = ' + str(numMember)) #for id in NodeList: # print (NodeList[id].id+" "+str(NodeList[id].x)+" "+str(NodeList[id].y)+" "+str(NodeList[id].z)) femmesh = Fem.FemMesh() # nodes #print ("Add nodes") for id in NodeList: # node #femmesh.addNode(NodeList[id].x,NodeList[id].y,NodeList[id].z, int(id)+1 ) femmesh.addNode(NodeList[id].x, NodeList[id].y, NodeList[id].z, int(id)) for id in MemberList: mtype = MemberList[id].mtype if mtype == 'CROD': n1 = int(MemberList[id].n1) n2 = int(MemberList[id].n2) femmesh.addEdge([n1, n2]) elif mtype == 'CBAR': n1 = int(MemberList[id].n1) n2 = int(MemberList[id].n2) femmesh.addEdge([n1, n2]) elif mtype == 'CBEAM': n1 = int(MemberList[id].n1) n2 = int(MemberList[id].n2) femmesh.addEdge([n1, n2]) elif mtype == 'CTRIA3': n1 = int(MemberList[id].n1) n2 = int(MemberList[id].n2) n3 = int(MemberList[id].n3) femmesh.addEdge([n1, n2]) femmesh.addEdge([n2, n3]) femmesh.addEdge([n3, n1]) #femmesh.addFace([n1,n2,n3]) elif mtype == 'CQUAD4': n1 = int(MemberList[id].n1) n2 = int(MemberList[id].n2) n3 = int(MemberList[id].n3) n4 = int(MemberList[id].n4) #print (str(n1)+" "+str(n2)+" "+str(n3)+" "+str(n4)) femmesh.addEdge([n1, n2]) femmesh.addEdge([n2, n3]) femmesh.addEdge([n3, n4]) femmesh.addEdge([n4, n1]) #femmesh.addFace([n1,n2,n3,n4]) elif mtype == 'CQUAD8': n1 = int(MemberList[id].n1) n2 = int(MemberList[id].n2) n3 = int(MemberList[id].n3) n4 = int(MemberList[id].n4) femmesh.addEdge([n1, n2]) femmesh.addEdge([n2, n3]) femmesh.addEdge([n3, n4]) femmesh.addEdge([n4, n1]) #femmesh.addFace([n1,n2,n3,n4]) elif mtype == 'CTETRA': n1 = int(MemberList[id].n1) n2 = int(MemberList[id].n2) n3 = int(MemberList[id].n3) n4 = int(MemberList[id].n4) femmesh.addEdge([n1, n2]) femmesh.addEdge([n2, n3]) femmesh.addEdge([n3, n4]) femmesh.addEdge([n4, n1]) #femmesh.addVolume([n1,n2,n3,n4]) elif mtype == 'CHEXA': n1 = int(MemberList[id].n1) n2 = int(MemberList[id].n2) n3 = int(MemberList[id].n3) n4 = int(MemberList[id].n4) n5 = int(MemberList[id].n5) n6 = int(MemberList[id].n6) n7 = int(MemberList[id].n7) n8 = int(MemberList[id].n8) femmesh.addEdge([n1, n2]) femmesh.addEdge([n2, n3]) femmesh.addEdge([n3, n4]) femmesh.addEdge([n4, n1]) femmesh.addEdge([n5, n6]) femmesh.addEdge([n6, n7]) femmesh.addEdge([n7, n8]) femmesh.addEdge([n8, n5]) femmesh.addEdge([n1, n5]) femmesh.addEdge([n2, n6]) femmesh.addEdge([n3, n7]) femmesh.addEdge([n4, n8]) #femmesh.addVolume([n1,n2,n3,n4,n5,n6,n7,n8]) else: print(mtype + ' Not supported yet') result_mesh_object = None result_mesh_object = ObjectsFem.makeMeshResult(FreeCAD.ActiveDocument, "hfcMesh") result_mesh_object.FemMesh = femmesh FreeCAD.ActiveDocument.recompute() FreeCADGui.activeDocument().activeView().viewAxonometric() FreeCADGui.SendMsgToActiveView("ViewFit") print('Input done.') print('')
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 objects # 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_obj = SplitFeatures.makeBooleanFragments(name="BooleanFragments") geom_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: 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.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) # 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, "Edge1")] analysis.addObject(con_fixed) # constraint force con_force = ObjectsFem.makeConstraintForce(doc, "ConstraintForce") con_force.References = [(geom_obj, "Edge2")] con_force.Force = 10000.0 # 10000 N = 10 kN con_force.Direction = (geom_obj, ["Edge2"]) con_force.Reversed = False analysis.addObject(con_force) # constraint tie con_tie = ObjectsFem.makeConstraintTie(doc, "ConstraintTie") con_tie.References = [ (geom_obj, "Face5"), (geom_obj, "Face7"), ] con_tie.Tolerance = 25.0 analysis.addObject(con_tie) # 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(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 setup(doc=None, solvertype="ccxtools"): # setup reinfoced wall in 2D if doc is None: doc = init_doc() # geom objects v1 = vec(0, -2000, 0) v2 = vec(500, -2000, 0) v3 = vec(500, 0, 0) v4 = vec(3500, 0, 0) v5 = vec(3500, -2000, 0) v6 = vec(4000, -2000, 0) v7 = vec(4000, 2000, 0) v8 = vec(0, 2000, 0) l1 = ln(v1, v2) l2 = ln(v2, v3) l3 = ln(v3, v4) l4 = ln(v4, v5) l5 = ln(v5, v6) l6 = ln(v6, v7) l7 = ln(v7, v8) l8 = ln(v8, v1) geom_obj = doc.addObject("Part::Feature", "FIB_Wall") geom_obj.Shape = Part.Face(Part.Wire([l1, l2, l3, l4, l5, l6, l7, l8])) 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 # shell thickness thickness = analysis.addObject( ObjectsFem.makeElementGeometry2D(doc, 0, "ShellThickness"))[0] thickness.Thickness = 150.0 # material matrixprop = {} matrixprop["Name"] = "Concrete-EN-C35/45" matrixprop["YoungsModulus"] = "32000 MPa" matrixprop["PoissonRatio"] = "0.17" matrixprop["CompressiveStrength"] = "15.75 MPa" # make some hint on the possible angle units in material system matrixprop["AngleOfFriction"] = "30 deg" matrixprop["Density"] = "2500 kg/m^3" reinfoprop = {} reinfoprop["Name"] = "Reinforcement-FIB-B500" reinfoprop["YieldStrength"] = "315 MPa" # not an official FreeCAD material property reinfoprop["ReinforcementRatio"] = "0.0" material_reinforced = analysis.addObject( ObjectsFem.makeMaterialReinforced(doc, "MaterialReinforced"))[0] material_reinforced.Material = matrixprop material_reinforced.Reinforcement = reinfoprop # fixed_constraint fixed_constraint = analysis.addObject( ObjectsFem.makeConstraintFixed(doc, name="ConstraintFixed"))[0] fixed_constraint.References = [(geom_obj, "Edge1"), (geom_obj, "Edge5")] # force constraint force_constraint = doc.Analysis.addObject( ObjectsFem.makeConstraintForce(doc, name="ConstraintForce"))[0] force_constraint.References = [(geom_obj, "Edge7")] force_constraint.Force = 1000000.0 force_constraint.Direction = (geom_obj, ["Edge8"]) force_constraint.Reversed = False # displacement_constraint displacement_constraint = doc.Analysis.addObject( ObjectsFem.makeConstraintDisplacement( doc, name="ConstraintDisplacmentPrescribed"))[0] displacement_constraint.References = [(geom_obj, "Face1")] displacement_constraint.zFix = True # mesh from .meshes.mesh_rc_wall_2d_tria6 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") femmesh_obj = analysis.addObject(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_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('Analysis') self.assertTrue(analysis, "FemTest of new analysis failed") fcc_print('Checking FEM new solver...') solver_object = ObjectsFem.makeSolverCalculix('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.Member = analysis.Member + [solver_object] fcc_print('Checking FEM new material...') new_material_object = ObjectsFem.makeMaterialFluid('FluidMaterial') mat = new_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" 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 Flow1D inlet constraint...') Flow1d_inlet = self.active_doc.addObject("Fem::FeaturePython", "ElementFluid1D") import PyObjects._FemElementFluid1D PyObjects._FemElementFluid1D._FemElementFluid1D(Flow1d_inlet) 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.Member = analysis.Member + [Flow1d_inlet] fcc_print('Checking FEM new Flow1D entrance constraint...') Flow1d_entrance = self.active_doc.addObject("Fem::FeaturePython", "ElementFluid1D") import PyObjects._FemElementFluid1D PyObjects._FemElementFluid1D._FemElementFluid1D(Flow1d_entrance) 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.Member = analysis.Member + [Flow1d_entrance] fcc_print('Checking FEM new Flow1D manning constraint...') Flow1d_manning = self.active_doc.addObject("Fem::FeaturePython", "ElementFluid1D") import PyObjects._FemElementFluid1D PyObjects._FemElementFluid1D._FemElementFluid1D(Flow1d_manning) 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.Member = analysis.Member + [Flow1d_manning] fcc_print('Checking FEM new Flow1D bend constraint...') Flow1d_bend = self.active_doc.addObject("Fem::FeaturePython", "ElementFluid1D") import PyObjects._FemElementFluid1D PyObjects._FemElementFluid1D._FemElementFluid1D(Flow1d_bend) 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.Member = analysis.Member + [Flow1d_bend] fcc_print('Checking FEM new Flow1D enlargement constraint...') Flow1d_enlargement = self.active_doc.addObject("Fem::FeaturePython", "ElementFluid1D") import PyObjects._FemElementFluid1D PyObjects._FemElementFluid1D._FemElementFluid1D(Flow1d_enlargement) 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.Member = analysis.Member + [Flow1d_enlargement] fcc_print('Checking FEM new Flow1D manning constraint...') Flow1d_manning1 = self.active_doc.addObject("Fem::FeaturePython", "ElementFluid1D") import PyObjects._FemElementFluid1D PyObjects._FemElementFluid1D._FemElementFluid1D(Flow1d_manning1) 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.Member = analysis.Member + [Flow1d_manning1] fcc_print('Checking FEM new Flow1D contraction constraint...') Flow1d_contraction = self.active_doc.addObject("Fem::FeaturePython", "ElementFluid1D") import PyObjects._FemElementFluid1D PyObjects._FemElementFluid1D._FemElementFluid1D(Flow1d_contraction) 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.Member = analysis.Member + [Flow1d_contraction] fcc_print('Checking FEM new Flow1D manning constraint...') Flow1d_manning2 = self.active_doc.addObject("Fem::FeaturePython", "ElementFluid1D") import PyObjects._FemElementFluid1D PyObjects._FemElementFluid1D._FemElementFluid1D(Flow1d_manning2) 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.Member = analysis.Member + [Flow1d_manning2] fcc_print('Checking FEM new Flow1D gate valve constraint...') Flow1d_gate_valve = self.active_doc.addObject("Fem::FeaturePython", "ElementFluid1D") import PyObjects._FemElementFluid1D PyObjects._FemElementFluid1D._FemElementFluid1D(Flow1d_gate_valve) 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.Member = analysis.Member + [Flow1d_gate_valve] fcc_print('Checking FEM new Flow1D enlargement constraint...') Flow1d_enlargement1 = self.active_doc.addObject("Fem::FeaturePython", "ElementFluid1D") import PyObjects._FemElementFluid1D PyObjects._FemElementFluid1D._FemElementFluid1D(Flow1d_enlargement1) 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.Member = analysis.Member + [Flow1d_enlargement1] fcc_print('Checking FEM Flow1D outlet constraint...') Flow1d_outlet = self.active_doc.addObject("Fem::FeaturePython", "ElementFluid1D") import PyObjects._FemElementFluid1D PyObjects._FemElementFluid1D._FemElementFluid1D(Flow1d_outlet) 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.Member = analysis.Member + [Flow1d_outlet] fcc_print('Checking FEM self weight constraint...') Flow1d_self_weight = self.active_doc.addObject("Fem::FeaturePython", "ConstraintSelfWeight") import PyObjects._FemConstraintSelfWeight PyObjects._FemConstraintSelfWeight._FemConstraintSelfWeight(Flow1d_self_weight) 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.Member = analysis.Member + [Flow1d_self_weight] fcc_print('Checking FEM new mesh...') from test_files.ccx.Flow1D_mesh import create_nodes_Flow1D, 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', 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, 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('Setting analysis type to \'thermomech\"') fea.set_analysis_type("thermomech") self.assertTrue(True if fea.analysis_type == 'thermomech' else False, "Setting anlysis type to \'thermomech\' failed") fcc_print('Checking FEM inp file prerequisites for thermo-mechanical 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('Writing {}/{}.inp for thermomech analysis'.format(Flow1D_thermomech_analysis_dir, mesh_name)) error = fea.write_inp_file() self.assertFalse(error, "Writing failed") fcc_print('Comparing {} to {}/{}.inp'.format(Flow1D_thermomech_analysis_inp_file, Flow1D_thermomech_analysis_dir, mesh_name)) ret = compare_inp_files(Flow1D_thermomech_analysis_inp_file, Flow1D_thermomech_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('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...') ret = compare_stats(fea, Flow1D_thermomech_expected_values, ["U1", "U2", "U3", "Uabs", "Sabs"]) # TODO use all result stats self.assertFalse(ret, "Invalid results read from .frd file") 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 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 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_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 solver_obj.GeometricalNonlinearity = 'nonlinear' solver_obj.MaterialNonlinearity = 'nonlinear' analysis.addObject(solver_obj) # linear material material_obj = ObjectsFem.makeMaterialSolid(doc, "Material_lin") matprop = material_obj.Material matprop["Name"] = "CalculiX-Steel" matprop["YoungsModulus"] = "210000 MPa" matprop["PoissonRatio"] = "0.30" material_obj.Material = matprop analysis.addObject(material_obj) # nonlinear material name_nlm = "Material_nonlin" nonlinear_mat = ObjectsFem.makeMaterialMechanicalNonlinear( doc, material_obj, name_nlm) nonlinear_mat.YieldPoint1 = '240.0, 0.0' nonlinear_mat.YieldPoint2 = '270.0, 0.025' analysis.addObject(nonlinear_mat) # check solver attributes, Nonlinearity needs to be set to nonlinear # constraint fixed con_fixed = ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed") con_fixed.References = [(geom_obj, "Face4")] analysis.addObject(con_fixed) # pressure constraint con_pressure = ObjectsFem.makeConstraintPressure(doc, "ConstraintPressure") con_pressure.References = [(geom_obj, "Face2")] con_pressure.Pressure = 130.0 con_pressure.Reversed = True analysis.addObject(con_pressure) # 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, 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"): # 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 # 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_obj = ObjectsFem.makeSolverCalculix(doc, "SolverCalculiX") elif solvertype == "ccxtools": solver_obj = ObjectsFem.makeSolverCalculixCcxTools( doc, "CalculiXccxTools") solver_obj.WorkingDir = u"" elif solvertype == "elmer": solver_obj = analysis.addObject( ObjectsFem.makeSolverElmer(doc, "SolverElmer"))[0] solver_obj.SteadyStateMinIterations = 1 solver_obj.SteadyStateMaxIterations = 10 eq_heat = ObjectsFem.makeEquationHeat(doc, solver_obj) eq_heat.Bubbles = True eq_heat.Priority = 2 eq_elasticity = ObjectsFem.makeEquationElasticity(doc, solver_obj) 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_obj.AnalysisType = "thermomech" solver_obj.GeometricalNonlinearity = "linear" solver_obj.ThermoMechSteadyState = True # solver_obj.MatrixSolverType = "default" solver_obj.MatrixSolverType = "spooles" # thomas solver_obj.SplitInputWriter = False solver_obj.IterationsThermoMechMaximum = 2000 # solver_obj.IterationsControlParameterTimeUse = True # thermomech spine analysis.addObject(solver_obj) # material material_obj_bottom = ObjectsFem.makeMaterialSolid(doc, "MaterialCopper") 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 = ObjectsFem.makeMaterialSolid(doc, "MaterialInvar") 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 = ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed") con_fixed.References = [ (geom_obj, "Face1"), (geom_obj, "Face7"), ] analysis.addObject(con_fixed) # constraint initial temperature con_inittemp = ObjectsFem.makeConstraintInitialTemperature( doc, "ConstraintInitialTemperature") con_inittemp.initialTemperature = 273.0 analysis.addObject(con_inittemp) # constraint temperature con_temp = ObjectsFem.makeConstraintTemperature(doc, "ConstraintTemperature") con_temp.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"), ] con_temp.Temperature = 373.0 con_temp.CFlux = 0.0 analysis.addObject(con_temp) # mesh from .meshes.mesh_thermomech_bimetall_tetra10 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: 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"): # 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 # two boxes boxlow = doc.addObject("Part::Box", "BoxLower") boxupp = doc.addObject("Part::Box", "BoxUpper") boxupp.Placement.Base = (0, 0, 10) # boolean fragment of the two boxes bf = SplitFeatures.makeBooleanFragments(name="BooleanFragments") bf.Objects = [boxlow, boxupp] bf.Mode = "CompSolid" doc.recompute() bf.Proxy.execute(bf) bf.purgeTouched() doc.recompute() if FreeCAD.GuiUp: for child in bf.ViewObject.Proxy.claimChildren(): child.ViewObject.hide() # extract CompSolid by compound filter tool geom_obj = CompoundFilter.makeCompoundFilter(name="MultiMatCompSolid") geom_obj.Base = bf geom_obj.FilterType = "window-volume" geom_obj.Proxy.execute(geom_obj) geom_obj.purgeTouched() if FreeCAD.GuiUp: bf.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_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) # materials material_obj_low = ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterialLow") mat = material_obj_low.Material mat["Name"] = "Aluminium-Generic" mat["YoungsModulus"] = "70000 MPa" mat["PoissonRatio"] = "0.35" mat["Density"] = "2700 kg/m^3" material_obj_low.Material = mat material_obj_low.References = [(boxlow, "Solid1")] analysis.addObject(material_obj_low) material_obj_upp = ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterialUpp") mat = material_obj_upp.Material mat["Name"] = "Steel-Generic" mat["YoungsModulus"] = "200000 MPa" mat["PoissonRatio"] = "0.30" mat["Density"] = "7980 kg/m^3" material_obj_upp.Material = mat material_obj_upp.References = [(boxupp, "Solid1")] analysis.addObject(material_obj_upp) # constraint fixed con_fixed = ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed") con_fixed.References = [(geom_obj, "Face5")] analysis.addObject(con_fixed) # constraint pressure con_pressure = ObjectsFem.makeConstraintPressure(doc, "ConstraintPressure") con_pressure.References = [(geom_obj, "Face11")] con_pressure.Pressure = 1000.0 con_pressure.Reversed = False analysis.addObject(con_pressure) # mesh from .meshes.mesh_boxes_2_vertikal_tetra10 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, 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, solver="ccxtools"): # setup model if doc is None: doc = init_doc() 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 ] from Draft import makeWire line = makeWire( points, closed=False, face=False, support=None ) doc.recompute() if FreeCAD.GuiUp: import FreeCADGui FreeCADGui.ActiveDocument.activeView().viewAxonometric() FreeCADGui.SendMsgToActiveView("ViewFit") # analysis analysis = ObjectsFem.makeAnalysis(doc, "Analysis") # solver # TODO How to pass multiple solver for one analysis in one doc if solver == "calculix": solver_object = analysis.addObject( ObjectsFem.makeSolverCalculix(doc, "SolverCalculiX") )[0] elif solver == "ccxtools": solver_object = analysis.addObject( ObjectsFem.makeSolverCalculixCcxTools(doc, "CalculiXccxTools") # CalculiX )[0] solver_object.WorkingDir = u"" if solver == "calculix" or solver == "ccxtools": 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 = [(line, "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 = [(line, "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 = [(line, "Edge3"), (line, "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 = [(line, "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 = [(line, "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 = [(line, "Edge7")] contraction = analysis.addObject( ObjectsFem.makeElementFluid1D(doc, "ElementFluid1D") )[0] contraction.SectionType = "Liquid" contraction.LiquidSectionType = "PIPE CONTRACTION" contraction.ContractArea1 = 70686 contraction.ContractArea2 = 17671 contraction.References = [(line, "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 = [(line, "Edge11"), (line, "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 = [(line, "Edge10")] enlargement2 = analysis.addObject( ObjectsFem.makeElementFluid1D(doc, "ElementFluid1D") )[0] enlargement2.SectionType = "Liquid" enlargement2.LiquidSectionType = "PIPE ENLARGEMENT" enlargement2.EnlargeArea1 = 17671 enlargement2.EnlargeArea2 = 1e12 enlargement2.References = [(line, "Edge12")] outlet = analysis.addObject( ObjectsFem.makeElementFluid1D(doc, "ElementFluid1D") )[0] outlet.SectionType = "Liquid" outlet.LiquidSectionType = "PIPE OUTLET" outlet.OutletPressure = 0.1 outlet.References = [(line, "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 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") femmesh_obj = analysis.addObject( doc.addObject("Fem::FemMeshObject", mesh_name) )[0] femmesh_obj.FemMesh = fem_mesh doc.recompute() return doc
def setup(doc=None, solvertype="ccxtools"): if doc is None: doc = init_doc() # geometry object # the part sketch arc_sketch = doc.addObject('Sketcher::SketchObject', 'Arc_Sketch') arc_sketch.Placement = FreeCAD.Placement(Vector(0, 0, 0), Rotation(0, 0, 0, 1)) arc_sketch.MapMode = "Deactivated" # not the exact geometry which makes a closed wire # exact geometry will be made by the constraints # the order is important for the constraints definition geoList = [ Part.ArcOfCircle(Part.Circle(Vector(0, 0, 0), Vector(0, 0, 1), 47), 0, math.pi), Part.ArcOfCircle(Part.Circle(Vector(-19, -22, 0), Vector(0, 0, 1), 89), math.pi / 12, math.pi / 1.1), Part.LineSegment(Vector(-105, 0, 0), Vector(-47, 0, 0)), Part.LineSegment(Vector(47, 0, 0), Vector(67, 0, 0)) ] arc_sketch.addGeometry(geoList, False) # https://wiki.freecadweb.org/Sketcher_ConstrainCoincident # but the best way is to add a constraint is watching # FreeCAD python console while create this one by the Gui conList = [ Sketcher.Constraint('Coincident', 0, 3, -1, 1), Sketcher.Constraint('PointOnObject', 0, 2, -1), Sketcher.Constraint('PointOnObject', 0, 1, -1), Sketcher.Constraint('PointOnObject', 1, 2, -1), Sketcher.Constraint('PointOnObject', 1, 1, -1), Sketcher.Constraint('Coincident', 2, 1, 0, 2), Sketcher.Constraint('Coincident', 2, 2, 1, 2), Sketcher.Constraint('Coincident', 3, 1, 1, 1), Sketcher.Constraint('Coincident', 3, 2, 0, 1), Sketcher.Constraint('DistanceX', 2, 2, 2, 1, 58), Sketcher.Constraint('DistanceX', 3, 2, 3, 1, 20), Sketcher.Constraint('Radius', 0, 47), Sketcher.Constraint('Radius', 1, 89) ] arc_sketch.addConstraint(conList) # the part extrusion extrude_part = doc.addObject('Part::Extrusion', 'ArcExtrude') extrude_part.Base = arc_sketch extrude_part.DirMode = "Custom" extrude_part.Dir = Vector(0.00, 0.00, 1.00) extrude_part.DirLink = None extrude_part.LengthFwd = 30.00 extrude_part.LengthRev = 0.00 extrude_part.Solid = True extrude_part.Reversed = False extrude_part.Symmetric = True extrude_part.TaperAngle = 0.00 extrude_part.TaperAngleRev = 0.00 # section plane sketch section_sketch = doc.addObject('Sketcher::SketchObject', 'Section_Sketch') section_sketch.Placement = FreeCAD.Placement( Vector(0.000000, 0.000000, 0.000000), Rotation(0.000000, 0.000000, 0.000000, 1.000000)) section_sketch.MapMode = "Deactivated" section_sketch.addGeometry( Part.LineSegment(Vector(-6.691961, -16.840161, 0), Vector(75.156087, 79.421394, 0)), False) # section_sketch.ExternalGeometry = extrude_part # section plane extrusion extrude_section_plane = doc.addObject('Part::Extrusion', 'SectionPlaneExtrude') extrude_section_plane.Base = section_sketch extrude_section_plane.DirMode = "Custom" extrude_section_plane.Dir = Vector(0.00, 0.00, -1.00) extrude_section_plane.DirLink = None extrude_section_plane.LengthFwd = 40.00 extrude_section_plane.LengthRev = 0.00 extrude_section_plane.Solid = False extrude_section_plane.Reversed = False extrude_section_plane.Symmetric = True extrude_section_plane.TaperAngle = 0.00 extrude_section_plane.TaperAngleRev = 0.00 # TODO the extrusions could be done with much less code, see BOLTS if FreeCAD.GuiUp: arc_sketch.ViewObject.hide() section_sketch.ViewObject.hide() extrude_part.ViewObject.hide() extrude_section_plane.ViewObject.hide() Slice = makeSlice(name='Slice') Slice.Base = extrude_part Slice.Tools = extrude_section_plane Slice.Mode = 'Split' # Slice.Proxy.execute(Slice) Slice.purgeTouched() # compound filter to get the solids of the slice solid_one = makeCompoundFilter(name='SolidOne') solid_one.Base = Slice solid_one.FilterType = "specific items" solid_one.items = "0" # solid_one.Proxy.execute(solid_one) solid_one.purgeTouched() if FreeCAD.GuiUp: solid_one.Base.ViewObject.hide() solid_two = makeCompoundFilter(name='SolidTwo') solid_two.Base = Slice solid_two.FilterType = "specific items" solid_two.items = "1" # solid_two.Proxy.execute(solid_two) solid_two.purgeTouched() if FreeCAD.GuiUp: solid_two.Base.ViewObject.hide() # CompSolid out of the two solids geom_obj = makeBooleanFragments(name='BooleanFragments') geom_obj.Objects = [solid_one, solid_two] geom_obj.Mode = 'CompSolid' # geom_obj.Proxy.execute(geom_obj) geom_obj.purgeTouched() if FreeCAD.GuiUp: solid_one.ViewObject.hide() solid_two.ViewObject.hide() doc.recompute() if FreeCAD.GuiUp: geom_obj.ViewObject.Transparency = 50 geom_obj.ViewObject.Document.activeView().viewAxonometric() geom_obj.ViewObject.Document.activeView().fitAll() # analysis analysis = ObjectsFem.makeAnalysis(doc, "Analysis") # solver if solvertype == "calculix": solver_object = analysis.addObject( ObjectsFem.makeSolverCalculix(doc, "SolverCalculiX"))[0] elif solvertype == "ccxtools": solver_object = analysis.addObject( ObjectsFem.makeSolverCalculixCcxTools(doc, "CalculiXccxTools"))[0] solver_object.WorkingDir = u"" elif solvertype == "elmer": analysis.addObject(ObjectsFem.makeSolverElmer(doc, "SolverElmer")) elif solvertype == "z88": analysis.addObject(ObjectsFem.makeSolverZ88(doc, "SolverZ88")) if solvertype == "calculix" or solvertype == "ccxtools": solver_object.SplitInputWriter = False solver_object.AnalysisType = "static" solver_object.GeometricalNonlinearity = "linear" solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = "default" solver_object.IterationsControlParameterTimeUse = False # material material_object = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, "Material"))[0] mat = material_object.Material mat["Name"] = "CalculiX-Steel" mat["YoungsModulus"] = "210000 MPa" mat["PoissonRatio"] = "0.30" material_object.Material = mat # constraint fixed fixed_constraint = analysis.addObject( ObjectsFem.makeConstraintFixed(doc, name="ConstraintFixed"))[0] fixed_constraint.References = [(geom_obj, "Face9")] # constraint pressure pressure_constraint = analysis.addObject( ObjectsFem.makeConstraintPressure(doc, name="ConstraintPressure"))[0] pressure_constraint.References = [(geom_obj, "Face1")] pressure_constraint.Pressure = 100.0 pressure_constraint.Reversed = False # constraint section print section_constraint = analysis.addObject( ObjectsFem.makeConstraintSectionPrint( doc, name="ConstraintSectionPrint"))[0] section_constraint.References = [(geom_obj, "Face6")] # mesh from .meshes.mesh_section_print_tetra10 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") 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 # name is important because the other method in this module use obj name cube = doc.addObject("Part::Box", "Cube") cube.Height = "20 mm" cube.Length = "100 mm" cylinder = doc.addObject("Part::Cylinder", "Cylinder") cylinder.Height = "20 mm" cylinder.Radius = "6 mm" cylinder.Placement = FreeCAD.Placement( Vector(10, 12, 10), Rotation(0, 0, 90), Vector(0, 0, 0), ) cut = doc.addObject("Part::Cut", "Cut") cut.Base = cube cut.Tool = cylinder # mirroring mirror = doc.addObject("Part::Mirroring", "Mirror") mirror.Source = cut mirror.Normal = (1, 0, 0) mirror.Base = (100, 100, 20) # fusing fusion = doc.addObject("Part::Fuse", "Fusion") fusion.Base = cut fusion.Tool = mirror fusion.Refine = True # compound filter geom_obj = CompoundFilter.makeCompoundFilter(name='CompoundFilter') geom_obj.Base = fusion geom_obj.FilterType = 'window-volume' doc.recompute() if FreeCAD.GuiUp: geom_obj.Base.ViewObject.hide() 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) # material material_obj = ObjectsFem.makeMaterialSolid(doc, "FemMaterial") 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 pressure con_pressure = ObjectsFem.makeConstraintPressure( doc, name="FemConstraintPressure") con_pressure.References = [(geom_obj, "Face8")] con_pressure.Pressure = 10.0 con_pressure.Reversed = False analysis.addObject(con_pressure) # constraint displacement con_disp = ObjectsFem.makeConstraintDisplacement( doc, name="FemConstraintDisplacment") con_disp.References = [(geom_obj, "Face4"), (geom_obj, "Face5")] con_disp.xFree = False con_disp.xFix = True analysis.addObject(con_disp) # constraints transform con_transform1 = ObjectsFem.makeConstraintTransform( doc, name="FemConstraintTransform1") con_transform1.References = [(geom_obj, "Face4")] con_transform1.TransformType = "Cylindrical" con_transform1.X_rot = 0.0 con_transform1.Y_rot = 0.0 con_transform1.Z_rot = 0.0 analysis.addObject(con_transform1) con_transform2 = ObjectsFem.makeConstraintTransform( doc, name="FemConstraintTransform2") con_transform2.References = [(geom_obj, "Face5")] con_transform2.TransformType = "Cylindrical" con_transform2.X_rot = 0.0 con_transform2.Y_rot = 0.0 con_transform2.Z_rot = 0.0 analysis.addObject(con_transform2) # mesh from .meshes.mesh_transform_beam_hinged_tetra10 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") 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 = '7 mm' 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 doc.recompute() if FreeCAD.GuiUp: geom_obj.ViewObject.Document.activeView().viewAxonometric() geom_obj.ViewObject.Document.activeView().fitAll() # analysis analysis = ObjectsFem.makeAnalysis(doc, "Analysis") # solver if solvertype == "calculix": solver_object = analysis.addObject( ObjectsFem.makeSolverCalculix(doc, "SolverCalculiX") )[0] elif solvertype == "ccxtools": solver_object = analysis.addObject( ObjectsFem.makeSolverCalculixCcxTools(doc, "CalculiXccxTools") )[0] solver_object.WorkingDir = u"" else: FreeCAD.Console.PrintWarning( "Not known or not supported solver type: {}. " "No solver object was created.\n".format(solvertype) ) if solvertype == "calculix" or solvertype == "ccxtools": solver_object.SplitInputWriter = False solver_object.AnalysisType = "static" solver_object.GeometricalNonlinearity = "linear" solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = "default" solver_object.IterationsControlParameterTimeUse = False # shell thickness 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.SquareTube, "Edge4"), (doc.SquareTube, "Edge7"), (doc.SquareTube, "Edge10"), (doc.SquareTube, "Edge12")] # force_constraint1 force_constraint1 = analysis.addObject( ObjectsFem.makeConstraintForce(doc, name="ConstraintForce1"))[0] force_constraint1.References = [(doc.SquareTube, "Edge9")] force_constraint1.Force = 100000.00 force_constraint1.Direction = (doc.SquareTube, ["Edge9"]) force_constraint1.Reversed = True # force_constraint2 force_constraint2 = analysis.addObject( ObjectsFem.makeConstraintForce(doc, name="ConstraintForce2"))[0] force_constraint2.References = [(doc.SquareTube, "Edge3")] force_constraint2.Force = 100000.00 force_constraint2.Direction = (doc.SquareTube, ["Edge3"]) force_constraint2.Reversed = True # force_constraint3 force_constraint3 = analysis.addObject( ObjectsFem.makeConstraintForce(doc, name="ConstraintForce3"))[0] force_constraint3.References = [(doc.SquareTube, "Edge11")] force_constraint3.Force = 100000.00 force_constraint3.Direction = (doc.SquareTube, ["Edge11"]) force_constraint3.Reversed = True # force_constraint4 force_constraint4 = analysis.addObject( ObjectsFem.makeConstraintForce(doc, name="ConstraintForce4"))[0] force_constraint4.References = [(doc.SquareTube, "Edge6")] force_constraint4.Force = 100000.00 force_constraint4.Direction = (doc.SquareTube, ["Edge6"]) force_constraint4.Reversed = True # 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"): # 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(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_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 setup(doc=None, solvertype="ccxtools"): # setup model if doc is None: doc = init_doc() # geometry objects # two boxes boxlow = doc.addObject("Part::Box", "BoxLower") boxupp = doc.addObject("Part::Box", "BoxUpper") boxupp.Placement.Base = (0, 0, 10) # boolean fragment of the two boxes bf = SplitFeatures.makeBooleanFragments(name="BooleanFragments") bf.Objects = [boxlow, boxupp] bf.Mode = "CompSolid" doc.recompute() bf.Proxy.execute(bf) bf.purgeTouched() if FreeCAD.GuiUp: for child in bf.ViewObject.Proxy.claimChildren(): child.ViewObject.hide() doc.recompute() # extract CompSolid by compound filter tool geom_obj = CompoundFilter.makeCompoundFilter(name="MultiMatCompSolid") geom_obj.Base = bf geom_obj.FilterType = "window-volume" geom_obj.Proxy.execute(geom_obj) geom_obj.purgeTouched() if FreeCAD.GuiUp: geom_obj.Base.ViewObject.hide() doc.recompute() if FreeCAD.GuiUp: import FreeCADGui geom_obj.ViewObject.Document.activeView().viewAxonometric() FreeCADGui.SendMsgToActiveView("ViewFit") # analysis analysis = ObjectsFem.makeAnalysis(doc, "Analysis") # solver if solvertype == "calculix": solver_object = analysis.addObject( ObjectsFem.makeSolverCalculix(doc, "SolverCalculiX"))[0] elif solvertype == "ccxtools": solver_object = analysis.addObject( ObjectsFem.makeSolverCalculixCcxTools(doc, "CalculiXccxTools"))[0] solver_object.WorkingDir = u"" if solvertype == "calculix" or solvertype == "ccxtools": solver_object.SplitInputWriter = False solver_object.AnalysisType = "static" solver_object.GeometricalNonlinearity = "linear" solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = "default" solver_object.IterationsControlParameterTimeUse = False # material material_object_low = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterialLow"))[0] mat = material_object_low.Material mat["Name"] = "Aluminium-Generic" mat["YoungsModulus"] = "70000 MPa" mat["PoissonRatio"] = "0.35" mat["Density"] = "2700 kg/m^3" material_object_low.Material = mat material_object_low.References = [(boxlow, "Solid1")] analysis.addObject(material_object_low) material_object_upp = analysis.addObject( ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterialUpp"))[0] mat = material_object_upp.Material mat["Name"] = "Steel-Generic" mat["YoungsModulus"] = "200000 MPa" mat["PoissonRatio"] = "0.30" mat["Density"] = "7980 kg/m^3" material_object_upp.Material = mat material_object_upp.References = [(boxupp, "Solid1")] # fixed_constraint fixed_constraint = analysis.addObject( ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed"))[0] fixed_constraint.References = [(geom_obj, "Face5")] # pressure_constraint pressure_constraint = analysis.addObject( ObjectsFem.makeConstraintPressure(doc, "ConstraintPressure"))[0] pressure_constraint.References = [(geom_obj, "Face11")] pressure_constraint.Pressure = 1000.0 pressure_constraint.Reversed = False # mesh from .meshes.mesh_boxes_2_vertikal_tetra10 import create_nodes, create_elements fem_mesh = Fem.FemMesh() control = create_nodes(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating nodes.\n") control = create_elements(fem_mesh) if not control: FreeCAD.Console.PrintError("Error on creating elements.\n") femmesh_obj = analysis.addObject( doc.addObject("Fem::FemMeshObject", mesh_name))[0] femmesh_obj.FemMesh = fem_mesh doc.recompute() return doc
def test_static_freq_analysis(self): # static fcc_print('--------------- Start of FEM tests ---------------') box = self.active_doc.addObject("Part::Box", "Box") fcc_print('Checking FEM new analysis...') analysis = ObjectsFem.makeAnalysis('Analysis') self.assertTrue(analysis, "FemTest of new analysis failed") fcc_print('Checking FEM new solver...') solver_object = ObjectsFem.makeSolverCalculix('CalculiX') solver_object.GeometricalNonlinearity = 'linear' solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = 'default' solver_object.IterationsControlParameterTimeUse = False solver_object.EigenmodesCount = 10 solver_object.EigenmodeHighLimit = 1000000.0 solver_object.EigenmodeLowLimit = 0.0 self.assertTrue(solver_object, "FemTest of new solver failed") analysis.Member = analysis.Member + [solver_object] fcc_print('Checking FEM new material...') new_material_object = ObjectsFem.makeMaterialSolid('MechanicalMaterial') mat = new_material_object.Material mat['Name'] = "Steel-Generic" mat['YoungsModulus'] = "200000 MPa" mat['PoissonRatio'] = "0.30" mat['Density'] = "7900 kg/m^3" new_material_object.Material = mat self.assertTrue(new_material_object, "FemTest of new material failed") analysis.Member = analysis.Member + [new_material_object] fcc_print('Checking FEM new fixed constraint...') fixed_constraint = self.active_doc.addObject("Fem::ConstraintFixed", "FemConstraintFixed") fixed_constraint.References = [(box, "Face1")] self.assertTrue(fixed_constraint, "FemTest of new fixed constraint failed") analysis.Member = analysis.Member + [fixed_constraint] fcc_print('Checking FEM new force constraint...') force_constraint = self.active_doc.addObject("Fem::ConstraintForce", "FemConstraintForce") force_constraint.References = [(box, "Face6")] force_constraint.Force = 40000.0 force_constraint.Direction = (box, ["Edge5"]) self.active_doc.recompute() force_constraint.Reversed = True self.active_doc.recompute() self.assertTrue(force_constraint, "FemTest of new force constraint failed") analysis.Member = analysis.Member + [force_constraint] fcc_print('Checking FEM new pressure constraint...') pressure_constraint = self.active_doc.addObject("Fem::ConstraintPressure", "FemConstraintPressure") pressure_constraint.References = [(box, "Face2")] pressure_constraint.Pressure = 1000.0 pressure_constraint.Reversed = False self.assertTrue(pressure_constraint, "FemTest of new pressure constraint failed") analysis.Member = analysis.Member + [pressure_constraint] fcc_print('Checking FEM new mesh...') from test_files.ccx.cube_mesh import create_nodes_cube, 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', 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 ---------------')
def make_femmesh( mesh_data ): """ makes an FreeCAD FEM Mesh object from FEM Mesh data """ import Fem mesh = Fem.FemMesh() m = mesh_data if ("Nodes" in m) and (len(m["Nodes"]) > 0): FreeCAD.Console.PrintLog("Found: nodes\n") if ( ("Seg2Elem" in m) or ("Seg3Elem" in m) or ("Tria3Elem" in m) or ("Tria6Elem" in m) or ("Quad4Elem" in m) or ("Quad8Elem" in m) or ("Tetra4Elem" in m) or ("Tetra10Elem" in m) or ("Penta6Elem" in m) or ("Penta15Elem" in m) or ("Hexa8Elem" in m) or ("Hexa20Elem" in m) ): nds = m["Nodes"] FreeCAD.Console.PrintLog("Found: elements\n") for i in nds: n = nds[i] mesh.addNode(n[0], n[1], n[2], i) elms_hexa8 = m["Hexa8Elem"] for i in elms_hexa8: e = elms_hexa8[i] mesh.addVolume([e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7]], i) elms_penta6 = m["Penta6Elem"] for i in elms_penta6: e = elms_penta6[i] mesh.addVolume([e[0], e[1], e[2], e[3], e[4], e[5]], i) elms_tetra4 = m["Tetra4Elem"] for i in elms_tetra4: e = elms_tetra4[i] mesh.addVolume([e[0], e[1], e[2], e[3]], i) elms_tetra10 = m["Tetra10Elem"] for i in elms_tetra10: e = elms_tetra10[i] mesh.addVolume([e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8], e[9]], i) elms_penta15 = m["Penta15Elem"] for i in elms_penta15: e = elms_penta15[i] mesh.addVolume([e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8], e[9], e[10], e[11], e[12], e[13], e[14]], i) elms_hexa20 = m["Hexa20Elem"] for i in elms_hexa20: e = elms_hexa20[i] mesh.addVolume([ e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8], e[9], e[10], e[11], e[12], e[13], e[14], e[15], e[16], e[17], e[18], e[19] ], i) elms_tria3 = m["Tria3Elem"] for i in elms_tria3: e = elms_tria3[i] mesh.addFace([e[0], e[1], e[2]], i) elms_tria6 = m["Tria6Elem"] for i in elms_tria6: e = elms_tria6[i] mesh.addFace([e[0], e[1], e[2], e[3], e[4], e[5]], i) elms_quad4 = m["Quad4Elem"] for i in elms_quad4: e = elms_quad4[i] mesh.addFace([e[0], e[1], e[2], e[3]], i) elms_quad8 = m["Quad8Elem"] for i in elms_quad8: e = elms_quad8[i] mesh.addFace([e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7]], i) elms_seg2 = m["Seg2Elem"] for i in elms_seg2: e = elms_seg2[i] mesh.addEdge([e[0], e[1]], i) elms_seg3 = m["Seg3Elem"] for i in elms_seg3: e = elms_seg3[i] mesh.addEdge([e[0], e[1], e[2]], i) Console.PrintLog( "imported mesh: {} nodes, {} HEXA8, {} PENTA6, {} TETRA4, {} TETRA10, {} PENTA15\n" .format( len(nds), len(elms_hexa8), len(elms_penta6), len(elms_tetra4), len(elms_tetra10), len(elms_penta15) ) ) Console.PrintLog( "imported mesh: {} " "HEXA20, {} TRIA3, {} TRIA6, {} QUAD4, {} QUAD8, {} SEG2, {} SEG3\n" .format( len(elms_hexa20), len(elms_tria3), len(elms_tria6), len(elms_quad4), len(elms_quad8), len(elms_seg2), len(elms_seg3) ) ) else: Console.PrintError("No Elements found!\n") else: Console.PrintError("No Nodes found!\n") return mesh
def test_thermomech_analysis(self): fcc_print('--------------- Start of FEM tests ---------------') box = self.active_doc.addObject("Part::Box", "Box") box.Height = 25.4 box.Width = 25.4 box.Length = 203.2 fcc_print('Checking FEM new analysis...') analysis = ObjectsFem.makeAnalysis('Analysis') self.assertTrue(analysis, "FemTest of new analysis failed") fcc_print('Checking FEM new solver...') solver_object = ObjectsFem.makeSolverCalculix('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.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" 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 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 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.Member = analysis.Member + [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.Member = analysis.Member + [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.Member = analysis.Member + [heatflux_constraint] fcc_print('Checking FEM new mesh...') from test_files.ccx.spine_mesh import create_nodes_spine, 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', 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, 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('Setting analysis type to \'thermomech\"') fea.set_analysis_type("thermomech") self.assertTrue(True if fea.analysis_type == 'thermomech' else False, "Setting anlysis type to \'thermomech\' failed") fcc_print('Checking FEM inp file prerequisites for thermo-mechanical 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('Writing {}/{}.inp for thermomech analysis'.format(thermomech_analysis_dir, mesh_name)) error = fea.write_inp_file() self.assertFalse(error, "Writing failed") fcc_print('Comparing {} to {}/{}.inp'.format(thermomech_analysis_inp_file, thermomech_analysis_dir, mesh_name)) ret = compare_inp_files(thermomech_analysis_inp_file, thermomech_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('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...') ret = compare_stats(fea, thermomech_expected_values) self.assertFalse(ret, "Invalid results read from .frd file") 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 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() # 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: import FreeCADGui geom_obj.ViewObject.Document.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.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( 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 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