def __init__(self, analysis=None, solver=None): super(CfdRunnable, self).__init__() if analysis and analysis.isDerivedFrom("Fem::FemAnalysisPython"): ## @var analysis # FEM analysis - the core object. Has to be present. # It's set to analysis passed in "__init__" or set to current active analysis by default if nothing has been passed to "__init__" self.analysis = analysis else: if FreeCAD.GuiUp: import FemGui self.analysis = FemGui.getActiveAnalysis() self.solver = None if solver and solver.isDerivedFrom("Fem::FemSolverObjectPython"): ## @var solver # solver of the analysis. Used to store the active solver and analysis parameters self.solver = solver else: if analysis: self.solver = CfdTools.getSolver(self.analysis) if self.solver == None: FreeCAD.Console.printMessage("FemSolver object is missing from Analysis Object") if self.analysis: self.results_present = False self.result_object = None else: raise Exception('FEM: No active analysis found!') self.edit_process = None
def __init__(self, analysis_obj): """ analysis_obj should contains all the information needed, boundaryConditionList is a list of all boundary Conditions objects(FemConstraint) """ self.analysis_obj = analysis_obj self.solver_obj = CfdTools.getSolver(analysis_obj) self.mesh_obj = CfdTools.getMesh(analysis_obj) self.part_obj = self.mesh_obj.Part if not self.part_obj: print( "Error!, mesh has no Part property link to an geometry object") self.dimension = CfdTools.getPartDimension(self.part_obj) self.material_obj = CfdTools.getMaterial(analysis_obj) self.bc_group = CfdTools.getConstraintGroup( analysis_obj) # not work for pure Python constraint yet self.mesh_generated = False # unit schema detection is usful for mesh scaling, boundary type area, pressure calculation self.unit_shema = FreeCAD.ParamGet( "User parameter:BaseApp/Preferences/Units/").GetInt("UserSchema") self.case_file_name = self.solver_obj.WorkingDir + os.path.sep + self.solver_obj.InputCaseName + u".json" if self.solver_obj.Parallel: # FIXME: XDMF is the preferred file io for parallel mesh in the future self.mesh_file_name = self.solver_obj.WorkingDir + os.path.sep + self.solver_obj.InputCaseName + u".hdf5" else: self.mesh_file_name = self.solver_obj.WorkingDir + os.path.sep + self.solver_obj.InputCaseName + u".xml" self.case_settings = OrderedDict( ) # OrderedDict does not support pprint self.case_settings['case_name'] = self.solver_obj.InputCaseName self.case_settings['case_folder'] = self.solver_obj.WorkingDir self.case_settings['case_file'] = self.case_file_name
def __init__(self, analysis_obj): super(CfdCaseWriterFoam, self).__init__() """ analysis_obj should contains all the information needed, boundaryConditionList is a list of all boundary Conditions objects(FemConstraint) """ self.analysis_obj = analysis_obj self.solver_obj = CfdTools.getSolver(analysis_obj) self.physics_model, isPresent = CfdTools.getPhysicsModel(analysis_obj) self.mesh_obj = CfdTools.getMesh(analysis_obj) self.material_objs = CfdTools.getMaterials(analysis_obj) self.bc_group = CfdTools.getCfdBoundaryGroup(analysis_obj) self.initial_conditions, isPresent = CfdTools.getInitialConditions( analysis_obj) self.porousZone_objs, self.porousZonePresent = CfdTools.getPorousObjects( analysis_obj) self.alphaZone_objs = CfdTools.getAlphaObjects(analysis_obj) self.zone_objs = CfdTools.getZoneObjects(analysis_obj) self.mesh_generated = False self.signals = CfdCaseWriterSignals() if len(self.alphaZone_objs) > 0: self.physics_model['Time'] = 'Transient' # TODO: remove this code and add GUI support for transient simulations self.solver_obj.TimeStep = 0.001 self.solver_obj.WriteInterval = 0.05 self.solver_obj.EndTime = 1
def __init__(self, analysis_obj): self.analysis_obj = analysis_obj self.solver_obj = CfdTools.getSolver(analysis_obj) self.physics_model = CfdTools.getPhysicsModel(analysis_obj) self.mesh_obj = CfdTools.getMesh(analysis_obj) self.material_objs = CfdTools.getMaterials(analysis_obj) self.bc_group = CfdTools.getCfdBoundaryGroup(analysis_obj) self.initial_conditions = CfdTools.getInitialConditions(analysis_obj) self.porousZone_objs = CfdTools.getPorousZoneObjects(analysis_obj) self.initialisationZone_objs = CfdTools.getInitialisationZoneObjects(analysis_obj) self.zone_objs = CfdTools.getZoneObjects(analysis_obj) self.mesh_generated = False self.working_dir = CfdTools.getOutputPath(self.analysis_obj)
def __init__(self, analysis_obj): self.analysis_obj = analysis_obj self.solver_obj = CfdTools.getSolver(analysis_obj) self.physics_model, isPresent = CfdTools.getPhysicsModel(analysis_obj) self.mesh_obj = CfdTools.getMesh(analysis_obj) self.material_objs = CfdTools.getMaterials(analysis_obj) self.bc_group = CfdTools.getCfdBoundaryGroup(analysis_obj) self.initial_conditions, isPresent = CfdTools.getInitialConditions(analysis_obj) self.porousZone_objs = CfdTools.getPorousZoneObjects(analysis_obj) self.initialisationZone_objs = CfdTools.getInitialisationZoneObjects(analysis_obj) self.zone_objs = CfdTools.getZoneObjects(analysis_obj) self.conversion2D_obj,self.conversionObjPresent = CfdTools.get2DConversionObject(analysis_obj) self.mesh_generated = False
def __init__(self, obj): self.obj = obj analysis_obj = CfdTools.getParentAnalysisObject(obj) solver_obj = CfdTools.getSolver(analysis_obj) material_objs = CfdTools.getMaterials(analysis_obj) self.boundaryWidget = CfdBoundaryWidget(obj, None, solver_obj, material_objs) # fill the table in each variable tab, saved from the previous setup, existing case if BC name, done in each widget # geometry selection widget, only face is needed as boundary for CFD # GeometryElementsSelection(ref, eltypes=[], multigeom=True) # allow_multiple_geom_types = multigeom self.selectionWidget = FemSelectionWidgets.GeometryElementsSelection( obj.References, ['Face'], False) # check references, has to be after initialization of selectionWidget try: self.selectionWidget.has_equal_references_shape_types( ) # boundarySelector has no such method except: print( '`selectionWidget.has_equal_references_shape_types()` is only available in FreeCAD 0.18+' ) #the magic to have two widgets in one taskpanel self.form = [self.selectionWidget, self.boundaryWidget] if True: # todo: check if solver is 'OpenFOAM' from CfdFoamTools import getVariableList solverSettings = CfdTools.getSolverSettings( solver_obj) # physical_model variable_list = getVariableList(solverSettings) # TODO: if boundary_settings is empty dict, default setting for each variable could be provided if "FoamBoundarySettings" in self.obj.PropertiesList and self.obj.FoamBoundarySettings: self.foam_boundary_conditions = self.obj.FoamBoundarySettings else: print("debug print: variable_list", variable_list) self.foam_boundary_conditions = { var: {} for var in variable_list } # {varible: bc_dict, ...} from FoamCaseBuilder.FoamBoundaryWidget import FoamBoundaryWidget s = {"variables": self.foam_boundary_conditions} self.foamWidget = FoamBoundaryWidget(s) self.form.append(self.foamWidget)
def accept(self): changed_transient = False if self.obj.PhysicsModel['Time'] != self.physicsModel['Time']: changed_transient = True self.obj.PhysicsModel = self.physicsModel doc = FreeCADGui.getDocument(self.obj.Document) doc.resetEdit() FreeCADGui.doCommand( "\nphys = FreeCAD.ActiveDocument.{}.PhysicsModel".format( self.obj.Name)) FreeCADGui.doCommand("phys['Time'] = '{}'".format( self.physicsModel['Time'])) FreeCADGui.doCommand("phys['Flow'] = '{}'".format( self.physicsModel['Flow'])) FreeCADGui.doCommand("phys['Turbulence'] = '{}'".format( self.physicsModel['Turbulence'])) FreeCADGui.doCommand("phys['TurbulenceModel'] = '{}'".format( self.physicsModel['TurbulenceModel'])) FreeCADGui.doCommand("phys['Thermal'] = {}".format( self.physicsModel['Thermal'])) FreeCADGui.doCommand("phys['Gravity'] = {}".format( self.physicsModel['Gravity'])) FreeCADGui.doCommand( "FreeCAD.ActiveDocument.{}.PhysicsModel = phys".format( self.obj.Name)) if changed_transient: # TODO # For now, init the solver object's time values to sensible defaults for steady or transient # The user can then edit further a = CfdTools.getParentAnalysisObject(self.obj) if a: sol = CfdTools.getSolver(a) if sol: FreeCADGui.doCommand( "\nsol = FreeCAD.ActiveDocument.{}".format(sol.Name)) if self.obj.PhysicsModel['Time'] == 'Steady': FreeCADGui.doCommand("sol.EndTime = 1000\n" "sol.TimeStep = 1\n" "sol.WriteInterval = 100\n") else: FreeCADGui.doCommand("sol.EndTime = 1\n" "sol.TimeStep = 0.001\n" "sol.WriteInterval = 0.1\n")
def __init__(self, analysis_obj): """ analysis_obj should contains all the information needed, boundaryConditionList is a list of all boundary Conditions objects(FemConstraint) """ self.analysis_obj = analysis_obj self.solver_obj = CfdTools.getSolver(analysis_obj) self.mesh_obj = CfdTools.getMesh(analysis_obj) self.material_obj = CfdTools.getMaterial(analysis_obj) self.bc_group = CfdTools.getConstraintGroup(analysis_obj) self.mesh_generated = False self.case_folder = self.solver_obj.WorkingDir + os.path.sep + self.solver_obj.InputCaseName self.mesh_file_name = self.case_folder + os.path.sep + self.solver_obj.InputCaseName + u".unv" if self.solver_obj.HeatTransfering: self.builder = fcb.BasicBuilder(self.case_folder, CfdTools.getSolverSettings(self.solver_obj)) else: self.builder = fcb.BasicBuilder(self.case_folder, CfdTools.getSolverSettings(self.solver_obj)) self.builder.createCase()
def __init__(self, analysis_obj): super(CfdCaseWriterFoam, self).__init__() self.analysis_obj = analysis_obj self.solver_obj = CfdTools.getSolver(analysis_obj) self.physics_model, isPresent = CfdTools.getPhysicsModel(analysis_obj) self.mesh_obj = CfdTools.getMesh(analysis_obj) self.material_objs = CfdTools.getMaterials(analysis_obj) self.bc_group = CfdTools.getCfdBoundaryGroup(analysis_obj) self.initial_conditions, isPresent = CfdTools.getInitialConditions( analysis_obj) self.porousZone_objs = CfdTools.getPorousZoneObjects(analysis_obj) self.initialisationZone_objs = CfdTools.getInitialisationZoneObjects( analysis_obj) self.zone_objs = CfdTools.getZoneObjects(analysis_obj) self.mesh_generated = False self.signals = CfdCaseWriterSignals()
def __init__(self, analysis_obj): """ analysis_obj should contains all the information needed, boundaryConditionList is a list of all boundary Conditions objects(FemConstraint) """ self.analysis_obj = analysis_obj self.solver_obj = CfdTools.getSolver(analysis_obj) self.mesh_obj = CfdTools.getMesh(analysis_obj) self.material_obj = CfdTools.getMaterial(analysis_obj) self.bc_group = CfdTools.getConstraintGroup(analysis_obj) self.mesh_generated = False # unit schema detection is usful for mesh scaling, boundary type area, pressure calculation self.unit_shema = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Units/").GetInt("UserSchema") self.case_file_name = self.solver_obj.WorkingDir + os.path.sep + self.solver_obj.InputCaseName + u".json" self.mesh_file_name = self.solver_obj.WorkingDir + os.path.sep + self.solver_obj.InputCaseName + u".xml" # Collections.OrderedDict s also can not dump json self.case_settings = {'case_name': self.solver_obj.InputCaseName, 'case_folder': self.solver_obj.WorkingDir, 'case_file': self.case_file_name}
def __init__(self, analysis=None, solver=None): super(CfdRunnable, self).__init__() if analysis and isinstance(analysis.Proxy, CfdAnalysis._CfdAnalysis): self.analysis = analysis else: if FreeCAD.GuiUp: self.analysis = CfdTools.getActiveAnalysis() self.solver = None if solver: self.solver = solver else: if analysis: self.solver = CfdTools.getSolver(self.analysis) if not self.solver: FreeCAD.Console.printMessage("Solver object is missing from Analysis Object") if self.analysis: self.results_present = False self.result_object = None else: raise Exception('No active analysis found')
def __init__(self, analysis_obj): """ analysis_obj should contains all the information needed, boundaryConditionList is a list of all boundary Conditions objects(FemConstraint) """ self.analysis_obj = analysis_obj self.solver_obj = CfdTools.getSolver(analysis_obj) self.mesh_obj = CfdTools.getMesh(analysis_obj) self.material_obj = CfdTools.getMaterial(analysis_obj) self.bc_group = CfdTools.getConstraintGroup(analysis_obj) self.mesh_generated = False # unit schema detection is usful for mesh scaling, boundary type area, pressure calculation self.unit_shema = FreeCAD.ParamGet( "User parameter:BaseApp/Preferences/Units/").GetInt("UserSchema") self.case_folder = self.solver_obj.WorkingDir + os.path.sep + self.solver_obj.InputCaseName self.mesh_file_name = self.case_folder + os.path.sep + self.solver_obj.InputCaseName + u".unv" if self.solver_obj.HeatTransfering: self.builder = fcb.BasicBuilder( self.case_folder, CfdTools.getSolverSettings(self.solver_obj)) else: self.builder = fcb.BasicBuilder( self.case_folder, CfdTools.getSolverSettings(self.solver_obj))
def __init__(self, obj): self.obj = obj analysis_obj = CfdTools.getParentAnalysisObject(obj) solver_obj = CfdTools.getSolver(analysis_obj) material_objs = CfdTools.getMaterials(analysis_obj) from CfdBoundaryWidget import CfdBoundaryWidget self.boundaryWidget = CfdBoundaryWidget(obj, None, solver_obj, material_objs) # fill the table in each variable tab, saved from the previous setup, existing case if BC name, done in each widget # geometry selection widget, only face is needed as boundary self.selectionWidget = FemSelectionWidgets.BoundarySelector() self.selectionWidget.setReferences(obj.References) # check references, has to be after initialisation of selectionWidget try: self.selectionWidget.has_equal_references_shape_types() except: RuntimeError('this function only works for FreeCAD 0.18') #the magic to have two widgets in one taskpanel self.form = [self.selectionWidget, self.boundaryWidget] if True: # todo: check if solver is 'OpenFOAM' from CfdFoamTools import getVariableList solverSettings = CfdTools.getSolverSettings(solver_obj) # physical_model variable_list = getVariableList(solverSettings) # build a parameterTabWidget, with each tab has a tableView # TODO: if boundary_settings is empty dict, default setting for each variable could be provided if not self.obj.FoamBoundarySettings: self.foam_boundary_conditions = {'U': {"key": "value"}, 'p':{"key": "value"}} # {varible: bc_dict, ...} else: self.foam_boundary_conditions = self.obj.FoamBoundarySettings from FoamCaseBuilder.FoamBoundaryWidget import FoamBoundaryWidget self.foamWidget = FoamBoundaryWidget(self.foam_boundary_conditions) self.form.append(self.foamWidget)
def convertMesh(self): import tempfile import CfdCaseWriterFoam import CfdCartTools import TemplateBuilder import os if not (self.meshConverted): self.Start = time.time() self.Timer.start() self.console_log("Starting 3D to 2D mesh conversion ...") self.frontFaceName = self.form.comboBoxFront.currentText() self.backFaceName = self.form.comboBoxBack.currentText() tmpdir = tempfile.gettempdir() analysis_obj = FemGui.getActiveAnalysis() tmpdir = tempfile.gettempdir() self.meshCaseDir = os.path.join(tmpdir, "meshCase") self.meshObj = CfdTools.getMesh(analysis_obj) solver_obj = CfdTools.getSolver(analysis_obj) gmshMesh = False if self.meshObj.Proxy.Type == "Fem::FemMeshGmsh": # GMSH # Convert GMSH created UNV file to OpenFoam print("Writing GMSH UNV mesh to be converted to 2D mesh") unvMeshFile = self.meshCaseDir + os.path.sep + solver_obj.InputCaseName + u".unv" #try: if not os.path.exists(self.meshCaseDir): os.makedirs(self.meshCaseDir) bc_group = CfdTools.getCfdBoundaryGroup(analysis_obj) self.mesh_generated = CfdTools.write_unv_mesh( self.meshObj, bc_group, unvMeshFile) gmshMesh = True frontFaceList = self.frontFaceName backFaceList = [self.backFaceName] else: case = CfdCaseWriterFoam.CfdCaseWriterFoam(analysis_obj) case.settings = {} case.settings['createPatchesFromSnappyBaffles'] = False case.setupPatchNames() keys = case.settings['createPatches'].keys() frontPatchIndex = keys.index(self.frontFaceName) frontFaceList = case.settings['createPatches'][ keys[frontPatchIndex]]['PatchNamesList'] backPatchIndex = keys.index(self.backFaceName) backFaceList = case.settings['createPatches'][ keys[backPatchIndex]]['PatchNamesList'] template_path = os.path.join(CfdTools.get_module_path(), "data", "defaultsMesh") settings = { 'ConvertTo2D': True, 'gmshMesh': gmshMesh, 'unvFileName': solver_obj.InputCaseName + u".unv", 'FrontFaceList': frontFaceList, 'BackFaceList': backFaceList[0], 'Distance': self.distance / 1000.0, 'TranslatedFoamPath': CfdTools.translatePath(CfdTools.getFoamDir(), ), 'MeshPath': self.meshCaseDir } TemplateBuilder.TemplateBuilder(self.meshCaseDir, template_path, settings) cmd = CfdTools.makeRunCommand('./ConvertMeshTo2D', self.meshCaseDir, source_env=False) #will fail silently in Windows fname = os.path.join(self.meshCaseDir, "ConvertMeshTo2D") import stat s = os.stat(fname) os.chmod(fname, s.st_mode | stat.S_IEXEC) FreeCAD.Console.PrintMessage("Executing: " + ' '.join(cmd) + "\n") env = QtCore.QProcessEnvironment.systemEnvironment() env_vars = CfdTools.getRunEnvironment() for key in env_vars: env.insert(key, env_vars[key]) self.conversion_process.setProcessEnvironment(env) self.conversion_process.start(cmd[0], cmd[1:]) if self.conversion_process.waitForStarted(): self.form.convertButton.setEnabled( False) # Prevent user running a second instance self.form.paraviewButton.setEnabled(False) else: self.console_log("Error starting meshing process", "#FF0000")
def accept(self): doc = FreeCADGui.getDocument(self.obj.Document) doc.resetEdit() FreeCADGui.doCommand("\nobj = FreeCAD.ActiveDocument.{}".format( self.obj.Name)) changed_transient = False if self.form.radioButtonSteady.isChecked(): if self.obj.Time != 'Steady': changed_transient = True FreeCADGui.doCommand("obj.Time = 'Steady'") elif self.form.radioButtonTransient.isChecked(): if self.obj.Time != 'Transient': changed_transient = True FreeCADGui.doCommand("obj.Time = 'Transient'") if self.form.radioButtonSinglePhase.isChecked(): FreeCADGui.doCommand("obj.Phase = 'Single'") elif self.form.radioButtonFreeSurface.isChecked(): FreeCADGui.doCommand("obj.Phase = 'FreeSurface'") if self.form.radioButtonIncompressible.isChecked(): FreeCADGui.doCommand("obj.Flow = 'Incompressible'") FreeCADGui.doCommand("obj.Thermal = 'None'") elif self.form.radioButtonCompressible.isChecked(): if self.form.checkBoxHighMach.isChecked(): FreeCADGui.doCommand("obj.Flow = 'HighMachCompressible'") FreeCADGui.doCommand("obj.Thermal = 'Energy'") else: FreeCADGui.doCommand("obj.Flow = 'Compressible'") FreeCADGui.doCommand("obj.Thermal = 'None'") if self.form.viscousCheckBox.isChecked(): if self.form.radioButtonLaminar.isChecked(): FreeCADGui.doCommand("obj.Turbulence = 'Laminar'") elif self.form.radioButtonRANS.isChecked(): FreeCADGui.doCommand("obj.Turbulence = 'RANS'") FreeCADGui.doCommand("obj.TurbulenceModel = '{}'".format( self.form.turbulenceComboBox.currentText())) else: FreeCADGui.doCommand("obj.Turbulence = 'Inviscid'") #if self.form.radioButtonEnergy.isChecked(): # FreeCADGui.doCommand("obj.Thermal = 'Energy'") #elif self.form.radioButtonBuoyancy.isChecked(): # FreeCADGui.doCommand("obj.Thermal = 'Buoyancy'") FreeCADGui.doCommand("obj.gx = '{}'".format(self.form.gx.text())) FreeCADGui.doCommand("obj.gy = '{}'".format(self.form.gy.text())) FreeCADGui.doCommand("obj.gz = '{}'".format(self.form.gz.text())) if changed_transient: # TODO # For now, init the solver object's time values to sensible defaults for steady or transient # The user can then edit further a = CfdTools.getParentAnalysisObject(self.obj) if a: sol = CfdTools.getSolver(a) if sol: FreeCADGui.doCommand( "\nsol = FreeCAD.ActiveDocument.{}".format(sol.Name)) if self.obj.Time == 'Steady': FreeCADGui.doCommand("sol.EndTime = 1000\n" "sol.TimeStep = 1\n" "sol.WriteInterval = 100\n") else: FreeCADGui.doCommand("sol.EndTime = 1\n" "sol.TimeStep = 0.001\n" "sol.WriteInterval = 0.1\n")