diff --git a/src/Mod/Fem/App/FemVTKTools.cpp b/src/Mod/Fem/App/FemVTKTools.cpp index c5f8d337bbbf..0f06ed00b762 100644 --- a/src/Mod/Fem/App/FemVTKTools.cpp +++ b/src/Mod/Fem/App/FemVTKTools.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -109,7 +110,13 @@ template void writeVTKFile(const char* filename, vtkSmartPointer< writer->Write(); } -void FemVTKTools::importVTKMesh(vtkSmartPointer dataset, FemMesh* mesh) +/* + double scale = 1000; + p[0] = p[0]* scale; // scale back to mm + p[1] = p[1]* scale; + p[1] = p[1]* scale; + */ +void FemVTKTools::importVTKMesh(vtkSmartPointer dataset, FemMesh* mesh, float scale) { const vtkIdType nPoints = dataset->GetNumberOfPoints(); const vtkIdType nCells = dataset->GetNumberOfCells(); @@ -126,7 +133,7 @@ void FemVTKTools::importVTKMesh(vtkSmartPointer dataset, FemMesh* me for(vtkIdType i=0; iGetPoint(i); - meshds->AddNodeWithID(p[0], p[1], p[2], i+1); + meshds->AddNodeWithID(p[0]*scale, p[1]*scale, p[2]*scale, i+1); } for(vtkIdType iCell=0; iCellGetInt("UserSchema",0); + float scale = 1.0; + if(unitSchema == 0) // standard mm + { + scale = 1000.0; // convert from meter in length of CFD result file + } vtkSmartPointer ds; if(f.hasExtension("vtu")) { @@ -528,7 +542,7 @@ App::DocumentObject* FemVTKTools::readFluidicResult(const char* filename, App::D App::DocumentObject* mesh = pcDoc->addObject("Fem::FemMeshObject", "ResultMesh"); FemMesh* fmesh = new FemMesh(); // PropertyFemMesh instance is responsible to relase FemMesh ?? - importVTKMesh(dataset, fmesh); + importVTKMesh(dataset, fmesh, scale); static_cast(mesh->getPropertyByName("FemMesh"))->setValue(*fmesh); static_cast(result->getPropertyByName("Mesh"))->setValue(mesh); // PropertyLink is the property type to store DocumentObject pointer @@ -636,20 +650,37 @@ void FemVTKTools::importFluidicResult(vtkSmartPointer dataset, App:: vtkSmartPointer vel = pd->GetArray(vars["Velocity"]); if(nPoints && vel && vel->GetNumberOfComponents() == 3) { std::vector vec(nPoints); - double vmin=1.0e100, vmean=0.0, vmax=0.0; // only velocity magnitude is calc in c++ + double vmin=1.0e100, vmean=0.0, vmax=0.0; + //stat of Vx, Vy, Vz is not necessary + double vmins[3] = {0.0, 0.0, 0.0}; + double vmeans[3] = {0.0, 0.0, 0.0}; + double vmaxs[3] = {0.0, 0.0, 0.0}; for(vtkIdType i=0; iGetTuple(i); // both vtkFloatArray and vtkDoubleArray return double* for GetTuple(i) double vmag = std::sqrt(p[0]*p[0] + p[1]*p[1] + p[2]*p[2]); + for(int ii=0; ii<3; ii++) { + vmeans[ii] += p[ii]; + if(p[ii] > vmaxs[ii]) vmaxs[ii] = p[ii]; + if(p[ii] < vmins[ii]) vmins[ii] = p[ii]; + } vmean += vmag; if(vmag > vmax) vmax = vmag; if(vmag < vmin) vmin = vmag; + vec[i] = (Base::Vector3d(p[0], p[1], p[2])); nodeIds[i] = i; } + + for(int ii=0; ii<3; ii++) { + stats[ii*3] = vmins[ii]; + stats[ii*3 + 2] = vmaxs[ii]; + stats[ii*3 + 1] = vmeans[ii]/nPoints; + } int index = varids["Umag"]; stats[index*3] = vmin; stats[index*3 + 2] = vmax; stats[index*3 + 1] = vmean/nPoints; + App::PropertyVectorList* velocity = static_cast(res->getPropertyByName("Velocity")); if(velocity) { //PropertyVectorList will not show up in PropertyEditor diff --git a/src/Mod/Fem/App/FemVTKTools.h b/src/Mod/Fem/App/FemVTKTools.h index bcb14c426aa4..5ae25564039c 100644 --- a/src/Mod/Fem/App/FemVTKTools.h +++ b/src/Mod/Fem/App/FemVTKTools.h @@ -46,7 +46,7 @@ namespace Fem /*! FemMesh import from vtkUnstructuredGrid instance */ - static void importVTKMesh(vtkSmartPointer grid, FemMesh* mesh); + static void importVTKMesh(vtkSmartPointer grid, FemMesh* mesh, float scale = 1.0); /*! FemMesh read from vtkUnstructuredGrid data file */ diff --git a/src/Mod/Fem/Gui/Resources/Fem.qrc b/src/Mod/Fem/Gui/Resources/Fem.qrc index 41b7f96984f0..def1d5bc411e 100755 --- a/src/Mod/Fem/Gui/Resources/Fem.qrc +++ b/src/Mod/Fem/Gui/Resources/Fem.qrc @@ -36,6 +36,7 @@ icons/fem-frequency-analysis.svg icons/fem-inp-editor.svg icons/fem-material.svg + icons/fem-material-fluid.svg icons/fem-material-nonlinear.svg icons/fem-plane.svg icons/fem-purge-results.svg diff --git a/src/Mod/Fem/Gui/Resources/icons/fem-material-fluid.svg b/src/Mod/Fem/Gui/Resources/icons/fem-material-fluid.svg new file mode 100644 index 000000000000..752477bacdae --- /dev/null +++ b/src/Mod/Fem/Gui/Resources/icons/fem-material-fluid.svg @@ -0,0 +1,532 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/src/Mod/Fem/TaskPanelFemMaterial.ui b/src/Mod/Fem/TaskPanelFemMaterial.ui index 516c5362c6b8..6db6b83dc78f 100755 --- a/src/Mod/Fem/TaskPanelFemMaterial.ui +++ b/src/Mod/Fem/TaskPanelFemMaterial.ui @@ -137,24 +137,14 @@ QFormLayout::AllNonFixedFieldsGrow - + - Density + Density - - - - save as name - - - - - - - + @@ -576,6 +566,13 @@ External material resources + + + + save customed material + + + diff --git a/src/Mod/Fem/_CommandMaterialFluid.py b/src/Mod/Fem/_CommandMaterialFluid.py index 92927ef2b7d1..54b20b60e892 100644 --- a/src/Mod/Fem/_CommandMaterialFluid.py +++ b/src/Mod/Fem/_CommandMaterialFluid.py @@ -38,7 +38,7 @@ class _CommandMaterialFluid(FemCommands): "the Fem_MaterialFluid command definition" def __init__(self): super(_CommandMaterialFluid, self).__init__() - self.resources = {'Pixmap': 'fem-material', + self.resources = {'Pixmap': 'fem-material-fluid', 'MenuText': QtCore.QT_TRANSLATE_NOOP("Fem_MaterialFluid", "FEM material for Fluid"), 'Accel': "M, M", 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Fem_MaterialFluid", "Creates a FEM material for Fluid")} diff --git a/src/Mod/Fem/_TaskPanelFemMaterial.py b/src/Mod/Fem/_TaskPanelFemMaterial.py index 76de8660fbe8..313addb2946c 100644 --- a/src/Mod/Fem/_TaskPanelFemMaterial.py +++ b/src/Mod/Fem/_TaskPanelFemMaterial.py @@ -30,6 +30,8 @@ import FreeCAD import FreeCADGui from PySide import QtGui +from PySide.QtGui import QFileDialog +from PySide.QtGui import QMessageBox from PySide import QtCore import Units @@ -51,8 +53,8 @@ def __init__(self, obj): self.references_shape_type = None self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Fem/TaskPanelFemMaterial.ui") - QtCore.QObject.connect(self.form.pushButton_MatWeb, QtCore.SIGNAL("clicked()"), self.goMatWeb) - QtCore.QObject.connect(self.form.pushButton_saveas, QtCore.SIGNAL("clicked()"), self.saveas_material) + QtCore.QObject.connect(self.form.pushButton_MatWeb, QtCore.SIGNAL("clicked()"), self.goto_MatWeb) + QtCore.QObject.connect(self.form.pushButton_saveas, QtCore.SIGNAL("clicked()"), self.export_material) QtCore.QObject.connect(self.form.cb_materials, QtCore.SIGNAL("activated(int)"), self.choose_material) QtCore.QObject.connect(self.form.pushButton_Reference, QtCore.SIGNAL("clicked()"), self.add_references) QtCore.QObject.connect(self.form.rb_standard, QtCore.SIGNAL("toggled(bool)"), self.choose_selection_mode_standard) @@ -154,7 +156,7 @@ def has_equal_references_shape_types(self): return False return True - def goMatWeb(self): + def goto_MatWeb(self): import webbrowser webbrowser.open("http://matweb.com") @@ -353,6 +355,7 @@ def add_transient_material(self, material): self.form.cb_materials.addItem(QtGui.QIcon(":/icons/help-browser.svg"), material_name, material_name) self.materials[material_name] = material + ######################## material import and export ################### def import_materials(self): self.materials = {} self.pathList = [] @@ -388,7 +391,7 @@ def import_fluid_materials(self): use_mat_from_config_dir = self.fem_prefs.GetBool("UseMaterialsFromConfigDir", True) if use_mat_from_config_dir: - user_mat_dirname = FreeCAD.getUserAppDataDir() + "Materials" + user_mat_dirname = FreeCAD.getUserAppDataDir() + "FluidMaterial" self.add_mat_dir(user_mat_dirname, ":/icons/preferences-general.svg") use_mat_from_custom_dir = self.fem_prefs.GetBool("UseMaterialsFromCustomDir", True) @@ -413,10 +416,71 @@ def add_mat_dir(self, mat_dir, icon): for mat in material_name_list: self.form.cb_materials.addItem(QtGui.QIcon(icon), mat[0], mat[1]) - def saveas_material(self): - import Material - mat_file_extension = ".FCMat" - # overwritinig warning, save to customed dir, material name check + def export_FCMat(self, fileName, matDict): + """ + Write a material dictionary to a FCMat file, a version without group support, with Python3 + + """ + try: + import ConfigParser as configparser + except: + import configparser # Python 3 + import string + Config = configparser.ConfigParser() + Config.optionxform = str # disable conversion all uppercase leter in key into lower case + + # ignore creating group, just fill all into group 'FCMat' + grp = 'FCMat' + if not Config.has_section(grp): + Config.add_section(grp) + for x in matDict.keys(): + Config.set(grp,x,matDict[x]) + + Preamble = "# This is a FreeCAD material-card file\n\n" + # Writing our configuration file to 'example.cfg' + with open(fileName, 'wb') as configfile: + configfile.write(Preamble) + Config.write(configfile) + + def export_material(self): + import os + if self.obj.Category == 'Fluid': + MaterialDir = 'FluidMaterial' + else: + MaterialDir = 'Material' + _UseMaterialsFromCustomDir = self.fem_prefs.GetBool("UseMaterialsFromCustomDir", True) + _dir =self.fem_prefs.GetString("CustomMaterialsDir", "") + if _UseMaterialsFromCustomDir and _dir != "" and os.path.isdir(_dir): + TargetDir = self.fem_prefs.GetString("CustomMaterialsDir", "") + elif self.fem_prefs.GetBool("UseMaterialsFromConfigDir", True): + TargetDir = FreeCAD.getUserAppDataDir() + os.path.sep + MaterialDir # $HOME/.FreeCAD + else: + FreeCAD.Console.PrintMessage("Customed material saving directory is not setup in Fem preference") + if not os.path.exists(TargetDir): + os.mkdir(TargetDir) + + saveName, Filter = QFileDialog.getSaveFileName(None, "Save a Material property file", TargetDir, "*.FCMat") + if not saveName == "": + print(saveName) + knownMaterials = [self.form.cb_materials.itemText(i) for i in range(self.form.cb_materials.count())] + material_name = os.path.basename(saveName[:-len('.FCMat')]) + if material_name not in knownMaterials: + self.export_FCMat(saveName, self.obj.Material) + FreeCAD.Console.PrintMessage("Sucessfully save the Material property file: "+ saveName + "\n") + else: + self.export_FCMat(saveName, self.obj.Material) + FreeCAD.Console.PrintMessage("Sucessfully overwritren the Material property file: "+ saveName + "\n") + """ + msgBox = QMessageBox() + msgBox.setText("FcMat file name {} has existed in {} or system folder, overwriting?\n".format(saveName, TargetDir)) + msgBox.addButton(QMessageBox.Yes) + msgBox.addButton(QMessageBox.No) + msgBox.setDefaultButton(QMessageBox.No) + ret = msgBox.exec_() + if ret == QMessageBox.Yes: + self.export_FCMat(saveName, self.obj.Material) + FreeCAD.Console.PrintMessage("Sucessfully overwritren the Material property file: "+ saveName + "\n") + """ ###################geometry reference selection ################# def references_list_right_clicked(self, QPos): diff --git a/src/Mod/Material/FluidMaterial/None.FCMat b/src/Mod/Material/FluidMaterial/None.FCMat index 175136a874bd..41b44668b594 100644 --- a/src/Mod/Material/FluidMaterial/None.FCMat +++ b/src/Mod/Material/FluidMaterial/None.FCMat @@ -5,7 +5,7 @@ Description = None Density = 0 kg/m^3 DynamicViscosity = 0 kg/m/s KinematicViscosity = 0 m^2/s -VolumetricExpansionCoefficient = 0 m/m/K +VolumetricThermalExpansionCoefficient = 0 m/m/K SpecificHeat = 0 J/kg/K ThermalConductivity = 0 W/m/K diff --git a/src/Mod/Material/FluidMaterial/Water.FCMat b/src/Mod/Material/FluidMaterial/Water.FCMat index 141279687a74..7a80eb8e1673 100644 --- a/src/Mod/Material/FluidMaterial/Water.FCMat +++ b/src/Mod/Material/FluidMaterial/Water.FCMat @@ -7,7 +7,7 @@ Density = 998 kg/m^3 DynamicViscosity = 1.003e-3 kg/m/s KinematicViscosity = 1.005 m^2/s -VolumetricExpansionCoefficient = 2.07e-4 m/m/K +VolumetricThermalExpansionCoefficient = 2.07e-4 m/m/K SpecificHeat = 4.182 J/kg/K ThermalConductivity = 0.591 W/m/K