def test_tetra10_z88(self): # tetra10 element: reading from and writing to z88 mesh file format file_extension = "z88" outfile, testfile = self.get_file_paths(file_extension) self.femmesh.write(outfile) # write the mesh femmesh_testfile = Fem.read(outfile) # read the mesh from written mesh femmesh_outfile = Fem.read(testfile) # read the mesh from test mesh self.compare_mesh_files(femmesh_testfile, femmesh_outfile, file_extension)
def test_tetra10_inp(self): # tetra10 element: reading from and writing to inp mesh file format file_extension = "inp" outfile, testfile = self.get_file_paths(file_extension) self.femmesh.writeABAQUS(outfile, 1, False) # write the mesh femmesh_outfile = Fem.read(outfile) # read the mesh from written mesh femmesh_testfile = Fem.read(testfile) # read the mesh from test mesh self.compare_mesh_files(femmesh_testfile, femmesh_outfile, file_extension)
def read_and_set_new_mesh(self): if not self.error: fem_mesh = Fem.read(self.temp_file_mesh) self.mesh_obj.FemMesh = fem_mesh Console.PrintMessage(" The Part should have a pretty new FEM mesh!\n") else: Console.PrintError("No mesh was created.\n")
def test_unv_save_load( self ): tetra10 = Fem.FemMesh() tetra10.addNode(6, 12, 18, 1) tetra10.addNode(0, 0, 18, 2) tetra10.addNode(12, 0, 18, 3) tetra10.addNode(6, 6, 0, 4) tetra10.addNode(3, 6, 18, 5) tetra10.addNode(6, 0, 18, 6) tetra10.addNode(9, 6, 18, 7) tetra10.addNode(6, 9, 9, 8) tetra10.addNode(3, 3, 9, 9) tetra10.addNode(9, 3, 9, 10) tetra10.addVolume([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) unv_file = testtools.get_fem_test_tmp_dir() + "/tetra10_mesh.unv" tetra10.write(unv_file) newmesh = Fem.read(unv_file) expected = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) self.assertEqual( newmesh.getElementNodes(1), expected, "Nodes order of quadratic volume element is unexpected" )
def read_and_set_new_mesh(self): if not self.error: fem_mesh = Fem.read(self.temp_file_mesh) self.mesh_obj.FemMesh = fem_mesh Console.PrintMessage(" New mesh was added to the mesh object.\n") else: Console.PrintError("No mesh was created.\n")
def test_tetra10_vkt(self): # tetra10 element: reading from and writing to unv mesh file format filetyp = 'vtk' outfile = self.base_outfile + filetyp testfile = self.base_testfile + filetyp # fcc_print(outfile) # fcc_print(testfile) if "BUILD_FEM_VTK" in FreeCAD.__cmake__: self.femmesh.write(outfile) # write the mesh femmesh_outfile = Fem.read(outfile) # read the mesh from written mesh femmesh_testfile = Fem.read(testfile) # read the mesh from test mesh # reading the test mesh self.assertEqual( femmesh_testfile.Nodes, self.expected_nodes['nodes'], "Test writing " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n" ) self.assertEqual( [femmesh_testfile.Volumes[0], femmesh_testfile.getElementNodes(femmesh_outfile.Volumes[0])], self.expected_elem['volumes'], "Test writing " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n" ) # reading the written mesh self.assertEqual( femmesh_outfile.Nodes, self.expected_nodes['nodes'], "Test writing " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n" ) self.assertEqual( [femmesh_outfile.Volumes[0], femmesh_outfile.getElementNodes(femmesh_outfile.Volumes[0])], self.expected_elem['volumes'], "Test writing " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n" ) # both self.assertEqual( femmesh_outfile.Nodes, femmesh_testfile.Nodes, "Test writing " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n" ) self.assertEqual( femmesh_outfile.Volumes, femmesh_testfile.Volumes, "Test writing " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n" ) else: fcc_print('FEM_VTK post processing is disabled.')
def test_tetra10_vkt(self): # tetra10 element: reading from and writing to unv mesh file format file_extension = "vtk" outfile, testfile = self.get_file_paths(file_extension) if "BUILD_FEM_VTK" in FreeCAD.__cmake__: self.femmesh.write(outfile) # write the mesh femmesh_outfile = Fem.read( outfile) # read the mesh from written mesh femmesh_testfile = Fem.read( testfile) # read the mesh from test mesh self.compare_mesh_files(femmesh_testfile, femmesh_outfile, file_extension) else: fcc_print("FEM_VTK post processing is disabled.")
def test_tetra10_vkt(self): # tetra10 element: reading from and writing to unv mesh file format filetyp = 'vtk' outfile = self.base_outfile + filetyp testfile = self.base_testfile + filetyp # fcc_print(outfile) # fcc_print(testfile) if "BUILD_FEM_VTK" in FreeCAD.__cmake__: self.femmesh.write(outfile) # write the mesh femmesh_outfile = Fem.read( outfile) # read the mesh from written mesh femmesh_testfile = Fem.read( testfile) # read the mesh from test mesh # reading the test mesh self.assertEqual( femmesh_testfile.Nodes, self.expected_nodes['nodes'], "Test writing " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n") self.assertEqual([ femmesh_testfile.Volumes[0], femmesh_testfile.getElementNodes(femmesh_outfile.Volumes[0]) ], self.expected_elem['volumes'], "Test writing " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n") # reading the written mesh self.assertEqual( femmesh_outfile.Nodes, self.expected_nodes['nodes'], "Test writing " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n") self.assertEqual([ femmesh_outfile.Volumes[0], femmesh_outfile.getElementNodes(femmesh_outfile.Volumes[0]) ], self.expected_elem['volumes'], "Test writing " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n") # both self.assertEqual( femmesh_outfile.Nodes, femmesh_testfile.Nodes, "Test writing " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n") self.assertEqual( femmesh_outfile.Volumes, femmesh_testfile.Volumes, "Test writing " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n") else: fcc_print('FEM_VTK post processing is disabled.')
def test_tetra10_inp(self): # tetra10 element: reading from and writing to inp mesh file format filetyp = 'inp' outfile = self.base_outfile + filetyp testfile = self.base_testfile + filetyp # fcc_print(outfile) # fcc_print(testfile) self.femmesh.writeABAQUS(outfile, 1, False) # write the mesh femmesh_outfile = Fem.read(outfile) # read the mesh from written mesh femmesh_testfile = Fem.read(testfile) # read the mesh from test mesh # reading the test mesh # fcc_print([femmesh_testfile.Volumes[0], femmesh_testfile.getElementNodes(femmesh_outfile.Volumes[0])]) self.assertEqual( femmesh_testfile.Nodes, self.expected_nodes['nodes'], "Test reading " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n") self.assertEqual([ femmesh_testfile.Volumes[0], femmesh_testfile.getElementNodes(femmesh_outfile.Volumes[0]) ], self.expected_elem['volumes'], "Test reading " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n") # reading the written mesh self.assertEqual( femmesh_outfile.Nodes, self.expected_nodes['nodes'], "Test reading " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n") self.assertEqual([ femmesh_outfile.Volumes[0], femmesh_outfile.getElementNodes(femmesh_outfile.Volumes[0]) ], self.expected_elem['volumes'], "Test reading " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n") # both self.assertEqual( femmesh_outfile.Nodes, femmesh_testfile.Nodes, "Test writing " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n") self.assertEqual([ femmesh_outfile.Volumes[0], femmesh_outfile.getElementNodes(femmesh_outfile.Volumes[0]) ], [ femmesh_testfile.Volumes[0], femmesh_testfile.getElementNodes(femmesh_outfile.Volumes[0]) ], "Test writing " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n")
def read_and_set_new_mesh(self): if not self.error: fem_mesh = Fem.read(self.temp_file_mesh) self.mesh_obj.FemMesh = fem_mesh FreeCAD.Console.PrintError(' The Part should have a pretty new FEM mesh!\n') else: FreeCAD.Console.PrintError('No mesh was created.\n') del self.temp_file_geometry del self.temp_file_mesh
def importVtkFemMesh( filename, meshname ): meshobj = FreeCAD.ActiveDocument.addObject("Fem::FemMeshObject", meshname) meshobj.FemMesh = Fem.read(filename) meshobj.touch() FreeCAD.ActiveDocument.recompute() return meshobj
def read_and_set_new_mesh(self): if not self.error: fem_mesh = Fem.read(self.temp_file_mesh) self.mesh_obj.FemMesh = fem_mesh print(' The Part should have a pretty new FEM mesh!') else: print('No mesh was created.') del self.temp_file_geometry del self.temp_file_mesh
def test_tetra10_inp(self): # tetra10 element: reading from and writing to inp mesh file format filetyp = 'inp' outfile = self.base_outfile + filetyp testfile = self.base_testfile + filetyp # fcc_print(outfile) # fcc_print(testfile) self.femmesh.writeABAQUS(outfile, 1, False) # write the mesh femmesh_outfile = Fem.read(outfile) # read the mesh from written mesh femmesh_testfile = Fem.read(testfile) # read the mesh from test mesh # reading the test mesh # fcc_print([femmesh_testfile.Volumes[0], femmesh_testfile.getElementNodes(femmesh_outfile.Volumes[0])]) self.assertEqual( femmesh_testfile.Nodes, self.expected_nodes['nodes'], "Test reading " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n" ) self.assertEqual( [femmesh_testfile.Volumes[0], femmesh_testfile.getElementNodes(femmesh_outfile.Volumes[0])], self.expected_elem['volumes'], "Test reading " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n" ) # reading the written mesh self.assertEqual( femmesh_outfile.Nodes, self.expected_nodes['nodes'], "Test reading " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n" ) self.assertEqual( [femmesh_outfile.Volumes[0], femmesh_outfile.getElementNodes(femmesh_outfile.Volumes[0])], self.expected_elem['volumes'], "Test reading " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n" ) # both self.assertEqual( femmesh_outfile.Nodes, femmesh_testfile.Nodes, "Test writing " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n" ) self.assertEqual( [femmesh_outfile.Volumes[0], femmesh_outfile.getElementNodes(femmesh_outfile.Volumes[0])], [femmesh_testfile.Volumes[0], femmesh_testfile.getElementNodes(femmesh_outfile.Volumes[0])], "Test writing " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n" )
def read_and_set_new_mesh(self): if not self.error: # NOTE: FemMesh does not support multi element stl # fem_mesh = Fem.read(os.path.join(self.meshCaseDir,'mesh_outside.stl')) # This is a temp work around to remove multiple solids, but is not very efficient import Mesh stl = os.path.join(self.meshCaseDir, 'mesh_outside.stl') ast = os.path.join(self.meshCaseDir, 'mesh_outside.ast') mesh = Mesh.Mesh(stl) mesh.write(ast) os.remove(stl) os.rename(ast, stl) fem_mesh = Fem.read(stl) self.mesh_obj.FemMesh = fem_mesh print(' The Part should have a new mesh!') else: print('No mesh was created.')
def importGeometryAndMesh(geo_file, mesh_file): # caller guarant input parameter is valid path and type, each is a tuple of (filename, suffix) docname = FreeCAD.ActiveDocument.Name if geo_file: if isinstance(geo_file, (str, unicode)) and os.path.exists(geo_file): geo_suffix = geo_file.split(u'.')[-1] #if geo_suffix not in [u'iges', u'igs', u'step', u'stp', u'brep', u'fcstd']: # should be done in caller # FreeCAD.Console.PrintError(u"only step, brep, fcstd and iges geometry files are supported, while input file suffix is: {}".format(geo_suffix)) # return False # there must be a document to import objects #FreeCADGui.addModule("Part") #FreeCADGui.doCommand("Part.insert(u'" + geo_file + "','" + docname + "')") import Part Part.insert(geo_file, docname) part_obj = FreeCAD.ActiveDocument.ActiveObject elif geo_file.isDerivedFrom("Part::Feature"): part_obj = geo_file else: FreeCAD.Console.PrintError( "part should be provided as a valid file path or Part::Feature dervied Object" ) mesh_suffix = mesh_file.split(u'.')[-1] #if mesh_suffix not in [u'unv', u'inp', u'vtk', u'vtu', u'med']: # any type supported by FemMesh import # FreeCAD.Console.PrintError(u"input file suffix: {}, is NOT supported for mesh importing".format(geo_suffix)) # return False import Fem fem_mesh = Fem.read(mesh_file) # Fem.insert() gives <Fem::FemMeshObject object> can not add dynamic property # mesh must NOT been scaled to metre, or using LengthUnit property! if fem_mesh: #mesh_obj.isDerivedFrom("Part::FeaturePython"): import CfdObjects mesh_obj = CfdObjects.makeCfdMeshImported() mesh_obj.FemMesh = fem_mesh mesh_obj.Part = part_obj mesh_obj.Imported = True mesh_obj.ImportedMeshPath = mesh_file FreeCAD.Console.PrintMessage( 'The Part should have an FEM mesh imported') return mesh_obj else: FreeCAD.Console.PrintError( 'Mesh importing failed for {}'.format(mesh_file)) return False
def importGeometryAndMesh(geo_file, mesh_file): # caller guarant input parameter is valid path and type, each is a tuple of (filename, suffix) docname = FreeCAD.ActiveDocument.Name if geo_file: if os.path.exists(geo_file): geo_suffix = geo_file.split(u'.')[-1] if geo_suffix not in [u'iges', u'igs', u'step', u'stp', u'brep']: FreeCAD.Console.PrintError(u"only step, brep and iges geometry files are supported, while input file suffix is: {}".format(geo_suffix)) return False # there must be a document to import objects #FreeCADGui.addModule("Part") #FreeCADGui.doCommand("Part.insert(u'" + geo_file + "','" + docname + "')") import Part Part.insert(geo_file , docname) part_obj = FreeCAD.ActiveDocument.ActiveObject elif geo_file.isDerivedFrom("Part::Feature"): part_obj = geo_file else: part_obj = None mesh_suffix = mesh_file.split(u'.')[-1] if mesh_suffix not in [u'unv', u'inp', u'vtk', u'vtu', u'med']: FreeCAD.Console.PrintError(u"input file suffix: {}, is NOT supported for mesh importing".format(geo_suffix)) return False import Fem fem_mesh = Fem.read(mesh_file) #FreeCADGui.addModule("Fem") #FreeCADGui.doCommand("Fem.read(u'" + mesh_file + "')") # Fem.insert() gives <Fem::FemMeshObject object> can not add dynamic property # mesh must NOT been scaled to metre, or using LengthUnit property if fem_mesh: #mesh_obj.isDerivedFrom("Part::FeaturePython"): #FreeCADGui.addModule("CfdObjects") # FemGmsh has been adjusted for CFD like only first order element #FreeCADGui.doCommand("CfdObjects.makeCfdMeshImported('" + mesh_obj_name + "')") import CfdObjects mesh_obj = CfdObjects.makeCfdMeshImported() mesh_obj.FemMesh = fem_mesh mesh_obj.Part = part_obj FreeCAD.Console.PrintMessage('The Part should have an FEM mesh imported') return mesh_obj else: FreeCAD.Console.PrintError('Mesh importing failed for {}'.format(mesh_file))
def loadSurfMesh(self): if not self.error: # NOTE: FemMesh does not support multi element stl # fem_mesh = Fem.read(os.path.join(self.meshCaseDir,'mesh_outside.stl')) # This is a temp work around to remove multiple solids, but is not very efficient import Mesh stl = os.path.join(self.meshCaseDir, 'mesh_outside.stl') ast = os.path.join(self.meshCaseDir, 'mesh_outside.ast') mesh = Mesh.Mesh(stl) mesh.write(ast) os.remove(stl) os.rename(ast, stl) fem_mesh = Fem.read(stl) fem_mesh_obj = FreeCAD.ActiveDocument.addObject("Fem::FemMeshObject", self.mesh_obj.Name+"_Surf_Vis") fem_mesh_obj.FemMesh = fem_mesh self.mesh_obj.addObject(fem_mesh_obj) print(' Finished loading mesh.') else: print('No mesh was created.')
def test_unv_save_load(self): tetra10 = Fem.FemMesh() tetra10.addNode(6, 12, 18, 1) tetra10.addNode(0, 0, 18, 2) tetra10.addNode(12, 0, 18, 3) tetra10.addNode(6, 6, 0, 4) tetra10.addNode(3, 6, 18, 5) tetra10.addNode(6, 0, 18, 6) tetra10.addNode(9, 6, 18, 7) tetra10.addNode(6, 9, 9, 8) tetra10.addNode(3, 3, 9, 9) tetra10.addNode(9, 3, 9, 10) tetra10.addVolume([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) tetra10.write(static_save_unv_file) newmesh = Fem.read(static_save_unv_file) expected = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) self.assertEqual(newmesh.getElementNodes(1), expected, "Nodes order of quadratic volume element is unexpected")
def mesh_finished(self, exit_code): self.read_output() print("exit code", exit_code) if exit_code == 0: self.console_log("Reading mesh") #Reading stl created by OpenFOAM to display representation of mesh import Mesh import Fem self.meshConverted = True stl = os.path.join(self.meshCaseDir, 'mesh_outside.stl') ast = os.path.join(self.meshCaseDir, 'mesh_outside.ast') mesh = Mesh.Mesh(stl) mesh.write(ast) os.remove(stl) os.rename(ast, stl) fem_mesh = Fem.read(stl) self.meshObj.FemMesh = fem_mesh self.console_log('2D Meshing completed') self.console_log( 'The mesh should now contain only a single element through the thickness.' ) self.console_log( 'Warning: Tetrahedral representation of the mesh is a only a representation.' ) self.console_log( "Please use Paraview to view the new mesh correctly.\n") self.form.paraviewButton.setEnabled(True) self.form.convertButton.setEnabled(True) self.saveInfo() self.form.conversionStatusText.setText( "Mesh converted successfully.") self.form.conversionStatusText.setStyleSheet('color: green') else: print("Meshing error") self.meshConverted = False self.console_log("Meshing exited with error", "#FF0000") self.form.paraviewButton.setEnabled(False) self.form.convertButton.setEnabled(True) self.form.convertButton.setEnabled(True) self.Timer.stop() self.error_message = ''
def start_calculation(self): self.button_add_to_table.setEnabled(False) self.button_select_file.setEnabled(False) self.button_select_output.setEnabled(False) self.button_start_calculation.setEnabled(False) os.chdir("/") ##Get values from the GUI if (os.path.exists(str(self.dirname))): os.chdir("c:/") shutil.rmtree(str(self.dirname)) os.mkdir(str(self.dirname)) batch = open( str(self.dirname + "/" + "lcmt_CALCULIX_Calculation_batch.bat"), 'wb') #Tell calculixs solver spooles how many cpus to use #batch.write("export CCX_NPROC=" + str(self.params.GetInt("NumberCPUs")) + "\n") #If we have a tcsh #batch.write("setenv CCX_NPROC 4\n") #Now do the calculation stuff for each row in the table for job in range(0, self.JobTable.rowCount()): #Extract the data from the table current_file_name = self.JobTable.item(job, 0).text() z_offset_from = self.JobTable.item(job, 2).data( QtCore.Qt.DisplayRole).toInt()[0] z_offset_to = self.JobTable.item(job, 3).data( QtCore.Qt.DisplayRole).toInt()[0] z_offset_intervall = self.JobTable.item(job, 4).data( QtCore.Qt.DisplayRole).toInt()[0] x_rot_from = self.JobTable.item(job, 5).data( QtCore.Qt.DisplayRole).toInt()[0] x_rot_to = self.JobTable.item(job, 6).data( QtCore.Qt.DisplayRole).toInt()[0] x_rot_intervall = self.JobTable.item(job, 7).data( QtCore.Qt.DisplayRole).toInt()[0] y_rot_from = self.JobTable.item(job, 8).data( QtCore.Qt.DisplayRole).toInt()[0] y_rot_to = self.JobTable.item(job, 9).data( QtCore.Qt.DisplayRole).toInt()[0] y_rot_intervall = self.JobTable.item(job, 10).data( QtCore.Qt.DisplayRole).toInt()[0] z_rot_from = self.JobTable.item(job, 11).data( QtCore.Qt.DisplayRole).toInt()[0] z_rot_to = self.JobTable.item(job, 12).data( QtCore.Qt.DisplayRole).toInt()[0] z_rot_intervall = self.JobTable.item(job, 13).data( QtCore.Qt.DisplayRole).toInt()[0] young_modulus = self.JobTable.item(job, 14).data( QtCore.Qt.DisplayRole).toDouble()[0] poisson_ratio = self.JobTable.item(job, 15).data( QtCore.Qt.DisplayRole).toDouble()[0] lc1 = self.JobTable.item(job, 16).data( QtCore.Qt.DisplayRole).toDouble()[0] lc2 = self.JobTable.item(job, 17).data( QtCore.Qt.DisplayRole).toDouble()[0] lc3 = self.JobTable.item(job, 18).data( QtCore.Qt.DisplayRole).toDouble()[0] lc4 = self.JobTable.item(job, 19).data( QtCore.Qt.DisplayRole).toDouble()[0] lc5 = self.JobTable.item(job, 20).data( QtCore.Qt.DisplayRole).toDouble()[0] lc6 = self.JobTable.item(job, 21).data( QtCore.Qt.DisplayRole).toDouble()[0] ltc1 = self.JobTable.item(job, 22).data( QtCore.Qt.DisplayRole).toDouble()[0] ltc2 = self.JobTable.item(job, 23).data( QtCore.Qt.DisplayRole).toDouble()[0] ltc3 = self.JobTable.item(job, 24).data( QtCore.Qt.DisplayRole).toDouble()[0] ltc4 = self.JobTable.item(job, 25).data( QtCore.Qt.DisplayRole).toDouble()[0] ltc5 = self.JobTable.item(job, 26).data( QtCore.Qt.DisplayRole).toDouble()[0] ltc6 = self.JobTable.item(job, 27).data( QtCore.Qt.DisplayRole).toDouble()[0] plate_thickness = self.JobTable.item(job, 28).data( QtCore.Qt.DisplayRole).toDouble()[0] filename_without_suffix = self.JobTable.item( job, 0).text().split("/").takeLast().split(".")[0] meshobject = Fem.read(str(current_file_name)) #Perform PCA Fem.SMESH_PCA(meshobject) #Do min routine Fem.minBoundingBox(meshobject) #Now get the Node Numbers for the Boundary Conditions node_numbers = [] node_numbers = Fem.getBoundary_Conditions(meshobject) #Now we have set up the initial geometry for the calculations. Lets generate an ABAQUS input file now for each z-level with exactly the same #boundary conditions #1. Lets translate the geometry to the initial desired z-level #2. Generate a Folder for the current calculation z-level and output the ABAQUS Geometry and the boundary_conditions #Lets first generate a subfolder with the current filename os.mkdir(str(self.dirname + "/" + filename_without_suffix)) i = z_offset_from while i <= z_offset_to: j = x_rot_from while j <= x_rot_to: k = y_rot_from while k <= y_rot_to: l = z_rot_from while l <= z_rot_to: rotation_around_x = FreeCAD.Base.Placement( FreeCAD.Base.Vector(0, 0, 0), FreeCAD.Base.Vector(1, 0, 0), j) rotation_around_y = FreeCAD.Base.Placement( FreeCAD.Base.Vector(0, 0, 0), FreeCAD.Base.Vector(0, 1, 0), k) rotation_around_z = FreeCAD.Base.Placement( FreeCAD.Base.Vector(0, 0, 0), FreeCAD.Base.Vector(0, 0, 1), l) translate = FreeCAD.Base.Placement( FreeCAD.Base.Vector(0, 0, i), FreeCAD.Base.Vector(0, 0, 0), 0.0) translation = rotation_around_x.multiply( rotation_around_y).multiply( rotation_around_z).multiply(translate) #Now lets check if the part is still in the billet due to the rotation. If not, we directly skip to the next rotation value if (Fem.checkBB(meshobject, translation, plate_thickness)): print "Too heavy rotations" l = l + z_rot_intervall continue print "it seems that nothing changed" #Use the placedment as optional argument for the write() method #translated_mesh.setTransform(translation) Case_Dir = str(self.dirname) + "/" + filename_without_suffix + "/" + filename_without_suffix +\ "_"+"x_rot"+ str(int(j))+ \ "_"+"y_rot"+ str(int(k))+ \ "_"+"z_rot"+ str(int(l))+ \ "_"+"z_l"+ str(int(i)) if (os.path.exists(str(Case_Dir))): os.chdir(str(self.dirname)) shutil.rmtree(str(Case_Dir)) os.mkdir(str(Case_Dir)) os.chdir("c:/") #Lets generate a sigini Input Deck for the calculix user subroutine sigini_input = open( str(Case_Dir + "/" + "sigini_input.txt"), 'wb') #Write plate thickness to the sigini_file sigini_input.write(str(plate_thickness) + "\n") #Now write the Interpolation coefficients, first the L and then the LC ones sigini_input.write(\ str(lc1) + "," + \ str(lc2) + "," + \ str(lc3) + "," + \ str(lc4) + "," + \ str(lc5) + "," + \ str(lc6) + "\n") sigini_input.write(\ str(ltc1) + "," + \ str(ltc2) + "," + \ str(ltc3) + "," + \ str(ltc4) + "," + \ str(ltc5) + "," + \ str(ltc6) + "\n") sigini_input.close() #Check if the meshobject.writeABAQUS( str(Case_Dir + "/" + "geometry_fe_input.inp"), translation) ApplyingBC_IC(Case_Dir, young_modulus, poisson_ratio, node_numbers[0], node_numbers[1], node_numbers[2]) #Now lets generate a LSF Job-File to be used by the Airbus Clusters lsf_input = open(str(Case_Dir + "/" + "job.lsf"), "wb") lsf_input.write("#!/bin/bash\n") lsf_input.write( "export CCX_NPROC=" + str(self.params.GetInt("NumberCPUs")) + "\n") lsf_input.write( "#BSUB -n " + str(self.params.GetInt("NumberCPUs")) + "\n") lsf_input.write("#BSUB -W 10:00\n") lsf_input.write("#BSUB -o %J.out\n") lsf_input.write("#BSUB -e %J.err\n") lsf_input.write("#BSUB -J calculix\n") lsf_input.write("#BSUB -q loc_all_hiio\n") lsf_input.write( str("datadir=\"" + self.params.GetString("Linux Home Path") + "/" + self.dirname[str(self.dirname).rfind("/") + 1:] + "/" + filename_without_suffix + "/" + filename_without_suffix + "_" + "x_rot" + str(int(j)) + "_" + "y_rot" + str(int(k)) + "_" + "z_rot" + str(int(l)) + "_" + "z_l" + str(int(i)) + "\"\n")) lsf_input.write("cd $datadir\n") lsf_input.write( self.params.GetString("Solver Link") + " -i final_fe_input\n") lsf_input.close() batch.write( str("cd \"" + self.params.GetString("Linux Home Path") + "/" + self.dirname[str(self.dirname).rfind("/") + 1:] + "/" + filename_without_suffix + "/" + filename_without_suffix + "_" + "x_rot" + str(int(j)) + "_" + "y_rot" + str(int(k)) + "_" + "z_rot" + str(int(l)) + "_" + "z_l" + str(int(i)) + "\"\n")) batch.write("job.lsf\n") l = l + z_rot_intervall k = k + y_rot_intervall j = j + x_rot_intervall i = i + z_offset_intervall print "Ale Schleifen beendet" batch.write("cd \"" + self.params.GetString("Linux Home Path") + "\"\n") batch.write("find \"" + str(self.dirname[str(self.dirname).rfind("/") + 1:] + "/") + "\" -name \"sigini_output.txt\" -exec rm -f {} \;\n") batch.write("find \"" + str(self.dirname[str(self.dirname).rfind("/") + 1:] + "/") + "\" -name \"*.out\" -exec rm -f {} \;\n") batch.write("find \"" + str(self.dirname[str(self.dirname).rfind("/") + 1:] + "/") + "\" -name \"*.err\" -exec rm -f {} \;\n") batch.write("find \"" + str(self.dirname[str(self.dirname).rfind("/") + 1:] + "/") + "\" -name \"*.dat\" -exec rm -f {} \;\n") batch.write("find \"" + str(self.dirname[str(self.dirname).rfind("/") + 1:] + "/") + "\" -name \"*.sta\" -exec rm -f {} \;\n") batch.write( "tar cf \"" + str(self.dirname[str(self.dirname).rfind("/") + 1:] + ".tar\" \"" + str(self.dirname[str(self.dirname).rfind("/") + 1:] + "/") + "\"\n")) batch.write("rm -rf \"" + str(self.dirname[str(self.dirname).rfind("/") + 1:] + "/") + "\"\n") batch.close() os.chdir("c:/") fnull = open(os.devnull, 'w') #Generate the full zip name: zipname = tempfile.gettempdir() + "/" + str( self.dirname)[str(self.dirname).rfind("/") + 1:] + ".zip" #Check if the zip file already exists. If yes, then we have to remove it if os.path.exists(zipname): try: os.remove(zipname) except Exception, e: print e
def start_calculation(self): self.button_add_to_table.setEnabled(False) self.button_select_file.setEnabled(False) self.button_select_output.setEnabled(False) self.button_start_calculation.setEnabled(False) os.chdir(homepath) ##Get values from the GUI if ( os.path.exists(str(self.dirname)) ): os.chdir(homepath) shutil.rmtree(str(self.dirname)) os.mkdir(str(self.dirname)) batch = open(str(self.dirname + "/" + "lcmt_CALCULIX_Calculation_batch.bat"),'wb') batch.write("#!/bin/bash\n") batch.write("export CCX_NPROC=4\n") #Tell calculixs solver spooles how many cpus to use #batch.write("export CCX_NPROC=" + str(self.params.GetInt("NumberCPUs")) + "\n") #If we have a tcsh #batch.write("setenv CCX_NPROC 4\n") #Now do the calculation stuff for each row in the table for job in range (0,self.JobTable.rowCount()): #Extract the data from the table current_file_name = self.JobTable.item(job,0).text() z_offset_from = self.JobTable.item(job,2).data(QtCore.Qt.DisplayRole).toInt()[0] z_offset_to = self.JobTable.item(job,3).data(QtCore.Qt.DisplayRole).toInt()[0] z_offset_intervall = self.JobTable.item(job,4).data(QtCore.Qt.DisplayRole).toInt()[0] x_rot_from = self.JobTable.item(job,5).data(QtCore.Qt.DisplayRole).toInt()[0] x_rot_to = self.JobTable.item(job,6).data(QtCore.Qt.DisplayRole).toInt()[0] x_rot_intervall = self.JobTable.item(job,7).data(QtCore.Qt.DisplayRole).toInt()[0] y_rot_from = self.JobTable.item(job,8).data(QtCore.Qt.DisplayRole).toInt()[0] y_rot_to = self.JobTable.item(job,9).data(QtCore.Qt.DisplayRole).toInt()[0] y_rot_intervall = self.JobTable.item(job,10).data(QtCore.Qt.DisplayRole).toInt()[0] z_rot_from = self.JobTable.item(job,11).data(QtCore.Qt.DisplayRole).toInt()[0] z_rot_to = self.JobTable.item(job,12).data(QtCore.Qt.DisplayRole).toInt()[0] z_rot_intervall = self.JobTable.item(job,13).data(QtCore.Qt.DisplayRole).toInt()[0] young_modulus = self.JobTable.item(job,14).data(QtCore.Qt.DisplayRole).toDouble()[0] poisson_ratio = self.JobTable.item(job,15).data(QtCore.Qt.DisplayRole).toDouble()[0] lc1 = self.JobTable.item(job,16).data(QtCore.Qt.DisplayRole).toDouble()[0] lc2 = self.JobTable.item(job,17).data(QtCore.Qt.DisplayRole).toDouble()[0] lc3 = self.JobTable.item(job,18).data(QtCore.Qt.DisplayRole).toDouble()[0] lc4 = self.JobTable.item(job,19).data(QtCore.Qt.DisplayRole).toDouble()[0] lc5 = self.JobTable.item(job,20).data(QtCore.Qt.DisplayRole).toDouble()[0] lc6 = self.JobTable.item(job,21).data(QtCore.Qt.DisplayRole).toDouble()[0] ltc1 = self.JobTable.item(job,22).data(QtCore.Qt.DisplayRole).toDouble()[0] ltc2 = self.JobTable.item(job,23).data(QtCore.Qt.DisplayRole).toDouble()[0] ltc3 = self.JobTable.item(job,24).data(QtCore.Qt.DisplayRole).toDouble()[0] ltc4 = self.JobTable.item(job,25).data(QtCore.Qt.DisplayRole).toDouble()[0] ltc5 = self.JobTable.item(job,26).data(QtCore.Qt.DisplayRole).toDouble()[0] ltc6 = self.JobTable.item(job,27).data(QtCore.Qt.DisplayRole).toDouble()[0] plate_thickness = self.JobTable.item(job,28).data(QtCore.Qt.DisplayRole).toDouble()[0] filename_without_suffix = self.JobTable.item(job,0).text().split("/").takeLast().split(".")[0] print current_file_name meshobject = Fem.read(str(current_file_name)) #Perform PCA Fem.SMESH_PCA(meshobject) #Do min routine Fem.minBoundingBox(meshobject) #Now get the Node Numbers for the Boundary Conditions node_numbers = [] node_numbers = Fem.getBoundary_Conditions(meshobject) #Now we have set up the initial geometry for the calculations. Lets generate an ABAQUS input file now for each z-level with exactly the same #boundary conditions #1. Lets translate the geometry to the initial desired z-level #2. Generate a Folder for the current calculation z-level and output the ABAQUS Geometry and the boundary_conditions #Lets first generate a subfolder with the current filename os.mkdir(str(self.dirname + "/" + filename_without_suffix)) i = z_offset_from while i <= z_offset_to: j = x_rot_from while j <= x_rot_to: k = y_rot_from while k <= y_rot_to: l = z_rot_from while l <= z_rot_to: rotation_around_x = FreeCAD.Base.Placement(FreeCAD.Base.Vector(0,0,0),FreeCAD.Base.Vector(1,0,0),j) rotation_around_y = FreeCAD.Base.Placement(FreeCAD.Base.Vector(0,0,0),FreeCAD.Base.Vector(0,1,0),k) rotation_around_z = FreeCAD.Base.Placement(FreeCAD.Base.Vector(0,0,0),FreeCAD.Base.Vector(0,0,1),l) translate = FreeCAD.Base.Placement(FreeCAD.Base.Vector(0,0,i),FreeCAD.Base.Vector(0,0,0),0.0) translation = rotation_around_x.multiply(rotation_around_y).multiply(rotation_around_z).multiply(translate) #Now lets check if the part is still in the billet due to the rotation. If not, we directly skip to the next rotation value if(Fem.checkBB(meshobject,translation,plate_thickness)): print "Too heavy rotations" print str(plate_thickness) l= l + z_rot_intervall continue print "it seems that nothing changed" print str(plate_thickness) #Use the placedment as optional argument for the write() method #translated_mesh.setTransform(translation) Case_Dir = str(self.dirname) + "/" + filename_without_suffix + "/" + filename_without_suffix +\ "_"+"x_rot"+ str(int(j))+ \ "_"+"y_rot"+ str(int(k))+ \ "_"+"z_rot"+ str(int(l))+ \ "_"+"z_l"+ str(int(i)) if ( os.path.exists(str(Case_Dir)) ): os.chdir(str(self.dirname)) shutil.rmtree(str(Case_Dir)) os.mkdir(str(Case_Dir)) os.chdir(homepath) #Lets generate a sigini Input Deck for the calculix user subroutine sigini_input = open (str(Case_Dir + "/" + "sigini_input.txt"),'wb') #Write plate thickness to the sigini_file sigini_input.write(str(plate_thickness) + "\n") #Now write the Interpolation coefficients, first the L and then the LC ones sigini_input.write(\ str(lc1) + "," + \ str(lc2) + "," + \ str(lc3) + "," + \ str(lc4) + "," + \ str(lc5) + "," + \ str(lc6) + "\n") sigini_input.write(\ str(ltc1) + "," + \ str(ltc2) + "," + \ str(ltc3) + "," + \ str(ltc4) + "," + \ str(ltc5) + "," + \ str(ltc6) + "\n") sigini_input.close() #Check if the meshobject.writeABAQUS(str(Case_Dir + "/" + "geometry_fe_input.inp"), translation) ApplyingBC_IC(Case_Dir, young_modulus,poisson_ratio,node_numbers[0],node_numbers[1],node_numbers[2]) #Now lets generate a LSF Job-File to be used by the Airbus Clusters #lsf_input = open (str(Case_Dir + "/" + "job.lsf"),"wb") #lsf_input.write("#!/bin/bash\n") #lsf_input.write("export CCX_NPROC=" + str(self.params.GetInt("NumberCPUs")) + "\n") #lsf_input.write("#BSUB -n "+ str(self.params.GetInt("NumberCPUs")) + "\n") #lsf_input.write("#BSUB -W 10:00\n") #lsf_input.write("#BSUB -o %J.out\n") #lsf_input.write("#BSUB -e %J.err\n") #lsf_input.write("#BSUB -J calculix\n") #lsf_input.write("#BSUB -q loc_dev_par\n") #lsf_input.write(str("datadir=\"" + homepath + "/" + self.dirname[str(self.dirname).rfind("/")+1:] + "/" + filename_without_suffix + "/" + filename_without_suffix + #"_"+"x_rot"+ str(int(j))+ #"_"+"y_rot"+ str(int(k))+ #"_"+"z_rot"+ str(int(l))+ #"_"+"z_l"+ str(int(i)) + "\"\n")) #lsf_input.write("cd $datadir\n") #lsf_input.write("ccx -i geometry_fe_input\n") #lsf_input.close() batch.write("cd \"" + str(Case_Dir) + "\"\n") batch.write("ccx -i geometry_fe_input\n") l= l + z_rot_intervall k = k + y_rot_intervall j = j + x_rot_intervall i = i+ z_offset_intervall batch.write("cd \"" + homepath + "\"\n") #batch.write("find \"" + str(self.dirname[str(self.dirname).rfind("/")+1:] + "/") + "\" -name \"sigini_output.txt\" -exec rm -f {} \;\n") #batch.write("find \"" + str(self.dirname[str(self.dirname).rfind("/")+1:] + "/") + "\" -name \"*.out\" -exec rm -f {} \;\n") #batch.write("find \"" + str(self.dirname[str(self.dirname).rfind("/")+1:] + "/") + "\" -name \"*.err\" -exec rm -f {} \;\n") #batch.write("find \"" + str(self.dirname[str(self.dirname).rfind("/")+1:] + "/") + "\" -name \"*.dat\" -exec rm -f {} \;\n") #batch.write("find \"" + str(self.dirname[str(self.dirname).rfind("/")+1:] + "/") + "\" -name \"*.sta\" -exec rm -f {} \;\n") #batch.write("tar cf \"" + str(self.dirname[str(self.dirname).rfind("/")+1:] + ".tar\" \"" + str(self.dirname[str(self.dirname).rfind("/")+1:] + "/") + "\"\n")) #batch.write("rm -rf \"" + str(self.dirname[str(self.dirname).rfind("/")+1:] + "/") + "\"\n") batch.close() os.chdir(homepath) fnull = open(os.devnull, 'w') # #Generate the full tar name: # tarname = homepath + "/" + str(self.dirname)[str(self.dirname).rfind("/")+1:] + ".tar" # #Check if the tar file already exists. If yes, then we have to remove it # if os.path.exists(tarname): # try: # os.remove(tarname) # except Exception,e: # print e # # #tar the whole directory structure now and save the zip file in the temp folder for further processing # commandline = "tar cf \"" + tarname + "\" \"" + str(self.dirname) + "\" \n" # print commandline # result = subprocess.call(commandline, shell = False, stdout = fnull, stderr = fnull) # #somehow we have to check for a false return code! # if not result: # shutil.rmtree(str(self.dirname)) # # #Now send the zip file to the server for calculation # commandline = "scp -r \"" + tarname + "\" " + self.params.GetString("Servername") + ":" + homepath # print commandline # result = subprocess.call(commandline, shell = False, stdout = fnull, stderr = fnull) # # #Now untar, change into the directory and start the batch file # commandline = "ssh " + self.params.GetString("Servername") + " tar -xf \"" + tarname + "\"" # print commandline # result = subprocess.call(commandline, shell = False, stdout = fnull, stderr = fnull) # # commandline = "ssh " + self.params.GetString("Servername") + " chmod +x -R \"" + homepath + "/" + str(self.dirname)[str(self.dirname).rfind("/")+1:] + "\"" # print commandline # result = subprocess.call(commandline, shell = False, stdout = fnull, stderr = fnull) # # #Now we copy the batch file one level ahead as otherwise we cannot delete the calculation folder # commandline = "ssh " + self.params.GetString("Servername") + " mv \"" + homepath + "/" + str(self.dirname)[str(self.dirname).rfind("/")+1:] + "/lcmt_CALCULIX_Calculation_batch.bat\" " + homepath # print commandline # result = subprocess.call(commandline, shell = False, stdout = fnull, stderr = fnull) # #Set proper rights on the batch file commandline = "chmod +x \"" + str(self.dirname) + "/lcmt_CALCULIX_Calculation_batch.bat\"" print commandline result = subprocess.call(commandline, shell = True, stdout = fnull, stderr = fnull) #Start the Batch-File commandline = "\"" + str(self.dirname) + "/lcmt_CALCULIX_Calculation_batch.bat\"" print commandline result = subprocess.call(commandline, shell = True, stdout = fnull, stderr = fnull) # #Now send the zip file to the server for calculation # commandline = FreeCAD.getHomePath() + "bin/pscp -r -l "+ self.params.GetString("Linux User Name") + " -pw " + self.params.GetString("Linux Password") + " " + \ # "\"" + zipname + "\" " + self.params.GetString("Servername") + ":" + self.params.GetString("Linux Home Path") # result = subprocess.call(commandline, shell = False, stdout = fnull, stderr = fnull) # #Now unzip, change into the directory and start the batch file # commandline = FreeCAD.getHomePath() + "bin/plink -batch -l "+ self.params.GetString("Linux User Name") + " -pw " + self.params.GetString("Linux Password") + " " + \ # self.params.GetString("Servername") + " unzip -o \"" + self.params.GetString("Linux Home Path") + "/" + str(self.dirname)[str(self.dirname).rfind("/")+1:] + ".zip\"" # result = subprocess.call(commandline, shell = False, stdout = fnull, stderr = fnull) # commandline = FreeCAD.getHomePath() + "bin/plink -batch -l "+ self.params.GetString("Linux User Name") + " -pw " + self.params.GetString("Linux Password") + " " + \ # self.params.GetString("Servername") + " chmod +x -R \"" + self.params.GetString("Linux Home Path") + "/" + str(self.dirname)[str(self.dirname).rfind("/")+1:] + "\"" # result = subprocess.call(commandline, shell = False, stdout = fnull, stderr = fnull) # commandline = FreeCAD.getHomePath() + "bin/plink -batch -l "+ self.params.GetString("Linux User Name") + " -pw " + self.params.GetString("Linux Password") + " " + \ # self.params.GetString("Servername") + " chmod +x -R \"" + self.params.GetString("Linux Home Path") + "/" + str(self.dirname)[str(self.dirname).rfind("/")+1:] + "\"" # result = subprocess.call(commandline, shell = False, stdout = fnull, stderr = fnull) # #Now we copy the batch file one level ahead as otherwise we cannot delete the calculation folder # commandline = FreeCAD.getHomePath() + "bin/plink -batch -l "+ self.params.GetString("Linux User Name") + " -pw " + self.params.GetString("Linux Password") + " " + \ # self.params.GetString("Servername") + " mv \"" + self.params.GetString("Linux Home Path") + "/" + str(self.dirname)[str(self.dirname).rfind("/")+1:] + "/lcmt_CALCULIX_Calculation_batch.bat\" " + self.params.GetString("Linux Home Path") # result = subprocess.call(commandline, shell = False, stdout = fnull, stderr = fnull) # #Start the Batch-File # commandline = FreeCAD.getHomePath() + "bin/plink -batch -l "+ self.params.GetString("Linux User Name") + " -pw " + self.params.GetString("Linux Password") + " " + \ # self.params.GetString("Servername") + " " + self.params.GetString("Linux Home Path") + "lcmt_CALCULIX_Calculation_batch.bat" # result = subprocess.call(commandline, shell = False, stdout = fnull, stderr = fnull) #commandline = "plink -batch -l UN -pw PW dynabox \'/home/rmjzettl/" + str(self.dirname[str(self.dirname).rfind("/")+1:] + "/") + "lcmt_CALCULIX_Calculation_batch.bat\'" #result = subprocess.call(commandline, shell = False, stdout = fnull, stderr = fnull) #commandline = "pscp -r -l UN -pw PW dynabox:\"/home/rmjzettl/"+ str(self.dirname)[str(self.dirname).rfind("/")+1:] + ".tar\" " + str(self.dirname)[0:3] #result = subprocess.call(commandline, shell = False, stdout = fnull, stderr = fnull) #commandline = "plink -batch -l UN -pw PW dynabox rm -f \"/home/rmjzettl/"+ str(self.dirname)[str(self.dirname).rfind("/")+1:] + ".tar\"" #result = subprocess.call(commandline, shell = False, stdout = fnull, stderr = fnull) #commandline = "plink -batch -l UN -pw PW dynabox rm -f \"/home/rmjzettl/"+ str(self.dirname)[str(self.dirname).rfind("/")+1:] + ".zip\"" #result = subprocess.call(commandline, shell = False, stdout = fnull, stderr = fnull) #commandline = "7z x \"" + str(self.dirname)[0:3] + str(self.dirname)[str(self.dirname).rfind("/")+1:] + ".tar\" -o\"" + str(self.dirname[0:str(self.dirname).rfind("/")]) + "\"" #result = subprocess.call(commandline, shell = False, stdout = fnull, stderr = fnull) #commandline = "del /Q \"" + str(self.dirname)[0:3] + str(self.dirname)[str(self.dirname).rfind("/")+1:] + ".tar\"" #result = subprocess.call(commandline, shell = False, stdout = fnull, stderr = fnull) #commandline = "del /Q \"" + str(self.dirname)[0:3] + str(self.dirname)[str(self.dirname).rfind("/")+1:] + ".zip\"" #result = subprocess.call(commandline, shell = False, stdout = fnull, stderr = fnull) fnull.close() #Reset the GUI os.chdir(homepath) #Reset the table to be fully empty i = self.JobTable.rowCount() while i > 0: print i self.JobTable.removeRow(i-1) i = i-1 print "after" self.JobTable.setHorizontalHeaderLabels( ["Input File","Output Folder","Z-Offset From","Z-Offset To","Z-Intervall","X-Rot From","X-Rot To","X-Rot Intervall", "Y-Rot From","Y-Rot To","Y-Rot Intervall","Z-Rot From","Z-Rot To","Z-Rot Intervall","Young Modulus","Poisson Ratio", "LC1","LC2","LC3","LC4","LC5","LC6","LTC1","LTC2","LTC3","LTC4","LTC5","LTC6","Plate Thickness"]) self.button_select_file.setEnabled(True) self.button_select_output.setEnabled(True)
def test_mesh_tetra10(self): # 10 node tetrahedron --> tetra10 elem = 'tetra10' femmesh = Fem.FemMesh() femmesh.addNode(6, 12, 18, 1) femmesh.addNode(0, 0, 18, 2) femmesh.addNode(12, 0, 18, 3) femmesh.addNode(6, 6, 0, 4) femmesh.addNode(3, 6, 18, 5) femmesh.addNode(6, 0, 18, 6) femmesh.addNode(9, 6, 18, 7) femmesh.addNode(6, 9, 9, 8) femmesh.addNode(3, 3, 9, 9) femmesh.addNode(9, 3, 9, 10) femmesh.addVolume([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) node_data = { 'count': femmesh.NodeCount, 'nodes': femmesh.Nodes } elem_data = {'volcount': femmesh.VolumeCount, 'tetcount': femmesh.TetraCount, 'volumes': { femmesh.Volumes[0], femmesh.getElementNodes(femmesh.Volumes[0]), }} expected_nodes = {'count': 10, 'nodes': { 1: FreeCAD.Vector(6.0, 12.0, 18.0), 2: FreeCAD.Vector(0.0, 0.0, 18.0), 3: FreeCAD.Vector(12.0, 0.0, 18.0), 4: FreeCAD.Vector(6.0, 6.0, 0.0), 5: FreeCAD.Vector(3.0, 6.0, 18.0), 6: FreeCAD.Vector(6.0, 0.0, 18.0), 7: FreeCAD.Vector(9.0, 6.0, 18.0), 8: FreeCAD.Vector(6.0, 9.0, 9.0), 9: FreeCAD.Vector(3.0, 3.0, 9.0), 10: FreeCAD.Vector(9.0, 3.0, 9.0), }} expected_elem = {'volcount': 1, 'tetcount': 1, 'volumes': { 1, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) }} ''' fcc_print('\n') fcc_print(elem_data) fcc_print(expected_elem) fcc_print('\n') ''' self.assertEqual(node_data, expected_nodes, "Nodes of Python created " + elem + "mesh element are unexpected") self.assertEqual(elem_data, expected_elem, "Elements of Python created " + elem + "mesh element are unexpected") ''' obj = doc.addObject("Fem::FemMeshObject" , elem) obj.FemMesh = femmesh obj.Placement.Base = (30,50,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" ''' fcc_print(elem + 'export tests.\n') base_outfile = testtools.get_fem_test_tmp_dir() + '/' + elem + '_mesh.' base_testfile = testtools.get_fem_test_home_dir() + 'mesh/' + elem + '_mesh.' filetyp = 'inp' outfile = base_outfile + filetyp testfile = base_testfile + filetyp femmesh.writeABAQUS(outfile, 1, False) import feminout.importToolsFem import feminout.importInpMesh femmesh_outfile = feminout.importToolsFem.make_femmesh(feminout.importInpMesh.read_inp(outfile)) femmesh_testfile = feminout.importToolsFem.make_femmesh(feminout.importInpMesh.read_inp(testfile)) self.assertEqual(femmesh_outfile.Nodes, femmesh_testfile.Nodes, "Test writing " + elem + " mesh to " + filetyp + " file failed. Nodes are different.\n") self.assertEqual(femmesh_outfile.Volumes, femmesh_testfile.Volumes, "Test writing " + elem + " mesh to " + filetyp + " file failed. Volumes are different.\n") filetyp = 'unv' outfile = base_outfile + filetyp testfile = base_testfile + filetyp femmesh.write(outfile) femmesh_outfile = Fem.read(outfile) femmesh_testfile = Fem.read(testfile) self.assertEqual(femmesh_outfile.Nodes, femmesh_testfile.Nodes, "Test writing " + elem + " mesh to " + filetyp + " file failed. Nodes are different.\n") self.assertEqual(femmesh_outfile.Volumes, femmesh_testfile.Volumes, "Test writing " + elem + " mesh to " + filetyp + " file failed. Volumes are different.\n")
def start_calculation(self): self.button_add_to_table.setEnabled(False) self.button_select_file.setEnabled(False) self.button_select_output.setEnabled(False) self.button_start_calculation.setEnabled(False) os.chdir("/") ##Get values from the GUI if ( os.path.exists(str(self.dirname)) ): os.chdir("c:/") shutil.rmtree(str(self.dirname)) os.mkdir(str(self.dirname)) batch = open(str(self.dirname + "/" + "lcmt_CALCULIX_Calculation_batch.bat"),'wb') #Tell calculixs solver spooles how many cpus to use #batch.write("export CCX_NPROC=" + str(self.params.GetInt("NumberCPUs")) + "\n") #If we have a tcsh #batch.write("setenv CCX_NPROC 4\n") #Now do the calculation stuff for each row in the table for job in range (0,self.JobTable.rowCount()): #Extract the data from the table current_file_name = self.JobTable.item(job,0).text() z_offset_from = self.JobTable.item(job,2).data(QtCore.Qt.DisplayRole).toInt()[0] z_offset_to = self.JobTable.item(job,3).data(QtCore.Qt.DisplayRole).toInt()[0] z_offset_intervall = self.JobTable.item(job,4).data(QtCore.Qt.DisplayRole).toInt()[0] x_rot_from = self.JobTable.item(job,5).data(QtCore.Qt.DisplayRole).toInt()[0] x_rot_to = self.JobTable.item(job,6).data(QtCore.Qt.DisplayRole).toInt()[0] x_rot_intervall = self.JobTable.item(job,7).data(QtCore.Qt.DisplayRole).toInt()[0] y_rot_from = self.JobTable.item(job,8).data(QtCore.Qt.DisplayRole).toInt()[0] y_rot_to = self.JobTable.item(job,9).data(QtCore.Qt.DisplayRole).toInt()[0] y_rot_intervall = self.JobTable.item(job,10).data(QtCore.Qt.DisplayRole).toInt()[0] z_rot_from = self.JobTable.item(job,11).data(QtCore.Qt.DisplayRole).toInt()[0] z_rot_to = self.JobTable.item(job,12).data(QtCore.Qt.DisplayRole).toInt()[0] z_rot_intervall = self.JobTable.item(job,13).data(QtCore.Qt.DisplayRole).toInt()[0] young_modulus = self.JobTable.item(job,14).data(QtCore.Qt.DisplayRole).toDouble()[0] poisson_ratio = self.JobTable.item(job,15).data(QtCore.Qt.DisplayRole).toDouble()[0] lc1 = self.JobTable.item(job,16).data(QtCore.Qt.DisplayRole).toDouble()[0] lc2 = self.JobTable.item(job,17).data(QtCore.Qt.DisplayRole).toDouble()[0] lc3 = self.JobTable.item(job,18).data(QtCore.Qt.DisplayRole).toDouble()[0] lc4 = self.JobTable.item(job,19).data(QtCore.Qt.DisplayRole).toDouble()[0] lc5 = self.JobTable.item(job,20).data(QtCore.Qt.DisplayRole).toDouble()[0] lc6 = self.JobTable.item(job,21).data(QtCore.Qt.DisplayRole).toDouble()[0] ltc1 = self.JobTable.item(job,22).data(QtCore.Qt.DisplayRole).toDouble()[0] ltc2 = self.JobTable.item(job,23).data(QtCore.Qt.DisplayRole).toDouble()[0] ltc3 = self.JobTable.item(job,24).data(QtCore.Qt.DisplayRole).toDouble()[0] ltc4 = self.JobTable.item(job,25).data(QtCore.Qt.DisplayRole).toDouble()[0] ltc5 = self.JobTable.item(job,26).data(QtCore.Qt.DisplayRole).toDouble()[0] ltc6 = self.JobTable.item(job,27).data(QtCore.Qt.DisplayRole).toDouble()[0] plate_thickness = self.JobTable.item(job,28).data(QtCore.Qt.DisplayRole).toDouble()[0] filename_without_suffix = self.JobTable.item(job,0).text().split("/").takeLast().split(".")[0] meshobject = Fem.read(str(current_file_name)) #Perform PCA Fem.SMESH_PCA(meshobject) #Do min routine Fem.minBoundingBox(meshobject) #Now get the Node Numbers for the Boundary Conditions node_numbers = [] node_numbers = Fem.getBoundary_Conditions(meshobject) #Now we have set up the initial geometry for the calculations. Lets generate an ABAQUS input file now for each z-level with exactly the same #boundary conditions #1. Lets translate the geometry to the initial desired z-level #2. Generate a Folder for the current calculation z-level and output the ABAQUS Geometry and the boundary_conditions #Lets first generate a subfolder with the current filename os.mkdir(str(self.dirname + "/" + filename_without_suffix)) i = z_offset_from while i <= z_offset_to: j = x_rot_from while j <= x_rot_to: k = y_rot_from while k <= y_rot_to: l = z_rot_from while l <= z_rot_to: rotation_around_x = FreeCAD.Base.Placement(FreeCAD.Base.Vector(0,0,0),FreeCAD.Base.Vector(1,0,0),j) rotation_around_y = FreeCAD.Base.Placement(FreeCAD.Base.Vector(0,0,0),FreeCAD.Base.Vector(0,1,0),k) rotation_around_z = FreeCAD.Base.Placement(FreeCAD.Base.Vector(0,0,0),FreeCAD.Base.Vector(0,0,1),l) translate = FreeCAD.Base.Placement(FreeCAD.Base.Vector(0,0,i),FreeCAD.Base.Vector(0,0,0),0.0) translation = rotation_around_x.multiply(rotation_around_y).multiply(rotation_around_z).multiply(translate) #Now lets check if the part is still in the billet due to the rotation. If not, we directly skip to the next rotation value if(Fem.checkBB(meshobject,translation,plate_thickness)): print "Too heavy rotations" l= l + z_rot_intervall continue print "it seems that nothing changed" #Use the placedment as optional argument for the write() method #translated_mesh.setTransform(translation) Case_Dir = str(self.dirname) + "/" + filename_without_suffix + "/" + filename_without_suffix +\ "_"+"x_rot"+ str(int(j))+ \ "_"+"y_rot"+ str(int(k))+ \ "_"+"z_rot"+ str(int(l))+ \ "_"+"z_l"+ str(int(i)) if ( os.path.exists(str(Case_Dir)) ): os.chdir(str(self.dirname)) shutil.rmtree(str(Case_Dir)) os.mkdir(str(Case_Dir)) os.chdir("c:/") #Lets generate a sigini Input Deck for the calculix user subroutine sigini_input = open (str(Case_Dir + "/" + "sigini_input.txt"),'wb') #Write plate thickness to the sigini_file sigini_input.write(str(plate_thickness) + "\n") #Now write the Interpolation coefficients, first the L and then the LC ones sigini_input.write(\ str(lc1) + "," + \ str(lc2) + "," + \ str(lc3) + "," + \ str(lc4) + "," + \ str(lc5) + "," + \ str(lc6) + "\n") sigini_input.write(\ str(ltc1) + "," + \ str(ltc2) + "," + \ str(ltc3) + "," + \ str(ltc4) + "," + \ str(ltc5) + "," + \ str(ltc6) + "\n") sigini_input.close() #Check if the meshobject.writeABAQUS(str(Case_Dir + "/" + "geometry_fe_input.inp"), translation) ApplyingBC_IC(Case_Dir, young_modulus,poisson_ratio,node_numbers[0],node_numbers[1],node_numbers[2]) #Now lets generate a LSF Job-File to be used by the Airbus Clusters lsf_input = open (str(Case_Dir + "/" + "job.lsf"),"wb") lsf_input.write("#!/bin/bash\n") lsf_input.write("export CCX_NPROC=" + str(self.params.GetInt("NumberCPUs")) + "\n") lsf_input.write("#BSUB -n "+ str(self.params.GetInt("NumberCPUs")) + "\n") lsf_input.write("#BSUB -W 10:00\n") lsf_input.write("#BSUB -o %J.out\n") lsf_input.write("#BSUB -e %J.err\n") lsf_input.write("#BSUB -J calculix\n") lsf_input.write("#BSUB -q loc_all_hiio\n") lsf_input.write(str("datadir=\"" + self.params.GetString("Linux Home Path") + "/" + self.dirname[str(self.dirname).rfind("/")+1:] + "/" + filename_without_suffix + "/" + filename_without_suffix + "_"+"x_rot"+ str(int(j))+ "_"+"y_rot"+ str(int(k))+ "_"+"z_rot"+ str(int(l))+ "_"+"z_l"+ str(int(i)) + "\"\n")) lsf_input.write("cd $datadir\n") lsf_input.write(self.params.GetString("Solver Link") + " -i final_fe_input\n") lsf_input.close() batch.write(str("cd \"" + self.params.GetString("Linux Home Path") + "/" + self.dirname[str(self.dirname).rfind("/")+1:] + "/" + filename_without_suffix + "/" + filename_without_suffix + "_"+"x_rot"+ str(int(j))+ "_"+"y_rot"+ str(int(k))+ "_"+"z_rot"+ str(int(l))+ "_"+"z_l"+ str(int(i)) + "\"\n")) batch.write("job.lsf\n") l= l + z_rot_intervall k = k + y_rot_intervall j = j + x_rot_intervall i = i+ z_offset_intervall print "Ale Schleifen beendet" batch.write("cd \"" + self.params.GetString("Linux Home Path") + "\"\n") batch.write("find \"" + str(self.dirname[str(self.dirname).rfind("/")+1:] + "/") + "\" -name \"sigini_output.txt\" -exec rm -f {} \;\n") batch.write("find \"" + str(self.dirname[str(self.dirname).rfind("/")+1:] + "/") + "\" -name \"*.out\" -exec rm -f {} \;\n") batch.write("find \"" + str(self.dirname[str(self.dirname).rfind("/")+1:] + "/") + "\" -name \"*.err\" -exec rm -f {} \;\n") batch.write("find \"" + str(self.dirname[str(self.dirname).rfind("/")+1:] + "/") + "\" -name \"*.dat\" -exec rm -f {} \;\n") batch.write("find \"" + str(self.dirname[str(self.dirname).rfind("/")+1:] + "/") + "\" -name \"*.sta\" -exec rm -f {} \;\n") batch.write("tar cf \"" + str(self.dirname[str(self.dirname).rfind("/")+1:] + ".tar\" \"" + str(self.dirname[str(self.dirname).rfind("/")+1:] + "/") + "\"\n")) batch.write("rm -rf \"" + str(self.dirname[str(self.dirname).rfind("/")+1:] + "/") + "\"\n") batch.close() os.chdir("c:/") fnull = open(os.devnull, 'w') #Generate the full zip name: zipname = tempfile.gettempdir() + "/" + str(self.dirname)[str(self.dirname).rfind("/")+1:] + ".zip" #Check if the zip file already exists. If yes, then we have to remove it if os.path.exists(zipname): try: os.remove(zipname) except Exception,e: print e
def import_mesh(self, mesh_file): # import from saved mesh file self.imported_mesh_object = CfdObjects.makeCfdMeshImported() self.imported_mesh_object.FemMesh = Fem.read(mesh_file) self.active_doc.recompute()
int temp files to load with FreeCAD. """ if case is None: raise RuntimeError("Case parameter must be populated") file_type = ".{}".format(filename.split(".")[-1]).lower() if scale_x <= 0: scale_x = 1 if scale_y <= 0: scale_y = 1 if scale_z <= 0: scale_z = 1 # TODO: Adapt to VTL (FEM lib, convert to other format) if file_type == ".vtk": loaded_mesh = Mesh.Mesh(femmesh_2_mesh(Fem.read(filename))) else: loaded_mesh = Mesh.read(filename) scale_matrix = FreeCAD.Matrix() scale_matrix.scale(scale_x, scale_y, scale_z) loaded_mesh.transform(scale_matrix) Mesh.show(loaded_mesh, name) FreeCADGui.SendMsgToActiveView("ViewFit") case.add_object(SimulationObject(name, case.get_first_mk_not_used(ObjectType.BOUND), ObjectType.BOUND, ObjectFillMode.SOLID)) case.get_simulation_object(name).autofill = autofill def create_flowtool_boxes(file_path: str, boxes: list): """ Creates a file with flowtool box information """