def calculixFinished(self, exitCode): print("calculixFinished() {}".format(exitCode)) print(self.Calculix.state()) # Restore previous cwd QtCore.QDir.setCurrent(self.cwd) self.printCalculiXstdout() self.Timer.stop() self.femConsoleMessage("CalculiX done!", "#00AA00") self.form.pb_run_ccx.setText("Re-run CalculiX") self.femConsoleMessage("Loading result sets...") self.form.l_time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start)) fea = ccxtools.FemToolsCcx(None, self.solver_object) fea.reset_mesh_purge_results_checked() fea.inp_file_name = self.inp_file_name QApplication.setOverrideCursor(Qt.WaitCursor) try: fea.load_results() except: QApplication.restoreOverrideCursor() majorVersion, minorVersion = fea.get_ccx_version() if majorVersion == 2 and minorVersion <= 10: message = "The used CalculiX version {}.{} creates broken output files.\n" \ "Please upgrade to a newer version.".format(majorVersion, minorVersion) QtGui.QMessageBox.warning(None, "Upgrade CalculiX", message) raise else: QApplication.restoreOverrideCursor() self.form.l_time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start))
def fea_run(self): fea = ccxtools.FemToolsCcx(analysis=self.analysis, solver=self.solver, test_mode=False) fea.setup_working_dir('./.solver') self.doc.recompute() fea.update_objects() message = fea.check_prerequisites() if message: error_message = "CalculiX was not started due to missing prerequisites:\n{}\n".format( message) FreeCAD.Console.PrintError(error_message) return False else: fea.write_inp_file() if fea.inp_file_name == "": error_message = "Error on writing CalculiX input file.\n" FreeCAD.Console.PrintError(error_message) return False else: FreeCAD.Console.PrintMessage( "Writing CalculiX input file completed.\n") ret_code = fea.ccx_run() if ret_code != 0: error_message = "CalculiX finished with error {}.\n".format( ret_code) FreeCAD.Console.PrintError(error_message) return False else: fea.load_results() return True
def input_file_writing_test( self, test_name, base_name, analysis_dir=None, test_end=False, ): fcc_print("\n--------------- " "Start of FEM ccxtools {} test" "---------------".format(base_name)) if analysis_dir is None: analysis_dir = testtools.get_fem_test_tmp_dir(self.pre_dir_name + base_name) analysis = self.document.Analysis solver_object = self.document.CalculiXccxTools fea = ccxtools.FemToolsCcx(analysis, solver_object, test_mode=True) fea.update_objects() fcc_print("Setting up working directory {}".format(analysis_dir)) fea.setup_working_dir(analysis_dir) self.assertTrue( True if fea.working_dir == analysis_dir else False, "Setting working directory {} failed".format(analysis_dir)) fcc_print( "Checking FEM inp file prerequisites for {} ...".format(base_name)) error = fea.check_prerequisites() self.assertFalse( error, "ccxtools check_prerequisites returned error message: {}".format( error)) inpfile_given = join(self.test_file_dir, (base_name + ".inp")) inpfile_totest = join(analysis_dir, (self.mesh_name + ".inp")) fcc_print("Checking FEM inp file write...") fcc_print("Writing {} for {}".format(inpfile_totest, base_name)) error = fea.write_inp_file() self.assertFalse(error, "Writing failed") fcc_print("Comparing {} to {}".format(inpfile_given, inpfile_totest)) ret = testtools.compare_inp_files(inpfile_given, inpfile_totest) self.assertFalse( ret, "ccxtools write_inp_file test failed.\n{}".format(ret)) if test_end is True: # do not save and print End of tests return fea save_fc_file = join(analysis_dir, base_name + ".FCStd") fcc_print("Save FreeCAD file for {} to {}...".format( base_name, save_fc_file)) self.document.saveAs(save_fc_file) fcc_print("\n--------------- " "End of FEM ccxtools {}" "---------------".format(base_name))
def IsActive(self): if FreeCAD.ActiveDocument is None: return False else: try: ccxtools.FemToolsCcx() except Exception: return False else: return True
def check_prerequisites_helper(self): self.Start = time.time() self.femConsoleMessage("Check dependencies...") self.form.l_time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start)) fea = ccxtools.FemToolsCcx(None, self.solver_object) fea.update_objects() message = fea.check_prerequisites() if message != "": QtGui.QMessageBox.critical(None, "Missing prerequisite(s)", message) return False return True
def Activated(self): import femsolver.run from PySide import QtGui def load_results(ret_code): if ret_code == 0: self.fea.load_results() elif ret_code == 201: if self.fea.solver.AnalysisType == 'check': print('We run into the NOANALYSIS problem!') # https://forum.freecadweb.org/viewtopic.php?f=18&t=31303&start=10#p260743 self.fea.load_results() else: print("CalculiX failed ccx finished with error {}".format(ret_code)) self.solver = self.selobj if self.solver.Proxy.Type == 'Fem::FemSolverCalculixCcxTools': print('CalxuliX ccx tools solver!') from femtools import ccxtools self.fea = ccxtools.FemToolsCcx(None, self.solver) self.fea.reset_mesh_purge_results_checked() message = self.fea.check_prerequisites() if message: QtGui.QMessageBox.critical(None, "Missing prerequisite", message) return self.fea.finished.connect(load_results) QtCore.QThreadPool.globalInstance().start(self.fea) else: print('Frame work solver!') try: machine = femsolver.run.getMachine(self.solver) except femsolver.run.MustSaveError: QtGui.QMessageBox.critical( FreeCADGui.getMainWindow(), "Can't start Solver", "Please save the file before executing the solver. " "This must be done because the location of the working " "directory is set to \"Beside .fcstd File\".") return except femsolver.run.DirectoryDoesNotExist: QtGui.QMessageBox.critical( FreeCADGui.getMainWindow(), "Can't start Solver", "Selected working directory doesn't exist.") return if not machine.running: machine.reset() machine.target = femsolver.run.RESULTS machine.start() machine.join() # wait for the machine to finish. FreeCADGui.Selection.clearSelection() FreeCAD.ActiveDocument.recompute()
def test_2_static_multiple_material(self): fcc_print( "\n--------------- Start of FEM ccxtools multiple material test -------------" ) # set up the simple multimat example from femexamples import multimaterial_twoboxes multimaterial_twoboxes.setup(self.active_doc, "ccxtools") analysis = self.active_doc.Analysis solver_object = self.active_doc.CalculiXccxTools static_multiplemat_dir = testtools.get_unit_test_tmp_dir( self.temp_dir, "FEM_ccx_multimat/") fea = ccxtools.FemToolsCcx(analysis, solver_object, test_mode=True) fea.update_objects() fea.setup_working_dir(static_multiplemat_dir) fcc_print( "Checking FEM inp file prerequisites for ccxtools multimat analysis..." ) error = fea.check_prerequisites() self.assertFalse( error, "ccxtools check_prerequisites returned error message: {}".format( error)) static_base_name = "multimat" inpfile_given = join(self.test_file_dir, (static_base_name + ".inp")) inpfile_totest = join(static_multiplemat_dir, (self.mesh_name + ".inp")) fcc_print("Checking FEM inp file write...") fcc_print( "Writing {} for static multiple material".format(inpfile_totest)) error = fea.write_inp_file() self.assertFalse(error, "Writing failed") fcc_print("Comparing {} to {}".format(inpfile_given, inpfile_totest)) ret = testtools.compare_inp_files(inpfile_given, inpfile_totest) self.assertFalse( ret, "ccxtools write_inp_file test failed.\n{}".format(ret)) static_save_fc_file = static_multiplemat_dir + static_base_name + ".FCStd" fcc_print("Save FreeCAD file for static analysis to {}...".format( static_save_fc_file)) self.active_doc.saveAs(static_save_fc_file) fcc_print( "--------------- End of FEM ccxtools multiple material test -----------------" )
def Activated(self): fea = ccxtools.FemToolsCcx() fea.update_objects() fea.setup_working_dir() # sets up fea.working_dir fea.setup_ccx() # sets up fea.ccx_binary message = fea.check_prerequisites() # setup start parameters for optimization preferences = {} preferences["ccx_binary_path"] = fea.ccx_binary preferences["working_directory"] = fea.working_dir taskpanel = TaskPanelToOptixStart(fea, message, preferences) FreeCADGui.Control.showDialog(taskpanel)
def run(self): # self.doc.recompute() fea = ccxtools.FemToolsCcx(analysis=self.analysis, solver=self.solver, test_mode=False) # fea.setup_working_dir('solver-tmp') self.doc.recompute() message = fea.update_objects() if not message: fea.reset_all() fea.run() fea.load_results() else: raise Exception('AutoFEA -- error while running FEA analysis - {}'.format(message)) for mem in self.analysis.Group: if mem.isDerivedFrom('Fem::FemResultObject'): return mem
def Activated(self): import femsolver.run from PySide import QtGui def load_results(ret_code): if ret_code == 0: self.fea.load_results() else: print("CalculiX failed ccx finished with error {}".format( ret_code)) self.solver = self.selobj if hasattr(self.solver, "SolverType" ) and self.solver.SolverType == "FemSolverCalculix": from femtools import ccxtools self.fea = ccxtools.FemToolsCcx(None, self.solver) self.fea.reset_mesh_purge_results_checked() message = self.fea.check_prerequisites() if message: QtGui.QMessageBox.critical(None, "Missing prerequisite", message) return self.fea.finished.connect(load_results) QtCore.QThreadPool.globalInstance().start(self.fea) else: try: machine = femsolver.run.getMachine(self.solver) except femsolver.run.MustSaveError: QtGui.QMessageBox.critical( FreeCADGui.getMainWindow(), "Can't start Solver", "Please save the file before executing the solver. " "This must be done because the location of the working " "directory is set to \"Beside .fcstd File\".") return except femsolver.run.DirectoryDoesNotExist: QtGui.QMessageBox.critical( FreeCADGui.getMainWindow(), "Can't start Solver", "Selected working directory doesn't exist.") return if not machine.running: machine.reset() machine.target = femsolver.run.RESULTS machine.start() machine.join() # wait for the machine to finish. FreeCADGui.Selection.clearSelection()
def write_input_file_handler(self): self.Start = time.time() self.form.l_time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start)) QApplication.restoreOverrideCursor() if self.check_prerequisites_helper(): QApplication.setOverrideCursor(Qt.WaitCursor) self.inp_file_name = "" fea = ccxtools.FemToolsCcx(None, self.solver_object) fea.update_objects() fea.write_inp_file() if fea.inp_file_name != "": self.inp_file_name = fea.inp_file_name self.femConsoleMessage("Write completed.") self.form.pb_edit_inp.setEnabled(True) self.form.pb_run_ccx.setEnabled(True) else: self.femConsoleMessage("Write .inp file failed!", "#FF0000") QApplication.restoreOverrideCursor() self.form.l_time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start))
def Activated(self): import femsolver.run from PySide import QtGui self.solver = self.selobj if self.solver.Proxy.Type == 'Fem::FemSolverCalculixCcxTools': print('CalxuliX ccx tools solver!') from femtools import ccxtools self.fea = ccxtools.FemToolsCcx(None, self.solver) self.fea.reset_mesh_purge_results_checked() self.fea.run() else: print('Frame work solver!') try: machine = femsolver.run.getMachine(self.solver) except femsolver.run.MustSaveError: QtGui.QMessageBox.critical( FreeCADGui.getMainWindow(), "Can't start Solver", "Please save the file before executing the solver. " "This must be done because the location of the working " "directory is set to \"Beside .FCStd File\".") return except femsolver.run.DirectoryDoesNotExist: QtGui.QMessageBox.critical( FreeCADGui.getMainWindow(), "Can't start Solver", "Selected working directory doesn't exist.") return if not machine.running: machine.reset() machine.target = femsolver.run.RESULTS machine.start() machine.join() # wait for the machine to finish. FreeCADGui.Selection.clearSelection() FreeCAD.ActiveDocument.recompute()
def create_test_results(): import os import shutil import sys import FemGui import Test import femresult.resulttools as resulttools from femtools import ccxtools stat_types = [ "U1", "U2", "U3", "Uabs", "Sabs", "MaxPrin", "MidPrin", "MinPrin", "MaxShear", "Peeq", "Temp", "MFlow", "NPress" ] temp_dir = testtools.get_fem_test_tmp_dir() static_analysis_dir = temp_dir + "FEM_ccx_static/" frequency_analysis_dir = temp_dir + "FEM_ccx_frequency/" thermomech_analysis_dir = temp_dir + "FEM_ccx_thermomech/" Flow1D_thermomech_analysis_dir = temp_dir + "FEM_ccx_Flow1D_thermomech/" # run all unit tests from this module current_module = sys.modules[__name__] Test.runTestsFromModule(current_module) # static cube FreeCAD.open(static_analysis_dir + "cube_static.FCStd") FemGui.setActiveAnalysis(FreeCAD.ActiveDocument.Analysis) fea = ccxtools.FemToolsCcx() fea.update_objects() print("create static result files") fea.reset_all() fea.run() fea.load_results() stats_static = [] for s in stat_types: statval = resulttools.get_stats( FreeCAD.ActiveDocument.getObject("CalculiX_static_results"), s) stats_static.append("{0}: ({1:.14g}, {2:.14g}, {3:.14g})\n".format( s, statval[0], statval[1], statval[2])) static_expected_values_file = join(static_analysis_dir, "cube_static_expected_values") f = open(static_expected_values_file, "w") for s in stats_static: f.write(s) f.close() frd_result_file = os.path.splitext(fea.inp_file_name)[0] + ".frd" dat_result_file = os.path.splitext(fea.inp_file_name)[0] + ".dat" frd_static_test_result_file = static_analysis_dir + "cube_static.frd" dat_static_test_result_file = static_analysis_dir + "cube_static.dat" shutil.copyfile(frd_result_file, frd_static_test_result_file) shutil.copyfile(dat_result_file, dat_static_test_result_file) # frequency cube FreeCAD.open(frequency_analysis_dir + "cube_frequency.FCStd") FemGui.setActiveAnalysis(FreeCAD.ActiveDocument.Analysis) fea = ccxtools.FemToolsCcx() fea.update_objects() print("create frequency result files") fea.reset_all() fea.solver.EigenmodesCount = 1 # we should only have one result object fea.run() fea.load_results() stats_frequency = [] for s in stat_types: statval = resulttools.get_stats( FreeCAD.ActiveDocument.getObject( "CalculiX_frequency_mode_1_results"), s) stats_frequency.append("{0}: ({1:.14g}, {2:.14g}, {3:.14g})\n".format( s, statval[0], statval[1], statval[2])) frequency_expected_values_file = join(frequency_analysis_dir, "cube_frequency_expected_values") f = open(frequency_expected_values_file, "w") for s in stats_frequency: f.write(s) f.close() frd_frequency_test_result_file = frequency_analysis_dir + "cube_frequency.frd" dat_frequency_test_result_file = frequency_analysis_dir + "cube_frequency.dat" shutil.copyfile(frd_result_file, frd_frequency_test_result_file) shutil.copyfile(dat_result_file, dat_frequency_test_result_file) # thermomech print("create thermomech result files") FreeCAD.open(thermomech_analysis_dir + "spine_thermomech.FCStd") FemGui.setActiveAnalysis(FreeCAD.ActiveDocument.Analysis) fea = ccxtools.FemToolsCcx() fea.reset_all() fea.run() fea.load_results() stats_thermomech = [] for s in stat_types: statval = resulttools.get_stats( FreeCAD.ActiveDocument.getObject("CalculiX_thermomech_results"), s) stats_thermomech.append("{0}: ({1:.14g}, {2:.14g}, {3:.14g})\n".format( s, statval[0], statval[1], statval[2])) thermomech_expected_values_file = join(thermomech_analysis_dir, "spine_thermomech_expected_values") f = open(thermomech_expected_values_file, "w") for s in stats_thermomech: f.write(s) f.close() frd_result_file = os.path.splitext(fea.inp_file_name)[0] + ".frd" dat_result_file = os.path.splitext(fea.inp_file_name)[0] + ".dat" frd_thermomech_test_result_file = thermomech_analysis_dir + "spine_thermomech.frd" dat_thermomech_test_result_file = thermomech_analysis_dir + "spine_thermomech.dat" shutil.copyfile(frd_result_file, frd_thermomech_test_result_file) shutil.copyfile(dat_result_file, dat_thermomech_test_result_file) print("Results copied to the appropriate FEM test dirs in: " + temp_dir) # Flow1D print("create Flow1D result files") FreeCAD.open(Flow1D_thermomech_analysis_dir + "Flow1D_thermomech.FCStd") FemGui.setActiveAnalysis(FreeCAD.ActiveDocument.Analysis) fea = ccxtools.FemToolsCcx() fea.reset_all() fea.run() fea.load_results() stats_flow1D = [] for s in stat_types: statval = resulttools.get_stats( FreeCAD.ActiveDocument.getObject( "CalculiX_thermomech_time_1_0_results"), s) stats_flow1D.append("{0}: ({1:.14g}, {2:.14g}, {3:.14g})\n".format( s, statval[0], statval[1], statval[2])) Flow1D_thermomech_expected_values_file = join( Flow1D_thermomech_analysis_dir, "Flow1D_thermomech_expected_values") f = open(Flow1D_thermomech_expected_values_file, "w") for s in stats_flow1D: f.write(s) f.close() frd_result_file = os.path.splitext(fea.inp_file_name)[0] + ".frd" dat_result_file = os.path.splitext(fea.inp_file_name)[0] + ".dat" frd_Flow1D_thermomech_test_result_file = join( Flow1D_thermomech_analysis_dir, "Flow1D_thermomech.frd") dat_Flow1D_thermomech_test_result_file = join( Flow1D_thermomech_analysis_dir, "Flow1D_thermomech.dat") shutil.copyfile(frd_result_file, frd_Flow1D_thermomech_test_result_file) shutil.copyfile(dat_result_file, dat_Flow1D_thermomech_test_result_file) print( "Flow1D thermomech results copied to the appropriate FEM test dirs in: " + temp_dir)
def test_Flow1D_thermomech_analysis(self): fcc_print('--------------- Start of 1D Flow FEM tests ---------------') import Draft p1 = FreeCAD.Vector(0, 0, 50) p2 = FreeCAD.Vector(0, 0, -50) p3 = FreeCAD.Vector(0, 0, -4300) p4 = FreeCAD.Vector(4950, 0, -4300) p5 = FreeCAD.Vector(5000, 0, -4300) p6 = FreeCAD.Vector(8535.53, 0, -7835.53) p7 = FreeCAD.Vector(8569.88, 0, -7870.88) p8 = FreeCAD.Vector(12105.41, 0, -11406.41) p9 = FreeCAD.Vector(12140.76, 0, -11441.76) p10 = FreeCAD.Vector(13908.53, 0, -13209.53) p11 = FreeCAD.Vector(13943.88, 0, -13244.88) p12 = FreeCAD.Vector(15046.97, 0, -14347.97) p13 = FreeCAD.Vector(15046.97, 0, -7947.97) p14 = FreeCAD.Vector(15046.97, 0, -7847.97) p15 = FreeCAD.Vector(0, 0, 0) p16 = FreeCAD.Vector(0, 0, -2175) p17 = FreeCAD.Vector(2475, 0, -4300) p18 = FreeCAD.Vector(4975, 0, -4300) p19 = FreeCAD.Vector(6767.765, 0, -6067.765) p20 = FreeCAD.Vector(8552.705, 0, -7853.205) p21 = FreeCAD.Vector(10337.645, 0, -9638.645) p22 = FreeCAD.Vector(12123.085, 0, -11424.085) p23 = FreeCAD.Vector(13024.645, 0, -12325.645) p24 = FreeCAD.Vector(13926.205, 0, -13227.205) p25 = FreeCAD.Vector(14495.425, 0, -13796.425) p26 = FreeCAD.Vector(15046.97, 0, -11147.97) p27 = FreeCAD.Vector(15046.97, 0, -7897.97) points = [ p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27 ] line = Draft.makeWire(points, closed=False, face=False, support=None) fcc_print('Checking FEM new analysis...') analysis = ObjectsFem.makeAnalysis(self.active_doc, 'Analysis') self.assertTrue(analysis, "FemTest of new analysis failed") fcc_print('Checking FEM new solver...') solver_object = ObjectsFem.makeSolverCalculixCcxTools( self.active_doc, 'CalculiX') solver_object.AnalysisType = 'thermomech' solver_object.GeometricalNonlinearity = 'linear' solver_object.ThermoMechSteadyState = True solver_object.MatrixSolverType = 'default' solver_object.IterationsThermoMechMaximum = 2000 solver_object.IterationsControlParameterTimeUse = False self.assertTrue(solver_object, "FemTest of new solver failed") analysis.addObject(solver_object) fcc_print('Checking FEM new material...') material_object = ObjectsFem.makeMaterialFluid(self.active_doc, 'FluidMaterial') mat = material_object.Material mat['Name'] = "Water" mat['Density'] = "998 kg/m^3" mat['SpecificHeat'] = "4.182 J/kg/K" mat['DynamicViscosity'] = "1.003e-3 kg/m/s" mat['VolumetricThermalExpansionCoefficient'] = "2.07e-4 m/m/K" mat['ThermalConductivity'] = "0.591 W/m/K" material_object.Material = mat self.assertTrue(material_object, "FemTest of new material failed") analysis.addObject(material_object) fcc_print('Checking FEM Flow1D inlet constraint...') Flow1d_inlet = ObjectsFem.makeElementFluid1D(self.active_doc, "ElementFluid1D") Flow1d_inlet.SectionType = 'Liquid' Flow1d_inlet.LiquidSectionType = 'PIPE INLET' Flow1d_inlet.InletPressure = 0.1 Flow1d_inlet.References = [(line, "Edge1")] self.assertTrue(Flow1d_inlet, "FemTest of new Flow1D inlet constraint failed") analysis.addObject(Flow1d_inlet) fcc_print('Checking FEM new Flow1D entrance constraint...') Flow1d_entrance = ObjectsFem.makeElementFluid1D( self.active_doc, "ElementFluid1D") Flow1d_entrance.SectionType = 'Liquid' Flow1d_entrance.LiquidSectionType = 'PIPE ENTRANCE' Flow1d_entrance.EntrancePipeArea = 31416.00 Flow1d_entrance.EntranceArea = 25133.00 Flow1d_entrance.References = [(line, "Edge2")] self.assertTrue(Flow1d_entrance, "FemTest of new Flow1D entrance constraint failed") analysis.addObject(Flow1d_entrance) fcc_print('Checking FEM new Flow1D manning constraint...') Flow1d_manning = ObjectsFem.makeElementFluid1D(self.active_doc, "ElementFluid1D") Flow1d_manning.SectionType = 'Liquid' Flow1d_manning.LiquidSectionType = 'PIPE MANNING' Flow1d_manning.ManningArea = 31416 Flow1d_manning.ManningRadius = 50 Flow1d_manning.ManningCoefficient = 0.002 Flow1d_manning.References = [(line, "Edge3"), (line, "Edge5")] self.assertTrue(Flow1d_manning, "FemTest of new Flow1D manning constraint failed") analysis.addObject(Flow1d_manning) fcc_print('Checking FEM new Flow1D bend constraint...') Flow1d_bend = ObjectsFem.makeElementFluid1D(self.active_doc, "ElementFluid1D") Flow1d_bend.SectionType = 'Liquid' Flow1d_bend.LiquidSectionType = 'PIPE BEND' Flow1d_bend.BendPipeArea = 31416 Flow1d_bend.BendRadiusDiameter = 1.5 Flow1d_bend.BendAngle = 45 Flow1d_bend.BendLossCoefficient = 0.4 Flow1d_bend.References = [(line, "Edge4")] self.assertTrue(Flow1d_bend, "FemTest of new Flow1D bend constraint failed") analysis.addObject(Flow1d_bend) fcc_print('Checking FEM new Flow1D enlargement constraint...') Flow1d_enlargement = ObjectsFem.makeElementFluid1D( self.active_doc, "ElementFluid1D") Flow1d_enlargement.SectionType = 'Liquid' Flow1d_enlargement.LiquidSectionType = 'PIPE ENLARGEMENT' Flow1d_enlargement.EnlargeArea1 = 31416.00 Flow1d_enlargement.EnlargeArea2 = 70686.00 Flow1d_enlargement.References = [(line, "Edge6")] self.assertTrue(Flow1d_enlargement, "FemTest of new Flow1D enlargement constraint failed") analysis.addObject(Flow1d_enlargement) fcc_print('Checking FEM new Flow1D manning constraint...') Flow1d_manning1 = ObjectsFem.makeElementFluid1D( self.active_doc, "ElementFluid1D") Flow1d_manning1.SectionType = 'Liquid' Flow1d_manning1.LiquidSectionType = 'PIPE MANNING' Flow1d_manning1.ManningArea = 70686.00 Flow1d_manning1.ManningRadius = 75 Flow1d_manning1.ManningCoefficient = 0.002 Flow1d_manning1.References = [(line, "Edge7")] self.assertTrue(Flow1d_manning1, "FemTest of new Flow1D manning constraint failed") analysis.addObject(Flow1d_manning1) fcc_print('Checking FEM new Flow1D contraction constraint...') Flow1d_contraction = ObjectsFem.makeElementFluid1D( self.active_doc, "ElementFluid1D") Flow1d_contraction.SectionType = 'Liquid' Flow1d_contraction.LiquidSectionType = 'PIPE CONTRACTION' Flow1d_contraction.ContractArea1 = 70686 Flow1d_contraction.ContractArea2 = 17671 Flow1d_contraction.References = [(line, "Edge8")] self.assertTrue(Flow1d_contraction, "FemTest of new Flow1D contraction constraint failed") analysis.addObject(Flow1d_contraction) fcc_print('Checking FEM new Flow1D manning constraint...') Flow1d_manning2 = ObjectsFem.makeElementFluid1D( self.active_doc, "ElementFluid1D") Flow1d_manning2.SectionType = 'Liquid' Flow1d_manning2.LiquidSectionType = 'PIPE MANNING' Flow1d_manning2.ManningArea = 17671.00 Flow1d_manning2.ManningRadius = 37.5 Flow1d_manning2.ManningCoefficient = 0.002 Flow1d_manning2.References = [(line, "Edge11"), (line, "Edge9")] self.assertTrue(Flow1d_manning2, "FemTest of new Flow1D manning constraint failed") analysis.addObject(Flow1d_manning2) fcc_print('Checking FEM new Flow1D gate valve constraint...') Flow1d_gate_valve = ObjectsFem.makeElementFluid1D( self.active_doc, "ElementFluid1D") Flow1d_gate_valve.SectionType = 'Liquid' Flow1d_gate_valve.LiquidSectionType = 'PIPE GATE VALVE' Flow1d_gate_valve.GateValvePipeArea = 17671 Flow1d_gate_valve.GateValveClosingCoeff = 0.5 Flow1d_gate_valve.References = [(line, "Edge10")] self.assertTrue(Flow1d_gate_valve, "FemTest of new Flow1D gate valve constraint failed") analysis.addObject(Flow1d_gate_valve) fcc_print('Checking FEM new Flow1D enlargement constraint...') Flow1d_enlargement1 = ObjectsFem.makeElementFluid1D( self.active_doc, "ElementFluid1D") Flow1d_enlargement1.SectionType = 'Liquid' Flow1d_enlargement1.LiquidSectionType = 'PIPE ENLARGEMENT' Flow1d_enlargement1.EnlargeArea1 = 17671 Flow1d_enlargement1.EnlargeArea2 = 1e12 Flow1d_enlargement1.References = [(line, "Edge12")] self.assertTrue(Flow1d_enlargement1, "FemTest of new Flow1D enlargement constraint failed") analysis.addObject(Flow1d_enlargement1) fcc_print('Checking FEM Flow1D outlet constraint...') Flow1d_outlet = ObjectsFem.makeElementFluid1D(self.active_doc, "ElementFluid1D") Flow1d_outlet.SectionType = 'Liquid' Flow1d_outlet.LiquidSectionType = 'PIPE OUTLET' Flow1d_outlet.OutletPressure = 0.1 Flow1d_outlet.References = [(line, "Edge13")] self.assertTrue(Flow1d_outlet, "FemTest of new Flow1D inlet constraint failed") analysis.addObject(Flow1d_outlet) fcc_print('Checking FEM self weight constraint...') Flow1d_self_weight = ObjectsFem.makeConstraintSelfWeight( self.active_doc, "ConstraintSelfWeight") Flow1d_self_weight.Gravity_x = 0.0 Flow1d_self_weight.Gravity_y = 0.0 Flow1d_self_weight.Gravity_z = -1.0 self.assertTrue(Flow1d_outlet, "FemTest of new Flow1D self weight constraint failed") analysis.addObject(Flow1d_self_weight) fcc_print('Checking FEM new mesh...') from .testfiles.ccx.Flow1D_mesh import create_nodes_Flow1D from .testfiles.ccx.Flow1D_mesh import create_elements_Flow1D mesh = Fem.FemMesh() ret = create_nodes_Flow1D(mesh) self.assertTrue(ret, "Import of mesh nodes failed") ret = create_elements_Flow1D(mesh) self.assertTrue(ret, "Import of mesh volumes failed") mesh_object = self.active_doc.addObject('Fem::FemMeshObject', self.mesh_name) mesh_object.FemMesh = mesh self.assertTrue(mesh, "FemTest of new mesh failed") analysis.addObject(mesh_object) self.active_doc.recompute() Flow1D_thermomech_analysis_dir = self.temp_dir + 'FEM_ccx_Flow1D_thermomech/' fea = ccxtools.FemToolsCcx(analysis, test_mode=True) fcc_print('Setting up working directory {}'.format( Flow1D_thermomech_analysis_dir)) fea.setup_working_dir(Flow1D_thermomech_analysis_dir) self.assertTrue( True if fea.working_dir == Flow1D_thermomech_analysis_dir else False, "Setting working directory {} failed".format( Flow1D_thermomech_analysis_dir)) fcc_print( 'Checking FEM inp file prerequisites for thermo-mechanical analysis...' ) error = fea.check_prerequisites() self.assertFalse( error, "ccxtools check_prerequisites returned error message: {}".format( error)) fcc_print('Checking FEM inp file write...') fcc_print('Writing {}/{}.inp for thermomech analysis'.format( Flow1D_thermomech_analysis_dir, self.mesh_name)) error = fea.write_inp_file() self.assertFalse(error, "Writing failed") Flow1D_thermomech_base_name = 'Flow1D_thermomech' Flow1D_thermomech_analysis_inp_file = self.test_file_dir + Flow1D_thermomech_base_name + '.inp' fcc_print('Comparing {} to {}/{}.inp'.format( Flow1D_thermomech_analysis_inp_file, Flow1D_thermomech_analysis_dir, self.mesh_name)) ret = testtools.compare_inp_files( Flow1D_thermomech_analysis_inp_file, Flow1D_thermomech_analysis_dir + self.mesh_name + '.inp') self.assertFalse( ret, "ccxtools write_inp_file test failed.\n{}".format(ret)) fcc_print( 'Setting up working directory to {} in order to read simulated calculations' .format(self.test_file_dir)) fea.setup_working_dir(self.test_file_dir) self.assertTrue( True if fea.working_dir == self.test_file_dir else False, "Setting working directory {} failed".format(self.test_file_dir)) fcc_print('Setting base name to read test {}.frd file...'.format( 'Flow1D_thermomech')) fea.set_base_name(Flow1D_thermomech_base_name) self.assertTrue( True if fea.base_name == Flow1D_thermomech_base_name else False, "Setting base name to {} failed".format( Flow1D_thermomech_base_name)) fcc_print('Setting inp file name to read test {}.frd file...'.format( 'Flow1D_thermomech')) fea.set_inp_file_name() self.assertTrue( True if fea.inp_file_name == Flow1D_thermomech_analysis_inp_file else False, "Setting inp file name to {} failed".format( Flow1D_thermomech_analysis_inp_file)) fcc_print( 'Checking FEM frd file read from Flow1D thermomech analysis...') fea.load_results() self.assertTrue( fea.results_present, "Cannot read results from {}.frd frd file".format(fea.base_name)) fcc_print( 'Reading stats from result object for Flow1D thermomech analysis...' ) Flow1D_thermomech_expected_values = self.test_file_dir + "Flow1D_thermomech_expected_values" stat_types = [ "U1", "U2", "U3", "Uabs", "Sabs", "MaxPrin", "MidPrin", "MinPrin", "MaxShear", "Peeq", "Temp", "MFlow", "NPress" ] ret = testtools.compare_stats(fea, Flow1D_thermomech_expected_values, stat_types, 'CalculiX_thermomech_time_1_0_results') self.assertFalse(ret, "Invalid results read from .frd file") Flow1D_thermomech_save_fc_file = Flow1D_thermomech_analysis_dir + Flow1D_thermomech_base_name + '.fcstd' fcc_print('Save FreeCAD file for thermomech analysis to {}...'.format( Flow1D_thermomech_save_fc_file)) self.active_doc.saveAs(Flow1D_thermomech_save_fc_file) fcc_print( '--------------- End of FEM tests FLow 1D thermomech analysis ---------------' )
def test_static_analysis(self): fcc_print('--------------- Start of FEM tests ---------------') box = self.active_doc.addObject("Part::Box", "Box") fcc_print('Checking FEM new analysis...') analysis = ObjectsFem.makeAnalysis(self.active_doc, 'Analysis') self.assertTrue(analysis, "FemTest of new analysis failed") fcc_print('Checking FEM new solver...') solver_object = ObjectsFem.makeSolverCalculixCcxTools( self.active_doc, 'CalculiX') solver_object.AnalysisType = 'static' solver_object.GeometricalNonlinearity = 'linear' solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = 'default' solver_object.IterationsControlParameterTimeUse = False solver_object.EigenmodesCount = 10 solver_object.EigenmodeHighLimit = 1000000.0 solver_object.EigenmodeLowLimit = 0.0 self.assertTrue(solver_object, "FemTest of new solver failed") analysis.addObject(solver_object) fcc_print('Checking FEM new material...') material_object = ObjectsFem.makeMaterialSolid(self.active_doc, 'MechanicalMaterial') mat = material_object.Material mat['Name'] = "Steel-Generic" mat['YoungsModulus'] = "200000 MPa" mat['PoissonRatio'] = "0.30" mat['Density'] = "7900 kg/m^3" material_object.Material = mat self.assertTrue(material_object, "FemTest of new material failed") analysis.addObject(material_object) fcc_print('Checking FEM new fixed constraint...') fixed_constraint = self.active_doc.addObject("Fem::ConstraintFixed", "FemConstraintFixed") fixed_constraint.References = [(box, "Face1")] self.assertTrue(fixed_constraint, "FemTest of new fixed constraint failed") analysis.addObject(fixed_constraint) fcc_print('Checking FEM new force constraint...') force_constraint = self.active_doc.addObject("Fem::ConstraintForce", "FemConstraintForce") force_constraint.References = [(box, "Face6")] force_constraint.Force = 40000.0 force_constraint.Direction = (box, ["Edge5"]) self.active_doc.recompute() force_constraint.Reversed = True self.active_doc.recompute() self.assertTrue(force_constraint, "FemTest of new force constraint failed") analysis.addObject(force_constraint) fcc_print('Checking FEM new pressure constraint...') pressure_constraint = self.active_doc.addObject( "Fem::ConstraintPressure", "FemConstraintPressure") pressure_constraint.References = [(box, "Face2")] pressure_constraint.Pressure = 1000.0 pressure_constraint.Reversed = False self.assertTrue(pressure_constraint, "FemTest of new pressure constraint failed") analysis.addObject(pressure_constraint) fcc_print('Checking FEM new mesh...') from .testfiles.ccx.cube_mesh import create_nodes_cube from .testfiles.ccx.cube_mesh import create_elements_cube mesh = Fem.FemMesh() ret = create_nodes_cube(mesh) self.assertTrue(ret, "Import of mesh nodes failed") ret = create_elements_cube(mesh) self.assertTrue(ret, "Import of mesh volumes failed") mesh_object = self.active_doc.addObject('Fem::FemMeshObject', self.mesh_name) mesh_object.FemMesh = mesh self.assertTrue(mesh, "FemTest of new mesh failed") analysis.addObject(mesh_object) self.active_doc.recompute() static_analysis_dir = testtools.get_unit_test_tmp_dir( self.temp_dir, 'FEM_ccx_static/') fea = ccxtools.FemToolsCcx(analysis, solver_object, test_mode=True) fcc_print( 'Setting up working directory {}'.format(static_analysis_dir)) fea.setup_working_dir(static_analysis_dir) self.assertTrue( True if fea.working_dir == static_analysis_dir else False, "Setting working directory {} failed".format(static_analysis_dir)) fcc_print('Checking FEM inp file prerequisites for static analysis...') error = fea.check_prerequisites() self.assertFalse( error, "ccxtools check_prerequisites returned error message: {}".format( error)) fcc_print('Checking FEM inp file write...') fcc_print('Writing {}/{}.inp for static analysis'.format( static_analysis_dir, self.mesh_name)) error = fea.write_inp_file() self.assertFalse(error, "Writing failed") static_base_name = 'cube_static' static_analysis_inp_file = self.test_file_dir + static_base_name + '.inp' fcc_print('Comparing {} to {}/{}.inp'.format(static_analysis_inp_file, static_analysis_dir, self.mesh_name)) ret = testtools.compare_inp_files( static_analysis_inp_file, static_analysis_dir + self.mesh_name + '.inp') self.assertFalse( ret, "ccxtools write_inp_file test failed.\n{}".format(ret)) fcc_print( 'Setting up working directory to {} in order to read simulated calculations' .format(self.test_file_dir)) fea.setup_working_dir(self.test_file_dir) self.assertTrue( True if fea.working_dir == self.test_file_dir else False, "Setting working directory {} failed".format(self.test_file_dir)) fcc_print('Setting base name to read test {}.frd file...'.format( 'cube_static')) fea.set_base_name(static_base_name) self.assertTrue( True if fea.base_name == static_base_name else False, "Setting base name to {} failed".format(static_base_name)) fcc_print('Setting inp file name to read test {}.frd file...'.format( 'cube_static')) fea.set_inp_file_name() self.assertTrue( True if fea.inp_file_name == static_analysis_inp_file else False, "Setting inp file name to {} failed".format( static_analysis_inp_file)) fcc_print('Checking FEM frd file read from static analysis...') fea.load_results() self.assertTrue( fea.results_present, "Cannot read results from {}.frd frd file".format(fea.base_name)) fcc_print('Reading stats from result object for static analysis...') static_expected_values = self.test_file_dir + "cube_static_expected_values" ret = testtools.compare_stats(fea, static_expected_values, 'CalculiX_static_results') self.assertFalse(ret, "Invalid results read from .frd file") static_save_fc_file = static_analysis_dir + static_base_name + '.fcstd' fcc_print('Save FreeCAD file for static analysis to {}...'.format( static_save_fc_file)) self.active_doc.saveAs(static_save_fc_file) fcc_print( '--------------- End of FEM tests static and analysis ---------------' )
def test_thermomech_analysis(self): fcc_print('--------------- Start of FEM tests ---------------') box = self.active_doc.addObject("Part::Box", "Box") box.Height = 25.4 box.Width = 25.4 box.Length = 203.2 fcc_print('Checking FEM new analysis...') analysis = ObjectsFem.makeAnalysis(self.active_doc, 'Analysis') self.assertTrue(analysis, "FemTest of new analysis failed") fcc_print('Checking FEM new solver...') solver_object = ObjectsFem.makeSolverCalculixCcxTools( self.active_doc, 'CalculiX') solver_object.AnalysisType = 'thermomech' solver_object.GeometricalNonlinearity = 'linear' solver_object.ThermoMechSteadyState = True solver_object.MatrixSolverType = 'default' solver_object.IterationsThermoMechMaximum = 2000 solver_object.IterationsControlParameterTimeUse = True self.assertTrue(solver_object, "FemTest of new solver failed") analysis.addObject(solver_object) fcc_print('Checking FEM new material...') material_object = ObjectsFem.makeMaterialSolid(self.active_doc, 'MechanicalMaterial') mat = material_object.Material mat['Name'] = "Steel-Generic" mat['YoungsModulus'] = "200000 MPa" mat['PoissonRatio'] = "0.30" mat['Density'] = "7900 kg/m^3" mat['ThermalConductivity'] = "43.27 W/m/K" # SvdW: Change to Ansys model values mat['ThermalExpansionCoefficient'] = "12 um/m/K" mat['SpecificHeat'] = "500 J/kg/K" # SvdW: Change to Ansys model values material_object.Material = mat self.assertTrue(material_object, "FemTest of new material failed") analysis.addObject(material_object) fcc_print('Checking FEM new fixed constraint...') fixed_constraint = self.active_doc.addObject("Fem::ConstraintFixed", "FemConstraintFixed") fixed_constraint.References = [(box, "Face1")] self.assertTrue(fixed_constraint, "FemTest of new fixed constraint failed") analysis.addObject(fixed_constraint) fcc_print('Checking FEM new initial temperature constraint...') initialtemperature_constraint = self.active_doc.addObject( "Fem::ConstraintInitialTemperature", "FemConstraintInitialTemperature") initialtemperature_constraint.initialTemperature = 300.0 self.assertTrue( initialtemperature_constraint, "FemTest of new initial temperature constraint failed") analysis.addObject(initialtemperature_constraint) fcc_print('Checking FEM new temperature constraint...') temperature_constraint = self.active_doc.addObject( "Fem::ConstraintTemperature", "FemConstraintTemperature") temperature_constraint.References = [(box, "Face1")] temperature_constraint.Temperature = 310.93 self.assertTrue(temperature_constraint, "FemTest of new temperature constraint failed") analysis.addObject(temperature_constraint) fcc_print('Checking FEM new heatflux constraint...') heatflux_constraint = self.active_doc.addObject( "Fem::ConstraintHeatflux", "FemConstraintHeatflux") heatflux_constraint.References = [(box, "Face3"), (box, "Face4"), (box, "Face5"), (box, "Face6")] heatflux_constraint.AmbientTemp = 255.3722 heatflux_constraint.FilmCoef = 5.678 self.assertTrue(heatflux_constraint, "FemTest of new heatflux constraint failed") analysis.addObject(heatflux_constraint) fcc_print('Checking FEM new mesh...') from .testfiles.ccx.spine_mesh import create_nodes_spine from .testfiles.ccx.spine_mesh import create_elements_spine mesh = Fem.FemMesh() ret = create_nodes_spine(mesh) self.assertTrue(ret, "Import of mesh nodes failed") ret = create_elements_spine(mesh) self.assertTrue(ret, "Import of mesh volumes failed") mesh_object = self.active_doc.addObject('Fem::FemMeshObject', self.mesh_name) mesh_object.FemMesh = mesh self.assertTrue(mesh, "FemTest of new mesh failed") analysis.addObject(mesh_object) self.active_doc.recompute() thermomech_analysis_dir = self.temp_dir + 'FEM_ccx_thermomech/' fea = ccxtools.FemToolsCcx(analysis, test_mode=True) fcc_print( 'Setting up working directory {}'.format(thermomech_analysis_dir)) fea.setup_working_dir(thermomech_analysis_dir) self.assertTrue( True if fea.working_dir == thermomech_analysis_dir else False, "Setting working directory {} failed".format( thermomech_analysis_dir)) fcc_print( 'Checking FEM inp file prerequisites for thermo-mechanical analysis...' ) error = fea.check_prerequisites() self.assertFalse( error, "ccxtools check_prerequisites returned error message: {}".format( error)) fcc_print('Checking FEM inp file write...') fcc_print('Writing {}/{}.inp for thermomech analysis'.format( thermomech_analysis_dir, self.mesh_name)) error = fea.write_inp_file() self.assertFalse(error, "Writing failed") thermomech_base_name = 'spine_thermomech' thermomech_analysis_inp_file = self.test_file_dir + thermomech_base_name + '.inp' fcc_print('Comparing {} to {}/{}.inp'.format( thermomech_analysis_inp_file, thermomech_analysis_dir, self.mesh_name)) ret = testtools.compare_inp_files( thermomech_analysis_inp_file, thermomech_analysis_dir + self.mesh_name + '.inp') self.assertFalse( ret, "ccxtools write_inp_file test failed.\n{}".format(ret)) fcc_print( 'Setting up working directory to {} in order to read simulated calculations' .format(self.test_file_dir)) fea.setup_working_dir(self.test_file_dir) self.assertTrue( True if fea.working_dir == self.test_file_dir else False, "Setting working directory {} failed".format(self.test_file_dir)) fcc_print('Setting base name to read test {}.frd file...'.format( 'spine_thermomech')) fea.set_base_name(thermomech_base_name) self.assertTrue( True if fea.base_name == thermomech_base_name else False, "Setting base name to {} failed".format(thermomech_base_name)) fcc_print('Setting inp file name to read test {}.frd file...'.format( 'spine_thermomech')) fea.set_inp_file_name() self.assertTrue( True if fea.inp_file_name == thermomech_analysis_inp_file else False, "Setting inp file name to {} failed".format( thermomech_analysis_inp_file)) fcc_print('Checking FEM frd file read from thermomech analysis...') fea.load_results() self.assertTrue( fea.results_present, "Cannot read results from {}.frd frd file".format(fea.base_name)) fcc_print( 'Reading stats from result object for thermomech analysis...') thermomech_expected_values = self.test_file_dir + "spine_thermomech_expected_values" ret = testtools.compare_stats(fea, thermomech_expected_values, 'CalculiX_thermomech_results') self.assertFalse(ret, "Invalid results read from .frd file") thermomech_save_fc_file = thermomech_analysis_dir + thermomech_base_name + '.fcstd' fcc_print('Save FreeCAD file for thermomech analysis to {}...'.format( thermomech_save_fc_file)) self.active_doc.saveAs(thermomech_save_fc_file) fcc_print( '--------------- End of FEM tests thermomech analysis ---------------' )
def test_1_static_analysis(self): fcc_print( "\n--------------- Start of FEM ccxtools static analysis test ---------------" ) # set up the static analysis example from femexamples import boxanalysis as box box.setup_static(self.active_doc, "ccxtools") analysis = self.active_doc.Analysis solver_object = self.active_doc.CalculiXccxTools fcc_print("Analysis {}".format(type(analysis))) fcc_print("Analysis {}".format(analysis.TypeId)) static_analysis_dir = testtools.get_unit_test_tmp_dir( self.temp_dir, "FEM_ccx_static") fea = ccxtools.FemToolsCcx(analysis, solver_object, test_mode=True) fea.update_objects() fcc_print("fea Analysis {}".format(type(fea.analysis))) fcc_print("fea Analysis {}".format(fea.analysis.TypeId)) fcc_print( "Setting up working directory {}".format(static_analysis_dir)) fea.setup_working_dir(static_analysis_dir) self.assertTrue( True if fea.working_dir == static_analysis_dir else False, "Setting working directory {} failed".format(static_analysis_dir)) fcc_print("Checking FEM inp file prerequisites for static analysis...") error = fea.check_prerequisites() self.assertFalse( error, "ccxtools check_prerequisites returned error message: {}".format( error)) static_base_name = "cube_static" inpfile_given = join(self.test_file_dir, (static_base_name + ".inp")) inpfile_totest = join(static_analysis_dir, (self.mesh_name + ".inp")) fcc_print("Checking FEM inp file write...") fcc_print("Writing {} for static analysis".format(inpfile_totest)) error = fea.write_inp_file() self.assertFalse(error, "Writing failed") fcc_print("Comparing {} to {}".format(inpfile_given, inpfile_totest)) ret = testtools.compare_inp_files(inpfile_given, inpfile_totest) self.assertFalse( ret, "ccxtools write_inp_file test failed.\n{}".format(ret)) fcc_print( "Setting up working directory to {} in order to read simulated calculations" .format(self.test_file_dir)) fea.setup_working_dir(self.test_file_dir) fcc_print(fea.working_dir) fcc_print(self.test_file_dir) self.assertTrue( True if fea.working_dir == self.test_file_dir else False, "Setting working directory {} failed".format(self.test_file_dir)) fcc_print("Setting base name to read test {}.frd file...".format( "cube_static")) fea.set_base_name(static_base_name) self.assertTrue( True if fea.base_name == static_base_name else False, "Setting base name to {} failed".format(static_base_name)) fcc_print("Setting inp file name to read test {}.frd file...".format( "cube_static")) fea.set_inp_file_name() self.assertTrue( True if fea.inp_file_name == inpfile_given else False, "Setting inp file name to {} failed".format(inpfile_given)) fcc_print("Checking FEM frd file read from static analysis...") fea.load_results() self.assertTrue( fea.results_present, "Cannot read results from {}.frd frd file".format(fea.base_name)) fcc_print("Reading stats from result object for static analysis...") static_expected_values = join(self.test_file_dir, "cube_static_expected_values") ret = testtools.compare_stats(fea, static_expected_values, "CCX_Results") self.assertFalse(ret, "Invalid results read from .frd file") static_save_fc_file = static_analysis_dir + static_base_name + ".FCStd" fcc_print("Save FreeCAD file for static analysis to {}...".format( static_save_fc_file)) self.active_doc.saveAs(static_save_fc_file) fcc_print( "--------------- End of FEM ccxtools static analysis test -------------------" )
def test_5_Flow1D_thermomech_analysis(self): fcc_print( "\n--------------- Start of FEM ccxtools Flow1D analysis test ---------------" ) # set up the thermomech flow1d example from femexamples.thermomech_flow1d import setup as flow1d flow1d(self.active_doc, "ccxtools") analysis = self.active_doc.Analysis Flow1D_thermomech_analysis_dir = testtools.get_unit_test_tmp_dir( self.temp_dir, "FEM_ccx_Flow1D_thermomech") fea = ccxtools.FemToolsCcx(analysis, test_mode=True) fea.update_objects() fcc_print("Setting up working directory {}".format( Flow1D_thermomech_analysis_dir)) fea.setup_working_dir(Flow1D_thermomech_analysis_dir) self.assertTrue( True if fea.working_dir == Flow1D_thermomech_analysis_dir else False, "Setting working directory {} failed".format( Flow1D_thermomech_analysis_dir)) fcc_print( "Checking FEM inp file prerequisites for thermo-mechanical analysis..." ) error = fea.check_prerequisites() self.assertFalse( error, "ccxtools check_prerequisites returned error message: {}".format( error)) Flow1D_thermomech_base_name = "Flow1D_thermomech" inpfile_given = join(self.test_file_dir, (Flow1D_thermomech_base_name + ".inp")) inpfile_totest = join(Flow1D_thermomech_analysis_dir, (self.mesh_name + ".inp")) fcc_print("Checking FEM inp file write...") fcc_print("Writing {} for thermomech analysis".format(inpfile_totest)) error = fea.write_inp_file() self.assertFalse(error, "Writing failed") fcc_print("Comparing {} to {}".format(inpfile_given, inpfile_totest)) ret = testtools.compare_inp_files(inpfile_given, inpfile_totest) self.assertFalse( ret, "ccxtools write_inp_file test failed.\n{}".format(ret)) fcc_print( "Setting up working directory to {} in order to read simulated calculations" .format(self.test_file_dir)) fea.setup_working_dir(self.test_file_dir) self.assertTrue( True if fea.working_dir == self.test_file_dir else False, "Setting working directory {} failed".format(self.test_file_dir)) fcc_print("Setting base name to read test {}.frd file...".format( "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 == inpfile_given else False, "Setting inp file name to {} failed".format(inpfile_given)) fcc_print( "Checking FEM frd file read from Flow1D thermomech analysis...") fea.load_results() self.assertTrue( fea.results_present, "Cannot read results from {}.frd frd file".format(fea.base_name)) fcc_print( "Reading stats from result object for Flow1D thermomech analysis..." ) Flow1D_thermomech_expected_values = join( self.test_file_dir, "Flow1D_thermomech_expected_values") ret = testtools.compare_stats(fea, Flow1D_thermomech_expected_values, "CCX_Time1_0_Results") self.assertFalse(ret, "Invalid results read from .frd file") Flow1D_thermomech_save_fc_file = join( Flow1D_thermomech_analysis_dir, (Flow1D_thermomech_base_name + ".FCStd")) fcc_print("Save FreeCAD file for thermomech analysis to {}...".format( Flow1D_thermomech_save_fc_file)) self.active_doc.saveAs(Flow1D_thermomech_save_fc_file) fcc_print( "--------------- End of FEM ccxtools Flow1D analysis test -------------------" )
def on_click21(self): """Overwrite beso_conf.py file in the macro directory""" file_name = os.path.split(self.textbox_file_name.text())[1] path = os.path.split(self.textbox_file_name.text())[0] fea = ccxtools.FemToolsCcx() fea.setup_ccx() path_calculix = fea.ccx_binary optimization_base = self.combo51.currentText() elset_id = self.combo.currentIndex() - 1 thickness_id = self.combo0t.currentIndex() - 1 if elset_id != -1: if thickness_id != -1: elset = self.materials[elset_id].Name + self.thicknesses[ thickness_id].Name else: # 0 means None thickness selected elset = self.materials[elset_id].Name + "Solid" modulus = float( self.materials[elset_id].Material["YoungsModulus"].split() [0]) # MPa if self.materials[elset_id].Material["YoungsModulus"].split( )[1] != "MPa": raise Exception(" units not recognised in " + self.materials[elset_id].Name) poisson = float( self.materials[elset_id].Material["PoissonRatio"].split()[0]) try: density = float(self.materials[elset_id].Material["Density"]. split()[0]) * 1e-12 # kg/m3 -> t/mm3 if self.materials[elset_id].Material["Density"].split( )[1] not in ["kg/m^3", "kg/m3"]: raise Exception(" units not recognised in " + self.materials[elset_id].Name) except KeyError: density = 0. try: conductivity = float( self.materials[elset_id].Material["ThermalConductivity"]. split()[0]) # W/m/K if self.materials[elset_id].Material[ "ThermalConductivity"].split()[1] != "W/m/K": raise Exception(" units not recognised in " + self.materials[elset_id].Name) except KeyError: conductivity = 0. try: if self.materials[elset_id].Material[ "ThermalExpansionCoefficient"].split()[1] == "um/m/K": expansion = float(self.materials[elset_id]. Material["ThermalExpansionCoefficient"]. split()[0]) * 1e-6 # um/m/K -> mm/mm/K elif self.materials[elset_id].Material[ "ThermalExpansionCoefficient"].split()[1] == "m/m/K": expansion = float( self.materials[elset_id]. Material["ThermalExpansionCoefficient"].split() [0]) # m/m/K -> mm/mm/K else: raise Exception(" units not recognised in " + self.materials[elset_id].Name) except KeyError: expansion = 0. try: specific_heat = float( self.materials[elset_id].Material["SpecificHeat"].split() [0]) * 1e6 # J/kg/K -> mm^2/s^2/K if self.materials[elset_id].Material["SpecificHeat"].split( )[1] != "J/kg/K": raise Exception(" units not recognised in " + self.materials[elset_id].Name) except KeyError: specific_heat = 0. if thickness_id != -1: thickness = str( self.thicknesses[thickness_id].Thickness).split()[0] # mm if str(self.thicknesses[thickness_id].Thickness).split( )[1] != "mm": raise Exception(" units not recognised in " + self.thicknesses[thickness_id].Name) else: thickness = 0. optimized = self.checkbox.isChecked() if self.textbox.text(): von_mises = float(self.textbox.text()) else: von_mises = 0. elset_id1 = self.combo1.currentIndex() - 1 thickness_id1 = self.combo0t.currentIndex() - 1 if elset_id1 != -1: if thickness_id1 != -1: elset1 = self.materials[elset_id1].Name + self.thicknesses[ thickness_id1].Name else: # 0 means None thickness selected elset1 = self.materials[elset_id1].Name + "Solid" modulus1 = float( self.materials[elset_id1].Material["YoungsModulus"].split() [0]) # MPa if self.materials[elset_id1].Material["YoungsModulus"].split( )[1] != "MPa": raise Exception(" units not recognised in " + self.materials[elset_id1].Name) poisson1 = float( self.materials[elset_id1].Material["PoissonRatio"].split()[0]) try: density1 = float(self.materials[elset_id1].Material["Density"]. split()[0]) * 1e-12 # kg/m3 -> t/mm3 if self.materials[elset_id1].Material["Density"].split( )[1] not in ["kg/m^3", "kg/m3"]: raise Exception(" units not recognised in " + self.materials[elset_id1].Name) except KeyError: density1 = 0. try: conductivity1 = float( self.materials[elset_id1].Material["ThermalConductivity"]. split()[0]) # W/m/K if self.materials[elset_id1].Material[ "ThermalConductivity"].split()[1] != "W/m/K": raise Exception(" units not recognised in " + self.materials[elset_id1].Name) except KeyError: conductivity1 = 0. try: if self.materials[elset_id1].Material[ "ThermalExpansionCoefficient"].split()[1] == "um/m/K": expansion1 = float(self.materials[elset_id1]. Material["ThermalExpansionCoefficient"]. split()[0]) * 1e-6 # um/m/K -> mm/mm/K elif self.materials[elset_id1].Material[ "ThermalExpansionCoefficient"].split()[1] == "m/m/K": expansion1 = float( self.materials[elset_id1]. Material["ThermalExpansionCoefficient"].split() [0]) # m/m/K -> mm/mm/K else: raise Exception(" units not recognised in " + self.materials[elset_id1].Name) except KeyError: expansion1 = 0. try: specific_heat1 = float( self.materials[elset_id1].Material["SpecificHeat"].split() [0]) * 1e6 # J/kg/K -> mm^2/s^2/K if self.materials[elset_id1].Material["SpecificHeat"].split( )[1] != "J/kg/K": raise Exception(" units not recognised in " + self.materials[elset_id1].Name) except KeyError: specific_heat1 = 0. if thickness_id1 != -1: thickness1 = str( self.thicknesses[thickness_id1].Thickness).split()[0] # mm if str(self.thicknesses[thickness_id1].Thickness).split( )[1] != "mm": raise Exception(" units not recognised in " + self.thicknesses[thickness_id1].Name) else: thickness1 = 0. optimized1 = self.checkbox1.isChecked() if self.textbox1.text(): von_mises1 = float(self.textbox1.text()) else: von_mises1 = 0. elset_id2 = self.combo2.currentIndex() - 1 thickness_id2 = self.combo0t.currentIndex() - 1 if elset_id2 != -1: if thickness_id2 != -1: elset2 = self.materials[elset_id2].Name + self.thicknesses[ thickness_id2].Name else: # 0 means None thickness selected else2t = self.materials[elset_id2].Name + "Solid" modulus2 = float( self.materials[elset_id2].Material["YoungsModulus"].split() [0]) # MPa if self.materials[elset_id2].Material["YoungsModulus"].split( )[1] != "MPa": raise Exception(" units not recognised in " + self.materials[elset_id2].Name) poisson2 = float( self.materials[elset_id2].Material["PoissonRatio"].split()[0]) try: density2 = float(self.materials[elset_id2].Material["Density"]. split()[0]) * 1e-12 # kg/m3 -> t/mm3 if self.materials[elset_id2].Material["Density"].split( )[1] not in ["kg/m^3", "kg/m3"]: raise Exception(" units not recognised in " + self.materials[elset_id2].Name) except KeyError: density2 = 0. try: conductivity2 = float( self.materials[elset_id2].Material["ThermalConductivity"]. split()[0]) # W/m/K if self.materials[elset_id2].Material[ "ThermalConductivity"].split()[1] != "W/m/K": raise Exception(" units not recognised in " + self.materials[elset_id2].Name) except KeyError: conductivity2 = 0. try: if self.materials[elset_id2].Material[ "ThermalExpansionCoefficient"].split()[1] == "um/m/K": expansion2 = float(self.materials[elset_id2]. Material["ThermalExpansionCoefficient"]. split()[0]) * 1e-6 # um/m/K -> mm/mm/K elif self.materials[elset_id2].Material[ "ThermalExpansionCoefficient"].split()[1] == "m/m/K": expansion2 = float( self.materials[elset_id2]. Material["ThermalExpansionCoefficient"].split() [0]) # m/m/K -> mm/mm/K else: raise Exception(" units not recognised in " + self.materials[elset_id2].Name) except KeyError: expansion2 = 0. try: specific_heat2 = float( self.materials[elset_id2].Material["SpecificHeat"].split() [0]) * 1e6 # J/kg/K -> mm^2/s^2/K if self.materials[elset_id2].Material["SpecificHeat"].split( )[1] != "J/kg/K": raise Exception(" units not recognised in " + self.materials[elset_id2].Name) except KeyError: specific_heat2 = 0. if thickness_id2 != -1: thickness2 = str( self.thicknesses[thickness_id2].Thickness).split()[0] # mm if str(self.thicknesses[thickness_id2].Thickness).split( )[1] != "mm": raise Exception(" units not recognised in " + self.thicknesses[thickness_id2].Name) else: thickness2 = 0. optimized2 = self.checkbox2.isChecked() if self.textbox2.text(): von_mises2 = float(self.textbox2.text()) else: von_mises2 = 0. with open(os.path.join(self.beso_dir, "beso_conf.py"), "w") as f: f.write( "# This is the configuration file with input parameters. It will be executed as python commands\n" ) f.write("# Written by beso_fc_gui.py at {}\n".format( datetime.datetime.now())) f.write("\n") f.write("path_calculix = '{}'\n".format(path_calculix)) f.write("path = '{}'\n".format(path)) f.write("file_name = '{}'\n".format(file_name)) f.write("\n") if elset_id != -1: f.write("elset_name = '{}'\n".format(elset)) f.write( "domain_optimized[elset_name] = {}\n".format(optimized)) f.write("domain_density[elset_name] = [{}, {}]\n".format( density * 1e-6, density)) if thickness: f.write("domain_thickness[elset_name] = [{}, {}]\n".format( thickness, thickness)) if von_mises: f.write( "domain_FI[elset_name] = [[('stress_von_Mises', {:.6})],\n" .format(von_mises * 1e6)) f.write( " [('stress_von_Mises', {:.6})]]\n" .format(von_mises)) f.write( "domain_material[elset_name] = ['*ELASTIC\\n{:.6}, {}\\n*DENSITY\\n{:.6}\\n*CONDUCTIVITY\\n" "{:.6}\\n*EXPANSION\\n{:.6}\\n*SPECIFIC HEAT\\n{:.6}\\n',\n" .format(modulus * 1e-6, poisson, density * 1e-6, conductivity * 1e-6, expansion * 1e-6, specific_heat * 1e-6)) f.write( " '*ELASTIC\\n{:.6}, {:.6}\\n*DENSITY\\n{:.6}\\n*CONDUCTIVITY\\n" "{:.6}\\n*EXPANSION\\n{:.6}\\n*SPECIFIC HEAT\\n{:.6}\\n']\n" .format(modulus, poisson, density, conductivity, expansion, specific_heat)) f.write("\n") if elset_id1 != -1: f.write("elset_name = '{}'\n".format(elset1)) f.write( "domain_optimized[elset_name] = {}\n".format(optimized1)) f.write("domain_density[elset_name] = [{}, {}]\n".format( density1 * 1e-6, density1)) if thickness1: f.write("domain_thickness[elset_name] = [{}, {}]\n".format( thickness1, thickness1)) if von_mises1: f.write( "domain_FI[elset_name] = [[('stress_von_Mises', {:.6})],\n" .format(von_mises1 * 1e6)) f.write( " [('stress_von_Mises', {:.6})]]\n" .format(von_mises1)) f.write( "domain_material[elset_name] = ['*ELASTIC\\n{:.6}, {:.6}\\n*DENSITY\\n{:.6}\\n*CONDUCTIVITY" "\\n{:.6}\\n*EXPANSION\\n{:.6}\\n*SPECIFIC HEAT\\n{:.6}\\n',\n" .format(modulus1 * 1e-6, poisson1, density1 * 1e-6, conductivity1 * 1e-6, expansion1 * 1e-6, specific_heat1 * 1e-6)) f.write( " '*ELASTIC\\n{:.6}, {:.6}\\n*DENSITY\\n{:.6}\\n*CONDUCTIVITY\\n" "{:.6}\\n" "*EXPANSION\\n{:.6}\\n*SPECIFIC HEAT\\n{:.6}\\n']\n". format(modulus1, poisson1, density1, conductivity1, expansion1, specific_heat1)) f.write("\n") if elset_id2 != -1: f.write("elset_name = '{}'\n".format(elset2)) f.write( "domain_optimized[elset_name] = {}\n".format(optimized2)) f.write("domain_density[elset_name] = [{}, {}]\n".format( density2 * 1e-6, density2)) if thickness2: f.write("domain_thickness[elset_name] = [{}, {}]\n".format( thickness2, thickness2)) if von_mises2: f.write( "domain_FI[elset_name] = [[('stress_von_Mises', {:.6})],\n" .format(von_mises2 * 1e6)) f.write( " [('stress_von_Mises', {:.6})]]\n" .format(von_mises2)) f.write( "domain_material[elset_name] = ['*ELASTIC\\n{:.6}, {:.6}\\n*DENSITY\\n{:.6}\\n*CONDUCTIVITY" "\\n{:.6}\\n*EXPANSION\\n{:.6}\\n*SPECIFIC HEAT\\n{:.6}\\n',\n" .format(modulus2 * 1e-6, poisson2, density2 * 1e-6, conductivity2 * 1e-6, expansion2 * 1e-6, specific_heat2 * 1e-6)) f.write( " '*ELASTIC\\n{:.6}, {:.6}\\n*DENSITY\\n{:.6}\\n*CONDUCTIVITY\\n" "{:.6}\\n*EXPANSION\\n{:.6}\\n*SPECIFIC HEAT\\n{:.6}\\n']\n" .format(modulus2, poisson2, density2, conductivity2, expansion2, specific_heat2)) f.write("\n") f.write("mass_goal_ratio = " + self.textbox52.text()) f.write("\n") f.write("filter_list = [") filter = self.combo6.currentText() range = self.textbox6.text() direction = self.textbox9.text() selection = [item.text() for item in self.widget.selectedItems()] filter_domains = [] if "All defined" not in selection: if "Domain 0" in selection: filter_domains.append(elset) if "Domain 1" in selection: filter_domains.append(elset1) if "Domain 2" in selection: filter_domains.append(elset2) if filter == "simple": f.write("['simple', {}".format(range)) for dn in filter_domains: f.write(", '{}'".format(dn)) f.write("],\n") elif filter == "casting": f.write("['casting', {}, ({})".format(range, direction)) for dn in filter_domains: f.write(", '{}'".format(dn)) f.write("],\n") filter1 = self.combo7.currentText() range1 = self.textbox7.text() direction1 = self.textbox10.text() selection = [item.text() for item in self.widget1.selectedItems()] filter_domains1 = [] if "All defined" not in selection: if "Domain 0" in selection: filter_domains1.append(elset) if "Domain 1" in selection: filter_domains1.append(elset1) if "Domain 2" in selection: filter_domains1.append(elset2) if filter1 == "simple": f.write(" ['simple', {}".format(range1)) for dn in filter_domains1: f.write(", '{}'".format(dn)) f.write("],\n") elif filter1 == "casting": f.write(" ['casting', {}, ({})".format( range1, direction1)) for dn in filter_domains1: f.write(", '{}'".format(dn)) f.write("],\n") filter2 = self.combo8.currentText() range2 = self.textbox8.text() direction2 = self.textbox11.text() selection = [item.text() for item in self.widget2.selectedItems()] filter_domains2 = [] if "All defined" not in selection: if "Domain 0" in selection: filter_domains2.append(elset) if "Domain 1" in selection: filter_domains2.append(elset1) if "Domain 2" in selection: filter_domains2.append(elset2) if filter2 == "simple": f.write(" ['simple', {}".format(range2)) for dn in filter_domains2: f.write(", '{}'".format(dn)) f.write("],\n") elif filter2 == "casting": f.write(" ['casting', {}, ({})".format( range2, direction2)) for dn in filter_domains2: f.write(", '{}'".format(dn)) f.write("],\n") f.write(" ]\n") f.write("\n") f.write("optimization_base = '{}'\n".format(optimization_base)) f.write("\n") slider_position = self.slider.value() if slider_position == 1: f.write("mass_addition_ratio = 0.01\n") f.write("mass_removal_ratio = 0.02\n") if slider_position == 2: f.write("mass_addition_ratio = 0.015\n") f.write("mass_removal_ratio = 0.03\n") if slider_position == 3: f.write("mass_addition_ratio = 0.03\n") f.write("mass_removal_ratio = 0.06\n") f.write("ratio_type = 'relative'\n") f.write("\n")
def test_3_freq_analysis(self): fcc_print('--------------- Start of FEM tests ---------------') self.active_doc.addObject("Part::Box", "Box") fcc_print('Checking FEM new analysis...') analysis = ObjectsFem.makeAnalysis(self.active_doc, 'Analysis') self.assertTrue(analysis, "FemTest of new analysis failed") fcc_print('Checking FEM new solver...') solver_object = ObjectsFem.makeSolverCalculixCcxTools(self.active_doc, 'CalculiX') solver_object.AnalysisType = 'frequency' solver_object.GeometricalNonlinearity = 'linear' solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = 'default' solver_object.IterationsControlParameterTimeUse = False solver_object.EigenmodesCount = 10 solver_object.EigenmodeHighLimit = 1000000.0 solver_object.EigenmodeLowLimit = 0.01 self.assertTrue(solver_object, "FemTest of new solver failed") analysis.addObject(solver_object) fcc_print('Checking FEM new material...') material_object = ObjectsFem.makeMaterialSolid(self.active_doc, 'MechanicalMaterial') mat = material_object.Material mat['Name'] = "Steel-Generic" mat['YoungsModulus'] = "200000 MPa" mat['PoissonRatio'] = "0.30" mat['Density'] = "7900 kg/m^3" material_object.Material = mat self.assertTrue(material_object, "FemTest of new material failed") analysis.addObject(material_object) fcc_print('Checking FEM new mesh...') from .testfiles.ccx.cube_mesh import create_nodes_cube from .testfiles.ccx.cube_mesh import create_elements_cube mesh = Fem.FemMesh() ret = create_nodes_cube(mesh) self.assertTrue(ret, "Import of mesh nodes failed") ret = create_elements_cube(mesh) self.assertTrue(ret, "Import of mesh volumes failed") mesh_object = self.active_doc.addObject('Fem::FemMeshObject', self.mesh_name) mesh_object.FemMesh = mesh self.assertTrue(mesh, "FemTest of new mesh failed") analysis.addObject(mesh_object) self.active_doc.recompute() frequency_analysis_dir = testtools.get_unit_test_tmp_dir(self.temp_dir, 'FEM_ccx_frequency') fea = ccxtools.FemToolsCcx(analysis, solver_object, test_mode=True) fea.update_objects() fcc_print('Setting up working directory {}'.format(frequency_analysis_dir)) fea.setup_working_dir(frequency_analysis_dir) self.assertTrue(True if fea.working_dir == frequency_analysis_dir else False, "Setting working directory {} failed".format(frequency_analysis_dir)) fcc_print('Checking FEM inp file prerequisites for frequency analysis...') error = fea.check_prerequisites() self.assertFalse(error, "ccxtools check_prerequisites returned error message: {}".format(error)) frequency_base_name = 'cube_frequency' inpfile_given = join(self.test_file_dir, (frequency_base_name + '.inp')) inpfile_totest = join(frequency_analysis_dir, (self.mesh_name + '.inp')) fcc_print('Checking FEM inp file write...') fcc_print('Writing {} for frequency analysis'.format(inpfile_totest)) error = fea.write_inp_file() self.assertFalse(error, "Writing failed") fcc_print('Comparing {} to {}'.format(inpfile_given, inpfile_totest)) ret = testtools.compare_inp_files(inpfile_given, inpfile_totest) self.assertFalse(ret, "ccxtools write_inp_file test failed.\n{}".format(ret)) fcc_print('Setting up working directory to {} in order to read simulated calculations'.format(self.test_file_dir)) fea.setup_working_dir(self.test_file_dir) self.assertTrue(True if fea.working_dir == self.test_file_dir else False, "Setting working directory {} failed".format(self.test_file_dir)) fcc_print('Setting base name to read test {}.frd file...'.format(frequency_base_name)) fea.set_base_name(frequency_base_name) self.assertTrue(True if fea.base_name == frequency_base_name else False, "Setting base name to {} failed".format(frequency_base_name)) fcc_print('Setting inp file name to read test {}.frd file...'.format('cube_frequency')) fea.set_inp_file_name() self.assertTrue(True if fea.inp_file_name == inpfile_given else False, "Setting inp file name to {} failed".format(inpfile_given)) fcc_print('Checking FEM frd file read from frequency analysis...') fea.load_results() self.assertTrue(fea.results_present, "Cannot read results from {}.frd frd file".format(fea.base_name)) fcc_print('Reading stats from result object for frequency analysis...') frequency_expected_values = join(self.test_file_dir, "cube_frequency_expected_values") ret = testtools.compare_stats(fea, frequency_expected_values, 'CalculiX_frequency_mode_1_results') self.assertFalse(ret, "Invalid results read from .frd file") frequency_save_fc_file = frequency_analysis_dir + frequency_base_name + '.FCStd' fcc_print('Save FreeCAD file for frequency analysis to {}...'.format(frequency_save_fc_file)) self.active_doc.saveAs(frequency_save_fc_file) fcc_print('--------------- End of FEM tests frequency analysis ---------------')
def test_2_static_multiple_material(self): fcc_print('--------------- Start of FEM ccxtools multiple material test ---------------') # create a CompSolid of two Boxes extract the CompSolid (we are able to remesh if needed) boxlow = self.active_doc.addObject("Part::Box", "BoxLower") boxupp = self.active_doc.addObject("Part::Box", "BoxUpper") boxupp.Placement.Base = (0, 0, 10) # for BooleanFragments Occt >=6.9 is needed ''' import BOPTools.SplitFeatures bf = BOPTools.SplitFeatures.makeBooleanFragments(name='BooleanFragments') bf.Objects = [boxlow, boxupp] bf.Mode = "CompSolid" self.active_doc.recompute() bf.Proxy.execute(bf) bf.purgeTouched() for obj in bf.ViewObject.Proxy.claimChildren(): obj.ViewObject.hide() self.active_doc.recompute() import CompoundTools.CompoundFilter cf = CompoundTools.CompoundFilter.makeCompoundFilter(name='MultiMatCompSolid') cf.Base = bf cf.FilterType = 'window-volume' cf.Proxy.execute(cf) cf.purgeTouched() cf.Base.ViewObject.hide() ''' self.active_doc.recompute() if FreeCAD.GuiUp: import FreeCADGui FreeCADGui.ActiveDocument.activeView().viewAxonometric() FreeCADGui.SendMsgToActiveView("ViewFit") analysis = ObjectsFem.makeAnalysis(self.active_doc, 'Analysis') solver_object = ObjectsFem.makeSolverCalculixCcxTools(self.active_doc, 'CalculiXccxTools') solver_object.AnalysisType = 'static' solver_object.GeometricalNonlinearity = 'linear' solver_object.ThermoMechSteadyState = False solver_object.MatrixSolverType = 'default' solver_object.IterationsControlParameterTimeUse = False analysis.addObject(solver_object) material_object_low = ObjectsFem.makeMaterialSolid(self.active_doc, 'MechanicalMaterialLow') mat = material_object_low.Material mat['Name'] = "Aluminium-Generic" mat['YoungsModulus'] = "70000 MPa" mat['PoissonRatio'] = "0.35" mat['Density'] = "2700 kg/m^3" material_object_low.Material = mat material_object_low.References = [(boxlow, 'Solid1')] analysis.addObject(material_object_low) material_object_upp = ObjectsFem.makeMaterialSolid(self.active_doc, 'MechanicalMaterialUpp') mat = material_object_upp.Material mat['Name'] = "Steel-Generic" mat['YoungsModulus'] = "200000 MPa" mat['PoissonRatio'] = "0.30" mat['Density'] = "7980 kg/m^3" material_object_upp.Material = mat material_object_upp.References = [(boxupp, 'Solid1')] analysis.addObject(material_object_upp) fixed_constraint = self.active_doc.addObject("Fem::ConstraintFixed", "ConstraintFixed") # fixed_constraint.References = [(cf, "Face3")] fixed_constraint.References = [(boxlow, "Face5")] analysis.addObject(fixed_constraint) pressure_constraint = self.active_doc.addObject("Fem::ConstraintPressure", "ConstraintPressure") # pressure_constraint.References = [(cf, "Face9")] pressure_constraint.References = [(boxupp, "Face6")] pressure_constraint.Pressure = 1000.0 pressure_constraint.Reversed = False analysis.addObject(pressure_constraint) mesh = Fem.FemMesh() import femtest.testfiles.ccx.multimat_mesh as multimatmesh multimatmesh.create_nodes(mesh) multimatmesh.create_elements(mesh) mesh_object = self.active_doc.addObject('Fem::FemMeshObject', self.mesh_name) mesh_object.FemMesh = mesh analysis.addObject(mesh_object) self.active_doc.recompute() static_multiplemat_dir = testtools.get_unit_test_tmp_dir(self.temp_dir, 'FEM_ccx_multimat/') fea = ccxtools.FemToolsCcx(analysis, solver_object, test_mode=True) fea.update_objects() fea.setup_working_dir(static_multiplemat_dir) fcc_print('Checking FEM inp file prerequisites for ccxtools multimat analysis...') error = fea.check_prerequisites() self.assertFalse(error, "ccxtools check_prerequisites returned error message: {}".format(error)) static_base_name = 'multimat' inpfile_given = join(self.test_file_dir, (static_base_name + '.inp')) inpfile_totest = join(static_multiplemat_dir, (self.mesh_name + '.inp')) fcc_print('Checking FEM inp file write...') fcc_print('Writing {} for static multiple material'.format(inpfile_totest)) error = fea.write_inp_file() self.assertFalse(error, "Writing failed") fcc_print('Comparing {} to {}'.format(inpfile_given, inpfile_totest)) ret = testtools.compare_inp_files(inpfile_given, inpfile_totest) self.assertFalse(ret, "ccxtools write_inp_file test failed.\n{}".format(ret)) static_save_fc_file = static_multiplemat_dir + static_base_name + '.FCStd' fcc_print('Save FreeCAD file for static analysis to {}...'.format(static_save_fc_file)) self.active_doc.saveAs(static_save_fc_file) fcc_print('--------------- End of FEM ccxtools multiple material test ---------------')
'Programs', 'Python', 'Python36', 'python.exe') installation_path = os.path.join("C:\\", "Users", "Denk", 'Downloads', 'ToOptixUpdate-master', 'ToOptixUpdate-master', 'ToOptix_FreeCADAddon') import FreeCAD import Part import commands import FemGui import ObjectsFem import Fem import FemGui from femtools import ccxtools fea = ccxtools.FemToolsCcx() fea.update_objects() message = fea.check_prerequisites() if not message: fea.write_inp_file() ccx_path = fea.__dict__['ccx_binary'] inp_path = fea.__dict__['inp_file_name'] else: raise IOError # Global settings for the installation script # Use python 3 for executing the tooptix script ccx_path = str(ccx_path) ccx_path.replace("/", "\\") run_path = os.path.join("run_optimization_freeCAD.py")
def _calculate(self): self._settings.save() print("Starting solving...") if not self._fem_mesh: self.form.logBox.append(f"<b>Missing FEM mesh, see options tab</b>") return if not self._fem_solver: self.form.logBox.append(f"<b>Missing FEM solver, see options tab</b>") return if not self._fem_analysis: self.form.logBox.append(f"<b>Missing FEM analysis, see options tab</b>") return self._calculation_running = True max_iterations = self._settings.iteration_limit print(f"Max iterations: {max_iterations}") start_time = time.time() # Show Log tab and progress bar self.form.tabWidget.setCurrentIndex(2) self.form.progressBar.setVisible(True) self.form.progressText.setVisible(True) # Aggregate all checks and changes from table cells # Loop until we hit max iterations or a check passes condition_fail = False iteration = 0 changes = self._settings.changes checks = self._settings.checks try: # NOTE: we pick out the analysis and solver ourselves because for # some reason ccxtools did not find it at times. No idea why. fea = ccxtools.FemToolsCcx(analysis=self._fem_analysis, solver=self._fem_solver) fea.purge_results() # ccxtools throws raw Exceptions, not a lazy catch-all here except Exception as e: self.form.logBox.append(f"<b>{e}</b>") condition_fail = True while not condition_fail and iteration < max_iterations: self.form.progressBar.setValue(float(iteration+1) / float(max_iterations) * 100) self.form.progressText.setText(f"Running iteration {iteration+1}/{max_iterations}") self.form.logBox.append(f"<b>Running iteration {iteration+1}</b>") ret = self._calculate_single_shot(fea, changes, checks, iteration, self.form.logBox, self._fem_mesh) if ret is not None: if ret is False: condition_fail = True break self.form.logBox.append("Checking...") current_result = self._find_rename_latest_result(iteration) if self._eval_checks(checks, current_result, iteration): self.form.logBox.append("All checks passed!") break iteration += 1 if iteration == max_iterations: self.form.logBox.append(f"<b>Hit iteration limit without finding a solution</b>") if condition_fail: # Hide progressbars on failure since they can be in a weird state self.form.progressBar.setVisible(False) self.form.progressText.setVisible(False) self.form.logBox.append(f"<b>Had an error!</b>") self.form.logBox.append("Restoring original values...") self._revert_delta_changes(changes) self.form.logBox.append("<b>Done!</b>") elapsed_time = round(time.time() - start_time, 1) print(f"Solving finished in {elapsed_time} s") self.form.progressText.setText(f"Finished in {elapsed_time} s, computed {iteration+1} iterations") self.form.progressBar.setVisible(False) self._calculation_running = False
def create_test_results(): import os import shutil import unittest import FemGui from femresult import resulttools from femtools import ccxtools temp_dir = testtools.get_fem_test_tmp_dir() test_class = "femtest.app.test_ccxtools.TestCcxTools" # unit test class stat_types = [ "U1", "U2", "U3", "Uabs", "Sabs", "MaxPrin", "MidPrin", "MinPrin", "MaxShear", "Peeq", "Temp", "MFlow", "NPress" ] # **************************************************************************** # static cube print("create static result files") unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromName( test_class + ".test_static_analysis") ) static_analysis_dir = join(temp_dir, "FEM_ccx_static") doc_static_cube = FreeCAD.open(join(static_analysis_dir, "cube_static.FCStd")) FemGui.setActiveAnalysis(doc_static_cube.Analysis) fea = ccxtools.FemToolsCcx() fea.update_objects() fea.reset_all() fea.run() fea.load_results() stats_static = [] res_obj_static = doc_static_cube.getObject("CCX_Results") for s in stat_types: statval = resulttools.get_stats(res_obj_static, s) stats_static.append( "{0}: ({1:.14g}, {2:.14g}, )\n" .format(s, statval[0], statval[1]) ) static_expected_values_file = join( static_analysis_dir, "cube_static_expected_values" ) f = open(static_expected_values_file, "w") for s in stats_static: f.write(s) f.close() frd_result_file = os.path.splitext(fea.inp_file_name)[0] + ".frd" dat_result_file = os.path.splitext(fea.inp_file_name)[0] + ".dat" frd_static_test_result_file = join(static_analysis_dir, "cube_static.frd") dat_static_test_result_file = join(static_analysis_dir, "cube_static.dat") shutil.copyfile(frd_result_file, frd_static_test_result_file) shutil.copyfile(dat_result_file, dat_static_test_result_file) print("Results copied to the appropriate FEM test dirs in: " + temp_dir) # **************************************************************************** # frequency cube print("create frequency result files") unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromName( test_class + ".test_freq_analysis") ) frequency_analysis_dir = join(temp_dir, "FEM_ccx_frequency") doc_frequency_cube = FreeCAD.open(join(frequency_analysis_dir, "cube_frequency.FCStd")) FemGui.setActiveAnalysis(doc_frequency_cube.Analysis) fea = ccxtools.FemToolsCcx() fea.update_objects() fea.reset_all() # we should only have one result object 1 to 6 will be less than 0.01 and ignored fea.solver.EigenmodesCount = 7 doc_frequency_cube.recompute() fea.run() fea.load_results() stats_frequency = [] res_obj_freq = doc_frequency_cube.getObject("CCX_Mode7_Results") for s in stat_types: statval = resulttools.get_stats(res_obj_freq, s) stats_frequency.append( "{0}: ({1:.14g}, {2:.14g})\n" .format(s, statval[0], statval[1]) ) frequency_expected_values_file = join( frequency_analysis_dir, "cube_frequency_expected_values" ) f = open(frequency_expected_values_file, "w") for s in stats_frequency: f.write(s) f.close() frd_result_file = os.path.splitext(fea.inp_file_name)[0] + ".frd" dat_result_file = os.path.splitext(fea.inp_file_name)[0] + ".dat" frd_frequency_test_result_file = join(frequency_analysis_dir, "cube_frequency.frd") dat_frequency_test_result_file = join(frequency_analysis_dir, "cube_frequency.dat") shutil.copyfile(frd_result_file, frd_frequency_test_result_file) shutil.copyfile(dat_result_file, dat_frequency_test_result_file) print("Results copied to the appropriate FEM test dirs in: " + temp_dir) # **************************************************************************** # thermomech print("create thermomech result files") unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromName( test_class + ".test_thermomech_spine_analysis") ) thermomech_analysis_dir = join(temp_dir, "FEM_ccx_thermomech") doc_thermomech = FreeCAD.open(join(thermomech_analysis_dir, "spine_thermomech.FCStd")) FemGui.setActiveAnalysis(doc_thermomech.Analysis) fea = ccxtools.FemToolsCcx() fea.reset_all() fea.run() fea.load_results() stats_thermomech = [] res_obj_thermo = doc_thermomech.getObject("CCX_Results001") # two time step results after run for s in stat_types: statval = resulttools.get_stats(res_obj_thermo, s) stats_thermomech.append( "{0}: ({1:.14g}, {2:.14g})\n" .format(s, statval[0], statval[1]) ) thermomech_expected_values_file = join( thermomech_analysis_dir, "spine_thermomech_expected_values" ) f = open(thermomech_expected_values_file, "w") for s in stats_thermomech: f.write(s) f.close() frd_result_file = os.path.splitext(fea.inp_file_name)[0] + ".frd" dat_result_file = os.path.splitext(fea.inp_file_name)[0] + ".dat" frd_thermomech_test_result_file = join(thermomech_analysis_dir, "spine_thermomech.frd") dat_thermomech_test_result_file = join(thermomech_analysis_dir, "spine_thermomech.dat") shutil.copyfile(frd_result_file, frd_thermomech_test_result_file) shutil.copyfile(dat_result_file, dat_thermomech_test_result_file) print("Results copied to the appropriate FEM test dirs in: " + temp_dir) # **************************************************************************** # Flow1D print("create Flow1D result files") unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromName( test_class + ".test_thermomech_flow1D_analysis") ) Flow1D_thermomech_analysis_dir = join(temp_dir, "FEM_ccx_Flow1D_thermomech") doc_flow1d = FreeCAD.open(join(Flow1D_thermomech_analysis_dir, "Flow1D_thermomech.FCStd")) FemGui.setActiveAnalysis(doc_flow1d.Analysis) fea = ccxtools.FemToolsCcx() fea.reset_all() fea.run() fea.load_results() stats_flow1D = [] res_obj_flow1d = doc_flow1d.getObject("CCX_Time1_0_Results001") for s in stat_types: statval = resulttools.get_stats(res_obj_flow1d, s) stats_flow1D.append( "{0}: ({1:.14g}, {2:.14g})\n" .format(s, statval[0], statval[1]) ) Flow1D_thermomech_expected_values_file = join( Flow1D_thermomech_analysis_dir, "Flow1D_thermomech_expected_values" ) f = open(Flow1D_thermomech_expected_values_file, "w") for s in stats_flow1D: f.write(s) f.close() frd_result_file = os.path.splitext(fea.inp_file_name)[0] + ".frd" dat_result_file = os.path.splitext(fea.inp_file_name)[0] + ".dat" frd_Flow1D_thermomech_test_result_file = join( Flow1D_thermomech_analysis_dir, "Flow1D_thermomech.frd" ) dat_Flow1D_thermomech_test_result_file = join( Flow1D_thermomech_analysis_dir, "Flow1D_thermomech.dat" ) shutil.copyfile(frd_result_file, frd_Flow1D_thermomech_test_result_file) shutil.copyfile(dat_result_file, dat_Flow1D_thermomech_test_result_file) print("Flow1D thermomech results copied to the appropriate FEM test dirs in: " + temp_dir)