Add ViewProvider and TaskPanel FemConstraintFluidBoundary for CFD analysis
This commit is contained in:
parent
df8e53630d
commit
17829b9727
|
@ -56,6 +56,7 @@
|
|||
#include "FemConstraintInitialTemperature.h"
|
||||
#include "FemConstraintPlaneRotation.h"
|
||||
#include "FemConstraintContact.h"
|
||||
#include "FemConstraintFluidBoundary.h"
|
||||
|
||||
#include "FemResultObject.h"
|
||||
#include "FemSolverObject.h"
|
||||
|
@ -157,7 +158,8 @@ PyMODINIT_FUNC initFem()
|
|||
Fem::ConstraintInitialTemperature ::init();
|
||||
Fem::ConstraintPlaneRotation ::init();
|
||||
Fem::ConstraintContact ::init();
|
||||
|
||||
Fem::ConstraintFluidBoundary ::init();
|
||||
|
||||
Fem::FemResultObject ::init();
|
||||
Fem::FemSolverObject ::init();
|
||||
Fem::FemSolverObjectPython ::init();
|
||||
|
|
|
@ -197,6 +197,8 @@ SET(FemConstraints_SRCS
|
|||
FemConstraintFixed.h
|
||||
FemConstraintForce.cpp
|
||||
FemConstraintForce.h
|
||||
FemConstraintFluidBoundary.cpp
|
||||
FemConstraintFluidBoundary.h
|
||||
FemConstraintPressure.cpp
|
||||
FemConstraintPressure.h
|
||||
FemConstraintGear.cpp
|
||||
|
|
197
src/Mod/Fem/App/FemConstraintFluidBoundary.cpp
Normal file
197
src/Mod/Fem/App/FemConstraintFluidBoundary.cpp
Normal file
|
@ -0,0 +1,197 @@
|
|||
/***************************************************************************
|
||||
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Pln.hxx>
|
||||
#include <gp_Lin.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <BRepAdaptor_Surface.hxx>
|
||||
#include <BRepAdaptor_Curve.hxx>
|
||||
#include <Precision.hxx>
|
||||
#endif
|
||||
|
||||
#include "FemConstraintFluidBoundary.h"
|
||||
|
||||
#include <Mod/Part/App/PartFeature.h>
|
||||
#include <Base/Console.h>
|
||||
|
||||
using namespace Fem;
|
||||
|
||||
PROPERTY_SOURCE(Fem::ConstraintFluidBoundary, Fem::Constraint);
|
||||
|
||||
// also defined in TaskFemConstraintFluidBoundary.cpp and foamcasebuilder/basicbuilder.py,
|
||||
// please update simultaneously
|
||||
// the second (index 1) is the default enum, as index 0 causes compiling error
|
||||
static const char* BoundaryTypes[] = {"inlet","wall","outlet","interface","freestream", NULL};
|
||||
static const char* WallSubtypes[] = {"unspecific", "fixed", "slip", "moving", NULL};
|
||||
static const char* InletSubtypes[] = {"unspecific","totalPressure","uniformVelocity","volumetricFlowRate","massFlowRate", NULL};
|
||||
static const char* OutletSubtypes[] = {"unspecific","totalPressure","staticPressure","uniformVelocity", "outFlow", NULL};
|
||||
static const char* InterfaceSubtypes[] = {"unspecific","symmetry","wedge","cyclic","empty", NULL};
|
||||
static const char* FreestreamSubtypes[] = {"unspecific", "freestream",NULL};
|
||||
|
||||
// see Ansys fluet manual: Turbulence Specification method
|
||||
static const char* TurbulenceSpecifications[] = {"Intensity&LengthScale","Intensity&HydraulicDiameter",NULL};
|
||||
// activate the heat transfer and radiation model in Solver object explorer
|
||||
/* only used in TaskPanel
|
||||
static const char* TurbulenceSpecificationHelpTexts[] = {"see Ansys fluet manual: Turbulence Specification method",
|
||||
"or fully devloped internal flow, Turbulence intensity (0-1.0) 0.05 typical", NULL};
|
||||
*/
|
||||
|
||||
//HTC value type, not sure it is supported in OpenFOAM
|
||||
static const char* ThermalBoundaryTypes[] = {"fixedValue","zeroGradient", "fixedGradient", "mixed", "HTC","coupled", NULL};
|
||||
/* only used in TaskPanel
|
||||
static const char* ThermalBoundaryHelpTexts[] = {"fixed Temperature [K]", "no heat transfer ()", "fixed value heat flux [W/m2]",
|
||||
"mixed fixedGradient and fixedValue", "Heat transfer coeff [W/(M2)/K]", "conjugate heat transfer with solid", NULL};
|
||||
*/
|
||||
|
||||
ConstraintFluidBoundary::ConstraintFluidBoundary()
|
||||
{
|
||||
// momemtum boundary: pressure and velocity
|
||||
ADD_PROPERTY_TYPE(BoundaryType,(1),"FluidBoundary",(App::PropertyType)(App::Prop_None),
|
||||
"Basic boundary type like inlet, wall, outlet,etc");
|
||||
BoundaryType.setEnums(BoundaryTypes);
|
||||
ADD_PROPERTY_TYPE(Subtype,(1),"FluidBoundary",(App::PropertyType)(App::Prop_None),
|
||||
"Subtype defines value type or more specific type");
|
||||
Subtype.setEnums(WallSubtypes);
|
||||
ADD_PROPERTY_TYPE(BoundaryValue,(0.0),"FluidBoundary",(App::PropertyType)(App::Prop_None),
|
||||
"Scaler value for the specific value subtype, like pressure, velocity");
|
||||
ADD_PROPERTY_TYPE(Direction,(0),"FluidBoundary",(App::PropertyType)(App::Prop_None),
|
||||
"Element giving vector direction of constraint");
|
||||
|
||||
ADD_PROPERTY_TYPE(TurbulenceSpecification,(1),"Turbulence",(App::PropertyType)(App::Prop_None),
|
||||
"Turbulence boundary type");
|
||||
TurbulenceSpecification.setEnums(TurbulenceSpecifications); //Turbulence Specification Method
|
||||
ADD_PROPERTY_TYPE(TurbulentIntensityValue,(0.0),"Turbulence",(App::PropertyType)(App::Prop_None),
|
||||
"Scaler value for Turbulent intensity etc");
|
||||
ADD_PROPERTY_TYPE(TurbulentLengthValue,(0.0),"Turbulence",(App::PropertyType)(App::Prop_None),
|
||||
"Scaler value for Turbulent length scale, hydraulic diameter etc");
|
||||
// consider the newly added Fem::ConstraintTemperature
|
||||
ADD_PROPERTY_TYPE(ThermalBoundaryType,(1),"HeatTransfer",(App::PropertyType)(App::Prop_None),
|
||||
"Thermal boundary type");
|
||||
ThermalBoundaryType.setEnums(ThermalBoundaryTypes);
|
||||
ADD_PROPERTY_TYPE(TemperatureValue,(0.0),"HeatTransfer",(App::PropertyType)(App::Prop_None),
|
||||
"Temperature value for thermal boundary condition");
|
||||
ADD_PROPERTY_TYPE(HeatFluxValue,(0.0),"HeatTransfer",(App::PropertyType)(App::Prop_None),
|
||||
"Heat flux value for thermal boundary condition");
|
||||
ADD_PROPERTY_TYPE(HTCoeffValue,(0.0),"HeatTransfer",(App::PropertyType)(App::Prop_None),
|
||||
"Heat transfer coefficient for convective boundary condition");
|
||||
// geometry rendering related properties
|
||||
ADD_PROPERTY(Reversed,(0));
|
||||
ADD_PROPERTY_TYPE(Points,(Base::Vector3d()),"FluidBoundary",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),
|
||||
"Points where arrows are drawn");
|
||||
ADD_PROPERTY_TYPE(DirectionVector,(Base::Vector3d(0,0,1)),"FluidBoundary",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),
|
||||
"Direction of arrows");
|
||||
naturalDirectionVector = Base::Vector3d(0,0,0); // by default use the null vector to indication an invalid value
|
||||
Points.setValues(std::vector<Base::Vector3d>());
|
||||
// property from: FemConstraintFixed object
|
||||
ADD_PROPERTY_TYPE(Normals,(Base::Vector3d()),"FluidBoundary",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),
|
||||
"Normals where symbols are drawn");
|
||||
Normals.setValues(std::vector<Base::Vector3d>());
|
||||
}
|
||||
|
||||
App::DocumentObjectExecReturn *ConstraintFluidBoundary::execute(void)
|
||||
{
|
||||
return Constraint::execute();
|
||||
}
|
||||
|
||||
void ConstraintFluidBoundary::onChanged(const App::Property* prop)
|
||||
{
|
||||
// Note: If we call this at the end, then the arrows are not oriented correctly initially
|
||||
// because the NormalDirection has not been calculated yet
|
||||
Constraint::onChanged(prop);
|
||||
|
||||
if (prop == &BoundaryType)
|
||||
{
|
||||
std::string boundaryType = BoundaryType.getValueAsString();
|
||||
if (boundaryType == "wall")
|
||||
{
|
||||
Subtype.setEnums(WallSubtypes);
|
||||
}
|
||||
else if (boundaryType == "interface")
|
||||
{
|
||||
Subtype.setEnums(InterfaceSubtypes);
|
||||
}
|
||||
else if (boundaryType == "freestream")
|
||||
{
|
||||
Subtype.setEnums(FreestreamSubtypes);
|
||||
}
|
||||
else if(boundaryType == "inlet")
|
||||
{
|
||||
Subtype.setEnums(InletSubtypes);
|
||||
}
|
||||
else if(boundaryType == "outlet")
|
||||
{
|
||||
Subtype.setEnums(OutletSubtypes);
|
||||
}
|
||||
else
|
||||
{
|
||||
Base::Console().Message(boundaryType.c_str());
|
||||
Base::Console().Message(" Error: this boundaryType is not defined\n");
|
||||
}
|
||||
//need to trigger ViewProvider::updateData() for redraw in 3D view
|
||||
}
|
||||
|
||||
if (prop == &References) {
|
||||
std::vector<Base::Vector3d> points;
|
||||
std::vector<Base::Vector3d> normals;
|
||||
int scale = 1; //OvG: Enforce use of scale
|
||||
if (getPoints(points, normals, &scale)) {
|
||||
Points.setValues(points);
|
||||
Normals.setValues(normals);
|
||||
Scale.setValue(scale); //OvG: Scale
|
||||
Points.touch(); // This triggers ViewProvider::updateData()
|
||||
}
|
||||
} else if (prop == &Direction) {
|
||||
Base::Vector3d direction = getDirection(Direction);
|
||||
if (direction.Length() < Precision::Confusion())
|
||||
return;
|
||||
naturalDirectionVector = direction;
|
||||
if (Reversed.getValue())
|
||||
direction = -direction;
|
||||
DirectionVector.setValue(direction);
|
||||
} else if (prop == &Reversed) {
|
||||
// if the direction is invalid try to compute it again
|
||||
if (naturalDirectionVector.Length() < Precision::Confusion()) {
|
||||
naturalDirectionVector = getDirection(Direction);
|
||||
}
|
||||
if (naturalDirectionVector.Length() >= Precision::Confusion()) {
|
||||
if (Reversed.getValue() && (DirectionVector.getValue() == naturalDirectionVector)) {
|
||||
DirectionVector.setValue(-naturalDirectionVector);
|
||||
} else if (!Reversed.getValue() && (DirectionVector.getValue() != naturalDirectionVector)) {
|
||||
DirectionVector.setValue(naturalDirectionVector);
|
||||
}
|
||||
}
|
||||
} else if (prop == &NormalDirection) {
|
||||
// Set a default direction if no direction reference has been given
|
||||
if (Direction.getValue() == NULL) {
|
||||
Base::Vector3d direction = NormalDirection.getValue();
|
||||
if (Reversed.getValue())
|
||||
direction = -direction;
|
||||
DirectionVector.setValue(direction);
|
||||
naturalDirectionVector = direction;
|
||||
}
|
||||
}
|
||||
}
|
83
src/Mod/Fem/App/FemConstraintFluidBoundary.h
Normal file
83
src/Mod/Fem/App/FemConstraintFluidBoundary.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
/***************************************************************************
|
||||
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef FEM_FLUIDBOUNDARY_H
|
||||
#define FEM_FLUIDBOUNDARY_H
|
||||
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/PropertyStandard.h>
|
||||
#include <App/PropertyLinks.h>
|
||||
#include <App/PropertyGeo.h>
|
||||
|
||||
#include "FemConstraint.h"
|
||||
|
||||
namespace Fem
|
||||
{
|
||||
|
||||
class AppFemExport ConstraintFluidBoundary: public Fem::Constraint
|
||||
{
|
||||
PROPERTY_HEADER(Fem::ConstraintFluidBoundary);
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
ConstraintFluidBoundary(void);
|
||||
//
|
||||
App::PropertyEnumeration BoundaryType;
|
||||
App::PropertyEnumeration Subtype;
|
||||
App::PropertyFloat BoundaryValue;
|
||||
App::PropertyLinkSub Direction;
|
||||
|
||||
App::PropertyEnumeration TurbulenceSpecification;
|
||||
App::PropertyFloat TurbulentIntensityValue;
|
||||
App::PropertyFloat TurbulentLengthValue;
|
||||
|
||||
App::PropertyEnumeration ThermalBoundaryType;
|
||||
App::PropertyFloat TemperatureValue;
|
||||
App::PropertyFloat HeatFluxValue;
|
||||
App::PropertyFloat HTCoeffValue;
|
||||
|
||||
App::PropertyBool Reversed;
|
||||
// Read-only (calculated values). These trigger changes in the ViewProvider
|
||||
App::PropertyVectorList Points;
|
||||
App::PropertyVectorList Normals; // needed to draw diff BoundaryType
|
||||
App::PropertyVector DirectionVector;
|
||||
|
||||
/// recalculate the object
|
||||
virtual App::DocumentObjectExecReturn *execute(void);
|
||||
|
||||
/// returns the type name of the ViewProvider
|
||||
const char* getViewProviderName(void) const {
|
||||
return "FemGui::ViewProviderFemConstraintFluidBoundary";
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void onChanged(const App::Property* prop);
|
||||
|
||||
private:
|
||||
Base::Vector3d naturalDirectionVector;
|
||||
};
|
||||
|
||||
} //namespace Fem
|
||||
|
||||
|
||||
#endif // FEM_FLUIDBOUNDARY_H
|
|
@ -48,6 +48,7 @@
|
|||
#include "ViewProviderFemConstraintBearing.h"
|
||||
#include "ViewProviderFemConstraintFixed.h"
|
||||
#include "ViewProviderFemConstraintForce.h"
|
||||
#include "ViewProviderFemConstraintFluidBoundary.h"
|
||||
#include "ViewProviderFemConstraintPressure.h"
|
||||
#include "ViewProviderFemConstraintGear.h"
|
||||
#include "ViewProviderFemConstraintPulley.h"
|
||||
|
@ -118,6 +119,7 @@ PyMODINIT_FUNC initFemGui()
|
|||
FemGui::ViewProviderFemConstraintBearing ::init();
|
||||
FemGui::ViewProviderFemConstraintFixed ::init();
|
||||
FemGui::ViewProviderFemConstraintForce ::init();
|
||||
FemGui::ViewProviderFemConstraintFluidBoundary ::init();
|
||||
FemGui::ViewProviderFemConstraintPressure ::init();
|
||||
FemGui::ViewProviderFemConstraintGear ::init();
|
||||
FemGui::ViewProviderFemConstraintPulley ::init();
|
||||
|
|
|
@ -61,6 +61,7 @@ set(FemGui_MOC_HDRS
|
|||
TaskFemConstraintBearing.h
|
||||
TaskFemConstraintFixed.h
|
||||
TaskFemConstraintForce.h
|
||||
TaskFemConstraintFluidBoundary.h
|
||||
TaskFemConstraintPressure.h
|
||||
TaskFemConstraintGear.h
|
||||
TaskFemConstraintPulley.h
|
||||
|
@ -95,6 +96,7 @@ set(FemGui_UIC_SRCS
|
|||
TaskFemConstraintBearing.ui
|
||||
TaskFemConstraintFixed.ui
|
||||
TaskFemConstraintForce.ui
|
||||
TaskFemConstraintFluidBoundary.ui
|
||||
TaskFemConstraintPressure.ui
|
||||
TaskFemConstraintDisplacement.ui
|
||||
TaskFemConstraintTemperature.ui
|
||||
|
@ -140,6 +142,9 @@ SET(FemGui_DLG_SRCS
|
|||
TaskFemConstraintForce.ui
|
||||
TaskFemConstraintForce.cpp
|
||||
TaskFemConstraintForce.h
|
||||
TaskFemConstraintFluidBoundary.ui
|
||||
TaskFemConstraintFluidBoundary.cpp
|
||||
TaskFemConstraintFluidBoundary.h
|
||||
TaskFemConstraintPressure.ui
|
||||
TaskFemConstraintPressure.cpp
|
||||
TaskFemConstraintPressure.h
|
||||
|
@ -201,6 +206,8 @@ SET(FemGui_SRCS_ViewProvider
|
|||
ViewProviderFemConstraintFixed.h
|
||||
ViewProviderFemConstraintForce.cpp
|
||||
ViewProviderFemConstraintForce.h
|
||||
ViewProviderFemConstraintFluidBoundary.cpp
|
||||
ViewProviderFemConstraintFluidBoundary.h
|
||||
ViewProviderFemConstraintPressure.cpp
|
||||
ViewProviderFemConstraintPressure.h
|
||||
ViewProviderFemConstraintGear.cpp
|
||||
|
|
729
src/Mod/Fem/Gui/TaskFemConstraintFluidBoundary.cpp
Normal file
729
src/Mod/Fem/Gui/TaskFemConstraintFluidBoundary.cpp
Normal file
|
@ -0,0 +1,729 @@
|
|||
/***************************************************************************
|
||||
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
|
||||
* Copyright (c) 2016 Qingfeng Xia <qingfeng.xia iesensor.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <sstream>
|
||||
# include <QRegExp>
|
||||
# include <QTextStream>
|
||||
# include <QMessageBox>
|
||||
# include <Precision.hxx>
|
||||
# include <TopoDS.hxx>
|
||||
# include <BRepAdaptor_Surface.hxx>
|
||||
# include <Geom_Plane.hxx>
|
||||
# include <gp_Pln.hxx>
|
||||
# include <gp_Ax1.hxx>
|
||||
# include <BRepAdaptor_Curve.hxx>
|
||||
# include <Geom_Line.hxx>
|
||||
# include <gp_Lin.hxx>
|
||||
#endif
|
||||
|
||||
#include "ui_TaskFemConstraintFluidBoundary.h"
|
||||
#include "TaskFemConstraintFluidBoundary.h"
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/PropertyGeo.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/Document.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Gui/ViewProvider.h>
|
||||
#include <Gui/WaitCursor.h>
|
||||
#include <Gui/Selection.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <Mod/Fem/App/FemConstraintFluidBoundary.h>
|
||||
#include <Mod/Fem/App/FemTools.h>
|
||||
#include <Mod/Part/App/PartFeature.h>
|
||||
|
||||
#include <Mod/Fem/App/FemAnalysis.h>
|
||||
#include <Mod/Fem/App/FemSolverObject.h>
|
||||
#include "ActiveAnalysisObserver.h"
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Tools.h>
|
||||
|
||||
using namespace FemGui;
|
||||
using namespace Gui;
|
||||
using namespace Fem;
|
||||
|
||||
//also defined in FemConstrainFluidBoundary and foamcasebuilder/basicbuilder.py, please update simultaneously
|
||||
//the second (index 1) is the default enum, as index 0 causes compiling error
|
||||
//static const char* BoundaryTypes[] = {"inlet","wall","outlet","interface","freestream", NULL};
|
||||
static const char* WallSubtypes[] = {"unspecific", "fixed", "slip", "moving", NULL};
|
||||
static const char* InletSubtypes[] = {"unspecific","totalPressure","uniformVelocity","volumetricFlowRate","massFlowRate",NULL};
|
||||
static const char* OutletSubtypes[] = {"unspecific","totalPressure","staticPressure","uniformVelocity", "outFlow", NULL};
|
||||
static const char* InterfaceSubtypes[] = {"unspecific","symmetry","wedge","cyclic","empty", NULL};
|
||||
static const char* FreestreamSubtypes[] = {"unspecific", "freestream",NULL};
|
||||
|
||||
// see Ansys fluet manual: Turbulence Specification method
|
||||
//static const char* TurbulenceSpecifications[] = {"Intensity&LengthScale","Intensity&HydraulicDiameter",NULL};
|
||||
//activate the heat transfer and radiation model in Solver object explorer
|
||||
static const char* TurbulenceSpecificationHelpTexts[] = {"see Ansys fluet manual: Turbulence Specification method",
|
||||
"or fully devloped internal flow, Turbulence intensity (0-1.0) 0.05 typical", NULL};
|
||||
|
||||
//static const char* ThermalBoundaryTypes[] = {"fixedValue","zeroGradient", "fixedGradient", "mixed", "HTC","coupled", NULL};
|
||||
//const char* ThermalBoundaryTypes[] = {"fixedValue","zeroGradient", "fixedGradient", "mixed", "coupled",NULL};
|
||||
static const char* ThermalBoundaryHelpTexts[] = {"fixed Temperature [K]", "no heat transfer ()", "fixed value heat flux [W/m2]",
|
||||
"mixed fixedGradient and fixedValue", "Heat transfer coeff [W/(M2)/K]", "conjugate heat transfer with solid", NULL};
|
||||
|
||||
|
||||
// internal function not declared in header file
|
||||
void initComboBox(QComboBox* combo, const std::vector<std::string>& textItems, const char* sItem)
|
||||
{
|
||||
combo->blockSignals(true);
|
||||
|
||||
int iItem = 1; // the first one is "unspecific" (index 0)
|
||||
combo->clear();
|
||||
for (unsigned int it = 0; it < textItems.size(); it++)
|
||||
{
|
||||
combo->insertItem(it, Base::Tools::fromStdString(textItems[it]));
|
||||
if (sItem == textItems[it])
|
||||
{
|
||||
iItem = it;
|
||||
}
|
||||
}
|
||||
combo->blockSignals(false);
|
||||
combo->setCurrentIndex(iItem);
|
||||
}
|
||||
|
||||
/* TRANSLATOR FemGui::TaskFemConstraintFluidBoundary */
|
||||
TaskFemConstraintFluidBoundary::TaskFemConstraintFluidBoundary(ViewProviderFemConstraintFluidBoundary *ConstraintView,QWidget *parent)
|
||||
: TaskFemConstraint(ConstraintView, parent, "fem-constraint-fluid-boundary")
|
||||
{
|
||||
// we need a separate container widget to add all controls to
|
||||
proxy = new QWidget(this);
|
||||
ui = new Ui_TaskFemConstraintFluidBoundary();
|
||||
ui->setupUi(proxy);
|
||||
QMetaObject::connectSlotsByName(this);
|
||||
|
||||
// Create a context menu for the listview of the references
|
||||
QAction* action = new QAction(tr("Delete"), ui->listReferences);
|
||||
action->connect(action, SIGNAL(triggered()),
|
||||
this, SLOT(onReferenceDeleted()));
|
||||
ui->listReferences->addAction(action);
|
||||
ui->listReferences->setContextMenuPolicy(Qt::ActionsContextMenu);
|
||||
|
||||
connect(ui->comboBoundaryType, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(onBoundaryTypeChanged(void)));
|
||||
connect(ui->comboSubtype, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(onSubtypeChanged(void)));
|
||||
connect(ui->spinBoundaryValue, SIGNAL(valueChanged(double)),
|
||||
this, SLOT(onBoundaryValueChanged(double)));
|
||||
|
||||
connect(ui->comboTurbulenceSpecification, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(onTurbulenceSpecificationChanged(void)));
|
||||
connect(ui->comboThermalBoundaryType, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(onThermalBoundaryTypeChanged(void)));
|
||||
|
||||
connect(ui->buttonReference, SIGNAL(pressed()),
|
||||
this, SLOT(onButtonReference()));
|
||||
connect(ui->buttonDirection, SIGNAL(pressed()),
|
||||
this, SLOT(onButtonDirection()));
|
||||
connect(ui->checkReverse, SIGNAL(toggled(bool)),
|
||||
this, SLOT(onCheckReverse(bool)));
|
||||
|
||||
this->groupLayout()->addWidget(proxy);
|
||||
|
||||
// Temporarily prevent unnecessary feature recomputes
|
||||
ui->spinBoundaryValue->blockSignals(true);
|
||||
ui->listReferences->blockSignals(true);
|
||||
|
||||
ui->buttonReference->blockSignals(true);
|
||||
ui->buttonDirection->blockSignals(true);
|
||||
ui->checkReverse->blockSignals(true);
|
||||
|
||||
// Get the feature data
|
||||
Fem::ConstraintFluidBoundary* pcConstraint = static_cast<Fem::ConstraintFluidBoundary*>(ConstraintView->getObject());
|
||||
|
||||
Fem::FemSolverObject* pcSolver = NULL;
|
||||
if (FemGui::ActiveAnalysisObserver::instance()->hasActiveObject()) {
|
||||
Fem::FemAnalysis* pcAnalysis = FemGui::ActiveAnalysisObserver::instance()->getActiveObject();
|
||||
//Fem::FemSolverObject is derived from DocumentObject
|
||||
std::vector<App::DocumentObject*> fem = pcAnalysis->Member.getValues();
|
||||
for (std::vector<App::DocumentObject*>::iterator it = fem.begin(); it != fem.end(); ++it) {
|
||||
if ((*it)->getTypeId().isDerivedFrom(Fem::FemSolverObject::getClassTypeId()))
|
||||
pcSolver = static_cast<Fem::FemSolverObject*>(*it);
|
||||
}
|
||||
}
|
||||
pHeatTransfering = NULL;
|
||||
pTurbulenceModel = NULL;
|
||||
if(pcSolver != NULL){
|
||||
//if only it is CFD solver, otherwise exit by SIGSEGV error, detect getPropertyByName() != NULL
|
||||
if(pcSolver->getPropertyByName("HeatTransfering")){
|
||||
pHeatTransfering = static_cast<App::PropertyBool*>(pcSolver->getPropertyByName("HeatTransfering"));
|
||||
if (pHeatTransfering->getValue()){
|
||||
ui->tabThermalBoundary->setVisible(true);
|
||||
initComboBox(ui->comboThermalBoundaryType, pcConstraint->ThermalBoundaryType.getEnumVector(),
|
||||
pcConstraint->ThermalBoundaryType.getValueAsString());
|
||||
updateThermalBoundaryUI();
|
||||
}
|
||||
else{
|
||||
ui->tabThermalBoundary->setVisible(false);
|
||||
//Base::Console().Message("retrieve solver property HeatTransfering as false\n");
|
||||
}
|
||||
}
|
||||
else{
|
||||
ui->tabThermalBoundary->setVisible(false);
|
||||
}
|
||||
if (pcSolver->getPropertyByName("TurbulenceModel")){
|
||||
pTurbulenceModel = static_cast<App::PropertyEnumeration*>(pcSolver->getPropertyByName("TurbulenceModel"));
|
||||
if (pTurbulenceModel->getValueAsString() == std::string("laminar")){
|
||||
ui->tabTurbulenceBoundary->setVisible(false);
|
||||
}
|
||||
else{
|
||||
ui->tabTurbulenceBoundary->setVisible(true);
|
||||
ui->groupTurbulence->setTitle(Base::Tools::fromStdString(
|
||||
pTurbulenceModel->getValueAsString()));
|
||||
initComboBox(ui->comboTurbulenceSpecification, pcConstraint->TurbulenceSpecification.getEnumVector(),
|
||||
pcConstraint->TurbulenceSpecification.getValueAsString());
|
||||
updateTurbulenceUI();
|
||||
}
|
||||
}
|
||||
else{
|
||||
ui->tabTurbulenceBoundary->setVisible(false);
|
||||
}
|
||||
}
|
||||
else{
|
||||
Base::Console().Message("Warning: No solver object inside FemAnalysis object\n");
|
||||
}
|
||||
ui->tabWidget->setTabText(0, tr("Basic"));
|
||||
ui->tabWidget->setTabText(1, tr("Turbulence"));
|
||||
ui->tabWidget->setTabText(2, tr("Thermal"));
|
||||
ui->labelHelpText->setText(tr("select boundary type, faces and set value"));
|
||||
|
||||
initComboBox(ui->comboBoundaryType, pcConstraint->BoundaryType.getEnumVector(),
|
||||
pcConstraint->BoundaryType.getValueAsString());
|
||||
updateBoundaryTypeUI();
|
||||
updateSubtypeUI();
|
||||
|
||||
std::vector<App::DocumentObject*> Objects = pcConstraint->References.getValues();
|
||||
std::vector<std::string> SubElements = pcConstraint->References.getSubValues();
|
||||
std::vector<std::string> dirStrings = pcConstraint->Direction.getSubValues();
|
||||
QString dir;
|
||||
if (!dirStrings.empty())
|
||||
dir = makeRefText(pcConstraint->Direction.getValue(), dirStrings.front());
|
||||
//bool reversed = pcConstraint->Reversed.getValue();
|
||||
|
||||
// Fill data into dialog elements
|
||||
double f = pcConstraint->BoundaryValue.getValue();
|
||||
ui->spinBoundaryValue->setMinimum(0);
|
||||
ui->spinBoundaryValue->setMaximum(FLOAT_MAX);
|
||||
ui->spinBoundaryValue->setValue(f);
|
||||
ui->listReferences->clear();
|
||||
for (std::size_t i = 0; i < Objects.size(); i++)
|
||||
ui->listReferences->addItem(makeRefText(Objects[i], SubElements[i]));
|
||||
if (Objects.size() > 0)
|
||||
ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect);
|
||||
ui->lineDirection->setText(dir.isEmpty() ? tr("") : dir);
|
||||
//ui->checkReverse->setChecked(reversed);
|
||||
ui->checkReverse->setVisible(false); // no need such UI for fluid boundary
|
||||
|
||||
ui->listReferences->blockSignals(false);
|
||||
ui->buttonReference->blockSignals(false);
|
||||
|
||||
ui->spinBoundaryValue->blockSignals(false);
|
||||
ui->buttonDirection->blockSignals(false);
|
||||
ui->checkReverse->blockSignals(false);
|
||||
updateSelectionUI();
|
||||
}
|
||||
|
||||
void TaskFemConstraintFluidBoundary::updateBoundaryTypeUI()
|
||||
{
|
||||
Fem::ConstraintFluidBoundary* pcConstraint = static_cast<Fem::ConstraintFluidBoundary*>(ConstraintView->getObject());
|
||||
std::string boundaryType = pcConstraint->BoundaryType.getValueAsString();
|
||||
|
||||
// Update subtypes, any change here should be written back to FemConstraintFluidBoundary.cpp
|
||||
if (boundaryType == "wall")
|
||||
{
|
||||
ui->tabBasicBoundary->setVisible(false);
|
||||
//todo: hidden only for fixed wall
|
||||
pcConstraint->Subtype.setEnums(WallSubtypes);
|
||||
}
|
||||
else if (boundaryType == "interface")
|
||||
{
|
||||
ui->tabBasicBoundary->setVisible(false);
|
||||
pcConstraint->Subtype.setEnums(InterfaceSubtypes);
|
||||
}
|
||||
else if (boundaryType == "freestream")
|
||||
{
|
||||
ui->tabBasicBoundary->setVisible(false);
|
||||
pcConstraint->Subtype.setEnums(FreestreamSubtypes);
|
||||
}
|
||||
else if(boundaryType == "inlet")
|
||||
{
|
||||
ui->tabBasicBoundary->setVisible(true);
|
||||
ui->labelSubtype->setText(QString::fromUtf8("valueType"));
|
||||
pcConstraint->Subtype.setEnums(InletSubtypes);
|
||||
pcConstraint->Reversed.setValue(true); // inlet must point into volume
|
||||
}
|
||||
else if(boundaryType == "outlet")
|
||||
{
|
||||
ui->tabBasicBoundary->setVisible(true);
|
||||
ui->labelSubtype->setText(QString::fromUtf8("valueType"));
|
||||
pcConstraint->Subtype.setEnums(OutletSubtypes);
|
||||
pcConstraint->Reversed.setValue(false); // inlet must point outside
|
||||
}
|
||||
else
|
||||
{
|
||||
Base::Console().Message(boundaryType.c_str());
|
||||
Base::Console().Message("Error boundaryType is not defined\n");
|
||||
}
|
||||
|
||||
std::vector<std::string> subtypes = pcConstraint->Subtype.getEnumVector();
|
||||
initComboBox(ui->comboSubtype, subtypes, pcConstraint->Subtype.getValueAsString());
|
||||
}
|
||||
|
||||
|
||||
void TaskFemConstraintFluidBoundary::updateSubtypeUI()
|
||||
{
|
||||
|
||||
Fem::ConstraintFluidBoundary* pcConstraint = static_cast<Fem::ConstraintFluidBoundary*>(ConstraintView->getObject());
|
||||
//* Subtype PropertyEnumeration is updated if BoundaryType is changed
|
||||
std::string boundaryType = pcConstraint->BoundaryType.getValueAsString();
|
||||
|
||||
if(boundaryType == "inlet" || boundaryType == "outlet")
|
||||
{
|
||||
std::string subtype = Base::Tools::toStdString(ui->comboSubtype->currentText());
|
||||
|
||||
if (subtype == "totalPressure" || subtype == "staticPressure")
|
||||
{
|
||||
ui->labelBoundaryValue->setText(QString::fromUtf8("pressure [Pa]")); //* tr()
|
||||
}
|
||||
else if (subtype == "uniformVelocity")
|
||||
{
|
||||
ui->labelBoundaryValue->setText(QString::fromUtf8("velocity [m/s]"));
|
||||
}
|
||||
else if (subtype == "flowrate")
|
||||
{
|
||||
ui->labelBoundaryValue->setText(QString::fromUtf8("flowrate [kg/s]"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->labelBoundaryValue->setText(QString::fromUtf8("unspecific"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// hide/disable UI only happend in constructor, update helptext and valuetext here
|
||||
void TaskFemConstraintFluidBoundary::updateTurbulenceUI()
|
||||
{
|
||||
ui->labelHelpText->setText(tr(TurbulenceSpecificationHelpTexts[ui->comboTurbulenceSpecification->currentIndex()]));
|
||||
}
|
||||
|
||||
void TaskFemConstraintFluidBoundary::updateThermalBoundaryUI()
|
||||
{
|
||||
Fem::ConstraintFluidBoundary* pcConstraint = static_cast<Fem::ConstraintFluidBoundary*>(ConstraintView->getObject());
|
||||
std::string thermalBoundaryType = pcConstraint->ThermalBoundaryType.getValueAsString();
|
||||
//to hide/disable UI
|
||||
ui->labelHelpText->setText(tr(ThermalBoundaryHelpTexts[ui->comboThermalBoundaryType->currentIndex()]));
|
||||
}
|
||||
|
||||
|
||||
void TaskFemConstraintFluidBoundary::updateSelectionUI()
|
||||
{
|
||||
if (ui->listReferences->model()->rowCount() == 0) {
|
||||
// Go into reference selection mode if no reference has been selected yet
|
||||
onButtonReference(true);
|
||||
return;
|
||||
}
|
||||
|
||||
/** not needed for fluid boundary, as it must be Face
|
||||
std::string ref = ui->listReferences->item(0)->text().toStdString();
|
||||
int pos = ref.find_last_of(":");
|
||||
if (ref.substr(pos+1, 6) == "Vertex")
|
||||
ui->labelForce->setText(tr("Point load"));
|
||||
else if (ref.substr(pos+1, 4) == "Edge")
|
||||
ui->labelForce->setText(tr("Line load"));
|
||||
else if (ref.substr(pos+1, 4) == "Face")
|
||||
ui->labelForce->setText(tr("Area load"));
|
||||
*/
|
||||
}
|
||||
|
||||
void TaskFemConstraintFluidBoundary::onSelectionChanged(const Gui::SelectionChanges& msg)
|
||||
{
|
||||
if (msg.Type == Gui::SelectionChanges::AddSelection) {
|
||||
// Don't allow selection in other document
|
||||
if (strcmp(msg.pDocName, ConstraintView->getObject()->getDocument()->getName()) != 0)
|
||||
return;
|
||||
|
||||
if (!msg.pSubName || msg.pSubName[0] == '\0')
|
||||
return;
|
||||
std::string subName(msg.pSubName);
|
||||
|
||||
if (selectionMode == selnone)
|
||||
return;
|
||||
|
||||
std::vector<std::string> references(1,subName);
|
||||
Fem::ConstraintFluidBoundary* pcConstraint = static_cast<Fem::ConstraintFluidBoundary*>(ConstraintView->getObject());
|
||||
App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(msg.pObjectName);
|
||||
Part::Feature* feat = static_cast<Part::Feature*>(obj);
|
||||
TopoDS_Shape ref = feat->Shape.getShape().getSubShape(subName.c_str());
|
||||
//* string conversion: <Base/Tools.h> toStdString()/fromStdString()
|
||||
if (selectionMode == selref) {
|
||||
std::vector<App::DocumentObject*> Objects = pcConstraint->References.getValues();
|
||||
std::vector<std::string> SubElements = pcConstraint->References.getSubValues();
|
||||
|
||||
// Ensure we don't have mixed reference types
|
||||
if (SubElements.size() > 0) {
|
||||
if (subName.substr(0,4) != SubElements.front().substr(0,4)) {
|
||||
QMessageBox::warning(this, tr("Selection error"), tr("Mixed shape types are not possible. Use a second constraint instead"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((subName.substr(0,4) != "Face")) {
|
||||
QMessageBox::warning(this, tr("Selection error"), tr("Only faces can be picked for fluid boundary"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Avoid duplicates
|
||||
std::size_t pos = 0;
|
||||
for (; pos < Objects.size(); pos++) {
|
||||
if (obj == Objects[pos]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pos != Objects.size()) {
|
||||
if (subName == SubElements[pos]) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// add the new reference
|
||||
Objects.push_back(obj);
|
||||
SubElements.push_back(subName);
|
||||
pcConstraint->References.setValues(Objects,SubElements);
|
||||
ui->listReferences->addItem(makeRefText(obj, subName));
|
||||
|
||||
// Turn off reference selection mode
|
||||
onButtonReference(false);
|
||||
}
|
||||
else if (selectionMode == seldir) {
|
||||
if (subName.substr(0,4) == "Face") {
|
||||
if (!Fem::Tools::isPlanar(TopoDS::Face(ref))) {
|
||||
QMessageBox::warning(this, tr("Selection error"), tr("Only planar faces can be picked"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
QMessageBox::warning(this, tr("Selection error"), tr("Only faces and edges can be picked"));
|
||||
return;
|
||||
}
|
||||
pcConstraint->Direction.setValue(obj, references);
|
||||
ui->lineDirection->setText(makeRefText(obj, subName));
|
||||
// Turn off direction selection mode
|
||||
onButtonDirection(false);
|
||||
}
|
||||
|
||||
Gui::Selection().clearSelection();
|
||||
updateSelectionUI();
|
||||
}
|
||||
}
|
||||
|
||||
void TaskFemConstraintFluidBoundary::onBoundaryTypeChanged(void)
|
||||
{
|
||||
Fem::ConstraintFluidBoundary* pcConstraint = static_cast<Fem::ConstraintFluidBoundary*>(ConstraintView->getObject());
|
||||
pcConstraint->BoundaryType.setValue(ui->comboBoundaryType->currentIndex());
|
||||
updateBoundaryTypeUI();
|
||||
//ConstraintView->updateData(&pcConstraint->BoundaryType); //force a 3D redraw
|
||||
//however, there is a bug of cube normal is not correct in redraw, close task panel , redraw is correct
|
||||
}
|
||||
|
||||
void TaskFemConstraintFluidBoundary::onSubtypeChanged(void)
|
||||
{
|
||||
Fem::ConstraintFluidBoundary* pcConstraint = static_cast<Fem::ConstraintFluidBoundary*>(ConstraintView->getObject());
|
||||
pcConstraint->Subtype.setValue(ui->comboSubtype->currentIndex());
|
||||
updateSubtypeUI();
|
||||
}
|
||||
|
||||
|
||||
void TaskFemConstraintFluidBoundary::onTurbulenceSpecificationChanged(void)
|
||||
{
|
||||
Fem::ConstraintFluidBoundary* pcConstraint = static_cast<Fem::ConstraintFluidBoundary*>(ConstraintView->getObject());
|
||||
pcConstraint->TurbulenceSpecification.setValue(ui->comboTurbulenceSpecification->currentIndex());
|
||||
updateTurbulenceUI();
|
||||
}
|
||||
|
||||
void TaskFemConstraintFluidBoundary::onThermalBoundaryTypeChanged(void)
|
||||
{
|
||||
Fem::ConstraintFluidBoundary* pcConstraint = static_cast<Fem::ConstraintFluidBoundary*>(ConstraintView->getObject());
|
||||
pcConstraint->ThermalBoundaryType.setValue(ui->comboThermalBoundaryType->currentIndex());
|
||||
updateThermalBoundaryUI();
|
||||
}
|
||||
|
||||
void TaskFemConstraintFluidBoundary::onReferenceDeleted() {
|
||||
int row = ui->listReferences->currentIndex().row();
|
||||
TaskFemConstraint::onReferenceDeleted(row);
|
||||
ui->listReferences->model()->removeRow(row);
|
||||
ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect);
|
||||
}
|
||||
|
||||
void TaskFemConstraintFluidBoundary::onButtonDirection(const bool pressed) {
|
||||
if (pressed) {
|
||||
selectionMode = seldir;
|
||||
} else {
|
||||
selectionMode = selnone;
|
||||
}
|
||||
ui->buttonDirection->setChecked(pressed);
|
||||
Gui::Selection().clearSelection();
|
||||
}
|
||||
|
||||
void TaskFemConstraintFluidBoundary::onCheckReverse(const bool pressed)
|
||||
{
|
||||
Fem::ConstraintFluidBoundary* pcConstraint = static_cast<Fem::ConstraintFluidBoundary*>(ConstraintView->getObject());
|
||||
pcConstraint->Reversed.setValue(pressed);
|
||||
}
|
||||
|
||||
std::string TaskFemConstraintFluidBoundary::getBoundaryType(void) const
|
||||
{
|
||||
return Base::Tools::toStdString(ui->comboBoundaryType->currentText());
|
||||
}
|
||||
|
||||
std::string TaskFemConstraintFluidBoundary::getSubtype(void) const
|
||||
{
|
||||
return Base::Tools::toStdString(ui->comboSubtype->currentText());
|
||||
}
|
||||
|
||||
double TaskFemConstraintFluidBoundary::getBoundaryValue(void) const
|
||||
{
|
||||
return ui->spinBoundaryValue->value();
|
||||
}
|
||||
|
||||
|
||||
std::string TaskFemConstraintFluidBoundary::getTurbulenceModel(void) const
|
||||
{
|
||||
if(pTurbulenceModel){
|
||||
return pTurbulenceModel->getValueAsString();
|
||||
}
|
||||
else{
|
||||
return "wall";
|
||||
}
|
||||
}
|
||||
std::string TaskFemConstraintFluidBoundary::getTurbulenceSpecification(void) const
|
||||
{
|
||||
return Base::Tools::toStdString(ui->comboTurbulenceSpecification->currentText());
|
||||
}
|
||||
double TaskFemConstraintFluidBoundary::getTurbulentIntensityValue(void) const
|
||||
{
|
||||
return ui->spinTurbulentIntensityValue->value();
|
||||
}
|
||||
double TaskFemConstraintFluidBoundary::getTurbulentLengthValue(void) const
|
||||
{
|
||||
return ui->spinTurbulentLengthValue->value();
|
||||
}
|
||||
|
||||
|
||||
bool TaskFemConstraintFluidBoundary::getHeatTransfering(void) const
|
||||
{
|
||||
if(pHeatTransfering){
|
||||
return pHeatTransfering->getValue();
|
||||
}
|
||||
else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
std::string TaskFemConstraintFluidBoundary::getThermalBoundaryType(void) const
|
||||
{
|
||||
return Base::Tools::toStdString(ui->comboThermalBoundaryType->currentText());
|
||||
}
|
||||
|
||||
double TaskFemConstraintFluidBoundary::getTemperatureValue(void) const
|
||||
{
|
||||
return ui->spinTemperatureValue->value();
|
||||
}
|
||||
|
||||
double TaskFemConstraintFluidBoundary::getHeatFluxValue(void) const
|
||||
{
|
||||
return ui->spinHeatFluxValue->value();
|
||||
}
|
||||
double TaskFemConstraintFluidBoundary::getHTCoeffValue(void) const
|
||||
{
|
||||
return ui->spinHTCoeffValue->value();
|
||||
}
|
||||
|
||||
|
||||
const std::string TaskFemConstraintFluidBoundary::getReferences() const
|
||||
{
|
||||
int rows = ui->listReferences->model()->rowCount();
|
||||
|
||||
std::vector<std::string> items;
|
||||
for (int r = 0; r < rows; r++)
|
||||
items.push_back(ui->listReferences->item(r)->text().toStdString());
|
||||
return TaskFemConstraint::getReferences(items);
|
||||
}
|
||||
|
||||
const std::string TaskFemConstraintFluidBoundary::getDirectionName(void) const
|
||||
{
|
||||
std::string dir = ui->lineDirection->text().toStdString();
|
||||
if (dir.empty())
|
||||
return "";
|
||||
|
||||
int pos = dir.find_last_of(":");
|
||||
return dir.substr(0, pos).c_str();
|
||||
}
|
||||
|
||||
const std::string TaskFemConstraintFluidBoundary::getDirectionObject(void) const
|
||||
{
|
||||
std::string dir = ui->lineDirection->text().toStdString();
|
||||
if (dir.empty())
|
||||
return "";
|
||||
|
||||
int pos = dir.find_last_of(":");
|
||||
return dir.substr(pos+1).c_str();
|
||||
}
|
||||
|
||||
bool TaskFemConstraintFluidBoundary::getReverse() const
|
||||
{
|
||||
return ui->checkReverse->isChecked();
|
||||
}
|
||||
|
||||
TaskFemConstraintFluidBoundary::~TaskFemConstraintFluidBoundary()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void TaskFemConstraintFluidBoundary::changeEvent(QEvent *e)
|
||||
{
|
||||
TaskBox::changeEvent(e);
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
ui->spinBoundaryValue->blockSignals(true);
|
||||
//more ui widget? those UI are does not support tr yet!
|
||||
ui->retranslateUi(proxy);
|
||||
|
||||
ui->spinBoundaryValue->blockSignals(false);
|
||||
}
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
//**************************************************************************
|
||||
// TaskDialog
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
TaskDlgFemConstraintFluidBoundary::TaskDlgFemConstraintFluidBoundary(ViewProviderFemConstraintFluidBoundary *ConstraintView)
|
||||
{
|
||||
this->ConstraintView = ConstraintView;
|
||||
assert(ConstraintView);
|
||||
this->parameter = new TaskFemConstraintFluidBoundary(ConstraintView);;
|
||||
|
||||
Content.push_back(parameter);
|
||||
}
|
||||
|
||||
//==== calls from the TaskView ===============================================================
|
||||
|
||||
void TaskDlgFemConstraintFluidBoundary::open()
|
||||
{
|
||||
// a transaction is already open at creation time of the panel
|
||||
if (!Gui::Command::hasPendingCommand()) {
|
||||
QString msg = QObject::tr("Constraint fluid boundary");
|
||||
Gui::Command::openCommand((const char*)msg.toUtf8());
|
||||
}
|
||||
}
|
||||
|
||||
bool TaskDlgFemConstraintFluidBoundary::accept()
|
||||
{
|
||||
std::string name = ConstraintView->getObject()->getNameInDocument();
|
||||
const TaskFemConstraintFluidBoundary* boundary = static_cast<const TaskFemConstraintFluidBoundary*>(parameter);
|
||||
|
||||
try {
|
||||
//Gui::Command::openCommand("Fluid boundary condition changed");
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.BoundaryType = '%s'",
|
||||
name.c_str(), boundary->getBoundaryType().c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Subtype = '%s'",
|
||||
name.c_str(), boundary->getSubtype().c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.BoundaryValue = %f",
|
||||
name.c_str(), boundary->getBoundaryValue());
|
||||
|
||||
std::string dirname = boundary->getDirectionName().data();
|
||||
std::string dirobj = boundary->getDirectionObject().data();
|
||||
|
||||
if (!dirname.empty()) {
|
||||
QString buf = QString::fromUtf8("(App.ActiveDocument.%1,[\"%2\"])");
|
||||
buf = buf.arg(QString::fromStdString(dirname));
|
||||
buf = buf.arg(QString::fromStdString(dirobj));
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = %s", name.c_str(), buf.toStdString().c_str());
|
||||
} else {
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = None", name.c_str());
|
||||
}
|
||||
//Reverse control is done at BoundaryType selection, this UI is hiden from user
|
||||
//Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %s", name.c_str(), boundary->getReverse() ? "True" : "False");
|
||||
|
||||
std::string scale = "1";
|
||||
scale = boundary->getScale(); //OvG: determine modified scale
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Scale = %s", name.c_str(), scale.c_str()); //OvG: implement modified scale
|
||||
|
||||
//solver specific setting
|
||||
Fem::FemSolverObject* pcSolver = NULL;
|
||||
if (FemGui::ActiveAnalysisObserver::instance()->hasActiveObject()) {
|
||||
Fem::FemAnalysis* pcAnalysis = FemGui::ActiveAnalysisObserver::instance()->getActiveObject();
|
||||
//Fem::FemSolverObject is derived from DocumentObject
|
||||
std::vector<App::DocumentObject*> fem = pcAnalysis->Member.getValues();
|
||||
for (std::vector<App::DocumentObject*>::iterator it = fem.begin(); it != fem.end(); ++it) {
|
||||
if ((*it)->getTypeId().isDerivedFrom(Fem::FemSolverObject::getClassTypeId()))
|
||||
pcSolver = static_cast<Fem::FemSolverObject*>(*it);
|
||||
}
|
||||
}
|
||||
if(pcSolver){
|
||||
App::PropertyBool* pHeatTransfering = NULL;
|
||||
App::PropertyEnumeration* pTurbulenceModel = NULL;
|
||||
pHeatTransfering = static_cast<App::PropertyBool*>(pcSolver->getPropertyByName("HeatTransfering"));
|
||||
pTurbulenceModel = static_cast<App::PropertyEnumeration*>(pcSolver->getPropertyByName("TurbulenceModel"));
|
||||
|
||||
if(pHeatTransfering && pHeatTransfering->getValue()){
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.ThermalBoundaryType = '%s'",name.c_str(), boundary->getThermalBoundaryType().c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.TemperatureValue = %f",name.c_str(), boundary->getTemperatureValue());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.HeatFluxValue = %f",name.c_str(), boundary->getHeatFluxValue());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.HTCoeffValue = %f",name.c_str(), boundary->getHTCoeffValue());
|
||||
}
|
||||
if(pTurbulenceModel && std::string(pTurbulenceModel->getValueAsString()) != "laminar"){
|
||||
//update turbulence and thermal boundary settings, only if those models are activated
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.TurbulenceSpecification = '%s'",name.c_str(), boundary->getTurbulenceSpecification().c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.TurbulentIntensityValue = %f",name.c_str(), boundary->getTurbulentIntensityValue());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.TurbulentLengthValue = %f",name.c_str(), boundary->getTurbulentLengthValue());
|
||||
}
|
||||
}
|
||||
//rename document obj according to boundaryType:
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what()));
|
||||
return false;
|
||||
}
|
||||
|
||||
return TaskDlgFemConstraint::accept();
|
||||
}
|
||||
|
||||
bool TaskDlgFemConstraintFluidBoundary::reject()
|
||||
{
|
||||
// roll back the changes
|
||||
Gui::Command::abortCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
|
||||
Gui::Command::updateActive();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#include "moc_TaskFemConstraintFluidBoundary.cpp"
|
118
src/Mod/Fem/Gui/TaskFemConstraintFluidBoundary.h
Normal file
118
src/Mod/Fem/Gui/TaskFemConstraintFluidBoundary.h
Normal file
|
@ -0,0 +1,118 @@
|
|||
/***************************************************************************
|
||||
* Copyright (c) 2016 Qingfeng Xia <qingfeng.xia iesensor.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef GUI_TASKVIEW_TaskFemConstraintFluidBoundary_H
|
||||
#define GUI_TASKVIEW_TaskFemConstraintFluidBoundary_H
|
||||
|
||||
#include <App/PropertyStandard.h>
|
||||
#include <Gui/TaskView/TaskView.h>
|
||||
#include <Gui/Selection.h>
|
||||
#include <Gui/TaskView/TaskDialog.h>
|
||||
|
||||
#include "TaskFemConstraint.h"
|
||||
#include "ViewProviderFemConstraintFluidBoundary.h"
|
||||
|
||||
class Ui_TaskFemConstraintFluidBoundary;
|
||||
|
||||
namespace App {
|
||||
class Property;
|
||||
}
|
||||
|
||||
namespace Gui {
|
||||
class ViewProvider;
|
||||
}
|
||||
|
||||
namespace FemGui {
|
||||
|
||||
class TaskFemConstraintFluidBoundary : public TaskFemConstraint
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TaskFemConstraintFluidBoundary(ViewProviderFemConstraintFluidBoundary *ConstraintView,QWidget *parent = 0);
|
||||
virtual ~TaskFemConstraintFluidBoundary();
|
||||
|
||||
std::string getBoundaryType(void) const;
|
||||
std::string getSubtype(void) const;
|
||||
double getBoundaryValue(void) const;
|
||||
|
||||
std::string getTurbulenceModel(void) const;
|
||||
std::string getTurbulenceSpecification(void) const;
|
||||
double getTurbulentIntensityValue(void) const;
|
||||
double getTurbulentLengthValue(void) const;
|
||||
|
||||
bool getHeatTransfering(void) const;
|
||||
std::string getThermalBoundaryType(void) const;
|
||||
double getTemperatureValue(void) const;
|
||||
double getHeatFluxValue(void) const;
|
||||
double getHTCoeffValue(void) const;
|
||||
|
||||
virtual const std::string getReferences() const;
|
||||
const std::string getDirectionName(void) const;
|
||||
const std::string getDirectionObject(void) const;
|
||||
bool getReverse(void) const;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onBoundaryTypeChanged(void);
|
||||
void onSubtypeChanged(void);
|
||||
void onTurbulenceSpecificationChanged(void);
|
||||
void onThermalBoundaryTypeChanged(void);
|
||||
void onReferenceDeleted(void);
|
||||
void onButtonDirection(const bool pressed = true);
|
||||
void onCheckReverse(bool);
|
||||
|
||||
protected:
|
||||
virtual void changeEvent(QEvent *e);
|
||||
|
||||
private:
|
||||
virtual void onSelectionChanged(const Gui::SelectionChanges& msg);
|
||||
void updateSelectionUI();
|
||||
void updateBoundaryTypeUI();
|
||||
void updateSubtypeUI();
|
||||
void updateThermalBoundaryUI();
|
||||
void updateTurbulenceUI();
|
||||
|
||||
private:
|
||||
Ui_TaskFemConstraintFluidBoundary* ui;
|
||||
App::PropertyBool* pHeatTransfering;
|
||||
App::PropertyEnumeration* pTurbulenceModel;
|
||||
};
|
||||
|
||||
/// simulation dialog for the TaskView
|
||||
class TaskDlgFemConstraintFluidBoundary : public TaskDlgFemConstraint
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TaskDlgFemConstraintFluidBoundary(ViewProviderFemConstraintFluidBoundary *ConstraintView);
|
||||
|
||||
/// is called by the framework if the dialog is accepted (Ok)
|
||||
virtual void open();
|
||||
virtual bool accept();
|
||||
virtual bool reject();
|
||||
|
||||
};
|
||||
|
||||
} //namespace FemGui
|
||||
|
||||
#endif // GUI_TASKVIEW_TaskFemConstraintFluidBoundary_H
|
376
src/Mod/Fem/Gui/TaskFemConstraintFluidBoundary.ui
Normal file
376
src/Mod/Fem/Gui/TaskFemConstraintFluidBoundary.ui
Normal file
|
@ -0,0 +1,376 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TaskFemConstraintFluidBoundary</class>
|
||||
<widget class="QWidget" name="TaskFemConstraintFluidBoundary">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>280</width>
|
||||
<height>475</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelBoundaryType">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Boundary </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="comboBoundaryType">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelSubtype">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Subtype</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="comboSubtype">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonReference">
|
||||
<property name="text">
|
||||
<string>Add geometry reference</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="listReferences">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="baseSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelHelpText">
|
||||
<property name="text">
|
||||
<string>HelpText</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tabBasicBoundary">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="title">
|
||||
<string>Tab 1</string>
|
||||
</attribute>
|
||||
<widget class="QCheckBox" name="checkReverse">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>90</y>
|
||||
<width>148</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reverse direction</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>241</width>
|
||||
<height>71</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelBoundaryValue">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Value [Unit]</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QDoubleSpinBox" name="spinBoundaryValue">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>-99999.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>99999.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="buttonDirection">
|
||||
<property name="text">
|
||||
<string>Direction </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="lineDirection">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>75</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="baseSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabTurbulenceBoundary">
|
||||
<attribute name="title">
|
||||
<string>Page</string>
|
||||
</attribute>
|
||||
<widget class="QGroupBox" name="groupTurbulence">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>261</width>
|
||||
<height>151</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Turbulence specification</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboTurbulenceSpecification">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="layoutTurbulenceValue">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelTurbulentIntensityValue">
|
||||
<property name="text">
|
||||
<string>Intensity </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="spinTurbulentIntensityValue"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelTurbulentLengthValue">
|
||||
<property name="text">
|
||||
<string>Length [m]</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="spinTurbulentLengthValue"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
<zorder>comboTurbulenceSpecification</zorder>
|
||||
<zorder></zorder>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabThermalBoundary">
|
||||
<attribute name="title">
|
||||
<string>Tab 2</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelThermalBoundaryType">
|
||||
<property name="text">
|
||||
<string> Type </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="comboThermalBoundaryType"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelTemperature">
|
||||
<property name="text">
|
||||
<string>Temp[K]</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="spinTemperatureValue">
|
||||
<property name="minimum">
|
||||
<double>-273.149999999999977</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>9999.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelHeatFlux">
|
||||
<property name="text">
|
||||
<string>Heat flux</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDoubleSpinBox" name="spinHeatFluxValue">
|
||||
<property name="minimum">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>99999.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelHTCeoff">
|
||||
<property name="text">
|
||||
<string>HT coeff</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QDoubleSpinBox" name="spinHTCoeffValue">
|
||||
<property name="minimum">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>99999.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
297
src/Mod/Fem/Gui/ViewProviderFemConstraintFluidBoundary.cpp
Normal file
297
src/Mod/Fem/Gui/ViewProviderFemConstraintFluidBoundary.cpp
Normal file
|
@ -0,0 +1,297 @@
|
|||
/***************************************************************************
|
||||
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <Standard_math.hxx>
|
||||
# include <Inventor/nodes/SoSeparator.h>
|
||||
# include <Inventor/nodes/SoTranslation.h>
|
||||
# include <Inventor/nodes/SoRotation.h>
|
||||
# include <Inventor/nodes/SoMultipleCopy.h>
|
||||
# include <Precision.hxx>
|
||||
# include <QMessageBox>
|
||||
#endif
|
||||
|
||||
#include "ViewProviderFemConstraintFluidBoundary.h"
|
||||
#include <Mod/Fem/App/FemConstraintFluidBoundary.h>
|
||||
#include "TaskFemConstraintFluidBoundary.h"
|
||||
#include "Gui/Control.h"
|
||||
|
||||
#include <Base/Console.h>
|
||||
|
||||
using namespace FemGui;
|
||||
|
||||
PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintFluidBoundary, FemGui::ViewProviderFemConstraint)
|
||||
|
||||
|
||||
ViewProviderFemConstraintFluidBoundary::ViewProviderFemConstraintFluidBoundary()
|
||||
{
|
||||
sPixmap = "fem-constraint-fluid-boundary";
|
||||
}
|
||||
|
||||
ViewProviderFemConstraintFluidBoundary::~ViewProviderFemConstraintFluidBoundary()
|
||||
{
|
||||
}
|
||||
|
||||
bool ViewProviderFemConstraintFluidBoundary::setEdit(int ModNum)
|
||||
{
|
||||
if (ModNum == ViewProvider::Default ) {
|
||||
// When double-clicking on the item for this constraint,
|
||||
// object unsets and sets its edit mode without closing the task panel
|
||||
Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
|
||||
TaskDlgFemConstraintFluidBoundary *constrDlg = qobject_cast<TaskDlgFemConstraintFluidBoundary *>(dlg);
|
||||
if (constrDlg && constrDlg->getConstraintView() != this)
|
||||
constrDlg = 0; // another constraint left open its task panel
|
||||
if (dlg && !constrDlg) {
|
||||
// This case will occur in the ShaftWizard application
|
||||
checkForWizard();
|
||||
if ((wizardWidget == NULL) || (wizardSubLayout == NULL)) {
|
||||
// No shaft wizard is running
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText(QObject::tr("A dialog is already open in the task panel"));
|
||||
msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?"));
|
||||
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
msgBox.setDefaultButton(QMessageBox::Yes);
|
||||
int ret = msgBox.exec();
|
||||
if (ret == QMessageBox::Yes)
|
||||
Gui::Control().reject();
|
||||
else
|
||||
return false;
|
||||
} else if (constraintDialog != NULL) {
|
||||
// Another FemConstraint* dialog is already open inside the Shaft Wizard
|
||||
// Ignore the request to open another dialog
|
||||
return false;
|
||||
} else {
|
||||
constraintDialog = new TaskFemConstraintFluidBoundary(this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// clear the selection (convenience)
|
||||
Gui::Selection().clearSelection();
|
||||
|
||||
// start the edit dialog
|
||||
if (constrDlg)
|
||||
Gui::Control().showDialog(constrDlg);
|
||||
else
|
||||
Gui::Control().showDialog(new TaskDlgFemConstraintFluidBoundary(this));
|
||||
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return ViewProviderDocumentObject::setEdit(ModNum);
|
||||
}
|
||||
}
|
||||
|
||||
//Rendering: Combination of ConstraintFixed and ConstraintForce
|
||||
#define ARROWLENGTH (4)
|
||||
#define ARROWHEADRADIUS (ARROWLENGTH/3)
|
||||
#define WIDTH (2)
|
||||
#define HEIGHT (1)
|
||||
//#define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled display on initial drawing - so disable
|
||||
|
||||
void ViewProviderFemConstraintFluidBoundary::updateData(const App::Property* prop)
|
||||
{
|
||||
// Gets called whenever a property of the attached object changes
|
||||
Fem::ConstraintFluidBoundary* pcConstraint = static_cast<Fem::ConstraintFluidBoundary*>(this->getObject());
|
||||
float scaledwidth = WIDTH * pcConstraint->Scale.getValue(); //OvG: Calculate scaled values once only
|
||||
float scaledheight = HEIGHT * pcConstraint->Scale.getValue();
|
||||
|
||||
float scaledheadradius = ARROWHEADRADIUS * pcConstraint->Scale.getValue(); //OvG: Calculate scaled values once only
|
||||
float scaledlength = ARROWLENGTH * pcConstraint->Scale.getValue();
|
||||
|
||||
std::string boundaryType = pcConstraint->BoundaryType.getValueAsString();
|
||||
if (strcmp(prop->getName(),"BoundaryType") == 0)
|
||||
{
|
||||
if (boundaryType == "wall")
|
||||
{
|
||||
FaceColor.setValue(0.0,1.0,1.0);
|
||||
}
|
||||
else if (boundaryType == "interface")
|
||||
{
|
||||
FaceColor.setValue(0.0,1.0,0.0);
|
||||
}
|
||||
else if (boundaryType == "freestream")
|
||||
{
|
||||
FaceColor.setValue(1.0,1.0,0.0);
|
||||
}
|
||||
else if(boundaryType == "inlet")
|
||||
{
|
||||
FaceColor.setValue(1.0,0.0,0.0);
|
||||
}
|
||||
else //(boundaryType == "outlet")
|
||||
{
|
||||
FaceColor.setValue(0.0,0.0,1.0);
|
||||
}
|
||||
}
|
||||
|
||||
if (boundaryType == "inlet" || boundaryType == "outlet"){
|
||||
#ifdef USE_MULTIPLE_COPY
|
||||
//OvG: need access to cp for scaling
|
||||
SoMultipleCopy* cp = new SoMultipleCopy();
|
||||
if (pShapeSep->getNumChildren() == 0) {
|
||||
// Set up the nodes
|
||||
cp->matrix.setNum(0);
|
||||
cp->addChild((SoNode*)createArrow(scaledlength , scaledheadradius)); //OvG: Scaling
|
||||
pShapeSep->addChild(cp);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (strcmp(prop->getName(),"Points") == 0) {
|
||||
const std::vector<Base::Vector3d>& points = pcConstraint->Points.getValues();
|
||||
|
||||
#ifdef USE_MULTIPLE_COPY
|
||||
cp = static_cast<SoMultipleCopy*>(pShapeSep->getChild(0));
|
||||
cp->matrix.setNum(points.size());
|
||||
SbMatrix* matrices = cp->matrix.startEditing();
|
||||
int idx = 0;
|
||||
#else
|
||||
// Redraw all arrows
|
||||
pShapeSep->removeAllChildren();
|
||||
#endif
|
||||
// This should always point outside of the solid
|
||||
Base::Vector3d normal = pcConstraint->NormalDirection.getValue();
|
||||
|
||||
// Get default direction (on first call to method)
|
||||
Base::Vector3d forceDirection = pcConstraint->DirectionVector.getValue();
|
||||
if (forceDirection.Length() < Precision::Confusion())
|
||||
forceDirection = normal;
|
||||
|
||||
SbVec3f dir(forceDirection.x, forceDirection.y, forceDirection.z);
|
||||
SbRotation rot(SbVec3f(0,1,0), dir);
|
||||
|
||||
for (std::vector<Base::Vector3d>::const_iterator p = points.begin(); p != points.end(); p++) {
|
||||
SbVec3f base(p->x, p->y, p->z);
|
||||
if (forceDirection.GetAngle(normal) < M_PI_2) // Move arrow so it doesn't disappear inside the solid
|
||||
base = base + dir * scaledlength; //OvG: Scaling
|
||||
#ifdef USE_MULTIPLE_COPY
|
||||
SbMatrix m;
|
||||
m.setTransform(base, rot, SbVec3f(1,1,1));
|
||||
matrices[idx] = m;
|
||||
idx++;
|
||||
#else
|
||||
SoSeparator* sep = new SoSeparator();
|
||||
createPlacement(sep, base, rot);
|
||||
createArrow(sep, scaledlength, scaledheadradius); //OvG: Scaling
|
||||
pShapeSep->addChild(sep);
|
||||
#endif
|
||||
}
|
||||
#ifdef USE_MULTIPLE_COPY
|
||||
cp->matrix.finishEditing();
|
||||
#endif
|
||||
}
|
||||
else if (strcmp(prop->getName(),"DirectionVector") == 0) { // Note: "Reversed" also triggers "DirectionVector"
|
||||
// Re-orient all arrows
|
||||
Base::Vector3d normal = pcConstraint->NormalDirection.getValue();
|
||||
Base::Vector3d forceDirection = pcConstraint->DirectionVector.getValue();
|
||||
if (forceDirection.Length() < Precision::Confusion())
|
||||
forceDirection = normal;
|
||||
|
||||
SbVec3f dir(forceDirection.x, forceDirection.y, forceDirection.z);
|
||||
SbRotation rot(SbVec3f(0,1,0), dir);
|
||||
|
||||
const std::vector<Base::Vector3d>& points = pcConstraint->Points.getValues();
|
||||
|
||||
#ifdef USE_MULTIPLE_COPY
|
||||
SoMultipleCopy* cp = static_cast<SoMultipleCopy*>(pShapeSep->getChild(0));
|
||||
cp->matrix.setNum(points.size());
|
||||
SbMatrix* matrices = cp->matrix.startEditing();
|
||||
#endif
|
||||
int idx = 0;
|
||||
|
||||
for (std::vector<Base::Vector3d>::const_iterator p = points.begin(); p != points.end(); p++) {
|
||||
SbVec3f base(p->x, p->y, p->z);
|
||||
if (forceDirection.GetAngle(normal) < M_PI_2)
|
||||
base = base + dir * scaledlength; //OvG: Scaling
|
||||
#ifdef USE_MULTIPLE_COPY
|
||||
SbMatrix m;
|
||||
m.setTransform(base, rot, SbVec3f(1,1,1));
|
||||
matrices[idx] = m;
|
||||
#else
|
||||
SoSeparator* sep = static_cast<SoSeparator*>(pShapeSep->getChild(idx));
|
||||
updatePlacement(sep, 0, base, rot);
|
||||
updateArrow(sep, 2, scaledlength, scaledheadradius); //OvG: Scaling
|
||||
#endif
|
||||
idx++;
|
||||
}
|
||||
#ifdef USE_MULTIPLE_COPY
|
||||
cp->matrix.finishEditing();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else{// not inlet or outlet boundary type
|
||||
|
||||
#ifdef USE_MULTIPLE_COPY
|
||||
//OvG: always need access to cp for scaling
|
||||
SoMultipleCopy* cp = new SoMultipleCopy();
|
||||
if (pShapeSep->getNumChildren() == 0) {
|
||||
// Set up the nodes
|
||||
cp->matrix.setNum(0);
|
||||
cp->addChild((SoNode*)createFixed(scaledheight, scaledwidth)); //OvG: Scaling
|
||||
pShapeSep->addChild(cp);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (strcmp(prop->getName(),"Points") == 0) {
|
||||
const std::vector<Base::Vector3d>& points = pcConstraint->Points.getValues();
|
||||
const std::vector<Base::Vector3d>& normals = pcConstraint->Normals.getValues();
|
||||
if (points.size() != normals.size())
|
||||
return;
|
||||
std::vector<Base::Vector3d>::const_iterator n = normals.begin();
|
||||
|
||||
#ifdef USE_MULTIPLE_COPY
|
||||
cp = static_cast<SoMultipleCopy*>(pShapeSep->getChild(0));
|
||||
cp->matrix.setNum(points.size());
|
||||
SbMatrix* matrices = cp->matrix.startEditing();
|
||||
int idx = 0;
|
||||
#else
|
||||
// Note: Points and Normals are always updated together
|
||||
pShapeSep->removeAllChildren();
|
||||
#endif
|
||||
|
||||
for (std::vector<Base::Vector3d>::const_iterator p = points.begin(); p != points.end(); p++) {
|
||||
SbVec3f base(p->x, p->y, p->z);
|
||||
SbVec3f dir(n->x, n->y, n->z);
|
||||
SbRotation rot(SbVec3f(0,-1,0), dir);
|
||||
#ifdef USE_MULTIPLE_COPY
|
||||
SbMatrix m;
|
||||
m.setTransform(base, rot, SbVec3f(1,1,1));
|
||||
matrices[idx] = m;
|
||||
idx++;
|
||||
#else
|
||||
SoSeparator* sep = new SoSeparator();
|
||||
createPlacement(sep, base, rot);
|
||||
createFixed(sep, scaledheight, scaledwidth); //OvG: Scaling
|
||||
pShapeSep->addChild(sep);
|
||||
#endif
|
||||
n++;
|
||||
}
|
||||
#ifdef USE_MULTIPLE_COPY
|
||||
cp->matrix.finishEditing();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ViewProviderFemConstraint::updateData(prop);
|
||||
}
|
54
src/Mod/Fem/Gui/ViewProviderFemConstraintFluidBoundary.h
Normal file
54
src/Mod/Fem/Gui/ViewProviderFemConstraintFluidBoundary.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/***************************************************************************
|
||||
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef GUI_VIEWPROVIDERFEMFLUIDBOUNDARY_H
|
||||
#define GUI_VIEWPROVIDERFEMFLUIDBOUNDARY_H
|
||||
|
||||
#include "ViewProviderFemConstraint.h"
|
||||
|
||||
namespace FemGui
|
||||
{
|
||||
|
||||
class FemGuiExport ViewProviderFemConstraintFluidBoundary : public FemGui::ViewProviderFemConstraint
|
||||
{
|
||||
PROPERTY_HEADER(FemGui::ViewProviderFemConstraintFluidBoundary);
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
ViewProviderFemConstraintFluidBoundary();
|
||||
virtual ~ViewProviderFemConstraintFluidBoundary();
|
||||
|
||||
virtual void updateData(const App::Property*);
|
||||
//virtual void onChanged(const App::Property*); //no further property for viewProvider
|
||||
protected:
|
||||
virtual bool setEdit(int ModNum);
|
||||
|
||||
private:
|
||||
/// Direction of the force
|
||||
Base::Vector3f forceDirection;
|
||||
};
|
||||
|
||||
} //namespace FemGui
|
||||
|
||||
|
||||
#endif // GUI_VIEWPROVIDERFEMConstraintFluidBoundary_H
|
Loading…
Reference in New Issue
Block a user