diff --git a/Common/include/config_structure.hpp b/Common/include/config_structure.hpp index 193b77c79439..60d2c6e21ab1 100644 --- a/Common/include/config_structure.hpp +++ b/Common/include/config_structure.hpp @@ -200,7 +200,6 @@ class CConfig { nMarker_Fluid_Load, /*!< \brief Number of markers in which the flow load is computed/employed. */ nMarker_Fluid_InterfaceBound, /*!< \brief Number of fluid interface markers. */ nMarker_CHTInterface, /*!< \brief Number of conjugate heat transfer interface markers. */ - nMarker_Dirichlet, /*!< \brief Number of interface boundary markers. */ nMarker_Inlet, /*!< \brief Number of inlet flow markers. */ nMarker_Riemann, /*!< \brief Number of Riemann flow markers. */ nMarker_Giles, /*!< \brief Number of Giles flow markers. */ @@ -220,8 +219,7 @@ class CConfig { nMarker_Disp_Dir, /*!< \brief Number of load surface markers defined by magnitude and direction. */ nMarker_Load_Sine, /*!< \brief Number of load surface markers defined by magnitude and direction. */ nMarker_FlowLoad, /*!< \brief Number of load surface markers. */ - nMarker_Neumann, /*!< \brief Number of Neumann flow markers. */ - nMarker_Internal, /*!< \brief Number of Neumann flow markers. */ + nMarker_Internal, /*!< \brief Number of internal flow markers. */ nMarker_All, /*!< \brief Total number of markers using the grid information. */ nMarker_Max, /*!< \brief Max number of number of markers using the grid information. */ nMarker_CfgFile; /*!< \brief Total number of markers using the config file @@ -248,7 +246,6 @@ class CConfig { *Marker_CHTInterface, /*!< \brief Conjugate heat transfer interface markers. */ *Marker_ActDiskInlet, /*!< \brief Actuator disk inlet markers. */ *Marker_ActDiskOutlet, /*!< \brief Actuator disk outlet markers. */ - *Marker_Dirichlet, /*!< \brief Interface boundaries markers. */ *Marker_Inlet, /*!< \brief Inlet flow markers. */ *Marker_Riemann, /*!< \brief Riemann markers. */ *Marker_Giles, /*!< \brief Giles markers. */ @@ -268,11 +265,9 @@ class CConfig { *Marker_Disp_Dir, /*!< \brief Load markers defined in cartesian coordinates. */ *Marker_Load_Sine, /*!< \brief Sine-wave loaded markers defined in cartesian coordinates. */ *Marker_FlowLoad, /*!< \brief Flow Load markers. */ - *Marker_Neumann, /*!< \brief Neumann flow markers. */ - *Marker_Internal, /*!< \brief Neumann flow markers. */ + *Marker_Internal, /*!< \brief Internal flow markers. */ *Marker_All_TagBound; /*!< \brief Global index for markers using grid information. */ - su2double *Dirichlet_Value; /*!< \brief Specified Dirichlet value at the boundaries. */ su2double *Exhaust_Temperature_Target; /*!< \brief Specified total temperatures for nacelle boundaries. */ su2double *Exhaust_Pressure_Target; /*!< \brief Specified total pressures for nacelle boundaries. */ su2double *Inlet_Ttotal; /*!< \brief Specified total temperatures for inlet boundaries. */ @@ -6554,21 +6549,7 @@ class CConfig { * \return The inlet velocity vector. */ su2double* GetInlet_Velocity(string val_index); - - /*! - * \brief Get the fixed value at the Dirichlet boundary. - * \param[in] val_index - Index corresponding to the Dirichlet boundary. - * \return The total temperature. - */ - su2double GetDirichlet_Value(string val_index); - - /*! - * \brief Get whether this is a Dirichlet or a Neumann boundary. - * \param[in] val_index - Index corresponding to the Dirichlet boundary. - * \return Yes or No. - */ - bool GetDirichlet_Boundary(string val_index); - + /*! * \brief Get the total pressure at an inlet boundary. * \param[in] val_index - Index corresponding to the inlet boundary. diff --git a/Common/lib/Makefile.am b/Common/lib/Makefile.am index de5a9c06edc9..3ff0eceab21e 100644 --- a/Common/lib/Makefile.am +++ b/Common/lib/Makefile.am @@ -45,91 +45,19 @@ noinst_LIBRARIES += libSU2_AD.a endif lib_sources = \ - ../include/datatypes/primitive_structure.hpp \ - ../include/datatypes/primitive_structure.inl \ - ../include/datatypes/complex_structure.hpp \ - ../include/datatypes/complex_structure.inl \ - ../include/ad_structure.hpp \ - ../include/ad_structure.inl \ - ../include/fem_cgns_elements.hpp \ - ../include/config_structure.hpp \ - ../include/config_structure.hpp \ - ../include/config_structure.inl \ - ../include/blas_structure.hpp \ - ../include/dual_grid_structure.hpp \ - ../include/dual_grid_structure.inl \ - ../include/fem_geometry_structure.hpp \ - ../include/fem_geometry_structure.inl \ - ../include/fem_standard_element.hpp \ - ../include/fem_standard_element.inl \ - ../include/CMultiGridQueue.hpp \ - ../include/CMeshReaderFVM.hpp \ - ../include/CSU2ASCIIMeshReaderFVM.hpp \ - ../include/CCGNSMeshReaderFVM.hpp \ - ../include/CRectangularMeshReaderFVM.hpp \ - ../include/CBoxMeshReaderFVM.hpp \ - ../include/graph_coloring_structure.hpp \ - ../include/grid_adaptation_structure.hpp \ - ../include/grid_adaptation_structure.inl \ - ../include/grid_movement_structure.hpp \ - ../include/grid_movement_structure.inl \ - ../include/option_structure.hpp \ - ../include/primal_grid_structure.hpp \ - ../include/primal_grid_structure.inl \ - ../include/mpi_structure.hpp \ - ../include/mpi_structure.inl \ - ../include/datatype_structure.hpp \ - ../include/datatype_structure.inl \ - ../include/interpolation_structure.hpp \ - ../include/fem_gauss_jacobi_quadrature.hpp \ - ../include/fem_gauss_jacobi_quadrature.inl \ - ../include/adt_structure.hpp \ - ../include/adt_structure.inl \ - ../include/wall_model.hpp \ - ../include/wall_model.inl \ - ../include/toolboxes/printing_toolbox.hpp \ - ../include/toolboxes/CLinearPartitioner.hpp \ - ../include/toolboxes/MMS/CVerificationSolution.hpp \ - ../include/toolboxes/MMS/CVerificationSolution.inl \ - ../include/toolboxes/MMS/CIncTGVSolution.hpp \ - ../include/toolboxes/MMS/CInviscidVortexSolution.hpp \ - ../include/toolboxes/MMS/CMMSIncEulerSolution.hpp \ - ../include/toolboxes/MMS/CMMSIncNSSolution.hpp \ - ../include/toolboxes/MMS/CMMSNSTwoHalfCirclesSolution.hpp \ - ../include/toolboxes/MMS/CMMSNSTwoHalfSpheresSolution.hpp \ - ../include/toolboxes/MMS/CMMSNSUnitQuadSolution.hpp \ - ../include/toolboxes/MMS/CMMSNSUnitQuadSolutionWallBC.hpp \ - ../include/toolboxes/MMS/CNSUnitQuadSolution.hpp \ - ../include/toolboxes/MMS/CRinglebSolution.hpp \ - ../include/toolboxes/MMS/CTGVSolution.hpp \ - ../include/toolboxes/MMS/CUserDefinedSolution.hpp \ - ../include/linear_algebra/CSysVector.hpp \ - ../include/linear_algebra/CSysMatrix.hpp \ - ../include/linear_algebra/CSysMatrix.inl \ - ../include/linear_algebra/CMatrixVectorProduct.hpp \ - ../include/linear_algebra/CPreconditioner.inl \ - ../include/linear_algebra/CSysSolve.hpp \ - ../include/linear_algebra/CSysSolve_b.hpp \ ../src/fem_cgns_elements.cpp \ ../src/config_structure.cpp \ ../src/blas_structure.cpp \ - ../src/dual_grid_structure.cpp \ ../src/fem_geometry_structure.cpp \ ../src/fem_integration_rules.cpp \ ../src/fem_standard_element.cpp \ ../src/fem_wall_distance.cpp \ ../src/fem_work_estimate_metis.cpp \ ../src/CMultiGridQueue.cpp \ - ../src/CMeshReaderFVM.cpp \ - ../src/CSU2ASCIIMeshReaderFVM.cpp \ - ../src/CCGNSMeshReaderFVM.cpp \ - ../src/CRectangularMeshReaderFVM.cpp \ - ../src/CBoxMeshReaderFVM.cpp \ ../src/geometry_structure_fem_part.cpp \ ../src/graph_coloring_structure.cpp \ ../src/grid_adaptation_structure.cpp \ ../src/grid_movement_structure.cpp \ - ../src/primal_grid_structure.cpp \ ../src/mpi_structure.cpp \ ../src/ad_structure.cpp \ ../src/fem_gauss_jacobi_quadrature.cpp \ @@ -144,11 +72,31 @@ lib_sources = \ ../src/geometry/elements/CPYRAM5.cpp \ ../src/geometry/elements/CPRISM6.cpp \ ../src/geometry/elements/CHEXA8.cpp \ + ../src/geometry/meshreader/CMeshReaderFVM.cpp \ + ../src/geometry/meshreader/CSU2ASCIIMeshReaderFVM.cpp \ + ../src/geometry/meshreader/CCGNSMeshReaderFVM.cpp \ + ../src/geometry/meshreader/CRectangularMeshReaderFVM.cpp \ + ../src/geometry/meshreader/CBoxMeshReaderFVM.cpp \ + ../src/geometry/dual_grid/CDualGrid.cpp \ + ../src/geometry/dual_grid/CEdge.cpp \ + ../src/geometry/dual_grid/CPoint.cpp \ + ../src/geometry/dual_grid/CVertex.cpp \ + ../src/geometry/dual_grid/CTurboVertex.cpp \ + ../src/geometry/primal_grid/CPrimalGrid.cpp \ + ../src/geometry/primal_grid/CPrimalGridFEM.cpp \ + ../src/geometry/primal_grid/CPrimalGridBoundFEM.cpp \ + ../src/geometry/primal_grid/CLine.cpp \ + ../src/geometry/primal_grid/CTriangle.cpp \ + ../src/geometry/primal_grid/CPrism.cpp \ + ../src/geometry/primal_grid/CPyramid.cpp \ + ../src/geometry/primal_grid/CHexahedron.cpp \ + ../src/geometry/primal_grid/CTetrahedron.cpp \ + ../src/geometry/primal_grid/CQuadrilateral.cpp \ + ../src/geometry/primal_grid/CVertexMPI.cpp \ ../src/interpolation_structure.cpp \ ../src/adt_structure.cpp \ ../src/wall_model.cpp \ ../src/toolboxes/printing_toolbox.cpp \ - ../src/toolboxes/signal_processing_toolbox.cpp \ ../src/toolboxes/CLinearPartitioner.cpp \ ../src/toolboxes/MMS/CVerificationSolution.cpp \ ../src/toolboxes/MMS/CIncTGVSolution.cpp \ diff --git a/Common/src/config_structure.cpp b/Common/src/config_structure.cpp index de7133fcdcff..80c78ba2ea08 100644 --- a/Common/src/config_structure.cpp +++ b/Common/src/config_structure.cpp @@ -519,27 +519,27 @@ void CConfig::SetPointersNull(void) { /*--- Marker Pointers ---*/ Marker_Euler = NULL; Marker_FarField = NULL; Marker_Custom = NULL; - Marker_SymWall = NULL; Marker_PerBound = NULL; + Marker_SymWall = NULL; Marker_PerBound = NULL; Marker_PerDonor = NULL; Marker_NearFieldBound = NULL; Marker_Deform_Mesh = NULL; Marker_Fluid_Load = NULL; - Marker_Dirichlet = NULL; Marker_Inlet = NULL; - Marker_Supersonic_Inlet = NULL; Marker_Outlet = NULL; + Marker_Inlet = NULL; Marker_Outlet = NULL; + Marker_Supersonic_Inlet = NULL; Marker_Supersonic_Outlet= NULL; Marker_Isothermal = NULL; Marker_HeatFlux = NULL; Marker_EngineInflow = NULL; - Marker_Supersonic_Outlet = NULL; Marker_Load = NULL; Marker_Disp_Dir = NULL; + Marker_Load = NULL; Marker_Disp_Dir = NULL; Marker_EngineExhaust = NULL; Marker_Displacement = NULL; Marker_Load = NULL; Marker_Load_Dir = NULL; Marker_Load_Sine = NULL; Marker_Clamped = NULL; - Marker_FlowLoad = NULL; Marker_Neumann = NULL; Marker_Internal = NULL; + Marker_FlowLoad = NULL; Marker_Internal = NULL; Marker_All_TagBound = NULL; Marker_CfgFile_TagBound = NULL; Marker_All_KindBC = NULL; Marker_CfgFile_KindBC = NULL; Marker_All_SendRecv = NULL; Marker_All_PerBound = NULL; Marker_ZoneInterface = NULL; Marker_All_ZoneInterface= NULL; Marker_Riemann = NULL; - Marker_Fluid_InterfaceBound = NULL; Marker_CHTInterface = NULL; Marker_Damper = NULL; + Marker_Fluid_InterfaceBound = NULL; Marker_CHTInterface = NULL; Marker_Damper = NULL; /*--- Boundary Condition settings ---*/ - Dirichlet_Value = NULL; Isothermal_Temperature = NULL; - Heat_Flux = NULL; Displ_Value = NULL; Load_Value = NULL; - FlowLoad_Value = NULL; Damper_Constant = NULL; + Isothermal_Temperature = NULL; + Heat_Flux = NULL; Displ_Value = NULL; Load_Value = NULL; + FlowLoad_Value = NULL; Damper_Constant = NULL; /*--- Inlet Outlet Boundary Condition settings ---*/ @@ -565,7 +565,7 @@ void CConfig::SetPointersNull(void) { Engine_Power = NULL; Engine_NetThrust = NULL; Engine_GrossThrust = NULL; Engine_Area = NULL; EngineInflow_Target = NULL; - Dirichlet_Value = NULL; Exhaust_Temperature_Target = NULL; Exhaust_Temperature = NULL; + Exhaust_Temperature_Target = NULL; Exhaust_Temperature = NULL; Exhaust_Pressure_Target = NULL; Inlet_Ttotal = NULL; Inlet_Ptotal = NULL; Inlet_FlowDir = NULL; Inlet_Temperature = NULL; Inlet_Pressure = NULL; Inlet_Velocity = NULL; Inflow_Mach = NULL; Inflow_Pressure = NULL; @@ -1153,11 +1153,7 @@ void CConfig::SetConfig_Options() { addStringListOption("MARKER_ZONE_INTERFACE", nMarker_ZoneInterface, Marker_ZoneInterface); /*!\brief MARKER_CHT_INTERFACE \n DESCRIPTION: CHT interface boundary marker(s) \ingroup Config*/ addStringListOption("MARKER_CHT_INTERFACE", nMarker_CHTInterface, Marker_CHTInterface); - /*!\brief MARKER_DIRICHLET \n DESCRIPTION: Dirichlet boundary marker(s) \ingroup Config*/ - addStringListOption("MARKER_DIRICHLET", nMarker_Dirichlet, Marker_Dirichlet); - /* DESCRIPTION: Neumann boundary marker(s) */ - addStringListOption("MARKER_NEUMANN", nMarker_Neumann, Marker_Neumann); - /* DESCRIPTION: Neumann boundary marker(s) */ + /* DESCRIPTION: Internal boundary marker(s) */ addStringListOption("MARKER_INTERNAL", nMarker_Internal, Marker_Internal); /* DESCRIPTION: Custom boundary marker(s) */ addStringListOption("MARKER_CUSTOM", nMarker_Custom, Marker_Custom); @@ -4639,10 +4635,10 @@ void CConfig::SetMarkers(unsigned short val_software) { unsigned short iMarker_All, iMarker_CfgFile, iMarker_Euler, iMarker_Custom, iMarker_FarField, iMarker_SymWall, iMarker_PerBound, - iMarker_NearFieldBound, iMarker_Fluid_InterfaceBound, iMarker_Dirichlet, + iMarker_NearFieldBound, iMarker_Fluid_InterfaceBound, iMarker_Inlet, iMarker_Riemann, iMarker_Giles, iMarker_Outlet, iMarker_Isothermal, iMarker_HeatFlux, iMarker_EngineInflow, iMarker_EngineExhaust, iMarker_Damper, - iMarker_Displacement, iMarker_Load, iMarker_FlowLoad, iMarker_Neumann, iMarker_Internal, + iMarker_Displacement, iMarker_Load, iMarker_FlowLoad, iMarker_Internal, iMarker_Monitoring, iMarker_Designing, iMarker_GeoEval, iMarker_Plotting, iMarker_Analyze, iMarker_DV, iMarker_Moving, iMarker_PyCustom, iMarker_Supersonic_Inlet, iMarker_Supersonic_Outlet, iMarker_Clamped, iMarker_ZoneInterface, iMarker_CHTInterface, iMarker_Load_Dir, iMarker_Disp_Dir, iMarker_Load_Sine, @@ -4661,7 +4657,7 @@ void CConfig::SetMarkers(unsigned short val_software) { nMarker_CfgFile = nMarker_Euler + nMarker_FarField + nMarker_SymWall + nMarker_PerBound + nMarker_NearFieldBound + nMarker_Fluid_InterfaceBound + - nMarker_CHTInterface + nMarker_Dirichlet + nMarker_Neumann + nMarker_Inlet + nMarker_Riemann + + nMarker_CHTInterface + nMarker_Inlet + nMarker_Riemann + nMarker_Giles + nMarker_Outlet + nMarker_Isothermal + nMarker_HeatFlux + nMarker_EngineInflow + nMarker_EngineExhaust + nMarker_Internal + nMarker_Supersonic_Inlet + nMarker_Supersonic_Outlet + nMarker_Displacement + nMarker_Load + @@ -4939,12 +4935,6 @@ void CConfig::SetMarkers(unsigned short val_software) { iMarker_CfgFile++; } - for (iMarker_Dirichlet = 0; iMarker_Dirichlet < nMarker_Dirichlet; iMarker_Dirichlet++) { - Marker_CfgFile_TagBound[iMarker_CfgFile] = Marker_Dirichlet[iMarker_Dirichlet]; - Marker_CfgFile_KindBC[iMarker_CfgFile] = DIRICHLET; - iMarker_CfgFile++; - } - for (iMarker_Inlet = 0; iMarker_Inlet < nMarker_Inlet; iMarker_Inlet++) { Marker_CfgFile_TagBound[iMarker_CfgFile] = Marker_Inlet[iMarker_Inlet]; Marker_CfgFile_KindBC[iMarker_CfgFile] = INLET_FLOW; @@ -5040,12 +5030,6 @@ void CConfig::SetMarkers(unsigned short val_software) { Marker_CfgFile_KindBC[iMarker_CfgFile] = SUPERSONIC_OUTLET; iMarker_CfgFile++; } - - for (iMarker_Neumann = 0; iMarker_Neumann < nMarker_Neumann; iMarker_Neumann++) { - Marker_CfgFile_TagBound[iMarker_CfgFile] = Marker_Neumann[iMarker_Neumann]; - Marker_CfgFile_KindBC[iMarker_CfgFile] = NEUMANN; - iMarker_CfgFile++; - } for (iMarker_Internal = 0; iMarker_Internal < nMarker_Internal; iMarker_Internal++) { Marker_CfgFile_TagBound[iMarker_CfgFile] = Marker_Internal[iMarker_Internal]; @@ -5264,11 +5248,11 @@ void CConfig::SetOutput(unsigned short val_software, unsigned short val_izone) { unsigned short iMarker_Euler, iMarker_Custom, iMarker_FarField, iMarker_SymWall, iMarker_PerBound, iMarker_NearFieldBound, - iMarker_Fluid_InterfaceBound, iMarker_Dirichlet, iMarker_Inlet, iMarker_Riemann, + iMarker_Fluid_InterfaceBound, iMarker_Inlet, iMarker_Riemann, iMarker_Deform_Mesh, iMarker_Fluid_Load, iMarker_Giles, iMarker_Outlet, iMarker_Isothermal, iMarker_HeatFlux, iMarker_EngineInflow, iMarker_EngineExhaust, iMarker_Displacement, iMarker_Damper, - iMarker_Load, iMarker_FlowLoad, iMarker_Neumann, iMarker_Internal, iMarker_Monitoring, + iMarker_Load, iMarker_FlowLoad, iMarker_Internal, iMarker_Monitoring, iMarker_Designing, iMarker_GeoEval, iMarker_Plotting, iMarker_Analyze, iMarker_DV, iDV_Value, iMarker_ZoneInterface, iMarker_PyCustom, iMarker_Load_Dir, iMarker_Disp_Dir, iMarker_Load_Sine, iMarker_Clamped, iMarker_Moving, iMarker_Supersonic_Inlet, iMarker_Supersonic_Outlet, iMarker_ActDiskInlet, @@ -6553,15 +6537,6 @@ void CConfig::SetOutput(unsigned short val_software, unsigned short val_izone) { BoundaryTable.PrintFooter(); } - if (nMarker_Dirichlet != 0) { - BoundaryTable << "Dirichlet boundary"; - for (iMarker_Dirichlet = 0; iMarker_Dirichlet < nMarker_Dirichlet; iMarker_Dirichlet++) { - BoundaryTable << Marker_Dirichlet[iMarker_Dirichlet]; - if (iMarker_Dirichlet < nMarker_Dirichlet-1) BoundaryTable << " "; - } - BoundaryTable.PrintFooter(); - } - if (nMarker_FlowLoad != 0) { BoundaryTable << "Flow load boundary"; for (iMarker_FlowLoad = 0; iMarker_FlowLoad < nMarker_FlowLoad; iMarker_FlowLoad++) { @@ -6742,15 +6717,6 @@ void CConfig::SetOutput(unsigned short val_software, unsigned short val_izone) { BoundaryTable.PrintFooter(); } - if (nMarker_Neumann != 0) { - BoundaryTable << "Neumann boundary"; - for (iMarker_Neumann = 0; iMarker_Neumann < nMarker_Neumann; iMarker_Neumann++) { - BoundaryTable << Marker_Neumann[iMarker_Neumann]; - if (iMarker_Neumann < nMarker_Neumann-1) BoundaryTable << " "; - } - BoundaryTable.PrintFooter(); - } - if (nMarker_Custom != 0) { BoundaryTable << "Custom boundary"; for (iMarker_Custom = 0; iMarker_Custom < nMarker_Custom; iMarker_Custom++) { @@ -7302,7 +7268,6 @@ CConfig::~CConfig(void) { } if (Design_Variable != NULL) delete[] Design_Variable; - if (Dirichlet_Value != NULL) delete[] Dirichlet_Value; if (Exhaust_Temperature_Target != NULL) delete[] Exhaust_Temperature_Target; if (Exhaust_Pressure_Target != NULL) delete[] Exhaust_Pressure_Target; @@ -7483,7 +7448,6 @@ CConfig::~CConfig(void) { if (Marker_Deform_Mesh != NULL ) delete[] Marker_Deform_Mesh; if (Marker_Fluid_Load != NULL ) delete[] Marker_Fluid_Load; if (Marker_Fluid_InterfaceBound != NULL ) delete[] Marker_Fluid_InterfaceBound; - if (Marker_Dirichlet != NULL ) delete[] Marker_Dirichlet; if (Marker_Inlet != NULL ) delete[] Marker_Inlet; if (Marker_Supersonic_Inlet != NULL ) delete[] Marker_Supersonic_Inlet; if (Marker_Supersonic_Outlet != NULL ) delete[] Marker_Supersonic_Outlet; @@ -7498,7 +7462,6 @@ CConfig::~CConfig(void) { if (Marker_Disp_Dir != NULL ) delete[] Marker_Disp_Dir; if (Marker_Load_Sine != NULL ) delete[] Marker_Load_Sine; if (Marker_FlowLoad != NULL ) delete[] Marker_FlowLoad; - if (Marker_Neumann != NULL ) delete[] Marker_Neumann; if (Marker_Internal != NULL ) delete[] Marker_Internal; if (Marker_HeatFlux != NULL ) delete[] Marker_HeatFlux; @@ -8227,24 +8190,6 @@ unsigned short CConfig::GetMarker_Fluid_Load(string val_marker) { return iMarker_Fluid_Load; } -su2double CConfig::GetDirichlet_Value(string val_marker) { - unsigned short iMarker_Dirichlet; - for (iMarker_Dirichlet = 0; iMarker_Dirichlet < nMarker_Dirichlet; iMarker_Dirichlet++) - if (Marker_Dirichlet[iMarker_Dirichlet] == val_marker) break; - return Dirichlet_Value[iMarker_Dirichlet]; -} - -bool CConfig::GetDirichlet_Boundary(string val_marker) { - unsigned short iMarker_Dirichlet; - bool Dirichlet = false; - for (iMarker_Dirichlet = 0; iMarker_Dirichlet < nMarker_Dirichlet; iMarker_Dirichlet++) - if (Marker_Dirichlet[iMarker_Dirichlet] == val_marker) { - Dirichlet = true; - break; - } - return Dirichlet; -} - su2double CConfig::GetExhaust_Temperature_Target(string val_marker) { unsigned short iMarker_EngineExhaust; for (iMarker_EngineExhaust = 0; iMarker_EngineExhaust < nMarker_EngineExhaust; iMarker_EngineExhaust++) diff --git a/Common/src/fem_geometry_structure.cpp b/Common/src/fem_geometry_structure.cpp index 9b6f89881a86..fa33a7d08da7 100644 --- a/Common/src/fem_geometry_structure.cpp +++ b/Common/src/fem_geometry_structure.cpp @@ -26,6 +26,7 @@ */ #include "../include/fem_geometry_structure.hpp" +#include "../include/geometry/primal_grid/CPrimalGridFEM.hpp" #include "../include/geometry/primal_grid/CPrimalGridBoundFEM.hpp" #include "../include/adt_structure.hpp" diff --git a/Common/src/geometry/meshreader/CBoxMeshReaderFVM.cpp b/Common/src/geometry/meshreader/CBoxMeshReaderFVM.cpp index 88d0b3df3c05..a27eb7819fb3 100644 --- a/Common/src/geometry/meshreader/CBoxMeshReaderFVM.cpp +++ b/Common/src/geometry/meshreader/CBoxMeshReaderFVM.cpp @@ -26,8 +26,8 @@ * License along with SU2. If not, see . */ -#include "../include/toolboxes/CLinearPartitioner.hpp" -#include "../include/geometry/meshreader/CBoxMeshReaderFVM.hpp" +#include "../../../include/toolboxes/CLinearPartitioner.hpp" +#include "../../../include/geometry/meshreader/CBoxMeshReaderFVM.hpp" CBoxMeshReaderFVM::CBoxMeshReaderFVM(CConfig *val_config, unsigned short val_iZone, diff --git a/Common/src/geometry/meshreader/CCGNSMeshReaderFVM.cpp b/Common/src/geometry/meshreader/CCGNSMeshReaderFVM.cpp index 202b6f3c7324..b4f8f2eacfe5 100644 --- a/Common/src/geometry/meshreader/CCGNSMeshReaderFVM.cpp +++ b/Common/src/geometry/meshreader/CCGNSMeshReaderFVM.cpp @@ -26,8 +26,8 @@ * License along with SU2. If not, see . */ -#include "../include/toolboxes/CLinearPartitioner.hpp" -#include "../include/geometry/meshreader/CCGNSMeshReaderFVM.hpp" +#include "../../../include/toolboxes/CLinearPartitioner.hpp" +#include "../../../include/geometry/meshreader/CCGNSMeshReaderFVM.hpp" CCGNSMeshReaderFVM::CCGNSMeshReaderFVM(CConfig *val_config, unsigned short val_iZone, diff --git a/Common/src/geometry/meshreader/CMeshReaderFVM.cpp b/Common/src/geometry/meshreader/CMeshReaderFVM.cpp index 509b6ce390ec..c530a235a063 100644 --- a/Common/src/geometry/meshreader/CMeshReaderFVM.cpp +++ b/Common/src/geometry/meshreader/CMeshReaderFVM.cpp @@ -26,7 +26,7 @@ * License along with SU2. If not, see . */ -#include "../include/geometry/meshreader/CMeshReaderFVM.hpp" +#include "../../../include/geometry/meshreader/CMeshReaderFVM.hpp" CMeshReaderFVM::CMeshReaderFVM(CConfig *val_config, unsigned short val_iZone, diff --git a/Common/src/geometry/meshreader/CRectangularMeshReaderFVM.cpp b/Common/src/geometry/meshreader/CRectangularMeshReaderFVM.cpp index 1675ad4e7e5e..83c4074dd385 100644 --- a/Common/src/geometry/meshreader/CRectangularMeshReaderFVM.cpp +++ b/Common/src/geometry/meshreader/CRectangularMeshReaderFVM.cpp @@ -26,8 +26,8 @@ * License along with SU2. If not, see . */ -#include "../include/toolboxes/CLinearPartitioner.hpp" -#include "../include/geometry/meshreader/CRectangularMeshReaderFVM.hpp" +#include "../../../include/toolboxes/CLinearPartitioner.hpp" +#include "../../../include/geometry/meshreader/CRectangularMeshReaderFVM.hpp" CRectangularMeshReaderFVM::CRectangularMeshReaderFVM(CConfig *val_config, unsigned short val_iZone, diff --git a/Common/src/geometry/meshreader/CSU2ASCIIMeshReaderFVM.cpp b/Common/src/geometry/meshreader/CSU2ASCIIMeshReaderFVM.cpp index e5e7c816905c..ecfada621a67 100644 --- a/Common/src/geometry/meshreader/CSU2ASCIIMeshReaderFVM.cpp +++ b/Common/src/geometry/meshreader/CSU2ASCIIMeshReaderFVM.cpp @@ -26,8 +26,8 @@ * License along with SU2. If not, see . */ -#include "../include/toolboxes/CLinearPartitioner.hpp" -#include "../include/geometry/meshreader/CSU2ASCIIMeshReaderFVM.hpp" +#include "../../../include/toolboxes/CLinearPartitioner.hpp" +#include "../../../include/geometry/meshreader/CSU2ASCIIMeshReaderFVM.hpp" CSU2ASCIIMeshReaderFVM::CSU2ASCIIMeshReaderFVM(CConfig *val_config, unsigned short val_iZone, diff --git a/Common/src/geometry/primal_grid/CHexahedron.cpp b/Common/src/geometry/primal_grid/CHexahedron.cpp index 376bc8e7886f..ca43aa97567b 100644 --- a/Common/src/geometry/primal_grid/CHexahedron.cpp +++ b/Common/src/geometry/primal_grid/CHexahedron.cpp @@ -25,7 +25,7 @@ * License along with SU2. If not, see . */ -#include "../include/geometry/primal_grid/CHexahedron.hpp" +#include "../../../include/geometry/primal_grid/CHexahedron.hpp" unsigned short CHexahedron::Faces[6][4] = {{0,1,5,4},{1,2,6,5},{2,3,7,6},{3,0,4,7},{0,3,2,1},{4,5,6,7}}; diff --git a/Common/src/geometry/primal_grid/CLine.cpp b/Common/src/geometry/primal_grid/CLine.cpp index a0bbb36151c9..275c0a3ae1da 100644 --- a/Common/src/geometry/primal_grid/CLine.cpp +++ b/Common/src/geometry/primal_grid/CLine.cpp @@ -25,7 +25,7 @@ * License along with SU2. If not, see . */ -#include "../include/geometry/primal_grid/CLine.hpp" +#include "../../../include/geometry/primal_grid/CLine.hpp" unsigned short CLine::Faces[1][2]={{0,1}}; diff --git a/Common/src/geometry/primal_grid/CPrimalGrid.cpp b/Common/src/geometry/primal_grid/CPrimalGrid.cpp index c8b651e36af7..e3b2e19159d1 100644 --- a/Common/src/geometry/primal_grid/CPrimalGrid.cpp +++ b/Common/src/geometry/primal_grid/CPrimalGrid.cpp @@ -25,7 +25,7 @@ * License along with SU2. If not, see . */ -#include "../include/geometry/primal_grid/CPrimalGrid.hpp" +#include "../../../include/geometry/primal_grid/CPrimalGrid.hpp" unsigned short CPrimalGrid::nDim; diff --git a/Common/src/geometry/primal_grid/CPrimalGridBoundFEM.cpp b/Common/src/geometry/primal_grid/CPrimalGridBoundFEM.cpp index 43c93ba95f85..d3b618cb4bb5 100644 --- a/Common/src/geometry/primal_grid/CPrimalGridBoundFEM.cpp +++ b/Common/src/geometry/primal_grid/CPrimalGridBoundFEM.cpp @@ -25,7 +25,7 @@ * License along with SU2. If not, see . */ -#include "../include/geometry/primal_grid/CPrimalGridBoundFEM.hpp" +#include "../../../include/geometry/primal_grid/CPrimalGridBoundFEM.hpp" CPrimalGridBoundFEM::CPrimalGridBoundFEM(unsigned long val_elemGlobalID, unsigned long val_domainElementID, diff --git a/Common/src/geometry/primal_grid/CPrimalGridFEM.cpp b/Common/src/geometry/primal_grid/CPrimalGridFEM.cpp index c3f017e698ef..27b418fdb03f 100644 --- a/Common/src/geometry/primal_grid/CPrimalGridFEM.cpp +++ b/Common/src/geometry/primal_grid/CPrimalGridFEM.cpp @@ -25,7 +25,7 @@ * License along with SU2. If not, see . */ -#include "../include/geometry/primal_grid/CPrimalGridFEM.hpp" +#include "../../../include/geometry/primal_grid/CPrimalGridFEM.hpp" CPrimalGridFEM::CPrimalGridFEM(unsigned long val_elemGlobalID, unsigned short val_VTK_Type, unsigned short val_nPolyGrid, unsigned short val_nPolySol, diff --git a/Common/src/geometry/primal_grid/CPrism.cpp b/Common/src/geometry/primal_grid/CPrism.cpp index 3757027f772a..0c2f23f18c3b 100644 --- a/Common/src/geometry/primal_grid/CPrism.cpp +++ b/Common/src/geometry/primal_grid/CPrism.cpp @@ -25,7 +25,7 @@ * License along with SU2. If not, see . */ -#include "../include/geometry/primal_grid/CPrism.hpp" +#include "../../../include/geometry/primal_grid/CPrism.hpp" unsigned short CPrism::Faces[5][4] = {{3,4,1,0},{5,2,1,4},{2,5,3,0},{0,1,2,2},{5,4,3,3}}; diff --git a/Common/src/geometry/primal_grid/CPyramid.cpp b/Common/src/geometry/primal_grid/CPyramid.cpp index 7a4d92d7915b..0d6c49a45b95 100644 --- a/Common/src/geometry/primal_grid/CPyramid.cpp +++ b/Common/src/geometry/primal_grid/CPyramid.cpp @@ -25,7 +25,7 @@ * License along with SU2. If not, see . */ -#include "../include/geometry/primal_grid/CPyramid.hpp" +#include "../../../include/geometry/primal_grid/CPyramid.hpp" unsigned short CPyramid::Faces[5][4] = {{0,3,2,1},{4,3,0,0},{4,0,1,1},{2,4,1,1},{3,4,2,2}}; diff --git a/Common/src/geometry/primal_grid/CQuadrilateral.cpp b/Common/src/geometry/primal_grid/CQuadrilateral.cpp index 448756a6f160..8eaa2987f97a 100644 --- a/Common/src/geometry/primal_grid/CQuadrilateral.cpp +++ b/Common/src/geometry/primal_grid/CQuadrilateral.cpp @@ -25,7 +25,7 @@ * License along with SU2. If not, see . */ -#include "../include/geometry/primal_grid/CQuadrilateral.hpp" +#include "../../../include/geometry/primal_grid/CQuadrilateral.hpp" unsigned short CQuadrilateral::Faces[4][2] = {{0,1},{1,2},{2,3},{3,0}}; diff --git a/Common/src/geometry/primal_grid/CTetrahedron.cpp b/Common/src/geometry/primal_grid/CTetrahedron.cpp index 02e7299d4519..570c44fe260e 100644 --- a/Common/src/geometry/primal_grid/CTetrahedron.cpp +++ b/Common/src/geometry/primal_grid/CTetrahedron.cpp @@ -25,7 +25,7 @@ * License along with SU2. If not, see . */ -#include "../include/geometry/primal_grid/CTetrahedron.hpp" +#include "../../../include/geometry/primal_grid/CTetrahedron.hpp" unsigned short CTetrahedron::Faces[4][3]={{0,2,1},{0,1,3},{0,3,2},{1,2,3}}; diff --git a/Common/src/geometry/primal_grid/CTriangle.cpp b/Common/src/geometry/primal_grid/CTriangle.cpp index d50dba7f6b0a..38763f1db9f0 100644 --- a/Common/src/geometry/primal_grid/CTriangle.cpp +++ b/Common/src/geometry/primal_grid/CTriangle.cpp @@ -25,7 +25,7 @@ * License along with SU2. If not, see . */ -#include "../include/geometry/primal_grid/CTriangle.hpp" +#include "../../../include/geometry/primal_grid/CTriangle.hpp" unsigned short CTriangle::Faces[3][2] = {{0,1},{1,2},{2,0}}; diff --git a/Common/src/geometry/primal_grid/CVertexMPI.cpp b/Common/src/geometry/primal_grid/CVertexMPI.cpp index 79eac135578f..536c2b0b33a4 100644 --- a/Common/src/geometry/primal_grid/CVertexMPI.cpp +++ b/Common/src/geometry/primal_grid/CVertexMPI.cpp @@ -25,7 +25,7 @@ * License along with SU2. If not, see . */ -#include "../include/geometry/primal_grid/CVertexMPI.hpp" +#include "../../../include/geometry/primal_grid/CVertexMPI.hpp" unsigned short CVertexMPI::nFaces = 0; diff --git a/Common/src/geometry_structure_fem_part.cpp b/Common/src/geometry_structure_fem_part.cpp index ab98c2798ad4..ede5780f3875 100644 --- a/Common/src/geometry_structure_fem_part.cpp +++ b/Common/src/geometry_structure_fem_part.cpp @@ -27,6 +27,7 @@ #include "../include/geometry/CPhysicalGeometry.hpp" #include "../include/fem_standard_element.hpp" +#include "../include/geometry/primal_grid/CPrimalGridFEM.hpp" #include "../include/geometry/primal_grid/CPrimalGridBoundFEM.hpp" #ifdef HAVE_CGNS diff --git a/Common/src/linear_algebra/CPastixWrapper.cpp b/Common/src/linear_algebra/CPastixWrapper.cpp index d632ecb4ea46..521fd3c8571f 100644 --- a/Common/src/linear_algebra/CPastixWrapper.cpp +++ b/Common/src/linear_algebra/CPastixWrapper.cpp @@ -89,8 +89,15 @@ void CPastixWrapper::Initialize(CGeometry *geometry, CConfig *config) { iparm[IPARM_ORDERING] = API_ORDER_PTSCOTCH; iparm[IPARM_INCOMPLETE] = incomplete; iparm[IPARM_LEVEL_OF_FILL] = pastix_int_t(config->GetPastixFillLvl()); - iparm[IPARM_THREAD_COMM_MODE] = API_THREAD_FUNNELED; iparm[IPARM_THREAD_NBR] = omp_get_max_threads(); +#ifdef HAVE_MPI + int comm_mode = MPI_THREAD_SINGLE; + MPI_Query_thread(&comm_mode); + if (comm_mode == MPI_THREAD_MULTIPLE) + iparm[IPARM_THREAD_COMM_MODE] = API_THREAD_MULTIPLE; + else + iparm[IPARM_THREAD_COMM_MODE] = API_THREAD_FUNNELED; +#endif /*--- Prepare sparsity structure ---*/ diff --git a/SU2_CFD/include/SU2_CFD.hpp b/SU2_CFD/include/SU2_CFD.hpp index 57ce99b0d8db..1c0d0e0f11b5 100644 --- a/SU2_CFD/include/SU2_CFD.hpp +++ b/SU2_CFD/include/SU2_CFD.hpp @@ -39,7 +39,6 @@ #include "drivers/CDiscAdjSinglezoneDriver.hpp" #include "drivers/CDiscAdjMultizoneDriver.hpp" #include "drivers/CDummyDriver.hpp" -#include "solver_structure.hpp" #include "integration_structure.hpp" #include "output/COutput.hpp" #include "numerics_structure.hpp" diff --git a/SU2_CFD/include/drivers/CDriver.hpp b/SU2_CFD/include/drivers/CDriver.hpp index bcfc4882ac43..c1876bcf862b 100644 --- a/SU2_CFD/include/drivers/CDriver.hpp +++ b/SU2_CFD/include/drivers/CDriver.hpp @@ -30,7 +30,7 @@ #include "../../../Common/include/mpi_structure.hpp" #include "../iteration_structure.hpp" -#include "../solver_structure.hpp" + #include "../integration_structure.hpp" #include "../numerics_structure.hpp" diff --git a/SU2_CFD/include/fluid_model.inl b/SU2_CFD/include/fluid_model.inl index 18c060dce2c8..14c4596ffdeb 100644 --- a/SU2_CFD/include/fluid_model.inl +++ b/SU2_CFD/include/fluid_model.inl @@ -1,6 +1,6 @@ /*! * \file fluid_model.inl - * \brief In-Line subroutines of the solver_structure.hpp file. + * \brief In-Line subroutines of the fluid_model.hpp file. * \author S. Vitale, M. Pini, G. Gori, A. Guardone, P. Colonna * \version 7.0.0 "Blackbird" * diff --git a/SU2_CFD/include/gradients/computeGradientsLeastSquares.hpp b/SU2_CFD/include/gradients/computeGradientsLeastSquares.hpp index 1f1766813662..e9d86759e1eb 100644 --- a/SU2_CFD/include/gradients/computeGradientsLeastSquares.hpp +++ b/SU2_CFD/include/gradients/computeGradientsLeastSquares.hpp @@ -108,7 +108,7 @@ void computeGradientsLeastSquares(CSolver* solver, /*--- Distance vector from iPoint to jPoint ---*/ - su2double dist_ij[MAXNDIM]; + su2double dist_ij[MAXNDIM] = {0.0}; for (size_t iDim = 0; iDim < nDim; ++iDim) dist_ij[iDim] = coord_j[iDim] - coord_i[iDim]; diff --git a/SU2_CFD/include/integration_structure.hpp b/SU2_CFD/include/integration_structure.hpp index a5c22c7b7771..7f1ef25bc55b 100644 --- a/SU2_CFD/include/integration_structure.hpp +++ b/SU2_CFD/include/integration_structure.hpp @@ -35,7 +35,7 @@ #include #include -#include "solver_structure.hpp" +#include "solvers/CSolver.hpp" #include "../../Common/include/geometry/CGeometry.hpp" #include "../../Common/include/config_structure.hpp" diff --git a/SU2_CFD/include/interfaces/CInterface.hpp b/SU2_CFD/include/interfaces/CInterface.hpp index 9e8193c1a427..11f1b22d6f00 100644 --- a/SU2_CFD/include/interfaces/CInterface.hpp +++ b/SU2_CFD/include/interfaces/CInterface.hpp @@ -41,7 +41,8 @@ #include "../../../Common/include/config_structure.hpp" #include "../../../Common/include/geometry/CGeometry.hpp" -#include "../solver_structure.hpp" +#include "../solvers/CSolver.hpp" + using namespace std; diff --git a/SU2_CFD/include/iteration_structure.hpp b/SU2_CFD/include/iteration_structure.hpp index e8791ebc755f..83475978f9d1 100644 --- a/SU2_CFD/include/iteration_structure.hpp +++ b/SU2_CFD/include/iteration_structure.hpp @@ -32,11 +32,11 @@ #include -#include "solver_structure.hpp" #include "integration_structure.hpp" + #include "output/COutput.hpp" #include "numerics_structure.hpp" -#include "../../Common/include/geometry/CGeometry.hpp" + #include "../../Common/include/grid_movement_structure.hpp" #include "../../Common/include/config_structure.hpp" diff --git a/SU2_CFD/include/limiters/computeLimiters_impl.hpp b/SU2_CFD/include/limiters/computeLimiters_impl.hpp index 2c0b720c7034..6b5d405cb1cf 100644 --- a/SU2_CFD/include/limiters/computeLimiters_impl.hpp +++ b/SU2_CFD/include/limiters/computeLimiters_impl.hpp @@ -187,7 +187,7 @@ void computeLimiters_impl(CSolver* solver, /*--- Distance vector from iPoint to face (middle of the edge). ---*/ - su2double dist_ij[MAXNDIM]; + su2double dist_ij[MAXNDIM] = {0.0}; for(size_t iDim = 0; iDim < nDim; ++iDim) dist_ij[iDim] = 0.5 * (coord_j[iDim] - coord_i[iDim]); diff --git a/SU2_CFD/include/output/COutputLegacy.hpp b/SU2_CFD/include/output/COutputLegacy.hpp index 9d62a1bbb402..57aa0f4e6317 100644 --- a/SU2_CFD/include/output/COutputLegacy.hpp +++ b/SU2_CFD/include/output/COutputLegacy.hpp @@ -42,12 +42,6 @@ #include #include -//#include "../solver_structure.hpp" -//#include "../integration_structure.hpp" -//#include "../../../Common/include/geometry_structure.hpp" -//#include "../../../Common/include/fem_geometry_structure.hpp" -//#include "../../../Common/include/fem_standard_element.hpp" - #include "../../../Common/include/option_structure.hpp" class CGeometry; class CConfig; diff --git a/SU2_CFD/include/solver_structure.hpp b/SU2_CFD/include/solver_structure.hpp deleted file mode 100644 index f88232ed8a9f..000000000000 --- a/SU2_CFD/include/solver_structure.hpp +++ /dev/null @@ -1,14906 +0,0 @@ -/*! - * \file solver_structure.hpp - * \brief Headers of the main subroutines for solving partial differential equations. - * The subroutines and functions are in the solver_structure.cpp, - * solution_direct.cpp, solution_adjoint.cpp, and - * solution_linearized.cpp files. - * \author F. Palacios, T. Economon - * \version 7.0.0 "Blackbird" - * - * SU2 Project Website: https://su2code.github.io - * - * The SU2 Project is maintained by the SU2 Foundation - * (http://su2foundation.org) - * - * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) - * - * SU2 is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * SU2 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with SU2. If not, see . - */ - -#pragma once - -#include "../../Common/include/mpi_structure.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "fluid_model.hpp" -#include "task_definition.hpp" -#include "numerics_structure.hpp" -#include "sgs_model.hpp" -#include "../../Common/include/fem_geometry_structure.hpp" -#include "../../Common/include/geometry/CGeometry.hpp" -#include "../../Common/include/config_structure.hpp" -#include "../../Common/include/linear_algebra/CSysMatrix.hpp" -#include "../../Common/include/linear_algebra/CSysVector.hpp" -#include "../../Common/include/linear_algebra/CSysSolve.hpp" -#include "../../Common/include/grid_movement_structure.hpp" -#include "../../Common/include/blas_structure.hpp" -#include "../../Common/include/graph_coloring_structure.hpp" -#include "../../Common/include/toolboxes/MMS/CVerificationSolution.hpp" - -/*--- CVariable includes, ToDo: Once this file is split, one per class these includes can also be separated. ---*/ -#include "variables/CBaselineVariable.hpp" -#include "variables/CEulerVariable.hpp" -#include "variables/CIncEulerVariable.hpp" -#include "variables/CTurbVariable.hpp" -#include "variables/CAdjEulerVariable.hpp" -#include "variables/CAdjTurbVariable.hpp" -#include "variables/CHeatFVMVariable.hpp" -#include "variables/CDiscAdjVariable.hpp" -#include "variables/CDiscAdjFEABoundVariable.hpp" - -using namespace std; - -/*! - * \class CSolver - * \brief Main class for defining the PDE solution, it requires - * a child class for each particular solver (Euler, Navier-Stokes, etc.) - * \author F. Palacios - */ -class CSolver { -protected: - int rank, /*!< \brief MPI Rank. */ - size; /*!< \brief MPI Size. */ - bool adjoint; /*!< \brief Boolean to determine whether solver is initialized as a direct or an adjoint solver. */ - unsigned short MGLevel; /*!< \brief Multigrid level of this solver object. */ - unsigned short IterLinSolver; /*!< \brief Linear solver iterations. */ - su2double ResLinSolver; /*!< \brief Final linear solver residual. */ - su2double NonLinRes_Value, /*!< \brief Summed value of the nonlinear residual indicator. */ - NonLinRes_Func; /*!< \brief Current value of the nonlinear residual indicator at one iteration. */ - unsigned short NonLinRes_Counter; /*!< \brief Number of elements of the nonlinear residual indicator series. */ - vector NonLinRes_Series; /*!< \brief Vector holding the nonlinear residual indicator series. */ - su2double Old_Func, /*!< \brief Old value of the nonlinear residual indicator. */ - New_Func; /*!< \brief Current value of the nonlinear residual indicator. */ - unsigned short nVar, /*!< \brief Number of variables of the problem. */ - nPrimVar, /*!< \brief Number of primitive variables of the problem. */ - nPrimVarGrad, /*!< \brief Number of primitive variables of the problem in the gradient computation. */ - nSecondaryVar, /*!< \brief Number of primitive variables of the problem. */ - nSecondaryVarGrad, /*!< \brief Number of primitive variables of the problem in the gradient computation. */ - nVarGrad, /*!< \brief Number of variables for deallocating the LS Cvector. */ - nDim; /*!< \brief Number of dimensions of the problem. */ - unsigned long nPoint; /*!< \brief Number of points of the computational grid. */ - unsigned long nPointDomain; /*!< \brief Number of points of the computational grid. */ - su2double Max_Delta_Time, /*!< \brief Maximum value of the delta time for all the control volumes. */ - Min_Delta_Time; /*!< \brief Minimum value of the delta time for all the control volumes. */ - su2double Max_CFL_Local; /*!< \brief Maximum value of the CFL across all the control volumes. */ - su2double Min_CFL_Local; /*!< \brief Minimum value of the CFL across all the control volumes. */ - su2double Avg_CFL_Local; /*!< \brief Average value of the CFL across all the control volumes. */ - su2double *Residual_RMS, /*!< \brief Vector with the mean residual for each variable. */ - *Residual_Max, /*!< \brief Vector with the maximal residual for each variable. */ - *Residual, /*!< \brief Auxiliary nVar vector. */ - *Residual_i, /*!< \brief Auxiliary nVar vector for storing the residual at point i. */ - *Residual_j; /*!< \brief Auxiliary nVar vector for storing the residual at point j. */ - su2double *Residual_BGS, /*!< \brief Vector with the mean residual for each variable for BGS subiterations. */ - *Residual_Max_BGS; /*!< \brief Vector with the maximal residual for each variable for BGS subiterations. */ - unsigned long *Point_Max; /*!< \brief Vector with the maximal residual for each variable. */ - unsigned long *Point_Max_BGS; /*!< \brief Vector with the maximal residual for each variable. */ - su2double **Point_Max_Coord; /*!< \brief Vector with pointers to the coords of the maximal residual for each variable. */ - su2double **Point_Max_Coord_BGS; /*!< \brief Vector with pointers to the coords of the maximal residual for each variable. */ - su2double *Solution, /*!< \brief Auxiliary nVar vector. */ - *Solution_i, /*!< \brief Auxiliary nVar vector for storing the solution at point i. */ - *Solution_j; /*!< \brief Auxiliary nVar vector for storing the solution at point j. */ - su2double *Vector, /*!< \brief Auxiliary nDim vector. */ - *Vector_i, /*!< \brief Auxiliary nDim vector to do the reconstruction of the variables at point i. */ - *Vector_j; /*!< \brief Auxiliary nDim vector to do the reconstruction of the variables at point j. */ - su2double *Res_Conv, /*!< \brief Auxiliary nVar vector for storing the convective residual. */ - *Res_Visc, /*!< \brief Auxiliary nVar vector for storing the viscous residual. */ - *Res_Sour, /*!< \brief Auxiliary nVar vector for storing the viscous residual. */ - *Res_Conv_i, /*!< \brief Auxiliary vector for storing the convective residual at point i. */ - *Res_Visc_i, /*!< \brief Auxiliary vector for storing the viscous residual at point i. */ - *Res_Conv_j, /*!< \brief Auxiliary vector for storing the convective residual at point j. */ - *Res_Visc_j; /*!< \brief Auxiliary vector for storing the viscous residual at point j. */ - su2double **Jacobian_i, /*!< \brief Auxiliary matrices for storing point to point Jacobians at point i. */ - **Jacobian_j; /*!< \brief Auxiliary matrices for storing point to point Jacobians at point j. */ - su2double **Jacobian_ii, /*!< \brief Auxiliary matrices for storing point to point Jacobians. */ - **Jacobian_ij, /*!< \brief Auxiliary matrices for storing point to point Jacobians. */ - **Jacobian_ji, /*!< \brief Auxiliary matrices for storing point to point Jacobians. */ - **Jacobian_jj; /*!< \brief Auxiliary matrices for storing point to point Jacobians. */ - su2double *iPoint_UndLapl, /*!< \brief Auxiliary variable for the undivided Laplacians. */ - *jPoint_UndLapl; /*!< \brief Auxiliary variable for the undivided Laplacians. */ - su2double **Smatrix, /*!< \brief Auxiliary structure for computing gradients by least-squares */ - **Cvector; /*!< \brief Auxiliary structure for computing gradients by least-squares */ - - int *Restart_Vars; /*!< \brief Auxiliary structure for holding the number of variables and points in a restart. */ - int Restart_ExtIter; /*!< \brief Auxiliary structure for holding the external iteration offset from a restart. */ - passivedouble *Restart_Data; /*!< \brief Auxiliary structure for holding the data values from a restart. */ - unsigned short nOutputVariables; /*!< \brief Number of variables to write. */ - - unsigned long nMarker, /*!< \brief Total number of markers using the grid information. */ - *nVertex; /*!< \brief Store nVertex at each marker for deallocation */ - - bool rotate_periodic; /*!< \brief Flag that controls whether the periodic solution needs to be rotated for the solver. */ - bool implicit_periodic; /*!< \brief Flag that controls whether the implicit system should be treated by the periodic BC comms. */ - - bool dynamic_grid; /*!< \brief Flag that determines whether the grid is dynamic (moving or deforming + grid velocities). */ - - su2double ***VertexTraction; /*- Temporary, this will be moved to a new postprocessing structure once in place -*/ - su2double ***VertexTractionAdjoint; /*- Also temporary -*/ - - string SolverName; /*!< \brief Store the name of the solver for output purposes. */ - - /*! - * \brief Pure virtual function, all derived solvers MUST implement a method returning their "nodes". - * \note Don't forget to call SetBaseClassPointerToNodes() in the constructor of the derived CSolver. - * \return Nodes of the solver, upcast to their base class (CVariable). - */ - virtual CVariable* GetBaseClassPointerToNodes() = 0; - - /*! - * \brief Call this method to set "base_nodes" after the "nodes" variable of the derived solver is instantiated. - * \note One could set base_nodes directly if it were not private but that could lead to confusion - */ - inline void SetBaseClassPointerToNodes() { base_nodes = GetBaseClassPointerToNodes(); } - -private: - - /*--- Private to prevent use by derived solvers, each solver MUST have its own "nodes" member of the - most derived type possible, e.g. CEulerVariable has nodes of CEulerVariable* and not CVariable*. - This variable is to avoid two virtual functions calls per call i.e. CSolver::GetNodes() returns - directly instead of calling GetBaseClassPointerToNodes() or doing something equivalent. ---*/ - CVariable* base_nodes; /*!< \brief Pointer to CVariable to allow polymorphic access to solver nodes. */ - -public: - - CSysVector LinSysSol; /*!< \brief vector to store iterative solution of implicit linear system. */ - CSysVector LinSysRes; /*!< \brief vector to store iterative residual of implicit linear system. */ - CSysVector LinSysAux; /*!< \brief vector to store iterative residual of implicit linear system. */ -#ifndef CODI_FORWARD_TYPE - CSysMatrix Jacobian; /*!< \brief Complete sparse Jacobian structure for implicit computations. */ - CSysSolve System; /*!< \brief Linear solver/smoother. */ -#else - CSysMatrix Jacobian; - CSysSolve System; -#endif - - CSysMatrix StiffMatrix; /*!< \brief Sparse structure for storing the stiffness matrix in Galerkin computations, and grid movement. */ - - CSysVector OutputVariables; /*!< \brief vector to store the extra variables to be written. */ - string* OutputHeadingNames; /*!< \brief vector of strings to store the headings for the exra variables */ - - CVerificationSolution *VerificationSolution; /*!< \brief Verification solution class used within the solver. */ - - vector fields; - /*! - * \brief Constructor of the class. - */ - CSolver(bool mesh_deform_mode = false); - - /*! - * \brief Destructor of the class. - */ - virtual ~CSolver(void); - - /*! - * \brief Allow outside access to the nodes of the solver, containing conservatives, primitives, etc. - * \return Nodes of the solver. - */ - inline CVariable* GetNodes() { - assert(base_nodes!=nullptr && "CSolver::base_nodes was not set properly, see brief for CSolver::SetBaseClassPointerToNodes()"); - return base_nodes; - } - - /*! - * \brief Routine to load a solver quantity into the data structures for MPI point-to-point communication and to launch non-blocking sends and recvs. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] commType - Enumerated type for the quantity to be communicated. - */ - void InitiateComms(CGeometry *geometry, - CConfig *config, - unsigned short commType); - - /*! - * \brief Routine to complete the set of non-blocking communications launched by InitiateComms() and unpacking of the data in the solver class. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] commType - Enumerated type for the quantity to be unpacked. - */ - void CompleteComms(CGeometry *geometry, - CConfig *config, - unsigned short commType); - - /*! - * \brief Routine to load a solver quantity into the data structures for MPI periodic communication and to launch non-blocking sends and recvs. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] val_periodic_index - Index for the periodic marker to be treated (first in a pair). - * \param[in] commType - Enumerated type for the quantity to be communicated. - */ - void InitiatePeriodicComms(CGeometry *geometry, - CConfig *config, - unsigned short val_periodic_index, - unsigned short commType); - - /*! - * \brief Routine to complete the set of non-blocking periodic communications launched by InitiatePeriodicComms() and unpacking of the data in the solver class. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] val_periodic_index - Index for the periodic marker to be treated (first in a pair). - * \param[in] commType - Enumerated type for the quantity to be unpacked. - */ - void CompletePeriodicComms(CGeometry *geometry, - CConfig *config, - unsigned short val_periodic_index, - unsigned short commType); - - /*! - * \brief Set number of linear solver iterations. - * \param[in] val_iterlinsolver - Number of linear iterations. - */ - void SetIterLinSolver(unsigned short val_iterlinsolver); - - /*! - * \brief Set the final linear solver residual. - * \param[in] val_reslinsolver - Value of final linear solver residual. - */ - void SetResLinSolver(su2double val_reslinsolver); - - /*! - * \brief Set the value of the max residual and RMS residual. - * \param[in] val_iterlinsolver - Number of linear iterations. - */ - void SetResidual_RMS(CGeometry *geometry, CConfig *config); - - /*! - * \brief Communicate the value of the max residual and RMS residual. - * \param[in] val_iterlinsolver - Number of linear iterations. - */ - void SetResidual_BGS(CGeometry *geometry, CConfig *config); - - /*! - * \brief Set the value of the max residual and RMS residual. - * \param[in] val_iterlinsolver - Number of linear iterations. - */ - virtual void ComputeResidual_Multizone(CGeometry *geometry, CConfig *config); - - /*! - * \brief Move the mesh in time - */ - virtual void SetDualTime_Mesh(void); - - /*! - * \brief Store the BGS solution in the previous subiteration in the corresponding vector. - */ - void UpdateSolution_BGS(CGeometry *geometry, CConfig *config); - - /*! - * \brief Set the solver nondimensionalization. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - virtual void SetNondimensionalization(CConfig *config, unsigned short iMesh); - - /*! - * \brief Get information whether the initialization is an adjoint solver or not. - * \return TRUE means that it is an adjoint solver. - */ - bool GetAdjoint(void); - - /*! - * \brief Compute the pressure at the infinity. - * \return Value of the pressure at the infinity. - */ - virtual CFluidModel* GetFluidModel(void); - - /*! - * \brief Get number of linear solver iterations. - * \return Number of linear solver iterations. - */ - unsigned short GetIterLinSolver(void); - - /*! - * \brief Get the final linear solver residual. - * \return Value of final linear solver residual. - */ - inline su2double GetResLinSolver(void) { return ResLinSolver; } - - /*! - * \brief Get the value of the maximum delta time. - * \return Value of the maximum delta time. - */ - su2double GetMax_Delta_Time(void); - - /*! - * \brief Get the value of the minimum delta time. - * \return Value of the minimum delta time. - */ - su2double GetMin_Delta_Time(void); - - /*! - * \brief Get the value of the maximum delta time. - * \return Value of the maximum delta time. - */ - virtual su2double GetMax_Delta_Time(unsigned short val_Species); - - /*! - * \brief Get the value of the minimum delta time. - * \return Value of the minimum delta time. - */ - virtual su2double GetMin_Delta_Time(unsigned short val_Species); - - /*! - * \brief Get the value of the maximum local CFL number. - * \return Value of the maximum local CFL number. - */ - inline su2double GetMax_CFL_Local(void) { return Max_CFL_Local; } - - /*! - * \brief Get the value of the minimum local CFL number. - * \return Value of the minimum local CFL number. - */ - inline su2double GetMin_CFL_Local(void) { return Min_CFL_Local; } - - /*! - * \brief Get the value of the average local CFL number. - * \return Value of the average local CFL number. - */ - inline su2double GetAvg_CFL_Local(void) { return Avg_CFL_Local; } - - /*! - * \brief Get the number of variables of the problem. - */ - unsigned short GetnVar(void); - - /*! - * \brief Get the number of variables of the problem. - */ - unsigned short GetnPrimVar(void); - - /*! - * \brief Get the number of variables of the problem. - */ - unsigned short GetnPrimVarGrad(void); - - /*! - * \brief Get the number of variables of the problem. - */ - unsigned short GetnSecondaryVar(void); - - /*! - * \brief Get the number of variables of the problem. - */ - unsigned short GetnSecondaryVarGrad(void); - - /*! - * \brief Get the number of variables of the problem. - */ - unsigned short GetnOutputVariables(void); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - */ - virtual void SetResidual_DualTime(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iRKStep, unsigned short iMesh, unsigned short RunTime_EqSystem); - - /*! - * \brief Set the maximal residual, this is useful for the convergence history. - * \param[in] val_var - Index of the variable. - * \param[in] val_residual - Value of the residual to store in the position val_var. - */ - void SetRes_RMS(unsigned short val_var, su2double val_residual); - - /*! - * \brief Adds the maximal residual, this is useful for the convergence history. - * \param[in] val_var - Index of the variable. - * \param[in] val_residual - Value of the residual to store in the position val_var. - */ - void AddRes_RMS(unsigned short val_var, su2double val_residual); - - /*! - * \brief Get the maximal residual, this is useful for the convergence history. - * \param[in] val_var - Index of the variable. - * \return Value of the biggest residual for the variable in the position val_var. - */ - su2double GetRes_RMS(unsigned short val_var); - - /*! - * \brief Set the maximal residual, this is useful for the convergence history. - * \param[in] val_var - Index of the variable. - * \param[in] val_residual - Value of the residual to store in the position val_var. - */ - void SetRes_Max(unsigned short val_var, su2double val_residual, unsigned long val_point); - - /*! - * \brief Adds the maximal residual, this is useful for the convergence history. - * \param[in] val_var - Index of the variable. - * \param[in] val_residual - Value of the residual to store in the position val_var. - * \param[in] val_point - Value of the point index for the max residual. - * \param[in] val_coord - Location (x, y, z) of the max residual point. - */ - void AddRes_Max(unsigned short val_var, su2double val_residual, unsigned long val_point, su2double* val_coord); - - /*! - * \brief Adds the maximal residual, this is useful for the convergence history (overload). - * \param[in] val_var - Index of the variable. - * \param[in] val_residual - Value of the residual to store in the position val_var. - * \param[in] val_point - Value of the point index for the max residual. - * \param[in] val_coord - Location (x, y, z) of the max residual point. - */ - void AddRes_Max(unsigned short val_var, su2double val_residual, unsigned long val_point, const su2double* val_coord); - - /*! - * \brief Get the maximal residual, this is useful for the convergence history. - * \param[in] val_var - Index of the variable. - * \return Value of the biggest residual for the variable in the position val_var. - */ - su2double GetRes_Max(unsigned short val_var); - - /*! - * \brief Set the residual for BGS subiterations. - * \param[in] val_var - Index of the variable. - * \param[in] val_residual - Value of the residual to store in the position val_var. - */ - void SetRes_BGS(unsigned short val_var, su2double val_residual); - - /*! - * \brief Adds the residual for BGS subiterations. - * \param[in] val_var - Index of the variable. - * \param[in] val_residual - Value of the residual to store in the position val_var. - */ - void AddRes_BGS(unsigned short val_var, su2double val_residual); - - /*! - * \brief Get the residual for BGS subiterations. - * \param[in] val_var - Index of the variable. - * \return Value of the biggest residual for the variable in the position val_var. - */ - su2double GetRes_BGS(unsigned short val_var); - - /*! - * \brief Set the maximal residual for BGS subiterations. - * \param[in] val_var - Index of the variable. - * \param[in] val_residual - Value of the residual to store in the position val_var. - */ - void SetRes_Max_BGS(unsigned short val_var, su2double val_residual, unsigned long val_point); - - /*! - * \brief Adds the maximal residual for BGS subiterations. - * \param[in] val_var - Index of the variable. - * \param[in] val_residual - Value of the residual to store in the position val_var. - * \param[in] val_point - Value of the point index for the max residual. - * \param[in] val_coord - Location (x, y, z) of the max residual point. - */ - void AddRes_Max_BGS(unsigned short val_var, su2double val_residual, unsigned long val_point, su2double* val_coord); - - /*! - * \brief Get the maximal residual for BGS subiterations. - * \param[in] val_var - Index of the variable. - * \return Value of the biggest residual for the variable in the position val_var. - */ - su2double GetRes_Max_BGS(unsigned short val_var); - - /*! - * \brief Get the residual for FEM structural analysis. - * \param[in] val_var - Index of the variable. - * \return Value of the residual for the variable in the position val_var. - */ - virtual su2double GetRes_FEM(unsigned short val_var) const; - - /*! - * \brief Get the maximal residual, this is useful for the convergence history. - * \param[in] val_var - Index of the variable. - * \return Value of the biggest residual for the variable in the position val_var. - */ - unsigned long GetPoint_Max(unsigned short val_var); - - /*! - * \brief Get the location of the maximal residual, this is useful for the convergence history. - * \param[in] val_var - Index of the variable. - * \return Pointer to the location (x, y, z) of the biggest residual for the variable val_var. - */ - su2double* GetPoint_Max_Coord(unsigned short val_var); - - /*! - * \brief Get the maximal residual, this is useful for the convergence history. - * \param[in] val_var - Index of the variable. - * \return Value of the biggest residual for the variable in the position val_var. - */ - unsigned long GetPoint_Max_BGS(unsigned short val_var); - - /*! - * \brief Get the location of the maximal residual, this is useful for the convergence history. - * \param[in] val_var - Index of the variable. - * \return Pointer to the location (x, y, z) of the biggest residual for the variable val_var. - */ - su2double* GetPoint_Max_Coord_BGS(unsigned short val_var); - - /*! - * \brief Set the value of the RMS residual respective solution. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void SetResidual_Solution(CGeometry *geometry, CConfig *config); - - /*! - * \brief Set Value of the residual due to the Geometric Conservation Law (GCL) for steady rotating frame problems. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void SetRotatingFrame_GCL(CGeometry *geometry, CConfig *config); - - /*! - * \brief Compute the Green-Gauss gradient of the auxiliary variable. - * \param[in] geometry - Geometrical definition of the problem. - */ - void SetAuxVar_Gradient_GG(CGeometry *geometry, CConfig *config); - - /*! - * \brief Compute the Least Squares gradient of the auxiliary variable. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void SetAuxVar_Gradient_LS(CGeometry *geometry, CConfig *config); - - /*! - * \brief Compute the Least Squares gradient of an auxiliar variable on the profile surface. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void SetAuxVar_Surface_Gradient(CGeometry *geometry, CConfig *config); - - /*! - * \brief Add External to Solution vector. - */ - void Add_External_To_Solution(); - - /*! - * \brief Add the current Solution vector to External. - */ - void Add_Solution_To_External(); - - /*! - * \brief Update a given cross-term with relaxation and the running total (External). - * \param[in] config - Definition of the particular problem. - * \param[in,out] cross_term - The cross-term being updated. - */ - void Update_Cross_Term(CConfig *config, su2passivematrix &cross_term); - - /*! - * \brief Compute the Green-Gauss gradient of the solution. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] reconstruction - indicator that the gradient being computed is for upwind reconstruction. - */ - void SetSolution_Gradient_GG(CGeometry *geometry, CConfig *config, bool reconstruction = false); - - /*! - * \brief Compute the Least Squares gradient of the solution. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] reconstruction - indicator that the gradient being computed is for upwind reconstruction. - */ - void SetSolution_Gradient_LS(CGeometry *geometry, CConfig *config, bool reconstruction = false); - - /*! - * \brief Compute the Least Squares gradient of the grid velocity. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void SetGridVel_Gradient(CGeometry *geometry, CConfig *config); - - /*! - * \brief Compute slope limiter. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void SetSolution_Limiter(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - virtual void SetPrimitive_Limiter(CGeometry *geometry, CConfig *config); - - /*! - * \brief Compute the pressure laplacian using in a incompressible solver. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] PressureLaplacian - Pressure laplacian. - */ - void SetPressureLaplacian(CGeometry *geometry, CConfig *config, su2double *PressureLaplacian); - - /*! - * \brief Set the old solution variables to the current solution value for Runge-Kutta iteration. - It is a virtual function, because for the DG-FEM solver a different version is needed. - * \param[in] geometry - Geometrical definition of the problem. - */ - virtual void Set_OldSolution(CGeometry *geometry); - - /*! - * \brief Set the new solution variables to the current solution value for classical RK. - * \param[in] geometry - Geometrical definition of the problem. - */ - virtual void Set_NewSolution(CGeometry *geometry); - - /*! - * \brief Load the geometries at the previous time states n and nM1. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - virtual void Restart_OldGeometry(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] Iteration - Index of the current iteration. - */ - virtual void SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh, unsigned long Iteration); - - /*! - * \brief A virtual member. - * \param[in] config - Definition of the particular problem. - * \param[in] TimeSync - The synchronization time. - * \param[in,out] timeEvolved - On input the time evolved before the time step, - on output the time evolved after the time step. - * \param[out] syncTimeReached - Whether or not the synchronization time is reached. - */ - virtual void CheckTimeSynchronization(CConfig *config, - const su2double TimeSync, - su2double &timeEvolved, - bool &syncTimeReached); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - virtual void ProcessTaskList_DG(CGeometry *geometry, CSolver **solver_container, - CNumerics **numerics, CConfig *config, - unsigned short iMesh); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - virtual void ADER_SpaceTimeIntegration(CGeometry *geometry, CSolver **solver_container, - CNumerics **numerics, CConfig *config, - unsigned short iMesh, unsigned short RunTime_EqSystem); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - virtual void ComputeSpatialJacobian(CGeometry *geometry, CSolver **solver_container, - CNumerics **numerics, CConfig *config, - unsigned short iMesh, unsigned short RunTime_EqSystem); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - virtual void Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh); - - /*! - * \brief A virtual member, overloaded. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - virtual void Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, CNumerics **numerics, - unsigned short iMesh); - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - virtual void Centered_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh, unsigned short iRKStep); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - virtual void Upwind_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - virtual void Convective_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh, unsigned short iRKStep); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - * \param[in] Output - boolean to determine whether to print output. - */ - virtual void Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output); - - /*! - * \brief A virtual member overloaded. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Container vector of the numerics of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - * \param[in] Output - boolean to determine whether to print output. - */ - virtual void Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, CNumerics **numerics, unsigned short iMesh, unsigned long Iteration, unsigned short RunTime_EqSystem, bool Output); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - virtual void SetUndivided_Laplacian(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - virtual void Set_MPI_ActDisk(CSolver **solver_container, CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - virtual void Set_MPI_Nearfield(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - virtual void SetMax_Eigenvalue(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void SetCentered_Dissipation_Sensor(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void SetUpwind_Ducros_Sensor(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void Set_Heatflux_Areas(CGeometry *geometry, CConfig *config); - - /*! - * \author H. Kline - * \brief Compute weighted-sum "combo" objective output - * \param[in] config - Definition of the particular problem. - */ - virtual void Evaluate_ObjFunc(CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_Euler_Wall(CGeometry *geometry, - CSolver **solver_container, - CNumerics *conv_numerics, - CNumerics *visc_numerics, - CConfig *config, - unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - - virtual void BC_Clamped(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - - virtual void BC_Clamped_Post(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - - virtual void BC_DispDir(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - - virtual void BC_Normal_Displacement(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker); - - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_Normal_Load(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - - virtual void BC_Dir_Load(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - - virtual void BC_Sine_Load(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_Damper(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - - virtual void BC_Deforming(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_Interface_Boundary(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_NearField_Boundary(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - virtual void BC_Periodic(CGeometry *geometry, CSolver **solver_container, - CNumerics *numerics, CConfig *config); - - /*! - * \brief Impose the interface state across sliding meshes. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - virtual void BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_ActDisk_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_ActDisk_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_ActDisk(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker, bool val_inlet_surface); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_Isothermal_Wall(CGeometry *geometry, - CSolver **solver_container, - CNumerics *conv_numerics, - CNumerics *visc_numerics, - CConfig *config, - unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, - CNumerics *conv_numerics, - CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_Dirichlet(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_Neumann(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_Far_Field(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose via the residual the Euler boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_Sym_Plane(CGeometry *geometry, - CSolver **solver_container, - CNumerics *conv_numerics, - CNumerics *visc_numerics, - CConfig *config, - unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_Riemann(CGeometry *geometry, CSolver **solver_container, - CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_TurboRiemann(CGeometry *geometry, CSolver **solver_container, - CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief It computes Fourier transformation for the needed quantities along the pitch for each span in turbomachinery analysis. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] marker_flag - Surface marker flag where the function is applied. - */ - virtual void PreprocessBC_Giles(CGeometry *geometry, CConfig *config, CNumerics *conv_numerics, unsigned short marker_flag); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_Giles(CGeometry *geometry, CSolver **solver_container, - CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_Inlet_Turbo(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_Inlet_MixingPlane(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_Supersonic_Inlet(CGeometry *geometry, CSolver **solver_container, - CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_Supersonic_Outlet(CGeometry *geometry, CSolver **solver_container, - CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the convective numerical method. - * \param[in] visc_numerics - Description of the viscous numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_Custom(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_Engine_Inflow(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_Engine_Exhaust(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose the symmetry boundary condition using the residual. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_Dielec(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_Electrode(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - virtual void BC_ConjugateHeat_Interface(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief Get the outer state for fluid interface nodes. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - * \param[in] val_state - requested state component - */ - virtual su2double GetSlidingState(unsigned short val_marker, unsigned long val_vertex, unsigned short val_state, unsigned long donor_index); - - /*! - * \brief Allocates the final pointer of SlidingState depending on how many donor vertex donate to it. That number is stored in SlidingStateNodes[val_marker][val_vertex]. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - */ - virtual void SetSlidingStateStructure(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Set the outer state for fluid interface nodes. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - * \param[in] val_state - requested state component - * \param[in] component - set value - */ - virtual void SetSlidingState(unsigned short val_marker, unsigned long val_vertex, unsigned short val_state, unsigned long donor_index, su2double component); - - /*! - * \brief Get the number of outer states for fluid interface nodes. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - */ - virtual int GetnSlidingStates(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Set the number of outer states for fluid interface nodes. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - * \param[in] value - number of outer states - */ - virtual void SetnSlidingStates(unsigned short val_marker, unsigned long val_vertex, int value); - - /*! - * \brief Set the conjugate heat variables. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - * \param[in] pos_var - variable position (in vector of all conjugate heat variables) - * \param[in] relaxation factor - relaxation factor for the change of the variables - * \param[in] val_var - value of the variable - */ - virtual void SetConjugateHeatVariable(unsigned short val_marker, unsigned long val_vertex, unsigned short pos_var, su2double relaxation_factor, su2double val_var); - - /*! - * \brief Set the conjugate heat variables. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - * \param[in] pos_var - variable position (in vector of all conjugate heat variables) - */ - virtual su2double GetConjugateHeatVariable(unsigned short val_marker, unsigned long val_vertex, unsigned short pos_var); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - virtual void ExplicitRK_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iRKStep); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - virtual void ClassicalRK4_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iRKStep); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void ExplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] solver - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void ComputeUnderRelaxationFactor(CSolver **solver, CConfig *config); - - /*! - * \brief Adapt the CFL number based on the local under-relaxation parameters - * computed for each nonlinear iteration. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] solver_container - Container vector with all the solutions. - */ - void AdaptCFLNumber(CGeometry **geometry, CSolver ***solver_container, CConfig *config); - - /*! - * \brief Reset the local CFL adaption variables - */ - void ResetCFLAdapt(); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void ImplicitNewmark_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void ImplicitNewmark_Update(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void ImplicitNewmark_Relaxation(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void GeneralizedAlpha_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void GeneralizedAlpha_UpdateDisp(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void GeneralizedAlpha_UpdateSolution(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void GeneralizedAlpha_UpdateLoads(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - virtual void Compute_Residual(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - virtual void Pressure_Forces(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - virtual void Momentum_Forces(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void Inviscid_DeltaForces(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - virtual void Friction_Forces(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - virtual void Buffet_Monitoring(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void Heat_Fluxes(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - virtual void Viscous_DeltaForces(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - virtual void Wave_Strength(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] reconstruction - indicator that the gradient being computed is for upwind reconstruction. - */ - virtual void SetPrimitive_Gradient_GG(CGeometry *geometry, CConfig *config, bool reconstruction = false); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] reconstruction - indicator that the gradient being computed is for upwind reconstruction. - */ - virtual void SetPrimitive_Gradient_LS(CGeometry *geometry, CConfig *config, bool reconstruction = false); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - virtual void SetPrimitive_Limiter_MPI(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] iPoint - Index of the grid point. - * \param[in] config - Definition of the particular problem. - */ - virtual void SetPreconditioner(CConfig *config, unsigned long iPoint); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - virtual void Viscous_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh, unsigned short iRKStep); - - /*! - * \brief A virtual member. - * \param[in] StiffMatrix_Elem - Stiffness matrix of an element - */ - virtual void AddStiffMatrix(su2double **StiffMatrix_Elem, unsigned long Point_0, unsigned long Point_1, unsigned long Point_2, unsigned long Point_3 ); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] second_numerics - Description of the second numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - virtual void Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CNumerics *second_numerics, - CConfig *config, unsigned short iMesh); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - virtual void Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \param[in] val_sensitivity - Value of the sensitivity coefficient. - */ - virtual void SetCSensitivity(unsigned short val_marker, unsigned long val_vertex, su2double val_sensitivity); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void SetForceProj_Vector(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void SetIntBoundary_Jump(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - virtual void SetTotal_CD(su2double val_Total_CD); - - /*! - * \brief A virtual member. - * \param[in] val_Total_CL - Value of the total lift coefficient. - */ - virtual void SetTotal_CL(su2double val_Total_CL); - - /*! - * \brief A virtual member. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - virtual void SetTotal_NetThrust(su2double val_Total_NetThrust); - - /*! - * \brief A virtual member. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - virtual void SetTotal_Power(su2double val_Total_Power); - - /*! - * \brief A virtual member. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - virtual void SetTotal_SolidCD(su2double val_Total_SolidCD); - - /*! - * \brief A virtual member. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - virtual void SetTotal_ReverseFlow(su2double val_ReverseFlow); - - /*! - * \brief A virtual member. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - virtual void SetTotal_MFR(su2double val_Total_MFR); - - /*! - * \brief A virtual member. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - virtual void SetTotal_Prop_Eff(su2double val_Total_Prop_Eff); - - /*! - * \brief A virtual member. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - virtual void SetTotal_ByPassProp_Eff(su2double val_Total_ByPassProp_Eff); - - /*! - * \brief A virtual member. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - virtual void SetTotal_Adiab_Eff(su2double val_Total_Adiab_Eff); - - /*! - * \brief A virtual member. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - virtual void SetTotal_Poly_Eff(su2double val_Total_Poly_Eff); - - /*! - * \brief A virtual member. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - virtual void SetTotal_IDC(su2double val_Total_IDC); - - /*! - * \brief A virtual member. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - virtual void SetTotal_IDC_Mach(su2double val_Total_IDC_Mach); - - /*! - * \brief A virtual member. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - virtual void SetTotal_IDR(su2double val_Total_IDR); - - /*! - * \brief A virtual member. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - virtual void SetTotal_DC60(su2double val_Total_DC60); - - /*! - * \brief A virtual member. - * \param[in] val_Total_Custom_ObjFunc - Value of the total custom objective function. - * \param[in] val_weight - Value of the weight for the custom objective function. - */ - virtual void SetTotal_Custom_ObjFunc(su2double val_total_custom_objfunc, su2double val_weight); - - /*! - * \brief A virtual member. - * \param[in] val_Total_Custom_ObjFunc - Value of the total custom objective function. - * \param[in] val_weight - Value of the weight for the custom objective function. - */ - virtual void AddTotal_Custom_ObjFunc(su2double val_total_custom_objfunc, su2double val_weight); - - /*! - * \brief A virtual member. - * \param[in] val_Total_CT - Value of the total thrust coefficient. - */ - virtual void SetTotal_CT(su2double val_Total_CT); - - /*! - * \brief A virtual member. - * \param[in] val_Total_CQ - Value of the total torque coefficient. - */ - virtual void SetTotal_CQ(su2double val_Total_CQ); - - /*! - * \brief A virtual member. - * \param[in] val_Total_Heat - Value of the total heat load. - */ - virtual void SetTotal_HeatFlux(su2double val_Total_Heat); - - /*! - * \brief A virtual member. - * \param[in] val_Total_MaxHeat - Value of the total heat load. - */ - virtual void SetTotal_MaxHeatFlux(su2double val_Total_MaxHeat); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - virtual void SetDistance(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - virtual void Inviscid_Sensitivity(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - virtual void Smooth_Sensitivity(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - virtual void Viscous_Sensitivity(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the lift coefficient (inviscid contribution) on the surface val_marker. - */ - virtual su2double GetCL_Inv(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the lift coefficient (viscous contribution) on the surface val_marker. - */ - virtual su2double GetCL_Visc(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the lift coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CL(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the drag coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CD(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side force coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CSF(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side force coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CEff(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x force coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CFx(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y force coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CFy(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z force coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CFz(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x moment coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CMx(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y moment coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CMy(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z moment coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CMz(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the lift coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CL_Inv(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the drag coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CD_Inv(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side force coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CSF_Inv(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side force coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CEff_Inv(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x force coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CFx_Inv(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y force coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CFy_Inv(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z force coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CFz_Inv(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x moment coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CMx_Inv(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y moment coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CMy_Inv(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z moment coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CMz_Inv(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the lift coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CL_Visc(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the drag coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CD_Visc(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side force coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CSF_Visc(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side force coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CEff_Visc(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x force coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CFx_Visc(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y force coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CFy_Visc(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z force coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CFz_Visc(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x moment coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CMx_Visc(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y moment coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CMy_Visc(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z moment coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CMz_Visc(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the buffet metric on the surface val_marker. - */ - virtual su2double GetSurface_Buffet_Metric(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the lift coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CL_Mnt(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the drag coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CD_Mnt(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side force coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CSF_Mnt(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side force coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CEff_Mnt(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x force coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CFx_Mnt(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y force coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CFy_Mnt(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z force coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CFz_Mnt(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x moment coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CMx_Mnt(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y moment coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CMy_Mnt(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z moment coefficient on the surface val_marker. - */ - virtual su2double GetSurface_CMz_Mnt(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the lift coefficient (viscous contribution) on the surface val_marker. - */ - virtual su2double GetCSF_Visc(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the drag coefficient (inviscid contribution) on the surface val_marker. - */ - virtual su2double GetCD_Inv(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the mass flow rate on the surface val_marker. - */ - virtual su2double GetInflow_MassFlow(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solution - Container vector with all the solutions. - */ - virtual void GetPower_Properties(CGeometry *geometry, CConfig *config, unsigned short iMesh, bool Output); - - /*! - * \brief A virtual member. - */ - virtual void GetOutlet_Properties(CGeometry *geometry, CConfig *config, unsigned short iMesh, bool Output); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solution - Container vector with all the solutions. - */ - virtual void GetEllipticSpanLoad_Diff(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - current mesh level for the multigrid. - * \param[in] Output - boolean to determine whether to print output. - */ - virtual void SetFarfield_AoA(CGeometry *geometry, CSolver **solver_container, - CConfig *config, unsigned short iMesh, bool Output); - - /*! - * \brief A virtual member. - * \param[in] config - Definition of the particular problem. - * \param[in] convergence - boolean for whether the solution is converged - * \return boolean for whether the Fixed C_L mode is converged to target C_L - */ - virtual bool FixedCL_Convergence(CConfig *config, bool convergence); - - /*! - * \brief A virtual member. - * \return boolean for whether the Fixed C_L mode is currently in finite-differencing mode - */ - virtual bool GetStart_AoA_FD(void); - - /*! - * \brief A virtual member. - * \return boolean for whether the Fixed C_L mode is currently in finite-differencing mode - */ - virtual bool GetEnd_AoA_FD(void); - - /*! - * \brief A virtual member. - * \return value for the last iteration that the AoA was updated - */ - virtual unsigned long GetIter_Update_AoA(); - - /*! - * \brief A virtual member. - * \return value of the AoA before most recent update - */ - virtual su2double GetPrevious_AoA(); - - /*! - * \brief A virtual member. - * \return value of CL Driver control command (AoA_inc) - */ - virtual su2double GetAoA_inc(); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - current mesh level for the multigrid. - * \param[in] Output - boolean to determine whether to print output. - */ - virtual void SetActDisk_BCThrust(CGeometry *geometry, CSolver **solver_container, - CConfig *config, unsigned short iMesh, bool Output); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the mass flow rate on the surface val_marker. - */ - virtual su2double GetExhaust_MassFlow(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the fan face pressure on the surface val_marker. - */ - virtual su2double GetInflow_Pressure(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the fan face mach on the surface val_marker. - */ - virtual su2double GetInflow_Mach(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the sideforce coefficient (inviscid contribution) on the surface val_marker. - */ - virtual su2double GetCSF_Inv(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the efficiency coefficient (inviscid contribution) on the surface val_marker. - */ - virtual su2double GetCEff_Inv(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the heat flux is computed. - * \return Value of the integrated heat flux (viscous contribution) on the surface val_marker. - */ - virtual su2double GetSurface_HF_Visc(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the heat flux is computed. - * \return Value of the maximum heat flux (viscous contribution) on the surface val_marker. - */ - virtual su2double GetSurface_MaxHF_Visc(unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the drag coefficient (viscous contribution) on the surface val_marker. - */ - virtual su2double GetCD_Visc(unsigned short val_marker); - - /*! - * \author H. Kline - * \brief Set the total "combo" objective (weighted sum of other values). - * \param[in] ComboObj - Value of the combined objective. - */ - virtual void SetTotal_ComboObj(su2double ComboObj); - - /*! - * \author H. Kline - * \brief Provide the total "combo" objective (weighted sum of other values). - * \return Value of the "combo" objective values. - */ - virtual su2double GetTotal_ComboObj(void); - - /*! - * \brief A virtual member. - * \return Value of the sideforce coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_CSF(void); - - /*! - * \brief A virtual member. - * \return Value of the efficiency coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_CEff(void); - - /*! - * \brief A virtual member. - * \return Value of the thrust coefficient (force in the -x direction, inviscid + viscous contribution). - */ - virtual su2double GetTotal_CT(void); - - /*! - * \brief A virtual member. - * \return Value of the torque coefficient (moment in the -x direction, inviscid + viscous contribution). - */ - virtual su2double GetTotal_CQ(void); - - /*! - * \brief A virtual member. - * \return Value of the heat load (integrated heat flux). - */ - virtual su2double GetTotal_HeatFlux(void); - - /*! - * \brief A virtual member. - * \return Value of the heat load (integrated heat flux). - */ - virtual su2double GetTotal_MaxHeatFlux(void); - - /*! - * \brief A virtual member. - * \return Value of the average temperature. - */ - virtual su2double GetTotal_AvgTemperature(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - virtual su2double Get_PressureDrag(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - virtual su2double Get_ViscDrag(void); - - /*! - * \brief A virtual member. - * \return Value of the rotor Figure of Merit (FM) (inviscid + viscous contribution). - */ - virtual su2double GetTotal_CMerit(void); - - /*! - * \brief A virtual member. - * \return Value of the Equivalent Area coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_CEquivArea(void); - - /*! - * \brief A virtual member. - * \return Value of the Aero drag (inviscid + viscous contribution). - */ - virtual su2double GetTotal_AeroCD(void); - - /*! - * \brief A virtual member. - * \return Value of the difference of the presure and the target pressure. - */ - virtual su2double GetTotal_CpDiff(void); - - /*! - * \brief A virtual member. - * \return Value of the difference of the heat and the target heat. - */ - virtual su2double GetTotal_HeatFluxDiff(void); - - /*! - * \brief A virtual member. - * \return Value of the FEA coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_CFEA(void) const; - - /*! - * \brief A virtual member. - * \return Value of the Near-Field Pressure coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_CNearFieldOF(void); - - /*! - * \author H. Kline - * \brief Add to the value of the total 'combo' objective. - * \param[in] val_obj - Value of the contribution to the 'combo' objective. - */ - virtual void AddTotal_ComboObj(su2double val_obj); - - /*! - * \brief A virtual member. - * \return Value of the objective function for a reference geometry. - */ - virtual su2double GetTotal_OFRefGeom(void) const; - - /*! - * \brief A virtual member. - * \return Value of the objective function for a reference node. - */ - virtual su2double GetTotal_OFRefNode(void) const; - - /*! - * \brief A virtual member. - * \return Value of the objective function for the volume fraction. - */ - virtual su2double GetTotal_OFVolFrac(void) const; - - /*! - * \brief A virtual member. - * \return Value of the objective function for the structural compliance. - */ - virtual su2double GetTotal_OFCompliance(void) const; - - /*! - * \brief A virtual member. - * \return Bool that defines whether the solution has an element-based file or not - */ - virtual bool IsElementBased(void) const; - - /*! - * \brief A virtual member. - * \param[in] val_cequivarea - Value of the Equivalent Area coefficient. - */ - virtual void SetTotal_CEquivArea(su2double val_cequivarea); - - /*! - * \brief A virtual member. - * \param[in] val_aerocd - Value of the aero drag. - */ - virtual void SetTotal_AeroCD(su2double val_aerocd); - - /*! - * \brief A virtual member. - * \param[in] val_pressure - Value of the difference between pressure and the target pressure. - */ - virtual void SetTotal_CpDiff(su2double val_pressure); - - /*! - * \brief A virtual member. - * \param[in] val_pressure - Value of the difference between heat and the target heat. - */ - virtual void SetTotal_HeatFluxDiff(su2double val_heat); - - /*! - * \brief A virtual member. - * \param[in] val_cfea - Value of the FEA coefficient. - */ - virtual void SetTotal_CFEA(su2double val_cfea); - - /*! - * \brief A virtual member. - * \param[in] val_ofrefgeom - Value of the objective function for a reference geometry. - */ - virtual void SetTotal_OFRefGeom(su2double val_ofrefgeom); - - /*! - * \brief A virtual member. - * \param[in] val_ofrefgeom - Value of the objective function for a reference node. - */ - virtual void SetTotal_OFRefNode(su2double val_ofrefnode); - - /*! - * \brief A virtual member. - * \param[in] val_cnearfieldpress - Value of the Near-Field pressure coefficient. - */ - virtual void SetTotal_CNearFieldOF(su2double val_cnearfieldpress); - - /*! - * \brief A virtual member. - * \return Value of the lift coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_CL(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_CD(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_NetThrust(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_Power(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_SolidCD(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_ReverseFlow(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_MFR(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_Prop_Eff(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_ByPassProp_Eff(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_Adiab_Eff(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_Poly_Eff(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_IDC(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_IDC_Mach(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_IDR(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_DC60(void); - - /*! - * \brief A virtual member. - * \return Value of the custom objective function. - */ - virtual su2double GetTotal_Custom_ObjFunc(void); - - /*! - * \brief A virtual member. - * \return Value of the moment x coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_CMx(void); - - /*! - * \brief A virtual member. - * \return Value of the moment y coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_CMy(void); - - /*! - * \brief A virtual member. - * \return Value of the moment y coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_CMz(void); - - /*! - * \brief A virtual member. - * \return Value of the moment x coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_CoPx(void); - - /*! - * \brief A virtual member. - * \return Value of the moment y coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_CoPy(void); - - /*! - * \brief A virtual member. - * \return Value of the moment y coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_CoPz(void); - - /*! - * \brief A virtual member. - * \return Value of the force x coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_CFx(void); - - /*! - * \brief A virtual member. - * \return Value of the force y coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_CFy(void); - - /*! - * \brief A virtual member. - * \return Value of the force y coefficient (inviscid + viscous contribution). - */ - virtual su2double GetTotal_CFz(void); - - /*! - * \brief A virtual member. - * \return Value of the wave strength. - */ - virtual su2double GetTotal_CWave(void); - - /*! - * \brief A virtual member. - * \return Value of the wave strength. - */ - virtual su2double GetTotal_CHeat(void); - - /*! - * \brief A virtual member. - * \return Value of the lift coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CL_Inv(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CD_Inv(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CSF_Inv(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CEff_Inv(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CMx_Inv(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CMy_Inv(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CMz_Inv(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CoPx_Inv(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CoPy_Inv(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CoPz_Inv(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CFx_Inv(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CFy_Inv(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CFz_Inv(void); - - /*! - * \brief A virtual member. - * \return Value of the lift coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CL_Visc(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CD_Visc(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CSF_Visc(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CEff_Visc(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CMx_Visc(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CMy_Visc(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CMz_Visc(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CoPx_Visc(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CoPy_Visc(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CoPz_Visc(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CFx_Visc(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CFy_Visc(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CFz_Visc(void); - - /*! - * \brief A virtual member. - * \return Value of the lift coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CL_Mnt(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CD_Mnt(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CSF_Mnt(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CEff_Mnt(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CMx_Mnt(void); - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CMy_Mnt(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CMz_Mnt(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CoPx_Mnt(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CoPy_Mnt(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CoPz_Mnt(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CFx_Mnt(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CFy_Mnt(void); - - /*! - * \brief A virtual member. - * \return Value of the drag coefficient (inviscid contribution). - */ - virtual su2double GetAllBound_CFz_Mnt(void); - - /*! - * \brief A virtual member. - * \return Value of the buffet metric. - */ - virtual su2double GetTotal_Buffet_Metric(void); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - virtual su2double GetCPressure(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - virtual su2double GetCPressureTarget(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - virtual void SetCPressureTarget(unsigned short val_marker, unsigned long val_vertex, su2double val_pressure); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - - virtual void SetCharacPrimVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_var, su2double val_value); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - virtual su2double *GetDonorPrimVar(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - virtual void SetDonorPrimVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_var, su2double val_value); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - - virtual void SetDonorAdjVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_var, su2double val_value); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - virtual su2double GetDonorPrimVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_var); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - - virtual su2double *GetDonorAdjVar(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - - virtual su2double GetDonorAdjVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_var); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - virtual unsigned long GetDonorGlobalIndex(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - virtual void SetDonorGlobalIndex(unsigned short val_marker, unsigned long val_vertex, unsigned long val_index); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - virtual su2double *GetCharacPrimVar(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - virtual su2double GetActDisk_DeltaP(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - virtual void SetActDisk_DeltaP(unsigned short val_marker, unsigned long val_vertex, su2double val_deltap); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - virtual su2double GetActDisk_DeltaT(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - virtual void SetActDisk_DeltaT(unsigned short val_marker, unsigned long val_vertex, su2double val_deltat); - - /*! - * \brief A virtual member - * \param[in] val_marker - Surface marker where the total temperature is evaluated. - * \param[in] val_vertex - Vertex of the marker val_marker where the total temperature is evaluated. - * \return Value of the total temperature - */ - virtual su2double GetInlet_Ttotal(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief A virtual member - * \param[in] val_marker - Surface marker where the total pressure is evaluated. - * \param[in] val_vertex - Vertex of the marker val_marker where the total pressure is evaluated. - * \return Value of the total pressure - */ - virtual su2double GetInlet_Ptotal(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief A virtual member - * \param[in] val_marker - Surface marker where the flow direction is evaluated - * \param[in] val_vertex - Vertex of the marker val_marker where the flow direction is evaluated - * \param[in] val_dim - The component of the flow direction unit vector to be evaluated - * \return Component of a unit vector representing the flow direction. - */ - virtual su2double GetInlet_FlowDir(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim); - - /*! - * \brief A virtual member - * \param[in] val_marker - Surface marker where the total temperature is set. - * \param[in] val_vertex - Vertex of the marker val_marker where the total temperature is set. - * \param[in] val_ttotal - Value of the total temperature - */ - virtual void SetInlet_Ttotal(unsigned short val_marker, unsigned long val_vertex, su2double val_ttotal); - - /*! - * \brief A virtual member - * \param[in] val_marker - Surface marker where the total pressure is set. - * \param[in] val_vertex - Vertex of the marker val_marker where the total pressure is set. - * \param[in] val_ptotal - Value of the total pressure - */ - virtual void SetInlet_Ptotal(unsigned short val_marker, unsigned long val_vertex, su2double val_ptotal); - - /*! - * \brief A virtual member - * \param[in] val_marker - Surface marker where the flow direction is set. - * \param[in] val_vertex - Vertex of the marker val_marker where the flow direction is set. - * \param[in] val_dim - The component of the flow direction unit vector to be set - * \param[in] val_flowdir - Component of a unit vector representing the flow direction. - */ - virtual void SetInlet_FlowDir(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim, su2double val_flowdir); - - /*! - * \brief A virtual member - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \param[in] iDim - Index of the turbulence variable (i.e. k is 0 in SST) - * \param[in] val_turb_var - Value of the turbulence variable to be used. - */ - virtual void SetInlet_TurbVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim, su2double val_turb_var); - - /*! - * \brief A virtual member - * \param[in] config - Definition of the particular problem. - * \param[in] iMarker - Surface marker where the coefficient is computed. - */ - virtual void SetUniformInlet(CConfig* config, unsigned short iMarker); - - /*! - * \brief A virtual member - * \param[in] val_inlet - vector containing the inlet values for the current vertex. - * \param[in] iMarker - Surface marker where the coefficient is computed. - * \param[in] iVertex - Vertex of the marker iMarker where the inlet is being set. - */ - virtual void SetInletAtVertex(su2double *val_inlet, unsigned short iMarker, unsigned long iVertex); - - /*! - * \brief A virtual member - * \param[in] val_inlet - vector returning the inlet values for the current vertex. - * \param[in] val_inlet_point - Node index where the inlet is being set. - * \param[in] val_kind_marker - Enumerated type for the particular inlet type. - * \param[in] geometry - Geometrical definition of the problem. - * \param config - Definition of the particular problem. - * \return Value of the face area at the vertex. - */ - virtual su2double GetInletAtVertex(su2double *val_inlet, - unsigned long val_inlet_point, - unsigned short val_kind_marker, - string val_marker, - CGeometry *geometry, - CConfig *config); - - /*! - * \brief Update the multi-grid structure for the customized boundary conditions - * \param geometry_container - Geometrical definition. - * \param config - Definition of the particular problem. - */ - virtual void UpdateCustomBoundaryConditions(CGeometry **geometry_container, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the skin friction coefficient. - */ - virtual su2double GetCSkinFriction(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the heat transfer coefficient. - */ - virtual su2double GetHeatFlux(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the heat transfer coefficient. - */ - virtual su2double GetHeatFluxTarget(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - virtual void SetHeatFluxTarget(unsigned short val_marker, unsigned long val_vertex, su2double val_heat); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the buffet sensor. - */ - virtual su2double GetBuffetSensor(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the y plus. - */ - virtual su2double GetYPlus(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief A virtual member. - * \return Value of the StrainMag_Max - */ - virtual su2double GetStrainMag_Max(void); - - /*! - * \brief A virtual member. - * \return Value of the Omega_Max - */ - virtual su2double GetOmega_Max(void); - - /*! - * \brief A virtual member. - * \return Value of the StrainMag_Max - */ - virtual void SetStrainMag_Max(su2double val_strainmag_max); - - /*! - * \brief A virtual member. - * \return Value of the Omega_Max - */ - virtual void SetOmega_Max(su2double val_omega_max); - - /*! - * \brief A virtual member. - * \return Value of the adjoint density at the infinity. - */ - virtual su2double GetPsiRho_Inf(void); - - /*! - * \brief A virtual member. - * \return Value of the adjoint density at the infinity. - */ - virtual su2double* GetPsiRhos_Inf(void); - - /*! - * \brief A virtual member. - * \return Value of the adjoint energy at the infinity. - */ - virtual su2double GetPsiE_Inf(void); - - /*! - * \brief A virtual member. - * \param[in] val_dim - Index of the adjoint velocity vector. - * \return Value of the adjoint velocity vector at the infinity. - */ - virtual su2double GetPhi_Inf(unsigned short val_dim); - - /*! - * \brief A virtual member. - * \return Value of the geometrical sensitivity coefficient - * (inviscid + viscous contribution). - */ - virtual su2double GetTotal_Sens_Geo(void); - - /*! - * \brief A virtual member. - * \return Value of the Mach sensitivity coefficient - * (inviscid + viscous contribution). - */ - virtual su2double GetTotal_Sens_Mach(void); - - /*! - * \brief A virtual member. - * \return Value of the angle of attack sensitivity coefficient - * (inviscid + viscous contribution). - */ - virtual su2double GetTotal_Sens_AoA(void); - - /*! - * \brief Set the total farfield pressure sensitivity coefficient. - * \return Value of the farfield pressure sensitivity coefficient - * (inviscid + viscous contribution). - */ - virtual su2double GetTotal_Sens_Press(void); - - /*! - * \brief Set the total farfield temperature sensitivity coefficient. - * \return Value of the farfield temperature sensitivity coefficient - * (inviscid + viscous contribution). - */ - virtual su2double GetTotal_Sens_Temp(void); - - /*! - * \author H. Kline - * \brief Get the total back pressure sensitivity coefficient. - * \return Value of the back pressure sensitivity coefficient - * (inviscid + viscous contribution). - */ - virtual su2double GetTotal_Sens_BPress(void); - - /*! - * \brief A virtual member. - * \return Value of the density sensitivity. - */ - virtual su2double GetTotal_Sens_Density(void); - - /*! - * \brief A virtual member. - * \return Value of the velocity magnitude sensitivity. - */ - virtual su2double GetTotal_Sens_ModVel(void); - - /*! - * \brief A virtual member. - * \return Value of the density at the infinity. - */ - virtual su2double GetDensity_Inf(void); - - /*! - * \brief A virtual member. - * \param[in] val_var - Index of the variable for the density. - * \return Value of the density at the infinity. - */ - virtual su2double GetDensity_Inf(unsigned short val_var); - - /*! - * \brief A virtual member. - * \return Value of the velocity at the infinity. - */ - virtual su2double GetModVelocity_Inf(void); - - /*! - * \brief A virtual member. - * \return Value of the density x energy at the infinity. - */ - virtual su2double GetDensity_Energy_Inf(void); - - /*! - * \brief A virtual member. - * \return Value of the pressure at the infinity. - */ - virtual su2double GetPressure_Inf(void); - - /*! - * \brief A virtual member. - * \param[in] val_dim - Index of the adjoint velocity vector. - * \return Value of the density x velocity at the infinity. - */ - virtual su2double GetDensity_Velocity_Inf(unsigned short val_dim); - - /*! - * \brief A virtual member. - * \param[in] val_dim - Index of the velocity vector. - * \param[in] val_var - Index of the variable for the velocity. - * \return Value of the density multiply by the velocity at the infinity. - */ - virtual su2double GetDensity_Velocity_Inf(unsigned short val_dim, unsigned short val_var); - - /*! - * \brief A virtual member. - * \param[in] val_dim - Index of the velocity vector. - * \return Value of the velocity at the infinity. - */ - virtual su2double GetVelocity_Inf(unsigned short val_dim); - - /*! - * \brief A virtual member. - * \return Value of the velocity at the infinity. - */ - virtual su2double *GetVelocity_Inf(void); - - /*! - * \brief A virtual member. - * \return Value of the viscosity at the infinity. - */ - virtual su2double GetViscosity_Inf(void); - - /*! - * \brief A virtual member. - * \return Value of nu tilde at the far-field. - */ - virtual su2double GetNuTilde_Inf(void); - - /*! - * \brief A virtual member. - * \return Value of the turbulent kinetic energy. - */ - virtual su2double GetTke_Inf(void); - - /*! - * \brief A virtual member. - * \return Value of the turbulent frequency. - */ - virtual su2double GetOmega_Inf(void); - - /*! - * \brief A virtual member. - * \return Value of the sensitivity coefficient for the Young Modulus E - */ - virtual su2double GetTotal_Sens_E(unsigned short iVal); - - /*! - * \brief A virtual member. - * \return Value of the sensitivity for the Poisson's ratio Nu - */ - virtual su2double GetTotal_Sens_Nu(unsigned short iVal); - - /*! - * \brief A virtual member. - * \return Value of the structural density sensitivity - */ - virtual su2double GetTotal_Sens_Rho(unsigned short iVal); - - /*! - * \brief A virtual member. - * \return Value of the structural weight sensitivity - */ - virtual su2double GetTotal_Sens_Rho_DL(unsigned short iVal); - - /*! - * \brief A virtual member. - * \return Value of the sensitivity coefficient for the Electric Field in the region iEField - */ - virtual su2double GetTotal_Sens_EField(unsigned short iEField); - - /*! - * \brief A virtual member. - * \return Value of the sensitivity coefficient for the FEA DV in the region iDVFEA - */ - virtual su2double GetTotal_Sens_DVFEA(unsigned short iDVFEA); - - /*! - * \brief A virtual member. - * \return Value of the sensitivity coefficient for the Young Modulus E - */ - virtual su2double GetGlobal_Sens_E(unsigned short iVal); - - /*! - * \brief A virtual member. - * \return Value of the sensitivity coefficient for the Poisson's ratio Nu - */ - virtual su2double GetGlobal_Sens_Nu(unsigned short iVal); - - /*! - * \brief A virtual member. - * \return Value of the structural density sensitivity - */ - virtual su2double GetGlobal_Sens_Rho(unsigned short iVal); - - /*! - * \brief A virtual member. - * \return Value of the structural weight sensitivity - */ - virtual su2double GetGlobal_Sens_Rho_DL(unsigned short iVal); - - /*! - * \brief A virtual member. - * \return Value of the sensitivity coefficient for the Electric Field in the region iEField - */ - virtual su2double GetGlobal_Sens_EField(unsigned short iEField); - - /*! - * \brief A virtual member. - * \return Value of the sensitivity coefficient for the FEA DV in the region iDVFEA - */ - virtual su2double GetGlobal_Sens_DVFEA(unsigned short iDVFEA); - - /*! - * \brief A virtual member. - * \return Value of the Young modulus from the adjoint solver - */ - virtual su2double GetVal_Young(unsigned short iVal); - - /*! - * \brief A virtual member. - * \return Value of the Poisson's ratio from the adjoint solver - */ - virtual su2double GetVal_Poisson(unsigned short iVal); - - /*! - * \brief A virtual member. - * \return Value of the density for inertial effects, from the adjoint solver - */ - virtual su2double GetVal_Rho(unsigned short iVal); - - /*! - * \brief A virtual member. - * \return Value of the density for dead loads, from the adjoint solver - */ - virtual su2double GetVal_Rho_DL(unsigned short iVal); - - /*! - * \brief A virtual member. - * \return Number of electric field variables from the adjoint solver - */ - virtual unsigned short GetnEField(void); - - /*! - * \brief A virtual member. - * \return Number of design variables from the adjoint solver - */ - virtual unsigned short GetnDVFEA(void); - - /*! - * \brief A virtual member. - */ - virtual void ReadDV(CConfig *config); - - /*! - * \brief A virtual member. - * \return Pointer to the values of the Electric Field - */ - virtual su2double GetVal_EField(unsigned short iVal); - - /*! - * \brief A virtual member. - * \return Pointer to the values of the design variables - */ - virtual su2double GetVal_DVFEA(unsigned short iVal); - - /*! - * \brief A virtual member. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the sensitivity coefficient. - */ - virtual su2double GetCSensitivity(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief A virtual member. - * \return A pointer to an array containing a set of constants - */ - virtual su2double* GetConstants(); - - /*! - * \brief A virtual member. - * \param[in] iBGS - Number of BGS iteration. - * \param[in] val_forcecoeff_history - Value of the force coefficient. - */ - virtual void SetForceCoeff(su2double val_forcecoeff_history); - - /*! - * \brief A virtual member. - * \param[in] val_relaxcoeff_history - Value of the force coefficient. - */ - virtual void SetRelaxCoeff(su2double val_relaxcoeff_history); - - /*! - * \brief A virtual member. - * \param[in] iBGS - Number of BGS iteration. - * \param[in] val_FSI_residual - Value of the residual. - */ - virtual void SetFSI_Residual(su2double val_FSI_residual); - - /*! - * \brief A virtual member. - * \param[out] val_forcecoeff_history - Value of the force coefficient. - */ - virtual su2double GetForceCoeff() const; - - /*! - * \brief A virtual member. - * \param[out] val_relaxcoeff_history - Value of the relax coefficient. - */ - virtual su2double GetRelaxCoeff() const; - - /*! - * \brief A virtual member. - * \param[out] val_FSI_residual - Value of the residual. - */ - virtual su2double GetFSI_Residual() const; - - /*! - * \brief A virtual member. - * \param[in] solver1_geometry - Geometrical definition of the problem. - * \param[in] solver1_solution - Container vector with all the solutions. - * \param[in] solver1_config - Definition of the particular problem. - * \param[in] solver2_geometry - Geometrical definition of the problem. - * \param[in] solver2_solution - Container vector with all the solutions. - * \param[in] solver2_config - Definition of the particular problem. - */ - virtual void Copy_Zone_Solution(CSolver ***solver1_solution, - CGeometry **solver1_geometry, - CConfig *solver1_config, - CSolver ***solver2_solution, - CGeometry **solver2_geometry, - CConfig *solver2_config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] ExtIter - External iteration. - */ - virtual void SetInitialCondition(CGeometry **geometry, - CSolver ***solver_container, - CConfig *config, unsigned long ExtIter); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] ExtIter - External iteration. - */ - virtual void ResetInitialCondition(CGeometry **geometry, - CSolver ***solver_container, - CConfig *config, unsigned long ExtIter); - - /*! - * \brief A virtual member. - * \param[in] fea_geometry - Geometrical definition of the problem. - * \param[in] fea_config - Geometrical definition of the problem. - * \param[in] fea_geometry - Definition of the particular problem. - */ - virtual void PredictStruct_Displacement(CGeometry **fea_geometry, - CConfig *fea_config, - CSolver ***fea_solution); - - /*! - * \brief A virtual member. - * \param[in] fea_geometry - Geometrical definition of the problem. - * \param[in] fea_config - Geometrical definition of the problem. - * \param[in] fea_geometry - Definition of the particular problem. - */ - virtual void ComputeAitken_Coefficient(CGeometry **fea_geometry, - CConfig *fea_config, - CSolver ***fea_solution, - unsigned long iOuterIter); - - - /*! - * \brief A virtual member. - * \param[in] fea_geometry - Geometrical definition of the problem. - * \param[in] fea_config - Geometrical definition of the problem. - * \param[in] fea_geometry - Definition of the particular problem. - */ - virtual void SetAitken_Relaxation(CGeometry **fea_geometry, - CConfig *fea_config, - CSolver ***fea_solution); - - /*! - * \brief A virtual member. - * \param[in] fea_geometry - Geometrical definition of the problem. - * \param[in] fea_config - Geometrical definition of the problem. - * \param[in] fea_geometry - Definition of the particular problem. - */ - virtual void Update_StructSolution(CGeometry **fea_geometry, - CConfig *fea_config, - CSolver ***fea_solution); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - Container vector with all of the solvers. - * \param[in] config - Definition of the particular problem. - * \param[in] val_iter - Current external iteration number. - * \param[in] val_update_geo - Flag for updating coords and grid velocity. - */ - virtual void LoadRestart(CGeometry **geometry, CSolver ***solver, - CConfig *config, int val_iter, bool val_update_geo); - - /*! - * \brief Read a native SU2 restart file in ASCII format. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] val_filename - String name of the restart file. - */ - void Read_SU2_Restart_ASCII(CGeometry *geometry, CConfig *config, string val_filename); - - /*! - * \brief Read a native SU2 restart file in binary format. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] val_filename - String name of the restart file. - */ - void Read_SU2_Restart_Binary(CGeometry *geometry, CConfig *config, string val_filename); - - /*! - * \brief Read the metadata from a native SU2 restart file (ASCII or binary). - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] adjoint - Boolean to identify the restart file of an adjoint run. - * \param[in] val_filename - String name of the restart file. - */ - void Read_SU2_Restart_Metadata(CGeometry *geometry, CConfig *config, bool adjoint_run, string val_filename); - - /*! - * \brief Load a inlet profile data from file into a particular solver. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - Container vector with all of the solvers. - * \param[in] config - Definition of the particular problem. - * \param[in] val_iter - Current external iteration number. - * \param[in] val_kind_solver - Solver container position. - * \param[in] val_kind_marker - Kind of marker to apply the profiles. - */ - void LoadInletProfile(CGeometry **geometry, - CSolver ***solver, - CConfig *config, - int val_iter, - unsigned short val_kind_solver, - unsigned short val_kind_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void Compute_OFRefGeom(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void Compute_OFRefNode(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void Compute_OFVolFrac(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void Compute_OFCompliance(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - virtual void Stiffness_Penalty(CGeometry *geometry, CSolver **solver_container, CNumerics **numerics_container, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] val_iter - Current external iteration number. - */ - virtual void LoadRestart_FSI(CGeometry *geometry, CConfig *config, int val_iter); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - virtual void RefGeom_Sensitivity(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - virtual void DE_Sensitivity(CGeometry *geometry, CSolver **solver_container, CNumerics **numerics_container, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - virtual void Stiffness_Sensitivity(CGeometry *geometry, CSolver **solver_container, CNumerics **numerics_container, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] iElem - element parameter. - * \param[out] iElem_iDe - ID of the Dielectric Elastomer region. - */ - virtual unsigned short Get_iElem_iDe(unsigned long iElem) const; - - /*! - * \brief A virtual member. - * \param[in] i_DV - number of design variable. - * \param[in] val_EField - value of the design variable. - */ - virtual void Set_DV_Val(su2double val_EField, unsigned short i_DV); - - /*! - * \brief A virtual member. - * \param[in] i_DV - number of design variable. - * \param[out] DV_Val - value of the design variable. - */ - virtual su2double Get_DV_Val(unsigned short i_DV); - - /*! - * \brief A virtual member. - * \param[out] val_I - value of the objective function. - */ - virtual su2double Get_val_I(void); - - /*! - * \brief Gauss method for solving a linear system. - * \param[in] A - Matrix Ax = b. - * \param[in] rhs - Right hand side. - * \param[in] nVar - Number of variables. - */ - void Gauss_Elimination(su2double** A, su2double* rhs, unsigned short nVar); - - /*! - * \brief Prepares and solves the aeroelastic equations. - * \param[in] surface_movement - Surface movement classes of the problem. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] ExtIter - Physical iteration number. - */ - void Aeroelastic(CSurfaceMovement *surface_movement, CGeometry *geometry, CConfig *config, unsigned long TimeIter); - - /*! - * \brief Sets up the generalized eigenvectors and eigenvalues needed to solve the aeroelastic equations. - * \param[in] PHI - Matrix of the generalized eigenvectors. - * \param[in] lambda - The eigenvalues of the generalized eigensystem. - * \param[in] config - Definition of the particular problem. - */ - void SetUpTypicalSectionWingModel(vector >& PHI, vector& w, CConfig *config); - - /*! - * \brief Solve the typical section wing model. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] Cl - Coefficient of lift at particular iteration. - * \param[in] Cm - Moment coefficient about z-axis at particular iteration. - * \param[in] config - Definition of the particular problem. - * \param[in] val_Marker - Surface that is being monitored. - * \param[in] displacements - solution of typical section wing model. - */ - - void SolveTypicalSectionWingModel(CGeometry *geometry, su2double Cl, su2double Cm, CConfig *config, unsigned short val_Marker, vector& displacements); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config_container - The particular config. - */ - virtual void RegisterSolution(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config_container - The particular config. - */ - virtual void RegisterOutput(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - The geometrical definition of the problem. - * \param[in] config - The particular config. - */ - virtual void SetAdjoint_Output(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - The geometrical definition of the problem. - * \param[in] config - The particular config. - */ - virtual void SetAdjoint_OutputMesh(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - The geometrical definition of the problem. - * \param[in] solver_container - The solver container holding all solutions. - * \param[in] config - The particular config. - */ - virtual void ExtractAdjoint_Solution(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - The geometrical definition of the problem. - * \param[in] solver_container - The solver container holding all solutions. - * \param[in] config - The particular config. - */ - virtual void ExtractAdjoint_Geometry(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - The geometrical definition of the problem. - * \param[in] solver_container - The solver container holding all solutions. - * \param[in] config - The particular config. - */ - virtual void ExtractAdjoint_CrossTerm(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - The geometrical definition of the problem. - * \param[in] solver_container - The solver container holding all solutions. - * \param[in] config - The particular config. - */ - virtual void ExtractAdjoint_CrossTerm_Geometry(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - The geometrical definition of the problem. - * \param[in] solver_container - The solver container holding all solutions. - * \param[in] config - The particular config. - */ - virtual void ExtractAdjoint_CrossTerm_Geometry_Flow(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member - * \param[in] geometry - The geometrical definition of the problem. - */ - virtual void RegisterObj_Func(CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - virtual void SetSurface_Sensitivity(CGeometry *geometry, CConfig* config); - - /*! - * \brief A virtual member. Extract and set the geometrical sensitivity. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - The solver container holding all terms of the solution. - * \param[in] config - Definition of the particular problem. - */ - virtual void SetSensitivity(CGeometry *geometry, CSolver **solver, CConfig *config); - - virtual void SetAdj_ObjFunc(CGeometry *geometry, CConfig* config); - - /*! - * \brief A virtual member. - * \param[in] Set value of interest: 0 - Initial value, 1 - Current value. - */ - virtual void SetFSI_ConvValue(unsigned short val_index, su2double val_criteria); - - /*! - * \brief A virtual member. - * \param[in] Value of interest: 0 - Initial value, 1 - Current value. - * \return Values to compare - */ - virtual su2double GetFSI_ConvValue(unsigned short val_index) const; - - /*! - * \brief A virtual member. - * \param[in] CurrentTime - Current time step. - * \param[in] RampTime - Time for application of the ramp.* - * \param[in] config - Definition of the particular problem. - */ - virtual su2double Compute_LoadCoefficient(su2double CurrentTime, su2double RampTime, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - virtual void Compute_StiffMatrix(CGeometry *geometry, CNumerics **numerics, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - virtual void Compute_StiffMatrix_NodalStressRes(CGeometry *geometry, CNumerics **numerics, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - virtual void Compute_MassMatrix(CGeometry *geometry, CNumerics **numerics, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - virtual void Compute_MassRes(CGeometry *geometry, CNumerics **numerics, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - virtual void Compute_NodalStressRes(CGeometry *geometry, CNumerics **numerics, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - virtual void Compute_NodalStress(CGeometry *geometry, CNumerics **numerics, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] solver - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - virtual void Compute_DeadLoad(CGeometry *geometry, CNumerics **numerics, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void Solve_System(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \return Value of the dynamic Aitken relaxation factor - */ - virtual su2double GetWAitken_Dyn(void) const; - - /*! - * \brief A virtual member. - * \return Value of the last Aitken relaxation factor in the previous time step. - */ - virtual su2double GetWAitken_Dyn_tn1(void) const; - - /*! - * \brief A virtual member. - * \param[in] Value of the dynamic Aitken relaxation factor - */ - virtual void SetWAitken_Dyn(su2double waitk); - - /*! - * \brief A virtual member. - * \param[in] Value of the last Aitken relaxation factor in the previous time step. - */ - virtual void SetWAitken_Dyn_tn1(su2double waitk_tn1); - - /*! - * \brief A virtual member. - * \param[in] Value of the load increment for nonlinear structural analysis - */ - virtual void SetLoad_Increment(su2double val_loadIncrement); - - /*! - * \brief A virtual member. - * \param[in] Value of the load increment for nonlinear structural analysis - */ - virtual su2double GetLoad_Increment(void) const; - - /*! - * \brief A virtual member. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] Output - boolean to determine whether to print output. - */ - virtual unsigned long SetPrimitive_Variables(CSolver **solver_container, CConfig *config, bool Output); - - /*! - * \brief A virtual member. - * \param[in] Value of freestream pressure. - */ - virtual void SetPressure_Inf(su2double p_inf); - - /*! - * \brief A virtual member. - * \param[in] Value of freestream temperature. - */ - virtual void SetTemperature_Inf(su2double t_inf); - - /*! - * \brief A virtual member. - * \param[in] Value of freestream density. - */ - virtual void SetDensity_Inf(su2double rho_inf); - - /*! - * \brief A virtual member. - * \param[in] val_dim - Index of the velocity vector. - * \param[in] val_velocity - Value of the velocity. - */ - virtual void SetVelocity_Inf(unsigned short val_dim, su2double val_velocity); - - /*! - * \brief A virtual member. - * \param[in] kind_recording - Kind of AD recording. - */ - virtual void SetRecording(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] kind_recording - Kind of AD recording. - */ - virtual void SetMesh_Recording(CGeometry **geometry, CVolumetricMovement *grid_movement, - CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] reset - If true reset variables to their initial values. - */ - virtual void RegisterVariables(CGeometry *geometry, CConfig *config, bool reset = false); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - virtual void ExtractAdjoint_Variables(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] config - Definition of the particular problem. - */ - virtual void SetFreeStream_Solution(CConfig *config); - - /*! - * \brief A virtual member. - */ - virtual su2double* GetVecSolDOFs(void); - - /*! - * \brief A virtual member. - */ - virtual unsigned long GetnDOFsGlobal(void); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void SetTauWall_WF(CGeometry *geometry, CSolver** solver_container, CConfig* config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - virtual void SetNuTilde_WF(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, - CNumerics *visc_numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - virtual void InitTurboContainers(CGeometry *geometry, CConfig *config); - - /*! - * \brief virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the average is evaluated. - */ - virtual void PreprocessAverage(CSolver **solver, CGeometry *geometry, CConfig *config, unsigned short marker_flag); - - - /*! - * \brief virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the average is evaluated. - */ - virtual void TurboAverageProcess(CSolver **solver, CGeometry *geometry, CConfig *config, unsigned short marker_flag); - - /*! - * \brief virtual member. - * \param[in] config - Definition of the particular problem. - * \param[in] geometry - Geometrical definition of the problem. - */ - virtual void GatherInOutAverageValues(CConfig *config, CGeometry *geometry); - - /*! - * \brief A virtual member. - * \param[in] val_marker - bound marker. - * \return Value of the Average Density on the surface val_marker. - */ - virtual su2double GetAverageDensity(unsigned short valMarker, unsigned short iSpan); - - /*! - * \brief A virtual member. - * \param[in] val_marker - bound marker. - * \return Value of the Average Pressure on the surface val_marker. - */ - virtual su2double GetAveragePressure(unsigned short valMarker, unsigned short iSpan); - - /*! - * \brief A virtual member. - * \param[in] val_marker - bound marker. - * \return Value of the Average Total Pressure on the surface val_marker. - */ - virtual su2double* GetAverageTurboVelocity(unsigned short valMarker, unsigned short iSpan); - - /*! - * \brief A virtual member. - * \param[in] val_marker - bound marker. - * \return Value of the Average Nu on the surface val_marker. - */ - virtual su2double GetAverageNu(unsigned short valMarker, unsigned short iSpan); - - /*! - * \brief A virtual member. - * \param[in] val_marker - bound marker. - * \return Value of the Average Kine on the surface val_marker. - */ - virtual su2double GetAverageKine(unsigned short valMarker, unsigned short iSpan); - - /*! - * \brief A virtual member. - * \param[in] val_marker - bound marker. - * \return Value of the Average Omega on the surface val_marker. - */ - virtual su2double GetAverageOmega(unsigned short valMarker, unsigned short iSpan); - - /*! - * \brief A virtual member. - * \param[in] val_marker - bound marker. - * \return Value of the Average Nu on the surface val_marker. - */ - virtual su2double GetExtAverageNu(unsigned short valMarker, unsigned short iSpan); - - /*! - * \brief A virtual member. - * \param[in] val_marker - bound marker. - * \return Value of the Average Kine on the surface val_marker. - */ - virtual su2double GetExtAverageKine(unsigned short valMarker, unsigned short iSpan); - - /*! - * \brief A virtual member. - * \param[in] val_marker - bound marker. - * \return Value of the Average Omega on the surface val_marker. - */ - virtual su2double GetExtAverageOmega(unsigned short valMarker, unsigned short iSpan); - - - /*! - * \brief A virtual member. - * \param[in] val_marker - bound marker. - * \return Value of the Average Density on the surface val_marker. - */ - virtual void SetExtAverageDensity(unsigned short valMarker, unsigned short valSpan, su2double valDensity); - - /*! - * \brief A virtual member. - * \param[in] val_marker - bound marker. - * \return Value of the Average Pressure on the surface val_marker. - */ - virtual void SetExtAveragePressure(unsigned short valMarker, unsigned short valSpan, su2double valPressure); - - /*! - * \brief A virtual member. - * \param[in] val_marker - bound marker. - * \return Value of the Average Total Pressure on the surface val_marker. - */ - virtual void SetExtAverageTurboVelocity(unsigned short valMarker, unsigned short valSpan, unsigned short valIndex, su2double valTurboVelocity); - - /*! - * \brief A virtual member. - * \param[in] val_marker - bound marker. - * \return Value of the Average Nu on the surface val_marker. - */ - virtual void SetExtAverageNu(unsigned short valMarker, unsigned short valSpan, su2double valNu); - - /*! - * \brief A virtual member. - * \param[in] val_marker - bound marker. - * \return Value of the Average Kine on the surface val_marker. - */ - virtual void SetExtAverageKine(unsigned short valMarker, unsigned short valSpan, su2double valKine); - - /*! - * \brief A virtual member. - * \param[in] val_marker - bound marker. - * \return Value of the Average Omega on the surface val_marker. - */ - virtual void SetExtAverageOmega(unsigned short valMarker, unsigned short valSpan, su2double valOmega); - - /*! - * \brief A virtual member. - * \param[in] inMarkerTP - bound marker. - * \return Value of the inlet density. - */ - virtual su2double GetDensityIn(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] inMarkerTP - bound marker. - * \return Value of inlet pressure. - */ - virtual su2double GetPressureIn(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] inMarkerTP - bound marker. - * \return Value of the inlet normal velocity. - */ - virtual su2double* GetTurboVelocityIn(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] inMarkerTP - bound marker. - * \return Value of the outlet density. - */ - virtual su2double GetDensityOut(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] inMarkerTP - bound marker. - * \return Value of the outlet pressure. - */ - virtual su2double GetPressureOut(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] inMarkerTP - bound marker. - * \return Value of the outlet normal velocity. - */ - virtual su2double* GetTurboVelocityOut(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] inMarkerTP - bound marker. - * \return Value of the inlet density. - */ - virtual su2double GetKineIn(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] inMarkerTP - bound marker. - * \return Value of the inlet density. - */ - virtual su2double GetOmegaIn(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] inMarkerTP - bound marker. - * \return Value of the inlet density. - */ - virtual su2double GetNuIn(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] inMarkerTP - bound marker. - * \return Value of the inlet density. - */ - virtual su2double GetKineOut(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] inMarkerTP - bound marker. - * \return Value of the inlet density. - */ - virtual su2double GetOmegaOut(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] inMarkerTP - bound marker. - * \return Value of the inlet density. - */ - virtual su2double GetNuOut(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - virtual void SetDensityIn(su2double value, unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - virtual void SetPressureIn(su2double value, unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - virtual void SetTurboVelocityIn(su2double* value, unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - virtual void SetDensityOut(su2double value, unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - virtual void SetPressureOut(su2double value, unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - virtual void SetTurboVelocityOut(su2double* value, unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - virtual void SetKineIn(su2double value, unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - virtual void SetOmegaIn(su2double value, unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - virtual void SetNuIn(su2double value, unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - virtual void SetKineOut(su2double value, unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - virtual void SetOmegaOut(su2double value, unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - virtual void SetNuOut(su2double value, unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief A virtual member. - * \param[in] config - Definition of the particular problem. - */ - virtual void SetFreeStream_TurboSolution(CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - current mesh level for the multigrid. - */ - virtual void SetBeta_Parameter(CGeometry *geometry, CSolver **solver_container, - CConfig *config, unsigned short iMesh); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition. - * \param[in] config - Definition of the particular problem. - */ - virtual void SetRoe_Dissipation(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] solver - Solver container - * \param[in] geometry - Geometrical definition. - * \param[in] config - Definition of the particular problem. - */ - virtual void SetDES_LengthScale(CSolver** solver, CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition. - * \param[in] config - Definition of the particular problem. - * \param[in] referenceCoord - Determine if the mesh is deformed from the reference or from the current coordinates. - */ - virtual void DeformMesh(CGeometry **geometry, CNumerics **numerics, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition. - * \param[in] config - Definition of the particular problem. - * \param[in] referenceCoord - Determine if the mesh is deformed from the reference or from the current coordinates. - */ - virtual void SetMesh_Stiffness(CGeometry **geometry, CNumerics **numerics, CConfig *config); - - /*! - * \brief Routine that sets the flag controlling implicit treatment for periodic BCs. - * \param[in] val_implicit_periodic - Flag controlling implicit treatment for periodic BCs. - */ - void SetImplicitPeriodic(bool val_implicit_periodic); - - /*! - * \brief Routine that sets the flag controlling solution rotation for periodic BCs. - * \param[in] val_implicit_periodic - Flag controlling solution rotation for periodic BCs. - */ - void SetRotatePeriodic(bool val_rotate_periodic); - - /*! - * \brief Retrieve the solver name for output purposes. - * \param[out] val_solvername - Name of the solver. - */ - string GetSolverName(void); - - /*! - * \brief Get the solution fields. - * \return A vector containing the solution fields. - */ - vector GetSolutionFields(); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition. - * \param[in] config - Definition of the particular problem. - */ - virtual void ComputeVerificationError(CGeometry *geometry, CConfig *config); - - /*! - * \brief Initialize the vertex traction containers at the vertices. - * \param[in] geometry - Geometrical definition. - * \param[in] config - Definition of the particular problem. - */ - - inline void InitVertexTractionContainer(CGeometry *geometry, CConfig *config){ - - unsigned long iVertex; - unsigned short iMarker; - - VertexTraction = new su2double** [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - VertexTraction[iMarker] = new su2double* [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - VertexTraction[iMarker][iVertex] = new su2double [nDim](); - } - } - } - - /*! - * \brief Initialize the adjoint vertex traction containers at the vertices. - * \param[in] geometry - Geometrical definition. - * \param[in] config - Definition of the particular problem. - */ - - inline void InitVertexTractionAdjointContainer(CGeometry *geometry, CConfig *config){ - - unsigned long iVertex; - unsigned short iMarker; - - VertexTractionAdjoint = new su2double** [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - VertexTractionAdjoint[iMarker] = new su2double* [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - VertexTractionAdjoint[iMarker][iVertex] = new su2double [nDim](); - } - } - } - - /*! - * \brief Compute the tractions at the vertices. - * \param[in] geometry - Geometrical definition. - * \param[in] config - Definition of the particular problem. - */ - void ComputeVertexTractions(CGeometry *geometry, CConfig *config); - - /*! - * \brief Set the adjoints of the vertex tractions. - * \param[in] iMarker - Index of the marker - * \param[in] iVertex - Index of the relevant vertex - * \param[in] iDim - Dimension - */ - inline su2double GetVertexTractions(unsigned short iMarker, unsigned long iVertex, - unsigned short iDim){ return VertexTraction[iMarker][iVertex][iDim]; } - - /*! - * \brief Register the vertex tractions as output. - * \param[in] geometry - Geometrical definition. - * \param[in] config - Definition of the particular problem. - */ - void RegisterVertexTractions(CGeometry *geometry, CConfig *config); - - /*! - * \brief Store the adjoints of the vertex tractions. - * \param[in] iMarker - Index of the marker - * \param[in] iVertex - Index of the relevant vertex - * \param[in] iDim - Dimension - * \param[in] val_adjoint - Value received for the adjoint (from another solver) - */ - inline void StoreVertexTractionsAdjoint(unsigned short iMarker, unsigned long iVertex, - unsigned short iDim, su2double val_adjoint){ - VertexTractionAdjoint[iMarker][iVertex][iDim] = val_adjoint; - } - - /*! - * \brief Set the adjoints of the vertex tractions to the AD structure. - * \param[in] geometry - Geometrical definition. - * \param[in] config - Definition of the particular problem. - */ - void SetVertexTractionsAdjoint(CGeometry *geometry, CConfig *config); - - /*! - * \brief Get minimun volume in the mesh - * \return - */ - virtual su2double GetMinimum_Volume() const { return 0.0; } - - /*! - * \brief Get maximum volume in the mesh - * \return - */ - virtual su2double GetMaximum_Volume() const { return 0.0; } - -protected: - /*! - * \brief Allocate the memory for the verification solution, if necessary. - * \param[in] nDim - Number of dimensions of the problem. - * \param[in] nVar - Number of variables of the problem. - * \param[in] config - Definition of the particular problem. - */ - void SetVerificationSolution(unsigned short nDim, - unsigned short nVar, - CConfig *config); -}; - -/*! - * \class CBaselineSolver - * \brief Main class for defining a baseline solution from a restart file (for output). - * \author F. Palacios, T. Economon. - */ -class CBaselineSolver final : public CSolver { -protected: - - CBaselineVariable* nodes = nullptr; /*!< \brief Variables of the baseline solver. */ - - /*! - * \brief Return nodes to allow CSolver::base_nodes to be set. - */ - inline CVariable* GetBaseClassPointerToNodes() override { return nodes; } - -public: - - /*! - * \brief Constructor of the class. - */ - CBaselineSolver(void); - - /*! - * \overload - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - CBaselineSolver(CGeometry *geometry, CConfig *config); - - /*! - * \overload - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] nVar - Number of variables. - * \param[in] field_names - Vector of variable names. - */ - CBaselineSolver(CGeometry *geometry, CConfig *config, unsigned short val_nvar, vector field_names); - - /*! - * \brief Destructor of the class. - */ - virtual ~CBaselineSolver(void); - - /*! - * \brief Load a solution from a restart file. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - Container vector with all of the solvers. - * \param[in] config - Definition of the particular problem. - * \param[in] val_iter - Current external iteration number. - * \param[in] val_update_geo - Flag for updating coords and grid velocity. - */ - void LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo); - - /*! - * \brief Load a FSI solution from a restart file. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - Container vector with all of the solvers. - * \param[in] config - Definition of the particular problem. - * \param[in] val_iter - Current external iteration number. - */ - void LoadRestart_FSI(CGeometry *geometry, CConfig *config, int val_iter); - - /*! - * \brief Set the number of variables and string names from the restart file. - * \param[in] config - Definition of the particular problem. - */ - void SetOutputVariables(CGeometry *geometry, CConfig *config); - -}; - -/*! - * \class CBaselineSolver_FEM - * \brief Main class for defining a baseline solution from a restart file for the DG-FEM solver output. - * \author T. Economon. - * \version 7.0.0 "Blackbird" - */ -class CBaselineSolver_FEM : public CSolver { -protected: - - unsigned long nDOFsLocTot; /*!< \brief Total number of local DOFs, including halos. */ - unsigned long nDOFsLocOwned; /*!< \brief Number of owned local DOFs. */ - unsigned long nDOFsGlobal; /*!< \brief Number of global DOFs. */ - - unsigned long nVolElemTot; /*!< \brief Total number of local volume elements, including halos. */ - unsigned long nVolElemOwned; /*!< \brief Number of owned local volume elements. */ - CVolumeElementFEM *volElem; /*!< \brief Array of the local volume elements, including halos. */ - - vector VecSolDOFs; /*!< \brief Vector, which stores the solution variables in all the DOFs. */ - - CVariable* GetBaseClassPointerToNodes() {return nullptr;} - -public: - - /*! - * \brief Constructor of the class. - */ - CBaselineSolver_FEM(void); - - /*! - * \overload - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - CBaselineSolver_FEM(CGeometry *geometry, CConfig *config); - - /*! - * \brief Destructor of the class. - */ - virtual ~CBaselineSolver_FEM(void); - - /*! - * \brief Set the number of variables and string names from the restart file. - * \param[in] config - Definition of the particular problem. - */ - void SetOutputVariables(CGeometry *geometry, CConfig *config); - - /*! - * \brief Load a solution from a restart file. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - Container vector with all of the solvers. - * \param[in] config - Definition of the particular problem. - * \param[in] val_iter - Current external iteration number. - * \param[in] val_update_geo - Flag for updating coords and grid velocity. - */ - void LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo); - - /*! - * \brief Get a pointer to the vector of the solution degrees of freedom. - * \return Pointer to the vector of the solution degrees of freedom. - */ - su2double* GetVecSolDOFs(void); - -}; - -/*! - * \class CEulerSolver - * \brief Main class for defining the Euler's flow solver. - * \ingroup Euler_Equations - * \author F. Palacios - */ -class CEulerSolver : public CSolver { -protected: - - su2double - Mach_Inf, /*!< \brief Mach number at the infinity. */ - Density_Inf, /*!< \brief Density at the infinity. */ - Energy_Inf, /*!< \brief Energy at the infinity. */ - Temperature_Inf, /*!< \brief Energy at the infinity. */ - Pressure_Inf, /*!< \brief Pressure at the infinity. */ - *Velocity_Inf; /*!< \brief Flow Velocity vector at the infinity. */ - - su2double - *CD_Inv, /*!< \brief Drag coefficient (inviscid contribution) for each boundary. */ - *CL_Inv, /*!< \brief Lift coefficient (inviscid contribution) for each boundary. */ - *CSF_Inv, /*!< \brief Sideforce coefficient (inviscid contribution) for each boundary. */ - *CMx_Inv, /*!< \brief x Moment coefficient (inviscid contribution) for each boundary. */ - *CMy_Inv, /*!< \brief y Moment coefficient (inviscid contribution) for each boundary. */ - *CMz_Inv, /*!< \brief z Moment coefficient (inviscid contribution) for each boundary. */ - *CoPx_Inv, /*!< \brief x Moment coefficient (inviscid contribution) for each boundary. */ - *CoPy_Inv, /*!< \brief y Moment coefficient (inviscid contribution) for each boundary. */ - *CoPz_Inv, /*!< \brief z Moment coefficient (inviscid contribution) for each boundary. */ - *CFx_Inv, /*!< \brief x Force coefficient (inviscid contribution) for each boundary. */ - *CFy_Inv, /*!< \brief y Force coefficient (inviscid contribution) for each boundary. */ - *CFz_Inv, /*!< \brief z Force coefficient (inviscid contribution) for each boundary. */ - *Surface_CL_Inv, /*!< \brief Lift coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CD_Inv, /*!< \brief Drag coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CSF_Inv, /*!< \brief Side-force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CEff_Inv, /*!< \brief Side-force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CFx_Inv, /*!< \brief x Force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CFy_Inv, /*!< \brief y Force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CFz_Inv, /*!< \brief z Force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CMx_Inv, /*!< \brief x Moment coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CMy_Inv, /*!< \brief y Moment coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CMz_Inv, /*!< \brief z Moment coefficient (inviscid contribution) for each monitoring surface. */ - *CEff_Inv, /*!< \brief Efficiency (Cl/Cd) (inviscid contribution) for each boundary. */ - *CMerit_Inv, /*!< \brief Rotor Figure of Merit (inviscid contribution) for each boundary. */ - *CT_Inv, /*!< \brief Thrust coefficient (force in -x direction, inviscid contribution) for each boundary. */ - *CQ_Inv, /*!< \brief Torque coefficient (moment in -x direction, inviscid contribution) for each boundary. */ - *CEquivArea_Inv, /*!< \brief Equivalent area (inviscid contribution) for each boundary. */ - *CNearFieldOF_Inv, /*!< \brief Near field pressure (inviscid contribution) for each boundary. */ - *CD_Mnt, /*!< \brief Drag coefficient (inviscid contribution) for each boundary. */ - *CL_Mnt, /*!< \brief Lift coefficient (inviscid contribution) for each boundary. */ - *CSF_Mnt, /*!< \brief Sideforce coefficient (inviscid contribution) for each boundary. */ - *CMx_Mnt, /*!< \brief x Moment coefficient (inviscid contribution) for each boundary. */ - *CMy_Mnt, /*!< \brief y Moment coefficient (inviscid contribution) for each boundary. */ - *CMz_Mnt, /*!< \brief z Moment coefficient (inviscid contribution) for each boundary. */ - *CoPx_Mnt, /*!< \brief x Moment coefficient (inviscid contribution) for each boundary. */ - *CoPy_Mnt, /*!< \brief y Moment coefficient (inviscid contribution) for each boundary. */ - *CoPz_Mnt, /*!< \brief z Moment coefficient (inviscid contribution) for each boundary. */ - *CFx_Mnt, /*!< \brief x Force coefficient (inviscid contribution) for each boundary. */ - *CFy_Mnt, /*!< \brief y Force coefficient (inviscid contribution) for each boundary. */ - *CFz_Mnt, /*!< \brief z Force coefficient (inviscid contribution) for each boundary. */ - *Surface_CL_Mnt, /*!< \brief Lift coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CD_Mnt, /*!< \brief Drag coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CSF_Mnt, /*!< \brief Side-force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CEff_Mnt, /*!< \brief Side-force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CFx_Mnt, /*!< \brief x Force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CFy_Mnt, /*!< \brief y Force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CFz_Mnt, /*!< \brief z Force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CMx_Mnt, /*!< \brief x Moment coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CMy_Mnt, /*!< \brief y Moment coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CMz_Mnt, /*!< \brief z Moment coefficient (inviscid contribution) for each monitoring surface. */ - *CEff_Mnt, /*!< \brief Efficiency (Cl/Cd) (inviscid contribution) for each boundary. */ - *CMerit_Mnt, /*!< \brief Rotor Figure of Merit (inviscid contribution) for each boundary. */ - *CT_Mnt, /*!< \brief Thrust coefficient (force in -x direction, inviscid contribution) for each boundary. */ - *CQ_Mnt, /*!< \brief Torque coefficient (moment in -x direction, inviscid contribution) for each boundary. */ - *CEquivArea_Mnt, /*!< \brief Equivalent area (inviscid contribution) for each boundary. */ - **CPressure, /*!< \brief Pressure coefficient for each boundary and vertex. */ - **CPressureTarget, /*!< \brief Target Pressure coefficient for each boundary and vertex. */ - **HeatFlux, /*!< \brief Heat transfer coefficient for each boundary and vertex. */ - **HeatFluxTarget, /*!< \brief Heat transfer coefficient for each boundary and vertex. */ - **YPlus, /*!< \brief Yplus for each boundary and vertex. */ - ***CharacPrimVar, /*!< \brief Value of the characteristic variables at each boundary. */ - ***DonorPrimVar, /*!< \brief Value of the donor variables at each boundary. */ - *ForceInviscid, /*!< \brief Inviscid force for each boundary. */ - *MomentInviscid, /*!< \brief Inviscid moment for each boundary. */ - *ForceMomentum, /*!< \brief Inviscid force for each boundary. */ - *MomentMomentum; /*!< \brief Inviscid moment for each boundary. */ - su2double - *Inflow_MassFlow, /*!< \brief Mass flow rate for each boundary. */ - *Exhaust_MassFlow, /*!< \brief Mass flow rate for each boundary. */ - *Inflow_Pressure, /*!< \brief Fan face pressure for each boundary. */ - *Inflow_Mach, /*!< \brief Fan face mach number for each boundary. */ - *Inflow_Area, /*!< \brief Boundary total area. */ - *Exhaust_Area, /*!< \brief Boundary total area. */ - *Exhaust_Pressure, /*!< \brief Fan face pressure for each boundary. */ - *Exhaust_Temperature, /*!< \brief Fan face mach number for each boundary. */ - Inflow_MassFlow_Total, /*!< \brief Mass flow rate for each boundary. */ - Exhaust_MassFlow_Total, /*!< \brief Mass flow rate for each boundary. */ - Inflow_Pressure_Total, /*!< \brief Fan face pressure for each boundary. */ - Inflow_Mach_Total, /*!< \brief Fan face mach number for each boundary. */ - InverseDesign; /*!< \brief Inverse design functional for each boundary. */ - unsigned long - **DonorGlobalIndex; /*!< \brief Value of the donor global index. */ - su2double - **ActDisk_DeltaP, /*!< \brief Value of the Delta P. */ - **ActDisk_DeltaT; /*!< \brief Value of the Delta T. */ - su2double - **Inlet_Ptotal, /*!< \brief Value of the Total P. */ - **Inlet_Ttotal, /*!< \brief Value of the Total T. */ - ***Inlet_FlowDir; /*!< \brief Value of the Flow Direction. */ - - su2double - AllBound_CD_Inv, /*!< \brief Total drag coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CL_Inv, /*!< \brief Total lift coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CSF_Inv, /*!< \brief Total sideforce coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMx_Inv, /*!< \brief Total x moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMy_Inv, /*!< \brief Total y moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMz_Inv, /*!< \brief Total z moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CoPx_Inv, /*!< \brief Total x moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CoPy_Inv, /*!< \brief Total y moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CoPz_Inv, /*!< \brief Total z moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CFx_Inv, /*!< \brief Total x force coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CFy_Inv, /*!< \brief Total y force coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CFz_Inv, /*!< \brief Total z force coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CEff_Inv, /*!< \brief Efficient coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMerit_Inv, /*!< \brief Rotor Figure of Merit (inviscid contribution) for all the boundaries. */ - AllBound_CT_Inv, /*!< \brief Total thrust coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CQ_Inv, /*!< \brief Total torque coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CEquivArea_Inv, /*!< \brief equivalent area coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CNearFieldOF_Inv; /*!< \brief Near-Field press coefficient (inviscid contribution) for all the boundaries. */ - - su2double - AllBound_CD_Mnt, /*!< \brief Total drag coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CL_Mnt, /*!< \brief Total lift coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CSF_Mnt, /*!< \brief Total sideforce coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMx_Mnt, /*!< \brief Total x moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMy_Mnt, /*!< \brief Total y moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMz_Mnt, /*!< \brief Total z moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CoPx_Mnt, /*!< \brief Total x moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CoPy_Mnt, /*!< \brief Total y moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CoPz_Mnt, /*!< \brief Total z moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CFx_Mnt, /*!< \brief Total x force coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CFy_Mnt, /*!< \brief Total y force coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CFz_Mnt, /*!< \brief Total z force coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CEff_Mnt, /*!< \brief Efficient coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMerit_Mnt, /*!< \brief Rotor Figure of Merit (inviscid contribution) for all the boundaries. */ - AllBound_CT_Mnt, /*!< \brief Total thrust coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CQ_Mnt; /*!< \brief Total torque coefficient (inviscid contribution) for all the boundaries. */ - - su2double - Total_ComboObj, /*!< \brief Total 'combo' objective for all monitored boundaries */ - Total_CD, /*!< \brief Total drag coefficient for all the boundaries. */ - Total_CL, /*!< \brief Total lift coefficient for all the boundaries. */ - Total_CL_Prev, /*!< \brief Total lift coefficient for all the boundaries (fixed lift mode). */ - Total_SolidCD, /*!< \brief Total drag coefficient for all the boundaries. */ - Total_CD_Prev, /*!< \brief Total drag coefficient for all the boundaries (fixed lift mode). */ - Total_NetThrust, /*!< \brief Total drag coefficient for all the boundaries. */ - Total_Power, /*!< \brief Total drag coefficient for all the boundaries. */ - Total_ReverseFlow, /*!< \brief Total drag coefficient for all the boundaries. */ - Total_IDC, /*!< \brief Total IDC coefficient for all the boundaries. */ - Total_IDC_Mach, /*!< \brief Total IDC coefficient for all the boundaries. */ - Total_IDR, /*!< \brief Total IDC coefficient for all the boundaries. */ - Total_DC60, /*!< \brief Total IDC coefficient for all the boundaries. */ - Total_MFR, /*!< \brief Total Mass Flow Ratio for all the boundaries. */ - Total_Prop_Eff, /*!< \brief Total Mass Flow Ratio for all the boundaries. */ - Total_ByPassProp_Eff, /*!< \brief Total Mass Flow Ratio for all the boundaries. */ - Total_Adiab_Eff, /*!< \brief Total Mass Flow Ratio for all the boundaries. */ - Total_Poly_Eff, /*!< \brief Total Mass Flow Ratio for all the boundaries. */ - Total_Custom_ObjFunc, /*!< \brief Total custom objective function for all the boundaries. */ - Total_CSF, /*!< \brief Total sideforce coefficient for all the boundaries. */ - Total_CMx, /*!< \brief Total x moment coefficient for all the boundaries. */ - Total_CMx_Prev, /*!< \brief Total drag coefficient for all the boundaries (fixed lift mode). */ - Total_CMy, /*!< \brief Total y moment coefficient for all the boundaries. */ - Total_CMy_Prev, /*!< \brief Total drag coefficient for all the boundaries (fixed lift mode). */ - Total_CMz, /*!< \brief Total z moment coefficient for all the boundaries. */ - Total_CMz_Prev, /*!< \brief Total drag coefficient for all the boundaries (fixed lift mode). */ - Total_CoPx, /*!< \brief Total x moment coefficient for all the boundaries. */ - Total_CoPy, /*!< \brief Total y moment coefficient for all the boundaries. */ - Total_CoPz, /*!< \brief Total z moment coefficient for all the boundaries. */ - Total_CFx, /*!< \brief Total x force coefficient for all the boundaries. */ - Total_CFy, /*!< \brief Total y force coefficient for all the boundaries. */ - Total_CFz, /*!< \brief Total z force coefficient for all the boundaries. */ - Total_CEff, /*!< \brief Total efficiency coefficient for all the boundaries. */ - Total_CMerit, /*!< \brief Total rotor Figure of Merit for all the boundaries. */ - Total_CT, /*!< \brief Total thrust coefficient for all the boundaries. */ - Total_CQ, /*!< \brief Total torque coefficient for all the boundaries. */ - Total_Heat, /*!< \brief Total heat load for all the boundaries. */ - Total_MaxHeat, /*!< \brief Maximum heat flux on all boundaries. */ - Total_AeroCD, /*!< \brief Total aero drag coefficient for all the boundaries. */ - Total_CEquivArea, /*!< \brief Total Equivalent Area coefficient for all the boundaries. */ - Total_CNearFieldOF, /*!< \brief Total Near-Field Pressure coefficient for all the boundaries. */ - Total_CpDiff, /*!< \brief Total Equivalent Area coefficient for all the boundaries. */ - Total_HeatFluxDiff, /*!< \brief Total Equivalent Area coefficient for all the boundaries. */ - Total_MassFlowRate; /*!< \brief Total Mass Flow Rate on monitored boundaries. */ - su2double - *Surface_CL, /*!< \brief Lift coefficient for each monitoring surface. */ - *Surface_CD, /*!< \brief Drag coefficient for each monitoring surface. */ - *Surface_CSF, /*!< \brief Side-force coefficient for each monitoring surface. */ - *Surface_CEff, /*!< \brief Side-force coefficient for each monitoring surface. */ - *Surface_CFx, /*!< \brief x Force coefficient for each monitoring surface. */ - *Surface_CFy, /*!< \brief y Force coefficient for each monitoring surface. */ - *Surface_CFz, /*!< \brief z Force coefficient for each monitoring surface. */ - *Surface_CMx, /*!< \brief x Moment coefficient for each monitoring surface. */ - *Surface_CMy, /*!< \brief y Moment coefficient for each monitoring surface. */ - *Surface_CMz, /*!< \brief z Moment coefficient for each monitoring surface. */ - *Surface_HF_Visc, /*!< \brief Total (integrated) heat flux for each monitored surface. */ - *Surface_MaxHF_Visc; /*!< \brief Maximum heat flux for each monitored surface. */ - - su2double - *SecondaryVar_i, /*!< \brief Auxiliary vector for storing the solution at point i. */ - *SecondaryVar_j; /*!< \brief Auxiliary vector for storing the solution at point j. */ - su2double - *PrimVar_i, /*!< \brief Auxiliary vector for storing the solution at point i. */ - *PrimVar_j; /*!< \brief Auxiliary vector for storing the solution at point j. */ - su2double **LowMach_Precontioner; /*!< \brief Auxiliary vector for storing the inverse of Roe-turkel preconditioner. */ - bool space_centered, /*!< \brief True if space centered scheeme used. */ - euler_implicit, /*!< \brief True if euler implicit scheme used. */ - least_squares; /*!< \brief True if computing gradients by least squares. */ - su2double Gamma; /*!< \brief Fluid's Gamma constant (ratio of specific heats). */ - su2double Gamma_Minus_One; /*!< \brief Fluids's Gamma - 1.0 . */ - - su2double *Primitive, /*!< \brief Auxiliary nPrimVar vector. */ - *Primitive_i, /*!< \brief Auxiliary nPrimVar vector for storing the primitive at point i. */ - *Primitive_j; /*!< \brief Auxiliary nPrimVar vector for storing the primitive at point j. */ - - su2double *Secondary, /*!< \brief Auxiliary nPrimVar vector. */ - *Secondary_i, /*!< \brief Auxiliary nPrimVar vector for storing the primitive at point i. */ - *Secondary_j; /*!< \brief Auxiliary nPrimVar vector for storing the primitive at point j. */ - - su2double AoA_Prev, /*!< \brief Old value of the angle of attack (monitored). */ - AoA_inc; - bool Start_AoA_FD, /*!< \brief Boolean for start of finite differencing for FixedCL mode */ - End_AoA_FD, /*!< \brief Boolean for end of finite differencing for FixedCL mode */ - Update_AoA; /*!< \brief Boolean to signal Angle of Attack Update */ - unsigned long Iter_Update_AoA; /*!< \brief Iteration at which AoA was updated last */ - su2double dCL_dAlpha; /*!< \brief Value of dCL_dAlpha used to control CL in fixed CL mode */ - unsigned long BCThrust_Counter; - unsigned short nSpanWiseSections; /*!< \brief Number of span-wise sections. */ - unsigned short nSpanMax; /*!< \brief Max number of maximum span-wise sections for all zones */ - unsigned short nMarkerTurboPerf; /*!< \brief Number of turbo performance. */ - - CFluidModel *FluidModel; /*!< \brief fluid model used in the solver */ - - /*--- Turbomachinery Solver Variables ---*/ - su2double *** AverageFlux, - ***SpanTotalFlux, - ***AverageVelocity, - ***AverageTurboVelocity, - ***OldAverageTurboVelocity, - ***ExtAverageTurboVelocity, - **AveragePressure, - **OldAveragePressure, - **RadialEquilibriumPressure, - **ExtAveragePressure, - **AverageDensity, - **OldAverageDensity, - **ExtAverageDensity, - **AverageNu, - **AverageKine, - **AverageOmega, - **ExtAverageNu, - **ExtAverageKine, - **ExtAverageOmega; - - su2double **DensityIn, - **PressureIn, - ***TurboVelocityIn, - **DensityOut, - **PressureOut, - ***TurboVelocityOut, - **KineIn, - **OmegaIn, - **NuIn, - **KineOut, - **OmegaOut, - **NuOut; - - complex ***CkInflow, - ***CkOutflow1, - ***CkOutflow2; - - /*--- End of Turbomachinery Solver Variables ---*/ - - /* Sliding meshes variables */ - - su2double ****SlidingState; - int **SlidingStateNodes; - - CEulerVariable* nodes = nullptr; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ - - /*! - * \brief Return nodes to allow CSolver::base_nodes to be set. - */ - inline CVariable* GetBaseClassPointerToNodes() override { return nodes; } - -public: - - - /*! - * \brief Constructor of the class. - */ - CEulerSolver(void); - - /*! - * \overload - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - CEulerSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); - - /*! - * \brief Destructor of the class. - */ - virtual ~CEulerSolver(void); - - /*! - * \brief Set the solver nondimensionalization. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void SetNondimensionalization(CConfig *config, unsigned short iMesh); - - /*! - * \brief Compute the pressure at the infinity. - * \return Value of the pressure at the infinity. - */ - CFluidModel* GetFluidModel(void); - - /*! - * \brief Compute the density at the infinity. - * \return Value of the density at the infinity. - */ - su2double GetDensity_Inf(void); - - /*! - * \brief Compute 2-norm of the velocity at the infinity. - * \return Value of the 2-norm of the velocity at the infinity. - */ - su2double GetModVelocity_Inf(void); - - /*! - * \brief Compute the density multiply by energy at the infinity. - * \return Value of the density multiply by energy at the infinity. - */ - su2double GetDensity_Energy_Inf(void); - - /*! - * \brief Compute the pressure at the infinity. - * \return Value of the pressure at the infinity. - */ - su2double GetPressure_Inf(void); - - /*! - * \brief Compute the density multiply by velocity at the infinity. - * \param[in] val_dim - Index of the velocity vector. - * \return Value of the density multiply by the velocity at the infinity. - */ - su2double GetDensity_Velocity_Inf(unsigned short val_dim); - - /*! - * \brief Get the velocity at the infinity. - * \param[in] val_dim - Index of the velocity vector. - * \return Value of the velocity at the infinity. - */ - su2double GetVelocity_Inf(unsigned short val_dim); - - /*! - * \brief Get the velocity at the infinity. - * \return Value of the velocity at the infinity. - */ - su2double *GetVelocity_Inf(void); - - /*! - * \brief Compute the time step for solving the Euler equations. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] Iteration - Value of the current iteration. - */ - void SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh, unsigned long Iteration); - - /*! - * \brief Compute the spatial integration using a centered scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - void Centered_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh, unsigned short iRKStep); - - /*! - * \brief Compute the spatial integration using a upwind scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Upwind_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh); - - /*! - * \brief Compute the extrapolated quantities, for MUSCL upwind 2nd reconstruction, - * in a more thermodynamic consistent way - * \param[in] config - Definition of the particular problem. - */ - void ComputeConsExtrapolation(CConfig *config); - - /*! - * \brief Source term integration. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] second_numerics - Description of the second numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CNumerics *second_numerics, - CConfig *config, unsigned short iMesh); - - /*! - * \brief Source term integration. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh); - - /*! - * \brief Compute primitive variables and their gradients. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - * \param[in] Output - boolean to determine whether to print output. - */ - void Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh); - - /*! - * \brief Compute the velocity^2, SoundSpeed, Pressure, Enthalpy, Viscosity. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] Output - boolean to determine whether to print output. - * \return - The number of non-physical points. - */ - unsigned long SetPrimitive_Variables(CSolver **solver_container, CConfig *config, bool Output); - - /*! - * \brief Compute a pressure sensor switch. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void SetCentered_Dissipation_Sensor(CGeometry *geometry, CConfig *config); - - /*! - * \brief Compute Ducros Sensor for Roe Dissipation. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void SetUpwind_Ducros_Sensor(CGeometry *geometry, CConfig *config); - - /*! - * \brief Compute the gradient of the primitive variables using Green-Gauss method, - * and stores the result in the Gradient_Primitive variable. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] reconstruction - indicator that the gradient being computed is for upwind reconstruction. - */ - void SetPrimitive_Gradient_GG(CGeometry *geometry, CConfig *config, bool reconstruction = false); - - /*! - * \brief Compute the gradient of the primitive variables using a Least-Squares method, - * and stores the result in the Gradient_Primitive variable. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] reconstruction - indicator that the gradient being computed is for upwind reconstruction. - */ - void SetPrimitive_Gradient_LS(CGeometry *geometry, CConfig *config, bool reconstruction = false); - - /*! - * \brief Compute the limiter of the primitive variables. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void SetPrimitive_Limiter(CGeometry *geometry, CConfig *config); - - /*! - * \brief Compute the preconditioner for convergence acceleration by Roe-Turkel method. - * \param[in] iPoint - Index of the grid point - * \param[in] config - Definition of the particular problem. - */ - void SetPreconditioner(CConfig *config, unsigned long iPoint); - - /*! - * \brief Compute the undivided laplacian for the solution, except the energy equation. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void SetUndivided_Laplacian(CGeometry *geometry, CConfig *config); - - /*! - * \brief Compute the max eigenvalue. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void SetMax_Eigenvalue(CGeometry *geometry, CConfig *config); - - /*! - * \brief Parallelization of Undivided Laplacian. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Set_MPI_ActDisk(CSolver **solver_container, CGeometry *geometry, CConfig *config); - - /*! - * \brief Parallelization of Undivided Laplacian. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Set_MPI_Nearfield(CGeometry *geometry, CConfig *config); - - /*! - * \author H. Kline - * \brief Compute weighted-sum "combo" objective output - * \param[in] config - Definition of the particular problem. - */ - void Evaluate_ObjFunc(CConfig *config); - - /*! - * \author: T. Kattmann - * - * \brief Impose via the residual the Euler wall boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Euler_Wall(CGeometry *geometry, - CSolver **solver_container, - CNumerics *conv_numerics, - CNumerics *visc_numerics, - CConfig *config, - unsigned short val_marker) override; - - /*! - * \brief Impose the far-field boundary condition using characteristics. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Far_Field(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose the symmetry boundary condition using the residual. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Sym_Plane(CGeometry *geometry, - CSolver **solver_container, - CNumerics *conv_numerics, - CNumerics *visc_numerics, - CConfig *config, - unsigned short val_marker) override; - - /*! - * \brief Impose the interface state across sliding meshes. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - void BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config); - - /*! - * \brief Impose the engine inflow boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_ActDisk_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose the engine exhaust boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_ActDisk_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose the engine inflow boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_ActDisk(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker, bool val_inlet_surface); - - /*! - * \brief Impose the interface boundary condition using the residual. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - void BC_Interface_Boundary(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose the near-field boundary condition using the residual. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - void BC_NearField_Boundary(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose a periodic boundary condition by summing contributions from the complete control volume. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - void BC_Periodic(CGeometry *geometry, CSolver **solver_container, - CNumerics *numerics, CConfig *config); - - /*! - * \brief Impose the dirichlet boundary condition using the residual. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Dirichlet(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short val_marker); - - /*! - * \author: G.Gori, S.Vitale, M.Pini, A.Guardone, P.Colonna - * - * \brief Impose the boundary condition using characteristic recostruction. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Riemann(CGeometry *geometry, CSolver **solver_container, - CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker); - - - /*! - * \brief Impose the boundary condition using characteristic recostruction. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_TurboRiemann(CGeometry *geometry, CSolver **solver_container, - CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief It computes Fourier transformation for the needed quantities along the pitch for each span in turbomachinery analysis. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] marker_flag - Surface marker flag where the function is applied. - */ - void PreprocessBC_Giles(CGeometry *geometry, CConfig *config, CNumerics *conv_numerics, unsigned short marker_flag); - - /*! - * \author: G.Gori, S.Vitale, M.Pini, A.Guardone, P.Colonna - * - * \brief Impose the boundary condition using characteristic recostruction. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Giles(CGeometry *geometry, CSolver **solver_container, - CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker); - - - /*! - * \brief Impose a subsonic inlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose a supersonic inlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Supersonic_Inlet(CGeometry *geometry, CSolver **solver_container, - CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose a supersonic outlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Supersonic_Outlet(CGeometry *geometry, CSolver **solver_container, - CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose a custom or verification boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the convective numerical method. - * \param[in] visc_numerics - Description of the viscous numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Custom(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose the outlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose the nacelle inflow boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Engine_Inflow(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose the ancelle exhaust boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Engine_Exhaust(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Set the new solution variables to the current solution value for classical RK. - * \param[in] geometry - Geometrical definition of the problem. - */ - void Set_NewSolution(CGeometry *geometry); - - /*! - * \brief Update the solution using a Runge-Kutta scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - void ExplicitRK_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iRKStep); - - /*! - * \brief Update the solution using the classical fourth-order Runge-Kutta scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - void ClassicalRK4_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iRKStep); - - /*! - * \brief Compute the Fan face Mach number. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solution - Container vector with all the solutions. - */ - void GetPower_Properties(CGeometry *geometry, CConfig *config, unsigned short iMesh, bool Output); - - /*! - * \brief Update the AoA and freestream velocity at the farfield. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - current mesh level for the multigrid. - * \param[in] Output - boolean to determine whether to print output. - */ - void SetActDisk_BCThrust(CGeometry *geometry, CSolver **solver_container, - CConfig *config, unsigned short iMesh, bool Output); - - /*! - * \brief Update the AoA and freestream velocity at the farfield. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - current mesh level for the multigrid. - * \param[in] Output - boolean to determine whether to print output. - */ - void SetFarfield_AoA(CGeometry *geometry, CSolver **solver_container, - CConfig *config, unsigned short iMesh, bool Output); - - /*! - * \brief Check for convergence of the Fixed CL mode to the target CL - * \param[in] config - Definition of the particular problem. - * \param[in] convergence - boolean for whether the solution is converged - * \return boolean for whether the Fixed CL mode is converged to target CL - */ - bool FixedCL_Convergence(CConfig *config, bool convergence); - - /*! - * \brief Checking whether fixed CL mode in finite-differencing mode - * \return boolean for whether the Fixed CL mode is currently in finite-differencing mode - */ - bool GetStart_AoA_FD(void); - - /*! - * \brief Checking whether fixed CL mode in finite-differencing mode - * \return boolean for whether the Fixed CL mode is currently in finite-differencing mode - */ - bool GetEnd_AoA_FD(void); - - /*! - * \brief Get the iteration of the last AoA update (Fixed CL Mode) - * \return value for the last iteration that the AoA was updated - */ - unsigned long GetIter_Update_AoA(); - - /*! - * \brief Get the AoA before the most recent update - * \return value of the AoA before most recent update - */ - su2double GetPrevious_AoA(); - - /*! - * \brief Get the CL Driver's control command - * \return value of CL Driver control command (AoA_inc) - */ - su2double GetAoA_inc(); - - /*! - * \brief Set gradients of coefficients for fixed CL mode - * \param[in] config - Definition of the particular problem. - */ - void SetCoefficient_Gradients(CConfig *config); - - /*! - * \brief Update the solution using the explicit Euler scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void ExplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief Update the solution using an implicit Euler scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief Compute a suitable under-relaxation parameter to limit the change in the solution variables over a nonlinear iteration for stability. - * \param[in] solver - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void ComputeUnderRelaxationFactor(CSolver **solver, CConfig *config); - - /*! - * \brief Compute the pressure forces and all the adimensional coefficients. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Pressure_Forces(CGeometry *geometry, CConfig *config); - - /*! - * \brief Compute the pressure forces and all the adimensional coefficients. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Momentum_Forces(CGeometry *geometry, CConfig *config); - - /*! - * \brief Compute turbomachinery performance. - * \param[in] solver - solver containing the outlet information. - * \param[in] inMarker - marker related to the inlet. - * \param[in] outMarker - marker related to the outlet. - */ - void TurboPerformance(CSolver *solver, CConfig *config, unsigned short inMarker, unsigned short outMarker, unsigned short Kind_TurboPerf , unsigned short inMarkerTP ); - - /*! - * \brief Compute turbomachinery performance. - * \param[in] solver - solver containing the outlet information. - * \param[in] inMarker - marker related to the inlet. - * \param[in] outMarker - marker related to the outlet. - */ - void StoreTurboPerformance(CSolver *solver, unsigned short inMarkerTP ); - - /*! - * \brief Get the outer state for fluid interface nodes. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - * \param[in] val_state - requested state component - */ - su2double GetSlidingState(unsigned short val_marker, unsigned long val_vertex, unsigned short val_state, unsigned long donor_index); - - /*! - * \brief Provide the non dimensional lift coefficient (inviscid contribution). - * \param val_marker Surface where the coefficient is going to be computed. - * \return Value of the lift coefficient (inviscid contribution) on the surface val_marker. - */ - su2double GetCL_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional lift coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the lift coefficient on the surface val_marker. - */ - su2double GetSurface_CL(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional drag coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the drag coefficient on the surface val_marker. - */ - su2double GetSurface_CD(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional side-force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side-force coefficient on the surface val_marker. - */ - su2double GetSurface_CSF(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional side-force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side-force coefficient on the surface val_marker. - */ - su2double GetSurface_CEff(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional x force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x force coefficient on the surface val_marker. - */ - su2double GetSurface_CFx(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional y force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y force coefficient on the surface val_marker. - */ - su2double GetSurface_CFy(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional z force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z force coefficient on the surface val_marker. - */ - su2double GetSurface_CFz(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional x moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMx(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional y moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMy(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional z moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMz(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional lift coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the lift coefficient on the surface val_marker. - */ - su2double GetSurface_CL_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional drag coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the drag coefficient on the surface val_marker. - */ - su2double GetSurface_CD_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional side-force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side-force coefficient on the surface val_marker. - */ - su2double GetSurface_CSF_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional side-force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side-force coefficient on the surface val_marker. - */ - su2double GetSurface_CEff_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional x force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x force coefficient on the surface val_marker. - */ - su2double GetSurface_CFx_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional y force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y force coefficient on the surface val_marker. - */ - su2double GetSurface_CFy_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional z force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z force coefficient on the surface val_marker. - */ - su2double GetSurface_CFz_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional x moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMx_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional y moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMy_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional z moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMz_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional lift coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the lift coefficient on the surface val_marker. - */ - su2double GetSurface_CL_Mnt(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional drag coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the drag coefficient on the surface val_marker. - */ - su2double GetSurface_CD_Mnt(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional side-force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side-force coefficient on the surface val_marker. - */ - su2double GetSurface_CSF_Mnt(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional side-force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side-force coefficient on the surface val_marker. - */ - su2double GetSurface_CEff_Mnt(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional x force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x force coefficient on the surface val_marker. - */ - su2double GetSurface_CFx_Mnt(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional y force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y force coefficient on the surface val_marker. - */ - su2double GetSurface_CFy_Mnt(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional z force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z force coefficient on the surface val_marker. - */ - su2double GetSurface_CFz_Mnt(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional x moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMx_Mnt(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional y moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMy_Mnt(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional z moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMz_Mnt(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional drag coefficient (inviscid contribution). - * \param val_marker Surface where the coeficient is going to be computed. - * \return Value of the drag coefficient (inviscid contribution) on the surface val_marker. - */ - su2double GetCD_Inv(unsigned short val_marker); - - /*! - * \brief Provide the mass flow rate. - * \param val_marker Surface where the coeficient is going to be computed. - * \return Value of the mass flow rate on the surface val_marker. - */ - su2double GetInflow_MassFlow(unsigned short val_marker); - - /*! - * \brief Provide the mass flow rate. - * \param val_marker Surface where the coeficient is going to be computed. - * \return Value of the mass flow rate on the surface val_marker. - */ - su2double GetExhaust_MassFlow(unsigned short val_marker); - - /*! - * \brief Provide the mass flow rate. - * \param val_marker Surface where the coeficient is going to be computed. - * \return Value of the fan face pressure on the surface val_marker. - */ - su2double GetInflow_Pressure(unsigned short val_marker); - - /*! - * \brief Provide the mass flow rate. - * \param val_marker Surface where the coeficient is going to be computed. - * \return Value of the fan face mach on the surface val_marker. - */ - su2double GetInflow_Mach(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional sideforce coefficient (inviscid contribution). - * \param val_marker Surface where the coeficient is going to be computed. - * \return Value of the sideforce coefficient (inviscid contribution) on the surface val_marker. - */ - su2double GetCSF_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional efficiency coefficient (inviscid contribution). - * \param val_marker Surface where the coeficient is going to be computed. - * \return Value of the efficiency coefficient (inviscid contribution) on the surface val_marker. - */ - su2double GetCEff_Inv(unsigned short val_marker); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional sideforce coefficient. - * \return Value of the sideforce coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CSF(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CEff(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional Equivalent Area coefficient. - * \return Value of the Equivalent Area coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CEquivArea(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional aero CD. - * \return Value of the Aero CD coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_AeroCD(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional Equivalent Area coefficient. - * \return Value of the Equivalent Area coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CpDiff(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional Equivalent Area coefficient. - * \return Value of the Equivalent Area coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_HeatFluxDiff(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional Near-Field pressure coefficient. - * \return Value of the NearField pressure coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CNearFieldOF(void); - - /*! - * \author H. Kline - * \brief Add to the value of the total 'combo' objective. - * \param[in] val_obj - Value of the contribution to the 'combo' objective. - */ - void AddTotal_ComboObj(su2double val_obj); - - /*! - * \brief Set the value of the Equivalent Area coefficient. - * \param[in] val_cequivarea - Value of the Equivalent Area coefficient. - */ - void SetTotal_CEquivArea(su2double val_cequivarea); - - /*! - * \brief Set the value of the Aero drag. - * \param[in] val_cequivarea - Value of the aero drag. - */ - void SetTotal_AeroCD(su2double val_aerocd); - - /*! - * \brief Set the value of the Equivalent Area coefficient. - * \param[in] val_cequivarea - Value of the Equivalent Area coefficient. - */ - void SetTotal_CpDiff(su2double val_pressure); - - /*! - * \brief Set the value of the Equivalent Area coefficient. - * \param[in] val_cequivarea - Value of the Equivalent Area coefficient. - */ - void SetTotal_HeatFluxDiff(su2double val_heat); - - /*! - * \brief Set the value of the Near-Field pressure oefficient. - * \param[in] val_cnearfieldpress - Value of the Near-Field pressure coefficient. - */ - void SetTotal_CNearFieldOF(su2double val_cnearfieldpress); - - /*! - * \author H. Kline - * \brief Set the total "combo" objective (weighted sum of other values). - * \param[in] ComboObj - Value of the combined objective. - */ - void SetTotal_ComboObj(su2double ComboObj); - - /*! - * \author H. Kline - * \brief Provide the total "combo" objective (weighted sum of other values). - * \return Value of the "combo" objective values. - */ - su2double GetTotal_ComboObj(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional lift coefficient. - * \return Value of the lift coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CL(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CD(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_NetThrust(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_Power(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_SolidCD(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_ReverseFlow(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_MFR(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_Prop_Eff(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_ByPassProp_Eff(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_Adiab_Eff(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_Poly_Eff(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_IDC(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_IDC_Mach(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_IDR(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_DC60(void); - - /*! - * \brief Provide the total custom objective function. - * \return Value of the custom objective function. - */ - su2double GetTotal_Custom_ObjFunc(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional x moment coefficient. - * \return Value of the moment x coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CMx(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional y moment coefficient. - * \return Value of the moment y coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CMy(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional z moment coefficient. - * \return Value of the moment z coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CMz(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional x moment coefficient. - * \return Value of the moment x coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CoPx(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional y moment coefficient. - * \return Value of the moment y coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CoPy(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional z moment coefficient. - * \return Value of the moment z coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CoPz(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional x force coefficient. - * \return Value of the force x coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CFx(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional y force coefficient. - * \return Value of the force y coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CFy(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional z force coefficient. - * \return Value of the force z coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CFz(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional thrust coefficient. - * \return Value of the rotor efficiency coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CT(void); - - /*! - * \brief Store the total (inviscid + viscous) non dimensional thrust coefficient. - * \param[in] val_Total_CT - Value of the total thrust coefficient. - */ - void SetTotal_CT(su2double val_Total_CT); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional torque coefficient. - * \return Value of the rotor efficiency coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CQ(void); - - /*! - * \brief Provide the total heat load. - * \return Value of the heat load (viscous contribution). - */ - su2double GetTotal_HeatFlux(void); - - /*! - * \brief Provide the total heat load. - * \return Value of the heat load (viscous contribution). - */ - su2double GetTotal_MaxHeatFlux(void); - - /*! - * \brief Store the total (inviscid + viscous) non dimensional torque coefficient. - * \param[in] val_Total_CQ - Value of the total torque coefficient. - */ - void SetTotal_CQ(su2double val_Total_CQ); - - /*! - * \brief Store the total heat load. - * \param[in] val_Total_Heat - Value of the heat load. - */ - void SetTotal_HeatFlux(su2double val_Total_Heat); - - /*! - * \brief Store the total heat load. - * \param[in] val_Total_Heat - Value of the heat load. - */ - void SetTotal_MaxHeatFlux(su2double val_Total_MaxHeat); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional rotor Figure of Merit. - * \return Value of the rotor efficiency coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CMerit(void); - - /*! - * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - void SetTotal_CD(su2double val_Total_CD); - - /*! - * \brief Store the total (inviscid + viscous) non dimensional lift coefficient. - * \param[in] val_Total_CL - Value of the total lift coefficient. - */ - void SetTotal_CL(su2double val_Total_CL); - - /*! - * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - void SetTotal_NetThrust(su2double val_Total_NetThrust); - - /*! - * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - void SetTotal_Power(su2double val_Total_Power); - - /*! - * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - void SetTotal_SolidCD(su2double val_Total_SolidCD); - - /*! - * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - void SetTotal_ReverseFlow(su2double val_ReverseFlow); - - /*! - * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - void SetTotal_MFR(su2double val_Total_MFR); - - /*! - * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - void SetTotal_Prop_Eff(su2double val_Total_Prop_Eff); - - /*! - * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - void SetTotal_ByPassProp_Eff(su2double val_Total_ByPassProp_Eff); - - /*! - * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - void SetTotal_Adiab_Eff(su2double val_Total_Adiab_Eff); - - /*! - * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - void SetTotal_Poly_Eff(su2double val_Total_Poly_Eff); - - /*! - * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - void SetTotal_IDC(su2double val_Total_IDC); - - /*! - * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - void SetTotal_IDC_Mach(su2double val_Total_IDC_Mach); - - /*! - * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - void SetTotal_IDR(su2double val_Total_IDR); - - /*! - * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - void SetTotal_DC60(su2double val_Total_DC60); - - /*! - * \brief Set the value of the custom objective function. - * \param[in] val_Total_Custom_ObjFunc - Value of the total custom objective function. - * \param[in] val_weight - Value of the weight for the custom objective function. - */ - void SetTotal_Custom_ObjFunc(su2double val_total_custom_objfunc, su2double val_weight); - - /*! - * \brief Add the value of the custom objective function. - * \param[in] val_Total_Custom_ObjFunc - Value of the total custom objective function. - * \param[in] val_weight - Value of the weight for the custom objective function. - */ - void AddTotal_Custom_ObjFunc(su2double val_total_custom_objfunc, su2double val_weight); - - /*! - * \brief Get the inviscid contribution to the lift coefficient. - * \return Value of the lift coefficient (inviscid contribution). - */ - su2double GetAllBound_CL_Inv(void); - - /*! - * \brief Get the inviscid contribution to the drag coefficient. - * \return Value of the drag coefficient (inviscid contribution). - */ - su2double GetAllBound_CD_Inv(void); - - /*! - * \brief Get the inviscid contribution to the sideforce coefficient. - * \return Value of the sideforce coefficient (inviscid contribution). - */ - su2double GetAllBound_CSF_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CEff_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CMx_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CMy_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CMz_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CoPx_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CoPy_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CoPz_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CFx_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CFy_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CFz_Inv(void); - - /*! - * \brief Get the inviscid contribution to the lift coefficient. - * \return Value of the lift coefficient (inviscid contribution). - */ - su2double GetAllBound_CL_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the drag coefficient. - * \return Value of the drag coefficient (inviscid contribution). - */ - su2double GetAllBound_CD_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the sideforce coefficient. - * \return Value of the sideforce coefficient (inviscid contribution). - */ - su2double GetAllBound_CSF_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CEff_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CMx_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CMy_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CMz_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CoPx_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CoPy_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CoPz_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CFx_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CFy_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CFz_Mnt(void); - - /*! - * \brief Provide the Pressure coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - su2double GetCPressure(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Provide the Target Pressure coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - su2double GetCPressureTarget(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Set the value of the target Pressure coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - void SetCPressureTarget(unsigned short val_marker, unsigned long val_vertex, su2double val_pressure); - - /*! - * \brief Value of the characteristic variables at the boundaries. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - su2double *GetCharacPrimVar(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Value of the characteristic variables at the boundaries. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - void SetCharacPrimVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_var, su2double val_value); - - /*! - * \brief Value of the characteristic variables at the boundaries. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - su2double *GetDonorPrimVar(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Value of the characteristic variables at the boundaries. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - void SetDonorPrimVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_var, su2double val_value); - - /*! - * \brief Value of the characteristic variables at the boundaries. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - su2double GetDonorPrimVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_var); - - /*! - * \brief Value of the characteristic global index at the boundaries. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - unsigned long GetDonorGlobalIndex(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Value of the characteristic global index at the boundaries. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - void SetDonorGlobalIndex(unsigned short val_marker, unsigned long val_vertex, unsigned long val_index); - - /*! - * \brief Value of the characteristic global index at the boundaries. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - su2double GetActDisk_DeltaP(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Value of the characteristic global index at the boundaries. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - void SetActDisk_DeltaP(unsigned short val_marker, unsigned long val_vertex, su2double val_deltap); - - /*! - * \brief Value of the characteristic global index at the boundaries. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - su2double GetActDisk_DeltaT(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Value of the characteristic global index at the boundaries. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - void SetActDisk_DeltaT(unsigned short val_marker, unsigned long val_vertex, su2double val_deltat); - - /*! - * \brief Value of the total temperature at an inlet boundary. - * \param[in] val_marker - Surface marker where the total temperature is evaluated. - * \param[in] val_vertex - Vertex of the marker val_marker where the total temperature is evaluated. - * \return Value of the total temperature - */ - su2double GetInlet_Ttotal(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Value of the total pressure at an inlet boundary. - * \param[in] val_marker - Surface marker where the total pressure is evaluated. - * \param[in] val_vertex - Vertex of the marker val_marker where the total pressure is evaluated. - * \return Value of the total pressure - */ - su2double GetInlet_Ptotal(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief A component of the unit vector representing the flow direction at an inlet boundary. - * \param[in] val_marker - Surface marker where the flow direction is evaluated - * \param[in] val_vertex - Vertex of the marker val_marker where the flow direction is evaluated - * \param[in] val_dim - The component of the flow direction unit vector to be evaluated - * \return Component of a unit vector representing the flow direction. - */ - su2double GetInlet_FlowDir(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim); - - /*! - * \brief Set the value of the total temperature at an inlet boundary. - * \param[in] val_marker - Surface marker where the total temperature is set. - * \param[in] val_vertex - Vertex of the marker val_marker where the total temperature is set. - * \param[in] val_ttotal - Value of the total temperature - */ - void SetInlet_Ttotal(unsigned short val_marker, unsigned long val_vertex, su2double val_ttotal); - - /*! - * \brief Set the value of the total pressure at an inlet boundary. - * \param[in] val_marker - Surface marker where the total pressure is set. - * \param[in] val_vertex - Vertex of the marker val_marker where the total pressure is set. - * \param[in] val_ptotal - Value of the total pressure - */ - void SetInlet_Ptotal(unsigned short val_marker, unsigned long val_vertex, su2double val_ptotal); - - /*! - * \brief Set a component of the unit vector representing the flow direction at an inlet boundary. - * \param[in] val_marker - Surface marker where the flow direction is set. - * \param[in] val_vertex - Vertex of the marker val_marker where the flow direction is set. - * \param[in] val_dim - The component of the flow direction unit vector to be set - * \param[in] val_flowdir - Component of a unit vector representing the flow direction. - */ - void SetInlet_FlowDir(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim, su2double val_flowdir); - - /*! - * \brief Set a uniform inlet profile - * - * The values at the inlet are set to match the values specified for - * inlets in the configuration file. - * - * \param[in] config - Definition of the particular problem. - * \param[in] iMarker - Surface marker where the coefficient is computed. - */ - void SetUniformInlet(CConfig* config, unsigned short iMarker); - - /*! - * \brief Store of a set of provided inlet profile values at a vertex. - * \param[in] val_inlet - vector containing the inlet values for the current vertex. - * \param[in] iMarker - Surface marker where the coefficient is computed. - * \param[in] iVertex - Vertex of the marker iMarker where the inlet is being set. - */ - void SetInletAtVertex(su2double *val_inlet, unsigned short iMarker, unsigned long iVertex); - - /*! - * \brief Get the set of value imposed at an inlet. - * \param[in] val_inlet - vector returning the inlet values for the current vertex. - * \param[in] val_inlet_point - Node index where the inlet is being set. - * \param[in] val_kind_marker - Enumerated type for the particular inlet type. - * \param[in] geometry - Geometrical definition of the problem. - * \param config - Definition of the particular problem. - * \return Value of the face area at the vertex. - */ - su2double GetInletAtVertex(su2double *val_inlet, - unsigned long val_inlet_point, - unsigned short val_kind_marker, - string val_marker, - CGeometry *geometry, - CConfig *config); - - /*! - * \brief Update the multi-grid structure for the customized boundary conditions - * \param geometry_container - Geometrical definition. - * \param config - Definition of the particular problem. - */ - void UpdateCustomBoundaryConditions(CGeometry **geometry_container, CConfig *config); - - /*! - * \brief Set the total residual adding the term that comes from the Dual Time Strategy. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - */ - void SetResidual_DualTime(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iRKStep, unsigned short iMesh, unsigned short RunTime_EqSystem); - - /*! - * \brief Load a solution from a restart file. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - Container vector with all of the solvers. - * \param[in] config - Definition of the particular problem. - * \param[in] val_iter - Current external iteration number. - * \param[in] val_update_geo - Flag for updating coords and grid velocity. - */ - void LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo); - - /*! - * \brief Allocates the final pointer of SlidingState depending on how many donor vertex donate to it. That number is stored in SlidingStateNodes[val_marker][val_vertex]. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - */ - void SetSlidingStateStructure(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Set the outer state for fluid interface nodes. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - * \param[in] val_state - requested state component - * \param[in] donor_index - index of the donor node to set - * \param[in] component - set value - */ - void SetSlidingState(unsigned short val_marker, unsigned long val_vertex, unsigned short val_state, unsigned long donor_index, su2double component); - - /*! - * \brief Set the number of outer state for fluid interface nodes. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - * \param[in] value - number of outer states - */ - void SetnSlidingStates(unsigned short val_marker, unsigned long val_vertex, int value); - - /*! - * \brief Get the number of outer state for fluid interface nodes. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - */ - int GetnSlidingStates(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Set the initial condition for the Euler Equations. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] ExtIter - External iteration. - */ - void SetInitialCondition(CGeometry **geometry, CSolver ***solver_container, CConfig *config, unsigned long TimeIter); - - /*! - * \brief Set the freestream pressure. - * \param[in] Value of freestream pressure. - */ - void SetPressure_Inf(su2double p_inf); - - /*! - * \brief Set the freestream temperature. - * \param[in] Value of freestream temperature. - */ - void SetTemperature_Inf(su2double t_inf); - - /*! - * \brief Set the solution using the Freestream values. - * \param[in] config - Definition of the particular problem. - */ - void SetFreeStream_Solution(CConfig *config); - - /*! - * \brief Initilize turbo containers. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void InitTurboContainers(CGeometry *geometry, CConfig *config); - - /*! - * \brief Set the solution using the Freestream values. - * \param[in] config - Definition of the particular problem. - */ - void SetFreeStream_TurboSolution(CConfig *config); - - /*! - * \brief It computes average quantities along the span for turbomachinery analysis. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] marker_flag - Surface marker flag where the function is applied. - */ - void PreprocessAverage(CSolver **solver, CGeometry *geometry, CConfig *config, unsigned short marker_flag); - - /*! - * \brief It computes average quantities along the span for turbomachinery analysis. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] marker_flag - Surface marker flag where the function is applied. - */ - void TurboAverageProcess(CSolver **solver, CGeometry *geometry, CConfig *config, unsigned short marker_flag); - - /*! - * \brief it performs a mixed out average of the nodes of a boundary. - * \param[in] val_init_pressure - initial pressure value - * \param[in] val_Averaged_Flux - flux averaged values. - * \param[in] val_normal - normal vector. - * \param[in] pressure_mix - value of the mixed-out avaraged pressure. - * \param[in] density_miz - value of the mixed-out avaraged density. - */ - void MixedOut_Average (CConfig *config, su2double val_init_pressure, const su2double *val_Averaged_Flux, - const su2double *val_normal, su2double& pressure_mix, su2double& density_mix); - - /*! - * \brief It gathers into the master node average quantities at inflow and outflow needed for turbomachinery analysis. - * \param[in] config - Definition of the particular problem. - * \param[in] geometry - Geometrical definition of the problem. - */ - void GatherInOutAverageValues(CConfig *config, CGeometry *geometry); - - /*! - * \brief it take a velocity in the cartesian reference of framework and transform into the turbomachinery frame of reference. - * \param[in] cartesianVelocity - cartesian components of velocity vector. - * \param[in] turboNormal - normal vector in the turbomachinery frame of reference. - * \param[in] turboVelocity - velocity vector in the turbomachinery frame of reference. - */ - void ComputeTurboVelocity(const su2double *cartesianVelocity, const su2double *turboNormal, su2double *turboVelocity, - unsigned short marker_flag, unsigned short marker_kindturb); - - /*! - * \brief it take a velocity in the cartesian reference of framework and transform into the turbomachinery frame of reference. - * \param[in] cartesianVelocity - cartesian components of velocity vector. - * \param[in] turboNormal - normal vector in the turbomachinery frame of reference. - * \param[in] turboVelocity - velocity vector in the turbomachinery frame of reference. - */ - void ComputeBackVelocity(const su2double *turboVelocity, const su2double *turboNormal, su2double *cartesianVelocity, - unsigned short marker_flag, unsigned short marker_kindturb); - - /*! - * \brief Provide the average density at the boundary of interest. - * \param[in] val_marker - bound marker. - * \return Value of the Average Density on the surface val_marker. - */ - su2double GetAverageDensity(unsigned short valMarker, unsigned short valSpan); - - /*! - * \brief Provide the average pressure at the boundary of interest. - * \param[in] val_marker - bound marker. - * \return Value of the Average Pressure on the surface val_marker. - */ - su2double GetAveragePressure(unsigned short valMarker, unsigned short valSpan); - - /*! - * \brief Provide the average turbo velocity average at the boundary of interest. - * \param[in] val_marker - bound marker. - * \return Value of the Average Total Pressure on the surface val_marker. - */ - su2double* GetAverageTurboVelocity(unsigned short valMarker, unsigned short valSpan); - - /*! - * \brief Provide the average density at the boundary of interest. - * \param[in] val_marker - bound marker. - * \return Value of the Average turbulent Nu on the surface val_marker. - */ - su2double GetAverageNu(unsigned short valMarker, unsigned short valSpan); - - /*! - * \brief Provide the average density at the boundary of interest. - * \param[in] val_marker - bound marker. - * \return Value of the Average turbulent Kine on the surface val_marker. - */ - su2double GetAverageKine(unsigned short valMarker, unsigned short valSpan); - - /*! - * \brief Provide the average density at the boundary of interest. - * \param[in] val_marker - bound marker. - * \return Value of the Average turbulent Omega on the surface val_marker. - */ - su2double GetAverageOmega(unsigned short valMarker, unsigned short valSpan); - - /*! - * \brief Provide the average density at the boundary of interest. - * \param[in] val_marker - bound marker. - * \return Value of the Average turbulent Nu on the surface val_marker. - */ - su2double GetExtAverageNu(unsigned short valMarker, unsigned short valSpan); - - /*! - * \brief Provide the average density at the boundary of interest. - * \param[in] val_marker - bound marker. - * \return Value of the Average turbulent Kine on the surface val_marker. - */ - su2double GetExtAverageKine(unsigned short valMarker, unsigned short valSpan); - - /*! - * \brief Provide the average density at the boundary of interest. - * \param[in] val_marker - bound marker. - * \return Value of the Average turbulent Omega on the surface val_marker. - */ - su2double GetExtAverageOmega(unsigned short valMarker, unsigned short valSpan); - - /*! - * \brief Set the external average density at the boundary of interest. - * \param[in] val_marker - bound marker. - * \param[in] val_Span - value of the Span. - * \param[in] valDensity - value to set. - */ - void SetExtAverageDensity(unsigned short valMarker, unsigned short valSpan, su2double valDensity); - - /*! - * \brief Set the external average density at the boundary of interest. - * \param[in] val_marker - bound marker. - * \param[in] val_Span - value of the Span. - * \param[in] valPressure - value to set. - */ - void SetExtAveragePressure(unsigned short valMarker, unsigned short valSpan, su2double valPressure); - - /*! - * \brief Set the external the average turbo velocity average at the boundary of interest. - * \param[in] val_marker - bound marker. - * \return Value of the Average Total Pressure on the surface val_marker. - */ - void SetExtAverageTurboVelocity(unsigned short valMarker, unsigned short valSpan, unsigned short valIndex, su2double valTurboVelocity); - - /*! - * \brief Set the external average turbulent Nu at the boundary of interest. - * \param[in] val_marker - bound marker. - * \param[in] val_Span - value of the Span. - * \param[in] valNu - value to set. - */ - void SetExtAverageNu(unsigned short valMarker, unsigned short valSpan, su2double valNu); - - /*! - * \brief Set the external average turbulent Kine at the boundary of interest. - * \param[in] val_marker - bound marker. - * \param[in] val_Span - value of the Span. - * \param[in] valKine - value to set. - */ - void SetExtAverageKine(unsigned short valMarker, unsigned short valSpan, su2double valKine); - - /*! - * \brief Set the external average turbulent Omega at the boundary of interest. - * \param[in] val_marker - bound marker. - * \param[in] val_Span - value of the Span. - * \param[in] valOmega - value to set. - */ - void SetExtAverageOmega(unsigned short valMarker, unsigned short valSpan, su2double valOmega); - - /*! - * \brief Provide the inlet density to check convergence of conservative mixing-plane. - * \param[in] inMarkerTP - bound marker. - * \return Value of the inlet density. - */ - su2double GetDensityIn(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief Provide the inlet pressure to check convergence of conservative mixing-plane. - * \param[in] inMarkerTP - bound marker. - * \return Value of inlet pressure. - */ - su2double GetPressureIn(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief Provide the inlet normal velocity to check convergence of conservative mixing-plane. - * \param[in] inMarkerTP - bound marker. - * \return Value of the inlet normal velocity. - */ - su2double* GetTurboVelocityIn(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief Provide the outlet density to check convergence of conservative mixing-plane. - * \param[in] inMarkerTP - bound marker. - * \return Value of the outlet density. - */ - su2double GetDensityOut(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief Provide the outlet pressure to check convergence of conservative mixing-plane. - * \param[in] inMarkerTP - bound marker. - * \return Value of the outlet pressure. - */ - su2double GetPressureOut(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief Provide the outlet normal velocity to check convergence of conservative mixing-plane. - * \param[in] inMarkerTP - bound marker. - * \return Value of the outlet normal velocity. - */ - su2double* GetTurboVelocityOut(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief Provide the inlet turbulent kei to check convergence of conservative mixing-plane. - * \param[in] inMarkerTP - bound marker. - * \return Value of the inlet density. - */ - su2double GetKineIn(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief Provide the inlet turbulent omega to check convergence of conservative mixing-plane. - * \param[in] inMarkerTP - bound marker. - * \return Value of the inlet density. - */ - su2double GetOmegaIn(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief Provide the inlet turbulent nu to check convergence of conservative mixing-plane. - * \param[in] inMarkerTP - bound marker. - * \return Value of the inlet density. - */ - su2double GetNuIn(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief Provide the outlet turbulent kei to check convergence of conservative mixing-plane. - * \param[in] inMarkerTP - bound marker. - * \return Value of the inlet density. - */ - su2double GetKineOut(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief Provide the outlet turbulent omega to check convergence of conservative mixing-plane. - * \param[in] inMarkerTP - bound marker. - * \return Value of the inlet density. - */ - su2double GetOmegaOut(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief Provide the outlet turbulent nu to check convergence of conservative mixing-plane. - * \param[in] inMarkerTP - bound marker. - * \return Value of the inlet density. - */ - su2double GetNuOut(unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief Set inlet density. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - void SetDensityIn(su2double value, unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief Set inlet pressure. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - void SetPressureIn(su2double value, unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief Set inlet normal velocity. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - void SetTurboVelocityIn(su2double* value, unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief Set outlet density. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - void SetDensityOut(su2double value, unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief Set outlet pressure. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - void SetPressureOut(su2double value, unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief Set outlet normal velocity. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - void SetTurboVelocityOut(su2double* value, unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief Set inlet turbulent kei. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - void SetKineIn(su2double value, unsigned short inMarkerTP, unsigned short valSpan); - /*! - * \brief Set inlet turbulent omega. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - void SetOmegaIn(su2double value, unsigned short inMarkerTP, unsigned short valSpan); - /*! - * \brief Set inlet turbulent Nu. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - void SetNuIn(su2double value, unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief Set outlet turbulent kei. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - void SetKineOut(su2double value, unsigned short inMarkerTP, unsigned short valSpan); - /*! - * \brief Set Outlet turbulent omega. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - void SetOmegaOut(su2double value, unsigned short inMarkerTP, unsigned short valSpan); - /*! - * \brief Set outlet turbulent Nu. - * \param[in] value - turboperformance value to set. - * \param[in] inMarkerTP - turboperformance marker. - */ - void SetNuOut(su2double value, unsigned short inMarkerTP, unsigned short valSpan); - - /*! - * \brief Compute the global error measures (L2, Linf) for verification cases. - * \param[in] geometry - Geometrical definition. - * \param[in] config - Definition of the particular problem. - */ - void ComputeVerificationError(CGeometry *geometry, CConfig *config); - -}; - -/*! - * \class CIncEulerSolver - * \brief Main class for defining the incompressible Euler flow solver. - * \ingroup Euler_Equations - * \author F. Palacios, T. Economon, T. Albring - */ -class CIncEulerSolver : public CSolver { -protected: - - su2double - Density_Inf, /*!< \brief Density at the infinity. */ - Pressure_Inf, /*!< \brief Pressure at the infinity. */ - *Velocity_Inf, /*!< \brief Flow Velocity vector at the infinity. */ - Temperature_Inf; /*!< \brief Temperature at infinity. */ - - su2double - *CD_Inv, /*!< \brief Drag coefficient (inviscid contribution) for each boundary. */ - *CL_Inv, /*!< \brief Lift coefficient (inviscid contribution) for each boundary. */ - *CSF_Inv, /*!< \brief Sideforce coefficient (inviscid contribution) for each boundary. */ - *CMx_Inv, /*!< \brief x Moment coefficient (inviscid contribution) for each boundary. */ - *CMy_Inv, /*!< \brief y Moment coefficient (inviscid contribution) for each boundary. */ - *CMz_Inv, /*!< \brief z Moment coefficient (inviscid contribution) for each boundary. */ - *CoPx_Inv, /*!< \brief x Moment coefficient (inviscid contribution) for each boundary. */ - *CoPy_Inv, /*!< \brief y Moment coefficient (inviscid contribution) for each boundary. */ - *CoPz_Inv, /*!< \brief z Moment coefficient (inviscid contribution) for each boundary. */ - *CFx_Inv, /*!< \brief x Force coefficient (inviscid contribution) for each boundary. */ - *CFy_Inv, /*!< \brief y Force coefficient (inviscid contribution) for each boundary. */ - *CFz_Inv, /*!< \brief z Force coefficient (inviscid contribution) for each boundary. */ - *Surface_CL_Inv, /*!< \brief Lift coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CD_Inv, /*!< \brief Drag coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CSF_Inv, /*!< \brief Side-force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CEff_Inv, /*!< \brief Side-force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CFx_Inv, /*!< \brief x Force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CFy_Inv, /*!< \brief y Force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CFz_Inv, /*!< \brief z Force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CMx_Inv, /*!< \brief x Moment coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CMy_Inv, /*!< \brief y Moment coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CMz_Inv, /*!< \brief z Moment coefficient (inviscid contribution) for each monitoring surface. */ - *CEff_Inv, /*!< \brief Efficiency (Cl/Cd) (inviscid contribution) for each boundary. */ - *CMerit_Inv, /*!< \brief Rotor Figure of Merit (inviscid contribution) for each boundary. */ - *CT_Inv, /*!< \brief Thrust coefficient (force in -x direction, inviscid contribution) for each boundary. */ - *CQ_Inv, /*!< \brief Torque coefficient (moment in -x direction, inviscid contribution) for each boundary. */ - *CD_Mnt, /*!< \brief Drag coefficient (inviscid contribution) for each boundary. */ - *CL_Mnt, /*!< \brief Lift coefficient (inviscid contribution) for each boundary. */ - *CSF_Mnt, /*!< \brief Sideforce coefficient (inviscid contribution) for each boundary. */ - *CMx_Mnt, /*!< \brief x Moment coefficient (inviscid contribution) for each boundary. */ - *CMy_Mnt, /*!< \brief y Moment coefficient (inviscid contribution) for each boundary. */ - *CMz_Mnt, /*!< \brief z Moment coefficient (inviscid contribution) for each boundary. */ - *CoPx_Mnt, /*!< \brief x Moment coefficient (inviscid contribution) for each boundary. */ - *CoPy_Mnt, /*!< \brief y Moment coefficient (inviscid contribution) for each boundary. */ - *CoPz_Mnt, /*!< \brief z Moment coefficient (inviscid contribution) for each boundary. */ - *CFx_Mnt, /*!< \brief x Force coefficient (inviscid contribution) for each boundary. */ - *CFy_Mnt, /*!< \brief y Force coefficient (inviscid contribution) for each boundary. */ - *CFz_Mnt, /*!< \brief z Force coefficient (inviscid contribution) for each boundary. */ - *Surface_CL_Mnt, /*!< \brief Lift coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CD_Mnt, /*!< \brief Drag coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CSF_Mnt, /*!< \brief Side-force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CEff_Mnt, /*!< \brief Side-force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CFx_Mnt, /*!< \brief x Force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CFy_Mnt, /*!< \brief y Force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CFz_Mnt, /*!< \brief z Force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CMx_Mnt, /*!< \brief x Moment coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CMy_Mnt, /*!< \brief y Moment coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CMz_Mnt, /*!< \brief z Moment coefficient (inviscid contribution) for each monitoring surface. */ - *CEff_Mnt, /*!< \brief Efficiency (Cl/Cd) (inviscid contribution) for each boundary. */ - *CMerit_Mnt, /*!< \brief Rotor Figure of Merit (inviscid contribution) for each boundary. */ - *CT_Mnt, /*!< \brief Thrust coefficient (force in -x direction, inviscid contribution) for each boundary. */ - *CQ_Mnt, /*!< \brief Torque coefficient (moment in -x direction, inviscid contribution) for each boundary. */ - **CPressure, /*!< \brief Pressure coefficient for each boundary and vertex. */ - **CPressureTarget, /*!< \brief Target Pressure coefficient for each boundary and vertex. */ - **HeatFlux, /*!< \brief Heat transfer coefficient for each boundary and vertex. */ - **HeatFluxTarget, /*!< \brief Heat transfer coefficient for each boundary and vertex. */ - **YPlus, /*!< \brief Yplus for each boundary and vertex. */ - ***CharacPrimVar, /*!< \brief Value of the characteristic variables at each boundary. */ - *ForceInviscid, /*!< \brief Inviscid force for each boundary. */ - *MomentInviscid, /*!< \brief Inviscid moment for each boundary. */ - *ForceMomentum, /*!< \brief Inviscid force for each boundary. */ - *MomentMomentum, /*!< \brief Inviscid moment for each boundary. */ - InverseDesign; /*!< \brief Inverse design functional for each boundary. */ - su2double - **Inlet_Ptotal, /*!< \brief Value of the Total P. */ - **Inlet_Ttotal, /*!< \brief Value of the Total T. */ - ***Inlet_FlowDir; /*!< \brief Value of the Flow Direction. */ - - su2double - AllBound_CD_Inv, /*!< \brief Total drag coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CL_Inv, /*!< \brief Total lift coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CSF_Inv, /*!< \brief Total sideforce coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMx_Inv, /*!< \brief Total x moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMy_Inv, /*!< \brief Total y moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMz_Inv, /*!< \brief Total z moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CFx_Inv, /*!< \brief Total x force coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CFy_Inv, /*!< \brief Total y force coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CFz_Inv, /*!< \brief Total z force coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CoPx_Inv, /*!< \brief Total x moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CoPy_Inv, /*!< \brief Total y moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CoPz_Inv, /*!< \brief Total z moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CEff_Inv, /*!< \brief Efficient coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMerit_Inv, /*!< \brief Rotor Figure of Merit (inviscid contribution) for all the boundaries. */ - AllBound_CT_Inv, /*!< \brief Total thrust coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CQ_Inv; /*!< \brief Total torque coefficient (inviscid contribution) for all the boundaries. */ - - - su2double - AllBound_CD_Mnt, /*!< \brief Total drag coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CL_Mnt, /*!< \brief Total lift coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CSF_Mnt, /*!< \brief Total sideforce coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMx_Mnt, /*!< \brief Total x moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMy_Mnt, /*!< \brief Total y moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMz_Mnt, /*!< \brief Total z moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CFx_Mnt, /*!< \brief Total x force coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CFy_Mnt, /*!< \brief Total y force coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CFz_Mnt, /*!< \brief Total z force coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CoPx_Mnt, /*!< \brief Total x moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CoPy_Mnt, /*!< \brief Total y moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CoPz_Mnt, /*!< \brief Total z moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CEff_Mnt, /*!< \brief Efficient coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMerit_Mnt, /*!< \brief Rotor Figure of Merit (inviscid contribution) for all the boundaries. */ - AllBound_CT_Mnt, /*!< \brief Total thrust coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CQ_Mnt; /*!< \brief Total torque coefficient (inviscid contribution) for all the boundaries. */ - - su2double - Total_ComboObj, /*!< \brief Total 'combo' objective for all monitored boundaries */ - Total_CD, /*!< \brief Total drag coefficient for all the boundaries. */ - Total_CL, /*!< \brief Total lift coefficient for all the boundaries. */ - Total_CSF, /*!< \brief Total sideforce coefficient for all the boundaries. */ - Total_CMx, /*!< \brief Total x moment coefficient for all the boundaries. */ - Total_CMy, /*!< \brief Total y moment coefficient for all the boundaries. */ - Total_CMz, /*!< \brief Total z moment coefficient for all the boundaries. */ - Total_CoPx, /*!< \brief Total x moment coefficient for all the boundaries. */ - Total_CoPy, /*!< \brief Total y moment coefficient for all the boundaries. */ - Total_CoPz, /*!< \brief Total z moment coefficient for all the boundaries. */ - Total_CFx, /*!< \brief Total x force coefficient for all the boundaries. */ - Total_CFy, /*!< \brief Total y force coefficient for all the boundaries. */ - Total_CFz, /*!< \brief Total z force coefficient for all the boundaries. */ - Total_CEff, /*!< \brief Total efficiency coefficient for all the boundaries. */ - Total_CMerit, /*!< \brief Total rotor Figure of Merit for all the boundaries. */ - Total_CT, /*!< \brief Total thrust coefficient for all the boundaries. */ - Total_CQ, /*!< \brief Total torque coefficient for all the boundaries. */ - Total_Heat, /*!< \brief Total heat load for all the boundaries. */ - Total_MaxHeat, /*!< \brief Maximum heat flux on all boundaries. */ - Total_CpDiff, /*!< \brief Total Equivalent Area coefficient for all the boundaries. */ - Total_HeatFluxDiff, /*!< \brief Total Equivalent Area coefficient for all the boundaries. */ - Total_Custom_ObjFunc, /*!< \brief Total custom objective function for all the boundaries. */ - Total_MassFlowRate; /*!< \brief Total Mass Flow Rate on monitored boundaries. */ - su2double - *Surface_CL, /*!< \brief Lift coefficient for each monitoring surface. */ - *Surface_CD, /*!< \brief Drag coefficient for each monitoring surface. */ - *Surface_CSF, /*!< \brief Side-force coefficient for each monitoring surface. */ - *Surface_CEff, /*!< \brief Side-force coefficient for each monitoring surface. */ - *Surface_CFx, /*!< \brief x Force coefficient for each monitoring surface. */ - *Surface_CFy, /*!< \brief y Force coefficient for each monitoring surface. */ - *Surface_CFz, /*!< \brief z Force coefficient for each monitoring surface. */ - *Surface_CMx, /*!< \brief x Moment coefficient for each monitoring surface. */ - *Surface_CMy, /*!< \brief y Moment coefficient for each monitoring surface. */ - *Surface_CMz, /*!< \brief z Moment coefficient for each monitoring surface. */ - *Surface_HF_Visc, /*!< \brief Total (integrated) heat flux for each monitored surface. */ - *Surface_MaxHF_Visc; /*!< \brief Maximum heat flux for each monitored surface. */ - - su2double *SecondaryVar_i, /*!< \brief Auxiliary vector for storing the solution at point i. */ - *SecondaryVar_j; /*!< \brief Auxiliary vector for storing the solution at point j. */ - su2double *PrimVar_i, /*!< \brief Auxiliary vector for storing the solution at point i. */ - *PrimVar_j; /*!< \brief Auxiliary vector for storing the solution at point j. */ - bool space_centered, /*!< \brief True if space centered scheeme used. */ - euler_implicit, /*!< \brief True if euler implicit scheme used. */ - least_squares; /*!< \brief True if computing gradients by least squares. */ - su2double Gamma; /*!< \brief Fluid's Gamma constant (ratio of specific heats). */ - su2double Gamma_Minus_One; /*!< \brief Fluids's Gamma - 1.0 . */ - - su2double *Primitive, /*!< \brief Auxiliary nPrimVar vector. */ - *Primitive_i, /*!< \brief Auxiliary nPrimVar vector for storing the primitive at point i. */ - *Primitive_j; /*!< \brief Auxiliary nPrimVar vector for storing the primitive at point j. */ - - CFluidModel *FluidModel; /*!< \brief fluid model used in the solver */ - su2double **Preconditioner; /*!< \brief Auxiliary matrix for storing the low speed preconditioner. */ - - /* Sliding meshes variables */ - - su2double ****SlidingState; - int **SlidingStateNodes; - - CIncEulerVariable* nodes = nullptr; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ - - /*! - * \brief Return nodes to allow CSolver::base_nodes to be set. - */ - inline CVariable* GetBaseClassPointerToNodes() override { return nodes; } - -public: - - /*! - * \brief Constructor of the class. - */ - CIncEulerSolver(void); - - /*! - * \overload - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - CIncEulerSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); - - /*! - * \brief Destructor of the class. - */ - virtual ~CIncEulerSolver(void); - - /*! - * \brief Set the solver nondimensionalization. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void SetNondimensionalization(CConfig *config, unsigned short iMesh); - - /*! - * \brief Compute the pressure at the infinity. - * \return Value of the pressure at the infinity. - */ - CFluidModel* GetFluidModel(void); - - /*! - * \brief Compute the density at the infinity. - * \return Value of the density at the infinity. - */ - su2double GetDensity_Inf(void); - - /*! - * \brief Compute 2-norm of the velocity at the infinity. - * \return Value of the 2-norm of the velocity at the infinity. - */ - su2double GetModVelocity_Inf(void); - - /*! - * \brief Compute the pressure at the infinity. - * \return Value of the pressure at the infinity. - */ - su2double GetPressure_Inf(void); - - /*! - * \brief Get the temperature value at infinity. - * \return Value of the temperature at infinity. - */ - su2double GetTemperature_Inf(void); - - /*! - * \brief Compute the density multiply by velocity at the infinity. - * \param[in] val_dim - Index of the velocity vector. - * \return Value of the density multiply by the velocity at the infinity. - */ - su2double GetDensity_Velocity_Inf(unsigned short val_dim); - - /*! - * \brief Get the velocity at the infinity. - * \param[in] val_dim - Index of the velocity vector. - * \return Value of the velocity at the infinity. - */ - su2double GetVelocity_Inf(unsigned short val_dim); - - /*! - * \brief Get the velocity at the infinity. - * \return Value of the velocity at the infinity. - */ - su2double *GetVelocity_Inf(void); - - /*! - * \brief Set the velocity at infinity. - * \param[in] val_dim - Index of the velocity vector. - * \param[in] val_velocity - Value of the velocity. - */ - void SetVelocity_Inf(unsigned short val_dim, su2double val_velocity); - - /*! - * \brief Compute the time step for solving the Euler equations. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] Iteration - Value of the current iteration. - */ - void SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh, unsigned long Iteration); - - /*! - * \brief Compute the spatial integration using a centered scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - void Centered_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh, unsigned short iRKStep); - - /*! - * \brief Compute the spatial integration using a upwind scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Upwind_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh); - - /*! - * \brief Source term integration. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] second_numerics - Description of the second numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CNumerics *second_numerics, - CConfig *config, unsigned short iMesh); - - /*! - * \brief Source term integration. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh); - - /*! - * \brief Compute primitive variables and their gradients. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - * \param[in] Output - boolean to determine whether to print output. - */ - void Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh); - - /*! - * \brief Compute the velocity^2, SoundSpeed, Pressure, Enthalpy, Viscosity. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] Output - boolean to determine whether to print output. - * \return - The number of non-physical points. - */ - unsigned long SetPrimitive_Variables(CSolver **solver_container, CConfig *config, bool Output); - - /*! - * \brief Compute a pressure sensor switch. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void SetCentered_Dissipation_Sensor(CGeometry *geometry, CConfig *config); - - /*! - * \brief Compute the gradient of the primitive variables using Green-Gauss method, - * and stores the result in the Gradient_Primitive variable. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] reconstruction - indicator that the gradient being computed is for upwind reconstruction. - */ - void SetPrimitive_Gradient_GG(CGeometry *geometry, CConfig *config, bool reconstruction = false); - - /*! - * \brief Compute the gradient of the primitive variables using a Least-Squares method, - * and stores the result in the Gradient_Primitive variable. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] reconstruction - indicator that the gradient being computed is for upwind reconstruction. - */ - void SetPrimitive_Gradient_LS(CGeometry *geometry, CConfig *config, bool reconstruction = false); - - /*! - * \brief Compute the limiter of the primitive variables. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void SetPrimitive_Limiter(CGeometry *geometry, CConfig *config); - - /*! - * \brief Compute the undivided laplacian for the solution, except the energy equation. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void SetUndivided_Laplacian(CGeometry *geometry, CConfig *config); - - /*! - * \brief Compute the max eigenvalue. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void SetMax_Eigenvalue(CGeometry *geometry, CConfig *config); - - /*! - * \author H. Kline - * \brief Compute weighted-sum "combo" objective output - * \param[in] config - Definition of the particular problem. - */ - void Evaluate_ObjFunc(CConfig *config); - - /*! - * \author: T. Kattmann - * \brief Impose via the residual the Euler wall boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Euler_Wall(CGeometry *geometry, - CSolver **solver_container, - CNumerics *conv_numerics, - CNumerics *visc_numerics, - CConfig *config, - unsigned short val_marker) override; - - /*! - * \brief Impose the far-field boundary condition using characteristics. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Far_Field(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose the symmetry boundary condition using the residual. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Sym_Plane(CGeometry *geometry, - CSolver **solver_container, - CNumerics *conv_numerics, - CNumerics *visc_numerics, - CConfig *config, - unsigned short val_marker) override; - - /*! - * \brief Impose a subsonic inlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose a custom or verification boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the convective numerical method. - * \param[in] visc_numerics - Description of the viscous numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Custom(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose the outlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose the interface state across sliding meshes. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - void BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config); - - /*! - * \brief Impose a periodic boundary condition by summing contributions from the complete control volume. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - void BC_Periodic(CGeometry *geometry, CSolver **solver_container, - CNumerics *numerics, CConfig *config); - - /*! - * \brief compare to values. - * \param[in] a - value 1. - * \param[in] b - value 2. - */ - static bool Compareval(std::vector a,std::vector b); - - /*! - * \brief Update the solution using a Runge-Kutta scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - void ExplicitRK_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iRKStep); - - /*! - * \brief Update the solution using the explicit Euler scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void ExplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief Compute the pressure forces and all the adimensional coefficients. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Pressure_Forces(CGeometry *geometry, CConfig *config); - - /*! - * \brief Compute the pressure forces and all the adimensional coefficients. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Momentum_Forces(CGeometry *geometry, CConfig *config); - - /*! - * \brief Update the solution using an implicit Euler scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief Compute a suitable under-relaxation parameter to limit the change in the solution variables over a nonlinear iteration for stability. - * \param[in] solver - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void ComputeUnderRelaxationFactor(CSolver **solver, CConfig *config); - - /*! - * \brief Provide the non dimensional lift coefficient (inviscid contribution). - * \param val_marker Surface where the coefficient is going to be computed. - * \return Value of the lift coefficient (inviscid contribution) on the surface val_marker. - */ - su2double GetCLift_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional lift coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the lift coefficient on the surface val_marker. - */ - su2double GetSurface_CL(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional drag coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the drag coefficient on the surface val_marker. - */ - su2double GetSurface_CD(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional side-force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side-force coefficient on the surface val_marker. - */ - su2double GetSurface_CSF(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional side-force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side-force coefficient on the surface val_marker. - */ - su2double GetSurface_CEff(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional x force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x force coefficient on the surface val_marker. - */ - su2double GetSurface_CFx(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional y force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y force coefficient on the surface val_marker. - */ - su2double GetSurface_CFy(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional z force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z force coefficient on the surface val_marker. - */ - su2double GetSurface_CFz(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional x moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMx(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional y moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMy(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional z moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMz(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional lift coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the lift coefficient on the surface val_marker. - */ - su2double GetSurface_CL_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional drag coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the drag coefficient on the surface val_marker. - */ - su2double GetSurface_CD_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional side-force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side-force coefficient on the surface val_marker. - */ - su2double GetSurface_CSF_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional side-force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side-force coefficient on the surface val_marker. - */ - su2double GetSurface_CEff_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional x force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x force coefficient on the surface val_marker. - */ - su2double GetSurface_CFx_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional y force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y force coefficient on the surface val_marker. - */ - su2double GetSurface_CFy_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional z force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z force coefficient on the surface val_marker. - */ - su2double GetSurface_CFz_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional x moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMx_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional y moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMy_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional z moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMz_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional lift coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the lift coefficient on the surface val_marker. - */ - su2double GetSurface_CL_Mnt(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional drag coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the drag coefficient on the surface val_marker. - */ - su2double GetSurface_CD_Mnt(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional side-force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side-force coefficient on the surface val_marker. - */ - su2double GetSurface_CSF_Mnt(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional side-force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side-force coefficient on the surface val_marker. - */ - su2double GetSurface_CEff_Mnt(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional x force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x force coefficient on the surface val_marker. - */ - su2double GetSurface_CFx_Mnt(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional y force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y force coefficient on the surface val_marker. - */ - su2double GetSurface_CFy_Mnt(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional z force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z force coefficient on the surface val_marker. - */ - su2double GetSurface_CFz_Mnt(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional x moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMx_Mnt(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional y moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMy_Mnt(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional z moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMz_Mnt(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional drag coefficient (inviscid contribution). - * \param val_marker Surface where the coeficient is going to be computed. - * \return Value of the drag coefficient (inviscid contribution) on the surface val_marker. - */ - su2double GetCD_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional sideforce coefficient (inviscid contribution). - * \param val_marker Surface where the coeficient is going to be computed. - * \return Value of the sideforce coefficient (inviscid contribution) on the surface val_marker. - */ - su2double GetCSF_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional efficiency coefficient (inviscid contribution). - * \param val_marker Surface where the coeficient is going to be computed. - * \return Value of the efficiency coefficient (inviscid contribution) on the surface val_marker. - */ - su2double GetCEff_Inv(unsigned short val_marker); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional sideforce coefficient. - * \return Value of the sideforce coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CSF(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CEff(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional Equivalent Area coefficient. - * \return Value of the Equivalent Area coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CpDiff(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional Equivalent Area coefficient. - * \return Value of the Equivalent Area coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_HeatFluxDiff(void); - - /*! - * \brief Set the value of the Equivalent Area coefficient. - * \param[in] val_cequivarea - Value of the Equivalent Area coefficient. - */ - void SetTotal_CpDiff(su2double val_pressure); - - /*! - * \brief Set the value of the Equivalent Area coefficient. - * \param[in] val_cequivarea - Value of the Equivalent Area coefficient. - */ - void SetTotal_HeatFluxDiff(su2double val_heat); - - /*! - * \brief Store the total (inviscid + viscous) non dimensional lift coefficient. - * \param[in] val_Total_CLift - Value of the total lift coefficient. - */ - void SetTotal_CLift(su2double val_Total_CLift); - - /*! - * \brief Set the value of the custom objective function. - * \param[in] val_Total_Custom_ObjFunc - Value of the total custom objective function. - * \param[in] val_weight - Value of the weight for the custom objective function. - */ - void SetTotal_Custom_ObjFunc(su2double val_total_custom_objfunc, su2double val_weight); - - /*! - * \brief Add the value of the custom objective function. - * \param[in] val_Total_Custom_ObjFunc - Value of the total custom objective function. - * \param[in] val_weight - Value of the weight for the custom objective function. - */ - void AddTotal_Custom_ObjFunc(su2double val_total_custom_objfunc, su2double val_weight); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional lift coefficient. - * \return Value of the lift coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CL(void); - - /*! - * \author H. Kline - * \brief Set the total "combo" objective (weighted sum of other values). - * \param[in] ComboObj - Value of the combined objective. - */ - void SetTotal_ComboObj(su2double ComboObj); - - /*! - * \author H. Kline - * \brief Provide the total "combo" objective (weighted sum of other values). - * \return Value of the "combo" objective values. - */ - su2double GetTotal_ComboObj(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CD(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional x moment coefficient. - * \return Value of the moment x coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CMx(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional y moment coefficient. - * \return Value of the moment y coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CMy(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional z moment coefficient. - * \return Value of the moment z coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CMz(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional x moment coefficient. - * \return Value of the moment x coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CoPx(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional y moment coefficient. - * \return Value of the moment y coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CoPy(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional z moment coefficient. - * \return Value of the moment z coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CoPz(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional x force coefficient. - * \return Value of the force x coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CFx(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional y force coefficient. - * \return Value of the force y coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CFy(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional z force coefficient. - * \return Value of the force z coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CFz(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional thrust coefficient. - * \return Value of the rotor efficiency coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CT(void); - - /*! - * \brief Store the total (inviscid + viscous) non dimensional thrust coefficient. - * \param[in] val_Total_CT - Value of the total thrust coefficient. - */ - void SetTotal_CT(su2double val_Total_CT); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional torque coefficient. - * \return Value of the rotor efficiency coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CQ(void); - - /*! - * \brief Provide the total heat load. - * \return Value of the heat load (viscous contribution). - */ - su2double GetTotal_HeatFlux(void); - - /*! - * \brief Provide the total heat load. - * \return Value of the heat load (viscous contribution). - */ - su2double GetTotal_MaxHeatFlux(void); - - /*! - * \brief Store the total (inviscid + viscous) non dimensional torque coefficient. - * \param[in] val_Total_CQ - Value of the total torque coefficient. - */ - void SetTotal_CQ(su2double val_Total_CQ); - - /*! - * \brief Store the total heat load. - * \param[in] val_Total_Heat - Value of the heat load. - */ - void SetTotal_HeatFlux(su2double val_Total_Heat); - - /*! - * \brief Store the total heat load. - * \param[in] val_Total_Heat - Value of the heat load. - */ - void SetTotal_MaxHeatFlux(su2double val_Total_MaxHeat); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional rotor Figure of Merit. - * \return Value of the rotor efficiency coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CMerit(void); - - /*! - * \brief Provide the total custom objective function. - * \return Value of the custom objective function. - */ - su2double GetTotal_Custom_ObjFunc(void); - - /*! - * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. - * \param[in] val_Total_CDrag - Value of the total drag coefficient. - */ - void SetTotal_CD(su2double val_Total_CDrag); - - /*! - * \brief Get the inviscid contribution to the lift coefficient. - * \return Value of the lift coefficient (inviscid contribution). - */ - su2double GetAllBound_CL_Inv(void); - - /*! - * \brief Get the inviscid contribution to the drag coefficient. - * \return Value of the drag coefficient (inviscid contribution). - */ - su2double GetAllBound_CD_Inv(void); - - /*! - * \brief Get the inviscid contribution to the sideforce coefficient. - * \return Value of the sideforce coefficient (inviscid contribution). - */ - su2double GetAllBound_CSF_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CEff_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CMx_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CMy_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CMz_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CoPx_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CoPy_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CoPz_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CFx_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CFy_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CFz_Inv(void); - - /*! - * \brief Get the inviscid contribution to the lift coefficient. - * \return Value of the lift coefficient (inviscid contribution). - */ - su2double GetAllBound_CL_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the drag coefficient. - * \return Value of the drag coefficient (inviscid contribution). - */ - su2double GetAllBound_CD_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the sideforce coefficient. - * \return Value of the sideforce coefficient (inviscid contribution). - */ - su2double GetAllBound_CSF_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CEff_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CMx_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CMy_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CMz_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CoPx_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CoPy_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CoPz_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CFx_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CFy_Mnt(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CFz_Mnt(void); - - /*! - * \brief Provide the Pressure coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - su2double GetCPressure(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Provide the Target Pressure coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - su2double GetCPressureTarget(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Set the value of the target Pressure coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - void SetCPressureTarget(unsigned short val_marker, unsigned long val_vertex, su2double val_pressure); - - /*! - * \brief Value of the characteristic variables at the boundaries. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - su2double *GetCharacPrimVar(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Set the total residual adding the term that comes from the Dual Time Strategy. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - */ - void SetResidual_DualTime(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iRKStep, unsigned short iMesh, unsigned short RunTime_EqSystem); - - /*! - * \brief Load a solution from a restart file. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - Container vector with all of the solvers. - * \param[in] config - Definition of the particular problem. - * \param[in] val_iter - Current external iteration number. - * \param[in] val_update_geo - Flag for updating coords and grid velocity. - */ - void LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo); - - /*! - * \brief Set the initial condition for the Euler Equations. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] ExtIter - External iteration. - */ - void SetInitialCondition(CGeometry **geometry, CSolver ***solver_container, CConfig *config, unsigned long TimeIter); - - /*! - * \brief Set the freestream pressure. - * \param[in] Value of freestream pressure. - */ - void SetPressure_Inf(su2double p_inf); - - /*! - * \brief Set the freestream temperature. - * \param[in] Value of freestream temperature. - */ - void SetTemperature_Inf(su2double t_inf); - - /*! - * \brief Set the freestream temperature. - * \param[in] Value of freestream temperature. - */ - void SetDensity_Inf(su2double rho_inf); - - /*! - * \brief Set the solution using the Freestream values. - * \param[in] config - Definition of the particular problem. - */ - void SetFreeStream_Solution(CConfig *config); - - /*! - * \brief Update the Beta parameter for the incompressible preconditioner. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - current mesh level for the multigrid. - */ - void SetBeta_Parameter(CGeometry *geometry, CSolver **solver_container, - CConfig *config, unsigned short iMesh); - - /*! - * \brief Compute the preconditioner for low-Mach flows. - * \param[in] iPoint - Index of the grid point - * \param[in] config - Definition of the particular problem. - */ - void SetPreconditioner(CConfig *config, unsigned long iPoint); - - /*! - * \brief Value of the total temperature at an inlet boundary. - * \param[in] val_marker - Surface marker where the total temperature is evaluated. - * \param[in] val_vertex - Vertex of the marker val_marker where the total temperature is evaluated. - * \return Value of the total temperature - */ - su2double GetInlet_Ttotal(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Value of the total pressure at an inlet boundary. - * \param[in] val_marker - Surface marker where the total pressure is evaluated. - * \param[in] val_vertex - Vertex of the marker val_marker where the total pressure is evaluated. - * \return Value of the total pressure - */ - su2double GetInlet_Ptotal(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief A component of the unit vector representing the flow direction at an inlet boundary. - * \param[in] val_marker - Surface marker where the flow direction is evaluated - * \param[in] val_vertex - Vertex of the marker val_marker where the flow direction is evaluated - * \param[in] val_dim - The component of the flow direction unit vector to be evaluated - * \return Component of a unit vector representing the flow direction. - */ - su2double GetInlet_FlowDir(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim); - - /*! - * \brief Set a uniform inlet profile - * - * The values at the inlet are set to match the values specified for - * inlets in the configuration file. - * - * \param[in] config - Definition of the particular problem. - * \param[in] iMarker - Surface marker where the coefficient is computed. - */ - void SetUniformInlet(CConfig* config, unsigned short iMarker); - - /*! - * \brief Store of a set of provided inlet profile values at a vertex. - * \param[in] val_inlet - vector containing the inlet values for the current vertex. - * \param[in] iMarker - Surface marker where the coefficient is computed. - * \param[in] iVertex - Vertex of the marker iMarker where the inlet is being set. - */ - void SetInletAtVertex(su2double *val_inlet, unsigned short iMarker, unsigned long iVertex); - - /*! - * \brief Get the set of value imposed at an inlet. - * \param[in] val_inlet - vector returning the inlet values for the current vertex. - * \param[in] val_inlet_point - Node index where the inlet is being set. - * \param[in] val_kind_marker - Enumerated type for the particular inlet type. - * \param[in] geometry - Geometrical definition of the problem. - * \param config - Definition of the particular problem. - * \return Value of the face area at the vertex. - */ - su2double GetInletAtVertex(su2double *val_inlet, - unsigned long val_inlet_point, - unsigned short val_kind_marker, - string val_marker, - CGeometry *geometry, - CConfig *config); - - /*! - * \brief A virtual member. - */ - void GetOutlet_Properties(CGeometry *geometry, CConfig *config, unsigned short iMesh, bool Output); - - /*! - * \brief Allocates the final pointer of SlidingState depending on how many donor vertex donate to it. That number is stored in SlidingStateNodes[val_marker][val_vertex]. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - */ - void SetSlidingStateStructure(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Set the outer state for fluid interface nodes. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - * \param[in] val_state - requested state component - * \param[in] donor_index - index of the donor node to set - * \param[in] component - set value - */ - void SetSlidingState(unsigned short val_marker, unsigned long val_vertex, unsigned short val_state, unsigned long donor_index, su2double component); - - /*! - * \brief Set the number of outer state for fluid interface nodes. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - * \param[in] value - number of outer states - */ - void SetnSlidingStates(unsigned short val_marker, unsigned long val_vertex, int value); - - /*! - * \brief Get the number of outer state for fluid interface nodes. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - */ - int GetnSlidingStates(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Get the outer state for fluid interface nodes. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - * \param[in] val_state - requested state component - */ - su2double GetSlidingState(unsigned short val_marker, unsigned long val_vertex, unsigned short val_state, unsigned long donor_index); - - /*! - * \brief Compute the global error measures (L2, Linf) for verification cases. - * \param[in] geometry - Geometrical definition. - * \param[in] config - Definition of the particular problem. - */ - void ComputeVerificationError(CGeometry *geometry, CConfig *config); - -}; - -/*! - * \class CNSSolver - * \brief Main class for defining the Navier-Stokes flow solver. - * \ingroup Navier_Stokes_Equations - * \author F. Palacios - */ -class CNSSolver : public CEulerSolver { -private: - su2double Viscosity_Inf; /*!< \brief Viscosity at the infinity. */ - su2double Tke_Inf; /*!< \brief Turbulent kinetic energy at the infinity. */ - su2double Prandtl_Lam, /*!< \brief Laminar Prandtl number. */ - Prandtl_Turb; /*!< \brief Turbulent Prandtl number. */ - su2double *CD_Visc, /*!< \brief Drag coefficient (viscous contribution) for each boundary. */ - *CL_Visc, /*!< \brief Lift coefficient (viscous contribution) for each boundary. */ - *CSF_Visc, /*!< \brief Side force coefficient (viscous contribution) for each boundary. */ - *CMx_Visc, /*!< \brief Moment x coefficient (viscous contribution) for each boundary. */ - *CMy_Visc, /*!< \brief Moment y coefficient (viscous contribution) for each boundary. */ - *CMz_Visc, /*!< \brief Moment z coefficient (viscous contribution) for each boundary. */ - *CoPx_Visc, /*!< \brief Moment x coefficient (viscous contribution) for each boundary. */ - *CoPy_Visc, /*!< \brief Moment y coefficient (viscous contribution) for each boundary. */ - *CoPz_Visc, /*!< \brief Moment z coefficient (viscous contribution) for each boundary. */ - *CFx_Visc, /*!< \brief Force x coefficient (viscous contribution) for each boundary. */ - *CFy_Visc, /*!< \brief Force y coefficient (viscous contribution) for each boundary. */ - *CFz_Visc, /*!< \brief Force z coefficient (viscous contribution) for each boundary. */ - *Surface_CL_Visc, /*!< \brief Lift coefficient (viscous contribution) for each monitoring surface. */ - *Surface_CD_Visc, /*!< \brief Drag coefficient (viscous contribution) for each monitoring surface. */ - *Surface_CSF_Visc, /*!< \brief Side-force coefficient (viscous contribution) for each monitoring surface. */ - *Surface_CEff_Visc, /*!< \brief Side-force coefficient (viscous contribution) for each monitoring surface. */ - *Surface_CFx_Visc, /*!< \brief Force x coefficient (viscous contribution) for each monitoring surface. */ - *Surface_CFy_Visc, /*!< \brief Force y coefficient (viscous contribution) for each monitoring surface. */ - *Surface_CFz_Visc, /*!< \brief Force z coefficient (viscous contribution) for each monitoring surface. */ - *Surface_CMx_Visc, /*!< \brief Moment x coefficient (viscous contribution) for each monitoring surface. */ - *Surface_CMy_Visc, /*!< \brief Moment y coefficient (viscous contribution) for each monitoring surface. */ - *Surface_CMz_Visc, /*!< \brief Moment z coefficient (viscous contribution) for each monitoring surface. */ - *Surface_Buffet_Metric, /*!< \brief Integrated separation sensor for each monitoring surface. */ - *CEff_Visc, /*!< \brief Efficiency (Cl/Cd) (Viscous contribution) for each boundary. */ - *CMerit_Visc, /*!< \brief Rotor Figure of Merit (Viscous contribution) for each boundary. */ - *Buffet_Metric, /*!< \brief Integrated separation sensor for each boundary. */ - *CT_Visc, /*!< \brief Thrust coefficient (viscous contribution) for each boundary. */ - *CQ_Visc, /*!< \brief Torque coefficient (viscous contribution) for each boundary. */ - *HF_Visc, /*!< \brief Heat load (viscous contribution) for each boundary. */ - *MaxHF_Visc, /*!< \brief Maximum heat flux (viscous contribution) for each boundary. */ - ***HeatConjugateVar, /*!< \brief Conjugate heat transfer variables for each boundary and vertex. */ - ***CSkinFriction, /*!< \brief Skin friction coefficient for each boundary and vertex. */ - **Buffet_Sensor; /*!< \brief Separation sensor for each boundary and vertex. */ - su2double Total_Buffet_Metric; /*!< \brief Integrated separation sensor for all the boundaries. */ - su2double *ForceViscous, /*!< \brief Viscous force for each boundary. */ - *MomentViscous; /*!< \brief Inviscid moment for each boundary. */ - su2double - AllBound_CD_Visc, /*!< \brief Drag coefficient (viscous contribution) for all the boundaries. */ - AllBound_CL_Visc, /*!< \brief Lift coefficient (viscous contribution) for all the boundaries. */ - AllBound_CSF_Visc, /*!< \brief Sideforce coefficient (viscous contribution) for all the boundaries. */ - AllBound_CMx_Visc, /*!< \brief Moment x coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMy_Visc, /*!< \brief Moment y coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMz_Visc, /*!< \brief Moment z coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CoPx_Visc, /*!< \brief Moment x coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CoPy_Visc, /*!< \brief Moment y coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CoPz_Visc, /*!< \brief Moment z coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CEff_Visc, /*!< \brief Efficient coefficient (Viscous contribution) for all the boundaries. */ - AllBound_CFx_Visc, /*!< \brief Force x coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CFy_Visc, /*!< \brief Force y coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CFz_Visc, /*!< \brief Force z coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMerit_Visc, /*!< \brief Rotor Figure of Merit coefficient (Viscous contribution) for all the boundaries. */ - AllBound_CT_Visc, /*!< \brief Thrust coefficient (viscous contribution) for all the boundaries. */ - AllBound_CQ_Visc, /*!< \brief Torque coefficient (viscous contribution) for all the boundaries. */ - AllBound_HF_Visc, /*!< \brief Heat load (viscous contribution) for all the boundaries. */ - AllBound_MaxHF_Visc; /*!< \brief Maximum heat flux (viscous contribution) for all boundaries. */ - su2double - StrainMag_Max, - Omega_Max; /*!< \brief Maximum Strain Rate magnitude and Omega. */ - -public: - - /*! - * \brief Constructor of the class. - */ - CNSSolver(void); - - /*! - * \overload - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - CNSSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); - - /*! - * \brief Destructor of the class. - */ - ~CNSSolver(void); - - /*! - * \brief Provide the non dimensional lift coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the lift coefficient on the surface val_marker. - */ - su2double GetSurface_CL_Visc(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional drag coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the drag coefficient on the surface val_marker. - */ - su2double GetSurface_CD_Visc(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional side-force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side-force coefficient on the surface val_marker. - */ - su2double GetSurface_CSF_Visc(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional side-force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side-force coefficient on the surface val_marker. - */ - su2double GetSurface_CEff_Visc(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional x force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x force coefficient on the surface val_marker. - */ - su2double GetSurface_CFx_Visc(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional y force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y force coefficient on the surface val_marker. - */ - su2double GetSurface_CFy_Visc(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional z force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z force coefficient on the surface val_marker. - */ - su2double GetSurface_CFz_Visc(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional x moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMx_Visc(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional y moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMy_Visc(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional z moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMz_Visc(unsigned short val_marker); - - /*! - * \brief Provide the buffet metric. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the buffet metric on the surface val_marker. - */ - su2double GetSurface_Buffet_Metric(unsigned short val_marker); - - /*! - * \brief Get the inviscid contribution to the lift coefficient. - * \return Value of the lift coefficient (inviscid contribution). - */ - su2double GetAllBound_CL_Visc(void); - - /*! - * \brief Get the inviscid contribution to the drag coefficient. - * \return Value of the drag coefficient (inviscid contribution). - */ - su2double GetAllBound_CD_Visc(void); - - /*! - * \brief Get the inviscid contribution to the sideforce coefficient. - * \return Value of the sideforce coefficient (inviscid contribution). - */ - su2double GetAllBound_CSF_Visc(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CEff_Visc(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CMx_Visc(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CMy_Visc(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CMz_Visc(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CoPx_Visc(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CoPy_Visc(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CoPz_Visc(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CFx_Visc(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CFy_Visc(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CFz_Visc(void); - - /*! - * \brief Get the buffet metric. - * \return Value of the buffet metric. - */ - su2double GetTotal_Buffet_Metric(void); - - /*! - * \brief Compute the viscosity at the infinity. - * \return Value of the viscosity at the infinity. - */ - su2double GetViscosity_Inf(void); - - /*! - * \brief Get the turbulent kinetic energy at the infinity. - * \return Value of the turbulent kinetic energy at the infinity. - */ - su2double GetTke_Inf(void); - - /*! - * \brief Compute the time step for solving the Navier-Stokes equations with turbulence model. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] Iteration - Index of the current iteration. - */ - void SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh, unsigned long Iteration); - - /*! - * \brief Restart residual and compute gradients. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - * \param[in] Output - boolean to determine whether to print output. - */ - void Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output); - - /*! - * \brief Compute the velocity^2, SoundSpeed, Pressure, Enthalpy, Viscosity. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] Output - boolean to determine whether to print output. - * \return - The number of non-physical points. - */ - unsigned long SetPrimitive_Variables(CSolver **solver_container, CConfig *config, bool Output); - - /*! - * \brief Compute weighted-sum "combo" objective output - * \param[in] config - Definition of the particular problem. - */ - void Evaluate_ObjFunc(CConfig *config); - - /*! - * \brief Impose a constant heat-flux condition at the wall. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose the Navier-Stokes boundary condition (strong). - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the Navier-Stokes boundary condition (strong) with values from a CHT coupling. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_ConjugateHeat_Interface(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief Set the conjugate heat variables. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - * \param[in] pos_var - variable position (in vector of all conjugate heat variables) - */ - su2double GetConjugateHeatVariable(unsigned short val_marker, unsigned long val_vertex, unsigned short pos_var); - - /*! - * \brief Set the conjugate heat variables. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - * \param[in] pos_var - variable position (in vector of all conjugate heat variables) - * \param[in] relaxation factor - relaxation factor for the change of the variables - * \param[in] val_var - value of the variable - */ - void SetConjugateHeatVariable(unsigned short val_marker, unsigned long val_vertex, unsigned short pos_var, su2double relaxation_factor, su2double val_var); - - /*! - * \brief Compute the viscous forces and all the addimensional coefficients. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Friction_Forces(CGeometry *geometry, CConfig *config); - - /*! - * \brief Compute the buffet sensor. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Buffet_Monitoring(CGeometry *geometry, CConfig *config); - - /*! - * \brief Get the total heat flux. - * \param[in] val_marker - Surface marker where the heat flux is computed. - * \return Value of the integrated heat flux (viscous contribution) on the surface val_marker. - */ - su2double GetSurface_HF_Visc(unsigned short val_marker); - - /*! - * \brief Get the maximum (per surface) heat flux. - * \param[in] val_marker - Surface marker where the heat flux is computed. - * \return Value of the maximum heat flux (viscous contribution) on the surface val_marker. - */ - su2double GetSurface_MaxHF_Visc(unsigned short val_marker); - - /*! - * \brief Get the non dimensional lift coefficient (viscous contribution). - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the lift coefficient (viscous contribution) on the surface val_marker. - */ - su2double GetCL_Visc(unsigned short val_marker); - - /*! - * \brief Get the non dimensional sideforce coefficient (viscous contribution). - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the sideforce coefficient (viscous contribution) on the surface val_marker. - */ - su2double GetCSF_Visc(unsigned short val_marker); - - /*! - * \brief Get the non dimensional drag coefficient (viscous contribution). - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the drag coefficient (viscous contribution) on the surface val_marker. - */ - su2double GetCD_Visc(unsigned short val_marker); - - /*! - * \brief Compute the viscous residuals. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - void Viscous_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh, unsigned short iRKStep); - - /*! - * \brief Get the skin friction coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the skin friction coefficient. - */ - su2double GetCSkinFriction(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim); - - /*! - * \brief Get the skin friction coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the heat transfer coefficient. - */ - su2double GetHeatFlux(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Get the skin friction coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the heat transfer coefficient. - */ - su2double GetHeatFluxTarget(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Set the value of the target Pressure coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - void SetHeatFluxTarget(unsigned short val_marker, unsigned long val_vertex, su2double val_heat); - - - /*! - * \brief Get the value of the buffet sensor - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the buffet sensor. - */ - su2double GetBuffetSensor(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Get the y plus. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the y plus. - */ - su2double GetYPlus(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Get the max Omega. - * \return Value of the max Omega. - */ - su2double GetOmega_Max(void); - - /*! - * \brief Get the max Strain rate magnitude. - * \return Value of the max Strain rate magnitude. - */ - su2double GetStrainMag_Max(void); - - /*! - * \brief A virtual member. - * \return Value of the StrainMag_Max - */ - void SetStrainMag_Max(su2double val_strainmag_max); - - /*! - * \brief A virtual member. - * \return Value of the Omega_Max - */ - void SetOmega_Max(su2double val_omega_max); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition. - * \param[in] config - Definition of the particular problem. - */ - void SetRoe_Dissipation(CGeometry *geometry, CConfig *config); - - /*! - * \brief Computes the wall shear stress (Tau_Wall) on the surface using a wall function. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void SetTauWall_WF(CGeometry *geometry, CSolver** solver_container, CConfig* config); - -}; - -/*! - * \class CIncNSSolver - * \brief Main class for defining the incompressible Navier-Stokes flow solver. - * \ingroup Navier_Stokes_Equations - * \author F. Palacios, T. Economon, T. Albring - */ -class CIncNSSolver : public CIncEulerSolver { -private: - su2double Viscosity_Inf; /*!< \brief Viscosity at the infinity. */ - su2double Tke_Inf; /*!< \brief Turbulent kinetic energy at the infinity. */ - su2double - *CD_Visc, /*!< \brief Drag coefficient (viscous contribution) for each boundary. */ - *CL_Visc, /*!< \brief Lift coefficient (viscous contribution) for each boundary. */ - *CSF_Visc, /*!< \brief Side force coefficient (viscous contribution) for each boundary. */ - *CMx_Visc, /*!< \brief Moment x coefficient (viscous contribution) for each boundary. */ - *CMy_Visc, /*!< \brief Moment y coefficient (viscous contribution) for each boundary. */ - *CMz_Visc, /*!< \brief Moment z coefficient (viscous contribution) for each boundary. */ - *CoPx_Visc, /*!< \brief Moment x coefficient (viscous contribution) for each boundary. */ - *CoPy_Visc, /*!< \brief Moment y coefficient (viscous contribution) for each boundary. */ - *CoPz_Visc, /*!< \brief Moment z coefficient (viscous contribution) for each boundary. */ - *CFx_Visc, /*!< \brief Force x coefficient (viscous contribution) for each boundary. */ - *CFy_Visc, /*!< \brief Force y coefficient (viscous contribution) for each boundary. */ - *CFz_Visc, /*!< \brief Force z coefficient (viscous contribution) for each boundary. */ - *Surface_CL_Visc, /*!< \brief Lift coefficient (viscous contribution) for each monitoring surface. */ - *Surface_CD_Visc, /*!< \brief Drag coefficient (viscous contribution) for each monitoring surface. */ - *Surface_CSF_Visc, /*!< \brief Side-force coefficient (viscous contribution) for each monitoring surface. */ - *Surface_CEff_Visc, /*!< \brief Side-force coefficient (viscous contribution) for each monitoring surface. */ - *Surface_CFx_Visc, /*!< \brief Force x coefficient (viscous contribution) for each monitoring surface. */ - *Surface_CFy_Visc, /*!< \brief Force y coefficient (viscous contribution) for each monitoring surface. */ - *Surface_CFz_Visc, /*!< \brief Force z coefficient (viscous contribution) for each monitoring surface. */ - *Surface_CMx_Visc, /*!< \brief Moment x coefficient (viscous contribution) for each monitoring surface. */ - *Surface_CMy_Visc, /*!< \brief Moment y coefficient (viscous contribution) for each monitoring surface. */ - *Surface_CMz_Visc, /*!< \brief Moment z coefficient (viscous contribution) for each monitoring surface. */ - *CEff_Visc, /*!< \brief Efficiency (Cl/Cd) (Viscous contribution) for each boundary. */ - *CMerit_Visc, /*!< \brief Rotor Figure of Merit (Viscous contribution) for each boundary. */ - *CT_Visc, /*!< \brief Thrust coefficient (viscous contribution) for each boundary. */ - *CQ_Visc, /*!< \brief Torque coefficient (viscous contribution) for each boundary. */ - *HF_Visc, /*!< \brief Heat load (viscous contribution) for each boundary. */ - *MaxHF_Visc, /*!< \brief Maximum heat flux (viscous contribution) for each boundary. */ - ***HeatConjugateVar, /*!< \brief Conjugate heat transfer variables for each boundary and vertex. */ - ***CSkinFriction; /*!< \brief Skin friction coefficient for each boundary and vertex. */ - su2double - *ForceViscous, /*!< \brief Viscous force for each boundary. */ - *MomentViscous; /*!< \brief Inviscid moment for each boundary. */ - su2double - AllBound_CD_Visc, /*!< \brief Drag coefficient (viscous contribution) for all the boundaries. */ - AllBound_CL_Visc, /*!< \brief Lift coefficient (viscous contribution) for all the boundaries. */ - AllBound_CSF_Visc, /*!< \brief Sideforce coefficient (viscous contribution) for all the boundaries. */ - AllBound_CMx_Visc, /*!< \brief Moment x coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMy_Visc, /*!< \brief Moment y coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMz_Visc, /*!< \brief Moment z coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CoPx_Visc, /*!< \brief Moment x coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CoPy_Visc, /*!< \brief Moment y coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CoPz_Visc, /*!< \brief Moment z coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CEff_Visc, /*!< \brief Efficient coefficient (Viscous contribution) for all the boundaries. */ - AllBound_CFx_Visc, /*!< \brief Force x coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CFy_Visc, /*!< \brief Force y coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CFz_Visc, /*!< \brief Force z coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMerit_Visc, /*!< \brief Rotor Figure of Merit coefficient (Viscous contribution) for all the boundaries. */ - AllBound_CT_Visc, /*!< \brief Thrust coefficient (viscous contribution) for all the boundaries. */ - AllBound_CQ_Visc, /*!< \brief Torque coefficient (viscous contribution) for all the boundaries. */ - AllBound_HF_Visc, /*!< \brief Heat load (viscous contribution) for all the boundaries. */ - AllBound_MaxHF_Visc; /*!< \brief Maximum heat flux (viscous contribution) for all boundaries. */ - su2double - StrainMag_Max, - Omega_Max; /*!< \brief Maximum Strain Rate magnitude and Omega. */ - -public: - - /*! - * \brief Constructor of the class. - */ - CIncNSSolver(void); - - /*! - * \overload - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - CIncNSSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); - - /*! - * \brief Destructor of the class. - */ - ~CIncNSSolver(void); - - /*! - * \brief Provide the non dimensional lift coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the lift coefficient on the surface val_marker. - */ - su2double GetSurface_CL_Visc(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional drag coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the drag coefficient on the surface val_marker. - */ - su2double GetSurface_CD_Visc(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional side-force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side-force coefficient on the surface val_marker. - */ - su2double GetSurface_CSF_Visc(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional side-force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side-force coefficient on the surface val_marker. - */ - su2double GetSurface_CEff_Visc(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional x force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x force coefficient on the surface val_marker. - */ - su2double GetSurface_CFx_Visc(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional y force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y force coefficient on the surface val_marker. - */ - su2double GetSurface_CFy_Visc(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional z force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z force coefficient on the surface val_marker. - */ - su2double GetSurface_CFz_Visc(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional x moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMx_Visc(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional y moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMy_Visc(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional z moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMz_Visc(unsigned short val_marker); - - /*! - * \brief Get the inviscid contribution to the lift coefficient. - * \return Value of the lift coefficient (inviscid contribution). - */ - su2double GetAllBound_CL_Visc(void); - - /*! - * \brief Get the inviscid contribution to the drag coefficient. - * \return Value of the drag coefficient (inviscid contribution). - */ - su2double GetAllBound_CD_Visc(void); - - /*! - * \brief Get the inviscid contribution to the sideforce coefficient. - * \return Value of the sideforce coefficient (inviscid contribution). - */ - su2double GetAllBound_CSF_Visc(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CEff_Visc(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CMx_Visc(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CMy_Visc(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CMz_Visc(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CoPx_Visc(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CoPy_Visc(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CoPz_Visc(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CFx_Visc(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CFy_Visc(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CFz_Visc(void); - - /*! - * \brief Compute the viscosity at the infinity. - * \return Value of the viscosity at the infinity. - */ - su2double GetViscosity_Inf(void); - - /*! - * \brief Get the turbulent kinetic energy at the infinity. - * \return Value of the turbulent kinetic energy at the infinity. - */ - su2double GetTke_Inf(void); - - /*! - * \brief Compute the time step for solving the Navier-Stokes equations with turbulence model. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] Iteration - Index of the current iteration. - */ - void SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh, unsigned long Iteration); - - /*! - * \brief Restart residual and compute gradients. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - * \param[in] Output - boolean to determine whether to print output. - */ - void Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output); - - /*! - * \brief Compute the velocity^2, SoundSpeed, Pressure, Enthalpy, Viscosity. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] Output - boolean to determine whether to print output. - * \return - The number of non-physical points. - */ - unsigned long SetPrimitive_Variables(CSolver **solver_container, CConfig *config, bool Output); - - /*! - * \brief Impose a no-slip condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose an isothermal temperature condition at the wall. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose the (received) conjugate heat variables. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_ConjugateHeat_Interface(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief Set the conjugate heat variables. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - * \param[in] pos_var - variable position (in vector of all conjugate heat variables) - * \param[in] relaxation factor - relaxation factor for the change of the variables - * \param[in] val_var - value of the variable - */ - void SetConjugateHeatVariable(unsigned short val_marker, unsigned long val_vertex, unsigned short pos_var, su2double relaxation_factor, su2double val_var); - - /*! - * \brief Set the conjugate heat variables. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - * \param[in] pos_var - variable position (in vector of all conjugate heat variables) - */ - su2double GetConjugateHeatVariable(unsigned short val_marker, unsigned long val_vertex, unsigned short pos_var); - - /*! - * \brief Compute the viscous forces and all the addimensional coefficients. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Friction_Forces(CGeometry *geometry, CConfig *config); - - /*! - * \brief Get the total heat flux. - * \param[in] val_marker - Surface marker where the heat flux is computed. - * \return Value of the integrated heat flux (viscous contribution) on the surface val_marker. - */ - su2double GetSurface_HF_Visc(unsigned short val_marker); - - /*! - * \brief Get the maximum (per surface) heat flux. - * \param[in] val_marker - Surface marker where the heat flux is computed. - * \return Value of the maximum heat flux (viscous contribution) on the surface val_marker. - */ - su2double GetSurface_MaxHF_Visc(unsigned short val_marker); - - /*! - * \brief Get the non dimensional lift coefficient (viscous contribution). - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the lift coefficient (viscous contribution) on the surface val_marker. - */ - su2double GetCL_Visc(unsigned short val_marker); - - /*! - * \brief Get the non dimensional sideforce coefficient (viscous contribution). - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the sideforce coefficient (viscous contribution) on the surface val_marker. - */ - su2double GetCSF_Visc(unsigned short val_marker); - - /*! - * \brief Get the non dimensional drag coefficient (viscous contribution). - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the drag coefficient (viscous contribution) on the surface val_marker. - */ - su2double GetCD_Visc(unsigned short val_marker); - - /*! - * \brief Compute the viscous residuals. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - void Viscous_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh, unsigned short iRKStep); - - /*! - * \brief Get the skin friction coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the skin friction coefficient. - */ - su2double GetCSkinFriction(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim); - - /*! - * \brief Get the skin friction coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the heat transfer coefficient. - */ - su2double GetHeatFlux(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Get the skin friction coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the heat transfer coefficient. - */ - su2double GetHeatFluxTarget(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Set the value of the target Pressure coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - void SetHeatFluxTarget(unsigned short val_marker, unsigned long val_vertex, su2double val_heat); - - /*! - * \brief Get the y plus. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the y plus. - */ - su2double GetYPlus(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Get the max Omega. - * \return Value of the max Omega. - */ - su2double GetOmega_Max(void); - - /*! - * \brief Get the max Strain rate magnitude. - * \return Value of the max Strain rate magnitude. - */ - su2double GetStrainMag_Max(void); - - /*! - * \brief A virtual member. - * \return Value of the StrainMag_Max - */ - void SetStrainMag_Max(su2double val_strainmag_max); - - /*! - * \brief A virtual member. - * \return Value of the Omega_Max - */ - void SetOmega_Max(su2double val_omega_max); - -}; - -/*! - * \class CTurbSolver - * \brief Main class for defining the turbulence model solver. - * \ingroup Turbulence_Model - * \author A. Bueno. - */ -class CTurbSolver : public CSolver { -protected: - su2double *FlowPrimVar_i, /*!< \brief Store the flow solution at point i. */ - *FlowPrimVar_j, /*!< \brief Store the flow solution at point j. */ - *lowerlimit, /*!< \brief contains lower limits for turbulence variables. */ - *upperlimit; /*!< \brief contains upper limits for turbulence variables. */ - su2double Gamma; /*!< \brief Fluid's Gamma constant (ratio of specific heats). */ - su2double Gamma_Minus_One; /*!< \brief Fluids's Gamma - 1.0 . */ - su2double*** Inlet_TurbVars; /*!< \brief Turbulence variables at inlet profiles */ - - CTurbVariable* snode; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ - - /* Sliding meshes variables */ - - su2double ****SlidingState; - int **SlidingStateNodes; - - CTurbVariable* nodes = nullptr; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ - - /*! - * \brief Return nodes to allow CSolver::base_nodes to be set. - */ - inline CVariable* GetBaseClassPointerToNodes() override { return nodes; } - -public: - - /*! - * \brief Constructor of the class. - */ - CTurbSolver(void); - - /*! - * \brief Destructor of the class. - */ - virtual ~CTurbSolver(void); - - /*! - * \brief Constructor of the class. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - CTurbSolver(CGeometry* geometry, CConfig *config); - - /*! - * \brief Compute the spatial integration using a upwind scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - - void Upwind_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, - unsigned short iMesh); - - /*! - * \brief Compute the viscous residuals for the turbulent equation. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - void Viscous_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh, unsigned short iRKStep); - - /*! - * \brief Impose the Symmetry Plane boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Sym_Plane(CGeometry *geometry, - CSolver **solver_container, - CNumerics *conv_numerics, - CNumerics *visc_numerics, - CConfig *config, - unsigned short val_marker) override; - - /*! - * \brief Impose via the residual the Euler wall boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Euler_Wall(CGeometry *geometry, - CSolver **solver_container, - CNumerics *conv_numerics, - CNumerics *visc_numerics, - CConfig *config, - unsigned short val_marker) override; - /*! - * \brief Impose via the residual the Euler wall boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Riemann(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose via the residual the Euler wall boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_TurboRiemann(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose via the residual the Euler wall boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Giles(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose a periodic boundary condition by summing contributions from the complete control volume. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - void BC_Periodic(CGeometry *geometry, CSolver **solver_container, - CNumerics *numerics, CConfig *config); - - /*! - * \brief Update the solution using an implicit solver. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief Set the total residual adding the term that comes from the Dual Time-Stepping Strategy. - * \param[in] geometry - Geometric definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - */ - void SetResidual_DualTime(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iRKStep, unsigned short iMesh, unsigned short RunTime_EqSystem); - - /*! - * \brief Compute a suitable under-relaxation parameter to limit the change in the solution variables over a nonlinear iteration for stability. - * \param[in] solver - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void ComputeUnderRelaxationFactor(CSolver **solver, CConfig *config); - - /*! - * \brief Load a solution from a restart file. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - Container vector with all of the solvers. - * \param[in] config - Definition of the particular problem. - * \param[in] val_iter - Current external iteration number. - * \param[in] val_update_geo - Flag for updating coords and grid velocity. - */ - void LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo); - - /*! - * \brief Get the outer state for fluid interface nodes. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - * \param[in] val_state - requested state component - */ - su2double GetSlidingState(unsigned short val_marker, unsigned long val_vertex, unsigned short val_state, unsigned long donor_index); - - /*! - * \brief Allocates the final pointer of SlidingState depending on how many donor vertex donate to it. That number is stored in SlidingStateNodes[val_marker][val_vertex]. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - */ - void SetSlidingStateStructure(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Set the outer state for fluid interface nodes. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - * \param[in] val_state - requested state component - * \param[in] donor_index - index of the donor node to set - * \param[in] component - set value - */ - void SetSlidingState(unsigned short val_marker, unsigned long val_vertex, unsigned short val_state, unsigned long donor_index, su2double component); - - /*! - * \brief Set the number of outer state for fluid interface nodes. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - * \param[in] value - number of outer states - */ - void SetnSlidingStates(unsigned short val_marker, unsigned long val_vertex, int value); - - /*! - * \brief Get the number of outer state for fluid interface nodes. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - */ - int GetnSlidingStates(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Set custom turbulence variables at the vertex of an inlet. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \param[in] iDim - Index of the turbulence variable (i.e. k is 0 in SST) - * \param[in] val_turb_var - Value of the turbulence variable to be used. - */ - void SetInlet_TurbVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim, su2double val_turb_var); -}; - -/*! - * \class CTurbSASolver - * \brief Main class for defining the turbulence model solver. - * \ingroup Turbulence_Model - * \author A. Bueno. - */ - -class CTurbSASolver: public CTurbSolver { -private: - su2double nu_tilde_Inf, nu_tilde_Engine, nu_tilde_ActDisk; - -public: - /*! - * \brief Constructor of the class. - */ - CTurbSASolver(void); - - /*! - * \overload - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] FluidModel - */ - CTurbSASolver(CGeometry *geometry, CConfig *config, unsigned short iMesh, CFluidModel* FluidModel); - - /*! - * \brief Destructor of the class. - */ - ~CTurbSASolver(void); - - /*! - * \brief Restart residual and compute gradients. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - * \param[in] Output - boolean to determine whether to print output. - */ - void Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh); - - /*! - * \brief Source term computation. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] second_numerics - Description of the second numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CNumerics *second_numerics, - CConfig *config, unsigned short iMesh); - - /*! - * \brief Source term computation. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh); - - /*! - * \brief Impose the Navier-Stokes wall boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the Navier-Stokes wall boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the Far Field boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Far_Field(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the inlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the inlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Inlet_Turbo(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the inlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Inlet_MixingPlane(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the outlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the engine inflow boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Engine_Inflow(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose the engine exhaust boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Engine_Exhaust(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose the interface boundary condition using the residual. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Interface_Boundary(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose the fluid interface boundary condition using tranfer data. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - void BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config); - - /*! - * \brief Impose the near-field boundary condition using the residual. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_NearField_Boundary(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose an actuator disk inlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_ActDisk_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose an actuator disk outlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_ActDisk_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose an actuator disk inlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_ActDisk(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker, bool val_inlet_surface); - - /*! - * \brief Set the solution using the Freestream values. - * \param[in] config - Definition of the particular problem. - */ - void SetFreeStream_Solution(CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] solver - Solver container - * \param[in] geometry - Geometrical definition. - * \param[in] config - Definition of the particular problem. - */ - void SetDES_LengthScale(CSolver** solver, CGeometry *geometry, CConfig *config); - - /*! - * \brief Store of a set of provided inlet profile values at a vertex. - * \param[in] val_inlet - vector containing the inlet values for the current vertex. - * \param[in] iMarker - Surface marker where the coefficient is computed. - * \param[in] iVertex - Vertex of the marker iMarker where the inlet is being set. - */ - void SetInletAtVertex(su2double *val_inlet, unsigned short iMarker, unsigned long iVertex); - - /*! - * \brief Get the set of value imposed at an inlet. - * \param[in] val_inlet - vector returning the inlet values for the current vertex. - * \param[in] val_inlet_point - Node index where the inlet is being set. - * \param[in] val_kind_marker - Enumerated type for the particular inlet type. - * \param[in] geometry - Geometrical definition of the problem. - * \param config - Definition of the particular problem. - * \return Value of the face area at the vertex. - */ - su2double GetInletAtVertex(su2double *val_inlet, - unsigned long val_inlet_point, - unsigned short val_kind_marker, - string val_marker, - CGeometry *geometry, - CConfig *config); - - /*! - * \brief Set a uniform inlet profile - * - * The values at the inlet are set to match the values specified for - * inlets in the configuration file. - * - * \param[in] config - Definition of the particular problem. - * \param[in] iMarker - Surface marker where the coefficient is computed. - */ - void SetUniformInlet(CConfig* config, unsigned short iMarker); - - /*! - * \brief Get the value of nu tilde at the far-field. - * \return Value of nu tilde at the far-field. - */ - su2double GetNuTilde_Inf(void); - - /*! - * \brief Compute nu tilde from the wall functions. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void SetNuTilde_WF(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, - CNumerics *visc_numerics, CConfig *config, unsigned short val_marker); -}; - -/*! - * \class CTurbSSTSolver - * \brief Main class for defining the turbulence model solver. - * \ingroup Turbulence_Model - * \author A. Campos, F. Palacios, T. Economon - */ - -class CTurbSSTSolver: public CTurbSolver { -private: - su2double *constants, /*!< \brief Constants for the model. */ - kine_Inf, /*!< \brief Free-stream turbulent kinetic energy. */ - omega_Inf; /*!< \brief Free-stream specific dissipation. */ - -public: - /*! - * \brief Constructor of the class. - */ - CTurbSSTSolver(void); - - /*! - * \overload - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - CTurbSSTSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); - - /*! - * \brief Destructor of the class. - */ - ~CTurbSSTSolver(void); - - /*! - * \brief Restart residual and compute gradients. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - * \param[in] Output - boolean to determine whether to print output. - */ - void Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output); - - /*! - * \brief Computes the eddy viscosity. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh); - - /*! - * \brief Source term computation. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] second_numerics - Description of the second numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CNumerics *second_numerics, - CConfig *config, unsigned short iMesh); - - /*! - * \brief Source term computation. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh); - - /*! - * \brief Impose the Navier-Stokes wall boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the Navier-Stokes wall boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the Far Field boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Far_Field(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the inlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the inlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Inlet_Turbo(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the inlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Inlet_MixingPlane(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the outlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the interface state across sliding meshes. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - void BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config); - - /*! - * \brief Get the constants for the SST model. - * \return A pointer to an array containing a set of constants - */ - su2double* GetConstants(); - - /*! - * \brief Set the solution using the Freestream values. - * \param[in] config - Definition of the particular problem. - */ - void SetFreeStream_Solution(CConfig *config); - - /*! - * \brief Store of a set of provided inlet profile values at a vertex. - * \param[in] val_inlet - vector containing the inlet values for the current vertex. - * \param[in] iMarker - Surface marker where the coefficient is computed. - * \param[in] iVertex - Vertex of the marker iMarker where the inlet is being set. - */ - void SetInletAtVertex(su2double *val_inlet, unsigned short iMarker, unsigned long iVertex); - - /*! - * \brief Get the set of value imposed at an inlet. - * \param[in] val_inlet - vector returning the inlet values for the current vertex. - * \param[in] val_inlet_point - Node index where the inlet is being set. - * \param[in] val_kind_marker - Enumerated type for the particular inlet type. - * \param[in] geometry - Geometrical definition of the problem. - * \param config - Definition of the particular problem. - * \return Value of the face area at the vertex. - */ - su2double GetInletAtVertex(su2double *val_inlet, - unsigned long val_inlet_point, - unsigned short val_kind_marker, - string val_marker, - CGeometry *geometry, - CConfig *config); - /*! - * \brief Set a uniform inlet profile - * - * The values at the inlet are set to match the values specified for - * inlets in the configuration file. - * - * \param[in] config - Definition of the particular problem. - * \param[in] iMarker - Surface marker where the coefficient is computed. - */ - void SetUniformInlet(CConfig* config, unsigned short iMarker); - - /*! - * \brief Get the value of the turbulent kinetic energy. - * \return Value of the turbulent kinetic energy. - */ - su2double GetTke_Inf(void); - - /*! - * \brief Get the value of the turbulent frequency. - * \return Value of the turbulent frequency. - */ - su2double GetOmega_Inf(void); - -}; - -/*! - * \class CTransLMSolver - * \brief Main class for defining the turbulence model solver. - * \ingroup Turbulence_Model - * \author A. Aranake. - */ - -class CTransLMSolver: public CTurbSolver { -private: - su2double Intermittency_Inf, REth_Inf; -public: - /*! - * \brief Constructor of the class. - */ - CTransLMSolver(void); - - /*! - * \overload - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); - - /*! - * \brief Destructor of the class. - */ - ~CTransLMSolver(void); - - /*! - * \brief Restart residual and compute gradients. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - * \param[in] Output - boolean to determine whether to print output. - */ - void Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh); - - /*! - * \brief Compute the spatial integration using a upwind scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Upwind_Residual(CGeometry *geometry, CSolver **solver_container, - CNumerics *numerics, CConfig *config, unsigned short iMesh); - - /*! - * \brief Compute the viscous residuals for the turbulent equation. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - void Viscous_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh, unsigned short iRKStep); - - /*! - * \brief Source term computation. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] second_numerics - Description of the second numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CNumerics *second_numerics, - CConfig *config, unsigned short iMesh); - - /*! - * \brief Source term computation. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh); - - /*! - * \brief Impose the Navier-Stokes wall boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the Far Field boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Far_Field(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the inlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the outlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the symmetry condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Sym_Plane(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - /*! - * \brief Update the solution using an implicit solver. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - // Another set of matrix structures for the Lm equations - CSysMatrix JacobianItmc; /*!< \brief Complete sparse Jacobian structure for implicit computations. */ - su2double *LinSysSolItmc; /*!< \brief vector to store iterative solution of implicit linear system. */ - su2double *LinSysResItmc; /*!< \brief vector to store iterative residual of implicit linear system. */ - su2double *rhsItmc; /*!< \brief right hand side of implicit linear system. */ - CSysMatrix JacobianReth; /*!< \brief Complete sparse Jacobian structure for implicit computations. */ - su2double *LinSysSolReth; /*!< \brief vector to store iterative solution of implicit linear system. */ - su2double *LinSysResReth; /*!< \brief vector to store iterative residual of implicit linear system. */ - su2double *rhsReth; /*!< \brief right hand side of implicit linear system. */ -}; - -/*! - * \class CAdjEulerSolver - * \brief Main class for defining the Euler's adjoint flow solver. - * \ingroup Euler_Equations - * \author F. Palacios - */ -class CAdjEulerSolver : public CSolver { -protected: - su2double - PsiRho_Inf, /*!< \brief PsiRho variable at the infinity. */ - PsiE_Inf, /*!< \brief PsiE variable at the infinity. */ - *Phi_Inf; /*!< \brief Phi vector at the infinity. */ - su2double - *Sens_Mach, /*!< \brief Mach sensitivity coefficient for each boundary. */ - *Sens_AoA, /*!< \brief Angle of attack sensitivity coefficient for each boundary. */ - *Sens_Geo, /*!< \brief Shape sensitivity coefficient for each boundary. */ - *Sens_Press, /*!< \brief Pressure sensitivity coefficient for each boundary. */ - *Sens_Temp, /*!< \brief Temperature sensitivity coefficient for each boundary. */ - *Sens_BPress, /*!< \brief Back pressure sensitivity coefficient for each boundary. */ - **CSensitivity, /*!< \brief Shape sensitivity coefficient for each boundary and vertex. */ - ***DonorAdjVar; /*!< \brief Value of the donor variables at each boundary. */ - su2double Total_Sens_Mach; /*!< \brief Total mach sensitivity coefficient for all the boundaries. */ - su2double Total_Sens_AoA; /*!< \brief Total angle of attack sensitivity coefficient for all the boundaries. */ - su2double Total_Sens_Geo; /*!< \brief Total shape sensitivity coefficient for all the boundaries. */ - su2double Total_Sens_Press; /*!< \brief Total farfield sensitivity to pressure. */ - su2double Total_Sens_Temp; /*!< \brief Total farfield sensitivity to temperature. */ - su2double Total_Sens_BPress; /*!< \brief Total sensitivity to back pressure. */ - bool space_centered; /*!< \brief True if space centered scheeme used. */ - su2double **Jacobian_Axisymmetric; /*!< \brief Storage for axisymmetric Jacobian. */ - su2double Gamma; /*!< \brief Fluid's Gamma constant (ratio of specific heats). */ - su2double Gamma_Minus_One; /*!< \brief Fluids's Gamma - 1.0 . */ - su2double *FlowPrimVar_i, /*!< \brief Store the flow solution at point i. */ - *FlowPrimVar_j; /*!< \brief Store the flow solution at point j. */ - unsigned long **DonorGlobalIndex; /*!< \brief Value of the donor global index. */ - - su2double pnorm, - Area_Monitored; /*!< \brief Store the total area of the monitored outflow surface (used for normalization in continuous adjoint outflow conditions) */ - - su2double ACoeff, ACoeff_inc, ACoeff_old; - bool Update_ACoeff; - - CAdjEulerVariable* nodes = nullptr; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ - - /*! - * \brief Return nodes to allow CSolver::base_nodes to be set. - */ - inline CVariable* GetBaseClassPointerToNodes() override { return nodes; } - -public: - - /*! - * \brief Constructor of the class. - */ - CAdjEulerSolver(void); - - /*! - * \overload - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - CAdjEulerSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); - - /*! - * \brief Destructor of the class. - */ - virtual ~CAdjEulerSolver(void); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] Iteration - Index of the current iteration. - */ - void SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh, unsigned long Iteration); - - /*! - * \brief Parallelization of Undivided Laplacian. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Set_MPI_Nearfield(CGeometry *geometry, CConfig *config); - - /*! - * \brief Parallelization of Undivided Laplacian. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Set_MPI_ActDisk(CSolver **solver_container, CGeometry *geometry, CConfig *config); - - /*! - * \brief Created the force projection vector for adjoint boundary conditions. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void SetForceProj_Vector(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief Compute the jump for the interior boundary problem. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void SetIntBoundary_Jump(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief Compute adjoint density at the infinity. - * \return Value of the adjoint density at the infinity. - */ - su2double GetPsiRho_Inf(void); - - /*! - * \brief Compute the adjoint energy at the infinity. - * \return Value of the adjoint energy at the infinity. - */ - su2double GetPsiE_Inf(void); - - /*! - * \brief Compute Phi (adjoint velocity) at the infinity. - * \param[in] val_dim - Index of the adjoint velocity vector. - * \return Value of the adjoint velocity vector at the infinity. - */ - su2double GetPhi_Inf(unsigned short val_dim); - - /*! - * \brief Compute the spatial integration using a centered scheme for the adjoint equations. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - void Centered_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, - unsigned short iMesh, unsigned short iRKStep); - - /*! - * \brief Compute the spatial integration using a upwind scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Upwind_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, - unsigned short iMesh); - - /*! - * \brief Source term integration. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] second_numerics - Description of the second numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CNumerics *second_numerics, - CConfig *config, unsigned short iMesh); - - /*! - * \brief Source term integration. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh); - - /*! - * \brief Compute the undivided laplacian for the adjoint solution. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void SetUndivided_Laplacian(CGeometry *geometry, CConfig *config); - - /*! - * \brief Value of the characteristic variables at the boundaries. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - su2double *GetDonorAdjVar(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Value of the characteristic variables at the boundaries. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - void SetDonorAdjVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_var, su2double val_value); - - /*! - * \brief Value of the characteristic variables at the boundaries. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - su2double GetDonorAdjVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_var); - - /*! - * \brief Value of the characteristic global index at the boundaries. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - unsigned long GetDonorGlobalIndex(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Value of the characteristic global index at the boundaries. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the pressure coefficient. - */ - void SetDonorGlobalIndex(unsigned short val_marker, unsigned long val_vertex, unsigned long val_index); - - /*! - * \brief Compute the sensor for higher order dissipation control in rotating problems. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void SetCentered_Dissipation_Sensor(CGeometry *geometry, CConfig *config); - - /*! - * \brief Update the AoA and freestream velocity at the farfield. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - current mesh level for the multigrid. - * \param[in] Output - boolean to determine whether to print output. - */ - void SetFarfield_AoA(CGeometry *geometry, CSolver **solver_container, - CConfig *config, unsigned short iMesh, bool Output); - - /*! - * \brief Impose via the residual the adjoint Euler wall boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Euler_Wall(CGeometry *geometry, - CSolver **solver_container, - CNumerics *conv_numerics, - CNumerics *visc_numerics, - CConfig *config, - unsigned short val_marker) override; - - /*! - * \brief Impose the interface boundary condition using the residual. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Interface_Boundary(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose the near-field boundary condition using the residual. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_NearField_Boundary(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose an actuator disk inlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_ActDisk_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose an actuator disk outlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_ActDisk_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose an actuator disk inlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_ActDisk(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker, bool val_inlet_surface); - - /*! - * \brief Impose via the residual the adjoint symmetry boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Sym_Plane(CGeometry *geometry, - CSolver **solver_container, - CNumerics *conv_numerics, - CNumerics *visc_numerics, - CConfig *config, - unsigned short val_marker) override; - - /*! - * \brief Impose the boundary condition to the far field using characteristics. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Far_Field(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the inlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - - /*! - * \brief Impose the supersonic inlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] solver - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Supersonic_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the supersonic outlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] solver - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Supersonic_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the outlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the engine inflow adjoint boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Engine_Inflow(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose the engine exhaust boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Engine_Exhaust(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Update the solution using a Runge-Kutta strategy. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - void ExplicitRK_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iRKStep); - - /*! - * \brief Update the solution using a explicit Euler scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void ExplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief Update the solution using an implicit solver. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief Initialize the residual vectors. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - * \param[in] Output - boolean to determine whether to print output. - */ - void Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output); - - /*! - * \brief Compute the inviscid sensitivity of the functional. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - void Inviscid_Sensitivity(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config); - - /*! - * \brief Smooth the inviscid sensitivity of the functional. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - void Smooth_Sensitivity(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config); - - /*! - * \brief Get the shape sensitivity coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the sensitivity coefficient. - */ - su2double GetCSensitivity(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Set the shape sensitivity coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \param[in] val_sensitivity - Value of the sensitivity coefficient. - */ - void SetCSensitivity(unsigned short val_marker, unsigned long val_vertex, su2double val_sensitivity); - - /*! - * \brief Provide the total shape sensitivity coefficient. - * \return Value of the geometrical sensitivity coefficient - * (inviscid + viscous contribution). - */ - su2double GetTotal_Sens_Geo(void); - - /*! - * \brief Set the total Mach number sensitivity coefficient. - * \return Value of the Mach sensitivity coefficient - * (inviscid + viscous contribution). - */ - su2double GetTotal_Sens_Mach(void); - - /*! - * \brief Set the total angle of attack sensitivity coefficient. - * \return Value of the angle of attack sensitivity coefficient - * (inviscid + viscous contribution). - */ - su2double GetTotal_Sens_AoA(void); - - /*! - * \brief Set the total farfield pressure sensitivity coefficient. - * \return Value of the farfield pressure sensitivity coefficient - * (inviscid + viscous contribution). - */ - su2double GetTotal_Sens_Press(void); - - /*! - * \brief Set the total farfield temperature sensitivity coefficient. - * \return Value of the farfield temperature sensitivity coefficient - * (inviscid + viscous contribution). - */ - su2double GetTotal_Sens_Temp(void); - - /*! - * \author H. Kline - * \brief Get the total Back pressure number sensitivity coefficient. - * \return Value of the Back sensitivity coefficient - * (inviscid + viscous contribution). - */ - su2double GetTotal_Sens_BPress(void); - - /*! - * \brief Set the total residual adding the term that comes from the Dual Time Strategy. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - */ - void SetResidual_DualTime(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iRKStep, unsigned short iMesh, unsigned short RunTime_EqSystem); - - /*! - * \brief Set the initial condition for the Euler Equations. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] ExtIter - External iteration. - */ - void SetInitialCondition(CGeometry **geometry, CSolver ***solver_container, CConfig *config, unsigned long TimeIter); - - /*! - * \brief Load a solution from a restart file. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - Container vector with all of the solvers. - * \param[in] config - Definition of the particular problem. - * \param[in] val_iter - Current external iteration number. - * \param[in] val_update_geo - Flag for updating coords and grid velocity. - */ - void LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo); - -}; - -/*! - * \class CAdjNSSolver - * \brief Main class for defining the Navier-Stokes' adjoint flow solver. - * \ingroup Navier_Stokes_Equations - * \author F. Palacios - */ -class CAdjNSSolver : public CAdjEulerSolver { -public: - - /*! - * \brief Constructor of the class. - */ - CAdjNSSolver(void); - - /*! - * \overload - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - CAdjNSSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); - - /*! - * \brief Destructor of the class. - */ - ~CAdjNSSolver(void); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] Iteration - Index of the current iteration. - */ - void SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh, unsigned long Iteration); - - - /*! - * \brief Impose via the residual or brute force the Navier-Stokes adjoint boundary condition (heat flux). - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose via the residual or brute force the Navier-Stokes adjoint boundary condition (heat flux). - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief Restart residual and compute gradients. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - * \param[in] Output - boolean to determine whether to print output. - */ - void Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output); - - /*! - * \brief Compute the viscous sensitivity of the functional. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - */ - void Viscous_Sensitivity(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config); - - /*! - * \brief Compute the viscous residuals for the adjoint equation. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - void Viscous_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh, unsigned short iRKStep); - - /*! - * \brief Source term computation. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] second_numerics - Description of the second numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CNumerics *second_numerics, - CConfig *config, unsigned short iMesh); - -}; - -/*! - * \class CAdjTurbSolver - * \brief Main class for defining the adjoint turbulence model solver. - * \ingroup Turbulence_Model - * \author F. Palacios, A. Bueno. - */ -class CAdjTurbSolver : public CSolver { -private: - su2double PsiNu_Inf, /*!< \brief PsiNu variable at the infinity. */ - *FlowSolution_i, /*!< \brief Store the flow solution at point i. */ - *FlowSolution_j; /*!< \brief Store the flow solution at point j. */ - - su2double Gamma; /*!< \brief Fluid's Gamma constant (ratio of specific heats). */ - su2double Gamma_Minus_One; /*!< \brief Fluids's Gamma - 1.0 . */ - - CAdjTurbVariable* nodes = nullptr; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ - - /*! - * \brief Return nodes to allow CSolver::base_nodes to be set. - */ - inline CVariable* GetBaseClassPointerToNodes() override { return nodes; } - -public: - - /*! - * \brief Default constructor of the class. - */ - CAdjTurbSolver(void); - - /*! - * \overload - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - CAdjTurbSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); - - /*! - * \brief Default destructor of the class. - */ - virtual ~CAdjTurbSolver(void); - - /*! - * \brief Impose the Navier-Stokes turbulent adjoint boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose an isothermal wall boundary condition (no-slip). - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the boundary condition to the far field using characteristics. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Far_Field(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Initializate the residual vectors. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - * \param[in] Output - boolean to determine whether to print output. - */ - void Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output); - - /*! - * \brief Compute the spatial integration using a upwind scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Upwind_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, - unsigned short iMesh); - - /*! - * \brief Compute the viscous residuals for the turbulent adjoint equation. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - void Viscous_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, - unsigned short iMesh, unsigned short iRKStep); - - /*! - * \brief Source term computation. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] second_numerics - Description of the second numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CNumerics *second_numerics, - CConfig *config, unsigned short iMesh); - - /*! - * \brief Update the solution using an implicit solver. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config); - -}; - -/*! \class CHeatSolverFVM - * \brief Main class for defining the finite-volume heat solver. - * \author O. Burghardt - * \date January 19, 2018. - */ -class CHeatSolverFVM : public CSolver { -protected: - unsigned short nVarFlow, nMarker, CurrentMesh; - su2double **HeatFlux, *HeatFlux_per_Marker, *Surface_HF, Total_HeatFlux, AllBound_HeatFlux, - *AverageT_per_Marker, Total_AverageT, AllBound_AverageT, - *Primitive, *Primitive_Flow_i, *Primitive_Flow_j, - *Surface_Areas, Total_HeatFlux_Areas, Total_HeatFlux_Areas_Monitor; - su2double ***ConjugateVar, ***InterfaceVar; - - CHeatFVMVariable* nodes = nullptr; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ - - /*! - * \brief Return nodes to allow CSolver::base_nodes to be set. - */ - inline CVariable* GetBaseClassPointerToNodes() override { return nodes; } - -public: - - /*! - * \brief Constructor of the class. - */ - CHeatSolverFVM(void); - - /*! - * \brief Constructor of the class. - */ - CHeatSolverFVM(CGeometry *geometry, CConfig *config, unsigned short iMesh); - - /*! - * \brief Destructor of the class. - */ - virtual ~CHeatSolverFVM(void); - - /*! - * \brief Restart residual and compute gradients. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - * \param[in] Output - boolean to determine whether to print output. - */ - void Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, - unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh); - - /*! - * \brief Load a solution from a restart file. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - Container vector with all of the solvers. - * \param[in] config - Definition of the particular problem. - * \param[in] val_iter - Current external iteration number. - * \param[in] val_update_geo - Flag for updating coords and grid velocity. - */ - void LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo); - - /*! - * \brief Source term computation. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] second_numerics - Description of the second numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CNumerics *second_numerics, - CConfig *config, unsigned short iMesh); - - /*! - * \brief Compute the undivided laplacian for the solution. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void SetUndivided_Laplacian(CGeometry *geometry, CConfig *config); - - /*! - * \brief Compute the spatial integration using a centered scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - void Centered_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh, unsigned short iRKStep); - - /*! - * \brief Compute the spatial integration using a upwind scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Upwind_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, - unsigned short iMesh); - - /*! - * \brief Compute the viscous residuals for the turbulent equation. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - void Viscous_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh, unsigned short iRKStep); - - - void Set_Heatflux_Areas(CGeometry *geometry, CConfig *config); - - /*! - * \brief Impose the Navier-Stokes boundary condition (strong). - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose a constant heat-flux condition at the wall. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the inlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - /*! - * \brief Impose the outlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Outlet(CGeometry *geometry, CSolver **solver_container, - CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker); - - /*! - * \brief Impose the (received) conjugate heat variables. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_ConjugateHeat_Interface(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Set the conjugate heat variables. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - * \param[in] pos_var - variable position (in vector of all conjugate heat variables) - */ - su2double GetConjugateHeatVariable(unsigned short val_marker, unsigned long val_vertex, unsigned short pos_var); - - /*! - * \brief Set the conjugate heat variables. - * \param[in] val_marker - marker index - * \param[in] val_vertex - vertex index - * \param[in] pos_var - variable position (in vector of all conjugate heat variables) - * \param[in] relaxation factor - relaxation factor for the change of the variables - * \param[in] val_var - value of the variable - */ - void SetConjugateHeatVariable(unsigned short val_marker, unsigned long val_vertex, unsigned short pos_var, su2double relaxation_factor, su2double val_var); - - /*! - * \brief Evaluate heat-flux related objectives. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void Heat_Fluxes(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief Get value of the heat load (integrated heat flux). - * \return Value of the heat load (integrated heat flux). - */ - su2double GetTotal_HeatFlux(void); - - /*! - * \brief Get value of the integral-averaged temperature. - * \return Value of the integral-averaged temperature. - */ - su2double GetTotal_AvgTemperature(void); - - /*! - * \brief Update the solution using an implicit solver. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief Update the solution using an explicit solver. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void ExplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - void SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh, unsigned long Iteration); - - /*! - * \brief Set the initial condition for the FEM structural problem. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] ExtIter - External iteration. - */ - void SetInitialCondition(CGeometry **geometry, CSolver ***solver_container, CConfig *config, unsigned long TimeIter); - - /*! - * \brief Set the total residual adding the term that comes from the Dual Time-Stepping Strategy. - * \param[in] geometry - Geometric definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - */ - void SetResidual_DualTime(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iRKStep, unsigned short iMesh, unsigned short RunTime_EqSystem); - - /*! - * \brief Get the heat flux. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the heat flux. - */ - su2double GetHeatFlux(unsigned short val_marker, unsigned long val_vertex); - -}; - -/*! - * \class CTemplateSolver - * \brief Main class for defining the template model solver. - * \ingroup Template_Flow_Equation - * \author F. Palacios - */ -class CTemplateSolver : public CSolver { -private: - - CVariable* nodes = nullptr; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ - - /*! - * \brief Return nodes to allow CSolver::base_nodes to be set. - */ - inline CVariable* GetBaseClassPointerToNodes() override { return nodes; } - -public: - - /*! - * \brief Constructor of the class. - */ - CTemplateSolver(void); - - /*! - * \overload - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - CTemplateSolver(CGeometry *geometry, CConfig *config); - - /*! - * \brief Destructor of the class. - */ - ~CTemplateSolver(void); - - /*! - * \brief Compute the velocity^2, SoundSpeed, Pressure. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - * \param[in] Output - boolean to determine whether to print output. - */ - void Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output); - - /*! - * \brief Compute the time step for solving the Euler equations. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] Iteration - Index of the current iteration. - */ - void SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh, unsigned long Iteration); - - /*! - * \brief Compute the spatial integration using a centered scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - void Centered_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh, unsigned short iRKStep); - - /*! - * \brief Compute the spatial integration using a upwind scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Upwind_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh); - - /*! - * \brief Source term integration. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] second_numerics - Description of the second numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CNumerics *second_numerics, - CConfig *config, unsigned short iMesh); - - /*! - * \brief Source term integration. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh); - - /*! - * \brief Impose via the residual the Euler wall boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Euler_Wall(CGeometry *geometry, - CSolver **solver_container, - CNumerics *conv_numerics, - CNumerics *visc_numerics, - CConfig *config, - unsigned short val_marker) override; - - /*! - * \brief Impose the Navier-Stokes boundary condition (strong). - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the far-field boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Far_Field(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the inlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the outlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker); - - /*! - * \brief Impose the symmetry plane boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Sym_Plane(CGeometry *geometry, - CSolver **solver_container, - CNumerics *conv_numerics, - CNumerics *visc_numerics, - CConfig *config, - unsigned short val_marker) override; - - /*! - * \brief Impose a custom or verification boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the convective numerical method. - * \param[in] visc_numerics - Description of the viscous numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Custom(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker); - - /*! - * \brief Update the solution using a Runge-Kutta scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - void ExplicitRK_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iRKStep); - - /*! - * \brief Update the solution using the explicit Euler scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void ExplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config); - - /*! - * \brief Update the solution using an implicit Euler scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config); - -}; - -/*! - * \class CDiscAdjSolver - * \brief Main class for defining the discrete adjoint solver. - * \ingroup Discrete_Adjoint - * \author T. Albring - */ -class CDiscAdjSolver : public CSolver { -private: - unsigned short KindDirect_Solver; - CSolver *direct_solver; - su2double **CSensitivity; /*!< \brief Shape sensitivity coefficient for each boundary and vertex. */ - su2double Total_Sens_Mach; /*!< \brief Total mach sensitivity coefficient for all the boundaries. */ - su2double Total_Sens_AoA; /*!< \brief Total angle of attack sensitivity coefficient for all the boundaries. */ - su2double Total_Sens_Geo; /*!< \brief Total shape sensitivity coefficient for all the boundaries. */ - su2double Total_Sens_Press; /*!< \brief Total farfield sensitivity to pressure. */ - su2double Total_Sens_Temp; /*!< \brief Total farfield sensitivity to temperature. */ - su2double Total_Sens_BPress; /*!< \brief Total sensitivity to outlet pressure. */ - su2double Total_Sens_Density; /*!< \brief Total sensitivity to initial density (incompressible). */ - su2double Total_Sens_ModVel; /*!< \brief Total sensitivity to inlet velocity (incompressible). */ - su2double ObjFunc_Value; /*!< \brief Value of the objective function. */ - su2double Mach, Alpha, Beta, Pressure, Temperature, BPressure, ModVel; - - su2double *Solution_Geometry; /*!< \brief Auxiliary vector for the geometry solution (dimension nDim instead of nVar). */ - - CDiscAdjVariable* nodes = nullptr; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ - - /*! - * \brief Return nodes to allow CSolver::base_nodes to be set. - */ - inline CVariable* GetBaseClassPointerToNodes() override { return nodes; } - -public: - - /*! - * \brief Constructor of the class. - */ - CDiscAdjSolver(void); - - /*! - * \overload - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - CDiscAdjSolver(CGeometry *geometry, CConfig *config); - - /*! - * \overload - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] solver - Initialize the discrete adjoint solver with the corresponding direct solver. - * \param[in] Kind_Solver - The kind of direct solver. - */ - CDiscAdjSolver(CGeometry *geometry, CConfig *config, CSolver* solver, unsigned short Kind_Solver, unsigned short iMesh); - - /*! - * \brief Destructor of the class. - */ - ~CDiscAdjSolver(void); - - /*! - * \brief Performs the preprocessing of the adjoint AD-based solver. - * Registers all necessary variables on the tape. Called while tape is active. - * \param[in] geometry_container - The geometry container holding all grid levels. - * \param[in] config_container - The particular config. - */ - void RegisterSolution(CGeometry *geometry, CConfig *config); - - /*! - * \brief Performs the preprocessing of the adjoint AD-based solver. - * Registers all necessary variables that are output variables on the tape. - * Called while tape is active. - * \param[in] geometry_container - The geometry container holding all grid levels. - * \param[in] config_container - The particular config. - */ - void RegisterOutput(CGeometry *geometry, CConfig *config); - - /*! - * \brief Sets the adjoint values of the output of the flow (+turb.) iteration - * before evaluation of the tape. - * \param[in] geometry - The geometrical definition of the problem. - * \param[in] config - The particular config. - */ - void SetAdjoint_Output(CGeometry *geometry, CConfig *config); - - /*! - * \brief Sets the adjoint values of the output of the mesh deformation iteration - * before evaluation of the tape. - * \param[in] geometry - The geometrical definition of the problem. - * \param[in] config - The particular config. - */ - void SetAdjoint_OutputMesh(CGeometry *geometry, CConfig *config); - - /*! - * \brief Sets the adjoint values of the input variables of the flow (+turb.) iteration - * after tape has been evaluated. - * \param[in] geometry - The geometrical definition of the problem. - * \param[in] config - The particular config. - */ - void ExtractAdjoint_Solution(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - The geometrical definition of the problem. - * \param[in] solver_container - The solver container holding all solutions. - * \param[in] config - The particular config. - */ - void ExtractAdjoint_Geometry(CGeometry *geometry, CConfig *config); - - /*! - * \brief Sets the adjoint values of the flow variables due to cross term contributions - * \param[in] geometry - The geometrical definition of the problem. - * \param[in] solver_container - The solver container holding all solutions. - * \param[in] config - The particular config. - */ - void ExtractAdjoint_CrossTerm(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - The geometrical definition of the problem. - * \param[in] solver_container - The solver container holding all solutions. - * \param[in] config - The particular config. - */ - void ExtractAdjoint_CrossTerm_Geometry(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - The geometrical definition of the problem. - * \param[in] solver_container - The solver container holding all solutions. - * \param[in] config - The particular config. - */ - void ExtractAdjoint_CrossTerm_Geometry_Flow(CGeometry *geometry, CConfig *config); - - /*! - * \brief Register the objective function as output. - * \param[in] geometry - The geometrical definition of the problem. - */ - void RegisterObj_Func(CConfig *config); - - /*! - * \brief Set the surface sensitivity. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void SetSurface_Sensitivity(CGeometry *geometry, CConfig* config); - - /*! - * \brief Extract and set the geometrical sensitivity. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - The solver container holding all terms of the solution. - * \param[in] config - Definition of the particular problem. - */ - void SetSensitivity(CGeometry *geometry, CSolver **solver, CConfig *config); - - /*! - * \brief Set the objective function. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void SetAdj_ObjFunc(CGeometry *geometry, CConfig* config); - - /*! - * \brief Provide the total shape sensitivity coefficient. - * \return Value of the geometrical sensitivity coefficient - * (inviscid + viscous contribution). - */ - su2double GetTotal_Sens_Geo(void); - - /*! - * \brief Set the total Mach number sensitivity coefficient. - * \return Value of the Mach sensitivity coefficient - * (inviscid + viscous contribution). - */ - su2double GetTotal_Sens_Mach(void); - - /*! - * \brief Set the total angle of attack sensitivity coefficient. - * \return Value of the angle of attack sensitivity coefficient - * (inviscid + viscous contribution). - */ - su2double GetTotal_Sens_AoA(void); - - /*! - * \brief Set the total farfield pressure sensitivity coefficient. - * \return Value of the farfield pressure sensitivity coefficient - * (inviscid + viscous contribution). - */ - su2double GetTotal_Sens_Press(void); - - /*! - * \brief Set the total farfield temperature sensitivity coefficient. - * \return Value of the farfield temperature sensitivity coefficient - * (inviscid + viscous contribution). - */ - su2double GetTotal_Sens_Temp(void); - - /*! - * \author H. Kline - * \brief Get the total Back pressure number sensitivity coefficient. - * \return Value of the Back sensitivity coefficient - * (inviscid + viscous contribution). - */ - su2double GetTotal_Sens_BPress(void); - - /*! - * \brief Get the total density sensitivity coefficient. - * \return Value of the density sensitivity. - */ - su2double GetTotal_Sens_Density(void); - - /*! - * \brief Get the total velocity magnitude sensitivity coefficient. - * \return Value of the velocity magnitude sensitivity. - */ - su2double GetTotal_Sens_ModVel(void); - - /*! - * \brief Get the shape sensitivity coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. - * \return Value of the sensitivity coefficient. - */ - su2double GetCSensitivity(unsigned short val_marker, unsigned long val_vertex); - - /*! - * \brief Prepare the solver for a new recording. - * \param[in] kind_recording - Kind of AD recording. - */ - void SetRecording(CGeometry *geometry, CConfig *config); - - /*! - * \brief Prepare the solver for a new recording. - * \param[in] kind_recording - Kind of AD recording. - */ - void SetMesh_Recording(CGeometry **geometry, CVolumetricMovement *grid_movement, - CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] reset - If true reset variables to their initial values. - */ - void RegisterVariables(CGeometry *geometry, CConfig *config, bool reset = false) override; - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void ExtractAdjoint_Variables(CGeometry *geometry, CConfig *config) override; - - /*! - * \brief Update the dual-time derivatives. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - * \param[in] Output - boolean to determine whether to print output. - */ - void Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output); - - /*! - * \brief Load a solution from a restart file. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - Container vector with all of the solvers. - * \param[in] config - Definition of the particular problem. - * \param[in] val_iter - Current external iteration number. - * \param[in] val_update_geo - Flag for updating coords and grid velocity. - */ - void LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo); - - /*! - * \brief Compute the multizone residual. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void ComputeResidual_Multizone(CGeometry *geometry, CConfig *config); - - /*! - * \brief Store the BGS solution in the previous subiteration in the corresponding vector. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void UpdateSolution_BGS(CGeometry *geometry, CConfig *config); - -}; - -/*! - * \class CDiscAdjFEASolver - * \brief Main class for defining the discrete adjoint solver for FE structural problems. - * \ingroup Discrete_Adjoint - * \author R. Sanchez - */ -class CDiscAdjFEASolver : public CSolver { -private: - unsigned short KindDirect_Solver; - CSolver *direct_solver; - su2double *Sens_E, /*!< \brief Young modulus sensitivity coefficient for each boundary. */ - *Sens_Nu, /*!< \brief Poisson's ratio sensitivity coefficient for each boundary. */ - *Sens_nL, /*!< \brief Normal pressure sensitivity coefficient for each boundary. */ - **CSensitivity; /*!< \brief Shape sensitivity coefficient for each boundary and vertex. */ - - su2double *Solution_Vel, /*!< \brief Velocity componenent of the solution. */ - *Solution_Accel; /*!< \brief Acceleration componenent of the solution. */ - - su2double *SolRest; /*!< \brief Auxiliary vector to restart the solution */ - - su2double ObjFunc_Value; /*!< \brief Value of the objective function. */ - su2double *normalLoads; /*!< \brief Values of the normal loads for each marker iMarker_nL. */ - unsigned long nMarker_nL; /*!< \brief Total number of markers that have a normal load applied. */ - - unsigned short nMPROP; /*!< \brief Number of material properties */ - - su2double *E_i, /*!< \brief Values of the Young's Modulus. */ - *Nu_i, /*!< \brief Values of the Poisson's ratio. */ - *Rho_i, /*!< \brief Values of the density (for inertial effects). */ - *Rho_DL_i; /*!< \brief Values of the density (for volume loading). */ - int *AD_Idx_E_i, /*!< \brief Derivative index of the Young's Modulus. */ - *AD_Idx_Nu_i, /*!< \brief Derivative index of the Poisson's ratio. */ - *AD_Idx_Rho_i, /*!< \brief Derivative index of the density (for inertial effects). */ - *AD_Idx_Rho_DL_i; /*!< \brief Derivative index of the density (for volume loading). */ - - su2double *Local_Sens_E, /*!< \brief Local sensitivity of the Young's modulus. */ - *Global_Sens_E, /*!< \brief Global sensitivity of the Young's modulus. */ - *Total_Sens_E; /*!< \brief Total sensitivity of the Young's modulus (time domain). */ - su2double *Local_Sens_Nu, /*!< \brief Local sensitivity of the Poisson ratio. */ - *Global_Sens_Nu, /*!< \brief Global sensitivity of the Poisson ratio. */ - *Total_Sens_Nu; /*!< \brief Total sensitivity of the Poisson ratio (time domain). */ - su2double *Local_Sens_Rho, /*!< \brief Local sensitivity of the density. */ - *Global_Sens_Rho, /*!< \brief Global sensitivity of the density. */ - *Total_Sens_Rho; /*!< \brief Total sensitivity of the density (time domain). */ - su2double *Local_Sens_Rho_DL, /*!< \brief Local sensitivity of the volume load. */ - *Global_Sens_Rho_DL, /*!< \brief Global sensitivity of the volume load. */ - *Total_Sens_Rho_DL; /*!< \brief Total sensitivity of the volume load (time domain). */ - - bool de_effects; /*!< \brief Determines if DE effects are considered. */ - unsigned short nEField; /*!< \brief Number of electric field areas in the problem. */ - su2double *EField; /*!< \brief Array that stores the electric field as design variables. */ - int *AD_Idx_EField; /*!< \brief Derivative index of the electric field as design variables. */ - su2double *Local_Sens_EField, /*!< \brief Local sensitivity of the Electric Field. */ - *Global_Sens_EField, /*!< \brief Global sensitivity of the Electric Field. */ - *Total_Sens_EField; /*!< \brief Total sensitivity of the Electric Field (time domain). */ - - bool fea_dv; /*!< \brief Determines if the design variable we study is a FEA parameter. */ - unsigned short nDV; /*!< \brief Number of design variables in the problem. */ - su2double *DV_Val; /*!< \brief Values of the design variables. */ - int *AD_Idx_DV_Val; /*!< \brief Derivative index of the design variables. */ - su2double *Local_Sens_DV, /*!< \brief Local sensitivity of the design variables. */ - *Global_Sens_DV, /*!< \brief Global sensitivity of the design variables. */ - *Total_Sens_DV; /*!< \brief Total sensitivity of the design variables (time domain). */ - - CDiscAdjFEABoundVariable* nodes = nullptr; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ - - /*! - * \brief Return nodes to allow CSolver::base_nodes to be set. - */ - inline CVariable* GetBaseClassPointerToNodes() override { return nodes; } - -public: - - /*! - * \brief Constructor of the class. - */ - CDiscAdjFEASolver(void); - - /*! - * \overload - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - CDiscAdjFEASolver(CGeometry *geometry, CConfig *config); - - /*! - * \overload - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] solver - Initialize the discrete adjoint solver with the corresponding direct solver. - * \param[in] Kind_Solver - The kind of direct solver. - */ - CDiscAdjFEASolver(CGeometry *geometry, CConfig *config, CSolver* solver, unsigned short Kind_Solver, unsigned short iMesh); - - /*! - * \brief Destructor of the class. - */ - ~CDiscAdjFEASolver(void); - - /*! - * \brief Performs the preprocessing of the adjoint AD-based solver. - * Registers all necessary variables on the tape. Called while tape is active. - * \param[in] geometry_container - The geometry container holding all grid levels. - * \param[in] config_container - The particular config. - */ - void RegisterSolution(CGeometry *geometry, CConfig *config); - - /*! - * \brief Performs the preprocessing of the adjoint AD-based solver. - * Registers all necessary variables that are output variables on the tape. - * Called while tape is active. - * \param[in] geometry_container - The geometry container holding all grid levels. - * \param[in] config_container - The particular config. - */ - void RegisterOutput(CGeometry *geometry, CConfig *config); - - /*! - * \brief Sets the adjoint values of the output of the flow (+turb.) iteration - * before evaluation of the tape. - * \param[in] geometry - The geometrical definition of the problem. - * \param[in] config - The particular config. - */ - void SetAdjoint_Output(CGeometry *geometry, CConfig *config); - - /*! - * \brief Sets the adjoint values of the input variables of the flow (+turb.) iteration - * after tape has been evaluated. - * \param[in] geometry - The geometrical definition of the problem. - * \param[in] config - The particular config. - */ - void ExtractAdjoint_Solution(CGeometry *geometry, CConfig *config); - - /*! - * \brief Sets the adjoint values of the structural variables due to cross term contributions - * \param[in] geometry - The geometrical definition of the problem. - * \param[in] solver_container - The solver container holding all solutions. - * \param[in] config - The particular config. - */ - void ExtractAdjoint_CrossTerm(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - The geometrical definition of the problem. - * \param[in] solver_container - The solver container holding all solutions. - * \param[in] config - The particular config. - */ - void ExtractAdjoint_CrossTerm_Geometry(CGeometry *geometry, CConfig *config); - - /*! - * \brief Register the objective function as output. - * \param[in] geometry - The geometrical definition of the problem. - */ - void RegisterObj_Func(CConfig *config); - - /*! - * \brief Set the surface sensitivity. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void SetSurface_Sensitivity(CGeometry *geometry, CConfig* config); - - /*! - * \brief Extract and set the geometrical sensitivity. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - The solver container holding all terms of the solution. - * \param[in] config - Definition of the particular problem. - */ - void SetSensitivity(CGeometry *geometry, CSolver **solver, CConfig *config); - - /*! - * \brief Set the objective function. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void SetAdj_ObjFunc(CGeometry *geometry, CConfig* config); - - /*! - * \brief Provide the total Young's modulus sensitivity - * \return Value of the total Young's modulus sensitivity - * (inviscid + viscous contribution). - */ - su2double GetTotal_Sens_E(unsigned short iVal); - - /*! - * \brief Set the total Poisson's ratio sensitivity. - * \return Value of the Poisson's ratio sensitivity - */ - su2double GetTotal_Sens_Nu(unsigned short iVal); - - /*! - * \brief Get the total sensitivity for the structural density - * \return Value of the structural density sensitivity - */ - su2double GetTotal_Sens_Rho(unsigned short iVal); - - /*! - * \brief Get the total sensitivity for the structural weight - * \return Value of the structural weight sensitivity - */ - su2double GetTotal_Sens_Rho_DL(unsigned short iVal); - - /*! - * \brief A virtual member. - * \return Value of the sensitivity coefficient for the Electric Field in the region iEField (time averaged) - */ - su2double GetTotal_Sens_EField(unsigned short iEField); - - /*! - * \brief A virtual member. - * \return Value of the total sensitivity coefficient for the FEA DV in the region iDVFEA (time averaged) - */ - su2double GetTotal_Sens_DVFEA(unsigned short iDVFEA); - - /*! - * \brief A virtual member. - * \return Value of the sensitivity coefficient for the Young Modulus E - */ - su2double GetGlobal_Sens_E(unsigned short iVal); - - /*! - * \brief A virtual member. - * \return Value of the Mach sensitivity for the Poisson's ratio Nu - */ - su2double GetGlobal_Sens_Nu(unsigned short iVal); - - /*! - * \brief A virtual member. - * \return Value of the sensitivity coefficient for the Electric Field in the region iEField - */ - su2double GetGlobal_Sens_EField(unsigned short iEField); - - /*! - * \brief A virtual member. - * \return Value of the sensitivity coefficient for the FEA DV in the region iDVFEA - */ - su2double GetGlobal_Sens_DVFEA(unsigned short iDVFEA); - - /*! - * \brief Get the total sensitivity for the structural density - * \return Value of the structural density sensitivity - */ - su2double GetGlobal_Sens_Rho(unsigned short iVal); - - /*! - * \brief Get the total sensitivity for the structural weight - * \return Value of the structural weight sensitivity - */ - su2double GetGlobal_Sens_Rho_DL(unsigned short iVal); - - - /*! - * \brief Get the value of the Young modulus from the adjoint solver - * \return Value of the Young modulus from the adjoint solver - */ - su2double GetVal_Young(unsigned short iVal); - - /*! - * \brief Get the value of the Poisson's ratio from the adjoint solver - * \return Value of the Poisson's ratio from the adjoint solver - */ - su2double GetVal_Poisson(unsigned short iVal); - - /*! - * \brief Get the value of the density from the adjoint solver, for inertial effects - * \return Value of the density from the adjoint solver - */ - su2double GetVal_Rho(unsigned short iVal); - - /*! - * \brief Get the value of the density from the adjoint solver, for dead loads - * \return Value of the density for dead loads, from the adjoint solver - */ - su2double GetVal_Rho_DL(unsigned short iVal); - - /*! - * \brief Get the number of variables for the Electric Field from the adjoint solver - * \return Number of electric field variables from the adjoint solver - */ - unsigned short GetnEField(void); - - /*! - * \brief Read the design variables for the adjoint solver - */ - void ReadDV(CConfig *config); - - /*! - * \brief Get the number of design variables from the adjoint solver, - * \return Number of design variables from the adjoint solver - */ - unsigned short GetnDVFEA(void); - - /*! - * \brief Get the value of the Electric Field from the adjoint solver - * \return Pointer to the values of the Electric Field - */ - su2double GetVal_EField(unsigned short iVal); - - /*! - * \brief Get the value of the design variables from the adjoint solver - * \return Pointer to the values of the design variables - */ - su2double GetVal_DVFEA(unsigned short iVal); - - /*! - * \brief Prepare the solver for a new recording. - * \param[in] kind_recording - Kind of AD recording. - */ - void SetRecording(CGeometry *geometry, CConfig *config); - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] reset - If true reset variables to their initial values. - */ - void RegisterVariables(CGeometry *geometry, CConfig *config, bool reset = false) override; - - /*! - * \brief A virtual member. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void ExtractAdjoint_Variables(CGeometry *geometry, CConfig *config) override; - - /*! - * \brief Update the dual-time derivatives. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - * \param[in] Output - boolean to determine whether to print output. - */ - void Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output); - - /*! - * \brief Load a solution from a restart file. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - Container vector with all of the solvers. - * \param[in] config - Definition of the particular problem. - * \param[in] val_iter - Current external iteration number. - * \param[in] val_update_geo - Flag for updating coords and grid velocity. - */ - void LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo); - - /*! - * \brief Compute the multizone residual. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void ComputeResidual_Multizone(CGeometry *geometry, CConfig *config); - - /*! - * \brief Store the BGS solution in the previous subiteration in the corresponding vector. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void UpdateSolution_BGS(CGeometry *geometry, CConfig *config); - -}; - -/*! - * \class CFEM_DG_EulerSolver - * \brief Main class for defining the Euler Discontinuous Galerkin finite element flow solver. - * \ingroup Euler_Equations - * \author E. van der Weide, T. Economon, J. Alonso - * \version 7.0.0 "Blackbird" - */ -class CFEM_DG_EulerSolver : public CSolver { -protected: - - su2double Gamma; /*!< \brief Fluid's Gamma constant (ratio of specific heats). */ - su2double Gamma_Minus_One; /*!< \brief Fluids's Gamma - 1.0 . */ - - CFluidModel *FluidModel; /*!< \brief fluid model used in the solver */ - - su2double - Mach_Inf, /*!< \brief Mach number at infinity. */ - Density_Inf, /*!< \brief Density at infinity. */ - Energy_Inf, /*!< \brief Energy at infinity. */ - Temperature_Inf, /*!< \brief Energy at infinity. */ - Pressure_Inf, /*!< \brief Pressure at infinity. */ - *Velocity_Inf; /*!< \brief Flow velocity vector at infinity. */ - - vector ConsVarFreeStream; /*!< \brief Vector, which contains the free stream - conservative variables. */ - su2double - *CL_Inv, /*!< \brief Lift coefficient (inviscid contribution) for each boundary. */ - *CD_Inv, /*!< \brief Drag coefficient (inviscid contribution) for each boundary. */ - *CSF_Inv, /*!< \brief Sideforce coefficient (inviscid contribution) for each boundary. */ - *CFx_Inv, /*!< \brief x Force coefficient (inviscid contribution) for each boundary. */ - *CFy_Inv, /*!< \brief y Force coefficient (inviscid contribution) for each boundary. */ - *CFz_Inv, /*!< \brief z Force coefficient (inviscid contribution) for each boundary. */ - *CMx_Inv, /*!< \brief x Moment coefficient (inviscid contribution) for each boundary. */ - *CMy_Inv, /*!< \brief y Moment coefficient (inviscid contribution) for each boundary. */ - *CMz_Inv, /*!< \brief z Moment coefficient (inviscid contribution) for each boundary. */ - *CEff_Inv; /*!< \brief Efficiency (Cl/Cd) (inviscid contribution) for each boundary. */ - - su2double - *Surface_CL_Inv, /*!< \brief Lift coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CD_Inv, /*!< \brief Drag coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CSF_Inv, /*!< \brief Side-force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CFx_Inv, /*!< \brief x Force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CFy_Inv, /*!< \brief y Force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CFz_Inv, /*!< \brief z Force coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CMx_Inv, /*!< \brief x Moment coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CMy_Inv, /*!< \brief y Moment coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CMz_Inv, /*!< \brief z Moment coefficient (inviscid contribution) for each monitoring surface. */ - *Surface_CEff_Inv; /*!< \brief Efficiency (Cl/Cd) (inviscid contribution) for each monitoring surface. */ - - su2double - AllBound_CL_Inv, /*!< \brief Total lift coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CD_Inv, /*!< \brief Total drag coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CSF_Inv, /*!< \brief Total sideforce coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CFx_Inv, /*!< \brief Total x force coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CFy_Inv, /*!< \brief Total y force coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CFz_Inv, /*!< \brief Total z force coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMx_Inv, /*!< \brief Total x moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMy_Inv, /*!< \brief Total y moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CMz_Inv, /*!< \brief Total z moment coefficient (inviscid contribution) for all the boundaries. */ - AllBound_CEff_Inv; /*!< \brief Total efficiency (Cl/Cd) (inviscid contribution) for all the boundaries. */ - - su2double - Total_CL, /*!< \brief Total lift coefficient for all the boundaries. */ - Total_CD, /*!< \brief Total drag coefficient for all the boundaries. */ - Total_CSF, /*!< \brief Total sideforce coefficient for all the boundaries. */ - Total_CFx, /*!< \brief Total x force coefficient for all the boundaries. */ - Total_CFy, /*!< \brief Total y force coefficient for all the boundaries. */ - Total_CFz, /*!< \brief Total z force coefficient for all the boundaries. */ - Total_CMx, /*!< \brief Total x moment coefficient for all the boundaries. */ - Total_CMy, /*!< \brief Total y moment coefficient for all the boundaries. */ - Total_CMz, /*!< \brief Total z moment coefficient for all the boundaries. */ - Total_CEff; /*!< \brief Total efficiency coefficient for all the boundaries. */ - - su2double - *Surface_CL, /*!< \brief Lift coefficient for each monitoring surface. */ - *Surface_CD, /*!< \brief Drag coefficient for each monitoring surface. */ - *Surface_CSF, /*!< \brief Side-force coefficient for each monitoring surface. */ - *Surface_CFx, /*!< \brief x Force coefficient for each monitoring surface. */ - *Surface_CFy, /*!< \brief y Force coefficient for each monitoring surface. */ - *Surface_CFz, /*!< \brief z Force coefficient for each monitoring surface. */ - *Surface_CMx, /*!< \brief x Moment coefficient for each monitoring surface. */ - *Surface_CMy, /*!< \brief y Moment coefficient for each monitoring surface. */ - *Surface_CMz, /*!< \brief z Moment coefficient for each monitoring surface. */ - *Surface_CEff; /*!< \brief Efficiency (Cl/Cd) for each monitoring surface. */ - - unsigned long nDOFsLocTot; /*!< \brief Total number of local DOFs, including halos. */ - unsigned long nDOFsLocOwned; /*!< \brief Number of owned local DOFs. */ - unsigned long nDOFsGlobal; /*!< \brief Number of global DOFs. */ - - unsigned long nVolElemTot; /*!< \brief Total number of local volume elements, including halos. */ - unsigned long nVolElemOwned; /*!< \brief Number of owned local volume elements. */ - CVolumeElementFEM *volElem; /*!< \brief Array of the local volume elements, including halos. */ - - const unsigned long *nVolElemOwnedPerTimeLevel; /*!< \brief Number of owned local volume elements - per time level. Cumulative storage. */ - const unsigned long *nVolElemInternalPerTimeLevel; /*!< \brief Number of internal local volume elements per - time level. Internal means that the solution - data does not need to be communicated. */ - const unsigned long *nVolElemHaloPerTimeLevel; /*!< \brief Number of halo volume elements - per time level. Cumulative storage. */ - - vector > ownedElemAdjLowTimeLevel; /*!< \brief List of owned elements per time level that are - adjacent to elements of the lower time level. */ - vector > haloElemAdjLowTimeLevel; /*!< \brief List of halo elements per time level that are - adjacent to elements of the lower time level. */ - - unsigned long nMeshPoints; /*!< \brief Number of mesh points in the local part of the grid. */ - CPointFEM *meshPoints; /*!< \brief Array of the points of the FEM mesh. */ - - const unsigned long *nMatchingInternalFacesWithHaloElem; /*!< \brief Number of local matching internal faces per time level - between an owned and a halo element. Cumulative storage. */ - const unsigned long *nMatchingInternalFacesLocalElem; /*!< \brief Number of local matching internal faces per time level - between local elements. Cumulative storage. */ - - CInternalFaceElementFEM *matchingInternalFaces; /*!< \brief Array of the local matching internal faces. */ - CBoundaryFEM *boundaries; /*!< \brief Array of the boundaries of the FEM mesh. */ - - unsigned short nStandardBoundaryFacesSol; /*!< \brief Number of standard boundary faces used for solution of the DG solver. */ - unsigned short nStandardElementsSol; /*!< \brief Number of standard volume elements used for solution of the DG solver. */ - unsigned short nStandardMatchingFacesSol; /*!< \brief Number of standard matching internal faces used for solution of the DG solver. */ - - const CFEMStandardBoundaryFace *standardBoundaryFacesSol; /*!< \brief Array that contains the standard boundary - faces used for the solution of the DG solver. */ - const CFEMStandardElement *standardElementsSol; /*!< \brief Array that contains the standard volume elements - used for the solution of the DG solver. */ - const CFEMStandardInternalFace *standardMatchingFacesSol; /*!< \brief Array that contains the standard matching - internal faces used for the solution of - the DG solver. */ - - const su2double *timeCoefADER_DG; /*!< \brief The time coefficients in the iteration matrix of - the ADER-DG predictor step. */ - const su2double *timeInterpolDOFToIntegrationADER_DG; /*!< \brief The interpolation matrix between the time DOFs and - the time integration points for ADER-DG. */ - const su2double *timeInterpolAdjDOFToIntegrationADER_DG; /*!< \brief The interpolation matrix between the time DOFs of adjacent - elements of a higher time level and the time integration - points for ADER-DG. */ - - unsigned int sizeWorkArray; /*!< \brief The size of the work array needed. */ - - vector TolSolADER; /*!< \brief Vector, which stores the tolerances for the conserved - variables in the ADER predictor step. */ - - vector VecSolDOFs; /*!< \brief Vector, which stores the solution variables in the owned DOFs. */ - vector VecSolDOFsNew; /*!< \brief Vector, which stores the new solution variables in the owned DOFs (needed for classical RK4 scheme). */ - vector VecDeltaTime; /*!< \brief Vector, which stores the time steps of the owned volume elements. */ - - vector VecSolDOFsPredictorADER; /*!< \brief Vector, which stores the ADER predictor solution in the owned - DOFs. These are both space and time DOFs. */ - - vector > VecWorkSolDOFs; /*!< \brief Working double vector to store the conserved variables for - the DOFs for the different time levels. */ - - vector VecResDOFs; /*!< \brief Vector, which stores the residuals in the owned DOFs. */ - vector VecResFaces; /*!< \brief Vector, which stores the residuals of the DOFs that - come from the faces, both boundary and internal. */ - vector VecTotResDOFsADER; /*!< \brief Vector, which stores the accumulated residuals of the - owned DOFs for the ADER corrector step. */ - - - vector nEntriesResFaces; /*!< \brief Number of entries for the DOFs in the - residual of the faces. Cumulative storage. */ - vector entriesResFaces; /*!< \brief The corresponding entries in the residual of the faces. */ - - vector nEntriesResAdjFaces; /*!< \brief Number of entries for the DOFs in the residual of the faces, - where the face is adjacent to an element of lower time - level. Cumulative storage. */ - vector entriesResAdjFaces; /*!< \brief The corresponding entries in the residual of the faces. */ - - vector > startLocResFacesMarkers; /*!< \brief The starting location in the residual of the - faces for the time levels of the boundary - markers. */ - - vector startLocResInternalFacesLocalElem; /*!< \brief The starting location in the residual of the - faces for the time levels of internal faces - between locally owned elements. */ - vector startLocResInternalFacesWithHaloElem; /*!< \brief The starting location in the residual of the - faces for the time levels of internal faces - between an owned and a halo element. */ - - bool symmetrizingTermsPresent; /*!< \brief Whether or not symmetrizing terms are present in the - discretization. */ - - vector nDOFsPerRank; /*!< \brief Number of DOFs per rank in - cumulative storage format. */ - vector > nonZeroEntriesJacobian; /*!< \brief The ID's of the DOFs for the - non-zero entries of the Jacobian - for the locally owned DOFs. */ - - int nGlobalColors; /*!< \brief Number of global colors for the Jacobian computation. */ - - vector > localDOFsPerColor; /*!< \brief Double vector, which contains for every - color the local DOFs. */ - vector > colorToIndEntriesJacobian; /*!< \brief Double vector, which contains for every - local DOF the mapping from the color to the - entry in the Jacobian. A -1 indicates that - the color does not contribute to the Jacobian - of the DOF. */ - - CBlasStructure *blasFunctions; /*!< \brief Pointer to the object to carry out the BLAS functionalities. */ - -private: - -#ifdef HAVE_MPI - vector > commRequests; /*!< \brief Communication requests in the communication of the solution for all - time levels. These are both sending and receiving requests. */ - - vector > > elementsRecvMPIComm; /*!< \brief Triple vector, which contains the halo elements - for MPI communication for all time levels. */ - vector > > elementsSendMPIComm; /*!< \brief Triple vector, which contains the donor elements - for MPI communication for all time levels. */ - - vector > ranksRecvMPI; /*!< \brief Double vector, which contains the ranks from which the halo elements - are received for all time levels. */ - vector > ranksSendMPI; /*!< \brief Double vector, which contains the ranks to which the donor elements - are sent for all time levels. */ - - vector > > commRecvBuf; /*!< \brief Receive buffers used to receive the solution data - in the communication pattern for all time levels. */ - vector > > commSendBuf; /*!< \brief Send buffers used to send the solution data - in the communication pattern for all time levels. */ -#endif - - vector > elementsRecvSelfComm; /*!< \brief Double vector, which contains the halo elements - for self communication for all time levels. */ - vector > elementsSendSelfComm; /*!< \brief Double vector, which contains the donor elements - for self communication for all time levels. */ - - vector rotationMatricesPeriodicity; /*!< \brief Vector, which contains the rotation matrices - for the rotational periodic transformations. */ - vector > > halosRotationalPeriodicity; /*!< \brief Triple vector, which contains the indices - of halo elements for which a periodic - transformation must be applied for all - time levels. */ - - vector tasksList; /*!< \brief List of tasks to be carried out in the computationally - intensive part of the solver. */ - - CVariable* GetBaseClassPointerToNodes() {return nullptr;} - -public: - - /*! - * \brief Constructor of the class. - */ - CFEM_DG_EulerSolver(void); - - /*! - * \overload - * \param[in] config - Definition of the particular problem. - * \param[in] val_nDim - Dimension of the problem (2D or 3D). - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - CFEM_DG_EulerSolver(CConfig *config, unsigned short val_nDim, unsigned short iMesh); - - /*! - * \overload - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - CFEM_DG_EulerSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); - - /*! - * \brief Destructor of the class. - */ - virtual ~CFEM_DG_EulerSolver(void); - - /*! - * \brief Set the fluid solver nondimensionalization. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] writeOutput - Whether or not output must be written. - */ - void SetNondimensionalization(CConfig *config, - unsigned short iMesh, - const bool writeOutput); - using CSolver::SetNondimensionalization; - - /*! - * \brief Get a pointer to the vector of the solution degrees of freedom. - * \return Pointer to the vector of the solution degrees of freedom. - */ - su2double* GetVecSolDOFs(void); - - /*! - * \brief Get the global number of solution degrees of freedom for the calculation. - * \return Global number of solution degrees of freedom - */ - unsigned long GetnDOFsGlobal(void); - - /*! - * \brief Compute the pressure at the infinity. - * \return Value of the pressure at the infinity. - */ - CFluidModel* GetFluidModel(void); - - /*! - * \brief Compute the density at the infinity. - * \return Value of the density at the infinity. - */ - su2double GetDensity_Inf(void); - - /*! - * \brief Compute 2-norm of the velocity at the infinity. - * \return Value of the 2-norm of the velocity at the infinity. - */ - su2double GetModVelocity_Inf(void); - - /*! - * \brief Compute the density multiply by energy at the infinity. - * \return Value of the density multiply by energy at the infinity. - */ - su2double GetDensity_Energy_Inf(void); - - /*! - * \brief Compute the pressure at the infinity. - * \return Value of the pressure at the infinity. - */ - su2double GetPressure_Inf(void); - - /*! - * \brief Compute the density multiply by velocity at the infinity. - * \param[in] val_dim - Index of the velocity vector. - * \return Value of the density multiply by the velocity at the infinity. - */ - su2double GetDensity_Velocity_Inf(unsigned short val_dim); - - /*! - * \brief Get the velocity at the infinity. - * \param[in] val_dim - Index of the velocity vector. - * \return Value of the velocity at the infinity. - */ - su2double GetVelocity_Inf(unsigned short val_dim); - - /*! - * \brief Get the velocity at the infinity. - * \return Value of the velocity at the infinity. - */ - su2double *GetVelocity_Inf(void); - - /*! - * \brief Set the freestream pressure. - * \param[in] Value of freestream pressure. - */ - void SetPressure_Inf(su2double p_inf); - - /*! - * \brief Set the freestream temperature. - * \param[in] Value of freestream temperature. - */ - void SetTemperature_Inf(su2double t_inf); - - /*! - * \brief Set the initial condition for the Euler Equations. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] ExtIter - External iteration. - */ - void SetInitialCondition(CGeometry **geometry, CSolver ***solver_container, - CConfig *config, unsigned long TimeIter); - - /*! - * \brief Set the working solution of the first time level to the current - solution. Used for Runge-Kutta type schemes. - * \param[in] geometry - Geometrical definition of the problem. - */ - void Set_OldSolution(CGeometry *geometry); - - /*! - * \brief Set the new solution to the current solution for classical RK. - * \param[in] geometry - Geometrical definition of the problem. - */ - void Set_NewSolution(CGeometry *geometry); - - /*! - * \brief Function to compute the time step for solving the Euler equations. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] Iteration - Value of the current iteration. - */ - void SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh, unsigned long Iteration); - - /*! - * \brief Function, which checks whether or not the time synchronization point is reached - when explicit time stepping is used. - * \param[in] config - Definition of the particular problem. - * \param[in] TimeSync - The synchronization time. - * \param[in,out] timeEvolved - On input the time evolved before the time step, - on output the time evolved after the time step. - * \param[out] syncTimeReached - Whether or not the synchronization time is reached. - */ - void CheckTimeSynchronization(CConfig *config, - const su2double TimeSync, - su2double &timeEvolved, - bool &syncTimeReached); - - /*! - * \brief Function, which processes the list of tasks to be executed by - the DG solver. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void ProcessTaskList_DG(CGeometry *geometry, CSolver **solver_container, - CNumerics **numerics, CConfig *config, - unsigned short iMesh); - - /*! - * \brief Function, to carry out the space time integration for ADER - with time accurate local time stepping. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void ADER_SpaceTimeIntegration(CGeometry *geometry, CSolver **solver_container, - CNumerics **numerics, CConfig *config, - unsigned short iMesh, unsigned short RunTime_EqSystem); - - /*! - * \brief Function, which controls the computation of the spatial Jacobian. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void ComputeSpatialJacobian(CGeometry *geometry, CSolver **solver_container, - CNumerics **numerics, CConfig *config, - unsigned short iMesh, unsigned short RunTime_EqSystem); - - /*! - * \brief Function, which determines the values of the tolerances in - the predictor step of ADER-DG. - */ - void TolerancesADERPredictorStep(void); - - /*! - * \brief Function, carries out the predictor step of the ADER-DG - time integration. - * \param[in] config - Definition of the particular problem. - * \param[in] elemBeg - Begin index of the element range to be computed. - * \param[in] elemEnd - End index (not included) of the element range to be computed. - * \param[out] workArray - Work array. - */ - void ADER_DG_PredictorStep(CConfig *config, - const unsigned long elemBeg, - const unsigned long elemEnd, - su2double *workArray); - - /*! - * \brief Function, which interpolates the predictor solution of ADER-DG - to the time value that corresponds to iTime. - * \param[in] config - Definition of the particular problem. - * \param[in] iTime - Time index of the time integration point for the - integration over the time slab in the corrector - step of ADER-DG. - * \param[in] elemBeg - Begin index of the element range to be computed. This - range is for elements of the same time level. - * \param[in] elemEnd - End index (not included) of the element range to be computed. - * \param[in] nAdjElem - Number of elements of the next time level, which are - adjacent to elements of the current time level. - * \param[in] adjElem - The ID's of the adjacent elements. - * \param[in] secondPartTimeInt - Whether or not this is the second part of the - time interval for the adjacent elements. - * \param[out] solTimeLevel - Array in which the interpolated solution for the - time level considered must be stored. - */ - void ADER_DG_TimeInterpolatePredictorSol(CConfig *config, - const unsigned short iTime, - const unsigned long elemBeg, - const unsigned long elemEnd, - const unsigned long nAdjElem, - const unsigned long *adjElem, - const bool secondPartTimeInt, - su2double *solTimeLevel); - - /*! - * \brief Compute the artificial viscosity for shock capturing in DG. It is a virtual - function, because this function is overruled for Navier-Stokes. - * \param[in] config - Definition of the particular problem. - * \param[in] elemBeg - Begin index of the element range to be computed. - * \param[in] elemEnd - End index (not included) of the element range to be computed. - * \param[out] workArray - Work array. - */ - virtual void Shock_Capturing_DG(CConfig *config, - const unsigned long elemBeg, - const unsigned long elemEnd, - su2double *workArray); - - /*! - * \brief Compute the volume contributions to the spatial residual. It is a virtual - function, because this function is overruled for Navier-Stokes. - * \param[in] config - Definition of the particular problem. - * \param[in] elemBeg - Begin index of the element range to be computed. - * \param[in] elemEnd - End index (not included) of the element range to be computed. - * \param[out] workArray - Work array. - */ - virtual void Volume_Residual(CConfig *config, - const unsigned long elemBeg, - const unsigned long elemEnd, - su2double *workArray); - - /*! - * \brief Function, which computes the spatial residual for the DG discretization. - * \param[in] timeLevel - Time level of the time accurate local time stepping, - if relevant. - * \param[in] config - Definition of the particular problem. - * \param[in] numerics - Description of the numerical method. - * \param[in] haloInfoNeededForBC - If true, treat boundaries for which halo data is needed. - If false, treat boundaries for which only owned data is needed. - * \param[out] workArray - Work array. - */ - void Boundary_Conditions(const unsigned short timeLevel, - CConfig *config, - CNumerics **numerics, - const bool haloInfoNeededForBC, - su2double *workArray); - - /*! - * \brief Compute the spatial residual for the given range of faces. It is a virtual - function, because this function is overruled for Navier-Stokes. - * \param[in] config - Definition of the particular problem. - * \param[in] indFaceBeg - Starting index in the matching faces. - * \param[in] indFaceEnd - End index in the matching faces. - * \param[in,out] indResFaces - Index where to store the residuals in - the vector of face residuals. - * \param[in] numerics - Description of the numerical method. - * \param[out] workArray - Work array. - */ - virtual void ResidualFaces(CConfig *config, - const unsigned long indFaceBeg, - const unsigned long indFaceEnd, - unsigned long &indResFaces, - CNumerics *numerics, - su2double *workArray); - - /*! - * \brief Function, which accumulates the space time residual of the ADER-DG - time integration scheme for the owned elements. - * \param[in] config - Definition of the particular problem. - * \param[in] timeLevel - time level for which the residuals must be - accumulated. - * \param[in] intPoint - Index of the time integration point. - */ - void AccumulateSpaceTimeResidualADEROwnedElem(CConfig *config, - const unsigned short timeLevel, - const unsigned short intPoint); - - /*! - * \brief Function, which accumulates the space time residual of the ADER-DG - time integration scheme for the halo elements. - * \param[in] config - Definition of the particular problem. - * \param[in] timeLevel - time level for which the residuals must be - accumulated. - * \param[in] intPoint - Index of the time integration point. - */ - void AccumulateSpaceTimeResidualADERHaloElem(CConfig *config, - const unsigned short timeLevel, - const unsigned short intPoint); - - /*! - * \brief Compute primitive variables and their gradients. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iStep - Current step in the time accurate local time - stepping algorithm, if appropriate. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - */ - void Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh, unsigned short iStep, unsigned short RunTime_EqSystem, bool Output); - - /*! - * \brief - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh); - - /*! - * \brief Impose via the residual the Euler wall boundary condition. It is a - virtual function, because for Navier-Stokes it is overwritten. - * \param[in] config - Definition of the particular problem. - * \param[in] surfElemBeg - Start index in the list of surface elements. - * \param[in] surfElemEnd - End index (not included) in the list of surface elements. - * \param[in] surfElem - Array of surface elements for which the boundary - conditions must be imposed. - * \param[out] resFaces - Array where the residual contribution from the - surface elements must be stored. - * \param[in] conv_numerics - Description of the numerical method. - * \param[out] workArray - Work array. - */ - virtual void BC_Euler_Wall(CConfig *config, - const unsigned long surfElemBeg, - const unsigned long surfElemEnd, - const CSurfaceElementFEM *surfElem, - su2double *resFaces, - CNumerics *conv_numerics, - su2double *workArray); - using CSolver::BC_Euler_Wall; - - /*! - * \brief Impose the far-field boundary condition. It is a virtual - function, because for Navier-Stokes it is overwritten. - * \param[in] config - Definition of the particular problem. - * \param[in] surfElemBeg - Start index in the list of surface elements. - * \param[in] surfElemEnd - End index (not included) in the list of surface elements. - * \param[in] surfElem - Array of surface elements for which the boundary - conditions must be imposed. - * \param[out] resFaces - Array where the residual contribution from the - surface elements must be stored. - * \param[in] conv_numerics - Description of the numerical method. - * \param[out] workArray - Work array. - */ - virtual void BC_Far_Field(CConfig *config, - const unsigned long surfElemBeg, - const unsigned long surfElemEnd, - const CSurfaceElementFEM *surfElem, - su2double *resFaces, - CNumerics *conv_numerics, - su2double *workArray); - using CSolver::BC_Far_Field; - - /*! - * \brief Impose the symmetry boundary condition. It is a virtual - function, because for Navier-Stokes it is overwritten. - * \param[in] config - Definition of the particular problem. - * \param[in] surfElemBeg - Start index in the list of surface elements. - * \param[in] surfElemEnd - End index (not included) in the list of surface elements. - * \param[in] surfElem - Array of surface elements for which the boundary - conditions must be imposed. - * \param[out] resFaces - Array where the residual contribution from the - surface elements must be stored. - * \param[in] conv_numerics - Description of the numerical method. - * \param[out] workArray - Work array. - */ - virtual void BC_Sym_Plane(CConfig *config, - const unsigned long surfElemBeg, - const unsigned long surfElemEnd, - const CSurfaceElementFEM *surfElem, - su2double *resFaces, - CNumerics *conv_numerics, - su2double *workArray); - using CSolver::BC_Sym_Plane; - - /*! - * \brief Impose the supersonic outlet boundary condition. It is a virtual - function, because for Navier-Stokes it is overwritten. - * \param[in] config - Definition of the particular problem. - * \param[in] surfElemBeg - Start index in the list of surface elements. - * \param[in] surfElemEnd - End index (not included) in the list of surface elements. - * \param[in] surfElem - Array of surface elements for which the boundary - conditions must be imposed. - * \param[out] resFaces - Array where the residual contribution from the - surface elements must be stored. - * \param[in] conv_numerics - Description of the numerical method. - * \param[out] workArray - Work array. - */ - virtual void BC_Supersonic_Outlet(CConfig *config, - const unsigned long surfElemBeg, - const unsigned long surfElemEnd, - const CSurfaceElementFEM *surfElem, - su2double *resFaces, - CNumerics *conv_numerics, - su2double *workArray); - using CSolver::BC_Supersonic_Outlet; - - /*! - * \brief Impose the subsonic inlet boundary condition. It is a virtual - function, because for Navier-Stokes it is overwritten. - * \param[in] config - Definition of the particular problem. - * \param[in] surfElemBeg - Start index in the list of surface elements. - * \param[in] surfElemEnd - End index (not included) in the list of surface elements. - * \param[in] surfElem - Array of surface elements for which the boundary - conditions must be imposed. - * \param[out] resFaces - Array where the residual contribution from the - surface elements must be stored. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - * \param[out] workArray - Work array. - */ - virtual void BC_Inlet(CConfig *config, - const unsigned long surfElemBeg, - const unsigned long surfElemEnd, - const CSurfaceElementFEM *surfElem, - su2double *resFaces, - CNumerics *conv_numerics, - unsigned short val_marker, - su2double *workArray); - using CSolver::BC_Inlet; - - /*! - * \brief Impose the outlet boundary condition.It is a virtual - function, because for Navier-Stokes it is overwritten. - * \param[in] config - Definition of the particular problem. - * \param[in] surfElemBeg - Start index in the list of surface elements. - * \param[in] surfElemEnd - End index (not included) in the list of surface elements. - * \param[in] surfElem - Array of surface elements for which the boundary - conditions must be imposed. - * \param[out] resFaces - Array where the residual contribution from the - surface elements must be stored. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - * \param[out] workArray - Work array. - */ - virtual void BC_Outlet(CConfig *config, - const unsigned long surfElemBeg, - const unsigned long surfElemEnd, - const CSurfaceElementFEM *surfElem, - su2double *resFaces, - CNumerics *conv_numerics, - unsigned short val_marker, - su2double *workArray); - using CSolver::BC_Outlet; - - /*! - * \brief Impose a constant heat-flux condition at the wall. It is a virtual - function, such that it can be overwritten for Navier-Stokes. - * \param[in] config - Definition of the particular problem. - * \param[in] surfElemBeg - Start index in the list of surface elements. - * \param[in] surfElemEnd - End index (not included) in the list of surface elements. - * \param[in] surfElem - Array of surface elements for which the boundary - conditions must be imposed. - * \param[out] resFaces - Array where the residual contribution from the - surface elements must be stored. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - * \param[out] workArray - Work array. - */ - virtual void BC_HeatFlux_Wall(CConfig *config, - const unsigned long surfElemBeg, - const unsigned long surfElemEnd, - const CSurfaceElementFEM *surfElem, - su2double *resFaces, - CNumerics *conv_numerics, - unsigned short val_marker, - su2double *workArray); - using CSolver::BC_HeatFlux_Wall; - - /*! - * \brief Impose an isothermal condition at the wall. It is a virtual - function, such that it can be overwritten for Navier-Stokes. - * \param[in] config - Definition of the particular problem. - * \param[in] surfElemBeg - Start index in the list of surface elements. - * \param[in] surfElemEnd - End index (not included) in the list of surface elements. - * \param[in] surfElem - Array of surface elements for which the boundary - conditions must be imposed. - * \param[out] resFaces - Array where the residual contribution from the - surface elements must be stored. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - * \param[out] workArray - Work array. - */ - virtual void BC_Isothermal_Wall(CConfig *config, - const unsigned long surfElemBeg, - const unsigned long surfElemEnd, - const CSurfaceElementFEM *surfElem, - su2double *resFaces, - CNumerics *conv_numerics, - unsigned short val_marker, - su2double *workArray); - using CSolver::BC_Isothermal_Wall; - - /*! - * \brief Impose the boundary condition using characteristic reconstruction. It is - * a virtual function, such that it can be overwritten for Navier-Stokes. - * \param[in] config - Definition of the particular problem. - * \param[in] surfElemBeg - Start index in the list of surface elements. - * \param[in] surfElemEnd - End index (not included) in the list of surface elements. - * \param[in] surfElem - Array of surface elements for which the boundary - conditions must be imposed. - * \param[out] resFaces - Array where the residual contribution from the - surface elements must be stored. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - * \param[out] workArray - Work array. - */ - virtual void BC_Riemann(CConfig *config, - const unsigned long surfElemBeg, - const unsigned long surfElemEnd, - const CSurfaceElementFEM *surfElem, - su2double *resFaces, - CNumerics *conv_numerics, - unsigned short val_marker, - su2double *workArray); - using CSolver::BC_Riemann; - - /*! - * \brief Impose the user customized boundary condition. It is a virtual - function, because for Navier-Stokes it is overwritten. - * \param[in] config - Definition of the particular problem. - * \param[in] surfElemBeg - Start index in the list of surface elements. - * \param[in] surfElemEnd - End index (not included) in the list of surface elements. - * \param[in] surfElem - Array of surface elements for which the boundary - conditions must be imposed. - * \param[out] resFaces - Array where the residual contribution from the - surface elements must be stored. - * \param[in] conv_numerics - Description of the numerical method. - * \param[out] workArray - Work array. - */ - virtual void BC_Custom(CConfig *config, - const unsigned long surfElemBeg, - const unsigned long surfElemEnd, - const CSurfaceElementFEM *surfElem, - su2double *resFaces, - CNumerics *conv_numerics, - su2double *workArray); - using CSolver::BC_Custom; - - /*! - * \brief Update the solution using a Runge-Kutta scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - void ExplicitRK_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iRKStep); - - /*! - * \brief Update the solution using the classical fourth-order Runge-Kutta scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - */ - void ClassicalRK4_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iRKStep); - - /*! - * \brief Update the solution using the classical fourth-order Runge-Kutta scheme. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void SetResidual_RMS_FEM(CGeometry *geometry, CConfig *config); - - /*! - * \brief Compute the global error measures (L2, Linf) for verification cases. - * \param[in] geometry - Geometrical definition. - * \param[in] config - Definition of the particular problem. - */ - void ComputeVerificationError(CGeometry *geometry, CConfig *config); - - /*! - * \brief Update the solution for the ADER-DG scheme for the given range - of elements. - * \param[in] elemBeg - Begin index of the element range to be computed. - * \param[in] elemEnd - End index (not included) of the element range to be computed. - */ - void ADER_DG_Iteration(const unsigned long elemBeg, - const unsigned long elemEnd); - - /*! - * \brief Compute the pressure forces and all the adimensional coefficients. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Pressure_Forces(CGeometry *geometry, CConfig *config); - - /*! - * \brief Load a solution from a restart file. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - Container vector with all of the solvers. - * \param[in] config - Definition of the particular problem. - * \param[in] val_iter - Current external iteration number. - * \param[in] val_update_geo - Flag for updating coords and grid velocity. - */ - void LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo); - - /*! - * \brief Provide the non dimensional lift coefficient (inviscid contribution). - * \param val_marker Surface where the coefficient is going to be computed. - * \return Value of the lift coefficient (inviscid contribution) on the surface val_marker. - */ - su2double GetCL_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional z moment coefficient (inviscid contribution). - * \param val_marker Surface where the coefficient is going to be computed. - * \return Value of the z moment coefficient (inviscid contribution) on the surface val_marker. - */ - su2double GetCMz_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional lift coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the lift coefficient on the surface val_marker. - */ - su2double GetSurface_CL(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional drag coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the drag coefficient on the surface val_marker. - */ - su2double GetSurface_CD(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional side-force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side-force coefficient on the surface val_marker. - */ - su2double GetSurface_CSF(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional side-force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side-force coefficient on the surface val_marker. - */ - su2double GetSurface_CEff(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional x force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x force coefficient on the surface val_marker. - */ - su2double GetSurface_CFx(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional y force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y force coefficient on the surface val_marker. - */ - su2double GetSurface_CFy(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional z force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z force coefficient on the surface val_marker. - */ - su2double GetSurface_CFz(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional x moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMx(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional y moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMy(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional z moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMz(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional lift coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the lift coefficient on the surface val_marker. - */ - su2double GetSurface_CL_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional drag coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the drag coefficient on the surface val_marker. - */ - su2double GetSurface_CD_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional side-force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side-force coefficient on the surface val_marker. - */ - su2double GetSurface_CSF_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional side-force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the side-force coefficient on the surface val_marker. - */ - su2double GetSurface_CEff_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional x force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x force coefficient on the surface val_marker. - */ - su2double GetSurface_CFx_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional y force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y force coefficient on the surface val_marker. - */ - su2double GetSurface_CFy_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional z force coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z force coefficient on the surface val_marker. - */ - su2double GetSurface_CFz_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional x moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the x moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMx_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional y moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the y moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMy_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional z moment coefficient. - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z moment coefficient on the surface val_marker. - */ - su2double GetSurface_CMz_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional drag coefficient (inviscid contribution). - * \param val_marker Surface where the coeficient is going to be computed. - * \return Value of the drag coefficient (inviscid contribution) on the surface val_marker. - */ - su2double GetCD_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional sideforce coefficient (inviscid contribution). - * \param val_marker Surface where the coeficient is going to be computed. - * \return Value of the sideforce coefficient (inviscid contribution) on the surface val_marker. - */ - su2double GetCSF_Inv(unsigned short val_marker); - - /*! - * \brief Provide the non dimensional efficiency coefficient (inviscid contribution). - * \param val_marker Surface where the coeficient is going to be computed. - * \return Value of the efficiency coefficient (inviscid contribution) on the surface val_marker. - */ - su2double GetCEff_Inv(unsigned short val_marker); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional sideforce coefficient. - * \return Value of the sideforce coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CSF(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CEff(void); - - /*! - * \brief Store the total (inviscid + viscous) non dimensional lift coefficient. - * \param[in] val_Total_CL - Value of the total lift coefficient. - */ - void SetTotal_CL(su2double val_Total_CL); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional lift coefficient. - * \return Value of the lift coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CL(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. - * \return Value of the drag coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CD(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional x moment coefficient. - * \return Value of the moment x coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CMx(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional y moment coefficient. - * \return Value of the moment y coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CMy(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional z moment coefficient. - * \return Value of the moment z coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CMz(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional x force coefficient. - * \return Value of the force x coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CFx(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional y force coefficient. - * \return Value of the force y coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CFy(void); - - /*! - * \brief Provide the total (inviscid + viscous) non dimensional z force coefficient. - * \return Value of the force z coefficient (inviscid + viscous contribution). - */ - su2double GetTotal_CFz(void); - - /*! - * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. - * \param[in] val_Total_CD - Value of the total drag coefficient. - */ - void SetTotal_CD(su2double val_Total_CD); - - /*! - * \brief Get the inviscid contribution to the lift coefficient. - * \return Value of the lift coefficient (inviscid contribution). - */ - su2double GetAllBound_CL_Inv(void); - - /*! - * \brief Get the inviscid contribution to the drag coefficient. - * \return Value of the drag coefficient (inviscid contribution). - */ - su2double GetAllBound_CD_Inv(void); - - /*! - * \brief Get the inviscid contribution to the sideforce coefficient. - * \return Value of the sideforce coefficient (inviscid contribution). - */ - su2double GetAllBound_CSF_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CEff_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CMx_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CMy_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CMz_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CFx_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CFy_Inv(void); - - /*! - * \brief Get the inviscid contribution to the efficiency coefficient. - * \return Value of the efficiency coefficient (inviscid contribution). - */ - su2double GetAllBound_CFz_Inv(void); - -protected: - - /*! - * \brief Routine that initiates the non-blocking communication between ranks - for the givem time level. - * \param[in] config - Definition of the particular problem. - * \param[in] timeLevel - The time level for which the communication must be - initiated. - */ - void Initiate_MPI_Communication(CConfig *config, - const unsigned short timeLevel); - - /*! - * \brief Routine that initiates the reverse non-blocking communication - between ranks. - * \param[in] config - Definition of the particular problem. - * \param[in] timeLevel - The time level for which the reverse communication - must be initiated. - */ - void Initiate_MPI_ReverseCommunication(CConfig *config, - const unsigned short timeLevel); - - /*! - * \brief Routine that completes the non-blocking communication between ranks. - * \param[in] config - Definition of the particular problem. - * \param[in] timeLevel - The time level for which the communication - may be completed. - * \param[in] commMustBeCompleted - Whether or not the communication must be completed. - * \return Whether or not the communication has been completed. - */ - bool Complete_MPI_Communication(CConfig *config, - const unsigned short timeLevel, - const bool commMustBeCompleted); - - /*! - * \brief Routine that completes the reverse non-blocking communication - between ranks. - * \param[in] config - Definition of the particular problem. - * \param[in] timeLevel - The time level for which the communication - may be completed. - * \param[in] commMustBeCompleted - Whether or not the communication must be completed. - * \return Whether or not the communication has been completed. - */ - bool Complete_MPI_ReverseCommunication(CConfig *config, - const unsigned short timeLevel, - const bool commMustBeCompleted); - - /*! - * \brief Function, which computes the inviscid fluxes in face points. - * \param[in] config - Definition of the particular problem. - * \param[in] nFaceSimul - Number of faces that are treated simultaneously - to improve performance. - * \param[in] NPad - Value of the padding parameter to obtain optimal - performance in the gemm computations. - * \param[in] nPoints - Number of points per face for which the fluxes - must be computed. - * \param[in] normalsFace - The normals in the points for the faces. - * \param[in] gridVelsFace - The grid velocities in the points for the faces. - * \param[in] solL - Solution in the left state of the points. - * \param[in] solR - Solution in the right state of the points. - * \param[out] fluxes - Inviscid fluxes in the points. - * \param[in] numerics - Object, which contains the Riemann solver. - */ - void ComputeInviscidFluxesFace(CConfig *config, - const unsigned short nFaceSimul, - const unsigned short NPad, - const unsigned long nPoints, - const su2double *normalsFace[], - const su2double *gridVelsFace[], - const su2double *solL, - const su2double *solR, - su2double *fluxes, - CNumerics *numerics); - - /*! - * \brief Function, which computes the inviscid fluxes in the face integration - points of a chunk of matching internal faces. - * \param[in] config - Definition of the particular problem. - * \param[in] lBeg - Start index in matchingInternalFaces for which - the inviscid fluxes should be computed. - * \param[in] lEnd - End index (not included) in matchingInternalFaces - for which the inviscid fluxes should be computed. - * \param[in] NPad - Value of the padding parameter to obtain optimal - performance in the gemm computations. - * \param[out] solIntL - Solution in the left state of the integration points. - * \param[out] solIntR - Solution in the right state of the integration points. - * \param[out] fluxes - Inviscid fluxes in the integration points. - * \param[in] numerics - Object, which contains the Riemann solver. - */ - void InviscidFluxesInternalMatchingFace(CConfig *config, - const unsigned long lBeg, - const unsigned long lEnd, - const unsigned short NPad, - su2double *solIntL, - su2double *solIntR, - su2double *fluxes, - CNumerics *numerics); - /*! - * \brief Function, which computes the left state of a boundary face. - * \param[in] config - Definition of the particular problem. - * \param[in] nFaceSimul - Number of faces that are treated simultaneously - to improve performance. - * \param[in] NPad - Value of the padding parameter to obtain optimal - performance in the gemm computations. - * \param[in] surfElem - Surface boundary elements for which the left state must be computed. - * \param[out] solFace - Temporary storage for the solution in the DOFs. - * \param[out] solIntL - Left states in the integration points of the face. - */ - void LeftStatesIntegrationPointsBoundaryFace(CConfig *config, - const unsigned short nFaceSimul, - const unsigned short NPad, - const CSurfaceElementFEM *surfElem, - su2double *solFace, - su2double *solIntL); - - /*! - * \brief Function, which computes the boundary states in the integration points - of the boundary face by applying the inviscid wall boundary conditions. - * \param[in] config - Definition of the particular problem. - * \param[in] nFaceSimul - Number of faces that are treated simultaneously - to improve performance. - * \param[in] NPad - Value of the padding parameter to obtain optimal - performance in the gemm computations. - * \param[in] surfElem - Surface boundary elements for which the left state must - be computed. - * \param[in] solIntL - Left states in the integration points of the face. - * \param[out] solIntR - Right states in the integration points of the face. - */ - void BoundaryStates_Euler_Wall(CConfig *config, - const unsigned short nFaceSimul, - const unsigned short NPad, - const CSurfaceElementFEM *surfElem, - const su2double *solIntL, - su2double *solIntR); - - /*! - * \brief Function, which computes the boundary states in the integration points - of the boundary face by applying the inlet boundary conditions. - * \param[in] config - Definition of the particular problem. - * \param[in] nFaceSimul - Number of fused faces, i.e. the number of faces - that are treated simultaneously to improve performance. - * \param[in] NPad - Value of the padding parameter to obtain optimal - performance in the gemm computations. - * \param[in] surfElem - Surface boundary element for which the left state must be computed. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - * \param[in] solIntL - Left states in the integration points of the face. - * \param[out] solIntR - Right states in the integration points of the face. - */ - void BoundaryStates_Inlet(CConfig *config, - const unsigned short nFaceSimul, - const unsigned short NPad, - const CSurfaceElementFEM *surfElem, - unsigned short val_marker, - const su2double *solIntL, - su2double *solIntR); - - /*! - * \brief Function, which computes the boundary states in the integration points - of the boundary face by applying the outlet boundary conditions. - * \param[in] config - Definition of the particular problem. - * \param[in] nFaceSimul - Number of fused faces, i.e. the number of faces - that are treated simultaneously to improve performance. - * \param[in] NPad - Value of the padding parameter to obtain optimal - performance in the gemm computations. - * \param[in] surfElem - Surface boundary element for which the left state must be computed. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - * \param[in] solIntL - Left states in the integration points of the face. - * \param[out] solIntR - Right states in the integration points of the face. - */ - void BoundaryStates_Outlet(CConfig *config, - const unsigned short nFaceSimul, - const unsigned short NPad, - const CSurfaceElementFEM *surfElem, - unsigned short val_marker, - const su2double *solIntL, - su2double *solIntR); - - /*! - * \brief Function, which computes the boundary states in the integration points - of the boundary face by applying the Riemann boundary conditions. - * \param[in] config - Definition of the particular problem. - * \param[in] nFaceSimul - Number of fused faces, i.e. the number of faces - that are treated simultaneously to improve performance. - * \param[in] NPad - Value of the padding parameter to obtain optimal - performance in the gemm computations. - * \param[in] surfElem - Surface boundary element for which the left state must be computed. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - * \param[in] solIntL - Left states in the integration points of the face. - * \param[out] solIntR - Right states in the integration points of the face. - */ - void BoundaryStates_Riemann(CConfig *config, - const unsigned short nFaceSimul, - const unsigned short NPad, - const CSurfaceElementFEM *surfElem, - unsigned short val_marker, - const su2double *solIntL, - su2double *solIntR); -private: - - /*! - * \brief Virtual function, which computes the spatial residual of the ADER-DG - predictor step for the given volume element and solution using an - aliased discretization in 2D. - * \param[in] config - Definition of the particular problem. - * \param[in] elem - Volume element for which the spatial residual of the - predictor step must be computed. - * \param[in] sol - Solution for which the residual must be computed. - * \param[in] nSimul - Number of entities (typically time integration points) - that are treated simultaneously. - * \param[in] NPad - Padded N value in the matrix multiplications to - obtain better performance. The solution sol is stored - with this padded value to avoid a memcpy. - * \param[out] res - Residual of the spatial DOFs to be computed by this - function. - * \param[out] work - Work array. - */ - virtual void ADER_DG_AliasedPredictorResidual_2D(CConfig *config, - CVolumeElementFEM *elem, - const su2double *sol, - const unsigned short nSimul, - const unsigned short NPad, - su2double *res, - su2double *work); - - /*! - * \brief Virtual function, which computes the spatial residual of the ADER-DG - predictor step for the given volume element and solution using an - aliased discretization in 3D. - * \param[in] config - Definition of the particular problem. - * \param[in] elem - Volume element for which the spatial residual of the - predictor step must be computed. - * \param[in] sol - Solution for which the residual must be computed. - * \param[in] nSimul - Number of entities (typically time integration points) - that are treated simultaneously. - * \param[in] NPad - Padded N value in the matrix multiplications to - obtain better performance. The solution sol is stored - with this padded value to avoid a memcpy. - * \param[out] res - Residual of the spatial DOFs to be computed by this - function. - * \param[out] work - Work array. - */ - virtual void ADER_DG_AliasedPredictorResidual_3D(CConfig *config, - CVolumeElementFEM *elem, - const su2double *sol, - const unsigned short nSimul, - const unsigned short NPad, - su2double *res, - su2double *work); - - /*! - * \brief Virtual function, which computes the spatial residual of the ADER-DG - predictor step for the given volume element and solution using a - non-aliased discretization in 2D. - * \param[in] config - Definition of the particular problem. - * \param[in] elem - Volume element for which the spatial residual of the - predictor step must be computed. - * \param[in] sol - Solution for which the residual must be computed. - * \param[in] nSimul - Number of entities (typically time integration points) - that are treated simultaneously. - * \param[in] NPad - Padded N value in the matrix multiplications to - obtain better performance. The solution sol is stored - with this padded value to avoid a memcpy. - * \param[out] res - Residual of the spatial DOFs to be computed by this - function. - * \param[out] work - Work array. - */ - virtual void ADER_DG_NonAliasedPredictorResidual_2D(CConfig *config, - CVolumeElementFEM *elem, - const su2double *sol, - const unsigned short nSimul, - const unsigned short NPad, - su2double *res, - su2double *work); - - /*! - * \brief Virtual function, which computes the spatial residual of the ADER-DG - predictor step for the given volume element and solution using a - non-aliased discretization in 3D. - * \param[in] config - Definition of the particular problem. - * \param[in] elem - Volume element for which the spatial residual of the - predictor step must be computed. - * \param[in] sol - Solution for which the residual must be computed. - * \param[in] nSimul - Number of entities (typically time integration points) - that are treated simultaneously. - * \param[in] NPad - Padded N value in the matrix multiplications to - obtain better performance. The solution sol is stored - with this padded value to avoid a memcpy. - * \param[out] res - Residual of the spatial DOFs to be computed by this - function. - * \param[out] work - Work array. - */ - virtual void ADER_DG_NonAliasedPredictorResidual_3D(CConfig *config, - CVolumeElementFEM *elem, - const su2double *sol, - const unsigned short nSimul, - const unsigned short NPad, - su2double *res, - su2double *work); - - /*! - * \brief Function, which computes the graph of the spatial discretization - for the locally owned DOFs. - * \param[in] DGGeometry - Geometrical definition of the DG problem. - * \param[in] config - Definition of the particular problem. - */ - void DetermineGraphDOFs(const CMeshFEM *FEMGeometry, - CConfig *config); - - /*! - * \brief Function, which determines the meta data needed for the computation - of the Jacobian of the spatial residual. - * \param[in] DGGeometry - Geometrical definition of the DG problem. - * \param[in] colorLocalDOFs - Color of the locally stored DOFs. - */ - void MetaDataJacobianComputation(const CMeshFEM *FEMGeometry, - const vector &colorLocalDOFs); - - /*! - * \brief Function, which sets up the list of tasks to be carried out in the - computationally expensive part of the solver. - * \param[in] config - Definition of the particular problem. - */ - void SetUpTaskList(CConfig *config); - - /*! - * \brief Function, which sets up the persistent communication of the flow - variables in the DOFs. - * \param[in] DGGeometry - Geometrical definition of the DG problem. - * \param[in] config - Definition of the particular problem. - */ - void Prepare_MPI_Communication(const CMeshFEM *FEMGeometry, - CConfig *config); - - /*! - * \brief Function, which creates the final residual by summing up - the contributions for the DOFs of the elements considered. - * \param[in] timeLevel - Time level of the elements for which the - final residual must be created. - * \param[in] ownedElements - Whether owned or halo elements must be treated. - */ - void CreateFinalResidual(const unsigned short timeLevel, - const bool ownedElements); - - /*! - * \brief Function, which multiplies the residual by the inverse - of the (lumped) mass matrix. - * \param[in] config - Definition of the particular problem. - * \param[in] useADER - Whether or not the ADER residual must be multiplied. - * \param[in] elemBeg - Begin index of the element range to be computed. - * \param[in] elemEnd - End index (not included) of the element range to be computed. - * \param[out] workArray - Work array. - */ - void MultiplyResidualByInverseMassMatrix(CConfig *config, - const bool useADER, - const unsigned long elemBeg, - const unsigned long elemEnd, - su2double *workArray); - - /*! - * \brief Function, which computes the residual contribution from a boundary - face in an inviscid computation when the boundary conditions have - already been applied. - * \param[in] config - Definition of the particular problem. - * \param[in] nFaceSimul - Number of faces that are treated simultaneously - to improve performance. - * \param[in] NPad - Value of the padding parameter to obtain optimal - performance in the gemm computations. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] surfElem - Surface boundary element for which the - contribution to the residual must be computed. - * \param[in] solInt0 - Solution in the integration points of side 0. - It is not const, because the array is used for - temporary storage for the residual. - * \param[in] solInt1 - Solution in the integration points of side 1. - * \param[out] fluxes - Temporary storage for the fluxes in the - integration points. - * \param[out] resFaces - Array to store the residuals of the face. - * \param[in,out] indResFaces - Index in resFaces, where the current residual - should be stored. It is updated in the function - for the next boundary element. - */ - void ResidualInviscidBoundaryFace(CConfig *config, - const unsigned short nFaceSimul, - const unsigned short NPad, - CNumerics *conv_numerics, - const CSurfaceElementFEM *surfElem, - su2double *solInt0, - su2double *solInt1, - su2double *fluxes, - su2double *resFaces, - unsigned long &indResFaces); - -protected: - /*! - * \brief Template function, which determines some meta data for the chunk of - elements/faces that must be treated simulaneously. - * \param[in] elem - Const pointer the volume or face elements for which - the meta data must be computed. - * \param[in] l - Start index for the current chunk of elements/faces. - * \param[in] elemEnd - End index (index not included) of the elements to be - treated in the residual computation from which this - function is called. - * \param[in] nElemSimul - Desired number of elements/faces that must be treated - simultaneously for optimal performance. - * \param[in] nPadMin - Minimum number of the padding value in the gemm calls. - * \param[out] lEnd - Actual end index (not included) for this chunk of - elements. - * \param[out] ind - Index in the standard elements to which this chunk of - elements can be mapped. - * \param[out] llEnd - Actual number of elements/faces that are treated - simultaneously, llEnd = lEnd - l. - * \param[out] NPad - Actual padded N value in the gemm computations for - this chunk of elements. - */ - template - void MetaDataChunkOfElem(const TElemType *elem, - const unsigned long l, - const unsigned long elemEnd, - const unsigned short nElemSimul, - const unsigned short nPadMin, - unsigned long &lEnd, - unsigned short &ind, - unsigned short &llEnd, - unsigned short &NPad) { - - /* Determine the end index for this chunk of elements that must be - treated simulaneously. The elements of this chunk must have the - same standard element in order to make this work. */ - const unsigned long lEndMax = min(l+nElemSimul, elemEnd); - - ind = elem[l].indStandardElement; - for(lEnd=l+1; lEndval_marker. - */ - su2double GetCL_Visc(unsigned short val_marker); - - /*! - * \brief Get the non dimensional z moment coefficient (viscous contribution). - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the z moment coefficient (viscous contribution) on the surface val_marker. - */ - su2double GetCMz_Visc(unsigned short val_marker); - - /*! - * \brief Get the non dimensional sideforce coefficient (viscous contribution). - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the sideforce coefficient (viscous contribution) on the surface val_marker. - */ - su2double GetCSF_Visc(unsigned short val_marker); - - /*! - * \brief Get the non dimensional drag coefficient (viscous contribution). - * \param[in] val_marker - Surface marker where the coefficient is computed. - * \return Value of the drag coefficient (viscous contribution) on the surface val_marker. - */ - su2double GetCD_Visc(unsigned short val_marker); - - /*! - * \brief Get the total non dimensional lift coefficient (viscous contribution). - * \return Value of the lift coefficient (viscous contribution). - */ - su2double GetAllBound_CL_Visc(void); - - /*! - * \brief Get the total non dimensional sideforce coefficient (viscous contribution). - * \return Value of the lift coefficient (viscous contribution). - */ - su2double GetAllBound_CSF_Visc(void); - - /*! - * \brief Get the total non dimensional drag coefficient (viscous contribution). - * \return Value of the drag coefficient (viscous contribution). - */ - su2double GetAllBound_CD_Visc(void); - - /*! - * \brief Get the max Omega. - * \return Value of the max Omega. - */ - su2double GetOmega_Max(void); - - /*! - * \brief Get the max Strain rate magnitude. - * \return Value of the max Strain rate magnitude. - */ - su2double GetStrainMag_Max(void); - - /*! - * \brief A virtual member. - * \return Value of the StrainMag_Max - */ - void SetStrainMag_Max(su2double val_strainmag_max); - - /*! - * \brief A virtual member. - * \return Value of the Omega_Max - */ - void SetOmega_Max(su2double val_omega_max); - -private: - - /*! - * \brief Function, which computes the spatial residual of the ADER-DG - predictor step for the given volume element and solution using an - aliased discretization in 2D. - * \param[in] config - Definition of the particular problem. - * \param[in] elem - Volume element for which the spatial residual of the - predictor step must be computed. - * \param[in] sol - Solution for which the residual must be computed. - * \param[in] nSimul - Number of entities (typically time integration points) - that are treated simultaneously. - * \param[in] NPad - Padded N value in the matrix multiplications to - obtain better performance. The solution sol is stored - with this padded value to avoid a memcpy. - * \param[out] res - Residual of the spatial DOFs to be computed by this - function. - * \param[out] work - Work array. - */ - void ADER_DG_AliasedPredictorResidual_2D(CConfig *config, - CVolumeElementFEM *elem, - const su2double *sol, - const unsigned short nSimul, - const unsigned short NPad, - su2double *res, - su2double *work); - -/*! - * \brief Function, which computes the spatial residual of the ADER-DG - predictor step for the given volume element and solution using an - aliased discretization in 3D. - * \param[in] config - Definition of the particular problem. - * \param[in] elem - Volume element for which the spatial residual of the - predictor step must be computed. - * \param[in] sol - Solution for which the residual must be computed. - * \param[in] nSimul - Number of entities (typically time integration points) - that are treated simultaneously. - * \param[in] NPad - Padded N value in the matrix multiplications to - obtain better performance. The solution sol is stored - with this padded value to avoid a memcpy. - * \param[out] res - Residual of the spatial DOFs to be computed by this - function. - * \param[out] work - Work array. - */ - void ADER_DG_AliasedPredictorResidual_3D(CConfig *config, - CVolumeElementFEM *elem, - const su2double *sol, - const unsigned short nSimul, - const unsigned short NPad, - su2double *res, - su2double *work); - /*! - * \brief Function, which computes the spatial residual of the ADER-DG - predictor step for the given volume element and solution using a - non-aliased discretization in 2D. - * \param[in] config - Definition of the particular problem. - * \param[in] elem - Volume element for which the spatial residual of the - predictor step must be computed. - * \param[in] sol - Solution for which the residual must be computed. - * \param[in] nSimul - Number of entities (typically time integration points) - that are treated simultaneously. - * \param[in] NPad - Padded N value in the matrix multiplications to - obtain better performance. The solution sol is stored - with this padded value to avoid a memcpy. - * \param[out] res - Residual of the spatial DOFs to be computed by this - function. - * \param[out] work - Work array. - */ - void ADER_DG_NonAliasedPredictorResidual_2D(CConfig *config, - CVolumeElementFEM *elem, - const su2double *sol, - const unsigned short nSimul, - const unsigned short NPad, - su2double *res, - su2double *work); - - /*! - * \brief Function, which computes the spatial residual of the ADER-DG - predictor step for the given volume element and solution using a - non-aliased discretization in 3D. - * \param[in] config - Definition of the particular problem. - * \param[in] elem - Volume element for which the spatial residual of the - predictor step must be computed. - * \param[in] sol - Solution for which the residual must be computed. - * \param[in] nSimul - Number of entities (typically time integration points) - that are treated simultaneously. - * \param[in] NPad - Padded N value in the matrix multiplications to - obtain better performance. The solution sol is stored - with this padded value to avoid a memcpy. - * \param[out] res - Residual of the spatial DOFs to be computed by this - function. - * \param[out] work - Work array. - */ - void ADER_DG_NonAliasedPredictorResidual_3D(CConfig *config, - CVolumeElementFEM *elem, - const su2double *sol, - const unsigned short nSimul, - const unsigned short NPad, - su2double *res, - su2double *work); - /*! - * \brief Function to compute the penalty terms in the integration - points of a face. - * \param[in] indFaceChunk - Index of the face in the chunk of fused faces. - * \param[in] nInt - Number of integration points of the face. - * \param[in] NPad - Value of the padding parameter to obtain optimal - performance in the gemm computations. - * \param[in] solInt0 - Solution in the integration points of side 0. - * \param[in] solInt1 - Solution in the integration points of side 1. - * \param[in] viscosityInt0 - Viscosity in the integration points of side 0. - * \param[in] viscosityInt1 - Viscosity in the integration points of side 1. - * \param[in] kOverCvInt0 - Heat conductivity divided by Cv in the - integration points of side 0. - * \param[in] kOverCvInt1 - Heat conductivity divided by Cv in the - integration points of side 1. - * \param[in] ConstPenFace - Penalty constant for this face. - * \param[in] lenScale0 - Length scale of the element of side 0. - * \param[in] lenScale1 - Length scale of the element of side 1. - * \param[in] metricNormalsFace - Metric terms in the integration points, which - contain the normals. - * \param[out] penaltyFluxes - Penalty fluxes in the integration points. - */ - void PenaltyTermsFluxFace(const unsigned short indFaceChunk, - const unsigned short nInt, - const unsigned short NPad, - const su2double *solInt0, - const su2double *solInt1, - const su2double *viscosityInt0, - const su2double *viscosityInt1, - const su2double *kOverCvInt0, - const su2double *kOverCvInt1, - const su2double ConstPenFace, - const su2double lenScale0, - const su2double lenScale1, - const su2double *metricNormalsFace, - su2double *penaltyFluxes); - - /*! - * \brief Function, which performs the treatment of the boundary faces for - the Navier-Stokes equations for the most of the boundary conditions. - * \param[in] config - Definition of the particular problem. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] nFaceSimul - Number of faces that are treated simultaneously - to improve performance. - * \param[in] NPad - Value of the padding parameter to obtain optimal - performance in the gemm computations. - * \param[in] Wall_HeatFlux - The value of the prescribed heat flux. - * \param[in] HeatFlux_Prescribed - Whether or not the heat flux is prescribed by - e.g. the boundary conditions. - * \param[in] Wall_Temperature - The value of the prescribed wall temperature. - * \param[in] Temperature_Prescribed - Whether or not the temperature is precribed - by e.g. the boundary conditions. - * \param[in] surfElem - Surface boundary elements for which the - residuals mut be computed. - * \param[in] solIntL - Left states in the integration points of the face. - * \param[in] solIntR - Right states in the integration points of the face. - * \param[out] workArray - Storage for the local arrays. - * \param[out] resFaces - Array to store the residuals of the face. - * \param[in,out] indResFaces - Index in resFaces, where the current residual - should be stored. It is updated in the function - for the next boundary element. - * \param[in,out] wallModel - Possible pointer to the wall model treatment. - NULL pointer indicates no wall model treatment. - */ - void ViscousBoundaryFacesBCTreatment(CConfig *config, - CNumerics *conv_numerics, - const unsigned short nFaceSimul, - const unsigned short NPad, - const su2double Wall_HeatFlux, - const bool HeatFlux_Prescribed, - const su2double Wall_Temperature, - const bool Temperature_Prescribed, - const CSurfaceElementFEM *surfElem, - const su2double *solIntL, - const su2double *solIntR, - su2double *workArray, - su2double *resFaces, - unsigned long &indResFaces, - CWallModel *wallModel); - - /*! - * \brief Function, which computes the viscous fluxes in the integration - points for the boundary faces that must be treated simulaneously. - This function uses the standard approach for computing the fluxes, - i.e. no wall modeling. - * \param[in] config - Definition of the particular problem. - * \param[in] nFaceSimul - Number of faces that are treated simultaneously - to improve performance. - * \param[in] NPad - Value of the padding parameter to obtain optimal - performance in the gemm computations. - * \param[in] nInt - Number of integration points on the face. - * \param[in] nDOFsElem - Number of DOFs of the adjacent element. - * \param[in] Wall_HeatFlux - The value of the prescribed heat flux. - * \param[in] HeatFlux_Prescribed - Whether or not the heat flux is prescribed by - e.g. the boundary conditions. - * \param[in] derBasisElem - Array, which contains the derivatives of the - basis functions of the adjacent element - in the integration points. - * \param[in] surfElem - Surface boundary elements for which the - viscous fluxes must be computed. - * \param[in] solIntL - Left states in the integration points of the face. - * \param[out] solElem - Storage for the solution in the adjacent elements. - * \param[out] gradSolInt - Storage for the gradients of the solution in the - integration points of the face. - * \param[out] viscFluxes - To be computed viscous fluxes in the - integration points. - * \param[out] viscosityInt - To be computed viscosity in the integration points. - * \param[out] kOverCvInt - To be computed thermal conductivity in the - integration points. - */ - void ComputeViscousFluxesBoundaryFaces(CConfig *config, - const unsigned short nFaceSimul, - const unsigned short NPad, - const unsigned short nInt, - const unsigned short nDOFsElem, - const su2double Wall_HeatFlux, - const bool HeatFlux_Prescribed, - const su2double *derBasisElem, - const CSurfaceElementFEM *surfElem, - const su2double *solIntL, - su2double *solElem, - su2double *gradSolInt, - su2double *viscFluxes, - su2double *viscosityInt, - su2double *kOverCvInt); - - /*! - * \brief Function, which computes the viscous fluxes in the integration - points for the boundary faces that must be treated simulaneously. - The viscous fluxes are computed via a wall modeling approach. - * \param[in] config - Definition of the particular problem. - * \param[in] nFaceSimul - Number of faces that are treated simultaneously - to improve performance. - * \param[in] NPad - Value of the padding parameter to obtain optimal - performance in the gemm computations. - * \param[in] nInt - Number of integration points on the face. - * \param[in] Wall_HeatFlux - The value of the prescribed heat flux. - * \param[in] HeatFlux_Prescribed - Whether or not the heat flux is prescribed by - the boundary conditions. - * \param[in] Wall_Temperature - The value of the prescribed wall temperature. - * \param[in] Temperature_Prescribed - Whether or not the temperature is precribed - by the boundary conditions - * \param[in] surfElem - Surface boundary elements for which the - viscous fluxes must be computed. - * \param[in] solIntL - Left states in the integration points of the face. - * \param[out] workArray - Storage array - * \param[out] viscFluxes - To be computed viscous fluxes in the - integration points. - * \param[out] viscosityInt - To be computed viscosity in the integration points. - * \param[out] kOverCvInt - To be computed thermal conductivity in the - integration points. - * \param[in,out] wallModel - Pointer to the wall model treatment. - */ - void WallTreatmentViscousFluxes(CConfig *config, - const unsigned short nFaceSimul, - const unsigned short NPad, - const unsigned short nInt, - const su2double Wall_HeatFlux, - const bool HeatFlux_Prescribed, - const su2double Wall_Temperature, - const bool Temperature_Prescribed, - const CSurfaceElementFEM *surfElem, - const su2double *solIntL, - su2double *workArray, - su2double *viscFluxes, - su2double *viscosityInt, - su2double *kOverCvInt, - CWallModel *wallModel); - - /*! - * \brief Function, which computes the residual contribution from a boundary - face in a viscous computation when the boundary conditions have - already been applied. - * \param[in] config - Definition of the particular problem. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] nFaceSimul - Number of fused faces, i.e. the number of faces - that are treated simultaneously to improve performance. - * \param[in] NPad - Value of the padding parameter to obtain optimal - performance in the gemm computations. - * \param[in] surfElem - Surface boundary elements for which the - contribution to the residual must be computed. - * \param[in] solInt0 - Solution in the integration points of side 0. - * \param[in] solInt1 - Solution in the integration points of side 1. - * \param[out] paramFluxes - Array used for temporary storage. - * \param[out] fluxes - Temporary storage for the fluxes in the - integration points. - * \param[in,out] viscFluxes - On input this array contains the viscous fluxes - in the integration points. It is also used for - temporary storage. - * \param[in] viscosityInt - Temporary storage for the viscosity in the - integration points. - * \param[in] kOverCvInt - Temporary storage for the thermal conductivity - over Cv in the integration points. - * \param[out] resFaces - Array to store the residuals of the face. - * \param[in,out] indResFaces - Index in resFaces, where the current residual - should be stored. It is updated in the function - for the next boundary element. - */ - void ResidualViscousBoundaryFace(CConfig *config, - CNumerics *conv_numerics, - const unsigned short nFaceSimul, - const unsigned short NPad, - const CSurfaceElementFEM *surfElem, - const su2double *solInt0, - const su2double *solInt1, - su2double *paramFluxes, - su2double *fluxes, - su2double *viscFluxes, - const su2double *viscosityInt, - const su2double *kOverCvInt, - su2double *resFaces, - unsigned long &indResFaces); - - /*! - * \brief Function to compute the symmetrizing terms in the integration - points of a face. - * \param[in] indFaceChunk - Index of the face in the chunk of fused faces. - * \param[in] nInt - Number of integration points of the face. - * \param[in] NPad - Value of the padding parameter to obtain optimal - performance in the gemm computations. - * \param[in] solInt0 - Solution in the integration points of side 0. - * \param[in] solInt1 - Solution in the integration points of side 1. - * \param[in] viscosityInt0 - Viscosity in the integration points of side 0. - * \param[in] viscosityInt1 - Viscosity in the integration points of side 1. - * \param[in] kOverCvInt0 - Heat conductivity divided by Cv in the - integration points of side 0. - * \param[in] kOverCvInt1 - Heat conductivity divided by Cv in the - integration points of side 1. - * \param[in] metricNormalsFace - Metric terms in the integration points, which - contain the normals. - * \param[out] symmFluxes - Symmetrizing fluxes in the integration points. - */ - void SymmetrizingFluxesFace(const unsigned short indFaceChunk, - const unsigned short nInt, - const unsigned short NPad, - const su2double *solInt0, - const su2double *solInt1, - const su2double *viscosityInt0, - const su2double *viscosityInt1, - const su2double *kOverCvInt0, - const su2double *kOverCvInt1, - const su2double *metricNormalsFace, - su2double *symmFluxes); - - /*! - * \brief Function, which transforms the symmetrizing fluxes in the integration points - such that they are suited to be multiplied by the parametric gradients of - the basis functions. - * \param[in] indFaceChunk - Index of the face in the chunk of fused faces. - * \param[in] nInt - Number of integration points of the face. - * \param[in] NPad - Value of the padding parameter to obtain optimal - performance in the gemm computations. - * \param[in] halfTheta - Half times the theta parameter in the symmetrizing terms. - * \param[in] symmFluxes - Symmetrizing fluxes to be multiplied by the Cartesian - gradients of the basis functions. - * \param[in] weights - Integration weights of the integration points. - * \param[in] metricCoorFace - Derivatives of the parametric coordinates w.r.t. the - Cartesian coordinates in the integration points of - the face. - * \param[out] paramFluxes - Parametric fluxes in the integration points. - */ - void TransformSymmetrizingFluxes(const unsigned short indFaceChunk, - const unsigned short nInt, - const unsigned short NPad, - const su2double halfTheta, - const su2double *symmFluxes, - const su2double *weights, - const su2double *metricCoorFace, - su2double *paramFluxes); - - /*! - * \brief Function to compute the viscous normal fluxes in the integration points of a face. - * \param[in] adjVolElem - Pointer to the adjacent volume. - * \param[in] indFaceChunk - Index of the face in the chunk of fused faces. - * \param[in] nInt - Number of integration points of the face. - * \param[in] NPad - Value of the padding parameter to obtain optimal - performance in the gemm computations. - * \param[in] Wall_HeatFlux - The value of the prescribed heat flux. - * \param[in] HeatFlux_Prescribed - Whether or not the heat flux is prescribed by - e.g. the boundary conditions. - * \param[in] solInt - Solution in the integration points. - * \param[in] gradSolInt - Gradient of the solution in the integration points. - * \param[in] metricCoorDerivFace - Metric terms in the integration points, which - contain the derivatives of the parametric - coordinates w.r.t. the Cartesian coordinates. - Needed to compute the Cartesian gradients. - * \param[in] metricNormalsFace - Metric terms in the integration points, which - contain the normals. - * \param[in] wallDistanceInt - Wall distances in the integration points of the face. - * \param[out] viscNormFluxes - Viscous normal fluxes in the integration points. - * \param[out] viscosityInt - Viscosity in the integration points, which is - needed for other terms in the discretization. - * \param[out] kOverCvInt - Thermal conductivity over Cv in the integration points, - which is needed for other terms in the discretization. - */ - void ViscousNormalFluxFace(const CVolumeElementFEM *adjVolElem, - const unsigned short indFaceChunk, - const unsigned short nInt, - const unsigned short NPad, - const su2double Wall_HeatFlux, - const bool HeatFlux_Prescribed, - const su2double *solInt, - const su2double *gradSolInt, - const su2double *metricCoorDerivFace, - const su2double *metricNormalsFace, - const su2double *wallDistanceInt, - su2double *viscNormFluxes, - su2double *viscosityInt, - su2double *kOverCvInt); - - /*! - * \brief Function to compute the viscous normal flux in one integration point for a - 2D simulation. - * \param[in] sol - Conservative variables. - * \param[in] solGradCart - Cartesian gradients of the conservative variables. - * \param[in] normal - Normal vector - * \param[in] HeatFlux - Value of the prescribed heat flux. If not - prescribed, this value should be zero. - * \param[in] factHeatFlux - Multiplication factor for the heat flux. It is zero - when the heat flux is prescribed and one when it has - to be computed. - * \param[in] wallDist - Distance to the nearest viscous wall, if appropriate. - * \param[in lenScale_LES - LES length scale, if appropriate. - * \param[out] Viscosity - Total viscosity, to be computed. - * \param[out] kOverCv - Total thermal conductivity over Cv, to be computed. - * \param[out] normalFlux - Viscous normal flux, to be computed. - */ - void ViscousNormalFluxIntegrationPoint_2D(const su2double *sol, - const su2double solGradCart[4][2], - const su2double *normal, - const su2double HeatFlux, - const su2double factHeatFlux, - const su2double wallDist, - const su2double lenScale_LES, - su2double &Viscosity, - su2double &kOverCv, - su2double *normalFlux); - - /*! - * \brief Function to compute the viscous normal flux in one integration point for a - 3D simulation. - * \param[in] sol - Conservative variables. - * \param[in] solGradCart - Cartesian gradients of the conservative variables. - * \param[in] normal - Normal vector - * \param[in] HeatFlux - Value of the prescribed heat flux. If not - prescribed, this value should be zero. - * \param[in] factHeatFlux - Multiplication factor for the heat flux. It is zero - when the heat flux is prescribed and one when it has - to be computed. - * \param[in] wallDist - Distance to the nearest viscous wall, if appropriate. - * \param[in lenScale_LES - LES length scale, if appropriate. - * \param[out] Viscosity - Total viscosity, to be computed. - * \param[out] kOverCv - Total thermal conductivity over Cv, to be computed. - * \param[out] normalFlux - Viscous normal flux, to be computed. - */ - void ViscousNormalFluxIntegrationPoint_3D(const su2double *sol, - const su2double solGradCart[5][3], - const su2double *normal, - const su2double HeatFlux, - const su2double factHeatFlux, - const su2double wallDist, - const su2double lenScale_LES, - su2double &Viscosity, - su2double &kOverCv, - su2double *normalFlux); -}; - -#include "solver_structure.inl" diff --git a/SU2_CFD/include/solver_structure.inl b/SU2_CFD/include/solver_structure.inl deleted file mode 100644 index ff4b1583a60b..000000000000 --- a/SU2_CFD/include/solver_structure.inl +++ /dev/null @@ -1,2454 +0,0 @@ -/*! - * \file solver_structure.inl - * \brief In-Line subroutines of the solver_structure.hpp file. - * \author F. Palacios, T. Economon - * \version 7.0.0 "Blackbird" - * - * SU2 Project Website: https://su2code.github.io - * - * The SU2 Project is maintained by the SU2 Foundation - * (http://su2foundation.org) - * - * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) - * - * SU2 is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * SU2 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with SU2. If not, see . - */ - -#pragma once - -inline void CSolver::SetIterLinSolver(unsigned short val_iterlinsolver) { IterLinSolver = val_iterlinsolver; } - -inline void CSolver::SetResLinSolver(su2double val_reslinsolver) { ResLinSolver = val_reslinsolver; } - -inline void CSolver::SetNondimensionalization(CConfig *config, unsigned short iMesh) { } - -inline bool CSolver::GetAdjoint(void) { return adjoint; } - -inline unsigned short CSolver::GetIterLinSolver(void) { return IterLinSolver; } - -inline su2double CSolver::GetCSensitivity(unsigned short val_marker, unsigned long val_vertex) { return 0; } - -inline void CSolver::SetResidual_DualTime(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iRKStep, - unsigned short iMesh, unsigned short RunTime_EqSystem) { } - -inline void CSolver::SetInitialCondition(CGeometry **geometry, CSolver ***solver_container, CConfig *config, unsigned long TimeIter) { } - -inline void CSolver::ResetInitialCondition(CGeometry **geometry, CSolver ***solver_container, CConfig *config, unsigned long TimeIter) { } - -inline void CSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo) { } - -inline void CSolver::LoadRestart_FSI(CGeometry *geometry, CConfig *config, int val_iter) { } - -inline void CSolver::PredictStruct_Displacement(CGeometry **fea_geometry, CConfig *fea_config, CSolver ***fea_solution) { } - -inline void CSolver::ComputeAitken_Coefficient(CGeometry **fea_geometry, CConfig *fea_config, CSolver ***fea_solution, unsigned long iOuterIter) { } - -inline void CSolver::SetAitken_Relaxation(CGeometry **fea_geometry, CConfig *fea_config, CSolver ***fea_solution) { } - -inline void CSolver::Update_StructSolution(CGeometry **fea_geometry, CConfig *fea_config, CSolver ***fea_solution) { } - -inline void CSolver::Compute_OFRefGeom(CGeometry *geometry, CSolver **solver_container, CConfig *config) { } - -inline void CSolver::Compute_OFRefNode(CGeometry *geometry, CSolver **solver_container, CConfig *config) { } - -inline void CSolver::Compute_OFVolFrac(CGeometry *geometry, CSolver **solver_container, CConfig *config) { } - -inline void CSolver::Compute_OFCompliance(CGeometry *geometry, CSolver **solver_container, CConfig *config) { } - -inline void CSolver::SetForceCoeff(su2double val_forcecoeff_history) { } - -inline void CSolver::SetFSI_Residual(su2double val_FSI_residual) { } - -inline void CSolver::SetRelaxCoeff(su2double val_relaxecoeff_history) { } - -inline su2double CSolver::GetRelaxCoeff(void) const { return 0.0; } - -inline su2double CSolver::GetForceCoeff(void) const { return 0.0; } - -inline su2double CSolver::GetFSI_Residual(void) const { return 0.0; } - -inline void CSolver::Stiffness_Penalty(CGeometry *geometry, CSolver **solver_container, CNumerics **numerics_container, CConfig *config) { } - -inline void CSolver::SetCSensitivity(unsigned short val_marker, unsigned long val_vertex, su2double val_sensitivity) { } - -inline void CSolver::Inviscid_Sensitivity(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config) { } - -inline void CSolver::Smooth_Sensitivity(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config) { } - -inline void CSolver::Viscous_Sensitivity(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config) { } - -inline su2double CSolver::GetPhi_Inf(unsigned short val_dim) { return 0; } - -inline su2double CSolver::GetPsiRho_Inf(void) { return 0; } - -inline su2double* CSolver::GetPsiRhos_Inf(void) { return NULL; } - -inline su2double CSolver::GetPsiE_Inf(void) { return 0; } - -inline void CSolver::SetPrimitive_Gradient_GG(CGeometry *geometry, CConfig *config, bool reconstruction) { } - -inline void CSolver::SetPrimitive_Gradient_LS(CGeometry *geometry, CConfig *config, bool reconstruction) { } - -inline void CSolver::SetPrimitive_Limiter_MPI(CGeometry *geometry, CConfig *config) { } - -inline void CSolver::SetPrimitive_Limiter(CGeometry *geometry, CConfig *config) { } - -inline void CSolver::SetPreconditioner(CConfig *config, unsigned long iPoint) { } - -inline void CSolver::SetDistance(CGeometry *geometry, CConfig *config) { }; - -inline su2double CSolver::GetCD_Inv(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetCL_Inv(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CL(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CD(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CSF(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CEff(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CFx(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CFy(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CFz(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CMx(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CMy(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CMz(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CL_Inv(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CD_Inv(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CSF_Inv(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CEff_Inv(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CFx_Inv(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CFy_Inv(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CFz_Inv(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CMx_Inv(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CMy_Inv(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CMz_Inv(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CL_Visc(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CD_Visc(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CSF_Visc(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CEff_Visc(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CFx_Visc(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CFy_Visc(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CFz_Visc(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CMx_Visc(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CMy_Visc(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CMz_Visc(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_Buffet_Metric(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CL_Mnt(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CD_Mnt(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CSF_Mnt(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CEff_Mnt(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CFx_Mnt(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CFy_Mnt(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CFz_Mnt(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CMx_Mnt(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CMy_Mnt(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_CMz_Mnt(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetInflow_MassFlow(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetExhaust_MassFlow(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetInflow_Pressure(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetInflow_Mach(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetCSF_Inv(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetCEff_Inv(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_HF_Visc(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetSurface_MaxHF_Visc(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetCL_Visc(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetCSF_Visc(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetCD_Visc(unsigned short val_marker) { return 0; } - -inline su2double CSolver::GetAllBound_CL_Inv() { return 0; } - -inline su2double CSolver::GetAllBound_CD_Inv() { return 0; } - -inline su2double CSolver::GetAllBound_CSF_Inv() { return 0; } - -inline su2double CSolver::GetAllBound_CEff_Inv() { return 0; } - -inline su2double CSolver::GetAllBound_CMx_Inv() { return 0; } - -inline su2double CSolver::GetAllBound_CMy_Inv() { return 0; } - -inline su2double CSolver::GetAllBound_CMz_Inv() { return 0; } - -inline su2double CSolver::GetAllBound_CoPx_Inv() { return 0; } - -inline su2double CSolver::GetAllBound_CoPy_Inv() { return 0; } - -inline su2double CSolver::GetAllBound_CoPz_Inv() { return 0; } - -inline su2double CSolver::GetAllBound_CFx_Inv() { return 0; } - -inline su2double CSolver::GetAllBound_CFy_Inv() { return 0; } - -inline su2double CSolver::GetAllBound_CFz_Inv() { return 0; } - -inline su2double CSolver::GetAllBound_CL_Mnt() { return 0; } - -inline su2double CSolver::GetAllBound_CD_Mnt() { return 0; } - -inline su2double CSolver::GetAllBound_CSF_Mnt() { return 0; } - -inline su2double CSolver::GetAllBound_CEff_Mnt() { return 0; } - -inline su2double CSolver::GetAllBound_CMx_Mnt() { return 0; } - -inline su2double CSolver::GetAllBound_CMy_Mnt() { return 0; } - -inline su2double CSolver::GetAllBound_CMz_Mnt() { return 0; } - -inline su2double CSolver::GetAllBound_CoPx_Mnt() { return 0; } - -inline su2double CSolver::GetAllBound_CoPy_Mnt() { return 0; } - -inline su2double CSolver::GetAllBound_CoPz_Mnt() { return 0; } - -inline su2double CSolver::GetAllBound_CFx_Mnt() { return 0; } - -inline su2double CSolver::GetAllBound_CFy_Mnt() { return 0; } - -inline su2double CSolver::GetAllBound_CFz_Mnt() { return 0; } - -inline su2double CSolver::GetAllBound_CL_Visc() { return 0; } - -inline su2double CSolver::GetAllBound_CD_Visc() { return 0; } - -inline su2double CSolver::GetAllBound_CSF_Visc() { return 0; } - -inline su2double CSolver::GetAllBound_CEff_Visc() { return 0; } - -inline su2double CSolver::GetAllBound_CMx_Visc() { return 0; } - -inline su2double CSolver::GetAllBound_CMy_Visc() { return 0; } - -inline su2double CSolver::GetAllBound_CMz_Visc() { return 0; } - -inline su2double CSolver::GetTotal_Buffet_Metric() { return 0; } - -inline su2double CSolver::GetAllBound_CoPx_Visc() { return 0; } - -inline su2double CSolver::GetAllBound_CoPy_Visc() { return 0; } - -inline su2double CSolver::GetAllBound_CoPz_Visc() { return 0; } - -inline su2double CSolver::GetAllBound_CFx_Visc() { return 0; } - -inline su2double CSolver::GetAllBound_CFy_Visc() { return 0; } - -inline su2double CSolver::GetAllBound_CFz_Visc() { return 0; } - -inline void CSolver::SetForceProj_Vector(CGeometry *geometry, CSolver **solver_container, CConfig *config) { } - -inline void CSolver::SetIntBoundary_Jump(CGeometry *geometry, CSolver **solver_container, CConfig *config) { } - -inline su2double CSolver::GetTotal_CL() { return 0; } - -inline su2double CSolver::GetTotal_CD() { return 0; } - -inline su2double CSolver::GetTotal_NetThrust() { return 0; } - -inline su2double CSolver::GetTotal_Power() { return 0; } - -inline su2double CSolver::GetTotal_SolidCD() { return 0; } - -inline su2double CSolver::GetTotal_ReverseFlow() { return 0; } - -inline su2double CSolver::GetTotal_MFR() { return 0; } - -inline su2double CSolver::GetTotal_Prop_Eff() { return 0; } - -inline su2double CSolver::GetTotal_ByPassProp_Eff() { return 0; } - -inline su2double CSolver::GetTotal_Adiab_Eff() { return 0; } - -inline su2double CSolver::GetTotal_Poly_Eff() { return 0; } - -inline su2double CSolver::GetTotal_IDC_Mach() { return 0; } - -inline su2double CSolver::GetTotal_DC60() { return 0; } - -inline su2double CSolver::GetTotal_Custom_ObjFunc() { return 0; } - -inline su2double CSolver::GetTotal_CMx() { return 0; } - -inline su2double CSolver::GetTotal_CMy() { return 0; } - -inline su2double CSolver::GetTotal_CMz() { return 0; } - -inline su2double CSolver::GetTotal_CoPx() { return 0; } - -inline su2double CSolver::GetTotal_CoPy() { return 0; } - -inline su2double CSolver::GetTotal_CoPz() { return 0; } - -inline su2double CSolver::GetTotal_CFx() { return 0; } - -inline su2double CSolver::GetTotal_CFy() { return 0; } - -inline su2double CSolver::GetTotal_CFz() { return 0; } - -inline su2double CSolver::GetTotal_CSF() { return 0; } - -inline su2double CSolver::GetTotal_CEff() { return 0; } - -inline su2double CSolver::GetTotal_CT() { return 0; } - -inline void CSolver::SetTotal_CT(su2double val_Total_CT) { } - -inline su2double CSolver::GetTotal_CQ() { return 0; } - -inline su2double CSolver::GetTotal_HeatFlux() { return 0; } - -inline su2double CSolver::GetTotal_AvgTemperature() { return 0; } - -inline su2double CSolver::GetTotal_MaxHeatFlux() { return 0; } - -inline su2double CSolver::Get_PressureDrag() { return 0; } - -inline su2double CSolver::Get_ViscDrag() { return 0; } - -inline void CSolver::SetTotal_CQ(su2double val_Total_CQ) { } - -inline void CSolver::SetTotal_HeatFlux(su2double val_Total_Heat) { } - -inline void CSolver::SetTotal_MaxHeatFlux(su2double val_Total_Heat) { } - -inline su2double CSolver::GetTotal_CMerit() { return 0; } - -inline su2double CSolver::GetTotal_CEquivArea() { return 0; } - -inline su2double CSolver::GetTotal_AeroCD() { return 0; } - -inline su2double CSolver::GetTotal_IDR() { return 0; } - -inline su2double CSolver::GetTotal_IDC() { return 0; } - -inline su2double CSolver::GetTotal_CpDiff() { return 0; } - -inline su2double CSolver::GetTotal_HeatFluxDiff() { return 0; } - -inline su2double CSolver::GetTotal_CFEA() const { return 0; } - -inline su2double CSolver::GetTotal_CNearFieldOF() { return 0; } - -inline su2double CSolver::GetTotal_OFRefGeom() const { return 0; } - -inline su2double CSolver::GetTotal_OFRefNode() const { return 0; } - -inline su2double CSolver::GetTotal_OFVolFrac() const { return 0; } - -inline su2double CSolver::GetTotal_OFCompliance() const { return 0; } - -inline bool CSolver::IsElementBased(void) const { return false; } - -inline void CSolver::AddTotal_ComboObj(su2double val_obj) {} - -inline void CSolver::SetTotal_CEquivArea(su2double val_cequivarea) { } - -inline void CSolver::SetTotal_AeroCD(su2double val_aerocd) { } - -inline void CSolver::SetTotal_CpDiff(su2double val_pressure) { } - -inline void CSolver::SetTotal_HeatFluxDiff(su2double val_heat) { } - -inline void CSolver::SetTotal_CFEA(su2double val_cfea) { } - -inline void CSolver::SetTotal_OFRefGeom(su2double val_ofrefgeom) { } - -inline void CSolver::SetTotal_OFRefNode(su2double val_ofrefnode) { } - -inline su2double CSolver::GetWAitken_Dyn(void) const { return 0; } - -inline su2double CSolver::GetWAitken_Dyn_tn1(void) const { return 0; } - -inline void CSolver::SetWAitken_Dyn(su2double waitk) { } - -inline void CSolver::SetWAitken_Dyn_tn1(su2double waitk_tn1) { } - -inline void CSolver::SetLoad_Increment(su2double val_loadIncrement) { } - -inline su2double CSolver::GetLoad_Increment() const { return 0; } - -inline void CSolver::SetTotal_CNearFieldOF(su2double val_cnearfieldpress) { } - -inline su2double CSolver::GetTotal_CWave() { return 0; } - -inline su2double CSolver::GetTotal_CHeat() { return 0; } - -inline void CSolver::SetTotal_CL(su2double val_Total_CL) { } - -inline void CSolver::SetTotal_CD(su2double val_Total_CD) { } - -inline void CSolver::SetTotal_NetThrust(su2double val_Total_NetThrust) { } - -inline void CSolver::SetTotal_Power(su2double val_Total_Power) { } - -inline void CSolver::SetTotal_SolidCD(su2double val_Total_SolidCD) { } - -inline void CSolver::SetTotal_ReverseFlow(su2double val_Total_ReverseFlow) { } - -inline void CSolver::SetTotal_MFR(su2double val_Total_MFR) { } - -inline void CSolver::SetTotal_Prop_Eff(su2double val_Total_Prop_Eff) { } - -inline void CSolver::SetTotal_ByPassProp_Eff(su2double val_Total_ByPassProp_Eff) { } - -inline void CSolver::SetTotal_Adiab_Eff(su2double val_Total_Adiab_Eff) { } - -inline void CSolver::SetTotal_Poly_Eff(su2double val_Total_Poly_Eff) { } - -inline void CSolver::SetTotal_IDC(su2double val_Total_IDC) { } - -inline void CSolver::SetTotal_IDC_Mach(su2double val_Total_IDC_Mach) { } - -inline void CSolver::SetTotal_IDR(su2double val_Total_IDR) { } - -inline void CSolver::SetTotal_DC60(su2double val_Total_DC60) { } - -inline void CSolver::SetTotal_Custom_ObjFunc(su2double val_total_custom_objfunc, su2double val_weight) { } - -inline void CSolver::AddTotal_Custom_ObjFunc(su2double val_total_custom_objfunc, su2double val_weight) { } - -inline su2double CSolver::GetCPressure(unsigned short val_marker, unsigned long val_vertex) { return 0; } - -inline su2double CSolver::GetCPressureTarget(unsigned short val_marker, unsigned long val_vertex) { return 0; } - -inline void CSolver::SetCPressureTarget(unsigned short val_marker, unsigned long val_vertex, su2double val_pressure) { } - -inline void CSolver::SetHeatFluxTarget(unsigned short val_marker, unsigned long val_vertex, su2double val_heat) { } - -inline su2double *CSolver::GetCharacPrimVar(unsigned short val_marker, unsigned long val_vertex) { return 0; } - -inline void CSolver::SetCharacPrimVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_var, su2double val_value) { } - -inline su2double *CSolver::GetDonorPrimVar(unsigned short val_marker, unsigned long val_vertex) { return 0; } - -inline void CSolver::SetDonorPrimVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_var, su2double val_value) { } - -inline void CSolver::SetDonorAdjVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_var, su2double val_value) { } - -inline su2double CSolver::GetDonorPrimVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_var) { return 0; } - -inline su2double *CSolver::GetDonorAdjVar(unsigned short val_marker, unsigned long val_vertex) { return 0; } - -inline su2double CSolver::GetDonorAdjVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_var) { return 0; } - -inline unsigned long CSolver::GetDonorGlobalIndex(unsigned short val_marker, unsigned long val_vertex) { return 0; } - -inline void CSolver::SetDonorGlobalIndex(unsigned short val_marker, unsigned long val_vertex, unsigned long val_index) { } - -inline su2double CSolver::GetActDisk_DeltaP(unsigned short val_marker, unsigned long val_vertex) { return 0; } - -inline void CSolver::SetActDisk_DeltaP(unsigned short val_marker, unsigned long val_vertex, su2double val_deltap) { } - -inline su2double CSolver::GetActDisk_DeltaT(unsigned short val_marker, unsigned long val_vertex) { return 0; } - -inline void CSolver::SetActDisk_DeltaT(unsigned short val_marker, unsigned long val_vertex, su2double val_deltat) { } - -inline su2double CSolver::GetInlet_Ttotal(unsigned short val_marker, unsigned long val_vertex) { return 0; } - -inline su2double CSolver::GetInlet_Ptotal(unsigned short val_marker, unsigned long val_vertex) { return 0; } - -inline su2double CSolver::GetInlet_FlowDir(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim) { return 0; } - -inline void CSolver::SetInlet_Ttotal(unsigned short val_marker, unsigned long val_vertex, su2double val_ttotal) { } - -inline void CSolver::SetInlet_Ptotal(unsigned short val_marker, unsigned long val_vertex, su2double val_ptotal) { } - -inline void CSolver::SetInlet_FlowDir(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim, su2double val_flowdir) { } - -inline void CSolver::SetInlet_TurbVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim, su2double val_turb_var) { } - -inline void CSolver::SetUniformInlet(CConfig* config, unsigned short iMarker) {}; - -inline void CSolver::SetInletAtVertex(su2double *val_inlet, unsigned short iMarker, unsigned long iVertex) { }; - -inline su2double CSolver::GetInletAtVertex(su2double *val_inlet, unsigned long val_inlet_point, unsigned short val_kind_marker, string val_marker, CGeometry *geometry, CConfig *config) { return 0; } - -inline void CSolver::UpdateCustomBoundaryConditions(CGeometry **geometry_container, CConfig *config) { } - -inline su2double CSolver::GetCSkinFriction(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim) { return 0; } - -inline su2double CSolver::GetHeatFlux(unsigned short val_marker, unsigned long val_vertex) { return 0; } - -inline su2double CSolver::GetHeatFluxTarget(unsigned short val_marker, unsigned long val_vertex) { return 0; } - -inline su2double CSolver::GetBuffetSensor(unsigned short val_marker, unsigned long val_vertex) { return 0; } - -inline su2double CSolver::GetYPlus(unsigned short val_marker, unsigned long val_vertex) { return 0; } - -inline su2double CSolver::GetStrainMag_Max(void) { return 0; } - -inline su2double CSolver::GetOmega_Max(void) { return 0; } - -inline void CSolver::SetStrainMag_Max(su2double val_strainmag_max) { } - -inline void CSolver::SetOmega_Max(su2double val_omega_max) { } - -inline void CSolver::Viscous_Residual(CGeometry *geometry, - CSolver **solver_container, - CNumerics *numerics, CConfig - *config, unsigned short iMesh, - unsigned short iRKstep) { } - -inline void CSolver::AddStiffMatrix(su2double ** StiffMatrix_Elem, unsigned long Point_0, unsigned long Point_1, unsigned long Point_2, unsigned long Point_3) { } - -inline void CSolver::Source_Residual(CGeometry *geometry, CSolver **solver_container, - CNumerics *numerics, CNumerics *second_numerics, CConfig *config, unsigned short iMesh) { } - -inline void CSolver::Source_Template(CGeometry *geometry, CSolver **solver_container, - CNumerics *numerics, CConfig *config, unsigned short iMesh) { } - -inline su2double CSolver::GetTotal_Sens_Geo() { return 0; } - -inline su2double CSolver::GetTotal_Sens_Mach() { return 0; } - -inline su2double CSolver::GetTotal_Sens_AoA() { return 0; } - -inline su2double CSolver::GetTotal_Sens_Press() { return 0; } - -inline su2double CSolver::GetTotal_Sens_Temp() { return 0; } - -inline su2double CSolver::GetTotal_Sens_BPress() { return 0; } - -inline su2double CSolver::GetTotal_Sens_Density() { return 0; } - -inline su2double CSolver::GetTotal_Sens_ModVel() { return 0; } - -inline su2double CSolver::GetDensity_Inf(void) { return 0; } - -inline su2double CSolver::GetDensity_Inf(unsigned short val_var) { return 0; } - -inline su2double CSolver::GetModVelocity_Inf(void) { return 0; } - -inline su2double CSolver::GetDensity_Energy_Inf(void) { return 0; } - -inline su2double CSolver::GetDensity_Velocity_Inf(unsigned short val_dim) { return 0; } - -inline su2double CSolver::GetDensity_Velocity_Inf(unsigned short val_dim, unsigned short val_var) { return 0; } - -inline su2double CSolver::GetVelocity_Inf(unsigned short val_dim) { return 0; } - -inline su2double* CSolver::GetVelocity_Inf(void) { return 0; } - -inline su2double CSolver::GetPressure_Inf(void) { return 0; } - -inline su2double CSolver::GetViscosity_Inf(void) { return 0; } - -inline su2double CSolver::GetNuTilde_Inf(void) { return 0; } - -inline su2double CSolver::GetTke_Inf(void) { return 0; } - -inline su2double CSolver::GetOmega_Inf(void) { return 0; } - -inline su2double CSolver::GetTotal_Sens_E(unsigned short iVal) { return 0.0; } - -inline su2double CSolver::GetTotal_Sens_Nu(unsigned short iVal) { return 0.0; } - -inline su2double CSolver::GetTotal_Sens_Rho(unsigned short iVal) { return 0.0; } - -inline su2double CSolver::GetTotal_Sens_Rho_DL(unsigned short iVal) { return 0.0; } - -inline su2double CSolver::GetTotal_Sens_EField(unsigned short iEField) { return 0.0; } - -inline su2double CSolver::GetTotal_Sens_DVFEA(unsigned short iDVFEA) { return 0.0; } - -inline su2double CSolver::GetGlobal_Sens_E(unsigned short iVal) { return 0.0; } - -inline su2double CSolver::GetGlobal_Sens_Nu(unsigned short iVal) { return 0.0; } - -inline su2double CSolver::GetGlobal_Sens_Rho(unsigned short iVal) { return 0.0; } - -inline su2double CSolver::GetGlobal_Sens_Rho_DL(unsigned short iVal) { return 0.0; } - -inline su2double CSolver::GetGlobal_Sens_EField(unsigned short iEField) { return 0.0; } - -inline su2double CSolver::GetGlobal_Sens_DVFEA(unsigned short iDVFEA) { return 0.0; } - -inline su2double CSolver::GetVal_Young(unsigned short iVal) { return 0.0; } - -inline su2double CSolver::GetVal_Poisson(unsigned short iVal) { return 0.0; } - -inline su2double CSolver::GetVal_Rho(unsigned short iVal) { return 0.0; } - -inline su2double CSolver::GetVal_Rho_DL(unsigned short iVal) { return 0.0; } - -inline unsigned short CSolver::GetnEField(void) { return 0; } - -inline unsigned short CSolver::GetnDVFEA(void) { return 0; } - -inline void CSolver::ReadDV(CConfig *config) { } - -inline su2double CSolver::GetVal_EField(unsigned short iVal) { return 0.0; } - -inline su2double CSolver::GetVal_DVFEA(unsigned short iVal) { return 0.0; } - -inline su2double* CSolver::GetConstants() { return NULL;} - -inline void CSolver::SetTotal_ComboObj(su2double ComboObj) {} - -inline su2double CSolver::GetTotal_ComboObj(void) { return 0;} - -inline void CSolver::Set_Heatflux_Areas(CGeometry *geometry, CConfig *config) { } - -inline void CSolver::Evaluate_ObjFunc(CConfig *config) {}; - -inline void CSolver::Solve_System(CGeometry *geometry, CConfig *config) { } - -inline void CSolver::BC_Euler_Wall(CGeometry *geometry, - CSolver **solver_container, - CNumerics *conv_numerics, - CNumerics *visc_numerics, - CConfig *config, - unsigned short val_marker) { } - -inline void CSolver::BC_Clamped(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_DispDir(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Clamped_Post(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Normal_Displacement(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Normal_Load(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Dir_Load(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Sine_Load(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Damper(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Deforming(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Dirichlet(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short val_marker) { } - -inline void CSolver::BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config) { } - -inline void CSolver::BC_Interface_Boundary(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_NearField_Boundary(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Periodic(CGeometry *geometry, CSolver **solver_container, - CNumerics *numerics, CConfig *config) { } - -inline void CSolver::BC_ActDisk_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_ActDisk_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_ActDisk(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker, bool val_inlet_surface) { } - -inline void CSolver::BC_Far_Field(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Sym_Plane(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Custom(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Riemann(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_TurboRiemann(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker) { } - -inline void CSolver::PreprocessBC_Giles(CGeometry *geometry, CConfig *config, - CNumerics *conv_numerics,unsigned short marker_flag){} - -inline void CSolver::BC_Giles(CGeometry *geometry, CSolver **solver_container, - CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Inlet_Turbo(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Inlet_MixingPlane(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Supersonic_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Supersonic_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Engine_Inflow(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Engine_Exhaust(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, - CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Neumann(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Dielec(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_Electrode(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short val_marker) { } - -inline void CSolver::BC_ConjugateHeat_Interface(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short val_marker) { } - -inline void CSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, unsigned short iMesh, bool Output) { } - -inline void CSolver::GetOutlet_Properties(CGeometry *geometry, CConfig *config, unsigned short iMesh, bool Output) { } - -inline void CSolver::GetEllipticSpanLoad_Diff(CGeometry *geometry, CConfig *config) { } - -inline void CSolver::SetFarfield_AoA(CGeometry *geometry, CSolver **solver_container, - CConfig *config, unsigned short iMesh, bool Output) { } - -inline bool CSolver::FixedCL_Convergence(CConfig *config, bool convergence) { return false; } - -inline bool CSolver::GetStart_AoA_FD(void) { return false; } - -inline bool CSolver::GetEnd_AoA_FD(void) { return false; } - -inline unsigned long CSolver::GetIter_Update_AoA(void) { return 0; } - -inline su2double CSolver::GetPrevious_AoA(void) { return 0.0; } - -inline su2double CSolver::GetAoA_inc(void) { return 0.0; } - -inline void CSolver::SetActDisk_BCThrust(CGeometry *geometry, CSolver **solver_container, - CConfig *config, unsigned short iMesh, bool Output) { } - -inline void CSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh, unsigned long Iteration) { } - -inline void CSolver::CheckTimeSynchronization(CConfig *config, - const su2double TimeSync, - su2double &timeEvolved, - bool &syncTimeReached) {} - -inline void CSolver::ProcessTaskList_DG(CGeometry *geometry, CSolver **solver_container, - CNumerics **numerics, CConfig *config, - unsigned short iMesh) {} - -inline void CSolver::ADER_SpaceTimeIntegration(CGeometry *geometry, CSolver **solver_container, - CNumerics **numerics, CConfig *config, - unsigned short iMesh, unsigned short RunTime_EqSystem) {} - -inline void CSolver::ComputeSpatialJacobian(CGeometry *geometry, CSolver **solver_container, - CNumerics **numerics, CConfig *config, - unsigned short iMesh, unsigned short RunTime_EqSystem) {} - -inline void CSolver::Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh) { } - -inline void CSolver::Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, CNumerics **numerics, - unsigned short iMesh) { } - -inline void CSolver::Centered_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh, unsigned short iRKStep) { } - -inline void CSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh) { } - -inline void CSolver::Convective_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh, unsigned short iRKStep) { } - -inline void CSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output) { } - -inline void CSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, CNumerics **numerics, unsigned short iMesh, unsigned long Iteration, unsigned short RunTime_EqSystem, bool Output) { } - -inline void CSolver::SetCentered_Dissipation_Sensor(CGeometry *geometry, CConfig *config) { } - -inline void CSolver::SetUpwind_Ducros_Sensor(CGeometry *geometry, CConfig *config) { } - -inline void CSolver::SetUndivided_Laplacian(CGeometry *geometry, CConfig *config) { } - -inline void CSolver::Set_MPI_ActDisk(CSolver **solver_container, CGeometry *geometry, CConfig *config) { } - -inline void CSolver::Set_MPI_Nearfield(CGeometry *geometry, CConfig *config) { } - -inline void CSolver::SetMax_Eigenvalue(CGeometry *geometry, CConfig *config) { } - -inline void CSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { } - -inline void CSolver::Momentum_Forces(CGeometry *geometry, CConfig *config) { } - -inline void CSolver::Friction_Forces(CGeometry *geometry, CConfig *config) { } - -inline void CSolver::Buffet_Monitoring(CGeometry *geometry, CConfig *config) { } - -inline void CSolver::Heat_Fluxes(CGeometry *geometry, CSolver **solver_container, CConfig *config) { } - -inline void CSolver::Inviscid_DeltaForces(CGeometry *geometry, CSolver **solver_container, CConfig *config) { } - -inline void CSolver::Viscous_DeltaForces(CGeometry *geometry, CConfig *config) { } - -inline void CSolver::Wave_Strength(CGeometry *geometry, CConfig *config) { } - -inline void CSolver::ExplicitRK_Iteration(CGeometry *geometry, CSolver **solver_container, - CConfig *config, unsigned short iRKStep) { } - -inline void CSolver::ClassicalRK4_Iteration(CGeometry *geometry, CSolver **solver_container, - CConfig *config, unsigned short iRKStep) { } - -inline void CSolver::ExplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { } - -inline void CSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { } - -inline void CSolver::ComputeUnderRelaxationFactor(CSolver **solver_container, CConfig *config) { } - -inline void CSolver::ImplicitNewmark_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { } - -inline void CSolver::ImplicitNewmark_Update(CGeometry *geometry, CSolver **solver_container, CConfig *config) { } - -inline void CSolver::ImplicitNewmark_Relaxation(CGeometry *geometry, CSolver **solver_container, CConfig *config) { } - -inline void CSolver::GeneralizedAlpha_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { } - -inline void CSolver::GeneralizedAlpha_UpdateDisp(CGeometry *geometry, CSolver **solver_container, CConfig *config) { } - -inline void CSolver::GeneralizedAlpha_UpdateSolution(CGeometry *geometry, CSolver **solver_container, CConfig *config) { } - -inline void CSolver::GeneralizedAlpha_UpdateLoads(CGeometry *geometry, CSolver **solver_container, CConfig *config) { } - -inline void CSolver::Compute_Residual(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh) { } - -inline void CSolver::SetRes_RMS(unsigned short val_var, su2double val_residual) { Residual_RMS[val_var] = val_residual; } - -inline void CSolver::AddRes_RMS(unsigned short val_var, su2double val_residual) { Residual_RMS[val_var] += val_residual; } - -inline su2double CSolver::GetRes_RMS(unsigned short val_var) { return Residual_RMS[val_var]; } - -inline void CSolver::SetRes_Max(unsigned short val_var, su2double val_residual, unsigned long val_point) { Residual_Max[val_var] = val_residual; Point_Max[val_var] = val_point; } - -inline void CSolver::AddRes_Max(unsigned short val_var, su2double val_residual, unsigned long val_point, su2double* val_coord) { - if (val_residual > Residual_Max[val_var]) { - Residual_Max[val_var] = val_residual; - Point_Max[val_var] = val_point; - for (unsigned short iDim = 0; iDim < nDim; iDim++) - Point_Max_Coord[val_var][iDim] = val_coord[iDim]; - } -} - -inline void CSolver::AddRes_Max(unsigned short val_var, su2double val_residual, unsigned long val_point, const su2double* val_coord) { - if (val_residual > Residual_Max[val_var]) { - Residual_Max[val_var] = val_residual; - Point_Max[val_var] = val_point; - for (unsigned short iDim = 0; iDim < nDim; iDim++) - Point_Max_Coord[val_var][iDim] = val_coord[iDim]; - } -} - -inline su2double CSolver::GetRes_Max(unsigned short val_var) { return Residual_Max[val_var]; } - -inline void CSolver::SetRes_BGS(unsigned short val_var, su2double val_residual) { Residual_BGS[val_var] = val_residual; } - -inline void CSolver::AddRes_BGS(unsigned short val_var, su2double val_residual) { Residual_BGS[val_var] += val_residual; } - -inline su2double CSolver::GetRes_BGS(unsigned short val_var) { return Residual_BGS[val_var]; } - -inline void CSolver::SetRes_Max_BGS(unsigned short val_var, su2double val_residual, unsigned long val_point) { Residual_Max_BGS[val_var] = val_residual; Point_Max_BGS[val_var] = val_point; } - -inline void CSolver::AddRes_Max_BGS(unsigned short val_var, su2double val_residual, unsigned long val_point, su2double* val_coord) { - if (val_residual > Residual_Max_BGS[val_var]) { - Residual_Max_BGS[val_var] = val_residual; - Point_Max_BGS[val_var] = val_point; - for (unsigned short iDim = 0; iDim < nDim; iDim++) - Point_Max_Coord_BGS[val_var][iDim] = val_coord[iDim]; - } -} - -inline su2double CSolver::GetRes_Max_BGS(unsigned short val_var) { return Residual_Max_BGS[val_var]; } - -inline su2double CSolver::GetRes_FEM(unsigned short val_var) const { return 0.0; } - -inline unsigned long CSolver::GetPoint_Max(unsigned short val_var) { return Point_Max[val_var]; } - -inline su2double* CSolver::GetPoint_Max_Coord(unsigned short val_var) { return Point_Max_Coord[val_var]; } - -inline unsigned long CSolver::GetPoint_Max_BGS(unsigned short val_var) { return Point_Max_BGS[val_var]; } - -inline su2double* CSolver::GetPoint_Max_Coord_BGS(unsigned short val_var) { return Point_Max_Coord_BGS[val_var]; } - -inline void CSolver::Set_OldSolution(CGeometry *geometry) { base_nodes->Set_OldSolution(); } - -inline void CSolver::Set_NewSolution(CGeometry *geometry) { } - -inline unsigned short CSolver::GetnVar(void) { return nVar; } - -inline unsigned short CSolver::GetnOutputVariables(void) { return nOutputVariables; } - -inline unsigned short CSolver::GetnPrimVar(void) { return nPrimVar; } - -inline unsigned short CSolver::GetnPrimVarGrad(void) { return nPrimVarGrad; } - -inline unsigned short CSolver::GetnSecondaryVar(void) { return nSecondaryVar; } - -inline unsigned short CSolver::GetnSecondaryVarGrad(void) { return nSecondaryVarGrad; } - -inline su2double CSolver::GetMax_Delta_Time(void) { return Max_Delta_Time; } - -inline su2double CSolver::GetMin_Delta_Time(void) { return Min_Delta_Time; } - -inline su2double CSolver::GetMax_Delta_Time(unsigned short val_Species) { return 0.0; } - -inline su2double CSolver::GetMin_Delta_Time(unsigned short val_Species) { return 0.0; } - -inline void CSolver::Copy_Zone_Solution(CSolver ***solver1_solution, CGeometry **solver1_geometry, CConfig *solver1_config, - CSolver ***solver2_solution, CGeometry **solver2_geometry, CConfig *solver2_config) {}; - -inline CFluidModel* CSolver::GetFluidModel(void) { return NULL;} - -inline su2double* CSolver::GetVecSolDOFs(void) {return NULL;} - -inline unsigned long CSolver::GetnDOFsGlobal(void) {return 0;} - -inline su2double CSolver::Compute_LoadCoefficient(su2double CurrentTime, su2double RampTime, CConfig *config) { return 0.0; } - -inline void CSolver::Compute_StiffMatrix(CGeometry *geometry, CNumerics **numerics, CConfig *config) { } - -inline void CSolver::Compute_StiffMatrix_NodalStressRes(CGeometry *geometry, CNumerics **numerics, CConfig *config) { } - -inline void CSolver::Compute_MassMatrix(CGeometry *geometry, CNumerics **numerics, CConfig *config) { } - -inline void CSolver::Compute_MassRes(CGeometry *geometry, CNumerics **numerics, CConfig *config) { } - -inline void CSolver::Compute_NodalStressRes(CGeometry *geometry, CNumerics **numerics, CConfig *config) { } - -inline void CSolver::Compute_NodalStress(CGeometry *geometry, CNumerics **numerics, CConfig *config) { } - -inline void CSolver::Compute_DeadLoad(CGeometry *geometry, CNumerics **numerics, CConfig *config) { } - -inline void CSolver::SetFSI_ConvValue(unsigned short val_index, su2double val_criteria) { }; - -inline su2double CSolver::GetFSI_ConvValue(unsigned short val_index) const { return 0.0; } - -inline void CSolver::RegisterSolution(CGeometry *geometry_container, CConfig *config){} - -inline void CSolver::RegisterOutput(CGeometry *geometry_container, CConfig *config){} - -inline void CSolver::SetAdjoint_Output(CGeometry *geometry, CConfig *config){} - -inline void CSolver::ExtractAdjoint_Solution(CGeometry *geometry, CConfig *config){} - -inline void CSolver::RegisterObj_Func(CConfig *config){} - -inline void CSolver::SetSurface_Sensitivity(CGeometry *geometry, CConfig *config){} - -inline void CSolver::SetSensitivity(CGeometry *geometry, CSolver **solver, CConfig *config){} - -inline void CSolver::SetAdj_ObjFunc(CGeometry *geometry, CConfig *config){} - -inline unsigned long CSolver::SetPrimitive_Variables(CSolver **solver_container, CConfig *config, bool Output) {return 0;} - -inline void CSolver::SetRecording(CGeometry *geometry, CConfig *config){} - -inline void CSolver::SetPressure_Inf(su2double p_inf){} - -inline void CSolver::SetTemperature_Inf(su2double t_inf){} - -inline void CSolver::SetDensity_Inf(su2double rho_inf){} - -inline void CSolver::SetVelocity_Inf(unsigned short val_dim, su2double val_velocity) { } - -inline void CSolver::RegisterVariables(CGeometry *geometry, CConfig *config, bool reset){} - -inline void CSolver::ExtractAdjoint_Variables(CGeometry *geometry, CConfig *config){} - -inline void CSolver::SetFreeStream_Solution(CConfig *config){} - -inline su2double* CBaselineSolver_FEM::GetVecSolDOFs(void) {return VecSolDOFs.data();} - -inline void CSolver::SetTauWall_WF(CGeometry *geometry, CSolver** solver_container, CConfig* config){} - -inline void CSolver::SetNuTilde_WF(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, - CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) {} - -inline void CEulerSolver::Set_NewSolution(CGeometry *geometry) { nodes->SetSolution_New(); } - -inline void CSolver::InitTurboContainers(CGeometry *geometry, CConfig *config){} - -inline void CSolver::PreprocessAverage(CSolver **solver, CGeometry *geometry, CConfig *config, unsigned short marker_flag){} - -inline void CSolver::TurboAverageProcess(CSolver **solver, CGeometry *geometry, CConfig *config, unsigned short marker_flag){} - -inline void CSolver::GatherInOutAverageValues(CConfig *config, CGeometry *geometry){ } - -inline su2double CSolver::GetAverageDensity(unsigned short valMarker, unsigned short valSpan){return 0.0;} - -inline su2double CSolver::GetAveragePressure(unsigned short valMarker, unsigned short valSpan){return 0.0;} - -inline su2double* CSolver::GetAverageTurboVelocity(unsigned short valMarker, unsigned short valSpan){return NULL;} - -inline su2double CSolver::GetAverageNu(unsigned short valMarker, unsigned short valSpan){return 0.0;} - -inline su2double CSolver::GetAverageKine(unsigned short valMarker, unsigned short valSpan){return 0.0;} - -inline su2double CSolver::GetAverageOmega(unsigned short valMarker, unsigned short valSpan){return 0.0;} - -inline su2double CSolver::GetExtAverageNu(unsigned short valMarker, unsigned short valSpan){return 0.0;} - -inline su2double CSolver::GetExtAverageKine(unsigned short valMarker, unsigned short valSpan){return 0.0;} - -inline su2double CSolver::GetExtAverageOmega(unsigned short valMarker, unsigned short valSpan){return 0.0;} - -inline void CSolver::SetExtAverageDensity(unsigned short valMarker, unsigned short valSpan, su2double valDensity){ } - -inline void CSolver::SetExtAveragePressure(unsigned short valMarker, unsigned short valSpan, su2double valPressure){ } - -inline void CSolver::SetExtAverageTurboVelocity(unsigned short valMarker, unsigned short valSpan, unsigned short valIndex, su2double valTurboVelocity){ } - -inline void CSolver::SetExtAverageNu(unsigned short valMarker, unsigned short valSpan, su2double valNu){ } - -inline void CSolver::SetExtAverageKine(unsigned short valMarker, unsigned short valSpan, su2double valKine){ } - -inline void CSolver::SetExtAverageOmega(unsigned short valMarker, unsigned short valSpan, su2double valOmega){ } - -inline su2double CSolver::GetDensityIn(unsigned short inMarkerTP, unsigned short valSpan){return 0;} - -inline su2double CSolver::GetPressureIn(unsigned short inMarkerTP, unsigned short valSpan){return 0;} - -inline su2double* CSolver::GetTurboVelocityIn(unsigned short inMarkerTP, unsigned short valSpan){return NULL;} - -inline su2double CSolver::GetDensityOut(unsigned short inMarkerTP, unsigned short valSpan){return 0;} - -inline su2double CSolver::GetPressureOut(unsigned short inMarkerTP, unsigned short valSpan){return 0;} - -inline su2double* CSolver::GetTurboVelocityOut(unsigned short inMarkerTP, unsigned short valSpan){return NULL;} - -inline su2double CSolver::GetKineIn(unsigned short inMarkerTP, unsigned short valSpan){return 0;} - -inline su2double CSolver::GetOmegaIn(unsigned short inMarkerTP, unsigned short valSpan){return 0;} - -inline su2double CSolver::GetNuIn(unsigned short inMarkerTP, unsigned short valSpan){return 0;} - -inline su2double CSolver::GetKineOut(unsigned short inMarkerTP, unsigned short valSpan){return 0;} - -inline su2double CSolver::GetOmegaOut(unsigned short inMarkerTP, unsigned short valSpan){return 0;} - -inline su2double CSolver::GetNuOut(unsigned short inMarkerTP, unsigned short valSpan){return 0;} - -inline void CSolver::SetDensityIn(su2double value, unsigned short inMarkerTP, unsigned short valSpan){ } - -inline void CSolver::SetPressureIn(su2double value, unsigned short inMarkerTP, unsigned short valSpan){ } - -inline void CSolver::SetTurboVelocityIn(su2double *value, unsigned short inMarkerTP, unsigned short valSpan){ } - -inline void CSolver::SetDensityOut(su2double value, unsigned short inMarkerTP, unsigned short valSpan){ } - -inline void CSolver::SetPressureOut(su2double value, unsigned short inMarkerTP, unsigned short valSpan){ } - -inline void CSolver::SetTurboVelocityOut(su2double *value, unsigned short inMarkerTP, unsigned short valSpan){ } - -inline void CSolver::SetKineIn(su2double value, unsigned short inMarkerTP, unsigned short valSpan){ } - -inline void CSolver::SetOmegaIn(su2double value, unsigned short inMarkerTP, unsigned short valSpan){ } - -inline void CSolver::SetNuIn(su2double value, unsigned short inMarkerTP, unsigned short valSpan){ } - -inline void CSolver::SetKineOut(su2double value, unsigned short inMarkerTP, unsigned short valSpan){ } - -inline void CSolver::SetOmegaOut(su2double value, unsigned short inMarkerTP, unsigned short valSpan){ } - -inline void CSolver::SetNuOut(su2double value, unsigned short inMarkerTP, unsigned short valSpan){ } - -inline void CSolver::SetFreeStream_TurboSolution(CConfig *config){ } - -inline void CSolver::SetBeta_Parameter(CGeometry *geometry, CSolver **solver_container, - CConfig *config, unsigned short iMesh) { } - -inline void CSolver::SetRoe_Dissipation(CGeometry *geometry, CConfig *config) {} - -inline void CSolver::SetDES_LengthScale(CSolver** solver, CGeometry *geometry, CConfig *config) { } - -inline void CSolver::DeformMesh(CGeometry **geometry, CNumerics **numerics, CConfig *config) { } - -inline void CSolver::SetMesh_Stiffness(CGeometry **geometry, CNumerics **numerics, CConfig *config) { } - -inline void CSolver::SetConjugateHeatVariable(unsigned short val_marker, unsigned long val_vertex, unsigned short pos_var, su2double relaxation_factor, su2double val_var) { } - -inline su2double CSolver::GetConjugateHeatVariable(unsigned short val_marker, unsigned long val_vertex, unsigned short pos_var) { return 0.0; } - -inline void CSolver::ComputeVerificationError(CGeometry *geometry, CConfig *config) { } - -inline void CSolver::SetImplicitPeriodic(bool val_implicit_periodic) { implicit_periodic = val_implicit_periodic; } - -inline void CSolver::SetRotatePeriodic(bool val_rotate_periodic) { rotate_periodic = val_rotate_periodic; } - -inline string CSolver::GetSolverName(void) {return SolverName;} - -inline su2double CEulerSolver::GetDensity_Inf(void) { return Density_Inf; } - -inline su2double CEulerSolver::GetModVelocity_Inf(void) { - su2double Vel2 = 0; - for (unsigned short iDim = 0; iDim < nDim; iDim++) - Vel2 += Velocity_Inf[iDim]*Velocity_Inf[iDim]; - return sqrt(Vel2); -} - -inline su2double CEulerSolver::GetDensity_Energy_Inf(void) { return Density_Inf*Energy_Inf; } - -inline su2double CEulerSolver::GetDensity_Velocity_Inf(unsigned short val_dim) { return Density_Inf*Velocity_Inf[val_dim]; } - -inline su2double CEulerSolver::GetVelocity_Inf(unsigned short val_dim) { return Velocity_Inf[val_dim]; } - -inline su2double *CEulerSolver::GetVelocity_Inf(void) { return Velocity_Inf; } - -inline su2double CEulerSolver::GetPressure_Inf(void) { return Pressure_Inf; } - -inline su2double CEulerSolver::GetCPressure(unsigned short val_marker, unsigned long val_vertex) { return CPressure[val_marker][val_vertex]; } - -inline su2double CEulerSolver::GetCPressureTarget(unsigned short val_marker, unsigned long val_vertex) { return CPressureTarget[val_marker][val_vertex]; } - -inline void CEulerSolver::SetCPressureTarget(unsigned short val_marker, unsigned long val_vertex, su2double val_pressure) { CPressureTarget[val_marker][val_vertex] = val_pressure; } - -inline su2double *CEulerSolver::GetCharacPrimVar(unsigned short val_marker, unsigned long val_vertex) { return CharacPrimVar[val_marker][val_vertex]; } - -inline void CEulerSolver::SetCharacPrimVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_var, su2double val_value) { CharacPrimVar[val_marker][val_vertex][val_var] = val_value; } - -inline su2double *CEulerSolver::GetDonorPrimVar(unsigned short val_marker, unsigned long val_vertex) { return DonorPrimVar[val_marker][val_vertex]; } - -inline void CEulerSolver::SetDonorPrimVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_var, su2double val_value) { DonorPrimVar[val_marker][val_vertex][val_var] = val_value; } - -inline su2double CEulerSolver::GetDonorPrimVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_var) { return DonorPrimVar[val_marker][val_vertex][val_var]; } - -inline unsigned long CEulerSolver::GetDonorGlobalIndex(unsigned short val_marker, unsigned long val_vertex) { return DonorGlobalIndex[val_marker][val_vertex]; } - -inline void CEulerSolver::SetDonorGlobalIndex(unsigned short val_marker, unsigned long val_vertex, unsigned long val_index) { DonorGlobalIndex[val_marker][val_vertex] = val_index; } - -inline su2double CEulerSolver::GetActDisk_DeltaP(unsigned short val_marker, unsigned long val_vertex) { return ActDisk_DeltaP[val_marker][val_vertex]; } - -inline void CEulerSolver::SetActDisk_DeltaP(unsigned short val_marker, unsigned long val_vertex, su2double val_deltap) { ActDisk_DeltaP[val_marker][val_vertex] = val_deltap; } - -inline su2double CEulerSolver::GetActDisk_DeltaT(unsigned short val_marker, unsigned long val_vertex) { return ActDisk_DeltaT[val_marker][val_vertex]; } - -inline void CEulerSolver::SetActDisk_DeltaT(unsigned short val_marker, unsigned long val_vertex, su2double val_deltat) { ActDisk_DeltaT[val_marker][val_vertex] = val_deltat; } - -inline su2double CEulerSolver::GetInlet_Ttotal(unsigned short val_marker, unsigned long val_vertex) { return Inlet_Ttotal[val_marker][val_vertex]; } - -inline su2double CEulerSolver::GetInlet_Ptotal(unsigned short val_marker, unsigned long val_vertex) { return Inlet_Ptotal[val_marker][val_vertex]; } - -inline su2double CEulerSolver::GetInlet_FlowDir(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim) { return Inlet_FlowDir[val_marker][val_vertex][val_dim]; } - -inline void CEulerSolver::SetInlet_Ttotal(unsigned short val_marker, unsigned long val_vertex, su2double val_ttotal) { - /*--- Since this call can be accessed indirectly using python, do some error - * checking to prevent segmentation faults ---*/ - if (val_marker >= nMarker) - SU2_MPI::Error("Out-of-bounds marker index used on inlet.", CURRENT_FUNCTION); - else if (Inlet_Ttotal == NULL || Inlet_Ttotal[val_marker] == NULL) - SU2_MPI::Error("Tried to set custom inlet BC on an invalid marker.", CURRENT_FUNCTION); - else if (val_vertex >= nVertex[val_marker]) - SU2_MPI::Error("Out-of-bounds vertex index used on inlet.", CURRENT_FUNCTION); - else - Inlet_Ttotal[val_marker][val_vertex] = val_ttotal; -} - -inline void CEulerSolver::SetInlet_Ptotal(unsigned short val_marker, unsigned long val_vertex, su2double val_ptotal) { - /*--- Since this call can be accessed indirectly using python, do some error - * checking to prevent segmentation faults ---*/ - if (val_marker >= nMarker) - SU2_MPI::Error("Out-of-bounds marker index used on inlet.", CURRENT_FUNCTION); - else if (Inlet_Ptotal == NULL || Inlet_Ptotal[val_marker] == NULL) - SU2_MPI::Error("Tried to set custom inlet BC on an invalid marker.", CURRENT_FUNCTION); - else if (val_vertex >= nVertex[val_marker]) - SU2_MPI::Error("Out-of-bounds vertex index used on inlet.", CURRENT_FUNCTION); - else - Inlet_Ptotal[val_marker][val_vertex] = val_ptotal; -} - -inline void CEulerSolver::SetInlet_FlowDir(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim, su2double val_flowdir) { - /*--- Since this call can be accessed indirectly using python, do some error - * checking to prevent segmentation faults ---*/ - if (val_marker >= nMarker) - SU2_MPI::Error("Out-of-bounds marker index used on inlet.", CURRENT_FUNCTION); - else if (Inlet_FlowDir == NULL || Inlet_FlowDir[val_marker] == NULL) - SU2_MPI::Error("Tried to set custom inlet BC on an invalid marker.", CURRENT_FUNCTION); - else if (val_vertex >= nVertex[val_marker]) - SU2_MPI::Error("Out-of-bounds vertex index used on inlet.", CURRENT_FUNCTION); - else - Inlet_FlowDir[val_marker][val_vertex][val_dim] = val_flowdir; -} - -inline su2double CEulerSolver::GetCL_Inv(unsigned short val_marker) { return CL_Inv[val_marker]; } - -inline su2double CEulerSolver::GetCD_Inv(unsigned short val_marker) { return CD_Inv[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CL(unsigned short val_marker) { return Surface_CL[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CD(unsigned short val_marker) { return Surface_CD[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CSF(unsigned short val_marker) { return Surface_CSF[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CEff(unsigned short val_marker) { return Surface_CEff[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CFx(unsigned short val_marker) { return Surface_CFx[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CFy(unsigned short val_marker) { return Surface_CFy[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CFz(unsigned short val_marker) { return Surface_CFz[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CMx(unsigned short val_marker) { return Surface_CMx[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CMy(unsigned short val_marker) { return Surface_CMy[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CMz(unsigned short val_marker) { return Surface_CMz[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CL_Inv(unsigned short val_marker) { return Surface_CL_Inv[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CD_Inv(unsigned short val_marker) { return Surface_CD_Inv[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CSF_Inv(unsigned short val_marker) { return Surface_CSF_Inv[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CEff_Inv(unsigned short val_marker) { return Surface_CEff_Inv[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CFx_Inv(unsigned short val_marker) { return Surface_CFx_Inv[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CFy_Inv(unsigned short val_marker) { return Surface_CFy_Inv[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CFz_Inv(unsigned short val_marker) { return Surface_CFz_Inv[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CMx_Inv(unsigned short val_marker) { return Surface_CMx_Inv[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CMy_Inv(unsigned short val_marker) { return Surface_CMy_Inv[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CMz_Inv(unsigned short val_marker) { return Surface_CMz_Inv[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CL_Mnt(unsigned short val_marker) { return Surface_CL_Mnt[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CD_Mnt(unsigned short val_marker) { return Surface_CD_Mnt[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CSF_Mnt(unsigned short val_marker) { return Surface_CSF_Mnt[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CEff_Mnt(unsigned short val_marker) { return Surface_CEff_Mnt[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CFx_Mnt(unsigned short val_marker) { return Surface_CFx_Mnt[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CFy_Mnt(unsigned short val_marker) { return Surface_CFy_Mnt[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CFz_Mnt(unsigned short val_marker) { return Surface_CFz_Mnt[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CMx_Mnt(unsigned short val_marker) { return Surface_CMx_Mnt[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CMy_Mnt(unsigned short val_marker) { return Surface_CMy_Mnt[val_marker]; } - -inline su2double CEulerSolver::GetSurface_CMz_Mnt(unsigned short val_marker) { return Surface_CMz_Mnt[val_marker]; } - -inline su2double CEulerSolver::GetInflow_MassFlow(unsigned short val_marker) { return Inflow_MassFlow[val_marker]; } - -inline su2double CEulerSolver::GetExhaust_MassFlow(unsigned short val_marker) { return Exhaust_MassFlow[val_marker]; } - -inline su2double CEulerSolver::GetInflow_Pressure(unsigned short val_marker) { return Inflow_Pressure[val_marker]; } - -inline su2double CEulerSolver::GetInflow_Mach(unsigned short val_marker) { return Inflow_Mach[val_marker]; } - -inline su2double CEulerSolver::GetCSF_Inv(unsigned short val_marker) { return CSF_Inv[val_marker]; } - -inline su2double CEulerSolver::GetCEff_Inv(unsigned short val_marker) { return CEff_Inv[val_marker]; } - -inline su2double CEulerSolver::GetTotal_CL() { return Total_CL; } - -inline void CEulerSolver::SetTotal_ComboObj(su2double ComboObj) {Total_ComboObj = ComboObj; } - -inline su2double CEulerSolver::GetTotal_ComboObj() { return Total_ComboObj; } - -inline su2double CEulerSolver::GetTotal_CD() { return Total_CD; } - -inline su2double CEulerSolver::GetTotal_NetThrust() { return Total_NetThrust; } - -inline su2double CEulerSolver::GetTotal_Power() { return Total_Power; } - -inline su2double CEulerSolver::GetTotal_SolidCD() { return Total_SolidCD; } - -inline su2double CEulerSolver::GetTotal_ReverseFlow() { return Total_ReverseFlow; } - -inline su2double CEulerSolver::GetTotal_MFR() { return Total_MFR; } - -inline su2double CEulerSolver::GetTotal_Prop_Eff() { return Total_Prop_Eff; } - -inline su2double CEulerSolver::GetTotal_ByPassProp_Eff() { return Total_ByPassProp_Eff; } - -inline su2double CEulerSolver::GetTotal_Adiab_Eff() { return Total_Adiab_Eff; } - -inline su2double CEulerSolver::GetTotal_Poly_Eff() { return Total_Poly_Eff; } - -inline su2double CEulerSolver::GetTotal_IDC_Mach() { return Total_IDC_Mach; } - -inline su2double CEulerSolver::GetTotal_DC60() { return Total_DC60; } - -inline su2double CEulerSolver::GetTotal_Custom_ObjFunc() { return Total_Custom_ObjFunc; } - -inline su2double CEulerSolver::GetTotal_CMx() { return Total_CMx; } - -inline su2double CEulerSolver::GetTotal_CMy() { return Total_CMy; } - -inline su2double CEulerSolver::GetTotal_CMz() { return Total_CMz; } - -inline su2double CEulerSolver::GetTotal_CoPx() { return Total_CoPx; } - -inline su2double CEulerSolver::GetTotal_CoPy() { return Total_CoPy; } - -inline su2double CEulerSolver::GetTotal_CoPz() { return Total_CoPz; } - -inline su2double CEulerSolver::GetTotal_CFx() { return Total_CFx; } - -inline su2double CEulerSolver::GetTotal_CFy() { return Total_CFy; } - -inline su2double CEulerSolver::GetTotal_CFz() { return Total_CFz; } - -inline su2double CEulerSolver::GetTotal_CSF() { return Total_CSF; } - -inline su2double CEulerSolver::GetTotal_CEff() { return Total_CEff; } - -inline su2double CEulerSolver::GetTotal_CT() { return Total_CT; } - -inline void CEulerSolver::SetTotal_CT(su2double val_Total_CT) { Total_CT = val_Total_CT; } - -inline su2double CEulerSolver::GetTotal_CQ() { return Total_CQ; } - -inline su2double CEulerSolver::GetTotal_HeatFlux() { return Total_Heat; } - -inline su2double CEulerSolver::GetTotal_MaxHeatFlux() { return Total_MaxHeat; } - -inline void CEulerSolver::SetTotal_CQ(su2double val_Total_CQ) { Total_CQ = val_Total_CQ; } - -inline void CEulerSolver::SetTotal_HeatFlux(su2double val_Total_Heat) { Total_Heat = val_Total_Heat; } - -inline void CEulerSolver::SetTotal_MaxHeatFlux(su2double val_Total_MaxHeat) { Total_MaxHeat = val_Total_MaxHeat; } - -inline su2double CEulerSolver::GetTotal_CMerit() { return Total_CMerit; } - -inline su2double CEulerSolver::GetTotal_CEquivArea() { return Total_CEquivArea; } - -inline su2double CEulerSolver::GetTotal_AeroCD() { return Total_AeroCD; } - -inline su2double CEulerSolver::GetTotal_IDR() { return Total_IDR; } - -inline su2double CEulerSolver::GetTotal_IDC() { return Total_IDC; } - -inline su2double CEulerSolver::GetTotal_CpDiff() { return Total_CpDiff; } - -inline su2double CEulerSolver::GetTotal_HeatFluxDiff() { return Total_HeatFluxDiff; } - -inline su2double CEulerSolver::GetTotal_CNearFieldOF() { return Total_CNearFieldOF; } - -inline void CEulerSolver::AddTotal_ComboObj(su2double val_obj) {Total_ComboObj +=val_obj;} - -inline void CEulerSolver::SetTotal_CEquivArea(su2double val_cequivarea) { Total_CEquivArea = val_cequivarea; } - -inline void CEulerSolver::SetTotal_AeroCD(su2double val_aerocd) { Total_AeroCD = val_aerocd; } - -inline void CEulerSolver::SetTotal_CpDiff(su2double pressure) { Total_CpDiff = pressure; } - -inline void CEulerSolver::SetTotal_HeatFluxDiff(su2double heat) { Total_HeatFluxDiff = heat; } - -inline void CEulerSolver::SetTotal_CNearFieldOF(su2double cnearfieldpress) { Total_CNearFieldOF = cnearfieldpress; } - -inline void CEulerSolver::SetTotal_CL(su2double val_Total_CL) { Total_CL = val_Total_CL; } - -inline void CEulerSolver::SetTotal_CD(su2double val_Total_CD) { Total_CD = val_Total_CD; } - -inline void CEulerSolver::SetTotal_NetThrust(su2double val_Total_NetThrust) { Total_NetThrust = val_Total_NetThrust; } - -inline void CEulerSolver::SetTotal_Power(su2double val_Total_Power) { Total_Power = val_Total_Power; } - -inline void CEulerSolver::SetTotal_SolidCD(su2double val_Total_SolidCD) { Total_SolidCD = val_Total_SolidCD; } - -inline void CEulerSolver::SetTotal_ReverseFlow(su2double val_Total_ReverseFlow) { Total_ReverseFlow = val_Total_ReverseFlow; } - -inline void CEulerSolver::SetTotal_MFR(su2double val_Total_MFR) { Total_MFR = val_Total_MFR; } - -inline void CEulerSolver::SetTotal_Prop_Eff(su2double val_Total_Prop_Eff) { Total_Prop_Eff = val_Total_Prop_Eff; } - -inline void CEulerSolver::SetTotal_ByPassProp_Eff(su2double val_Total_ByPassProp_Eff) { Total_ByPassProp_Eff = val_Total_ByPassProp_Eff; } - -inline void CEulerSolver::SetTotal_Adiab_Eff(su2double val_Total_Adiab_Eff) { Total_Adiab_Eff = val_Total_Adiab_Eff; } - -inline void CEulerSolver::SetTotal_Poly_Eff(su2double val_Total_Poly_Eff) { Total_Poly_Eff = val_Total_Poly_Eff; } - -inline void CEulerSolver::SetTotal_IDC(su2double val_Total_IDC) { Total_IDC = val_Total_IDC; } - -inline void CEulerSolver::SetTotal_IDC_Mach(su2double val_Total_IDC_Mach) { Total_IDC_Mach = val_Total_IDC_Mach; } - -inline void CEulerSolver::SetTotal_IDR(su2double val_Total_IDR) { Total_IDR = val_Total_IDR; } - -inline void CEulerSolver::SetTotal_DC60(su2double val_Total_DC60) { Total_DC60 = val_Total_DC60; } - -inline void CEulerSolver::SetTotal_Custom_ObjFunc(su2double val_total_custom_objfunc, su2double val_weight) { Total_Custom_ObjFunc = val_total_custom_objfunc*val_weight; } - -inline void CEulerSolver::AddTotal_Custom_ObjFunc(su2double val_total_custom_objfunc, su2double val_weight) { Total_Custom_ObjFunc += val_total_custom_objfunc*val_weight; } - -inline su2double CEulerSolver::GetAllBound_CL_Inv() { return AllBound_CL_Inv; } - -inline su2double CEulerSolver::GetAllBound_CD_Inv() { return AllBound_CD_Inv; } - -inline su2double CEulerSolver::GetAllBound_CSF_Inv() { return AllBound_CSF_Inv; } - -inline su2double CEulerSolver::GetAllBound_CEff_Inv() { return AllBound_CEff_Inv; } - -inline su2double CEulerSolver::GetAllBound_CMx_Inv() { return AllBound_CMx_Inv; } - -inline su2double CEulerSolver::GetAllBound_CMy_Inv() { return AllBound_CMy_Inv; } - -inline su2double CEulerSolver::GetAllBound_CMz_Inv() { return AllBound_CMz_Inv; } - -inline su2double CEulerSolver::GetAllBound_CoPx_Inv() { return AllBound_CoPx_Inv; } - -inline su2double CEulerSolver::GetAllBound_CoPy_Inv() { return AllBound_CoPy_Inv; } - -inline su2double CEulerSolver::GetAllBound_CoPz_Inv() { return AllBound_CoPz_Inv; } - -inline su2double CEulerSolver::GetAllBound_CFx_Inv() { return AllBound_CFx_Inv; } - -inline su2double CEulerSolver::GetAllBound_CFy_Inv() { return AllBound_CFy_Inv; } - -inline su2double CEulerSolver::GetAllBound_CFz_Inv() { return AllBound_CFz_Inv; } - -inline su2double CEulerSolver::GetAllBound_CL_Mnt() { return AllBound_CL_Mnt; } - -inline su2double CEulerSolver::GetAllBound_CD_Mnt() { return AllBound_CD_Mnt; } - -inline su2double CEulerSolver::GetAllBound_CSF_Mnt() { return AllBound_CSF_Mnt; } - -inline su2double CEulerSolver::GetAllBound_CEff_Mnt() { return AllBound_CEff_Mnt; } - -inline su2double CEulerSolver::GetAllBound_CMx_Mnt() { return AllBound_CMx_Mnt; } - -inline su2double CEulerSolver::GetAllBound_CMy_Mnt() { return AllBound_CMy_Mnt; } - -inline su2double CEulerSolver::GetAllBound_CMz_Mnt() { return AllBound_CMz_Mnt; } - -inline su2double CEulerSolver::GetAllBound_CoPx_Mnt() { return AllBound_CoPx_Mnt; } - -inline su2double CEulerSolver::GetAllBound_CoPy_Mnt() { return AllBound_CoPy_Mnt; } - -inline su2double CEulerSolver::GetAllBound_CoPz_Mnt() { return AllBound_CoPz_Mnt; } - -inline su2double CEulerSolver::GetAllBound_CFx_Mnt() { return AllBound_CFx_Mnt; } - -inline su2double CEulerSolver::GetAllBound_CFy_Mnt() { return AllBound_CFy_Mnt; } - -inline su2double CEulerSolver::GetAllBound_CFz_Mnt() { return AllBound_CFz_Mnt; } - -inline su2double CEulerSolver::GetAverageDensity(unsigned short valMarker, unsigned short valSpan){return AverageDensity[valMarker][valSpan];} - -inline su2double CEulerSolver::GetAveragePressure(unsigned short valMarker, unsigned short valSpan){return AveragePressure[valMarker][valSpan];} - -inline su2double* CEulerSolver::GetAverageTurboVelocity(unsigned short valMarker, unsigned short valSpan){return AverageTurboVelocity[valMarker][valSpan];} - -inline su2double CEulerSolver::GetAverageNu(unsigned short valMarker, unsigned short valSpan){return AverageNu[valMarker][valSpan];} - -inline su2double CEulerSolver::GetAverageKine(unsigned short valMarker, unsigned short valSpan){return AverageKine[valMarker][valSpan];} - -inline su2double CEulerSolver::GetAverageOmega(unsigned short valMarker, unsigned short valSpan){return AverageOmega[valMarker][valSpan];} - -inline su2double CEulerSolver::GetExtAverageNu(unsigned short valMarker, unsigned short valSpan){return ExtAverageNu[valMarker][valSpan];} - -inline su2double CEulerSolver::GetExtAverageKine(unsigned short valMarker, unsigned short valSpan){return ExtAverageKine[valMarker][valSpan];} - -inline su2double CEulerSolver::GetExtAverageOmega(unsigned short valMarker, unsigned short valSpan){return ExtAverageOmega[valMarker][valSpan];} - -inline void CEulerSolver::SetExtAverageDensity(unsigned short valMarker, unsigned short valSpan, su2double valDensity){ExtAverageDensity[valMarker][valSpan] = valDensity;} - -inline void CEulerSolver::SetExtAveragePressure(unsigned short valMarker, unsigned short valSpan, su2double valPressure){ExtAveragePressure[valMarker][valSpan] = valPressure;} - -inline void CEulerSolver::SetExtAverageTurboVelocity(unsigned short valMarker, unsigned short valSpan, unsigned short valIndex, su2double valTurboVelocity){ExtAverageTurboVelocity[valMarker][valSpan][valIndex] = valTurboVelocity;} - -inline void CEulerSolver::SetExtAverageNu(unsigned short valMarker, unsigned short valSpan, su2double valNu){ExtAverageNu[valMarker][valSpan] = valNu;} - -inline void CEulerSolver::SetExtAverageKine(unsigned short valMarker, unsigned short valSpan, su2double valKine){ExtAverageKine[valMarker][valSpan] = valKine;} - -inline void CEulerSolver::SetExtAverageOmega(unsigned short valMarker, unsigned short valSpan, su2double valOmega){ExtAverageOmega[valMarker][valSpan] = valOmega;} - -inline su2double CEulerSolver::GetDensityIn(unsigned short inMarkerTP, unsigned short valSpan){return DensityIn[inMarkerTP][valSpan];} - -inline su2double CEulerSolver::GetPressureIn(unsigned short inMarkerTP, unsigned short valSpan){return PressureIn[inMarkerTP][valSpan];} - -inline su2double* CEulerSolver::GetTurboVelocityIn(unsigned short inMarkerTP, unsigned short valSpan){return TurboVelocityIn[inMarkerTP][valSpan];} - -inline su2double CEulerSolver::GetDensityOut(unsigned short inMarkerTP, unsigned short valSpan){return DensityOut[inMarkerTP][valSpan];} - -inline su2double CEulerSolver::GetPressureOut(unsigned short inMarkerTP, unsigned short valSpan){return PressureOut[inMarkerTP][valSpan];} - -inline su2double* CEulerSolver::GetTurboVelocityOut(unsigned short inMarkerTP, unsigned short valSpan){return TurboVelocityOut[inMarkerTP][valSpan];} - -inline su2double CEulerSolver::GetKineIn(unsigned short inMarkerTP, unsigned short valSpan){return KineIn[inMarkerTP][valSpan];} - -inline su2double CEulerSolver::GetOmegaIn(unsigned short inMarkerTP, unsigned short valSpan){return OmegaIn[inMarkerTP][valSpan];} - -inline su2double CEulerSolver::GetNuIn(unsigned short inMarkerTP, unsigned short valSpan){return NuIn[inMarkerTP][valSpan];} - -inline su2double CEulerSolver::GetKineOut(unsigned short inMarkerTP, unsigned short valSpan){return KineOut[inMarkerTP][valSpan];} - -inline su2double CEulerSolver::GetOmegaOut(unsigned short inMarkerTP, unsigned short valSpan){return OmegaOut[inMarkerTP][valSpan];} - -inline su2double CEulerSolver::GetNuOut(unsigned short inMarkerTP, unsigned short valSpan){return NuOut[inMarkerTP][valSpan];} - -inline void CEulerSolver::SetDensityIn(su2double value, unsigned short inMarkerTP, unsigned short valSpan){DensityIn[inMarkerTP][valSpan] = value;} - -inline void CEulerSolver::SetPressureIn(su2double value, unsigned short inMarkerTP, unsigned short valSpan){PressureIn[inMarkerTP][valSpan] = value;} - -inline void CEulerSolver::SetTurboVelocityIn(su2double *value, unsigned short inMarkerTP, unsigned short valSpan){ - unsigned short iDim; - - for(iDim = 0; iDim < nDim; iDim++) - TurboVelocityIn[inMarkerTP][valSpan][iDim] = value[iDim]; -} - -inline void CEulerSolver::SetDensityOut(su2double value, unsigned short inMarkerTP, unsigned short valSpan){DensityOut[inMarkerTP][valSpan] = value;} - -inline void CEulerSolver::SetPressureOut(su2double value, unsigned short inMarkerTP, unsigned short valSpan){PressureOut[inMarkerTP][valSpan] = value;} - -inline void CEulerSolver::SetTurboVelocityOut(su2double *value, unsigned short inMarkerTP, unsigned short valSpan){ - unsigned short iDim; - - for(iDim = 0; iDim < nDim; iDim++) - TurboVelocityOut[inMarkerTP][valSpan][iDim] = value[iDim]; -} - -inline void CEulerSolver::SetKineIn(su2double value, unsigned short inMarkerTP, unsigned short valSpan){KineIn[inMarkerTP][valSpan] = value;} - -inline void CEulerSolver::SetOmegaIn(su2double value, unsigned short inMarkerTP, unsigned short valSpan){OmegaIn[inMarkerTP][valSpan] = value;} - -inline void CEulerSolver::SetNuIn(su2double value, unsigned short inMarkerTP, unsigned short valSpan){NuIn[inMarkerTP][valSpan] = value;} - -inline void CEulerSolver::SetKineOut(su2double value, unsigned short inMarkerTP, unsigned short valSpan){KineOut[inMarkerTP][valSpan] = value;} - -inline void CEulerSolver::SetOmegaOut(su2double value, unsigned short inMarkerTP, unsigned short valSpan){OmegaOut[inMarkerTP][valSpan] = value;} - -inline void CEulerSolver::SetNuOut(su2double value, unsigned short inMarkerTP, unsigned short valSpan){NuOut[inMarkerTP][valSpan] = value;} - -inline void CEulerSolver::ComputeTurboVelocity(const su2double *cartesianVelocity, const su2double *turboNormal, su2double *turboVelocity, - unsigned short marker_flag, unsigned short kind_turb) { - - if ((kind_turb == AXIAL && nDim == 3) || (kind_turb == CENTRIPETAL_AXIAL && marker_flag == OUTFLOW) || (kind_turb == AXIAL_CENTRIFUGAL && marker_flag == INFLOW) ){ - turboVelocity[2] = turboNormal[0]*cartesianVelocity[0] + cartesianVelocity[1]*turboNormal[1]; - turboVelocity[1] = turboNormal[0]*cartesianVelocity[1] - turboNormal[1]*cartesianVelocity[0]; - turboVelocity[0] = cartesianVelocity[2]; - } - else{ - turboVelocity[0] = turboNormal[0]*cartesianVelocity[0] + cartesianVelocity[1]*turboNormal[1]; - turboVelocity[1] = turboNormal[0]*cartesianVelocity[1] - turboNormal[1]*cartesianVelocity[0]; - if (marker_flag == INFLOW){ - turboVelocity[0] *= -1.0; - turboVelocity[1] *= -1.0; - } - if(nDim == 3) - turboVelocity[2] = cartesianVelocity[2]; - } -} - -inline void CEulerSolver::ComputeBackVelocity(const su2double *turboVelocity, const su2double *turboNormal, su2double *cartesianVelocity, - unsigned short marker_flag, unsigned short kind_turb){ - - if ((kind_turb == AXIAL && nDim == 3) || (kind_turb == CENTRIPETAL_AXIAL && marker_flag == OUTFLOW) || (kind_turb == AXIAL_CENTRIFUGAL && marker_flag == INFLOW)){ - cartesianVelocity[0] = turboVelocity[2]*turboNormal[0] - turboVelocity[1]*turboNormal[1]; - cartesianVelocity[1] = turboVelocity[2]*turboNormal[1] + turboVelocity[1]*turboNormal[0]; - cartesianVelocity[2] = turboVelocity[0]; - } - else{ - cartesianVelocity[0] = turboVelocity[0]*turboNormal[0] - turboVelocity[1]*turboNormal[1]; - cartesianVelocity[1] = turboVelocity[0]*turboNormal[1] + turboVelocity[1]*turboNormal[0]; - - if (marker_flag == INFLOW){ - cartesianVelocity[0] *= -1.0; - cartesianVelocity[1] *= -1.0; - } - - if(nDim == 3) - cartesianVelocity[2] = turboVelocity[2]; - } -} - - -inline CFluidModel* CEulerSolver::GetFluidModel(void) { return FluidModel;} - -inline void CEulerSolver::SetPressure_Inf(su2double p_inf) {Pressure_Inf = p_inf;} - -inline void CEulerSolver::SetTemperature_Inf(su2double t_inf) {Temperature_Inf = t_inf;} - -inline bool CEulerSolver::GetStart_AoA_FD(void) { return Start_AoA_FD; } - -inline bool CEulerSolver::GetEnd_AoA_FD(void) { return End_AoA_FD; } - -inline unsigned long CEulerSolver::GetIter_Update_AoA(void) { return Iter_Update_AoA; } - -inline su2double CEulerSolver::GetPrevious_AoA(void) { return AoA_Prev; } - -inline su2double CEulerSolver::GetAoA_inc(void) { return AoA_inc; } - -inline su2double CNSSolver::GetViscosity_Inf(void) { return Viscosity_Inf; } - -inline su2double CNSSolver::GetTke_Inf(void) { return Tke_Inf; } - -inline su2double CNSSolver::GetSurface_HF_Visc(unsigned short val_marker) { return Surface_HF_Visc[val_marker]; } - -inline su2double CNSSolver::GetSurface_MaxHF_Visc(unsigned short val_marker) { return Surface_MaxHF_Visc[val_marker]; } - -inline su2double CNSSolver::GetCL_Visc(unsigned short val_marker) { return CL_Visc[val_marker]; } - -inline su2double CNSSolver::GetCSF_Visc(unsigned short val_marker) { return CSF_Visc[val_marker]; } - -inline su2double CNSSolver::GetCD_Visc(unsigned short val_marker) { return CD_Visc[val_marker]; } - -inline su2double CNSSolver::GetAllBound_CL_Visc() { return AllBound_CL_Visc; } - -inline su2double CNSSolver::GetAllBound_CD_Visc() { return AllBound_CD_Visc; } - -inline su2double CNSSolver::GetAllBound_CSF_Visc() { return AllBound_CSF_Visc; } - -inline su2double CNSSolver::GetAllBound_CEff_Visc() { return AllBound_CEff_Visc; } - -inline su2double CNSSolver::GetAllBound_CMx_Visc() { return AllBound_CMx_Visc; } - -inline su2double CNSSolver::GetAllBound_CMy_Visc() { return AllBound_CMy_Visc; } - -inline su2double CNSSolver::GetAllBound_CMz_Visc() { return AllBound_CMz_Visc; } - -inline su2double CNSSolver::GetAllBound_CoPx_Visc() { return AllBound_CoPx_Visc; } - -inline su2double CNSSolver::GetAllBound_CoPy_Visc() { return AllBound_CoPy_Visc; } - -inline su2double CNSSolver::GetAllBound_CoPz_Visc() { return AllBound_CoPz_Visc; } - -inline su2double CNSSolver::GetAllBound_CFx_Visc() { return AllBound_CFx_Visc; } - -inline su2double CNSSolver::GetAllBound_CFy_Visc() { return AllBound_CFy_Visc; } - -inline su2double CNSSolver::GetAllBound_CFz_Visc() { return AllBound_CFz_Visc; } - -inline su2double CNSSolver::GetTotal_Buffet_Metric() { return Total_Buffet_Metric; } - -inline su2double CNSSolver::GetSurface_CL_Visc(unsigned short val_marker) { return Surface_CL_Visc[val_marker]; } - -inline su2double CNSSolver::GetSurface_CD_Visc(unsigned short val_marker) { return Surface_CD_Visc[val_marker]; } - -inline su2double CNSSolver::GetSurface_CSF_Visc(unsigned short val_marker) { return Surface_CSF_Visc[val_marker]; } - -inline su2double CNSSolver::GetSurface_CEff_Visc(unsigned short val_marker) { return Surface_CEff_Visc[val_marker]; } - -inline su2double CNSSolver::GetSurface_CFx_Visc(unsigned short val_marker) { return Surface_CFx_Visc[val_marker]; } - -inline su2double CNSSolver::GetSurface_CFy_Visc(unsigned short val_marker) { return Surface_CFy_Visc[val_marker]; } - -inline su2double CNSSolver::GetSurface_CFz_Visc(unsigned short val_marker) { return Surface_CFz_Visc[val_marker]; } - -inline su2double CNSSolver::GetSurface_CMx_Visc(unsigned short val_marker) { return Surface_CMx_Visc[val_marker]; } - -inline su2double CNSSolver::GetSurface_CMy_Visc(unsigned short val_marker) { return Surface_CMy_Visc[val_marker]; } - -inline su2double CNSSolver::GetSurface_CMz_Visc(unsigned short val_marker) { return Surface_CMz_Visc[val_marker]; } - -inline su2double CNSSolver::GetSurface_Buffet_Metric(unsigned short val_marker) { return Surface_Buffet_Metric[val_marker]; } - -inline su2double CNSSolver::GetCSkinFriction(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim) { return CSkinFriction[val_marker][val_dim][val_vertex]; } - -inline su2double CNSSolver::GetHeatFlux(unsigned short val_marker, unsigned long val_vertex) { return HeatFlux[val_marker][val_vertex]; } - -inline su2double CNSSolver::GetHeatFluxTarget(unsigned short val_marker, unsigned long val_vertex) { return HeatFluxTarget[val_marker][val_vertex]; } - -inline void CNSSolver::SetHeatFluxTarget(unsigned short val_marker, unsigned long val_vertex, su2double val_heat) { HeatFluxTarget[val_marker][val_vertex] = val_heat; } - -inline su2double CNSSolver::GetBuffetSensor(unsigned short val_marker, unsigned long val_vertex) { return Buffet_Sensor[val_marker][val_vertex]; } - -inline su2double CNSSolver::GetYPlus(unsigned short val_marker, unsigned long val_vertex) { return YPlus[val_marker][val_vertex]; } - -inline su2double CNSSolver::GetStrainMag_Max(void) { return StrainMag_Max; } - -inline su2double CNSSolver::GetOmega_Max(void) { return Omega_Max; } - -inline void CNSSolver::SetStrainMag_Max(su2double val_strainmag_max) { StrainMag_Max = val_strainmag_max; } - -inline void CNSSolver::SetOmega_Max(su2double val_omega_max) { Omega_Max = val_omega_max; } - -inline su2double CNSSolver::GetConjugateHeatVariable(unsigned short val_marker, unsigned long val_vertex, unsigned short pos_var) { return HeatConjugateVar[val_marker][val_vertex][pos_var]; } - -inline void CNSSolver::SetConjugateHeatVariable(unsigned short val_marker, unsigned long val_vertex, unsigned short pos_var, su2double relaxation_factor, su2double val_var) { - HeatConjugateVar[val_marker][val_vertex][pos_var] = relaxation_factor*val_var + (1.0-relaxation_factor)*HeatConjugateVar[val_marker][val_vertex][pos_var]; } - -inline CFluidModel* CFEM_DG_EulerSolver::GetFluidModel(void) { return FluidModel;} - -inline su2double* CFEM_DG_EulerSolver::GetVecSolDOFs(void) {return VecSolDOFs.data();} - -inline unsigned long CFEM_DG_EulerSolver::GetnDOFsGlobal(void) {return nDOFsGlobal;} - -inline su2double CFEM_DG_EulerSolver::GetDensity_Inf(void) { return Density_Inf; } - -inline su2double CFEM_DG_EulerSolver::GetModVelocity_Inf(void) { - su2double Vel2 = 0; - for (unsigned short iDim = 0; iDim < nDim; iDim++) - Vel2 += Velocity_Inf[iDim]*Velocity_Inf[iDim]; - return sqrt(Vel2); -} - -inline su2double CFEM_DG_EulerSolver::GetDensity_Energy_Inf(void) { return Density_Inf*Energy_Inf; } - -inline su2double CFEM_DG_EulerSolver::GetDensity_Velocity_Inf(unsigned short val_dim) { return Density_Inf*Velocity_Inf[val_dim]; } - -inline su2double CFEM_DG_EulerSolver::GetVelocity_Inf(unsigned short val_dim) { return Velocity_Inf[val_dim]; } - -inline su2double *CFEM_DG_EulerSolver::GetVelocity_Inf(void) { return Velocity_Inf; } - -inline su2double CFEM_DG_EulerSolver::GetPressure_Inf(void) { return Pressure_Inf; } - -inline su2double CFEM_DG_EulerSolver::GetCL_Inv(unsigned short val_marker) { return CL_Inv[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetCMz_Inv(unsigned short val_marker) { return CMz_Inv[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetCD_Inv(unsigned short val_marker) { return CD_Inv[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetSurface_CL(unsigned short val_marker) { return Surface_CL[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetSurface_CD(unsigned short val_marker) { return Surface_CD[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetSurface_CSF(unsigned short val_marker) { return Surface_CSF[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetSurface_CEff(unsigned short val_marker) { return Surface_CEff[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetSurface_CFx(unsigned short val_marker) { return Surface_CFx[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetSurface_CFy(unsigned short val_marker) { return Surface_CFy[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetSurface_CFz(unsigned short val_marker) { return Surface_CFz[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetSurface_CMx(unsigned short val_marker) { return Surface_CMx[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetSurface_CMy(unsigned short val_marker) { return Surface_CMy[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetSurface_CMz(unsigned short val_marker) { return Surface_CMz[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetSurface_CL_Inv(unsigned short val_marker) { return Surface_CL_Inv[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetSurface_CD_Inv(unsigned short val_marker) { return Surface_CD_Inv[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetSurface_CSF_Inv(unsigned short val_marker) { return Surface_CSF_Inv[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetSurface_CEff_Inv(unsigned short val_marker) { return Surface_CEff_Inv[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetSurface_CFx_Inv(unsigned short val_marker) { return Surface_CFx_Inv[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetSurface_CFy_Inv(unsigned short val_marker) { return Surface_CFy_Inv[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetSurface_CFz_Inv(unsigned short val_marker) { return Surface_CFz_Inv[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetSurface_CMx_Inv(unsigned short val_marker) { return Surface_CMx_Inv[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetSurface_CMy_Inv(unsigned short val_marker) { return Surface_CMy_Inv[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetSurface_CMz_Inv(unsigned short val_marker) { return Surface_CMz_Inv[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetCSF_Inv(unsigned short val_marker) { return CSF_Inv[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetCEff_Inv(unsigned short val_marker) { return CEff_Inv[val_marker]; } - -inline su2double CFEM_DG_EulerSolver::GetTotal_CL() { return Total_CL; } - -inline su2double CFEM_DG_EulerSolver::GetTotal_CD() { return Total_CD; } - -inline su2double CFEM_DG_EulerSolver::GetTotal_CMx() { return Total_CMx; } - -inline su2double CFEM_DG_EulerSolver::GetTotal_CMy() { return Total_CMy; } - -inline su2double CFEM_DG_EulerSolver::GetTotal_CMz() { return Total_CMz; } - -inline su2double CFEM_DG_EulerSolver::GetTotal_CFx() { return Total_CFx; } - -inline su2double CFEM_DG_EulerSolver::GetTotal_CFy() { return Total_CFy; } - -inline su2double CFEM_DG_EulerSolver::GetTotal_CFz() { return Total_CFz; } - -inline su2double CFEM_DG_EulerSolver::GetTotal_CSF() { return Total_CSF; } - -inline su2double CFEM_DG_EulerSolver::GetTotal_CEff() { return Total_CEff; } - -inline void CFEM_DG_EulerSolver::SetTotal_CL(su2double val_Total_CL) { Total_CL = val_Total_CL; } - -inline void CFEM_DG_EulerSolver::SetTotal_CD(su2double val_Total_CD) { Total_CD = val_Total_CD; } - -inline su2double CFEM_DG_EulerSolver::GetAllBound_CL_Inv() { return AllBound_CL_Inv; } - -inline su2double CFEM_DG_EulerSolver::GetAllBound_CD_Inv() { return AllBound_CD_Inv; } - -inline su2double CFEM_DG_EulerSolver::GetAllBound_CSF_Inv() { return AllBound_CSF_Inv; } - -inline su2double CFEM_DG_EulerSolver::GetAllBound_CEff_Inv() { return AllBound_CEff_Inv; } - -inline su2double CFEM_DG_EulerSolver::GetAllBound_CMx_Inv() { return AllBound_CMx_Inv; } - -inline su2double CFEM_DG_EulerSolver::GetAllBound_CMy_Inv() { return AllBound_CMy_Inv; } - -inline su2double CFEM_DG_EulerSolver::GetAllBound_CMz_Inv() { return AllBound_CMz_Inv; } - -inline su2double CFEM_DG_EulerSolver::GetAllBound_CFx_Inv() { return AllBound_CFx_Inv; } - -inline su2double CFEM_DG_EulerSolver::GetAllBound_CFy_Inv() { return AllBound_CFy_Inv; } - -inline su2double CFEM_DG_EulerSolver::GetAllBound_CFz_Inv() { return AllBound_CFz_Inv; } - -inline void CFEM_DG_EulerSolver::SetPressure_Inf(su2double p_inf){Pressure_Inf = p_inf;} - -inline void CFEM_DG_EulerSolver::SetTemperature_Inf(su2double t_inf){Temperature_Inf = t_inf;} - -inline void CFEM_DG_EulerSolver::BC_HeatFlux_Wall(CConfig *config, - const unsigned long surfElemBeg, - const unsigned long surfElemEnd, - const CSurfaceElementFEM *surfElem, - su2double *resFaces, - CNumerics *conv_numerics, - unsigned short val_marker, - su2double *workArray) {} - -inline void CFEM_DG_EulerSolver::BC_Isothermal_Wall(CConfig *config, - const unsigned long surfElemBeg, - const unsigned long surfElemEnd, - const CSurfaceElementFEM *surfElem, - su2double *resFaces, - CNumerics *conv_numerics, - unsigned short val_marker, - su2double *workArray) {} - -inline su2double CFEM_DG_NSSolver::GetViscosity_Inf(void) { return Viscosity_Inf; } - -inline su2double CFEM_DG_NSSolver::GetTke_Inf(void) { return Tke_Inf; } - -inline su2double CFEM_DG_NSSolver::GetCL_Visc(unsigned short val_marker) { return CL_Visc[val_marker]; } - -inline su2double CFEM_DG_NSSolver::GetCMz_Visc(unsigned short val_marker) { return CMz_Visc[val_marker]; } - -inline su2double CFEM_DG_NSSolver::GetCSF_Visc(unsigned short val_marker) { return CSF_Visc[val_marker]; } - -inline su2double CFEM_DG_NSSolver::GetCD_Visc(unsigned short val_marker) { return CD_Visc[val_marker]; } - -inline su2double CFEM_DG_NSSolver::GetAllBound_CL_Visc() { return AllBound_CL_Visc; } - -inline su2double CFEM_DG_NSSolver::GetAllBound_CSF_Visc() { return AllBound_CSF_Visc; } - -inline su2double CFEM_DG_NSSolver::GetAllBound_CD_Visc() { return AllBound_CD_Visc; } - -inline su2double CFEM_DG_NSSolver::GetStrainMag_Max(void) { return StrainMag_Max; } - -inline su2double CFEM_DG_NSSolver::GetOmega_Max(void) { return Omega_Max; } - -inline void CFEM_DG_NSSolver::SetStrainMag_Max(su2double val_strainmag_max) { StrainMag_Max = val_strainmag_max; } - -inline void CFEM_DG_NSSolver::SetOmega_Max(su2double val_omega_max) { Omega_Max = val_omega_max; } - -inline su2double CAdjEulerSolver::GetCSensitivity(unsigned short val_marker, unsigned long val_vertex) { return CSensitivity[val_marker][val_vertex]; } - -inline void CAdjEulerSolver::SetCSensitivity(unsigned short val_marker, unsigned long val_vertex, su2double val_sensitivity) { CSensitivity[val_marker][val_vertex] = val_sensitivity; } - -inline unsigned long CAdjEulerSolver::GetDonorGlobalIndex(unsigned short val_marker, unsigned long val_vertex) { return DonorGlobalIndex[val_marker][val_vertex]; } - -inline void CAdjEulerSolver::SetDonorGlobalIndex(unsigned short val_marker, unsigned long val_vertex, unsigned long val_index) { DonorGlobalIndex[val_marker][val_vertex] = val_index; } - -inline void CAdjEulerSolver::SetDonorAdjVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_var, su2double val_value) { DonorAdjVar[val_marker][val_vertex][val_var] = val_value; } - -inline su2double CAdjEulerSolver::GetTotal_Sens_Geo() { return Total_Sens_Geo; } - -inline su2double CAdjEulerSolver::GetTotal_Sens_Mach() { return Total_Sens_Mach; } - -inline su2double CAdjEulerSolver::GetTotal_Sens_AoA() { return Total_Sens_AoA; } - -inline su2double CAdjEulerSolver::GetTotal_Sens_Press() { return Total_Sens_Press; } - -inline su2double CAdjEulerSolver::GetTotal_Sens_Temp() { return Total_Sens_Temp; } - -inline su2double CAdjEulerSolver::GetTotal_Sens_BPress() { return Total_Sens_BPress; } - -inline su2double CAdjEulerSolver::GetPsiRho_Inf(void) { return PsiRho_Inf; } - -inline su2double CAdjEulerSolver::GetPsiE_Inf(void) { return PsiE_Inf; } - -inline su2double *CAdjEulerSolver::GetDonorAdjVar(unsigned short val_marker, unsigned long val_vertex) { return DonorAdjVar[val_marker][val_vertex]; } - -inline su2double CAdjEulerSolver::GetDonorAdjVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_var) { return DonorAdjVar[val_marker][val_vertex][val_var]; } - -inline su2double CAdjEulerSolver::GetPhi_Inf(unsigned short val_dim) { return Phi_Inf[val_dim]; } - -inline void CSolver::RefGeom_Sensitivity(CGeometry *geometry, CSolver **solver_container, CConfig *config){ } - -inline void CSolver::DE_Sensitivity(CGeometry *geometry, CSolver **solver_container, CNumerics **numerics, CConfig *config){ } - -inline void CSolver::Stiffness_Sensitivity(CGeometry *geometry, CSolver **solver_container, CNumerics **numerics, CConfig *config){ } - -inline unsigned short CSolver::Get_iElem_iDe(unsigned long iElem) const { return 0; } - -inline void CSolver::Set_DV_Val(su2double val_EField, unsigned short i_DV){ } - -inline su2double CSolver::Get_DV_Val(unsigned short i_DV){ return 0.0; } - -inline su2double CSolver::Get_val_I(void){ return 0.0; } - -inline su2double CIncEulerSolver::GetDensity_Inf(void) { return Density_Inf; } - -inline su2double CIncEulerSolver::GetModVelocity_Inf(void) { - su2double Vel2 = 0; - for (unsigned short iDim = 0; iDim < nDim; iDim++) - Vel2 += Velocity_Inf[iDim]*Velocity_Inf[iDim]; - return sqrt(Vel2); -} - -inline CFluidModel* CIncEulerSolver::GetFluidModel(void) { return FluidModel;} - -inline su2double CIncEulerSolver::GetDensity_Velocity_Inf(unsigned short val_dim) { return Density_Inf*Velocity_Inf[val_dim]; } - -inline su2double CIncEulerSolver::GetVelocity_Inf(unsigned short val_dim) { return Velocity_Inf[val_dim]; } - -inline void CIncEulerSolver::SetVelocity_Inf(unsigned short val_dim, su2double val_velocity) { Velocity_Inf[val_dim] = val_velocity; } - -inline su2double *CIncEulerSolver::GetVelocity_Inf(void) { return Velocity_Inf; } - -inline su2double CIncEulerSolver::GetPressure_Inf(void) { return Pressure_Inf; } - -inline su2double CIncEulerSolver::GetTemperature_Inf(void) { return Temperature_Inf; } - -inline su2double CIncEulerSolver::GetCPressure(unsigned short val_marker, unsigned long val_vertex) { return CPressure[val_marker][val_vertex]; } - -inline su2double CIncEulerSolver::GetCPressureTarget(unsigned short val_marker, unsigned long val_vertex) { return CPressureTarget[val_marker][val_vertex]; } - -inline void CIncEulerSolver::SetCPressureTarget(unsigned short val_marker, unsigned long val_vertex, su2double val_pressure) { CPressureTarget[val_marker][val_vertex] = val_pressure; } - -inline su2double *CIncEulerSolver::GetCharacPrimVar(unsigned short val_marker, unsigned long val_vertex) { return CharacPrimVar[val_marker][val_vertex]; } - -inline su2double CIncEulerSolver::GetInlet_Ttotal(unsigned short val_marker, unsigned long val_vertex) { return Inlet_Ttotal[val_marker][val_vertex]; } - -inline su2double CIncEulerSolver::GetInlet_Ptotal(unsigned short val_marker, unsigned long val_vertex) { return Inlet_Ptotal[val_marker][val_vertex]; } - -inline su2double CIncEulerSolver::GetInlet_FlowDir(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim) { return Inlet_FlowDir[val_marker][val_vertex][val_dim]; } - -inline su2double CIncEulerSolver::GetCD_Inv(unsigned short val_marker) { return CD_Inv[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CL(unsigned short val_marker) { return Surface_CL[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CD(unsigned short val_marker) { return Surface_CD[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CSF(unsigned short val_marker) { return Surface_CSF[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CEff(unsigned short val_marker) { return Surface_CEff[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CFx(unsigned short val_marker) { return Surface_CFx[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CFy(unsigned short val_marker) { return Surface_CFy[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CFz(unsigned short val_marker) { return Surface_CFz[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CMx(unsigned short val_marker) { return Surface_CMx[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CMy(unsigned short val_marker) { return Surface_CMy[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CMz(unsigned short val_marker) { return Surface_CMz[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CL_Inv(unsigned short val_marker) { return Surface_CL_Inv[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CD_Inv(unsigned short val_marker) { return Surface_CD_Inv[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CSF_Inv(unsigned short val_marker) { return Surface_CSF_Inv[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CEff_Inv(unsigned short val_marker) { return Surface_CEff_Inv[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CFx_Inv(unsigned short val_marker) { return Surface_CFx_Inv[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CFy_Inv(unsigned short val_marker) { return Surface_CFy_Inv[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CFz_Inv(unsigned short val_marker) { return Surface_CFz_Inv[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CMx_Inv(unsigned short val_marker) { return Surface_CMx_Inv[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CMy_Inv(unsigned short val_marker) { return Surface_CMy_Inv[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CMz_Inv(unsigned short val_marker) { return Surface_CMz_Inv[val_marker]; } - -inline su2double CIncEulerSolver::GetCSF_Inv(unsigned short val_marker) { return CSF_Inv[val_marker]; } - -inline su2double CIncEulerSolver::GetCEff_Inv(unsigned short val_marker) { return CEff_Inv[val_marker]; } - -inline su2double CIncEulerSolver::GetTotal_CL() { return Total_CL; } - -inline su2double CIncEulerSolver::GetTotal_CD() { return Total_CD; } - -inline su2double CIncEulerSolver::GetTotal_CMx() { return Total_CMx; } - -inline su2double CIncEulerSolver::GetTotal_CMy() { return Total_CMy; } - -inline su2double CIncEulerSolver::GetTotal_CMz() { return Total_CMz; } - -inline su2double CIncEulerSolver::GetTotal_CoPx() { return Total_CoPx; } - -inline su2double CIncEulerSolver::GetTotal_CoPy() { return Total_CoPy; } - -inline su2double CIncEulerSolver::GetTotal_CoPz() { return Total_CoPz; } - -inline su2double CIncEulerSolver::GetTotal_CFx() { return Total_CFx; } - -inline su2double CIncEulerSolver::GetTotal_CFy() { return Total_CFy; } - -inline su2double CIncEulerSolver::GetTotal_CFz() { return Total_CFz; } - -inline su2double CIncEulerSolver::GetTotal_CSF() { return Total_CSF; } - -inline su2double CIncEulerSolver::GetTotal_CEff() { return Total_CEff; } - -inline su2double CIncEulerSolver::GetTotal_CT() { return Total_CT; } - -inline void CIncEulerSolver::SetTotal_CT(su2double val_Total_CT) { Total_CT = val_Total_CT; } - -inline su2double CIncEulerSolver::GetTotal_CQ() { return Total_CQ; } - -inline su2double CIncEulerSolver::GetTotal_HeatFlux() { return Total_Heat; } - -inline su2double CIncEulerSolver::GetTotal_MaxHeatFlux() { return Total_MaxHeat; } - -inline void CIncEulerSolver::SetTotal_CQ(su2double val_Total_CQ) { Total_CQ = val_Total_CQ; } - -inline void CIncEulerSolver::SetTotal_HeatFlux(su2double val_Total_Heat) { Total_Heat = val_Total_Heat; } - -inline void CIncEulerSolver::SetTotal_MaxHeatFlux(su2double val_Total_MaxHeat) { Total_MaxHeat = val_Total_MaxHeat; } - -inline su2double CIncEulerSolver::GetTotal_CMerit() { return Total_CMerit; } - -inline su2double CIncEulerSolver::GetTotal_CpDiff() { return Total_CpDiff; } - -inline su2double CIncEulerSolver::GetTotal_HeatFluxDiff() { return Total_HeatFluxDiff; } - -inline void CIncEulerSolver::SetTotal_CpDiff(su2double pressure) { Total_CpDiff = pressure; } - -inline void CIncEulerSolver::SetTotal_HeatFluxDiff(su2double heat) { Total_HeatFluxDiff = heat; } - -inline void CIncEulerSolver::SetTotal_CD(su2double val_Total_CD) { Total_CD = val_Total_CD; } - -inline su2double CIncEulerSolver::GetTotal_Custom_ObjFunc() { return Total_Custom_ObjFunc; } - -inline void CIncEulerSolver::SetTotal_Custom_ObjFunc(su2double val_total_custom_objfunc, su2double val_weight) { Total_Custom_ObjFunc = val_total_custom_objfunc*val_weight; } - -inline void CIncEulerSolver::AddTotal_Custom_ObjFunc(su2double val_total_custom_objfunc, su2double val_weight) { Total_Custom_ObjFunc += val_total_custom_objfunc*val_weight; } - -inline su2double CIncEulerSolver::GetAllBound_CL_Inv() { return AllBound_CL_Inv; } - -inline su2double CIncEulerSolver::GetAllBound_CD_Inv() { return AllBound_CD_Inv; } - -inline su2double CIncEulerSolver::GetAllBound_CSF_Inv() { return AllBound_CSF_Inv; } - -inline su2double CIncEulerSolver::GetAllBound_CEff_Inv() { return AllBound_CEff_Inv; } - -inline su2double CIncEulerSolver::GetAllBound_CMx_Inv() { return AllBound_CMx_Inv; } - -inline su2double CIncEulerSolver::GetAllBound_CMy_Inv() { return AllBound_CMy_Inv; } - -inline su2double CIncEulerSolver::GetAllBound_CMz_Inv() { return AllBound_CMz_Inv; } - -inline su2double CIncEulerSolver::GetAllBound_CoPx_Inv() { return AllBound_CoPx_Inv; } - -inline su2double CIncEulerSolver::GetAllBound_CoPy_Inv() { return AllBound_CoPy_Inv; } - -inline su2double CIncEulerSolver::GetAllBound_CoPz_Inv() { return AllBound_CoPz_Inv; } - -inline su2double CIncEulerSolver::GetAllBound_CFx_Inv() { return AllBound_CFx_Inv; } - -inline su2double CIncEulerSolver::GetAllBound_CFy_Inv() { return AllBound_CFy_Inv; } - -inline su2double CIncEulerSolver::GetAllBound_CFz_Inv() { return AllBound_CFz_Inv; } - -inline su2double CIncEulerSolver::GetAllBound_CL_Mnt() { return AllBound_CL_Mnt; } - -inline su2double CIncEulerSolver::GetAllBound_CD_Mnt() { return AllBound_CD_Mnt; } - -inline su2double CIncEulerSolver::GetAllBound_CSF_Mnt() { return AllBound_CSF_Mnt; } - -inline su2double CIncEulerSolver::GetAllBound_CEff_Mnt() { return AllBound_CEff_Mnt; } - -inline su2double CIncEulerSolver::GetAllBound_CMx_Mnt() { return AllBound_CMx_Mnt; } - -inline su2double CIncEulerSolver::GetAllBound_CMy_Mnt() { return AllBound_CMy_Mnt; } - -inline su2double CIncEulerSolver::GetAllBound_CMz_Mnt() { return AllBound_CMz_Mnt; } - -inline su2double CIncEulerSolver::GetAllBound_CoPx_Mnt() { return AllBound_CoPx_Mnt; } - -inline su2double CIncEulerSolver::GetAllBound_CoPy_Mnt() { return AllBound_CoPy_Mnt; } - -inline su2double CIncEulerSolver::GetAllBound_CoPz_Mnt() { return AllBound_CoPz_Mnt; } - -inline su2double CIncEulerSolver::GetAllBound_CFx_Mnt() { return AllBound_CFx_Mnt; } - -inline su2double CIncEulerSolver::GetAllBound_CFy_Mnt() { return AllBound_CFy_Mnt; } - -inline su2double CIncEulerSolver::GetAllBound_CFz_Mnt() { return AllBound_CFz_Mnt; } - -inline su2double CIncEulerSolver::GetSurface_CL_Mnt(unsigned short val_marker) { return Surface_CL_Mnt[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CD_Mnt(unsigned short val_marker) { return Surface_CD_Mnt[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CSF_Mnt(unsigned short val_marker) { return Surface_CSF_Mnt[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CEff_Mnt(unsigned short val_marker) { return Surface_CEff_Mnt[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CFx_Mnt(unsigned short val_marker) { return Surface_CFx_Mnt[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CFy_Mnt(unsigned short val_marker) { return Surface_CFy_Mnt[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CFz_Mnt(unsigned short val_marker) { return Surface_CFz_Mnt[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CMx_Mnt(unsigned short val_marker) { return Surface_CMx_Mnt[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CMy_Mnt(unsigned short val_marker) { return Surface_CMy_Mnt[val_marker]; } - -inline su2double CIncEulerSolver::GetSurface_CMz_Mnt(unsigned short val_marker) { return Surface_CMz_Mnt[val_marker]; } - -inline void CIncEulerSolver::SetPressure_Inf(su2double p_inf){Pressure_Inf = p_inf;} - -inline void CIncEulerSolver::SetTemperature_Inf(su2double t_inf){Temperature_Inf = t_inf;} - -inline void CIncEulerSolver::SetDensity_Inf(su2double rho_inf){Density_Inf = rho_inf;} - -inline void CIncEulerSolver::SetTotal_ComboObj(su2double ComboObj) {Total_ComboObj = ComboObj; } - -inline su2double CIncEulerSolver::GetTotal_ComboObj() { return Total_ComboObj; } - -inline su2double CIncNSSolver::GetViscosity_Inf(void) { return Viscosity_Inf; } - -inline su2double CIncNSSolver::GetTke_Inf(void) { return Tke_Inf; } - -inline su2double CIncNSSolver::GetSurface_HF_Visc(unsigned short val_marker) { return Surface_HF_Visc[val_marker]; } - -inline su2double CIncNSSolver::GetSurface_MaxHF_Visc(unsigned short val_marker) { return Surface_MaxHF_Visc[val_marker]; } - -inline su2double CIncNSSolver::GetCL_Visc(unsigned short val_marker) { return CL_Visc[val_marker]; } - -inline su2double CIncNSSolver::GetCSF_Visc(unsigned short val_marker) { return CSF_Visc[val_marker]; } - -inline su2double CIncNSSolver::GetCD_Visc(unsigned short val_marker) { return CD_Visc[val_marker]; } - -inline su2double CIncNSSolver::GetAllBound_CL_Visc() { return AllBound_CL_Visc; } - -inline su2double CIncNSSolver::GetAllBound_CSF_Visc() { return AllBound_CSF_Visc; } - -inline su2double CIncNSSolver::GetAllBound_CD_Visc() { return AllBound_CD_Visc; } - -inline su2double CIncNSSolver::GetAllBound_CEff_Visc() { return AllBound_CEff_Visc; } - -inline su2double CIncNSSolver::GetAllBound_CMx_Visc() { return AllBound_CMx_Visc; } - -inline su2double CIncNSSolver::GetAllBound_CMy_Visc() { return AllBound_CMy_Visc; } - -inline su2double CIncNSSolver::GetAllBound_CMz_Visc() { return AllBound_CMz_Visc; } - -inline su2double CIncNSSolver::GetAllBound_CoPx_Visc() { return AllBound_CoPx_Visc; } - -inline su2double CIncNSSolver::GetAllBound_CoPy_Visc() { return AllBound_CoPy_Visc; } - -inline su2double CIncNSSolver::GetAllBound_CoPz_Visc() { return AllBound_CoPz_Visc; } - -inline su2double CIncNSSolver::GetAllBound_CFx_Visc() { return AllBound_CFx_Visc; } - -inline su2double CIncNSSolver::GetAllBound_CFy_Visc() { return AllBound_CFy_Visc; } - -inline su2double CIncNSSolver::GetAllBound_CFz_Visc() { return AllBound_CFz_Visc; } - -inline su2double CIncNSSolver::GetSurface_CL_Visc(unsigned short val_marker) { return Surface_CL_Visc[val_marker]; } - -inline su2double CIncNSSolver::GetSurface_CD_Visc(unsigned short val_marker) { return Surface_CD_Visc[val_marker]; } - -inline su2double CIncNSSolver::GetSurface_CSF_Visc(unsigned short val_marker) { return Surface_CSF_Visc[val_marker]; } - -inline su2double CIncNSSolver::GetSurface_CEff_Visc(unsigned short val_marker) { return Surface_CEff_Visc[val_marker]; } - -inline su2double CIncNSSolver::GetSurface_CFx_Visc(unsigned short val_marker) { return Surface_CFx_Visc[val_marker]; } - -inline su2double CIncNSSolver::GetSurface_CFy_Visc(unsigned short val_marker) { return Surface_CFy_Visc[val_marker]; } - -inline su2double CIncNSSolver::GetSurface_CFz_Visc(unsigned short val_marker) { return Surface_CFz_Visc[val_marker]; } - -inline su2double CIncNSSolver::GetSurface_CMx_Visc(unsigned short val_marker) { return Surface_CMx_Visc[val_marker]; } - -inline su2double CIncNSSolver::GetSurface_CMy_Visc(unsigned short val_marker) { return Surface_CMy_Visc[val_marker]; } - -inline su2double CIncNSSolver::GetSurface_CMz_Visc(unsigned short val_marker) { return Surface_CMz_Visc[val_marker]; } - -inline su2double CIncNSSolver::GetCSkinFriction(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim) { return CSkinFriction[val_marker][val_dim][val_vertex]; } - -inline su2double CIncNSSolver::GetHeatFlux(unsigned short val_marker, unsigned long val_vertex) { return HeatFlux[val_marker][val_vertex]; } - -inline su2double CIncNSSolver::GetHeatFluxTarget(unsigned short val_marker, unsigned long val_vertex) { return HeatFluxTarget[val_marker][val_vertex]; } - -inline void CIncNSSolver::SetHeatFluxTarget(unsigned short val_marker, unsigned long val_vertex, su2double val_heat) { HeatFluxTarget[val_marker][val_vertex] = val_heat; } - -inline su2double CIncNSSolver::GetYPlus(unsigned short val_marker, unsigned long val_vertex) { return YPlus[val_marker][val_vertex]; } - -inline su2double CIncNSSolver::GetStrainMag_Max(void) { return StrainMag_Max; } - -inline su2double CIncNSSolver::GetOmega_Max(void) { return Omega_Max; } - -inline void CIncNSSolver::SetStrainMag_Max(su2double val_strainmag_max) { StrainMag_Max = val_strainmag_max; } - -inline void CIncNSSolver::SetOmega_Max(su2double val_omega_max) { Omega_Max = val_omega_max; } - -inline su2double CIncNSSolver::GetConjugateHeatVariable(unsigned short val_marker, unsigned long val_vertex, unsigned short pos_var) { return HeatConjugateVar[val_marker][val_vertex][pos_var]; } - -inline void CIncNSSolver::SetConjugateHeatVariable(unsigned short val_marker, unsigned long val_vertex, unsigned short pos_var, su2double relaxation_factor, su2double val_var) { - HeatConjugateVar[val_marker][val_vertex][pos_var] = relaxation_factor*val_var + (1.0-relaxation_factor)*HeatConjugateVar[val_marker][val_vertex][pos_var]; } - -inline su2double CHeatSolverFVM::GetTotal_HeatFlux() { return Total_HeatFlux; } - -inline su2double CHeatSolverFVM::GetHeatFlux(unsigned short val_marker, unsigned long val_vertex) { return HeatFlux[val_marker][val_vertex]; } - -inline su2double CHeatSolverFVM::GetTotal_AvgTemperature() { return Total_AverageT; } - -inline su2double CHeatSolverFVM::GetConjugateHeatVariable(unsigned short val_marker, unsigned long val_vertex, unsigned short pos_var) { return ConjugateVar[val_marker][val_vertex][pos_var]; } - -inline void CHeatSolverFVM::SetConjugateHeatVariable(unsigned short val_marker, unsigned long val_vertex, unsigned short pos_var, su2double relaxation_factor, su2double val_var) { - ConjugateVar[val_marker][val_vertex][pos_var] = relaxation_factor*val_var + (1.0-relaxation_factor)*ConjugateVar[val_marker][val_vertex][pos_var]; } - -inline void CSolver::SetAdjoint_OutputMesh(CGeometry *geometry, CConfig *config) {} - -inline void CSolver::ExtractAdjoint_Geometry(CGeometry *geometry, CConfig *config) {} - -inline void CSolver::ExtractAdjoint_CrossTerm(CGeometry *geometry, CConfig *config) {} - -inline void CSolver::ExtractAdjoint_CrossTerm_Geometry(CGeometry *geometry, CConfig *config) {} - -inline void CSolver::ExtractAdjoint_CrossTerm_Geometry_Flow(CGeometry *geometry, CConfig *config) {} - -inline void CSolver::SetMesh_Recording(CGeometry **geometry, CVolumetricMovement *grid_movement, CConfig *config) {} - -inline su2double CDiscAdjSolver::GetTotal_Sens_Geo() { return Total_Sens_Geo; } - -inline su2double CDiscAdjSolver::GetTotal_Sens_Mach() { return Total_Sens_Mach; } - -inline su2double CDiscAdjSolver::GetTotal_Sens_AoA() { return Total_Sens_AoA; } - -inline su2double CDiscAdjSolver::GetTotal_Sens_Press() { return Total_Sens_Press; } - -inline su2double CDiscAdjSolver::GetTotal_Sens_Temp() { return Total_Sens_Temp; } - -inline su2double CDiscAdjSolver::GetTotal_Sens_BPress() { return Total_Sens_BPress; } - -inline su2double CDiscAdjSolver::GetTotal_Sens_Density() { return Total_Sens_Density; } - -inline su2double CDiscAdjSolver::GetTotal_Sens_ModVel() { return Total_Sens_ModVel; } - -inline su2double CDiscAdjSolver::GetCSensitivity(unsigned short val_marker, unsigned long val_vertex) { return CSensitivity[val_marker][val_vertex]; } - -inline void CEulerSolver::SetSlidingState(unsigned short val_marker, unsigned long val_vertex, unsigned short val_state, unsigned long donor_index, su2double component){ - SlidingState[val_marker][val_vertex][val_state][donor_index] = component; -} - -inline void CIncEulerSolver::SetSlidingState(unsigned short val_marker, unsigned long val_vertex, unsigned short val_state, unsigned long donor_index, su2double component){ - SlidingState[val_marker][val_vertex][val_state][donor_index] = component; -} - -inline void CSolver::SetSlidingState(unsigned short val_marker, unsigned long val_vertex, unsigned short val_state, unsigned long donor_index, su2double component){ } - -inline su2double CEulerSolver::GetSlidingState(unsigned short val_marker, unsigned long val_vertex, unsigned short val_state, unsigned long donor_index) { return SlidingState[val_marker][val_vertex][val_state][donor_index]; } - -inline su2double CIncEulerSolver::GetSlidingState(unsigned short val_marker, unsigned long val_vertex, unsigned short val_state, unsigned long donor_index) { return SlidingState[val_marker][val_vertex][val_state][donor_index]; } - -inline su2double CSolver::GetSlidingState(unsigned short val_marker, unsigned long val_vertex, unsigned short val_state, unsigned long donor_index) { return 0; } - -inline int CEulerSolver::GetnSlidingStates(unsigned short val_marker, unsigned long val_vertex){ return SlidingStateNodes[val_marker][val_vertex]; } - -inline int CIncEulerSolver::GetnSlidingStates(unsigned short val_marker, unsigned long val_vertex){ return SlidingStateNodes[val_marker][val_vertex]; } - -inline int CSolver::GetnSlidingStates(unsigned short val_marker, unsigned long val_vertex){ return 0; } - -inline void CEulerSolver::SetnSlidingStates(unsigned short val_marker, unsigned long val_vertex, int value){ SlidingStateNodes[val_marker][val_vertex] = value; } - -inline void CIncEulerSolver::SetnSlidingStates(unsigned short val_marker, unsigned long val_vertex, int value){ SlidingStateNodes[val_marker][val_vertex] = value; } - -inline void CSolver::SetnSlidingStates(unsigned short val_marker, unsigned long val_vertex, int value){} - -inline void CSolver::SetSlidingStateStructure(unsigned short val_marker, unsigned long val_vertex){} - -inline void CEulerSolver::SetSlidingStateStructure(unsigned short val_marker, unsigned long val_vertex){ - int iVar; - - for( iVar = 0; iVar < nPrimVar+1; iVar++){ - if( SlidingState[val_marker][val_vertex][iVar] != NULL ) - delete [] SlidingState[val_marker][val_vertex][iVar]; - } - - for( iVar = 0; iVar < nPrimVar+1; iVar++) - SlidingState[val_marker][val_vertex][iVar] = new su2double[ GetnSlidingStates(val_marker, val_vertex) ]; -} - - -inline void CIncEulerSolver::SetSlidingStateStructure(unsigned short val_marker, unsigned long val_vertex){ - int iVar; - - for( iVar = 0; iVar < nPrimVar+1; iVar++){ - if( SlidingState[val_marker][val_vertex][iVar] != NULL ) - delete [] SlidingState[val_marker][val_vertex][iVar]; - } - - for( iVar = 0; iVar < nPrimVar+1; iVar++) - SlidingState[val_marker][val_vertex][iVar] = new su2double[ GetnSlidingStates(val_marker, val_vertex) ]; -} - - - -inline void CTurbSolver::SetSlidingState(unsigned short val_marker, unsigned long val_vertex, unsigned short val_state, unsigned long donor_index, su2double component){ - SlidingState[val_marker][val_vertex][val_state][donor_index] = component; -} - -inline int CTurbSolver::GetnSlidingStates(unsigned short val_marker, unsigned long val_vertex){ return SlidingStateNodes[val_marker][val_vertex]; } - -inline void CTurbSolver::SetSlidingStateStructure(unsigned short val_marker, unsigned long val_vertex){ - int iVar; - - for( iVar = 0; iVar < nVar+1; iVar++){ - if( SlidingState[val_marker][val_vertex][iVar] != NULL ) - delete [] SlidingState[val_marker][val_vertex][iVar]; - } - - for( iVar = 0; iVar < nVar+1; iVar++) - SlidingState[val_marker][val_vertex][iVar] = new su2double[ GetnSlidingStates(val_marker, val_vertex) ]; -} - -inline void CTurbSolver::SetnSlidingStates(unsigned short val_marker, unsigned long val_vertex, int value){ SlidingStateNodes[val_marker][val_vertex] = value; } - -inline su2double CTurbSolver::GetSlidingState(unsigned short val_marker, unsigned long val_vertex, unsigned short val_state, unsigned long donor_index) { return SlidingState[val_marker][val_vertex][val_state][donor_index]; } - -inline void CTurbSolver::SetInlet_TurbVar(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim, su2double val_turb_var) { - /*--- Since this call can be accessed indirectly using python, do some error - * checking to prevent segmentation faults ---*/ - if (val_marker >= nMarker) - SU2_MPI::Error("Out-of-bounds marker index used on inlet.", CURRENT_FUNCTION); - else if (Inlet_TurbVars == NULL || Inlet_TurbVars[val_marker] == NULL) - SU2_MPI::Error("Tried to set custom inlet BC on an invalid marker.", CURRENT_FUNCTION); - else if (val_vertex >= nVertex[val_marker]) - SU2_MPI::Error("Out-of-bounds vertex index used on inlet.", CURRENT_FUNCTION); - else if (val_dim >= nVar) - SU2_MPI::Error("Out-of-bounds index used for inlet turbulence variable.", CURRENT_FUNCTION); - else - Inlet_TurbVars[val_marker][val_vertex][val_dim] = val_turb_var; -} - -inline void CTurbSASolver::SetFreeStream_Solution(CConfig *config) { - for (unsigned long iPoint = 0; iPoint < nPoint; iPoint++) nodes->SetSolution(iPoint, 0, nu_tilde_Inf); -} - -inline su2double CTurbSASolver::GetNuTilde_Inf(void) { return nu_tilde_Inf; } - -inline void CTurbSSTSolver::SetFreeStream_Solution(CConfig *config){ - for (unsigned long iPoint = 0; iPoint < nPoint; iPoint++){ - nodes->SetSolution(iPoint, 0, kine_Inf); - nodes->SetSolution(iPoint, 1, omega_Inf); - } -} - -inline su2double CTurbSSTSolver::GetTke_Inf(void) { return kine_Inf; } - -inline su2double CTurbSSTSolver::GetOmega_Inf(void) { return omega_Inf; } - -inline su2double CDiscAdjFEASolver::GetTotal_Sens_E(unsigned short iVal) { return Total_Sens_E[iVal]; } - -inline su2double CDiscAdjFEASolver::GetTotal_Sens_Nu(unsigned short iVal) { return Total_Sens_Nu[iVal]; } - -inline su2double CDiscAdjFEASolver::GetTotal_Sens_Rho(unsigned short iVal) { return Total_Sens_Rho[iVal]; } - -inline su2double CDiscAdjFEASolver::GetTotal_Sens_Rho_DL(unsigned short iVal) { return Total_Sens_Rho_DL[iVal]; } - -inline su2double CDiscAdjFEASolver::GetTotal_Sens_EField(unsigned short iEField) { return Total_Sens_EField[iEField]; } - -inline su2double CDiscAdjFEASolver::GetTotal_Sens_DVFEA(unsigned short iDVFEA) { return Total_Sens_DV[iDVFEA]; } - -inline su2double CDiscAdjFEASolver::GetGlobal_Sens_E(unsigned short iVal) { return Global_Sens_E[iVal]; } - -inline su2double CDiscAdjFEASolver::GetGlobal_Sens_Nu(unsigned short iVal) { return Global_Sens_Nu[iVal]; } - -inline su2double CDiscAdjFEASolver::GetGlobal_Sens_Rho(unsigned short iVal) { return Global_Sens_Rho[iVal]; } - -inline su2double CDiscAdjFEASolver::GetGlobal_Sens_Rho_DL(unsigned short iVal) { return Global_Sens_Rho_DL[iVal]; } - -inline su2double CDiscAdjFEASolver::GetGlobal_Sens_EField(unsigned short iEField) { return Global_Sens_EField[iEField]; } - -inline su2double CDiscAdjFEASolver::GetGlobal_Sens_DVFEA(unsigned short iDVFEA) { return Global_Sens_DV[iDVFEA]; } - -inline su2double CDiscAdjFEASolver::GetVal_Young(unsigned short iVal) { return E_i[iVal]; } - -inline su2double CDiscAdjFEASolver::GetVal_Poisson(unsigned short iVal) { return Nu_i[iVal]; } - -inline su2double CDiscAdjFEASolver::GetVal_Rho(unsigned short iVal) { return Rho_i[iVal]; } - -inline su2double CDiscAdjFEASolver::GetVal_Rho_DL(unsigned short iVal) { return Rho_DL_i[iVal]; } - -inline unsigned short CDiscAdjFEASolver::GetnEField(void) { return nEField; } - -inline unsigned short CDiscAdjFEASolver::GetnDVFEA(void) { return nDV; } - -inline su2double CDiscAdjFEASolver::GetVal_EField(unsigned short iVal) { return EField[iVal]; } - -inline su2double CDiscAdjFEASolver::GetVal_DVFEA(unsigned short iVal) { return DV_Val[iVal]; } - -inline void CSolver::SetDualTime_Mesh(void){ } - -inline vector CSolver::GetSolutionFields(){return fields;} diff --git a/SU2_CFD/include/solvers/CAdjEulerSolver.hpp b/SU2_CFD/include/solvers/CAdjEulerSolver.hpp new file mode 100644 index 000000000000..e6f8523d5216 --- /dev/null +++ b/SU2_CFD/include/solvers/CAdjEulerSolver.hpp @@ -0,0 +1,713 @@ +/*! + * \file CAdjEulerSolver.hpp + * \brief Headers of the CAdjEulerSolver class + * \author F. Palacios + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#pragma once + +#include "CSolver.hpp" +#include "../variables/CAdjEulerVariable.hpp" + +/*! + * \class CAdjEulerSolver + * \brief Main class for defining the Euler's adjoint flow solver. + * \ingroup Euler_Equations + * \author F. Palacios + */ +class CAdjEulerSolver : public CSolver { +protected: + su2double + PsiRho_Inf, /*!< \brief PsiRho variable at the infinity. */ + PsiE_Inf, /*!< \brief PsiE variable at the infinity. */ + *Phi_Inf; /*!< \brief Phi vector at the infinity. */ + su2double + *Sens_Mach, /*!< \brief Mach sensitivity coefficient for each boundary. */ + *Sens_AoA, /*!< \brief Angle of attack sensitivity coefficient for each boundary. */ + *Sens_Geo, /*!< \brief Shape sensitivity coefficient for each boundary. */ + *Sens_Press, /*!< \brief Pressure sensitivity coefficient for each boundary. */ + *Sens_Temp, /*!< \brief Temperature sensitivity coefficient for each boundary. */ + *Sens_BPress, /*!< \brief Back pressure sensitivity coefficient for each boundary. */ + **CSensitivity, /*!< \brief Shape sensitivity coefficient for each boundary and vertex. */ + ***DonorAdjVar; /*!< \brief Value of the donor variables at each boundary. */ + su2double Total_Sens_Mach; /*!< \brief Total mach sensitivity coefficient for all the boundaries. */ + su2double Total_Sens_AoA; /*!< \brief Total angle of attack sensitivity coefficient for all the boundaries. */ + su2double Total_Sens_Geo; /*!< \brief Total shape sensitivity coefficient for all the boundaries. */ + su2double Total_Sens_Press; /*!< \brief Total farfield sensitivity to pressure. */ + su2double Total_Sens_Temp; /*!< \brief Total farfield sensitivity to temperature. */ + su2double Total_Sens_BPress; /*!< \brief Total sensitivity to back pressure. */ + bool space_centered; /*!< \brief True if space centered scheeme used. */ + su2double **Jacobian_Axisymmetric; /*!< \brief Storage for axisymmetric Jacobian. */ + su2double Gamma; /*!< \brief Fluid's Gamma constant (ratio of specific heats). */ + su2double Gamma_Minus_One; /*!< \brief Fluids's Gamma - 1.0 . */ + su2double *FlowPrimVar_i, /*!< \brief Store the flow solution at point i. */ + *FlowPrimVar_j; /*!< \brief Store the flow solution at point j. */ + unsigned long **DonorGlobalIndex; /*!< \brief Value of the donor global index. */ + + su2double pnorm, + Area_Monitored; /*!< \brief Store the total area of the monitored outflow surface (used for normalization in continuous adjoint outflow conditions) */ + + su2double ACoeff, ACoeff_inc, ACoeff_old; + bool Update_ACoeff; + + CAdjEulerVariable* nodes = nullptr; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ + + /*! + * \brief Return nodes to allow CSolver::base_nodes to be set. + */ + inline CVariable* GetBaseClassPointerToNodes() override { return nodes; } + +public: + + /*! + * \brief Constructor of the class. + */ + CAdjEulerSolver(void); + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + CAdjEulerSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); + + /*! + * \brief Destructor of the class. + */ + virtual ~CAdjEulerSolver(void); + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] Iteration - Index of the current iteration. + */ + void SetTime_Step(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned long Iteration) override; + + /*! + * \brief Parallelization of Undivided Laplacian. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Set_MPI_Nearfield(CGeometry *geometry, CConfig *config) final; + + /*! + * \brief Parallelization of Undivided Laplacian. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Set_MPI_ActDisk(CSolver **solver_container, CGeometry *geometry, CConfig *config) final; + + /*! + * \brief Created the force projection vector for adjoint boundary conditions. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void SetForceProj_Vector(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) final; + + /*! + * \brief Compute the jump for the interior boundary problem. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void SetIntBoundary_Jump(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) final; + + /*! + * \brief Compute adjoint density at the infinity. + * \return Value of the adjoint density at the infinity. + */ + inline su2double GetPsiRho_Inf(void) const final { return PsiRho_Inf; } + + /*! + * \brief Compute the adjoint energy at the infinity. + * \return Value of the adjoint energy at the infinity. + */ + inline su2double GetPsiE_Inf(void) const final { return PsiE_Inf; } + + /*! + * \brief Compute Phi (adjoint velocity) at the infinity. + * \param[in] val_dim - Index of the adjoint velocity vector. + * \return Value of the adjoint velocity vector at the infinity. + */ + inline su2double GetPhi_Inf(unsigned short val_dim) const final { return Phi_Inf[val_dim]; } + + /*! + * \brief Compute the spatial integration using a centered scheme for the adjoint equations. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + void Centered_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep) final; + + /*! + * \brief Compute the spatial integration using a upwind scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Upwind_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh) final; + + /*! + * \brief Source term integration. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] second_numerics - Description of the second numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Source_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CNumerics *second_numerics, + CConfig *config, unsigned short iMesh) override; + + /*! + * \brief Source term integration. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Source_Template(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh) final; + + /*! + * \brief Compute the undivided laplacian for the adjoint solution. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void SetUndivided_Laplacian(CGeometry *geometry, CConfig *config) final; + + /*! + * \brief Value of the characteristic variables at the boundaries. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline su2double *GetDonorAdjVar(unsigned short val_marker, unsigned long val_vertex) const final { + return DonorAdjVar[val_marker][val_vertex]; + } + + /*! + * \brief Value of the characteristic variables at the boundaries. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline void SetDonorAdjVar(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_var, + su2double val_value) final { + DonorAdjVar[val_marker][val_vertex][val_var] = val_value; + } + + /*! + * \brief Value of the characteristic variables at the boundaries. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline su2double GetDonorAdjVar(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_var) const final { + return DonorAdjVar[val_marker][val_vertex][val_var]; + } + + /*! + * \brief Value of the characteristic global index at the boundaries. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline unsigned long GetDonorGlobalIndex(unsigned short val_marker, unsigned long val_vertex) const final { return DonorGlobalIndex[val_marker][val_vertex]; } + + /*! + * \brief Value of the characteristic global index at the boundaries. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline void SetDonorGlobalIndex(unsigned short val_marker, + unsigned long val_vertex, + unsigned long val_index) final { + DonorGlobalIndex[val_marker][val_vertex] = val_index; + } + + /*! + * \brief Compute the sensor for higher order dissipation control in rotating problems. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void SetCentered_Dissipation_Sensor(CGeometry *geometry, CConfig *config) final; + + /*! + * \brief Update the AoA and freestream velocity at the farfield. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - current mesh level for the multigrid. + * \param[in] Output - boolean to determine whether to print output. + */ + void SetFarfield_AoA(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + bool Output) final; + + /*! + * \brief Impose via the residual the adjoint Euler wall boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Euler_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the interface boundary condition using the residual. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Interface_Boundary(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose the near-field boundary condition using the residual. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_NearField_Boundary(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose an actuator disk inlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_ActDisk_Inlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose an actuator disk outlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_ActDisk_Outlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose an actuator disk inlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + * \param[in] val_inlet_surface - Boolean for whether val_marker is an inlet + */ + void BC_ActDisk(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker, + bool val_inlet_surface) final; + + /*! + * \brief Impose via the residual the adjoint symmetry boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Sym_Plane(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose the boundary condition to the far field using characteristics. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Far_Field(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose the inlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Inlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + + /*! + * \brief Impose the supersonic inlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] solver - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Supersonic_Inlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose the supersonic outlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] solver - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Supersonic_Outlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose the outlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Outlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + + /*! + * \brief Impose the engine inflow adjoint boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Engine_Inflow(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose the engine exhaust boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Engine_Exhaust(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Update the solution using a Runge-Kutta strategy. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + void ExplicitRK_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iRKStep) final; + + /*! + * \brief Update the solution using a explicit Euler scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void ExplicitEuler_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) final; + + /*! + * \brief Update the solution using an implicit solver. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void ImplicitEuler_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) final; + + /*! + * \brief Initialize the residual vectors. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + * \param[in] Output - boolean to determine whether to print output. + */ + void Preprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep, + unsigned short RunTime_EqSystem, + bool Output) override; + + /*! + * \brief Compute the inviscid sensitivity of the functional. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + void Inviscid_Sensitivity(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config) final; + + /*! + * \brief Smooth the inviscid sensitivity of the functional. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + void Smooth_Sensitivity(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config) final; + + /*! + * \brief Get the shape sensitivity coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the sensitivity coefficient. + */ + inline su2double GetCSensitivity(unsigned short val_marker, + unsigned long val_vertex) const final{ + return CSensitivity[val_marker][val_vertex]; + } + + /*! + * \brief Set the shape sensitivity coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \param[in] val_sensitivity - Value of the sensitivity coefficient. + */ + inline void SetCSensitivity(unsigned short val_marker, + unsigned long val_vertex, + su2double val_sensitivity) final { + CSensitivity[val_marker][val_vertex] = val_sensitivity; + } + + /*! + * \brief Provide the total shape sensitivity coefficient. + * \return Value of the geometrical sensitivity coefficient + * (inviscid + viscous contribution). + */ + inline su2double GetTotal_Sens_Geo() const final { return Total_Sens_Geo; } + + /*! + * \brief Set the total Mach number sensitivity coefficient. + * \return Value of the Mach sensitivity coefficient + * (inviscid + viscous contribution). + */ + inline su2double GetTotal_Sens_Mach() const final { return Total_Sens_Mach; } + + /*! + * \brief Set the total angle of attack sensitivity coefficient. + * \return Value of the angle of attack sensitivity coefficient + * (inviscid + viscous contribution). + */ + inline su2double GetTotal_Sens_AoA() const final { return Total_Sens_AoA; } + + /*! + * \brief Set the total farfield pressure sensitivity coefficient. + * \return Value of the farfield pressure sensitivity coefficient + * (inviscid + viscous contribution). + */ + inline su2double GetTotal_Sens_Press() const final { return Total_Sens_Press; } + + /*! + * \brief Set the total farfield temperature sensitivity coefficient. + * \return Value of the farfield temperature sensitivity coefficient + * (inviscid + viscous contribution). + */ + inline su2double GetTotal_Sens_Temp() const final { return Total_Sens_Temp; } + + /*! + * \author H. Kline + * \brief Get the total Back pressure number sensitivity coefficient. + * \return Value of the Back sensitivity coefficient + * (inviscid + viscous contribution). + */ + inline su2double GetTotal_Sens_BPress() const final { return Total_Sens_BPress; } + + /*! + * \brief Set the total residual adding the term that comes from the Dual Time Strategy. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + */ + void SetResidual_DualTime(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iRKStep, + unsigned short iMesh, + unsigned short RunTime_EqSystem) final; + + /*! + * \brief Set the initial condition for the Euler Equations. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] ExtIter - External iteration. + */ + void SetInitialCondition(CGeometry **geometry, + CSolver ***solver_container, + CConfig *config, + unsigned long TimeIter) final; + + /*! + * \brief Load a solution from a restart file. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Container vector with all of the solvers. + * \param[in] config - Definition of the particular problem. + * \param[in] val_iter - Current external iteration number. + * \param[in] val_update_geo - Flag for updating coords and grid velocity. + */ + void LoadRestart(CGeometry **geometry, + CSolver ***solver, + CConfig *config, + int val_iter, + bool val_update_geo) final; + +}; \ No newline at end of file diff --git a/SU2_CFD/include/solvers/CAdjNSSolver.hpp b/SU2_CFD/include/solvers/CAdjNSSolver.hpp new file mode 100644 index 000000000000..489e7c130fd9 --- /dev/null +++ b/SU2_CFD/include/solvers/CAdjNSSolver.hpp @@ -0,0 +1,166 @@ +/*! + * \file CAdjNSSolver.hpp + * \brief Headers of the CAdjNSSolver class + * \author F. Palacios + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#pragma once + +#include "CAdjEulerSolver.hpp" + +/*! + * \class CAdjNSSolver + * \brief Main class for defining the Navier-Stokes' adjoint flow solver. + * \ingroup Navier_Stokes_Equations + * \author F. Palacios + */ +class CAdjNSSolver final : public CAdjEulerSolver { +public: + + /*! + * \brief Constructor of the class. + */ + CAdjNSSolver(void); + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + CAdjNSSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); + + /*! + * \brief Destructor of the class. + */ + ~CAdjNSSolver(void); + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] Iteration - Index of the current iteration. + */ + void SetTime_Step(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned long Iteration) override; + + + /*! + * \brief Impose via the residual or brute force the Navier-Stokes adjoint boundary condition (heat flux). + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_HeatFlux_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose via the residual or brute force the Navier-Stokes adjoint boundary condition (heat flux). + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Isothermal_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Restart residual and compute gradients. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + * \param[in] Output - boolean to determine whether to print output. + */ + void Preprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep, + unsigned short RunTime_EqSystem, + bool Output) override; + + /*! + * \brief Compute the viscous sensitivity of the functional. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + void Viscous_Sensitivity(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config) override; + + /*! + * \brief Compute the viscous residuals for the adjoint equation. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + void Viscous_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep) override; + + /*! + * \brief Source term computation. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] second_numerics - Description of the second numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Source_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CNumerics *second_numerics, + CConfig *config, unsigned short iMesh) override; + +}; \ No newline at end of file diff --git a/SU2_CFD/include/solvers/CAdjTurbSolver.hpp b/SU2_CFD/include/solvers/CAdjTurbSolver.hpp new file mode 100644 index 000000000000..9105a8aebe81 --- /dev/null +++ b/SU2_CFD/include/solvers/CAdjTurbSolver.hpp @@ -0,0 +1,193 @@ +/*! + * \file CAdjTurbSolver.hpp + * \brief Headers of the CAdjTurbSolver class + * \author F. Palacios, A. Bueno. + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#pragma once + +#include "CSolver.hpp" +#include "../variables/CAdjTurbVariable.hpp" + +/*! + * \class CAdjTurbSolver + * \brief Main class for defining the adjoint turbulence model solver. + * \ingroup Turbulence_Model + * \author F. Palacios, A. Bueno. + */ +class CAdjTurbSolver final : public CSolver { +private: + su2double PsiNu_Inf, /*!< \brief PsiNu variable at the infinity. */ + *FlowSolution_i, /*!< \brief Store the flow solution at point i. */ + *FlowSolution_j; /*!< \brief Store the flow solution at point j. */ + + su2double Gamma; /*!< \brief Fluid's Gamma constant (ratio of specific heats). */ + su2double Gamma_Minus_One; /*!< \brief Fluids's Gamma - 1.0 . */ + + CAdjTurbVariable* nodes = nullptr; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ + + /*! + * \brief Return nodes to allow CSolver::base_nodes to be set. + */ + inline CVariable* GetBaseClassPointerToNodes() override { return nodes; } + +public: + + /*! + * \brief Default constructor of the class. + */ + CAdjTurbSolver(void); + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + CAdjTurbSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); + + /*! + * \brief Default destructor of the class. + */ + virtual ~CAdjTurbSolver(void); + + /*! + * \brief Impose the Navier-Stokes turbulent adjoint boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_HeatFlux_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + /*! + * \brief Impose an isothermal wall boundary condition (no-slip). + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Isothermal_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the boundary condition to the far field using characteristics. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Far_Field(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Initializate the residual vectors. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + * \param[in] Output - boolean to determine whether to print output. + */ + void Preprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep, + unsigned short RunTime_EqSystem, + bool Output) override; + + /*! + * \brief Compute the spatial integration using a upwind scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Upwind_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh) override; + + /*! + * \brief Compute the viscous residuals for the turbulent adjoint equation. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + void Viscous_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep) override; + + /*! + * \brief Source term computation. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] second_numerics - Description of the second numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Source_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CNumerics *second_numerics, + CConfig *config, unsigned short iMesh) override; + + /*! + * \brief Update the solution using an implicit solver. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void ImplicitEuler_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) override; + +}; diff --git a/SU2_CFD/include/solvers/CBaselineSolver.hpp b/SU2_CFD/include/solvers/CBaselineSolver.hpp new file mode 100644 index 000000000000..90dfbd02c53d --- /dev/null +++ b/SU2_CFD/include/solvers/CBaselineSolver.hpp @@ -0,0 +1,103 @@ +/*! + * \file CBaslineSolver.hpp + * \brief Headers of the CBaselineSolver class + * \author F. Palacios, T. Economon + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#include "CSolver.hpp" +#include "../variables/CBaselineVariable.hpp" + +/*! + * \class CBaselineSolver + * \brief Main class for defining a baseline solution from a restart file (for output). + * \author F. Palacios, T. Economon. + */ +class CBaselineSolver final : public CSolver { +protected: + + CBaselineVariable* nodes = nullptr; /*!< \brief Variables of the baseline solver. */ + + /*! + * \brief Return nodes to allow CSolver::base_nodes to be set. + */ + inline CVariable* GetBaseClassPointerToNodes() override { return nodes; } + +public: + + /*! + * \brief Constructor of the class. + */ + CBaselineSolver(void); + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + CBaselineSolver(CGeometry *geometry, CConfig *config); + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] nVar - Number of variables. + * \param[in] field_names - Vector of variable names. + */ + CBaselineSolver(CGeometry *geometry, CConfig *config, unsigned short val_nvar, vector field_names); + + /*! + * \brief Destructor of the class. + */ + virtual ~CBaselineSolver(void); + + /*! + * \brief Load a solution from a restart file. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Container vector with all of the solvers. + * \param[in] config - Definition of the particular problem. + * \param[in] val_iter - Current external iteration number. + * \param[in] val_update_geo - Flag for updating coords and grid velocity. + */ + void LoadRestart(CGeometry **geometry, + CSolver ***solver, + CConfig *config, + int val_iter, + bool val_update_geo) override; + + /*! + * \brief Load a FSI solution from a restart file. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Container vector with all of the solvers. + * \param[in] config - Definition of the particular problem. + * \param[in] val_iter - Current external iteration number. + */ + void LoadRestart_FSI(CGeometry *geometry, CConfig *config, int val_iter) final; + + /*! + * \brief Set the number of variables and string names from the restart file. + * \param[in] config - Definition of the particular problem. + */ + void SetOutputVariables(CGeometry *geometry, CConfig *config); + +}; \ No newline at end of file diff --git a/SU2_CFD/include/solvers/CBaselineSolver_FEM.hpp b/SU2_CFD/include/solvers/CBaselineSolver_FEM.hpp new file mode 100644 index 000000000000..520e319b0324 --- /dev/null +++ b/SU2_CFD/include/solvers/CBaselineSolver_FEM.hpp @@ -0,0 +1,96 @@ +/*! + * \file CBaslineSolver_FEM.hpp + * \brief Headers of the CBaselineSolver class + * \author F. Palacios, T. Economon + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#include "CSolver.hpp" + +/*! + * \class CBaselineSolver_FEM + * \brief Main class for defining a baseline solution from a restart file for the DG-FEM solver output. + * \author T. Economon. + * \version 7.0.0 "Blackbird" + */ +class CBaselineSolver_FEM final : public CSolver { +protected: + + unsigned long nDOFsLocTot; /*!< \brief Total number of local DOFs, including halos. */ + unsigned long nDOFsLocOwned; /*!< \brief Number of owned local DOFs. */ + unsigned long nDOFsGlobal; /*!< \brief Number of global DOFs. */ + + unsigned long nVolElemTot; /*!< \brief Total number of local volume elements, including halos. */ + unsigned long nVolElemOwned; /*!< \brief Number of owned local volume elements. */ + CVolumeElementFEM *volElem; /*!< \brief Array of the local volume elements, including halos. */ + + vector VecSolDOFs; /*!< \brief Vector, which stores the solution variables in all the DOFs. */ + + CVariable* GetBaseClassPointerToNodes() override {return nullptr;} + +public: + + /*! + * \brief Constructor of the class. + */ + CBaselineSolver_FEM(void); + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + CBaselineSolver_FEM(CGeometry *geometry, CConfig *config); + + /*! + * \brief Destructor of the class. + */ + virtual ~CBaselineSolver_FEM(void); + + /*! + * \brief Set the number of variables and string names from the restart file. + * \param[in] config - Definition of the particular problem. + */ + void SetOutputVariables(CGeometry *geometry, CConfig *config); + + /*! + * \brief Load a solution from a restart file. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Container vector with all of the solvers. + * \param[in] config - Definition of the particular problem. + * \param[in] val_iter - Current external iteration number. + * \param[in] val_update_geo - Flag for updating coords and grid velocity. + */ + void LoadRestart(CGeometry **geometry, + CSolver ***solver, + CConfig *config, + int val_iter, + bool val_update_geo) override; + + /*! + * \brief Get a pointer to the vector of the solution degrees of freedom. + * \return Pointer to the vector of the solution degrees of freedom. + */ + inline su2double* GetVecSolDOFs(void) override { return VecSolDOFs.data(); } + +}; \ No newline at end of file diff --git a/SU2_CFD/include/solvers/CDiscAdjFEASolver.hpp b/SU2_CFD/include/solvers/CDiscAdjFEASolver.hpp new file mode 100644 index 000000000000..3466cbe9704d --- /dev/null +++ b/SU2_CFD/include/solvers/CDiscAdjFEASolver.hpp @@ -0,0 +1,398 @@ +/*! + * \file CDiscAdjFEASolver.hpp + * \brief Headers of the CDiscAdjFEASolver class + * \author R. Sanchez + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#pragma once + +#include "CSolver.hpp" +#include "../variables/CDiscAdjFEABoundVariable.hpp" + +/*! + * \class CDiscAdjFEASolver + * \brief Main class for defining the discrete adjoint solver for FE structural problems. + * \ingroup Discrete_Adjoint + * \author R. Sanchez + */ +class CDiscAdjFEASolver final : public CSolver { +private: + unsigned short KindDirect_Solver; + CSolver *direct_solver; + su2double *Sens_E, /*!< \brief Young modulus sensitivity coefficient for each boundary. */ + *Sens_Nu, /*!< \brief Poisson's ratio sensitivity coefficient for each boundary. */ + *Sens_nL, /*!< \brief Normal pressure sensitivity coefficient for each boundary. */ + **CSensitivity; /*!< \brief Shape sensitivity coefficient for each boundary and vertex. */ + + su2double *Solution_Vel, /*!< \brief Velocity componenent of the solution. */ + *Solution_Accel; /*!< \brief Acceleration componenent of the solution. */ + + su2double *SolRest; /*!< \brief Auxiliary vector to restart the solution */ + + su2double ObjFunc_Value; /*!< \brief Value of the objective function. */ + su2double *normalLoads; /*!< \brief Values of the normal loads for each marker iMarker_nL. */ + unsigned long nMarker_nL; /*!< \brief Total number of markers that have a normal load applied. */ + + unsigned short nMPROP; /*!< \brief Number of material properties */ + + su2double *E_i, /*!< \brief Values of the Young's Modulus. */ + *Nu_i, /*!< \brief Values of the Poisson's ratio. */ + *Rho_i, /*!< \brief Values of the density (for inertial effects). */ + *Rho_DL_i; /*!< \brief Values of the density (for volume loading). */ + int *AD_Idx_E_i, /*!< \brief Derivative index of the Young's Modulus. */ + *AD_Idx_Nu_i, /*!< \brief Derivative index of the Poisson's ratio. */ + *AD_Idx_Rho_i, /*!< \brief Derivative index of the density (for inertial effects). */ + *AD_Idx_Rho_DL_i; /*!< \brief Derivative index of the density (for volume loading). */ + + su2double *Local_Sens_E, /*!< \brief Local sensitivity of the Young's modulus. */ + *Global_Sens_E, /*!< \brief Global sensitivity of the Young's modulus. */ + *Total_Sens_E; /*!< \brief Total sensitivity of the Young's modulus (time domain). */ + su2double *Local_Sens_Nu, /*!< \brief Local sensitivity of the Poisson ratio. */ + *Global_Sens_Nu, /*!< \brief Global sensitivity of the Poisson ratio. */ + *Total_Sens_Nu; /*!< \brief Total sensitivity of the Poisson ratio (time domain). */ + su2double *Local_Sens_Rho, /*!< \brief Local sensitivity of the density. */ + *Global_Sens_Rho, /*!< \brief Global sensitivity of the density. */ + *Total_Sens_Rho; /*!< \brief Total sensitivity of the density (time domain). */ + su2double *Local_Sens_Rho_DL, /*!< \brief Local sensitivity of the volume load. */ + *Global_Sens_Rho_DL, /*!< \brief Global sensitivity of the volume load. */ + *Total_Sens_Rho_DL; /*!< \brief Total sensitivity of the volume load (time domain). */ + + bool de_effects; /*!< \brief Determines if DE effects are considered. */ + unsigned short nEField; /*!< \brief Number of electric field areas in the problem. */ + su2double *EField; /*!< \brief Array that stores the electric field as design variables. */ + int *AD_Idx_EField; /*!< \brief Derivative index of the electric field as design variables. */ + su2double *Local_Sens_EField, /*!< \brief Local sensitivity of the Electric Field. */ + *Global_Sens_EField, /*!< \brief Global sensitivity of the Electric Field. */ + *Total_Sens_EField; /*!< \brief Total sensitivity of the Electric Field (time domain). */ + + bool fea_dv; /*!< \brief Determines if the design variable we study is a FEA parameter. */ + unsigned short nDV; /*!< \brief Number of design variables in the problem. */ + su2double *DV_Val; /*!< \brief Values of the design variables. */ + int *AD_Idx_DV_Val; /*!< \brief Derivative index of the design variables. */ + su2double *Local_Sens_DV, /*!< \brief Local sensitivity of the design variables. */ + *Global_Sens_DV, /*!< \brief Global sensitivity of the design variables. */ + *Total_Sens_DV; /*!< \brief Total sensitivity of the design variables (time domain). */ + + CDiscAdjFEABoundVariable* nodes = nullptr; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ + + /*! + * \brief Return nodes to allow CSolver::base_nodes to be set. + */ + inline CVariable* GetBaseClassPointerToNodes() override { return nodes; } + +public: + + /*! + * \brief Constructor of the class. + */ + CDiscAdjFEASolver(void); + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + CDiscAdjFEASolver(CGeometry *geometry, CConfig *config); + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] solver - Initialize the discrete adjoint solver with the corresponding direct solver. + * \param[in] Kind_Solver - The kind of direct solver. + */ + CDiscAdjFEASolver(CGeometry *geometry, CConfig *config, CSolver* solver, unsigned short Kind_Solver, unsigned short iMesh); + + /*! + * \brief Destructor of the class. + */ + ~CDiscAdjFEASolver(void); + + /*! + * \brief Performs the preprocessing of the adjoint AD-based solver. + * Registers all necessary variables on the tape. Called while tape is active. + * \param[in] geometry_container - The geometry container holding all grid levels. + * \param[in] config_container - The particular config. + */ + void RegisterSolution(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief Performs the preprocessing of the adjoint AD-based solver. + * Registers all necessary variables that are output variables on the tape. + * Called while tape is active. + * \param[in] geometry_container - The geometry container holding all grid levels. + * \param[in] config_container - The particular config. + */ + void RegisterOutput(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief Sets the adjoint values of the output of the flow (+turb.) iteration + * before evaluation of the tape. + * \param[in] geometry - The geometrical definition of the problem. + * \param[in] config - The particular config. + */ + void SetAdjoint_Output(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief Sets the adjoint values of the input variables of the flow (+turb.) iteration + * after tape has been evaluated. + * \param[in] geometry - The geometrical definition of the problem. + * \param[in] config - The particular config. + */ + void ExtractAdjoint_Solution(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief Sets the adjoint values of the structural variables due to cross term contributions + * \param[in] geometry - The geometrical definition of the problem. + * \param[in] solver_container - The solver container holding all solutions. + * \param[in] config - The particular config. + */ + void ExtractAdjoint_CrossTerm(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief A virtual member. + * \param[in] geometry - The geometrical definition of the problem. + * \param[in] solver_container - The solver container holding all solutions. + * \param[in] config - The particular config. + */ + void ExtractAdjoint_CrossTerm_Geometry(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief Register the objective function as output. + * \param[in] geometry - The geometrical definition of the problem. + */ + void RegisterObj_Func(CConfig *config) override; + + /*! + * \brief Set the surface sensitivity. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void SetSurface_Sensitivity(CGeometry *geometry, CConfig* config) override; + + /*! + * \brief Extract and set the geometrical sensitivity. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - The solver container holding all terms of the solution. + * \param[in] config - Definition of the particular problem. + */ + void SetSensitivity(CGeometry *geometry, CSolver **solver, CConfig *config) override; + + /*! + * \brief Set the objective function. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void SetAdj_ObjFunc(CGeometry *geometry, CConfig* config) override; + + /*! + * \brief Provide the total Young's modulus sensitivity + * \return Value of the total Young's modulus sensitivity + * (inviscid + viscous contribution). + */ + inline su2double GetTotal_Sens_E(unsigned short iVal) const override { return Total_Sens_E[iVal]; } + + /*! + * \brief Set the total Poisson's ratio sensitivity. + * \return Value of the Poisson's ratio sensitivity + */ + inline su2double GetTotal_Sens_Nu(unsigned short iVal) const override { return Total_Sens_Nu[iVal]; } + + /*! + * \brief Get the total sensitivity for the structural density + * \return Value of the structural density sensitivity + */ + inline su2double GetTotal_Sens_Rho(unsigned short iVal) const override { return Total_Sens_Rho[iVal]; } + + /*! + * \brief Get the total sensitivity for the structural weight + * \return Value of the structural weight sensitivity + */ + inline su2double GetTotal_Sens_Rho_DL(unsigned short iVal) const override { return Total_Sens_Rho_DL[iVal]; } + + /*! + * \brief A virtual member. + * \return Value of the sensitivity coefficient for the Electric Field in the region iEField (time averaged) + */ + inline su2double GetTotal_Sens_EField(unsigned short iEField) const override { return Total_Sens_EField[iEField]; } + + /*! + * \brief A virtual member. + * \return Value of the total sensitivity coefficient for the FEA DV in the region iDVFEA (time averaged) + */ + inline su2double GetTotal_Sens_DVFEA(unsigned short iDVFEA) const override { return Total_Sens_DV[iDVFEA]; } + + /*! + * \brief A virtual member. + * \return Value of the sensitivity coefficient for the Young Modulus E + */ + inline su2double GetGlobal_Sens_E(unsigned short iVal) const override { return Global_Sens_E[iVal]; } + + /*! + * \brief A virtual member. + * \return Value of the Mach sensitivity for the Poisson's ratio Nu + */ + inline su2double GetGlobal_Sens_Nu(unsigned short iVal) const override { return Global_Sens_Nu[iVal]; } + + /*! + * \brief A virtual member. + * \return Value of the sensitivity coefficient for the Electric Field in the region iEField + */ + inline su2double GetGlobal_Sens_EField(unsigned short iEField) const override { return Global_Sens_EField[iEField]; } + + /*! + * \brief A virtual member. + * \return Value of the sensitivity coefficient for the FEA DV in the region iDVFEA + */ + inline su2double GetGlobal_Sens_DVFEA(unsigned short iDVFEA) const override { return Global_Sens_DV[iDVFEA]; } + + /*! + * \brief Get the total sensitivity for the structural density + * \return Value of the structural density sensitivity + */ + inline su2double GetGlobal_Sens_Rho(unsigned short iVal) const override { return Global_Sens_Rho[iVal]; } + + /*! + * \brief Get the total sensitivity for the structural weight + * \return Value of the structural weight sensitivity + */ + inline su2double GetGlobal_Sens_Rho_DL(unsigned short iVal) const override { return Global_Sens_Rho_DL[iVal]; } + + /*! + * \brief Get the value of the Young modulus from the adjoint solver + * \return Value of the Young modulus from the adjoint solver + */ + inline su2double GetVal_Young(unsigned short iVal) const override { return E_i[iVal]; } + + /*! + * \brief Get the value of the Poisson's ratio from the adjoint solver + * \return Value of the Poisson's ratio from the adjoint solver + */ + inline su2double GetVal_Poisson(unsigned short iVal) const override { return Nu_i[iVal]; } + + /*! + * \brief Get the value of the density from the adjoint solver, for inertial effects + * \return Value of the density from the adjoint solver + */ + inline su2double GetVal_Rho(unsigned short iVal) const override { return Rho_i[iVal]; } + + /*! + * \brief Get the value of the density from the adjoint solver, for dead loads + * \return Value of the density for dead loads, from the adjoint solver + */ + inline su2double GetVal_Rho_DL(unsigned short iVal) const override { return Rho_DL_i[iVal]; } + + /*! + * \brief Get the number of variables for the Electric Field from the adjoint solver + * \return Number of electric field variables from the adjoint solver + */ + inline unsigned short GetnEField(void) const override { return nEField; } + + /*! + * \brief Read the design variables for the adjoint solver + */ + void ReadDV(CConfig *config) override; + + /*! + * \brief Get the number of design variables from the adjoint solver, + * \return Number of design variables from the adjoint solver + */ + inline unsigned short GetnDVFEA(void) const override { return nDV; } + + /*! + * \brief Get the value of the Electric Field from the adjoint solver + * \return Pointer to the values of the Electric Field + */ + inline su2double GetVal_EField(unsigned short iVal) const override { return EField[iVal]; } + + /*! + * \brief Get the value of the design variables from the adjoint solver + * \return Pointer to the values of the design variables + */ + inline su2double GetVal_DVFEA(unsigned short iVal) const override { return DV_Val[iVal]; } + + /*! + * \brief Prepare the solver for a new recording. + * \param[in] kind_recording - Kind of AD recording. + */ + void SetRecording(CGeometry *geometry, CConfig *config) override ; + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] reset - If true reset variables to their initial values. + */ + void RegisterVariables(CGeometry *geometry, + CConfig *config, + bool reset = false) override; + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void ExtractAdjoint_Variables(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief Update the dual-time derivatives. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + * \param[in] Output - boolean to determine whether to print output. + */ + void Preprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep, + unsigned short RunTime_EqSystem, + bool Output) override; + + /*! + * \brief Load a solution from a restart file. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Container vector with all of the solvers. + * \param[in] config - Definition of the particular problem. + * \param[in] val_iter - Current external iteration number. + * \param[in] val_update_geo - Flag for updating coords and grid velocity. + */ + void LoadRestart(CGeometry **geometry, + CSolver ***solver, + CConfig *config, + int val_iter, + bool val_update_geo) override; + + /*! + * \brief Compute the multizone residual. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void ComputeResidual_Multizone(CGeometry *geometry, CConfig *config) override; + +}; \ No newline at end of file diff --git a/SU2_CFD/include/solvers/CDiscAdjMeshSolver.hpp b/SU2_CFD/include/solvers/CDiscAdjMeshSolver.hpp index 750b6c79fbc2..a2653fa41e83 100644 --- a/SU2_CFD/include/solvers/CDiscAdjMeshSolver.hpp +++ b/SU2_CFD/include/solvers/CDiscAdjMeshSolver.hpp @@ -7,7 +7,7 @@ * * SU2 Project Website: https://su2code.github.io * - * The SU2 Project is maintained by the SU2 Foundation + * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) @@ -28,7 +28,7 @@ #pragma once -#include "../solver_structure.hpp" +#include "CSolver.hpp" #include "../variables/CDiscAdjMeshBoundVariable.hpp" /*! @@ -37,7 +37,7 @@ * \ingroup Discrete_Adjoint * \author R. Sanchez */ -class CDiscAdjMeshSolver : public CSolver { +class CDiscAdjMeshSolver final : public CSolver { private: unsigned short KindDirect_Solver; CSolver *direct_solver; @@ -84,7 +84,7 @@ class CDiscAdjMeshSolver : public CSolver { * \param[in] geometry_container - The geometry container holding all grid levels. * \param[in] config_container - The particular config. */ - void RegisterSolution(CGeometry *geometry, CConfig *config); + void RegisterSolution(CGeometry *geometry, CConfig *config) override; /*! * \brief Sets the adjoint values of the input variables of the flow (+turb.) iteration @@ -92,7 +92,7 @@ class CDiscAdjMeshSolver : public CSolver { * \param[in] geometry - The geometrical definition of the problem. * \param[in] config - The particular config. */ - void ExtractAdjoint_Solution(CGeometry *geometry, CConfig *config); + void ExtractAdjoint_Solution(CGeometry *geometry, CConfig *config) override; /*! * \brief Extract and set the geometrical sensitivity. @@ -100,33 +100,36 @@ class CDiscAdjMeshSolver : public CSolver { * \param[in] solver - The solver container holding all terms of the solution. * \param[in] config - Definition of the particular problem. */ - void SetSensitivity(CGeometry *geometry, CSolver **solver, CConfig *config); + void SetSensitivity(CGeometry *geometry, CSolver **solver, CConfig *config) override; /*! * \brief Set the value of the max residual and RMS residual. * \param[in] val_iterlinsolver - Number of linear iterations. */ - void ComputeResidual_Multizone(CGeometry *geometry, CConfig *config); + void ComputeResidual_Multizone(CGeometry *geometry, CConfig *config) override; /*! * \brief Prepare the solver for a new recording. * \param[in] kind_recording - Kind of AD recording. */ - void SetRecording(CGeometry *geometry, CConfig *config); + void SetRecording(CGeometry *geometry, CConfig *config) override; /*! * \brief A virtual member. * \param[in] geometry - Geometrical definition of the problem. * \param[in] config - Definition of the particular problem. + * \param[in] reset - If true reset variables to their initial values. */ - void RegisterVariables(CGeometry *geometry, CConfig *config, bool reset = false); + void RegisterVariables(CGeometry *geometry, + CConfig *config, + bool reset = false) override; /*! * \brief A virtual member. * \param[in] geometry - Geometrical definition of the problem. * \param[in] config - Definition of the particular problem. */ - void ExtractAdjoint_Variables(CGeometry *geometry, CConfig *config); + void ExtractAdjoint_Variables(CGeometry *geometry, CConfig *config) override; /*! * \brief Update the dual-time derivatives. @@ -138,7 +141,13 @@ class CDiscAdjMeshSolver : public CSolver { * \param[in] RunTime_EqSystem - System of equations which is going to be solved. * \param[in] Output - boolean to determine whether to print output. */ - void Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output); + void Preprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep, + unsigned short RunTime_EqSystem, + bool Output) override; /*! * \brief Load a solution from a restart file. @@ -148,6 +157,10 @@ class CDiscAdjMeshSolver : public CSolver { * \param[in] val_iter - Current external iteration number. * \param[in] val_update_geo - Flag for updating coords and grid velocity. */ - void LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo); + void LoadRestart(CGeometry **geometry, + CSolver ***solver, + CConfig *config, + int val_iter, + bool val_update_geo) override; }; diff --git a/SU2_CFD/include/solvers/CDiscAdjSolver.hpp b/SU2_CFD/include/solvers/CDiscAdjSolver.hpp new file mode 100644 index 000000000000..f40243fd3bff --- /dev/null +++ b/SU2_CFD/include/solvers/CDiscAdjSolver.hpp @@ -0,0 +1,330 @@ +/*! + * \file CDiscAdjSolver.hpp + * \brief Headers of the CDiscAdjSolver class + * \author T. Albring + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#pragma once + +#include "CSolver.hpp" +#include "../variables/CDiscAdjVariable.hpp" + +/*! + * \class CDiscAdjSolver + * \brief Main class for defining the discrete adjoint solver. + * \ingroup Discrete_Adjoint + * \author T. Albring + */ +class CDiscAdjSolver final : public CSolver { +private: + unsigned short KindDirect_Solver; + CSolver *direct_solver; + su2double **CSensitivity; /*!< \brief Shape sensitivity coefficient for each boundary and vertex. */ + su2double Total_Sens_Mach; /*!< \brief Total mach sensitivity coefficient for all the boundaries. */ + su2double Total_Sens_AoA; /*!< \brief Total angle of attack sensitivity coefficient for all the boundaries. */ + su2double Total_Sens_Geo; /*!< \brief Total shape sensitivity coefficient for all the boundaries. */ + su2double Total_Sens_Press; /*!< \brief Total farfield sensitivity to pressure. */ + su2double Total_Sens_Temp; /*!< \brief Total farfield sensitivity to temperature. */ + su2double Total_Sens_BPress; /*!< \brief Total sensitivity to outlet pressure. */ + su2double Total_Sens_Density; /*!< \brief Total sensitivity to initial density (incompressible). */ + su2double Total_Sens_ModVel; /*!< \brief Total sensitivity to inlet velocity (incompressible). */ + su2double ObjFunc_Value; /*!< \brief Value of the objective function. */ + su2double Mach, Alpha, Beta, Pressure, Temperature, BPressure, ModVel; + + su2double *Solution_Geometry; /*!< \brief Auxiliary vector for the geometry solution (dimension nDim instead of nVar). */ + + CDiscAdjVariable* nodes = nullptr; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ + + /*! + * \brief Return nodes to allow CSolver::base_nodes to be set. + */ + inline CVariable* GetBaseClassPointerToNodes() override { return nodes; } + +public: + + /*! + * \brief Constructor of the class. + */ + CDiscAdjSolver(void); + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + CDiscAdjSolver(CGeometry *geometry, CConfig *config); + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] solver - Initialize the discrete adjoint solver with the corresponding direct solver. + * \param[in] Kind_Solver - The kind of direct solver. + */ + CDiscAdjSolver(CGeometry *geometry, CConfig *config, CSolver* solver, unsigned short Kind_Solver, unsigned short iMesh); + + /*! + * \brief Destructor of the class. + */ + ~CDiscAdjSolver(void); + + /*! + * \brief Performs the preprocessing of the adjoint AD-based solver. + * Registers all necessary variables on the tape. Called while tape is active. + * \param[in] geometry_container - The geometry container holding all grid levels. + * \param[in] config_container - The particular config. + */ + void RegisterSolution(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief Performs the preprocessing of the adjoint AD-based solver. + * Registers all necessary variables that are output variables on the tape. + * Called while tape is active. + * \param[in] geometry_container - The geometry container holding all grid levels. + * \param[in] config_container - The particular config. + */ + void RegisterOutput(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief Sets the adjoint values of the output of the flow (+turb.) iteration + * before evaluation of the tape. + * \param[in] geometry - The geometrical definition of the problem. + * \param[in] config - The particular config. + */ + void SetAdjoint_Output(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief Sets the adjoint values of the output of the mesh deformation iteration + * before evaluation of the tape. + * \param[in] geometry - The geometrical definition of the problem. + * \param[in] config - The particular config. + */ + void SetAdjoint_OutputMesh(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief Sets the adjoint values of the input variables of the flow (+turb.) iteration + * after tape has been evaluated. + * \param[in] geometry - The geometrical definition of the problem. + * \param[in] config - The particular config. + */ + void ExtractAdjoint_Solution(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief A virtual member. + * \param[in] geometry - The geometrical definition of the problem. + * \param[in] solver_container - The solver container holding all solutions. + * \param[in] config - The particular config. + */ + void ExtractAdjoint_Geometry(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief Sets the adjoint values of the flow variables due to cross term contributions + * \param[in] geometry - The geometrical definition of the problem. + * \param[in] solver_container - The solver container holding all solutions. + * \param[in] config - The particular config. + */ + void ExtractAdjoint_CrossTerm(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief A virtual member. + * \param[in] geometry - The geometrical definition of the problem. + * \param[in] solver_container - The solver container holding all solutions. + * \param[in] config - The particular config. + */ + void ExtractAdjoint_CrossTerm_Geometry(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief A virtual member. + * \param[in] geometry - The geometrical definition of the problem. + * \param[in] solver_container - The solver container holding all solutions. + * \param[in] config - The particular config. + */ + void ExtractAdjoint_CrossTerm_Geometry_Flow(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief Register the objective function as output. + * \param[in] geometry - The geometrical definition of the problem. + */ + void RegisterObj_Func(CConfig *config) override; + + /*! + * \brief Set the surface sensitivity. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void SetSurface_Sensitivity(CGeometry *geometry, CConfig* config) override; + + /*! + * \brief Extract and set the geometrical sensitivity. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - The solver container holding all terms of the solution. + * \param[in] config - Definition of the particular problem. + */ + void SetSensitivity(CGeometry *geometry, CSolver **solver, CConfig *config) override; + + /*! + * \brief Set the objective function. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void SetAdj_ObjFunc(CGeometry *geometry, CConfig* config) override; + + /*! + * \brief Provide the total shape sensitivity coefficient. + * \return Value of the geometrical sensitivity coefficient + * (inviscid + viscous contribution). + */ + inline su2double GetTotal_Sens_Geo() const override { return Total_Sens_Geo; } + + /*! + * \brief Set the total Mach number sensitivity coefficient. + * \return Value of the Mach sensitivity coefficient + * (inviscid + viscous contribution). + */ + inline su2double GetTotal_Sens_Mach() const override { return Total_Sens_Mach; } + + /*! + * \brief Set the total angle of attack sensitivity coefficient. + * \return Value of the angle of attack sensitivity coefficient + * (inviscid + viscous contribution). + */ + inline su2double GetTotal_Sens_AoA() const override { return Total_Sens_AoA; } + + /*! + * \brief Set the total farfield pressure sensitivity coefficient. + * \return Value of the farfield pressure sensitivity coefficient + * (inviscid + viscous contribution). + */ + inline su2double GetTotal_Sens_Press() const override { return Total_Sens_Press; } + + /*! + * \brief Set the total farfield temperature sensitivity coefficient. + * \return Value of the farfield temperature sensitivity coefficient + * (inviscid + viscous contribution). + */ + inline su2double GetTotal_Sens_Temp() const override { return Total_Sens_Temp; } + + /*! + * \author H. Kline + * \brief Get the total Back pressure number sensitivity coefficient. + * \return Value of the Back sensitivity coefficient + * (inviscid + viscous contribution). + */ + inline su2double GetTotal_Sens_BPress() const override { return Total_Sens_BPress; } + + /*! + * \brief Get the total density sensitivity coefficient. + * \return Value of the density sensitivity. + */ + inline su2double GetTotal_Sens_Density() const override { return Total_Sens_Density; } + + /*! + * \brief Get the total velocity magnitude sensitivity coefficient. + * \return Value of the velocity magnitude sensitivity. + */ + inline su2double GetTotal_Sens_ModVel() const override { return Total_Sens_ModVel; } + + /*! + * \brief Get the shape sensitivity coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the sensitivity coefficient. + */ + inline su2double GetCSensitivity(unsigned short val_marker, + unsigned long val_vertex) const override { + return CSensitivity[val_marker][val_vertex]; + } + + /*! + * \brief Prepare the solver for a new recording. + * \param[in] kind_recording - Kind of AD recording. + */ + void SetRecording(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief Prepare the solver for a new recording. + * \param[in] kind_recording - Kind of AD recording. + */ + void SetMesh_Recording(CGeometry **geometry, + CVolumetricMovement *grid_movement, + CConfig *config) override; + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] reset - If true reset variables to their initial values. + */ + void RegisterVariables(CGeometry *geometry, + CConfig *config, + bool reset = false) override; + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void ExtractAdjoint_Variables(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief Update the dual-time derivatives. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + * \param[in] Output - boolean to determine whether to print output. + */ + void Preprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep, + unsigned short RunTime_EqSystem, + bool Output) override; + + /*! + * \brief Load a solution from a restart file. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Container vector with all of the solvers. + * \param[in] config - Definition of the particular problem. + * \param[in] val_iter - Current external iteration number. + * \param[in] val_update_geo - Flag for updating coords and grid velocity. + */ + void LoadRestart(CGeometry **geometry, + CSolver ***solver, + CConfig *config, + int val_iter, + bool val_update_geo) override; + + /*! + * \brief Compute the multizone residual. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void ComputeResidual_Multizone(CGeometry *geometry, CConfig *config) override; + +}; \ No newline at end of file diff --git a/SU2_CFD/include/solvers/CEulerSolver.hpp b/SU2_CFD/include/solvers/CEulerSolver.hpp new file mode 100644 index 000000000000..b447a2d094fe --- /dev/null +++ b/SU2_CFD/include/solvers/CEulerSolver.hpp @@ -0,0 +1,2876 @@ +/*! + * \file CEulerSolver.hpp + * \brief Headers of the CEulerSolver class + * \author F. Palacios, T. Economon + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#pragma once + +#include "CSolver.hpp" +#include "../variables/CEulerVariable.hpp" + +/*! + * \class CSolver + * \brief Main class for defining the PDE solution, it requires + * a child class for each particular solver (Euler, Navier-Stokes, etc.) + * \author F. Palacios + */ +class CEulerSolver : public CSolver { +protected: + + su2double + Mach_Inf, /*!< \brief Mach number at the infinity. */ + Density_Inf, /*!< \brief Density at the infinity. */ + Energy_Inf, /*!< \brief Energy at the infinity. */ + Temperature_Inf, /*!< \brief Energy at the infinity. */ + Pressure_Inf, /*!< \brief Pressure at the infinity. */ + *Velocity_Inf; /*!< \brief Flow Velocity vector at the infinity. */ + + su2double + *CD_Inv, /*!< \brief Drag coefficient (inviscid contribution) for each boundary. */ + *CL_Inv, /*!< \brief Lift coefficient (inviscid contribution) for each boundary. */ + *CSF_Inv, /*!< \brief Sideforce coefficient (inviscid contribution) for each boundary. */ + *CMx_Inv, /*!< \brief x Moment coefficient (inviscid contribution) for each boundary. */ + *CMy_Inv, /*!< \brief y Moment coefficient (inviscid contribution) for each boundary. */ + *CMz_Inv, /*!< \brief z Moment coefficient (inviscid contribution) for each boundary. */ + *CoPx_Inv, /*!< \brief x Moment coefficient (inviscid contribution) for each boundary. */ + *CoPy_Inv, /*!< \brief y Moment coefficient (inviscid contribution) for each boundary. */ + *CoPz_Inv, /*!< \brief z Moment coefficient (inviscid contribution) for each boundary. */ + *CFx_Inv, /*!< \brief x Force coefficient (inviscid contribution) for each boundary. */ + *CFy_Inv, /*!< \brief y Force coefficient (inviscid contribution) for each boundary. */ + *CFz_Inv, /*!< \brief z Force coefficient (inviscid contribution) for each boundary. */ + *Surface_CL_Inv, /*!< \brief Lift coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CD_Inv, /*!< \brief Drag coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CSF_Inv, /*!< \brief Side-force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CEff_Inv, /*!< \brief Side-force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CFx_Inv, /*!< \brief x Force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CFy_Inv, /*!< \brief y Force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CFz_Inv, /*!< \brief z Force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CMx_Inv, /*!< \brief x Moment coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CMy_Inv, /*!< \brief y Moment coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CMz_Inv, /*!< \brief z Moment coefficient (inviscid contribution) for each monitoring surface. */ + *CEff_Inv, /*!< \brief Efficiency (Cl/Cd) (inviscid contribution) for each boundary. */ + *CMerit_Inv, /*!< \brief Rotor Figure of Merit (inviscid contribution) for each boundary. */ + *CT_Inv, /*!< \brief Thrust coefficient (force in -x direction, inviscid contribution) for each boundary. */ + *CQ_Inv, /*!< \brief Torque coefficient (moment in -x direction, inviscid contribution) for each boundary. */ + *CEquivArea_Inv, /*!< \brief Equivalent area (inviscid contribution) for each boundary. */ + *CNearFieldOF_Inv, /*!< \brief Near field pressure (inviscid contribution) for each boundary. */ + *CD_Mnt, /*!< \brief Drag coefficient (inviscid contribution) for each boundary. */ + *CL_Mnt, /*!< \brief Lift coefficient (inviscid contribution) for each boundary. */ + *CSF_Mnt, /*!< \brief Sideforce coefficient (inviscid contribution) for each boundary. */ + *CMx_Mnt, /*!< \brief x Moment coefficient (inviscid contribution) for each boundary. */ + *CMy_Mnt, /*!< \brief y Moment coefficient (inviscid contribution) for each boundary. */ + *CMz_Mnt, /*!< \brief z Moment coefficient (inviscid contribution) for each boundary. */ + *CoPx_Mnt, /*!< \brief x Moment coefficient (inviscid contribution) for each boundary. */ + *CoPy_Mnt, /*!< \brief y Moment coefficient (inviscid contribution) for each boundary. */ + *CoPz_Mnt, /*!< \brief z Moment coefficient (inviscid contribution) for each boundary. */ + *CFx_Mnt, /*!< \brief x Force coefficient (inviscid contribution) for each boundary. */ + *CFy_Mnt, /*!< \brief y Force coefficient (inviscid contribution) for each boundary. */ + *CFz_Mnt, /*!< \brief z Force coefficient (inviscid contribution) for each boundary. */ + *Surface_CL_Mnt, /*!< \brief Lift coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CD_Mnt, /*!< \brief Drag coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CSF_Mnt, /*!< \brief Side-force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CEff_Mnt, /*!< \brief Side-force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CFx_Mnt, /*!< \brief x Force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CFy_Mnt, /*!< \brief y Force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CFz_Mnt, /*!< \brief z Force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CMx_Mnt, /*!< \brief x Moment coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CMy_Mnt, /*!< \brief y Moment coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CMz_Mnt, /*!< \brief z Moment coefficient (inviscid contribution) for each monitoring surface. */ + *CEff_Mnt, /*!< \brief Efficiency (Cl/Cd) (inviscid contribution) for each boundary. */ + *CMerit_Mnt, /*!< \brief Rotor Figure of Merit (inviscid contribution) for each boundary. */ + *CT_Mnt, /*!< \brief Thrust coefficient (force in -x direction, inviscid contribution) for each boundary. */ + *CQ_Mnt, /*!< \brief Torque coefficient (moment in -x direction, inviscid contribution) for each boundary. */ + *CEquivArea_Mnt, /*!< \brief Equivalent area (inviscid contribution) for each boundary. */ + **CPressure, /*!< \brief Pressure coefficient for each boundary and vertex. */ + **CPressureTarget, /*!< \brief Target Pressure coefficient for each boundary and vertex. */ + **HeatFlux, /*!< \brief Heat transfer coefficient for each boundary and vertex. */ + **HeatFluxTarget, /*!< \brief Heat transfer coefficient for each boundary and vertex. */ + **YPlus, /*!< \brief Yplus for each boundary and vertex. */ + ***CharacPrimVar, /*!< \brief Value of the characteristic variables at each boundary. */ + ***DonorPrimVar, /*!< \brief Value of the donor variables at each boundary. */ + *ForceInviscid, /*!< \brief Inviscid force for each boundary. */ + *MomentInviscid, /*!< \brief Inviscid moment for each boundary. */ + *ForceMomentum, /*!< \brief Inviscid force for each boundary. */ + *MomentMomentum; /*!< \brief Inviscid moment for each boundary. */ + su2double + *Inflow_MassFlow, /*!< \brief Mass flow rate for each boundary. */ + *Exhaust_MassFlow, /*!< \brief Mass flow rate for each boundary. */ + *Inflow_Pressure, /*!< \brief Fan face pressure for each boundary. */ + *Inflow_Mach, /*!< \brief Fan face mach number for each boundary. */ + *Inflow_Area, /*!< \brief Boundary total area. */ + *Exhaust_Area, /*!< \brief Boundary total area. */ + *Exhaust_Pressure, /*!< \brief Fan face pressure for each boundary. */ + *Exhaust_Temperature, /*!< \brief Fan face mach number for each boundary. */ + Inflow_MassFlow_Total, /*!< \brief Mass flow rate for each boundary. */ + Exhaust_MassFlow_Total, /*!< \brief Mass flow rate for each boundary. */ + Inflow_Pressure_Total, /*!< \brief Fan face pressure for each boundary. */ + Inflow_Mach_Total, /*!< \brief Fan face mach number for each boundary. */ + InverseDesign; /*!< \brief Inverse design functional for each boundary. */ + unsigned long + **DonorGlobalIndex; /*!< \brief Value of the donor global index. */ + su2double + **ActDisk_DeltaP, /*!< \brief Value of the Delta P. */ + **ActDisk_DeltaT; /*!< \brief Value of the Delta T. */ + su2double + **Inlet_Ptotal, /*!< \brief Value of the Total P. */ + **Inlet_Ttotal, /*!< \brief Value of the Total T. */ + ***Inlet_FlowDir; /*!< \brief Value of the Flow Direction. */ + + su2double + AllBound_CD_Inv, /*!< \brief Total drag coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CL_Inv, /*!< \brief Total lift coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CSF_Inv, /*!< \brief Total sideforce coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMx_Inv, /*!< \brief Total x moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMy_Inv, /*!< \brief Total y moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMz_Inv, /*!< \brief Total z moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CoPx_Inv, /*!< \brief Total x moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CoPy_Inv, /*!< \brief Total y moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CoPz_Inv, /*!< \brief Total z moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CFx_Inv, /*!< \brief Total x force coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CFy_Inv, /*!< \brief Total y force coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CFz_Inv, /*!< \brief Total z force coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CEff_Inv, /*!< \brief Efficient coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMerit_Inv, /*!< \brief Rotor Figure of Merit (inviscid contribution) for all the boundaries. */ + AllBound_CT_Inv, /*!< \brief Total thrust coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CQ_Inv, /*!< \brief Total torque coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CEquivArea_Inv, /*!< \brief equivalent area coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CNearFieldOF_Inv; /*!< \brief Near-Field press coefficient (inviscid contribution) for all the boundaries. */ + + su2double + AllBound_CD_Mnt, /*!< \brief Total drag coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CL_Mnt, /*!< \brief Total lift coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CSF_Mnt, /*!< \brief Total sideforce coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMx_Mnt, /*!< \brief Total x moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMy_Mnt, /*!< \brief Total y moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMz_Mnt, /*!< \brief Total z moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CoPx_Mnt, /*!< \brief Total x moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CoPy_Mnt, /*!< \brief Total y moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CoPz_Mnt, /*!< \brief Total z moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CFx_Mnt, /*!< \brief Total x force coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CFy_Mnt, /*!< \brief Total y force coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CFz_Mnt, /*!< \brief Total z force coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CEff_Mnt, /*!< \brief Efficient coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMerit_Mnt, /*!< \brief Rotor Figure of Merit (inviscid contribution) for all the boundaries. */ + AllBound_CT_Mnt, /*!< \brief Total thrust coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CQ_Mnt; /*!< \brief Total torque coefficient (inviscid contribution) for all the boundaries. */ + + su2double + Total_ComboObj, /*!< \brief Total 'combo' objective for all monitored boundaries */ + Total_CD, /*!< \brief Total drag coefficient for all the boundaries. */ + Total_CL, /*!< \brief Total lift coefficient for all the boundaries. */ + Total_CL_Prev, /*!< \brief Total lift coefficient for all the boundaries (fixed lift mode). */ + Total_SolidCD, /*!< \brief Total drag coefficient for all the boundaries. */ + Total_CD_Prev, /*!< \brief Total drag coefficient for all the boundaries (fixed lift mode). */ + Total_NetThrust, /*!< \brief Total drag coefficient for all the boundaries. */ + Total_Power, /*!< \brief Total drag coefficient for all the boundaries. */ + Total_ReverseFlow, /*!< \brief Total drag coefficient for all the boundaries. */ + Total_IDC, /*!< \brief Total IDC coefficient for all the boundaries. */ + Total_IDC_Mach, /*!< \brief Total IDC coefficient for all the boundaries. */ + Total_IDR, /*!< \brief Total IDC coefficient for all the boundaries. */ + Total_DC60, /*!< \brief Total IDC coefficient for all the boundaries. */ + Total_MFR, /*!< \brief Total Mass Flow Ratio for all the boundaries. */ + Total_Prop_Eff, /*!< \brief Total Mass Flow Ratio for all the boundaries. */ + Total_ByPassProp_Eff, /*!< \brief Total Mass Flow Ratio for all the boundaries. */ + Total_Adiab_Eff, /*!< \brief Total Mass Flow Ratio for all the boundaries. */ + Total_Poly_Eff, /*!< \brief Total Mass Flow Ratio for all the boundaries. */ + Total_Custom_ObjFunc, /*!< \brief Total custom objective function for all the boundaries. */ + Total_CSF, /*!< \brief Total sideforce coefficient for all the boundaries. */ + Total_CMx, /*!< \brief Total x moment coefficient for all the boundaries. */ + Total_CMx_Prev, /*!< \brief Total drag coefficient for all the boundaries (fixed lift mode). */ + Total_CMy, /*!< \brief Total y moment coefficient for all the boundaries. */ + Total_CMy_Prev, /*!< \brief Total drag coefficient for all the boundaries (fixed lift mode). */ + Total_CMz, /*!< \brief Total z moment coefficient for all the boundaries. */ + Total_CMz_Prev, /*!< \brief Total drag coefficient for all the boundaries (fixed lift mode). */ + Total_CoPx, /*!< \brief Total x moment coefficient for all the boundaries. */ + Total_CoPy, /*!< \brief Total y moment coefficient for all the boundaries. */ + Total_CoPz, /*!< \brief Total z moment coefficient for all the boundaries. */ + Total_CFx, /*!< \brief Total x force coefficient for all the boundaries. */ + Total_CFy, /*!< \brief Total y force coefficient for all the boundaries. */ + Total_CFz, /*!< \brief Total z force coefficient for all the boundaries. */ + Total_CEff, /*!< \brief Total efficiency coefficient for all the boundaries. */ + Total_CMerit, /*!< \brief Total rotor Figure of Merit for all the boundaries. */ + Total_CT, /*!< \brief Total thrust coefficient for all the boundaries. */ + Total_CQ, /*!< \brief Total torque coefficient for all the boundaries. */ + Total_Heat, /*!< \brief Total heat load for all the boundaries. */ + Total_MaxHeat, /*!< \brief Maximum heat flux on all boundaries. */ + Total_AeroCD, /*!< \brief Total aero drag coefficient for all the boundaries. */ + Total_CEquivArea, /*!< \brief Total Equivalent Area coefficient for all the boundaries. */ + Total_CNearFieldOF, /*!< \brief Total Near-Field Pressure coefficient for all the boundaries. */ + Total_CpDiff, /*!< \brief Total Equivalent Area coefficient for all the boundaries. */ + Total_HeatFluxDiff, /*!< \brief Total Equivalent Area coefficient for all the boundaries. */ + Total_MassFlowRate; /*!< \brief Total Mass Flow Rate on monitored boundaries. */ + su2double + *Surface_CL, /*!< \brief Lift coefficient for each monitoring surface. */ + *Surface_CD, /*!< \brief Drag coefficient for each monitoring surface. */ + *Surface_CSF, /*!< \brief Side-force coefficient for each monitoring surface. */ + *Surface_CEff, /*!< \brief Side-force coefficient for each monitoring surface. */ + *Surface_CFx, /*!< \brief x Force coefficient for each monitoring surface. */ + *Surface_CFy, /*!< \brief y Force coefficient for each monitoring surface. */ + *Surface_CFz, /*!< \brief z Force coefficient for each monitoring surface. */ + *Surface_CMx, /*!< \brief x Moment coefficient for each monitoring surface. */ + *Surface_CMy, /*!< \brief y Moment coefficient for each monitoring surface. */ + *Surface_CMz, /*!< \brief z Moment coefficient for each monitoring surface. */ + *Surface_HF_Visc, /*!< \brief Total (integrated) heat flux for each monitored surface. */ + *Surface_MaxHF_Visc; /*!< \brief Maximum heat flux for each monitored surface. */ + + su2double + *SecondaryVar_i, /*!< \brief Auxiliary vector for storing the solution at point i. */ + *SecondaryVar_j; /*!< \brief Auxiliary vector for storing the solution at point j. */ + su2double + *PrimVar_i, /*!< \brief Auxiliary vector for storing the solution at point i. */ + *PrimVar_j; /*!< \brief Auxiliary vector for storing the solution at point j. */ + su2double **LowMach_Precontioner; /*!< \brief Auxiliary vector for storing the inverse of Roe-turkel preconditioner. */ + bool space_centered, /*!< \brief True if space centered scheeme used. */ + euler_implicit, /*!< \brief True if euler implicit scheme used. */ + least_squares; /*!< \brief True if computing gradients by least squares. */ + su2double Gamma; /*!< \brief Fluid's Gamma constant (ratio of specific heats). */ + su2double Gamma_Minus_One; /*!< \brief Fluids's Gamma - 1.0 . */ + + su2double *Primitive, /*!< \brief Auxiliary nPrimVar vector. */ + *Primitive_i, /*!< \brief Auxiliary nPrimVar vector for storing the primitive at point i. */ + *Primitive_j; /*!< \brief Auxiliary nPrimVar vector for storing the primitive at point j. */ + + su2double *Secondary, /*!< \brief Auxiliary nPrimVar vector. */ + *Secondary_i, /*!< \brief Auxiliary nPrimVar vector for storing the primitive at point i. */ + *Secondary_j; /*!< \brief Auxiliary nPrimVar vector for storing the primitive at point j. */ + + su2double AoA_Prev, /*!< \brief Old value of the angle of attack (monitored). */ + AoA_inc; + bool Start_AoA_FD, /*!< \brief Boolean for start of finite differencing for FixedCL mode */ + End_AoA_FD, /*!< \brief Boolean for end of finite differencing for FixedCL mode */ + Update_AoA; /*!< \brief Boolean to signal Angle of Attack Update */ + unsigned long Iter_Update_AoA; /*!< \brief Iteration at which AoA was updated last */ + su2double dCL_dAlpha; /*!< \brief Value of dCL_dAlpha used to control CL in fixed CL mode */ + unsigned long BCThrust_Counter; + unsigned short nSpanWiseSections; /*!< \brief Number of span-wise sections. */ + unsigned short nSpanMax; /*!< \brief Max number of maximum span-wise sections for all zones */ + unsigned short nMarkerTurboPerf; /*!< \brief Number of turbo performance. */ + + CFluidModel *FluidModel; /*!< \brief fluid model used in the solver */ + + /*--- Turbomachinery Solver Variables ---*/ + su2double *** AverageFlux, + ***SpanTotalFlux, + ***AverageVelocity, + ***AverageTurboVelocity, + ***OldAverageTurboVelocity, + ***ExtAverageTurboVelocity, + **AveragePressure, + **OldAveragePressure, + **RadialEquilibriumPressure, + **ExtAveragePressure, + **AverageDensity, + **OldAverageDensity, + **ExtAverageDensity, + **AverageNu, + **AverageKine, + **AverageOmega, + **ExtAverageNu, + **ExtAverageKine, + **ExtAverageOmega; + + su2double **DensityIn, + **PressureIn, + ***TurboVelocityIn, + **DensityOut, + **PressureOut, + ***TurboVelocityOut, + **KineIn, + **OmegaIn, + **NuIn, + **KineOut, + **OmegaOut, + **NuOut; + + complex ***CkInflow, + ***CkOutflow1, + ***CkOutflow2; + + /*--- End of Turbomachinery Solver Variables ---*/ + + /* Sliding meshes variables */ + + su2double ****SlidingState; + int **SlidingStateNodes; + + CEulerVariable* nodes = nullptr; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ + + /*! + * \brief Return nodes to allow CSolver::base_nodes to be set. + */ + inline CVariable* GetBaseClassPointerToNodes() final { return nodes; } + +public: + + + /*! + * \brief Constructor of the class. + */ + CEulerSolver(void); + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + CEulerSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); + + /*! + * \brief Destructor of the class. + */ + virtual ~CEulerSolver(void); + + /*! + * \brief Set the solver nondimensionalization. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void SetNondimensionalization(CConfig *config, unsigned short iMesh) final; + + /*! + * \brief Compute the pressure at the infinity. + * \return Value of the pressure at the infinity. + */ + inline CFluidModel* GetFluidModel(void) const final { return FluidModel;} + + /*! + * \brief Compute the density at the infinity. + * \return Value of the density at the infinity. + */ + inline su2double GetDensity_Inf(void) const final { return Density_Inf; } + + /*! + * \brief Compute 2-norm of the velocity at the infinity. + * \return Value of the 2-norm of the velocity at the infinity. + */ + inline su2double GetModVelocity_Inf(void) const final { + su2double Vel2 = 0; + for (unsigned short iDim = 0; iDim < nDim; iDim++) + Vel2 += Velocity_Inf[iDim]*Velocity_Inf[iDim]; + return sqrt(Vel2); + } + + + /*! + * \brief Compute the density multiply by energy at the infinity. + * \return Value of the density multiply by energy at the infinity. + */ + inline su2double GetDensity_Energy_Inf(void) const final { return Density_Inf*Energy_Inf; } + + /*! + * \brief Compute the pressure at the infinity. + * \return Value of the pressure at the infinity. + */ + inline su2double GetPressure_Inf(void) const final { return Pressure_Inf; } + + /*! + * \brief Compute the density multiply by velocity at the infinity. + * \param[in] val_dim - Index of the velocity vector. + * \return Value of the density multiply by the velocity at the infinity. + */ + inline su2double GetDensity_Velocity_Inf(unsigned short val_dim) const final { return Density_Inf*Velocity_Inf[val_dim]; } + + /*! + * \brief Get the velocity at the infinity. + * \param[in] val_dim - Index of the velocity vector. + * \return Value of the velocity at the infinity. + */ + inline su2double GetVelocity_Inf(unsigned short val_dim) const final { return Velocity_Inf[val_dim]; } + + /*! + * \brief Get the velocity at the infinity. + * \return Value of the velocity at the infinity. + */ + inline su2double *GetVelocity_Inf(void) const final { return Velocity_Inf; } + + /*! + * \brief Compute the time step for solving the Euler equations. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] Iteration - Value of the current iteration. + */ + void SetTime_Step(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned long Iteration) override; + + /*! + * \brief Compute the spatial integration using a centered scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + void Centered_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep) final; + + /*! + * \brief Compute the spatial integration using a upwind scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Upwind_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh) final; + + /*! + * \brief Compute the extrapolated quantities, for MUSCL upwind 2nd reconstruction, + * in a more thermodynamic consistent way + * \param[in] config - Definition of the particular problem. + */ + void ComputeConsExtrapolation(CConfig *config); + + /*! + * \brief Source term integration. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] second_numerics - Description of the second numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Source_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CNumerics *second_numerics, + CConfig *config, unsigned short iMesh) override; + + /*! + * \brief Source term integration. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Source_Template(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh) final; + + /*! + * \brief Compute primitive variables and their gradients. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + * \param[in] Output - boolean to determine whether to print output. + */ + void Preprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep, + unsigned short RunTime_EqSystem, + bool Output) override; + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Postprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh) final; + + /*! + * \brief Compute the velocity^2, SoundSpeed, Pressure, Enthalpy, Viscosity. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] Output - boolean to determine whether to print output. + * \return - The number of non-physical points. + */ + unsigned long SetPrimitive_Variables(CSolver **solver_container, + CConfig *config, + bool Output) override; + + /*! + * \brief Compute a pressure sensor switch. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void SetCentered_Dissipation_Sensor(CGeometry *geometry, CConfig *config) final; + + /*! + * \brief Compute Ducros Sensor for Roe Dissipation. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void SetUpwind_Ducros_Sensor(CGeometry *geometry, CConfig *config) final; + + /*! + * \brief Compute the gradient of the primitive variables using Green-Gauss method, + * and stores the result in the Gradient_Primitive variable. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] reconstruction - indicator that the gradient being computed is for upwind reconstruction. + */ + void SetPrimitive_Gradient_GG(CGeometry *geometry, + CConfig *config, + bool reconstruction = false) final; + + /*! + * \brief Compute the gradient of the primitive variables using a Least-Squares method, + * and stores the result in the Gradient_Primitive variable. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] reconstruction - indicator that the gradient being computed is for upwind reconstruction. + */ + void SetPrimitive_Gradient_LS(CGeometry *geometry, + CConfig *config, + bool reconstruction = false) final; + + /*! + * \brief Compute the limiter of the primitive variables. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void SetPrimitive_Limiter(CGeometry *geometry, CConfig *config) final; + + /*! + * \brief Compute the preconditioner for convergence acceleration by Roe-Turkel method. + * \param[in] iPoint - Index of the grid point + * \param[in] config - Definition of the particular problem. + */ + void SetPreconditioner(CConfig *config, unsigned long iPoint) final; + + /*! + * \brief Compute the undivided laplacian for the solution, except the energy equation. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void SetUndivided_Laplacian(CGeometry *geometry, CConfig *config) final; + + /*! + * \brief Compute the max eigenvalue. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void SetMax_Eigenvalue(CGeometry *geometry, CConfig *config) final; + + /*! + * \brief Parallelization of Undivided Laplacian. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Set_MPI_ActDisk(CSolver **solver_container, CGeometry *geometry, CConfig *config) final; + + /*! + * \brief Parallelization of Undivided Laplacian. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Set_MPI_Nearfield(CGeometry *geometry, CConfig *config) final; + + /*! + * \author H. Kline + * \brief Compute weighted-sum "combo" objective output + * \param[in] config - Definition of the particular problem. + */ + void Evaluate_ObjFunc(CConfig *config) override; + + /*! + * \author: T. Kattmann + * + * \brief Impose via the residual the Euler wall boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Euler_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the far-field boundary condition using characteristics. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Far_Field(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose the symmetry boundary condition using the residual. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Sym_Plane(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose the interface state across sliding meshes. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + void BC_Fluid_Interface(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config) final; + + /*! + * \brief Impose the engine inflow boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_ActDisk_Inlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose the engine exhaust boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_ActDisk_Outlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose an actuator disk inlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + * \param[in] val_inlet_surface - Boolean for whether val_marker is an inlet + */ + void BC_ActDisk(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker, + bool val_inlet_surface) final; + + /*! + * \brief Impose the interface boundary condition using the residual. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + void BC_Interface_Boundary(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose the near-field boundary condition using the residual. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + void BC_NearField_Boundary(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose a periodic boundary condition by summing contributions from the complete control volume. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + void BC_Periodic(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config) final; + + /*! + * \author: G.Gori, S.Vitale, M.Pini, A.Guardone, P.Colonna + * + * \brief Impose the boundary condition using characteristic recostruction. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Riemann(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + + /*! + * \brief Impose the boundary condition using characteristic recostruction. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_TurboRiemann(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief It computes Fourier transformation for the needed quantities along the pitch for each span in turbomachinery analysis. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] marker_flag - Surface marker flag where the function is applied. + */ + void PreprocessBC_Giles(CGeometry *geometry, + CConfig *config, + CNumerics *conv_numerics, + unsigned short marker_flag) final; + + /*! + * \author: G.Gori, S.Vitale, M.Pini, A.Guardone, P.Colonna + * + * \brief Impose the boundary condition using characteristic recostruction. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Giles(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + + /*! + * \brief Impose a subsonic inlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Inlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose a supersonic inlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Supersonic_Inlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose a supersonic outlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Supersonic_Outlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose a custom or verification boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the convective numerical method. + * \param[in] visc_numerics - Description of the viscous numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Custom(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + + /*! + * \brief Impose the outlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Outlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + + /*! + * \brief Impose the nacelle inflow boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Engine_Inflow(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose the ancelle exhaust boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Engine_Exhaust(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Set the new solution variables to the current solution value for classical RK. + * \param[in] geometry - Geometrical definition of the problem. + */ + inline void Set_NewSolution(CGeometry *geometry) final { nodes->SetSolution_New(); } + + /*! + * \brief Update the solution using a Runge-Kutta scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + void ExplicitRK_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iRKStep) final; + + /*! + * \brief Update the solution using the classical fourth-order Runge-Kutta scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + void ClassicalRK4_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iRKStep) final; + + /*! + * \brief Compute the Fan face Mach number. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solution - Container vector with all the solutions. + */ + void GetPower_Properties(CGeometry *geometry, + CConfig *config, + unsigned short iMesh, + bool Output) final; + + /*! + * \brief Update the AoA and freestream velocity at the farfield. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - current mesh level for the multigrid. + * \param[in] Output - boolean to determine whether to print output. + */ + void SetActDisk_BCThrust(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + bool Output) final; + + /*! + * \brief Update the AoA and freestream velocity at the farfield. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - current mesh level for the multigrid. + * \param[in] Output - boolean to determine whether to print output. + */ + void SetFarfield_AoA(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + bool Output) final; + + /*! + * \brief Check for convergence of the Fixed CL mode to the target CL + * \param[in] config - Definition of the particular problem. + * \param[in] convergence - boolean for whether the solution is converged + * \return boolean for whether the Fixed CL mode is converged to target CL + */ + bool FixedCL_Convergence(CConfig *config, bool convergence) final; + + /*! + * \brief Checking whether fixed CL mode in finite-differencing mode + * \return boolean for whether the Fixed CL mode is currently in finite-differencing mode + */ + inline bool GetStart_AoA_FD(void) const final { return Start_AoA_FD; } + + /*! + * \brief Checking whether fixed CL mode in finite-differencing mode + * \return boolean for whether the Fixed CL mode is currently in finite-differencing mode + */ + inline bool GetEnd_AoA_FD(void) const final { return End_AoA_FD; } + + /*! + * \brief Get the iteration of the last AoA update (Fixed CL Mode) + * \return value for the last iteration that the AoA was updated + */ + inline unsigned long GetIter_Update_AoA(void) const final { return Iter_Update_AoA; } + + /*! + * \brief Get the AoA before the most recent update + * \return value of the AoA before most recent update + */ + inline su2double GetPrevious_AoA(void) const final { return AoA_Prev; } + + /*! + * \brief Get the CL Driver's control command + * \return value of CL Driver control command (AoA_inc) + */ + inline su2double GetAoA_inc(void) const final { return AoA_inc; } + + /*! + * \brief Set gradients of coefficients for fixed CL mode + * \param[in] config - Definition of the particular problem. + */ + void SetCoefficient_Gradients(CConfig *config); + + /*! + * \brief Update the solution using the explicit Euler scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void ExplicitEuler_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) final; + + /*! + * \brief Update the solution using an implicit Euler scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void ImplicitEuler_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) final; + + /*! + * \brief Compute a suitable under-relaxation parameter to limit the change in the solution variables over a nonlinear iteration for stability. + * \param[in] solver - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void ComputeUnderRelaxationFactor(CSolver **solver, CConfig *config) final; + + /*! + * \brief Compute the pressure forces and all the adimensional coefficients. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Pressure_Forces(CGeometry *geometry, CConfig *config) final; + + /*! + * \brief Compute the pressure forces and all the adimensional coefficients. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Momentum_Forces(CGeometry *geometry, CConfig *config) final; + + /*! + * \brief Get the outer state for fluid interface nodes. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + * \param[in] val_state - requested state component + * \param[in] donor_index- index of the donor node to get + */ + inline su2double GetSlidingState(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_state, + unsigned long donor_index) const final { + return SlidingState[val_marker][val_vertex][val_state][donor_index]; + } + + /*! + * \brief Provide the non dimensional lift coefficient (inviscid contribution). + * \param val_marker Surface where the coefficient is going to be computed. + * \return Value of the lift coefficient (inviscid contribution) on the surface val_marker. + */ + inline su2double GetCL_Inv(unsigned short val_marker) const final { return CL_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional lift coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the lift coefficient on the surface val_marker. + */ + inline su2double GetSurface_CL(unsigned short val_marker) const final { return Surface_CL[val_marker]; } + + /*! + * \brief Provide the non dimensional drag coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the drag coefficient on the surface val_marker. + */ + inline su2double GetSurface_CD(unsigned short val_marker) const final { return Surface_CD[val_marker]; } + + /*! + * \brief Provide the non dimensional side-force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side-force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CSF(unsigned short val_marker) const final { return Surface_CSF[val_marker]; } + + /*! + * \brief Provide the non dimensional side-force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side-force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CEff(unsigned short val_marker) const final { return Surface_CEff[val_marker]; } + + /*! + * \brief Provide the non dimensional x force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFx(unsigned short val_marker) const final { return Surface_CFx[val_marker]; } + + /*! + * \brief Provide the non dimensional y force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFy(unsigned short val_marker) const final { return Surface_CFy[val_marker]; } + + /*! + * \brief Provide the non dimensional z force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFz(unsigned short val_marker) const final { return Surface_CFz[val_marker]; } + + /*! + * \brief Provide the non dimensional x moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMx(unsigned short val_marker) const final { return Surface_CMx[val_marker]; } + + /*! + * \brief Provide the non dimensional y moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMy(unsigned short val_marker) const final { return Surface_CMy[val_marker]; } + + /*! + * \brief Provide the non dimensional z moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMz(unsigned short val_marker) const final { return Surface_CMz[val_marker]; } + + /*! + * \brief Provide the non dimensional lift coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the lift coefficient on the surface val_marker. + */ + inline su2double GetSurface_CL_Inv(unsigned short val_marker) const final { return Surface_CL_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional drag coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the drag coefficient on the surface val_marker. + */ + inline su2double GetSurface_CD_Inv(unsigned short val_marker) const final { return Surface_CD_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional side-force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side-force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CSF_Inv(unsigned short val_marker) const final { return Surface_CSF_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional side-force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side-force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CEff_Inv(unsigned short val_marker) const final { return Surface_CEff_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional x force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFx_Inv(unsigned short val_marker) const final { return Surface_CFx_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional y force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFy_Inv(unsigned short val_marker) const final { return Surface_CFy_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional z force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFz_Inv(unsigned short val_marker) const final { return Surface_CFz_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional x moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMx_Inv(unsigned short val_marker) const final { return Surface_CMx_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional y moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMy_Inv(unsigned short val_marker) const final { return Surface_CMy_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional z moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMz_Inv(unsigned short val_marker) const final { return Surface_CMz_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional lift coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the lift coefficient on the surface val_marker. + */ + inline su2double GetSurface_CL_Mnt(unsigned short val_marker) const final { return Surface_CL_Mnt[val_marker]; } + + /*! + * \brief Provide the non dimensional drag coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the drag coefficient on the surface val_marker. + */ + inline su2double GetSurface_CD_Mnt(unsigned short val_marker) const final { return Surface_CD_Mnt[val_marker]; } + + /*! + * \brief Provide the non dimensional side-force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side-force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CSF_Mnt(unsigned short val_marker) const final { return Surface_CSF_Mnt[val_marker]; } + + /*! + * \brief Provide the non dimensional side-force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side-force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CEff_Mnt(unsigned short val_marker) const final { return Surface_CEff_Mnt[val_marker]; } + + /*! + * \brief Provide the non dimensional x force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFx_Mnt(unsigned short val_marker) const final { return Surface_CFx_Mnt[val_marker]; } + + /*! + * \brief Provide the non dimensional y force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFy_Mnt(unsigned short val_marker) const final { return Surface_CFy_Mnt[val_marker]; } + + /*! + * \brief Provide the non dimensional z force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFz_Mnt(unsigned short val_marker) const final { return Surface_CFz_Mnt[val_marker]; } + + /*! + * \brief Provide the non dimensional x moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMx_Mnt(unsigned short val_marker) const final { return Surface_CMx_Mnt[val_marker]; } + + /*! + * \brief Provide the non dimensional y moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMy_Mnt(unsigned short val_marker) const final { return Surface_CMy_Mnt[val_marker]; } + + /*! + * \brief Provide the non dimensional z moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMz_Mnt(unsigned short val_marker) const final { return Surface_CMz_Mnt[val_marker]; } + + /*! + * \brief Provide the non dimensional drag coefficient (inviscid contribution). + * \param val_marker Surface where the coeficient is going to be computed. + * \return Value of the drag coefficient (inviscid contribution) on the surface val_marker. + */ + inline su2double GetCD_Inv(unsigned short val_marker) const final { return CD_Inv[val_marker]; } + + /*! + * \brief Provide the mass flow rate. + * \param val_marker Surface where the coeficient is going to be computed. + * \return Value of the mass flow rate on the surface val_marker. + */ + inline su2double GetInflow_MassFlow(unsigned short val_marker) const final { return Inflow_MassFlow[val_marker]; } + + /*! + * \brief Provide the mass flow rate. + * \param val_marker Surface where the coeficient is going to be computed. + * \return Value of the mass flow rate on the surface val_marker. + */ + inline su2double GetExhaust_MassFlow(unsigned short val_marker) const final { return Exhaust_MassFlow[val_marker]; } + + /*! + * \brief Provide the mass flow rate. + * \param val_marker Surface where the coeficient is going to be computed. + * \return Value of the fan face pressure on the surface val_marker. + */ + inline su2double GetInflow_Pressure(unsigned short val_marker) const final { return Inflow_Pressure[val_marker]; } + + /*! + * \brief Provide the mass flow rate. + * \param val_marker Surface where the coeficient is going to be computed. + * \return Value of the fan face mach on the surface val_marker. + */ + inline su2double GetInflow_Mach(unsigned short val_marker) const final { return Inflow_Mach[val_marker]; } + + /*! + * \brief Provide the non dimensional sideforce coefficient (inviscid contribution). + * \param val_marker Surface where the coeficient is going to be computed. + * \return Value of the sideforce coefficient (inviscid contribution) on the surface val_marker. + */ + inline su2double GetCSF_Inv(unsigned short val_marker) const final { return CSF_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional efficiency coefficient (inviscid contribution). + * \param val_marker Surface where the coeficient is going to be computed. + * \return Value of the efficiency coefficient (inviscid contribution) on the surface val_marker. + */ + inline su2double GetCEff_Inv(unsigned short val_marker) const final { return CEff_Inv[val_marker]; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional sideforce coefficient. + * \return Value of the sideforce coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CSF() const final { return Total_CSF; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CEff() const final { return Total_CEff; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional Equivalent Area coefficient. + * \return Value of the Equivalent Area coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CEquivArea() const final { return Total_CEquivArea; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional aero CD. + * \return Value of the Aero CD coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_AeroCD() const final { return Total_AeroCD; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional Equivalent Area coefficient. + * \return Value of the Equivalent Area coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CpDiff() const final { return Total_CpDiff; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional Equivalent Area coefficient. + * \return Value of the Equivalent Area coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_HeatFluxDiff() const final { return Total_HeatFluxDiff; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional Near-Field pressure coefficient. + * \return Value of the NearField pressure coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CNearFieldOF() const final { return Total_CNearFieldOF; } + + /*! + * \author H. Kline + * \brief Add to the value of the total 'combo' objective. + * \param[in] val_obj - Value of the contribution to the 'combo' objective. + */ + inline void AddTotal_ComboObj(su2double val_obj) final {Total_ComboObj +=val_obj;} + + /*! + * \brief Set the value of the Equivalent Area coefficient. + * \param[in] val_cequivarea - Value of the Equivalent Area coefficient. + */ + inline void SetTotal_CEquivArea(su2double val_cequivarea) final { Total_CEquivArea = val_cequivarea; } + + /*! + * \brief Set the value of the Aero drag. + * \param[in] val_cequivarea - Value of the aero drag. + */ + inline void SetTotal_AeroCD(su2double val_aerocd) final { Total_AeroCD = val_aerocd; } + + /*! + * \brief Set the value of the Equivalent Area coefficient. + * \param[in] val_cequivarea - Value of the Equivalent Area coefficient. + */ + inline void SetTotal_CpDiff(su2double val_pressure) final { Total_CpDiff = val_pressure; } + + /*! + * \brief Set the value of the Equivalent Area coefficient. + * \param[in] val_cequivarea - Value of the Equivalent Area coefficient. + */ + inline void SetTotal_HeatFluxDiff(su2double val_heat) final { Total_HeatFluxDiff = val_heat; } + + /*! + * \brief Set the value of the Near-Field pressure oefficient. + * \param[in] val_cnearfieldpress - Value of the Near-Field pressure coefficient. + */ + inline void SetTotal_CNearFieldOF(su2double val_cnearfieldpress) final { Total_CNearFieldOF = val_cnearfieldpress; } + + /*! + * \author H. Kline + * \brief Set the total "combo" objective (weighted sum of other values). + * \param[in] ComboObj - Value of the combined objective. + */ + inline void SetTotal_ComboObj(su2double ComboObj) final {Total_ComboObj = ComboObj; } + + /*! + * \author H. Kline + * \brief Provide the total "combo" objective (weighted sum of other values). + * \return Value of the "combo" objective values. + */ + inline su2double GetTotal_ComboObj() const final { return Total_ComboObj; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional lift coefficient. + * \return Value of the lift coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CL() const final { return Total_CL; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CD() const final { return Total_CD; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_NetThrust() const final { return Total_NetThrust; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_Power() const final { return Total_Power; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_SolidCD() const final { return Total_SolidCD; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_ReverseFlow() const final { return Total_ReverseFlow; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_MFR() const final { return Total_MFR; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_Prop_Eff() const final { return Total_Prop_Eff; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_ByPassProp_Eff() const final { return Total_ByPassProp_Eff; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_Adiab_Eff() const final { return Total_Adiab_Eff; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_Poly_Eff() const final { return Total_Poly_Eff; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_IDC() const final { return Total_IDC; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_IDC_Mach() const final { return Total_IDC_Mach; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_IDR() const final { return Total_IDR; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_DC60() const final { return Total_DC60; } + + /*! + * \brief Provide the total custom objective function. + * \return Value of the custom objective function. + */ + inline su2double GetTotal_Custom_ObjFunc() const final { return Total_Custom_ObjFunc; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional x moment coefficient. + * \return Value of the moment x coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CMx() const final { return Total_CMx; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional y moment coefficient. + * \return Value of the moment y coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CMy() const final { return Total_CMy; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional z moment coefficient. + * \return Value of the moment z coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CMz() const final { return Total_CMz; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional x moment coefficient. + * \return Value of the moment x coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CoPx() const final { return Total_CoPx; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional y moment coefficient. + * \return Value of the moment y coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CoPy() const final { return Total_CoPy; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional z moment coefficient. + * \return Value of the moment z coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CoPz() const final { return Total_CoPz; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional x force coefficient. + * \return Value of the force x coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CFx() const final { return Total_CFx; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional y force coefficient. + * \return Value of the force y coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CFy() const final { return Total_CFy; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional z force coefficient. + * \return Value of the force z coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CFz() const final { return Total_CFz; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional thrust coefficient. + * \return Value of the rotor efficiency coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CT() const final { return Total_CT; } + + /*! + * \brief Store the total (inviscid + viscous) non dimensional thrust coefficient. + * \param[in] val_Total_CT - Value of the total thrust coefficient. + */ + inline void SetTotal_CT(su2double val_Total_CT) final { Total_CT = val_Total_CT; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional torque coefficient. + * \return Value of the rotor efficiency coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CQ() const final { return Total_CQ; } + + /*! + * \brief Provide the total heat load. + * \return Value of the heat load (viscous contribution). + */ + inline su2double GetTotal_HeatFlux(void) const final { return Total_Heat; } + + /*! + * \brief Provide the total heat load. + * \return Value of the heat load (viscous contribution). + */ + inline su2double GetTotal_MaxHeatFlux() const final { return Total_MaxHeat; } + + /*! + * \brief Store the total (inviscid + viscous) non dimensional torque coefficient. + * \param[in] val_Total_CQ - Value of the total torque coefficient. + */ + inline void SetTotal_CQ(su2double val_Total_CQ) final { Total_CQ = val_Total_CQ; } + + /*! + * \brief Store the total heat load. + * \param[in] val_Total_Heat - Value of the heat load. + */ + inline void SetTotal_HeatFlux(su2double val_Total_Heat) final { Total_Heat = val_Total_Heat; } + + /*! + * \brief Store the total heat load. + * \param[in] val_Total_Heat - Value of the heat load. + */ + inline void SetTotal_MaxHeatFlux(su2double val_Total_MaxHeat) final { Total_MaxHeat = val_Total_MaxHeat; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional rotor Figure of Merit. + * \return Value of the rotor efficiency coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CMerit() const final { return Total_CMerit; } + + /*! + * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline void SetTotal_CD(su2double val_Total_CD) final { Total_CD = val_Total_CD; } + + /*! + * \brief Store the total (inviscid + viscous) non dimensional lift coefficient. + * \param[in] val_Total_CL - Value of the total lift coefficient. + */ + inline void SetTotal_CL(su2double val_Total_CL) final { Total_CL = val_Total_CL; } + + /*! + * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline void SetTotal_NetThrust(su2double val_Total_NetThrust) final { Total_NetThrust = val_Total_NetThrust; } + + /*! + * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline void SetTotal_Power(su2double val_Total_Power) final { Total_Power = val_Total_Power; } + + /*! + * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline void SetTotal_SolidCD(su2double val_Total_SolidCD) final { Total_SolidCD = val_Total_SolidCD; } + + /*! + * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline void SetTotal_ReverseFlow(su2double val_Total_ReverseFlow) final { Total_ReverseFlow = val_Total_ReverseFlow; } + + /*! + * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline void SetTotal_MFR(su2double val_Total_MFR) final { Total_MFR = val_Total_MFR; } + + /*! + * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline void SetTotal_Prop_Eff(su2double val_Total_Prop_Eff) final { Total_Prop_Eff = val_Total_Prop_Eff; } + + /*! + * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline void SetTotal_ByPassProp_Eff(su2double val_Total_ByPassProp_Eff) final { Total_ByPassProp_Eff = val_Total_ByPassProp_Eff; } + + /*! + * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline void SetTotal_Adiab_Eff(su2double val_Total_Adiab_Eff) final { Total_Adiab_Eff = val_Total_Adiab_Eff; } + + /*! + * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline void SetTotal_Poly_Eff(su2double val_Total_Poly_Eff) final { Total_Poly_Eff = val_Total_Poly_Eff; } + + /*! + * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline void SetTotal_IDC(su2double val_Total_IDC) final { Total_IDC = val_Total_IDC; } + + /*! + * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline void SetTotal_IDC_Mach(su2double val_Total_IDC_Mach) final { Total_IDC_Mach = val_Total_IDC_Mach; } + + /*! + * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline void SetTotal_IDR(su2double val_Total_IDR) final { Total_IDR = val_Total_IDR; } + + /*! + * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline void SetTotal_DC60(su2double val_Total_DC60) final { Total_DC60 = val_Total_DC60; } + + /*! + * \brief Set the value of the custom objective function. + * \param[in] val_Total_Custom_ObjFunc - Value of the total custom objective function. + * \param[in] val_weight - Value of the weight for the custom objective function. + */ + inline void SetTotal_Custom_ObjFunc(su2double val_total_custom_objfunc, su2double val_weight) final { + Total_Custom_ObjFunc = val_total_custom_objfunc*val_weight; + } + + /*! + * \brief Add the value of the custom objective function. + * \param[in] val_Total_Custom_ObjFunc - Value of the total custom objective function. + * \param[in] val_weight - Value of the weight for the custom objective function. + */ + inline void AddTotal_Custom_ObjFunc(su2double val_total_custom_objfunc, su2double val_weight) final { + Total_Custom_ObjFunc += val_total_custom_objfunc*val_weight; + } + + /*! + * \brief Get the inviscid contribution to the lift coefficient. + * \return Value of the lift coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CL_Inv() const final { return AllBound_CL_Inv; } + + /*! + * \brief Get the inviscid contribution to the drag coefficient. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CD_Inv() const final { return AllBound_CD_Inv; } + + /*! + * \brief Get the inviscid contribution to the sideforce coefficient. + * \return Value of the sideforce coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CSF_Inv() const final { return AllBound_CSF_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CEff_Inv() const final { return AllBound_CEff_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CMx_Inv() const final { return AllBound_CMx_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CMy_Inv() const final { return AllBound_CMy_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CMz_Inv() const final { return AllBound_CMz_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CoPx_Inv() const final { return AllBound_CoPx_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CoPy_Inv() const final { return AllBound_CoPy_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CoPz_Inv() const final { return AllBound_CoPz_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CFx_Inv() const final { return AllBound_CFx_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CFy_Inv() const final { return AllBound_CFy_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CFz_Inv() const final { return AllBound_CFz_Inv; } + + /*! + * \brief Get the inviscid contribution to the lift coefficient. + * \return Value of the lift coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CL_Mnt() const final { return AllBound_CL_Mnt; } + + /*! + * \brief Get the inviscid contribution to the drag coefficient. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CD_Mnt() const final { return AllBound_CD_Mnt; } + + /*! + * \brief Get the inviscid contribution to the sideforce coefficient. + * \return Value of the sideforce coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CSF_Mnt() const final { return AllBound_CSF_Mnt; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CEff_Mnt() const final { return AllBound_CEff_Mnt; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CMx_Mnt() const final { return AllBound_CMx_Mnt; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CMy_Mnt() const final { return AllBound_CMy_Mnt; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CMz_Mnt() const final { return AllBound_CMz_Mnt; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CoPx_Mnt() const final { return AllBound_CoPx_Mnt; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CoPy_Mnt() const final { return AllBound_CoPy_Mnt; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CoPz_Mnt() const final { return AllBound_CoPz_Mnt; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CFx_Mnt() const final { return AllBound_CFx_Mnt; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CFy_Mnt() const final { return AllBound_CFy_Mnt; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CFz_Mnt() const final { return AllBound_CFz_Mnt; } + + /*! + * \brief Provide the Pressure coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline su2double GetCPressure(unsigned short val_marker, unsigned long val_vertex) const final { + return CPressure[val_marker][val_vertex]; + } + + /*! + * \brief Provide the Target Pressure coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline su2double GetCPressureTarget(unsigned short val_marker, unsigned long val_vertex) const final { + return CPressureTarget[val_marker][val_vertex]; + } + + /*! + * \brief Set the value of the target Pressure coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline void SetCPressureTarget(unsigned short val_marker, + unsigned long val_vertex, + su2double val_pressure) final { + CPressureTarget[val_marker][val_vertex] = val_pressure; + } + + /*! + * \brief Value of the characteristic variables at the boundaries. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline su2double *GetCharacPrimVar(unsigned short val_marker, unsigned long val_vertex) const final { + return CharacPrimVar[val_marker][val_vertex]; + } + + /*! + * \brief Value of the characteristic variables at the boundaries. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline void SetCharacPrimVar(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_var, + su2double val_value) final { + CharacPrimVar[val_marker][val_vertex][val_var] = val_value; + } + + /*! + * \brief Value of the characteristic variables at the boundaries. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline su2double *GetDonorPrimVar(unsigned short val_marker, unsigned long val_vertex) const final{ + return DonorPrimVar[val_marker][val_vertex]; + } + + /*! + * \brief Value of the characteristic variables at the boundaries. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline void SetDonorPrimVar(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_var, + su2double val_value) final { + DonorPrimVar[val_marker][val_vertex][val_var] = val_value; + } + + /*! + * \brief Value of the characteristic variables at the boundaries. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline su2double GetDonorPrimVar(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_var) const final { + return DonorPrimVar[val_marker][val_vertex][val_var]; + } + + /*! + * \brief Value of the characteristic global index at the boundaries. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline unsigned long GetDonorGlobalIndex(unsigned short val_marker, + unsigned long val_vertex) const final { + return DonorGlobalIndex[val_marker][val_vertex]; + } + + /*! + * \brief Value of the characteristic global index at the boundaries. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline void SetDonorGlobalIndex(unsigned short val_marker, + unsigned long val_vertex, + unsigned long val_index) final { + DonorGlobalIndex[val_marker][val_vertex] = val_index; + } + + /*! + * \brief Value of the characteristic global index at the boundaries. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline su2double GetActDisk_DeltaP(unsigned short val_marker, + unsigned long val_vertex) const final { + return ActDisk_DeltaP[val_marker][val_vertex]; + } + + /*! + * \brief Value of the characteristic global index at the boundaries. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline void SetActDisk_DeltaP(unsigned short val_marker, + unsigned long val_vertex, + su2double val_deltap) final { ActDisk_DeltaP[val_marker][val_vertex] = val_deltap; } + + /*! + * \brief Value of the characteristic global index at the boundaries. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline su2double GetActDisk_DeltaT(unsigned short val_marker, unsigned long val_vertex) final { + return ActDisk_DeltaT[val_marker][val_vertex]; + } + + /*! + * \brief Value of the characteristic global index at the boundaries. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline void SetActDisk_DeltaT(unsigned short val_marker, + unsigned long val_vertex, + su2double val_deltat) final { + ActDisk_DeltaT[val_marker][val_vertex] = val_deltat; + } + + /*! + * \brief Value of the total temperature at an inlet boundary. + * \param[in] val_marker - Surface marker where the total temperature is evaluated. + * \param[in] val_vertex - Vertex of the marker val_marker where the total temperature is evaluated. + * \return Value of the total temperature + */ + inline su2double GetInlet_Ttotal(unsigned short val_marker, unsigned long val_vertex) const final { return Inlet_Ttotal[val_marker][val_vertex]; } + + /*! + * \brief Value of the total pressure at an inlet boundary. + * \param[in] val_marker - Surface marker where the total pressure is evaluated. + * \param[in] val_vertex - Vertex of the marker val_marker where the total pressure is evaluated. + * \return Value of the total pressure + */ + inline su2double GetInlet_Ptotal(unsigned short val_marker, unsigned long val_vertex) const final { return Inlet_Ptotal[val_marker][val_vertex]; } + + /*! + * \brief A component of the unit vector representing the flow direction at an inlet boundary. + * \param[in] val_marker - Surface marker where the flow direction is evaluated + * \param[in] val_vertex - Vertex of the marker val_marker where the flow direction is evaluated + * \param[in] val_dim - The component of the flow direction unit vector to be evaluated + * \return Component of a unit vector representing the flow direction. + */ + inline su2double GetInlet_FlowDir(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_dim) const final { + return Inlet_FlowDir[val_marker][val_vertex][val_dim]; + } + + /*! + * \brief Set the value of the total temperature at an inlet boundary. + * \param[in] val_marker - Surface marker where the total temperature is set. + * \param[in] val_vertex - Vertex of the marker val_marker where the total temperature is set. + * \param[in] val_ttotal - Value of the total temperature + */ + inline void SetInlet_Ttotal(unsigned short val_marker, + unsigned long val_vertex, + su2double val_ttotal) final { + /*--- Since this call can be accessed indirectly using python, do some error + * checking to prevent segmentation faults ---*/ + if (val_marker >= nMarker) + SU2_MPI::Error("Out-of-bounds marker index used on inlet.", CURRENT_FUNCTION); + else if (Inlet_Ttotal == NULL || Inlet_Ttotal[val_marker] == NULL) + SU2_MPI::Error("Tried to set custom inlet BC on an invalid marker.", CURRENT_FUNCTION); + else if (val_vertex >= nVertex[val_marker]) + SU2_MPI::Error("Out-of-bounds vertex index used on inlet.", CURRENT_FUNCTION); + else + Inlet_Ttotal[val_marker][val_vertex] = val_ttotal; + } + + + /*! + * \brief Set the value of the total pressure at an inlet boundary. + * \param[in] val_marker - Surface marker where the total pressure is set. + * \param[in] val_vertex - Vertex of the marker val_marker where the total pressure is set. + * \param[in] val_ptotal - Value of the total pressure + */ + inline void SetInlet_Ptotal(unsigned short val_marker, + unsigned long val_vertex, + su2double val_ptotal) final { + /*--- Since this call can be accessed indirectly using python, do some error + * checking to prevent segmentation faults ---*/ + if (val_marker >= nMarker) + SU2_MPI::Error("Out-of-bounds marker index used on inlet.", CURRENT_FUNCTION); + else if (Inlet_Ptotal == NULL || Inlet_Ptotal[val_marker] == NULL) + SU2_MPI::Error("Tried to set custom inlet BC on an invalid marker.", CURRENT_FUNCTION); + else if (val_vertex >= nVertex[val_marker]) + SU2_MPI::Error("Out-of-bounds vertex index used on inlet.", CURRENT_FUNCTION); + else + Inlet_Ptotal[val_marker][val_vertex] = val_ptotal; + } + + + /*! + * \brief Set a component of the unit vector representing the flow direction at an inlet boundary. + * \param[in] val_marker - Surface marker where the flow direction is set. + * \param[in] val_vertex - Vertex of the marker val_marker where the flow direction is set. + * \param[in] val_dim - The component of the flow direction unit vector to be set + * \param[in] val_flowdir - Component of a unit vector representing the flow direction. + */ + inline void SetInlet_FlowDir(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_dim, + su2double val_flowdir) final { + /*--- Since this call can be accessed indirectly using python, do some error + * checking to prevent segmentation faults ---*/ + if (val_marker >= nMarker) + SU2_MPI::Error("Out-of-bounds marker index used on inlet.", CURRENT_FUNCTION); + else if (Inlet_FlowDir == NULL || Inlet_FlowDir[val_marker] == NULL) + SU2_MPI::Error("Tried to set custom inlet BC on an invalid marker.", CURRENT_FUNCTION); + else if (val_vertex >= nVertex[val_marker]) + SU2_MPI::Error("Out-of-bounds vertex index used on inlet.", CURRENT_FUNCTION); + else + Inlet_FlowDir[val_marker][val_vertex][val_dim] = val_flowdir; + } + + + /*! + * \brief Set a uniform inlet profile + * + * The values at the inlet are set to match the values specified for + * inlets in the configuration file. + * + * \param[in] config - Definition of the particular problem. + * \param[in] iMarker - Surface marker where the coefficient is computed. + */ + void SetUniformInlet(CConfig* config, unsigned short iMarker) final; + + /*! + * \brief Store of a set of provided inlet profile values at a vertex. + * \param[in] val_inlet - vector containing the inlet values for the current vertex. + * \param[in] iMarker - Surface marker where the coefficient is computed. + * \param[in] iVertex - Vertex of the marker iMarker where the inlet is being set. + */ + void SetInletAtVertex(su2double *val_inlet, + unsigned short iMarker, + unsigned long iVertex) final; + + /*! + * \brief Get the set of value imposed at an inlet. + * \param[in] val_inlet - vector returning the inlet values for the current vertex. + * \param[in] val_inlet_point - Node index where the inlet is being set. + * \param[in] val_kind_marker - Enumerated type for the particular inlet type. + * \param[in] geometry - Geometrical definition of the problem. + * \param config - Definition of the particular problem. + * \return Value of the face area at the vertex. + */ + su2double GetInletAtVertex(su2double *val_inlet, + unsigned long val_inlet_point, + unsigned short val_kind_marker, + string val_marker, + CGeometry *geometry, + CConfig *config) const final; + + /*! + * \brief Update the multi-grid structure for the customized boundary conditions + * \param geometry_container - Geometrical definition. + * \param config - Definition of the particular problem. + */ + void UpdateCustomBoundaryConditions(CGeometry **geometry_container, CConfig *config) final; + + /*! + * \brief Set the total residual adding the term that comes from the Dual Time Strategy. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + */ + void SetResidual_DualTime(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iRKStep, + unsigned short iMesh, + unsigned short RunTime_EqSystem) final; + + /*! + * \brief Load a solution from a restart file. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Container vector with all of the solvers. + * \param[in] config - Definition of the particular problem. + * \param[in] val_iter - Current external iteration number. + * \param[in] val_update_geo - Flag for updating coords and grid velocity. + */ + void LoadRestart(CGeometry **geometry, + CSolver ***solver, + CConfig *config, + int val_iter, + bool val_update_geo) final; + + /*! + * \brief Allocates the final pointer of SlidingState depending on how many donor vertex donate to it. That number is stored in SlidingStateNodes[val_marker][val_vertex]. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + */ + inline void SetSlidingStateStructure(unsigned short val_marker, unsigned long val_vertex) final { + int iVar; + + for( iVar = 0; iVar < nPrimVar+1; iVar++){ + if( SlidingState[val_marker][val_vertex][iVar] != NULL ) + delete [] SlidingState[val_marker][val_vertex][iVar]; + } + + for( iVar = 0; iVar < nPrimVar+1; iVar++) + SlidingState[val_marker][val_vertex][iVar] = new su2double[ GetnSlidingStates(val_marker, val_vertex) ]; + } + + + + /*! + * \brief Set the outer state for fluid interface nodes. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + * \param[in] val_state - requested state component + * \param[in] donor_index - index of the donor node to set + * \param[in] component - set value + */ + inline void SetSlidingState(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_state, + unsigned long donor_index, + su2double component) final { + SlidingState[val_marker][val_vertex][val_state][donor_index] = component; + } + + + /*! + * \brief Set the number of outer state for fluid interface nodes. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + * \param[in] value - number of outer states + */ + inline void SetnSlidingStates(unsigned short val_marker, + unsigned long val_vertex, + int value) final { SlidingStateNodes[val_marker][val_vertex] = value; } + + /*! + * \brief Get the number of outer state for fluid interface nodes. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + */ + inline int GetnSlidingStates(unsigned short val_marker, unsigned long val_vertex) const final { + return SlidingStateNodes[val_marker][val_vertex]; + } + + /*! + * \brief Set the initial condition for the Euler Equations. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] ExtIter - External iteration. + */ + void SetInitialCondition(CGeometry **geometry, + CSolver ***solver_container, + CConfig *config, + unsigned long TimeIter) final; + + /*! + * \brief Set the freestream pressure. + * \param[in] Value of freestream pressure. + */ + inline void SetPressure_Inf(su2double p_inf) final {Pressure_Inf = p_inf;} + + /*! + * \brief Set the freestream temperature. + * \param[in] Value of freestream temperature. + */ + inline void SetTemperature_Inf(su2double t_inf) final {Temperature_Inf = t_inf;} + + /*! + * \brief Set the solution using the Freestream values. + * \param[in] config - Definition of the particular problem. + */ + void SetFreeStream_Solution(CConfig *config) final; + + /*! + * \brief Initilize turbo containers. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void InitTurboContainers(CGeometry *geometry, CConfig *config) final; + + /*! + * \brief Set the solution using the Freestream values. + * \param[in] config - Definition of the particular problem. + */ + void SetFreeStream_TurboSolution(CConfig *config) final; + + /*! + * \brief It computes average quantities along the span for turbomachinery analysis. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] marker_flag - Surface marker flag where the function is applied. + */ + void PreprocessAverage(CSolver **solver, + CGeometry *geometry, + CConfig *config, + unsigned short marker_flag) final; + + /*! + * \brief It computes average quantities along the span for turbomachinery analysis. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] marker_flag - Surface marker flag where the function is applied. + */ + void TurboAverageProcess(CSolver **solver, + CGeometry *geometry, + CConfig *config, + unsigned short marker_flag) final; + + /*! + * \brief it performs a mixed out average of the nodes of a boundary. + * \param[in] val_init_pressure - initial pressure value + * \param[in] val_Averaged_Flux - flux averaged values. + * \param[in] val_normal - normal vector. + * \param[in] pressure_mix - value of the mixed-out avaraged pressure. + * \param[in] density_miz - value of the mixed-out avaraged density. + */ + void MixedOut_Average (CConfig *config, + su2double val_init_pressure, + const su2double *val_Averaged_Flux, + const su2double *val_normal, + su2double& pressure_mix, + su2double& density_mix); + + /*! + * \brief It gathers into the master node average quantities at inflow and outflow needed for turbomachinery analysis. + * \param[in] config - Definition of the particular problem. + * \param[in] geometry - Geometrical definition of the problem. + */ + void GatherInOutAverageValues(CConfig *config, CGeometry *geometry) final; + + /*! + * \brief it take a velocity in the cartesian reference of framework and transform into the turbomachinery frame of reference. + * \param[in] cartesianVelocity - cartesian components of velocity vector. + * \param[in] turboNormal - normal vector in the turbomachinery frame of reference. + * \param[in] turboVelocity - velocity vector in the turbomachinery frame of reference. + */ + inline void ComputeTurboVelocity(const su2double *cartesianVelocity, + const su2double *turboNormal, + su2double *turboVelocity, + unsigned short marker_flag, + unsigned short kind_turb){ + + if ((kind_turb == AXIAL && nDim == 3) || (kind_turb == CENTRIPETAL_AXIAL && marker_flag == OUTFLOW) || (kind_turb == AXIAL_CENTRIFUGAL && marker_flag == INFLOW) ){ + turboVelocity[2] = turboNormal[0]*cartesianVelocity[0] + cartesianVelocity[1]*turboNormal[1]; + turboVelocity[1] = turboNormal[0]*cartesianVelocity[1] - turboNormal[1]*cartesianVelocity[0]; + turboVelocity[0] = cartesianVelocity[2]; + } + else{ + turboVelocity[0] = turboNormal[0]*cartesianVelocity[0] + cartesianVelocity[1]*turboNormal[1]; + turboVelocity[1] = turboNormal[0]*cartesianVelocity[1] - turboNormal[1]*cartesianVelocity[0]; + if (marker_flag == INFLOW){ + turboVelocity[0] *= -1.0; + turboVelocity[1] *= -1.0; + } + if(nDim == 3) + turboVelocity[2] = cartesianVelocity[2]; + } + } + + /*! + * \brief it take a velocity in the cartesian reference of framework and transform into the turbomachinery frame of reference. + * \param[in] cartesianVelocity - cartesian components of velocity vector. + * \param[in] turboNormal - normal vector in the turbomachinery frame of reference. + * \param[in] turboVelocity - velocity vector in the turbomachinery frame of reference. + */ + inline void ComputeBackVelocity(const su2double *turboVelocity, + const su2double *turboNormal, + su2double *cartesianVelocity, + unsigned short marker_flag, + unsigned short kind_turb){ + + if ((kind_turb == AXIAL && nDim == 3) || (kind_turb == CENTRIPETAL_AXIAL && marker_flag == OUTFLOW) || (kind_turb == AXIAL_CENTRIFUGAL && marker_flag == INFLOW)){ + cartesianVelocity[0] = turboVelocity[2]*turboNormal[0] - turboVelocity[1]*turboNormal[1]; + cartesianVelocity[1] = turboVelocity[2]*turboNormal[1] + turboVelocity[1]*turboNormal[0]; + cartesianVelocity[2] = turboVelocity[0]; + } + else{ + cartesianVelocity[0] = turboVelocity[0]*turboNormal[0] - turboVelocity[1]*turboNormal[1]; + cartesianVelocity[1] = turboVelocity[0]*turboNormal[1] + turboVelocity[1]*turboNormal[0]; + + if (marker_flag == INFLOW){ + cartesianVelocity[0] *= -1.0; + cartesianVelocity[1] *= -1.0; + } + + if(nDim == 3) + cartesianVelocity[2] = turboVelocity[2]; + } + } + + /*! + * \brief Provide the average density at the boundary of interest. + * \param[in] val_marker - bound marker. + * \return Value of the Average Density on the surface val_marker. + */ + inline su2double GetAverageDensity(unsigned short valMarker, unsigned short valSpan) const final { + return AverageDensity[valMarker][valSpan]; + } + + /*! + * \brief Provide the average pressure at the boundary of interest. + * \param[in] val_marker - bound marker. + * \return Value of the Average Pressure on the surface val_marker. + */ + inline su2double GetAveragePressure(unsigned short valMarker, unsigned short valSpan) const final { + return AveragePressure[valMarker][valSpan]; + } + + /*! + * \brief Provide the average turbo velocity average at the boundary of interest. + * \param[in] val_marker - bound marker. + * \return Value of the Average Total Pressure on the surface val_marker. + */ + inline su2double* GetAverageTurboVelocity(unsigned short valMarker, unsigned short valSpan) const final { + return AverageTurboVelocity[valMarker][valSpan]; + } + + /*! + * \brief Provide the average density at the boundary of interest. + * \param[in] val_marker - bound marker. + * \return Value of the Average turbulent Nu on the surface val_marker. + */ + inline su2double GetAverageNu(unsigned short valMarker, unsigned short valSpan) const final { + return AverageNu[valMarker][valSpan]; + } + + /*! + * \brief Provide the average density at the boundary of interest. + * \param[in] val_marker - bound marker. + * \return Value of the Average turbulent Kine on the surface val_marker. + */ + inline su2double GetAverageKine(unsigned short valMarker, unsigned short valSpan) const final { + return AverageKine[valMarker][valSpan]; + } + + /*! + * \brief Provide the average density at the boundary of interest. + * \param[in] val_marker - bound marker. + * \return Value of the Average turbulent Omega on the surface val_marker. + */ + inline su2double GetAverageOmega(unsigned short valMarker, unsigned short valSpan) const final { + return AverageOmega[valMarker][valSpan]; + } + + /*! + * \brief Provide the average density at the boundary of interest. + * \param[in] val_marker - bound marker. + * \return Value of the Average turbulent Nu on the surface val_marker. + */ + inline su2double GetExtAverageNu(unsigned short valMarker, unsigned short valSpan) const final { + return ExtAverageNu[valMarker][valSpan]; + } + + /*! + * \brief Provide the average density at the boundary of interest. + * \param[in] val_marker - bound marker. + * \return Value of the Average turbulent Kine on the surface val_marker. + */ + inline su2double GetExtAverageKine(unsigned short valMarker, unsigned short valSpan) const final { + return ExtAverageKine[valMarker][valSpan]; + } + + /*! + * \brief Provide the average density at the boundary of interest. + * \param[in] val_marker - bound marker. + * \return Value of the Average turbulent Omega on the surface val_marker. + */ + inline su2double GetExtAverageOmega(unsigned short valMarker, unsigned short valSpan) const final { + return ExtAverageOmega[valMarker][valSpan]; + } + + /*! + * \brief Set the external average density at the boundary of interest. + * \param[in] val_marker - bound marker. + * \param[in] val_Span - value of the Span. + * \param[in] valDensity - value to set. + */ + inline void SetExtAverageDensity(unsigned short valMarker, + unsigned short valSpan, + su2double valDensity) final { + ExtAverageDensity[valMarker][valSpan] = valDensity; + } + + /*! + * \brief Set the external average density at the boundary of interest. + * \param[in] val_marker - bound marker. + * \param[in] val_Span - value of the Span. + * \param[in] valPressure - value to set. + */ + inline void SetExtAveragePressure(unsigned short valMarker, + unsigned short valSpan, + su2double valPressure) final { + ExtAveragePressure[valMarker][valSpan] = valPressure; + } + + /*! + * \brief Set the external the average turbo velocity average at the boundary of interest. + * \param[in] val_marker - bound marker. + * \return Value of the Average Total Pressure on the surface val_marker. + */ + inline void SetExtAverageTurboVelocity(unsigned short valMarker, + unsigned short valSpan, + unsigned short valIndex, + su2double valTurboVelocity) final { + ExtAverageTurboVelocity[valMarker][valSpan][valIndex] = valTurboVelocity; + } + + /*! + * \brief Set the external average turbulent Nu at the boundary of interest. + * \param[in] val_marker - bound marker. + * \param[in] val_Span - value of the Span. + * \param[in] valNu - value to set. + */ + inline void SetExtAverageNu(unsigned short valMarker, + unsigned short valSpan, + su2double valNu) final { + ExtAverageNu[valMarker][valSpan] = valNu; + } + + /*! + * \brief Set the external average turbulent Kine at the boundary of interest. + * \param[in] val_marker - bound marker. + * \param[in] val_Span - value of the Span. + * \param[in] valKine - value to set. + */ + inline void SetExtAverageKine(unsigned short valMarker, + unsigned short valSpan, + su2double valKine) final { + ExtAverageKine[valMarker][valSpan] = valKine; + } + + /*! + * \brief Set the external average turbulent Omega at the boundary of interest. + * \param[in] val_marker - bound marker. + * \param[in] val_Span - value of the Span. + * \param[in] valOmega - value to set. + */ + inline void SetExtAverageOmega(unsigned short valMarker, + unsigned short valSpan, + su2double valOmega) final { + ExtAverageOmega[valMarker][valSpan] = valOmega; + } + + /*! + * \brief Provide the inlet density to check convergence of conservative mixing-plane. + * \param[in] inMarkerTP - bound marker. + * \return Value of the inlet density. + */ + inline su2double GetDensityIn(unsigned short inMarkerTP, unsigned short valSpan) const final { + return DensityIn[inMarkerTP][valSpan]; + } + + /*! + * \brief Provide the inlet pressure to check convergence of conservative mixing-plane. + * \param[in] inMarkerTP - bound marker. + * \return Value of inlet pressure. + */ + inline su2double GetPressureIn(unsigned short inMarkerTP, unsigned short valSpan) const final { + return PressureIn[inMarkerTP][valSpan]; + } + + /*! + * \brief Provide the inlet normal velocity to check convergence of conservative mixing-plane. + * \param[in] inMarkerTP - bound marker. + * \return Value of the inlet normal velocity. + */ + inline su2double* GetTurboVelocityIn(unsigned short inMarkerTP, unsigned short valSpan) const final { + return TurboVelocityIn[inMarkerTP][valSpan]; + } + + /*! + * \brief Provide the outlet density to check convergence of conservative mixing-plane. + * \param[in] inMarkerTP - bound marker. + * \return Value of the outlet density. + */ + inline su2double GetDensityOut(unsigned short inMarkerTP, unsigned short valSpan) const final { + return DensityOut[inMarkerTP][valSpan]; + } + + /*! + * \brief Provide the outlet pressure to check convergence of conservative mixing-plane. + * \param[in] inMarkerTP - bound marker. + * \return Value of the outlet pressure. + */ + inline su2double GetPressureOut(unsigned short inMarkerTP, unsigned short valSpan) const final { + return PressureOut[inMarkerTP][valSpan]; + } + + /*! + * \brief Provide the outlet normal velocity to check convergence of conservative mixing-plane. + * \param[in] inMarkerTP - bound marker. + * \return Value of the outlet normal velocity. + */ + inline su2double* GetTurboVelocityOut(unsigned short inMarkerTP, unsigned short valSpan) const final { + return TurboVelocityOut[inMarkerTP][valSpan]; + } + + /*! + * \brief Provide the inlet turbulent kei to check convergence of conservative mixing-plane. + * \param[in] inMarkerTP - bound marker. + * \return Value of the inlet density. + */ + inline su2double GetKineIn(unsigned short inMarkerTP, unsigned short valSpan) const final { + return KineIn[inMarkerTP][valSpan]; + } + + /*! + * \brief Provide the inlet turbulent omega to check convergence of conservative mixing-plane. + * \param[in] inMarkerTP - bound marker. + * \return Value of the inlet density. + */ + inline su2double GetOmegaIn(unsigned short inMarkerTP, unsigned short valSpan) const final { + return OmegaIn[inMarkerTP][valSpan]; + } + + /*! + * \brief Provide the inlet turbulent nu to check convergence of conservative mixing-plane. + * \param[in] inMarkerTP - bound marker. + * \return Value of the inlet density. + */ + inline su2double GetNuIn(unsigned short inMarkerTP, unsigned short valSpan) const final { + return NuIn[inMarkerTP][valSpan]; + } + + /*! + * \brief Provide the outlet turbulent kei to check convergence of conservative mixing-plane. + * \param[in] inMarkerTP - bound marker. + * \return Value of the inlet density. + */ + inline su2double GetKineOut(unsigned short inMarkerTP, unsigned short valSpan) const final { + return KineOut[inMarkerTP][valSpan]; + } + + /*! + * \brief Provide the outlet turbulent omega to check convergence of conservative mixing-plane. + * \param[in] inMarkerTP - bound marker. + * \return Value of the inlet density. + */ + inline su2double GetOmegaOut(unsigned short inMarkerTP, unsigned short valSpan) const final { + return OmegaOut[inMarkerTP][valSpan]; + } + + /*! + * \brief Provide the outlet turbulent nu to check convergence of conservative mixing-plane. + * \param[in] inMarkerTP - bound marker. + * \return Value of the inlet density. + */ + inline su2double GetNuOut(unsigned short inMarkerTP, unsigned short valSpan) const final { + return NuOut[inMarkerTP][valSpan]; + } + + /*! + * \brief Set inlet density. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline void SetDensityIn(su2double value, + unsigned short inMarkerTP, + unsigned short valSpan) final { + DensityIn[inMarkerTP][valSpan] = value; + } + + /*! + * \brief Set inlet pressure. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline void SetPressureIn(su2double value, + unsigned short inMarkerTP, + unsigned short valSpan) final { + PressureIn[inMarkerTP][valSpan] = value; + } + + /*! + * \brief Set inlet normal velocity. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline void SetTurboVelocityIn(su2double *value, + unsigned short inMarkerTP, + unsigned short valSpan) final { + unsigned short iDim; + + for(iDim = 0; iDim < nDim; iDim++) + TurboVelocityIn[inMarkerTP][valSpan][iDim] = value[iDim]; + } + + /*! + * \brief Set outlet density. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline void SetDensityOut(su2double value, + unsigned short inMarkerTP, + unsigned short valSpan) final { + DensityOut[inMarkerTP][valSpan] = value; + } + + /*! + * \brief Set outlet pressure. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline void SetPressureOut(su2double value, + unsigned short inMarkerTP, + unsigned short valSpan) final { + PressureOut[inMarkerTP][valSpan] = value; + } + + /*! + * \brief Set outlet normal velocity. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline void SetTurboVelocityOut(su2double *value, + unsigned short inMarkerTP, + unsigned short valSpan) final { + unsigned short iDim; + + for(iDim = 0; iDim < nDim; iDim++) + TurboVelocityOut[inMarkerTP][valSpan][iDim] = value[iDim]; + } + + /*! + * \brief Set inlet turbulent kei. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline void SetKineIn(su2double value, + unsigned short inMarkerTP, + unsigned short valSpan) final { + KineIn[inMarkerTP][valSpan] = value; + } + /*! + * \brief Set inlet turbulent omega. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline void SetOmegaIn(su2double value, + unsigned short inMarkerTP, + unsigned short valSpan) final { + OmegaIn[inMarkerTP][valSpan] = value; + } + + /*! + * \brief Set inlet turbulent Nu. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline void SetNuIn(su2double value, + unsigned short inMarkerTP, + unsigned short valSpan) final { + NuIn[inMarkerTP][valSpan] = value; + } + + /*! + * \brief Set outlet turbulent kei. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline void SetKineOut(su2double value, + unsigned short inMarkerTP, + unsigned short valSpan) final { + KineOut[inMarkerTP][valSpan] = value; + } + + /*! + * \brief Set Outlet turbulent omega. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline void SetOmegaOut(su2double value, + unsigned short inMarkerTP, + unsigned short valSpan) final { + OmegaOut[inMarkerTP][valSpan] = value; + } + + /*! + * \brief Set outlet turbulent Nu. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline void SetNuOut(su2double value, + unsigned short inMarkerTP, + unsigned short valSpan) final { + NuOut[inMarkerTP][valSpan] = value; + } + + /*! + * \brief Compute the global error measures (L2, Linf) for verification cases. + * \param[in] geometry - Geometrical definition. + * \param[in] config - Definition of the particular problem. + */ + void ComputeVerificationError(CGeometry *geometry, CConfig *config) final; + +}; diff --git a/SU2_CFD/include/solvers/CFEASolver.hpp b/SU2_CFD/include/solvers/CFEASolver.hpp index 0541bd51dd29..503f7627d5fe 100644 --- a/SU2_CFD/include/solvers/CFEASolver.hpp +++ b/SU2_CFD/include/solvers/CFEASolver.hpp @@ -27,7 +27,7 @@ #pragma once -#include "../solver_structure.hpp" +#include "CSolver.hpp" /*! * \class CFEASolver @@ -45,7 +45,7 @@ class CFEASolver : public CSolver { su2double Total_CFEA; /*!< \brief Total FEA coefficient for all the boundaries. */ - unsigned short *iElem_iDe; /*!< \brief For DE cases, ID of the region considered for each iElem. */ + unsigned short *iElem_iDe; /*!< \brief For DE cases, ID of the region considered for each iElem. */ su2double a_dt[9]; /*!< \brief Integration constants. */ @@ -148,8 +148,12 @@ class CFEASolver : public CSolver { * \param[in] der - Value of the derivative. * \param[in] der_avg - Time-averaged value of the derivative. */ - void OutputForwardModeGradient(CConfig *config, bool newFile, su2double fun, - su2double fun_avg, su2double der, su2double der_avg) const; + void OutputForwardModeGradient(CConfig *config, + bool newFile, + su2double fun, + su2double fun_avg, + su2double der, + su2double der_avg) const; public: @@ -190,8 +194,14 @@ class CFEASolver : public CSolver { * \param[in] iRKStep - Current step of the Runge-Kutta iteration. * \param[in] RunTime_EqSystem - System of equations which is going to be solved. */ - void Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, CNumerics **numerics, - unsigned short iMesh, unsigned long Iteration, unsigned short RunTime_EqSystem, bool Output) override; + void Preprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + CNumerics **numerics, + unsigned short iMesh, + unsigned long Iteration, + unsigned short RunTime_EqSystem, + bool Output) override; /*! * \brief Set the initial condition for the FEM structural problem. @@ -200,8 +210,10 @@ class CFEASolver : public CSolver { * \param[in] config - Definition of the particular problem. * \param[in] ExtIter - External iteration. */ - void SetInitialCondition(CGeometry **geometry, CSolver ***solver_container, - CConfig *config, unsigned long TimeIter) override; + void SetInitialCondition(CGeometry **geometry, + CSolver ***solver_container, + CConfig *config, + unsigned long TimeIter) override; /*! * \brief Reset the initial condition for the FEM structural problem. @@ -210,8 +222,10 @@ class CFEASolver : public CSolver { * \param[in] config - Definition of the particular problem. * \param[in] ExtIter - External iteration. */ - void ResetInitialCondition(CGeometry **geometry, CSolver ***solver_container, - CConfig *config, unsigned long TimeIter) override; + void ResetInitialCondition(CGeometry **geometry, + CSolver ***solver_container, + CConfig *config, + unsigned long TimeIter) override; /*! * \brief Compute the time step for solving the FEM equations. @@ -221,8 +235,11 @@ class CFEASolver : public CSolver { * \param[in] iMesh - Index of the mesh in multigrid computations. * \param[in] Iteration - Index of the current iteration. */ - inline void SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh, unsigned long Iteration) override { } + inline void SetTime_Step(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned long Iteration) override { } /*! * \brief Get the value of the reference coordinate to set on the element structure. @@ -230,7 +247,9 @@ class CFEASolver : public CSolver { * \param[in] indexNode - Index of the node. * \param[in] iDim - Dimension required. */ - inline virtual su2double Get_ValCoord(CGeometry *geometry, unsigned long indexNode, unsigned short iDim) const { + inline virtual su2double Get_ValCoord(CGeometry *geometry, + unsigned long indexNode, + unsigned short iDim) const { return geometry->node[indexNode]->GetCoord(iDim); } @@ -241,7 +260,9 @@ class CFEASolver : public CSolver { * \param[in] solver - Description of the numerical method. * \param[in] config - Definition of the particular problem. */ - void Compute_StiffMatrix(CGeometry *geometry, CNumerics **numerics, CConfig *config) final; + void Compute_StiffMatrix(CGeometry *geometry, + CNumerics **numerics, + CConfig *config) final; /*! * \brief Compute the stiffness matrix of the problem and the nodal stress terms at the same time. @@ -251,7 +272,9 @@ class CFEASolver : public CSolver { * \param[in] solver - Description of the numerical method. * \param[in] config - Definition of the particular problem. */ - void Compute_StiffMatrix_NodalStressRes(CGeometry *geometry, CNumerics **numerics, CConfig *config) final; + void Compute_StiffMatrix_NodalStressRes(CGeometry *geometry, + CNumerics **numerics, + CConfig *config) final; /*! * \brief Compute the mass matrix of the problem. @@ -259,7 +282,9 @@ class CFEASolver : public CSolver { * \param[in] solver - Description of the numerical method. * \param[in] config - Definition of the particular problem. */ - void Compute_MassMatrix(CGeometry *geometry, CNumerics **numerics, CConfig *config) final; + void Compute_MassMatrix(CGeometry *geometry, + CNumerics **numerics, + CConfig *config) final; /*! * \brief Compute the mass residual of the problem. @@ -267,7 +292,9 @@ class CFEASolver : public CSolver { * \param[in] solver - Description of the numerical method. * \param[in] config - Definition of the particular problem. */ - void Compute_MassRes(CGeometry *geometry, CNumerics **numerics, CConfig *config) final; + void Compute_MassRes(CGeometry *geometry, + CNumerics **numerics, + CConfig *config) final; /*! * \brief Compute the nodal stress terms and add them to the residual. @@ -275,7 +302,9 @@ class CFEASolver : public CSolver { * \param[in] solver - Description of the numerical method. * \param[in] config - Definition of the particular problem. */ - void Compute_NodalStressRes(CGeometry *geometry, CNumerics **numerics, CConfig *config) final; + void Compute_NodalStressRes(CGeometry *geometry, + CNumerics **numerics, + CConfig *config) final; /*! * \brief Compute the stress at the nodes for output purposes. @@ -284,7 +313,9 @@ class CFEASolver : public CSolver { * \param[in] solver - Description of the numerical method. * \param[in] config - Definition of the particular problem. */ - void Compute_NodalStress(CGeometry *geometry, CNumerics **numerics, CConfig *config) final; + void Compute_NodalStress(CGeometry *geometry, + CNumerics **numerics, + CConfig *config) final; /*! * \brief Compute the dead loads. @@ -293,7 +324,9 @@ class CFEASolver : public CSolver { * \param[in] solver - Description of the numerical method. * \param[in] config - Definition of the particular problem. */ - void Compute_DeadLoad(CGeometry *geometry, CNumerics **numerics, CConfig *config) final; + void Compute_DeadLoad(CGeometry *geometry, + CNumerics **numerics, + CConfig *config) final; /*! * \brief Clamped boundary conditions. @@ -301,7 +334,10 @@ class CFEASolver : public CSolver { * \param[in] solver - Description of the numerical method. * \param[in] config - Definition of the particular problem. */ - void BC_Clamped(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker) final; + void BC_Clamped(CGeometry *geometry, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) final; /*! * \brief Enforce the solution to be 0 in the clamped nodes - Avoids accumulation of numerical error. @@ -310,7 +346,10 @@ class CFEASolver : public CSolver { * \param[in] config - Definition of the particular problem. * \param[in] val_marker - Surface marker where the boundary condition is applied. */ - void BC_Clamped_Post(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker) final; + void BC_Clamped_Post(CGeometry *geometry, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) final; /*! * \brief A virtual member. @@ -320,7 +359,10 @@ class CFEASolver : public CSolver { * \param[in] val_marker - Surface marker where the boundary condition is applied. */ - void BC_DispDir(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker) final; + void BC_DispDir(CGeometry *geometry, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) final; /*! * \brief Impose a displacement (constraint) boundary condition. @@ -329,8 +371,10 @@ class CFEASolver : public CSolver { * \param[in] config - Definition of the particular problem. * \param[in] val_marker - Surface marker where the boundary condition is applied. */ - inline void BC_Normal_Displacement(CGeometry *geometry, CNumerics *numerics, - CConfig *config, unsigned short val_marker) final { } + inline void BC_Normal_Displacement(CGeometry *geometry, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) final { } /*! * \brief Impose a load boundary condition normal to the boundary. @@ -339,7 +383,10 @@ class CFEASolver : public CSolver { * \param[in] config - Definition of the particular problem. * \param[in] val_marker - Surface marker where the boundary condition is applied. */ - void BC_Normal_Load(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker) final; + void BC_Normal_Load(CGeometry *geometry, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) final; /*! * \brief Impose a load boundary condition in cartesian coordinates. @@ -348,7 +395,10 @@ class CFEASolver : public CSolver { * \param[in] config - Definition of the particular problem. * \param[in] val_marker - Surface marker where the boundary condition is applied. */ - void BC_Dir_Load(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker) final; + void BC_Dir_Load(CGeometry *geometry, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) final; /*! * \brief Impose a sine-wave load boundary condition in cartesian coordinates. @@ -357,7 +407,10 @@ class CFEASolver : public CSolver { * \param[in] config - Definition of the particular problem. * \param[in] val_marker - Surface marker where the boundary condition is applied. */ - inline void BC_Sine_Load(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker) final { } + inline void BC_Sine_Load(CGeometry *geometry, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) final { } /*! * \brief Impose a damping load. @@ -366,7 +419,10 @@ class CFEASolver : public CSolver { * \param[in] config - Definition of the particular problem. * \param[in] val_marker - Surface marker where the boundary condition is applied. */ - void BC_Damper(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker) final; + void BC_Damper(CGeometry *geometry, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) final; /*! * \brief Deformable boundary condition. @@ -375,7 +431,10 @@ class CFEASolver : public CSolver { * \param[in] config - Definition of the particular problem. * \param[in] val_marker - Surface marker where the boundary condition is applied. */ - void BC_Deforming(CGeometry *geometry, CNumerics *numerics, CConfig *config, unsigned short val_marker) final; + void BC_Deforming(CGeometry *geometry, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) final; /*! * \brief Required step for non conservative interpolation schemes where stresses are transferred instead of forces. @@ -390,7 +449,9 @@ class CFEASolver : public CSolver { * \param[in] solver_container - Container vector with all the solutions. * \param[in] config - Definition of the particular problem. */ - inline void ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) final { }; + inline void ImplicitEuler_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) final { }; /*! * \brief Iterate using an implicit Newmark solver. @@ -398,7 +459,9 @@ class CFEASolver : public CSolver { * \param[in] solver_container - Container vector with all the solutions. * \param[in] config - Definition of the particular problem. */ - void ImplicitNewmark_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) final; + void ImplicitNewmark_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) final; /*! * \brief Update the solution using an implicit Newmark solver. @@ -406,7 +469,9 @@ class CFEASolver : public CSolver { * \param[in] solver_container - Container vector with all the solutions. * \param[in] config - Definition of the particular problem. */ - void ImplicitNewmark_Update(CGeometry *geometry, CSolver **solver_container, CConfig *config) final; + void ImplicitNewmark_Update(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) final; /*! * \brief A virtual member. @@ -414,7 +479,9 @@ class CFEASolver : public CSolver { * \param[in] solver_container - Container vector with all the solutions. * \param[in] config - Definition of the particular problem. */ - void ImplicitNewmark_Relaxation(CGeometry *geometry, CSolver **solver_container, CConfig *config) final; + void ImplicitNewmark_Relaxation(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) final; /*! * \brief Iterate using an implicit Generalized Alpha solver. @@ -422,7 +489,9 @@ class CFEASolver : public CSolver { * \param[in] solver_container - Container vector with all the solutions. * \param[in] config - Definition of the particular problem. */ - void GeneralizedAlpha_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) final; + void GeneralizedAlpha_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) final; /*! * \brief Update the solution using an implicit Generalized Alpha solver. @@ -430,7 +499,9 @@ class CFEASolver : public CSolver { * \param[in] solver_container - Container vector with all the solutions. * \param[in] config - Definition of the particular problem. */ - void GeneralizedAlpha_UpdateDisp(CGeometry *geometry, CSolver **solver_container, CConfig *config) final; + void GeneralizedAlpha_UpdateDisp(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) final; /*! * \brief Update the solution using an implicit Generalized Alpha solver. @@ -438,7 +509,9 @@ class CFEASolver : public CSolver { * \param[in] solver_container - Container vector with all the solutions. * \param[in] config - Definition of the particular problem. */ - void GeneralizedAlpha_UpdateSolution(CGeometry *geometry, CSolver **solver_container, CConfig *config) final; + void GeneralizedAlpha_UpdateSolution(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) final; /*! * \brief Update the solution using an implicit Generalized Alpha solver. @@ -446,7 +519,9 @@ class CFEASolver : public CSolver { * \param[in] solver_container - Container vector with all the solutions. * \param[in] config - Definition of the particular problem. */ - void GeneralizedAlpha_UpdateLoads(CGeometry *geometry, CSolver **solver_container, CConfig *config) final; + void GeneralizedAlpha_UpdateLoads(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) final; /*! * \brief Postprocessing. @@ -455,8 +530,11 @@ class CFEASolver : public CSolver { * \param[in] config - Definition of the particular problem. * \param[in] iMesh - Index of the mesh in multigrid computations. */ - void Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, - CNumerics **numerics, unsigned short iMesh) final; + void Postprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + CNumerics **numerics, + unsigned short iMesh) final; /*! * \brief Routine to solve the Jacobian-Residual linearized system. @@ -614,7 +692,9 @@ class CFEASolver : public CSolver { * \param[in] solver_container - Container vector with all the solutions. * \param[in] config - Definition of the particular problem. */ - void Compute_OFRefGeom(CGeometry *geometry, CSolver **solver_container, CConfig *config) final; + void Compute_OFRefGeom(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) final; /*! * \brief Compute the objective function for a reference node @@ -622,7 +702,9 @@ class CFEASolver : public CSolver { * \param[in] solver_container - Container vector with all the solutions. * \param[in] config - Definition of the particular problem. */ - void Compute_OFRefNode(CGeometry *geometry, CSolver **solver_container, CConfig *config) final; + void Compute_OFRefNode(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) final; /*! * \brief Compute the objective function for a volume fraction @@ -630,7 +712,9 @@ class CFEASolver : public CSolver { * \param[in] solver_container - Container vector with all the solutions. * \param[in] config - Definition of the particular problem. */ - void Compute_OFVolFrac(CGeometry *geometry, CSolver **solver_container, CConfig *config) final; + void Compute_OFVolFrac(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) final; /*! * \brief Compute the compliance objective function @@ -638,7 +722,9 @@ class CFEASolver : public CSolver { * \param[in] solver_container - Container vector with all the solutions. * \param[in] config - Definition of the particular problem. */ - void Compute_OFCompliance(CGeometry *geometry, CSolver **solver_container, CConfig *config) final; + void Compute_OFCompliance(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) final; /*! * \brief Compute the penalty due to the stiffness increase @@ -647,8 +733,10 @@ class CFEASolver : public CSolver { * \param[in] numerics - Description of the numerical method. * \param[in] config - Definition of the particular problem. */ - void Stiffness_Penalty(CGeometry *geometry, CSolver **solver_container, - CNumerics **numerics_container, CConfig *config) final; + void Stiffness_Penalty(CGeometry *geometry, + CSolver **solver_container, + CNumerics **numerics_container, + CConfig *config) final; /*! * \brief Get the value of the FSI convergence. @@ -714,14 +802,20 @@ class CFEASolver : public CSolver { * \param[in] val_iter - Current external iteration number. * \param[in] val_update_geo - Flag for updating coords and grid velocity. */ - void LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo); + void LoadRestart(CGeometry **geometry, + CSolver ***solver, + CConfig *config, + int val_iter, + bool val_update_geo) override; /*! * \brief Get multiplier for loads. * \param[in] CurrentTime - Current time step. * \param[in] config - Definition of the particular problem. */ - su2double Compute_LoadCoefficient(su2double CurrentTime, su2double RampTime, CConfig *config) final; + su2double Compute_LoadCoefficient(su2double CurrentTime, + su2double RampTime, + CConfig *config) final; /*! * \brief A virtual member. @@ -729,7 +823,9 @@ class CFEASolver : public CSolver { * \param[in] config - Definition of the particular problem. * \param[in] reset - Not used by this class ATM. */ - void RegisterVariables(CGeometry *geometry, CConfig *config, bool reset) override; + void RegisterVariables(CGeometry *geometry, + CConfig *config, + bool reset) override; /*! * \brief A virtual member. diff --git a/SU2_CFD/include/solvers/CFEM_DG_EulerSolver.hpp b/SU2_CFD/include/solvers/CFEM_DG_EulerSolver.hpp new file mode 100644 index 000000000000..a5c2a1b241c7 --- /dev/null +++ b/SU2_CFD/include/solvers/CFEM_DG_EulerSolver.hpp @@ -0,0 +1,1688 @@ +/*! + * \file CFEM_DG_EulerSolver.hpp + * \brief Headers of the CFEM_DG_EulerSolver class + * \author E. van der Weide, T. Economon, J. Alonso + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + + +#pragma once + +#include "CSolver.hpp" + +/*! + * \class CFEM_DG_EulerSolver + * \brief Main class for defining the Euler Discontinuous Galerkin finite element flow solver. + * \ingroup Euler_Equations + * \author E. van der Weide, T. Economon, J. Alonso + * \version 7.0.0 "Blackbird" + */ +class CFEM_DG_EulerSolver : public CSolver { +protected: + + su2double Gamma; /*!< \brief Fluid's Gamma constant (ratio of specific heats). */ + su2double Gamma_Minus_One; /*!< \brief Fluids's Gamma - 1.0 . */ + + CFluidModel *FluidModel; /*!< \brief fluid model used in the solver */ + + su2double + Mach_Inf, /*!< \brief Mach number at infinity. */ + Density_Inf, /*!< \brief Density at infinity. */ + Energy_Inf, /*!< \brief Energy at infinity. */ + Temperature_Inf, /*!< \brief Energy at infinity. */ + Pressure_Inf, /*!< \brief Pressure at infinity. */ + *Velocity_Inf; /*!< \brief Flow velocity vector at infinity. */ + + vector ConsVarFreeStream; /*!< \brief Vector, which contains the free stream + conservative variables. */ + su2double + *CL_Inv, /*!< \brief Lift coefficient (inviscid contribution) for each boundary. */ + *CD_Inv, /*!< \brief Drag coefficient (inviscid contribution) for each boundary. */ + *CSF_Inv, /*!< \brief Sideforce coefficient (inviscid contribution) for each boundary. */ + *CFx_Inv, /*!< \brief x Force coefficient (inviscid contribution) for each boundary. */ + *CFy_Inv, /*!< \brief y Force coefficient (inviscid contribution) for each boundary. */ + *CFz_Inv, /*!< \brief z Force coefficient (inviscid contribution) for each boundary. */ + *CMx_Inv, /*!< \brief x Moment coefficient (inviscid contribution) for each boundary. */ + *CMy_Inv, /*!< \brief y Moment coefficient (inviscid contribution) for each boundary. */ + *CMz_Inv, /*!< \brief z Moment coefficient (inviscid contribution) for each boundary. */ + *CEff_Inv; /*!< \brief Efficiency (Cl/Cd) (inviscid contribution) for each boundary. */ + + su2double + *Surface_CL_Inv, /*!< \brief Lift coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CD_Inv, /*!< \brief Drag coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CSF_Inv, /*!< \brief Side-force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CFx_Inv, /*!< \brief x Force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CFy_Inv, /*!< \brief y Force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CFz_Inv, /*!< \brief z Force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CMx_Inv, /*!< \brief x Moment coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CMy_Inv, /*!< \brief y Moment coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CMz_Inv, /*!< \brief z Moment coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CEff_Inv; /*!< \brief Efficiency (Cl/Cd) (inviscid contribution) for each monitoring surface. */ + + su2double + AllBound_CL_Inv, /*!< \brief Total lift coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CD_Inv, /*!< \brief Total drag coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CSF_Inv, /*!< \brief Total sideforce coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CFx_Inv, /*!< \brief Total x force coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CFy_Inv, /*!< \brief Total y force coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CFz_Inv, /*!< \brief Total z force coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMx_Inv, /*!< \brief Total x moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMy_Inv, /*!< \brief Total y moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMz_Inv, /*!< \brief Total z moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CEff_Inv; /*!< \brief Total efficiency (Cl/Cd) (inviscid contribution) for all the boundaries. */ + + su2double + Total_CL, /*!< \brief Total lift coefficient for all the boundaries. */ + Total_CD, /*!< \brief Total drag coefficient for all the boundaries. */ + Total_CSF, /*!< \brief Total sideforce coefficient for all the boundaries. */ + Total_CFx, /*!< \brief Total x force coefficient for all the boundaries. */ + Total_CFy, /*!< \brief Total y force coefficient for all the boundaries. */ + Total_CFz, /*!< \brief Total z force coefficient for all the boundaries. */ + Total_CMx, /*!< \brief Total x moment coefficient for all the boundaries. */ + Total_CMy, /*!< \brief Total y moment coefficient for all the boundaries. */ + Total_CMz, /*!< \brief Total z moment coefficient for all the boundaries. */ + Total_CEff; /*!< \brief Total efficiency coefficient for all the boundaries. */ + + su2double + *Surface_CL, /*!< \brief Lift coefficient for each monitoring surface. */ + *Surface_CD, /*!< \brief Drag coefficient for each monitoring surface. */ + *Surface_CSF, /*!< \brief Side-force coefficient for each monitoring surface. */ + *Surface_CFx, /*!< \brief x Force coefficient for each monitoring surface. */ + *Surface_CFy, /*!< \brief y Force coefficient for each monitoring surface. */ + *Surface_CFz, /*!< \brief z Force coefficient for each monitoring surface. */ + *Surface_CMx, /*!< \brief x Moment coefficient for each monitoring surface. */ + *Surface_CMy, /*!< \brief y Moment coefficient for each monitoring surface. */ + *Surface_CMz, /*!< \brief z Moment coefficient for each monitoring surface. */ + *Surface_CEff; /*!< \brief Efficiency (Cl/Cd) for each monitoring surface. */ + + unsigned long nDOFsLocTot; /*!< \brief Total number of local DOFs, including halos. */ + unsigned long nDOFsLocOwned; /*!< \brief Number of owned local DOFs. */ + unsigned long nDOFsGlobal; /*!< \brief Number of global DOFs. */ + + unsigned long nVolElemTot; /*!< \brief Total number of local volume elements, including halos. */ + unsigned long nVolElemOwned; /*!< \brief Number of owned local volume elements. */ + CVolumeElementFEM *volElem; /*!< \brief Array of the local volume elements, including halos. */ + + const unsigned long *nVolElemOwnedPerTimeLevel; /*!< \brief Number of owned local volume elements + per time level. Cumulative storage. */ + const unsigned long *nVolElemInternalPerTimeLevel; /*!< \brief Number of internal local volume elements per + time level. Internal means that the solution + data does not need to be communicated. */ + const unsigned long *nVolElemHaloPerTimeLevel; /*!< \brief Number of halo volume elements + per time level. Cumulative storage. */ + + vector > ownedElemAdjLowTimeLevel; /*!< \brief List of owned elements per time level that are + adjacent to elements of the lower time level. */ + vector > haloElemAdjLowTimeLevel; /*!< \brief List of halo elements per time level that are + adjacent to elements of the lower time level. */ + + unsigned long nMeshPoints; /*!< \brief Number of mesh points in the local part of the grid. */ + CPointFEM *meshPoints; /*!< \brief Array of the points of the FEM mesh. */ + + const unsigned long *nMatchingInternalFacesWithHaloElem; /*!< \brief Number of local matching internal faces per time level + between an owned and a halo element. Cumulative storage. */ + const unsigned long *nMatchingInternalFacesLocalElem; /*!< \brief Number of local matching internal faces per time level + between local elements. Cumulative storage. */ + + CInternalFaceElementFEM *matchingInternalFaces; /*!< \brief Array of the local matching internal faces. */ + CBoundaryFEM *boundaries; /*!< \brief Array of the boundaries of the FEM mesh. */ + + unsigned short nStandardBoundaryFacesSol; /*!< \brief Number of standard boundary faces used for solution of the DG solver. */ + unsigned short nStandardElementsSol; /*!< \brief Number of standard volume elements used for solution of the DG solver. */ + unsigned short nStandardMatchingFacesSol; /*!< \brief Number of standard matching internal faces used for solution of the DG solver. */ + + const CFEMStandardBoundaryFace *standardBoundaryFacesSol; /*!< \brief Array that contains the standard boundary + faces used for the solution of the DG solver. */ + const CFEMStandardElement *standardElementsSol; /*!< \brief Array that contains the standard volume elements + used for the solution of the DG solver. */ + const CFEMStandardInternalFace *standardMatchingFacesSol; /*!< \brief Array that contains the standard matching + internal faces used for the solution of + the DG solver. */ + + const su2double *timeCoefADER_DG; /*!< \brief The time coefficients in the iteration matrix of + the ADER-DG predictor step. */ + const su2double *timeInterpolDOFToIntegrationADER_DG; /*!< \brief The interpolation matrix between the time DOFs and + the time integration points for ADER-DG. */ + const su2double *timeInterpolAdjDOFToIntegrationADER_DG; /*!< \brief The interpolation matrix between the time DOFs of adjacent + elements of a higher time level and the time integration + points for ADER-DG. */ + + unsigned int sizeWorkArray; /*!< \brief The size of the work array needed. */ + + vector TolSolADER; /*!< \brief Vector, which stores the tolerances for the conserved + variables in the ADER predictor step. */ + + vector VecSolDOFs; /*!< \brief Vector, which stores the solution variables in the owned DOFs. */ + vector VecSolDOFsNew; /*!< \brief Vector, which stores the new solution variables in the owned DOFs (needed for classical RK4 scheme). */ + vector VecDeltaTime; /*!< \brief Vector, which stores the time steps of the owned volume elements. */ + + vector VecSolDOFsPredictorADER; /*!< \brief Vector, which stores the ADER predictor solution in the owned + DOFs. These are both space and time DOFs. */ + + vector > VecWorkSolDOFs; /*!< \brief Working double vector to store the conserved variables for + the DOFs for the different time levels. */ + + vector VecResDOFs; /*!< \brief Vector, which stores the residuals in the owned DOFs. */ + vector VecResFaces; /*!< \brief Vector, which stores the residuals of the DOFs that + come from the faces, both boundary and internal. */ + vector VecTotResDOFsADER; /*!< \brief Vector, which stores the accumulated residuals of the + owned DOFs for the ADER corrector step. */ + + + vector nEntriesResFaces; /*!< \brief Number of entries for the DOFs in the + residual of the faces. Cumulative storage. */ + vector entriesResFaces; /*!< \brief The corresponding entries in the residual of the faces. */ + + vector nEntriesResAdjFaces; /*!< \brief Number of entries for the DOFs in the residual of the faces, + where the face is adjacent to an element of lower time + level. Cumulative storage. */ + vector entriesResAdjFaces; /*!< \brief The corresponding entries in the residual of the faces. */ + + vector > startLocResFacesMarkers; /*!< \brief The starting location in the residual of the + faces for the time levels of the boundary + markers. */ + + vector startLocResInternalFacesLocalElem; /*!< \brief The starting location in the residual of the + faces for the time levels of internal faces + between locally owned elements. */ + vector startLocResInternalFacesWithHaloElem; /*!< \brief The starting location in the residual of the + faces for the time levels of internal faces + between an owned and a halo element. */ + + bool symmetrizingTermsPresent; /*!< \brief Whether or not symmetrizing terms are present in the + discretization. */ + + vector nDOFsPerRank; /*!< \brief Number of DOFs per rank in + cumulative storage format. */ + vector > nonZeroEntriesJacobian; /*!< \brief The ID's of the DOFs for the + non-zero entries of the Jacobian + for the locally owned DOFs. */ + + int nGlobalColors; /*!< \brief Number of global colors for the Jacobian computation. */ + + vector > localDOFsPerColor; /*!< \brief Double vector, which contains for every + color the local DOFs. */ + vector > colorToIndEntriesJacobian; /*!< \brief Double vector, which contains for every + local DOF the mapping from the color to the + entry in the Jacobian. A -1 indicates that + the color does not contribute to the Jacobian + of the DOF. */ + + CBlasStructure *blasFunctions; /*!< \brief Pointer to the object to carry out the BLAS functionalities. */ + +private: + +#ifdef HAVE_MPI + vector > commRequests; /*!< \brief Communication requests in the communication of the solution for all + time levels. These are both sending and receiving requests. */ + + vector > > elementsRecvMPIComm; /*!< \brief Triple vector, which contains the halo elements + for MPI communication for all time levels. */ + vector > > elementsSendMPIComm; /*!< \brief Triple vector, which contains the donor elements + for MPI communication for all time levels. */ + + vector > ranksRecvMPI; /*!< \brief Double vector, which contains the ranks from which the halo elements + are received for all time levels. */ + vector > ranksSendMPI; /*!< \brief Double vector, which contains the ranks to which the donor elements + are sent for all time levels. */ + + vector > > commRecvBuf; /*!< \brief Receive buffers used to receive the solution data + in the communication pattern for all time levels. */ + vector > > commSendBuf; /*!< \brief Send buffers used to send the solution data + in the communication pattern for all time levels. */ +#endif + + vector > elementsRecvSelfComm; /*!< \brief Double vector, which contains the halo elements + for self communication for all time levels. */ + vector > elementsSendSelfComm; /*!< \brief Double vector, which contains the donor elements + for self communication for all time levels. */ + + vector rotationMatricesPeriodicity; /*!< \brief Vector, which contains the rotation matrices + for the rotational periodic transformations. */ + vector > > halosRotationalPeriodicity; /*!< \brief Triple vector, which contains the indices + of halo elements for which a periodic + transformation must be applied for all + time levels. */ + + vector tasksList; /*!< \brief List of tasks to be carried out in the computationally + intensive part of the solver. */ + + CVariable* GetBaseClassPointerToNodes() final {return nullptr;} + +public: + + /*! + * \brief Constructor of the class. + */ + CFEM_DG_EulerSolver(void); + + /*! + * \overload + * \param[in] config - Definition of the particular problem. + * \param[in] val_nDim - Dimension of the problem (2D or 3D). + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + CFEM_DG_EulerSolver(CConfig *config, unsigned short val_nDim, unsigned short iMesh); + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + CFEM_DG_EulerSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); + + /*! + * \brief Destructor of the class. + */ + virtual ~CFEM_DG_EulerSolver(void); + + /*! + * \brief Set the fluid solver nondimensionalization. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] writeOutput - Whether or not output must be written. + */ + void SetNondimensionalization(CConfig *config, + unsigned short iMesh, + const bool writeOutput); + using CSolver::SetNondimensionalization; + + /*! + * \brief Get a pointer to the vector of the solution degrees of freedom. + * \return Pointer to the vector of the solution degrees of freedom. + */ + inline su2double* GetVecSolDOFs(void) final { return VecSolDOFs.data(); } + + /*! + * \brief Get the global number of solution degrees of freedom for the calculation. + * \return Global number of solution degrees of freedom + */ + inline unsigned long GetnDOFsGlobal(void) const final { return nDOFsGlobal; } + + /*! + * \brief Compute the pressure at the infinity. + * \return Value of the pressure at the infinity. + */ + inline CFluidModel* GetFluidModel(void) const final { return FluidModel;} + + /*! + * \brief Compute the density at the infinity. + * \return Value of the density at the infinity. + */ + inline su2double GetDensity_Inf(void) const final { return Density_Inf; } + + /*! + * \brief Compute 2-norm of the velocity at the infinity. + * \return Value of the 2-norm of the velocity at the infinity. + */ + inline su2double GetModVelocity_Inf(void) const final { + su2double Vel2 = 0; + for (unsigned short iDim = 0; iDim < nDim; iDim++) + Vel2 += Velocity_Inf[iDim]*Velocity_Inf[iDim]; + return sqrt(Vel2); + } + + + /*! + * \brief Compute the density multiply by energy at the infinity. + * \return Value of the density multiply by energy at the infinity. + */ + inline su2double GetDensity_Energy_Inf(void) const final { return Density_Inf*Energy_Inf; } + + /*! + * \brief Compute the pressure at the infinity. + * \return Value of the pressure at the infinity. + */ + inline su2double GetPressure_Inf(void) const final { return Pressure_Inf; } + + /*! + * \brief Compute the density multiply by velocity at the infinity. + * \param[in] val_dim - Index of the velocity vector. + * \return Value of the density multiply by the velocity at the infinity. + */ + inline su2double GetDensity_Velocity_Inf(unsigned short val_dim) const final { return Density_Inf*Velocity_Inf[val_dim]; } + + /*! + * \brief Get the velocity at the infinity. + * \param[in] val_dim - Index of the velocity vector. + * \return Value of the velocity at the infinity. + */ + inline su2double GetVelocity_Inf(unsigned short val_dim) const final { return Velocity_Inf[val_dim]; } + + /*! + * \brief Get the velocity at the infinity. + * \return Value of the velocity at the infinity. + */ + inline su2double *GetVelocity_Inf(void) const final { return Velocity_Inf; } + + /*! + * \brief Set the freestream pressure. + * \param[in] Value of freestream pressure. + */ + inline void SetPressure_Inf(su2double p_inf) final { Pressure_Inf = p_inf; } + + /*! + * \brief Set the freestream temperature. + * \param[in] Value of freestream temperature. + */ + inline void SetTemperature_Inf(su2double t_inf) final { Temperature_Inf = t_inf; } + + /*! + * \brief Set the initial condition for the Euler Equations. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] ExtIter - External iteration. + */ + void SetInitialCondition(CGeometry **geometry, + CSolver ***solver_container, + CConfig *config, + unsigned long TimeIter) final; + + /*! + * \brief Set the working solution of the first time level to the current + solution. Used for Runge-Kutta type schemes. + * \param[in] geometry - Geometrical definition of the problem. + */ + void Set_OldSolution(CGeometry *geometry) final; + + /*! + * \brief Set the new solution to the current solution for classical RK. + * \param[in] geometry - Geometrical definition of the problem. + */ + void Set_NewSolution(CGeometry *geometry) final; + + /*! + * \brief Function to compute the time step for solving the Euler equations. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] Iteration - Value of the current iteration. + */ + void SetTime_Step(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned long Iteration) override; + + /*! + * \brief Function, which checks whether or not the time synchronization point is reached + when explicit time stepping is used. + * \param[in] config - Definition of the particular problem. + * \param[in] TimeSync - The synchronization time. + * \param[in,out] timeEvolved - On input the time evolved before the time step, + on output the time evolved after the time step. + * \param[out] syncTimeReached - Whether or not the synchronization time is reached. + */ + void CheckTimeSynchronization(CConfig *config, + const su2double TimeSync, + su2double &timeEvolved, + bool &syncTimeReached) final; + + /*! + * \brief Function, which processes the list of tasks to be executed by + the DG solver. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void ProcessTaskList_DG(CGeometry *geometry, + CSolver **solver_container, + CNumerics **numerics, + CConfig *config, + unsigned short iMesh) final; + + /*! + * \brief Function, to carry out the space time integration for ADER + with time accurate local time stepping. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void ADER_SpaceTimeIntegration(CGeometry *geometry, + CSolver **solver_container, + CNumerics **numerics, + CConfig *config, + unsigned short iMesh, + unsigned short RunTime_EqSystem) final; + + /*! + * \brief Function, which controls the computation of the spatial Jacobian. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void ComputeSpatialJacobian(CGeometry *geometry, + CSolver **solver_container, + CNumerics **numerics, + CConfig *config, + unsigned short iMesh, + unsigned short RunTime_EqSystem) final; + + /*! + * \brief Function, which determines the values of the tolerances in + the predictor step of ADER-DG. + */ + void TolerancesADERPredictorStep(void); + + /*! + * \brief Function, carries out the predictor step of the ADER-DG + time integration. + * \param[in] config - Definition of the particular problem. + * \param[in] elemBeg - Begin index of the element range to be computed. + * \param[in] elemEnd - End index (not included) of the element range to be computed. + * \param[out] workArray - Work array. + */ + void ADER_DG_PredictorStep(CConfig *config, + const unsigned long elemBeg, + const unsigned long elemEnd, + su2double *workArray); + + /*! + * \brief Function, which interpolates the predictor solution of ADER-DG + to the time value that corresponds to iTime. + * \param[in] config - Definition of the particular problem. + * \param[in] iTime - Time index of the time integration point for the + integration over the time slab in the corrector + step of ADER-DG. + * \param[in] elemBeg - Begin index of the element range to be computed. This + range is for elements of the same time level. + * \param[in] elemEnd - End index (not included) of the element range to be computed. + * \param[in] nAdjElem - Number of elements of the next time level, which are + adjacent to elements of the current time level. + * \param[in] adjElem - The ID's of the adjacent elements. + * \param[in] secondPartTimeInt - Whether or not this is the second part of the + time interval for the adjacent elements. + * \param[out] solTimeLevel - Array in which the interpolated solution for the + time level considered must be stored. + */ + void ADER_DG_TimeInterpolatePredictorSol(CConfig *config, + const unsigned short iTime, + const unsigned long elemBeg, + const unsigned long elemEnd, + const unsigned long nAdjElem, + const unsigned long *adjElem, + const bool secondPartTimeInt, + su2double *solTimeLevel); + + /*! + * \brief Compute the artificial viscosity for shock capturing in DG. It is a virtual + function, because this function is overruled for Navier-Stokes. + * \param[in] config - Definition of the particular problem. + * \param[in] elemBeg - Begin index of the element range to be computed. + * \param[in] elemEnd - End index (not included) of the element range to be computed. + * \param[out] workArray - Work array. + */ + virtual void Shock_Capturing_DG(CConfig *config, + const unsigned long elemBeg, + const unsigned long elemEnd, + su2double *workArray); + + /*! + * \brief Compute the volume contributions to the spatial residual. It is a virtual + function, because this function is overruled for Navier-Stokes. + * \param[in] config - Definition of the particular problem. + * \param[in] elemBeg - Begin index of the element range to be computed. + * \param[in] elemEnd - End index (not included) of the element range to be computed. + * \param[out] workArray - Work array. + */ + virtual void Volume_Residual(CConfig *config, + const unsigned long elemBeg, + const unsigned long elemEnd, + su2double *workArray); + + /*! + * \brief Function, which computes the spatial residual for the DG discretization. + * \param[in] timeLevel - Time level of the time accurate local time stepping, + if relevant. + * \param[in] config - Definition of the particular problem. + * \param[in] numerics - Description of the numerical method. + * \param[in] haloInfoNeededForBC - If true, treat boundaries for which halo data is needed. + If false, treat boundaries for which only owned data is needed. + * \param[out] workArray - Work array. + */ + void Boundary_Conditions(const unsigned short timeLevel, + CConfig *config, + CNumerics **numerics, + const bool haloInfoNeededForBC, + su2double *workArray); + + /*! + * \brief Compute the spatial residual for the given range of faces. It is a virtual + function, because this function is overruled for Navier-Stokes. + * \param[in] config - Definition of the particular problem. + * \param[in] indFaceBeg - Starting index in the matching faces. + * \param[in] indFaceEnd - End index in the matching faces. + * \param[in,out] indResFaces - Index where to store the residuals in + the vector of face residuals. + * \param[in] numerics - Description of the numerical method. + * \param[out] workArray - Work array. + */ + virtual void ResidualFaces(CConfig *config, + const unsigned long indFaceBeg, + const unsigned long indFaceEnd, + unsigned long &indResFaces, + CNumerics *numerics, + su2double *workArray); + + /*! + * \brief Function, which accumulates the space time residual of the ADER-DG + time integration scheme for the owned elements. + * \param[in] config - Definition of the particular problem. + * \param[in] timeLevel - time level for which the residuals must be + accumulated. + * \param[in] intPoint - Index of the time integration point. + */ + void AccumulateSpaceTimeResidualADEROwnedElem(CConfig *config, + const unsigned short timeLevel, + const unsigned short intPoint); + + /*! + * \brief Function, which accumulates the space time residual of the ADER-DG + time integration scheme for the halo elements. + * \param[in] config - Definition of the particular problem. + * \param[in] timeLevel - time level for which the residuals must be + accumulated. + * \param[in] intPoint - Index of the time integration point. + */ + void AccumulateSpaceTimeResidualADERHaloElem(CConfig *config, + const unsigned short timeLevel, + const unsigned short intPoint); + + /*! + * \brief Compute primitive variables and their gradients. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iStep - Current step in the time accurate local time + stepping algorithm, if appropriate. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + */ + void Preprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep, + unsigned short RunTime_EqSystem, + bool Output) final; + + /*! + * \brief + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Postprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh) final; + + /*! + * \brief Impose via the residual the Euler wall boundary condition. It is a + virtual function, because for Navier-Stokes it is overwritten. + * \param[in] config - Definition of the particular problem. + * \param[in] surfElemBeg - Start index in the list of surface elements. + * \param[in] surfElemEnd - End index (not included) in the list of surface elements. + * \param[in] surfElem - Array of surface elements for which the boundary + conditions must be imposed. + * \param[out] resFaces - Array where the residual contribution from the + surface elements must be stored. + * \param[in] conv_numerics - Description of the numerical method. + * \param[out] workArray - Work array. + */ + virtual void BC_Euler_Wall(CConfig *config, + const unsigned long surfElemBeg, + const unsigned long surfElemEnd, + const CSurfaceElementFEM *surfElem, + su2double *resFaces, + CNumerics *conv_numerics, + su2double *workArray); + using CSolver::BC_Euler_Wall; + + /*! + * \brief Impose the far-field boundary condition. It is a virtual + function, because for Navier-Stokes it is overwritten. + * \param[in] config - Definition of the particular problem. + * \param[in] surfElemBeg - Start index in the list of surface elements. + * \param[in] surfElemEnd - End index (not included) in the list of surface elements. + * \param[in] surfElem - Array of surface elements for which the boundary + conditions must be imposed. + * \param[out] resFaces - Array where the residual contribution from the + surface elements must be stored. + * \param[in] conv_numerics - Description of the numerical method. + * \param[out] workArray - Work array. + */ + virtual void BC_Far_Field(CConfig *config, + const unsigned long surfElemBeg, + const unsigned long surfElemEnd, + const CSurfaceElementFEM *surfElem, + su2double *resFaces, + CNumerics *conv_numerics, + su2double *workArray); + using CSolver::BC_Far_Field; + + /*! + * \brief Impose the symmetry boundary condition. It is a virtual + function, because for Navier-Stokes it is overwritten. + * \param[in] config - Definition of the particular problem. + * \param[in] surfElemBeg - Start index in the list of surface elements. + * \param[in] surfElemEnd - End index (not included) in the list of surface elements. + * \param[in] surfElem - Array of surface elements for which the boundary + conditions must be imposed. + * \param[out] resFaces - Array where the residual contribution from the + surface elements must be stored. + * \param[in] conv_numerics - Description of the numerical method. + * \param[out] workArray - Work array. + */ + virtual void BC_Sym_Plane(CConfig *config, + const unsigned long surfElemBeg, + const unsigned long surfElemEnd, + const CSurfaceElementFEM *surfElem, + su2double *resFaces, + CNumerics *conv_numerics, + su2double *workArray); + using CSolver::BC_Sym_Plane; + + /*! + * \brief Impose the supersonic outlet boundary condition. It is a virtual + function, because for Navier-Stokes it is overwritten. + * \param[in] config - Definition of the particular problem. + * \param[in] surfElemBeg - Start index in the list of surface elements. + * \param[in] surfElemEnd - End index (not included) in the list of surface elements. + * \param[in] surfElem - Array of surface elements for which the boundary + conditions must be imposed. + * \param[out] resFaces - Array where the residual contribution from the + surface elements must be stored. + * \param[in] conv_numerics - Description of the numerical method. + * \param[out] workArray - Work array. + */ + virtual void BC_Supersonic_Outlet(CConfig *config, + const unsigned long surfElemBeg, + const unsigned long surfElemEnd, + const CSurfaceElementFEM *surfElem, + su2double *resFaces, + CNumerics *conv_numerics, + su2double *workArray); + using CSolver::BC_Supersonic_Outlet; + + /*! + * \brief Impose the subsonic inlet boundary condition. It is a virtual + function, because for Navier-Stokes it is overwritten. + * \param[in] config - Definition of the particular problem. + * \param[in] surfElemBeg - Start index in the list of surface elements. + * \param[in] surfElemEnd - End index (not included) in the list of surface elements. + * \param[in] surfElem - Array of surface elements for which the boundary + conditions must be imposed. + * \param[out] resFaces - Array where the residual contribution from the + surface elements must be stored. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + * \param[out] workArray - Work array. + */ + virtual void BC_Inlet(CConfig *config, + const unsigned long surfElemBeg, + const unsigned long surfElemEnd, + const CSurfaceElementFEM *surfElem, + su2double *resFaces, + CNumerics *conv_numerics, + unsigned short val_marker, + su2double *workArray); + using CSolver::BC_Inlet; + + /*! + * \brief Impose the outlet boundary condition.It is a virtual + function, because for Navier-Stokes it is overwritten. + * \param[in] config - Definition of the particular problem. + * \param[in] surfElemBeg - Start index in the list of surface elements. + * \param[in] surfElemEnd - End index (not included) in the list of surface elements. + * \param[in] surfElem - Array of surface elements for which the boundary + conditions must be imposed. + * \param[out] resFaces - Array where the residual contribution from the + surface elements must be stored. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + * \param[out] workArray - Work array. + */ + virtual void BC_Outlet(CConfig *config, + const unsigned long surfElemBeg, + const unsigned long surfElemEnd, + const CSurfaceElementFEM *surfElem, + su2double *resFaces, + CNumerics *conv_numerics, + unsigned short val_marker, + su2double *workArray); + using CSolver::BC_Outlet; + + /*! + * \brief Impose a constant heat-flux condition at the wall. It is a virtual + function, such that it can be overwritten for Navier-Stokes. + * \param[in] config - Definition of the particular problem. + * \param[in] surfElemBeg - Start index in the list of surface elements. + * \param[in] surfElemEnd - End index (not included) in the list of surface elements. + * \param[in] surfElem - Array of surface elements for which the boundary + conditions must be imposed. + * \param[out] resFaces - Array where the residual contribution from the + surface elements must be stored. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + * \param[out] workArray - Work array. + */ + inline virtual void BC_HeatFlux_Wall(CConfig *config, + const unsigned long surfElemBeg, + const unsigned long surfElemEnd, + const CSurfaceElementFEM *surfElem, + su2double *resFaces, + CNumerics *conv_numerics, + unsigned short val_marker, + su2double *workArray) {} + using CSolver::BC_HeatFlux_Wall; + + /*! + * \brief Impose an isothermal condition at the wall. It is a virtual + function, such that it can be overwritten for Navier-Stokes. + * \param[in] config - Definition of the particular problem. + * \param[in] surfElemBeg - Start index in the list of surface elements. + * \param[in] surfElemEnd - End index (not included) in the list of surface elements. + * \param[in] surfElem - Array of surface elements for which the boundary + conditions must be imposed. + * \param[out] resFaces - Array where the residual contribution from the + surface elements must be stored. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + * \param[out] workArray - Work array. + */ + inline virtual void BC_Isothermal_Wall(CConfig *config, + const unsigned long surfElemBeg, + const unsigned long surfElemEnd, + const CSurfaceElementFEM *surfElem, + su2double *resFaces, + CNumerics *conv_numerics, + unsigned short val_marker, + su2double *workArray) {} + using CSolver::BC_Isothermal_Wall; + + /*! + * \brief Impose the boundary condition using characteristic reconstruction. It is + * a virtual function, such that it can be overwritten for Navier-Stokes. + * \param[in] config - Definition of the particular problem. + * \param[in] surfElemBeg - Start index in the list of surface elements. + * \param[in] surfElemEnd - End index (not included) in the list of surface elements. + * \param[in] surfElem - Array of surface elements for which the boundary + conditions must be imposed. + * \param[out] resFaces - Array where the residual contribution from the + surface elements must be stored. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + * \param[out] workArray - Work array. + */ + virtual void BC_Riemann(CConfig *config, + const unsigned long surfElemBeg, + const unsigned long surfElemEnd, + const CSurfaceElementFEM *surfElem, + su2double *resFaces, + CNumerics *conv_numerics, + unsigned short val_marker, + su2double *workArray); + using CSolver::BC_Riemann; + + /*! + * \brief Impose the user customized boundary condition. It is a virtual + function, because for Navier-Stokes it is overwritten. + * \param[in] config - Definition of the particular problem. + * \param[in] surfElemBeg - Start index in the list of surface elements. + * \param[in] surfElemEnd - End index (not included) in the list of surface elements. + * \param[in] surfElem - Array of surface elements for which the boundary + conditions must be imposed. + * \param[out] resFaces - Array where the residual contribution from the + surface elements must be stored. + * \param[in] conv_numerics - Description of the numerical method. + * \param[out] workArray - Work array. + */ + virtual void BC_Custom(CConfig *config, + const unsigned long surfElemBeg, + const unsigned long surfElemEnd, + const CSurfaceElementFEM *surfElem, + su2double *resFaces, + CNumerics *conv_numerics, + su2double *workArray); + using CSolver::BC_Custom; + + /*! + * \brief Update the solution using a Runge-Kutta scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + void ExplicitRK_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iRKStep) final; + + /*! + * \brief Update the solution using the classical fourth-order Runge-Kutta scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + void ClassicalRK4_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iRKStep) final; + + /*! + * \brief Update the solution using the classical fourth-order Runge-Kutta scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void SetResidual_RMS_FEM(CGeometry *geometry, CConfig *config); + + /*! + * \brief Compute the global error measures (L2, Linf) for verification cases. + * \param[in] geometry - Geometrical definition. + * \param[in] config - Definition of the particular problem. + */ + void ComputeVerificationError(CGeometry *geometry, CConfig *config) final; + + /*! + * \brief Update the solution for the ADER-DG scheme for the given range + of elements. + * \param[in] elemBeg - Begin index of the element range to be computed. + * \param[in] elemEnd - End index (not included) of the element range to be computed. + */ + void ADER_DG_Iteration(const unsigned long elemBeg, + const unsigned long elemEnd); + + /*! + * \brief Compute the pressure forces and all the adimensional coefficients. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Pressure_Forces(CGeometry *geometry, CConfig *config) final; + + /*! + * \brief Load a solution from a restart file. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Container vector with all of the solvers. + * \param[in] config - Definition of the particular problem. + * \param[in] val_iter - Current external iteration number. + * \param[in] val_update_geo - Flag for updating coords and grid velocity. + */ + void LoadRestart(CGeometry **geometry, + CSolver ***solver, + CConfig *config, + int val_iter, + bool val_update_geo) final; + + /*! + * \brief Provide the non dimensional lift coefficient (inviscid contribution). + * \param val_marker Surface where the coefficient is going to be computed. + * \return Value of the lift coefficient (inviscid contribution) on the surface val_marker. + */ + inline su2double GetCL_Inv(unsigned short val_marker) const final { return CL_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional lift coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the lift coefficient on the surface val_marker. + */ + inline su2double GetSurface_CL(unsigned short val_marker) const final { return Surface_CL[val_marker]; } + + /*! + * \brief Provide the non dimensional drag coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the drag coefficient on the surface val_marker. + */ + inline su2double GetSurface_CD(unsigned short val_marker) const final { return Surface_CD[val_marker]; } + + /*! + * \brief Provide the non dimensional side-force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side-force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CSF(unsigned short val_marker) const final { return Surface_CSF[val_marker]; } + + /*! + * \brief Provide the non dimensional side-force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side-force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CEff(unsigned short val_marker) const final { return Surface_CEff[val_marker]; } + + /*! + * \brief Provide the non dimensional x force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFx(unsigned short val_marker) const final { return Surface_CFx[val_marker]; } + + /*! + * \brief Provide the non dimensional y force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFy(unsigned short val_marker) const final { return Surface_CFy[val_marker]; } + + /*! + * \brief Provide the non dimensional z force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFz(unsigned short val_marker) const final { return Surface_CFz[val_marker]; } + + /*! + * \brief Provide the non dimensional x moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMx(unsigned short val_marker) const final { return Surface_CMx[val_marker]; } + + /*! + * \brief Provide the non dimensional y moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMy(unsigned short val_marker) const final { return Surface_CMy[val_marker]; } + + /*! + * \brief Provide the non dimensional z moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMz(unsigned short val_marker) const final { return Surface_CMz[val_marker]; } + + /*! + * \brief Provide the non dimensional lift coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the lift coefficient on the surface val_marker. + */ + inline su2double GetSurface_CL_Inv(unsigned short val_marker) const final { return Surface_CL_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional drag coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the drag coefficient on the surface val_marker. + */ + inline su2double GetSurface_CD_Inv(unsigned short val_marker) const final { return Surface_CD_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional side-force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side-force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CSF_Inv(unsigned short val_marker) const final { return Surface_CSF_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional side-force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side-force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CEff_Inv(unsigned short val_marker) const final { return Surface_CEff_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional x force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFx_Inv(unsigned short val_marker) const final { return Surface_CFx_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional y force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFy_Inv(unsigned short val_marker) const final { return Surface_CFy_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional z force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFz_Inv(unsigned short val_marker) const final { return Surface_CFz_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional x moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMx_Inv(unsigned short val_marker) const final { return Surface_CMx_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional y moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMy_Inv(unsigned short val_marker) const final { return Surface_CMy_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional z moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMz_Inv(unsigned short val_marker) const final { return Surface_CMz_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional drag coefficient (inviscid contribution). + * \param val_marker Surface where the coeficient is going to be computed. + * \return Value of the drag coefficient (inviscid contribution) on the surface val_marker. + */ + inline su2double GetCD_Inv(unsigned short val_marker) const final { return CD_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional sideforce coefficient (inviscid contribution). + * \param val_marker Surface where the coeficient is going to be computed. + * \return Value of the sideforce coefficient (inviscid contribution) on the surface val_marker. + */ + inline su2double GetCSF_Inv(unsigned short val_marker) const final { return CSF_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional efficiency coefficient (inviscid contribution). + * \param val_marker Surface where the coeficient is going to be computed. + * \return Value of the efficiency coefficient (inviscid contribution) on the surface val_marker. + */ + inline su2double GetCEff_Inv(unsigned short val_marker) const final { return CEff_Inv[val_marker]; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional sideforce coefficient. + * \return Value of the sideforce coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CSF() const final { return Total_CSF; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CEff() const final { return Total_CEff; } + + /*! + * \brief Store the total (inviscid + viscous) non dimensional lift coefficient. + * \param[in] val_Total_CL - Value of the total lift coefficient. + */ + inline void SetTotal_CL(su2double val_Total_CL) final { Total_CL = val_Total_CL; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional lift coefficient. + * \return Value of the lift coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CL() const final { return Total_CL; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CD() const final { return Total_CD; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional x moment coefficient. + * \return Value of the moment x coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CMx() const final { return Total_CMx; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional y moment coefficient. + * \return Value of the moment y coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CMy() const final { return Total_CMy; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional z moment coefficient. + * \return Value of the moment z coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CMz() const final { return Total_CMz; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional x force coefficient. + * \return Value of the force x coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CFx() const final { return Total_CFx; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional y force coefficient. + * \return Value of the force y coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CFy() const final { return Total_CFy; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional z force coefficient. + * \return Value of the force z coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CFz() const final { return Total_CFz; } + + /*! + * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline void SetTotal_CD(su2double val_Total_CD) final { Total_CD = val_Total_CD; } + + /*! + * \brief Get the inviscid contribution to the lift coefficient. + * \return Value of the lift coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CL_Inv() const final { return AllBound_CL_Inv; } + + /*! + * \brief Get the inviscid contribution to the drag coefficient. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CD_Inv() const final { return AllBound_CD_Inv; } + + /*! + * \brief Get the inviscid contribution to the sideforce coefficient. + * \return Value of the sideforce coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CSF_Inv() const final { return AllBound_CSF_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CEff_Inv() const final { return AllBound_CEff_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CMx_Inv() const final { return AllBound_CMx_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CMy_Inv() const final { return AllBound_CMy_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CMz_Inv() const final { return AllBound_CMz_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CFx_Inv() const final { return AllBound_CFx_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CFy_Inv() const final { return AllBound_CFy_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CFz_Inv() const final { return AllBound_CFz_Inv; } + +protected: + + /*! + * \brief Routine that initiates the non-blocking communication between ranks + for the givem time level. + * \param[in] config - Definition of the particular problem. + * \param[in] timeLevel - The time level for which the communication must be + initiated. + */ + void Initiate_MPI_Communication(CConfig *config, + const unsigned short timeLevel); + + /*! + * \brief Routine that initiates the reverse non-blocking communication + between ranks. + * \param[in] config - Definition of the particular problem. + * \param[in] timeLevel - The time level for which the reverse communication + must be initiated. + */ + void Initiate_MPI_ReverseCommunication(CConfig *config, + const unsigned short timeLevel); + + /*! + * \brief Routine that completes the non-blocking communication between ranks. + * \param[in] config - Definition of the particular problem. + * \param[in] timeLevel - The time level for which the communication + may be completed. + * \param[in] commMustBeCompleted - Whether or not the communication must be completed. + * \return Whether or not the communication has been completed. + */ + bool Complete_MPI_Communication(CConfig *config, + const unsigned short timeLevel, + const bool commMustBeCompleted); + + /*! + * \brief Routine that completes the reverse non-blocking communication + between ranks. + * \param[in] config - Definition of the particular problem. + * \param[in] timeLevel - The time level for which the communication + may be completed. + * \param[in] commMustBeCompleted - Whether or not the communication must be completed. + * \return Whether or not the communication has been completed. + */ + bool Complete_MPI_ReverseCommunication(CConfig *config, + const unsigned short timeLevel, + const bool commMustBeCompleted); + + /*! + * \brief Function, which computes the inviscid fluxes in face points. + * \param[in] config - Definition of the particular problem. + * \param[in] nFaceSimul - Number of faces that are treated simultaneously + to improve performance. + * \param[in] NPad - Value of the padding parameter to obtain optimal + performance in the gemm computations. + * \param[in] nPoints - Number of points per face for which the fluxes + must be computed. + * \param[in] normalsFace - The normals in the points for the faces. + * \param[in] gridVelsFace - The grid velocities in the points for the faces. + * \param[in] solL - Solution in the left state of the points. + * \param[in] solR - Solution in the right state of the points. + * \param[out] fluxes - Inviscid fluxes in the points. + * \param[in] numerics - Object, which contains the Riemann solver. + */ + void ComputeInviscidFluxesFace(CConfig *config, + const unsigned short nFaceSimul, + const unsigned short NPad, + const unsigned long nPoints, + const su2double *normalsFace[], + const su2double *gridVelsFace[], + const su2double *solL, + const su2double *solR, + su2double *fluxes, + CNumerics *numerics); + + /*! + * \brief Function, which computes the inviscid fluxes in the face integration + points of a chunk of matching internal faces. + * \param[in] config - Definition of the particular problem. + * \param[in] lBeg - Start index in matchingInternalFaces for which + the inviscid fluxes should be computed. + * \param[in] lEnd - End index (not included) in matchingInternalFaces + for which the inviscid fluxes should be computed. + * \param[in] NPad - Value of the padding parameter to obtain optimal + performance in the gemm computations. + * \param[out] solIntL - Solution in the left state of the integration points. + * \param[out] solIntR - Solution in the right state of the integration points. + * \param[out] fluxes - Inviscid fluxes in the integration points. + * \param[in] numerics - Object, which contains the Riemann solver. + */ + void InviscidFluxesInternalMatchingFace(CConfig *config, + const unsigned long lBeg, + const unsigned long lEnd, + const unsigned short NPad, + su2double *solIntL, + su2double *solIntR, + su2double *fluxes, + CNumerics *numerics); + /*! + * \brief Function, which computes the left state of a boundary face. + * \param[in] config - Definition of the particular problem. + * \param[in] nFaceSimul - Number of faces that are treated simultaneously + to improve performance. + * \param[in] NPad - Value of the padding parameter to obtain optimal + performance in the gemm computations. + * \param[in] surfElem - Surface boundary elements for which the left state must be computed. + * \param[out] solFace - Temporary storage for the solution in the DOFs. + * \param[out] solIntL - Left states in the integration points of the face. + */ + void LeftStatesIntegrationPointsBoundaryFace(CConfig *config, + const unsigned short nFaceSimul, + const unsigned short NPad, + const CSurfaceElementFEM *surfElem, + su2double *solFace, + su2double *solIntL); + + /*! + * \brief Function, which computes the boundary states in the integration points + of the boundary face by applying the inviscid wall boundary conditions. + * \param[in] config - Definition of the particular problem. + * \param[in] nFaceSimul - Number of faces that are treated simultaneously + to improve performance. + * \param[in] NPad - Value of the padding parameter to obtain optimal + performance in the gemm computations. + * \param[in] surfElem - Surface boundary elements for which the left state must + be computed. + * \param[in] solIntL - Left states in the integration points of the face. + * \param[out] solIntR - Right states in the integration points of the face. + */ + void BoundaryStates_Euler_Wall(CConfig *config, + const unsigned short nFaceSimul, + const unsigned short NPad, + const CSurfaceElementFEM *surfElem, + const su2double *solIntL, + su2double *solIntR); + + /*! + * \brief Function, which computes the boundary states in the integration points + of the boundary face by applying the inlet boundary conditions. + * \param[in] config - Definition of the particular problem. + * \param[in] nFaceSimul - Number of fused faces, i.e. the number of faces + that are treated simultaneously to improve performance. + * \param[in] NPad - Value of the padding parameter to obtain optimal + performance in the gemm computations. + * \param[in] surfElem - Surface boundary element for which the left state must be computed. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + * \param[in] solIntL - Left states in the integration points of the face. + * \param[out] solIntR - Right states in the integration points of the face. + */ + void BoundaryStates_Inlet(CConfig *config, + const unsigned short nFaceSimul, + const unsigned short NPad, + const CSurfaceElementFEM *surfElem, + unsigned short val_marker, + const su2double *solIntL, + su2double *solIntR); + + /*! + * \brief Function, which computes the boundary states in the integration points + of the boundary face by applying the outlet boundary conditions. + * \param[in] config - Definition of the particular problem. + * \param[in] nFaceSimul - Number of fused faces, i.e. the number of faces + that are treated simultaneously to improve performance. + * \param[in] NPad - Value of the padding parameter to obtain optimal + performance in the gemm computations. + * \param[in] surfElem - Surface boundary element for which the left state must be computed. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + * \param[in] solIntL - Left states in the integration points of the face. + * \param[out] solIntR - Right states in the integration points of the face. + */ + void BoundaryStates_Outlet(CConfig *config, + const unsigned short nFaceSimul, + const unsigned short NPad, + const CSurfaceElementFEM *surfElem, + unsigned short val_marker, + const su2double *solIntL, + su2double *solIntR); + + /*! + * \brief Function, which computes the boundary states in the integration points + of the boundary face by applying the Riemann boundary conditions. + * \param[in] config - Definition of the particular problem. + * \param[in] nFaceSimul - Number of fused faces, i.e. the number of faces + that are treated simultaneously to improve performance. + * \param[in] NPad - Value of the padding parameter to obtain optimal + performance in the gemm computations. + * \param[in] surfElem - Surface boundary element for which the left state must be computed. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + * \param[in] solIntL - Left states in the integration points of the face. + * \param[out] solIntR - Right states in the integration points of the face. + */ + void BoundaryStates_Riemann(CConfig *config, + const unsigned short nFaceSimul, + const unsigned short NPad, + const CSurfaceElementFEM *surfElem, + unsigned short val_marker, + const su2double *solIntL, + su2double *solIntR); +private: + + /*! + * \brief Virtual function, which computes the spatial residual of the ADER-DG + predictor step for the given volume element and solution using an + aliased discretization in 2D. + * \param[in] config - Definition of the particular problem. + * \param[in] elem - Volume element for which the spatial residual of the + predictor step must be computed. + * \param[in] sol - Solution for which the residual must be computed. + * \param[in] nSimul - Number of entities (typically time integration points) + that are treated simultaneously. + * \param[in] NPad - Padded N value in the matrix multiplications to + obtain better performance. The solution sol is stored + with this padded value to avoid a memcpy. + * \param[out] res - Residual of the spatial DOFs to be computed by this + function. + * \param[out] work - Work array. + */ + virtual void ADER_DG_AliasedPredictorResidual_2D(CConfig *config, + CVolumeElementFEM *elem, + const su2double *sol, + const unsigned short nSimul, + const unsigned short NPad, + su2double *res, + su2double *work); + + /*! + * \brief Virtual function, which computes the spatial residual of the ADER-DG + predictor step for the given volume element and solution using an + aliased discretization in 3D. + * \param[in] config - Definition of the particular problem. + * \param[in] elem - Volume element for which the spatial residual of the + predictor step must be computed. + * \param[in] sol - Solution for which the residual must be computed. + * \param[in] nSimul - Number of entities (typically time integration points) + that are treated simultaneously. + * \param[in] NPad - Padded N value in the matrix multiplications to + obtain better performance. The solution sol is stored + with this padded value to avoid a memcpy. + * \param[out] res - Residual of the spatial DOFs to be computed by this + function. + * \param[out] work - Work array. + */ + virtual void ADER_DG_AliasedPredictorResidual_3D(CConfig *config, + CVolumeElementFEM *elem, + const su2double *sol, + const unsigned short nSimul, + const unsigned short NPad, + su2double *res, + su2double *work); + + /*! + * \brief Virtual function, which computes the spatial residual of the ADER-DG + predictor step for the given volume element and solution using a + non-aliased discretization in 2D. + * \param[in] config - Definition of the particular problem. + * \param[in] elem - Volume element for which the spatial residual of the + predictor step must be computed. + * \param[in] sol - Solution for which the residual must be computed. + * \param[in] nSimul - Number of entities (typically time integration points) + that are treated simultaneously. + * \param[in] NPad - Padded N value in the matrix multiplications to + obtain better performance. The solution sol is stored + with this padded value to avoid a memcpy. + * \param[out] res - Residual of the spatial DOFs to be computed by this + function. + * \param[out] work - Work array. + */ + virtual void ADER_DG_NonAliasedPredictorResidual_2D(CConfig *config, + CVolumeElementFEM *elem, + const su2double *sol, + const unsigned short nSimul, + const unsigned short NPad, + su2double *res, + su2double *work); + + /*! + * \brief Virtual function, which computes the spatial residual of the ADER-DG + predictor step for the given volume element and solution using a + non-aliased discretization in 3D. + * \param[in] config - Definition of the particular problem. + * \param[in] elem - Volume element for which the spatial residual of the + predictor step must be computed. + * \param[in] sol - Solution for which the residual must be computed. + * \param[in] nSimul - Number of entities (typically time integration points) + that are treated simultaneously. + * \param[in] NPad - Padded N value in the matrix multiplications to + obtain better performance. The solution sol is stored + with this padded value to avoid a memcpy. + * \param[out] res - Residual of the spatial DOFs to be computed by this + function. + * \param[out] work - Work array. + */ + virtual void ADER_DG_NonAliasedPredictorResidual_3D(CConfig *config, + CVolumeElementFEM *elem, + const su2double *sol, + const unsigned short nSimul, + const unsigned short NPad, + su2double *res, + su2double *work); + + /*! + * \brief Function, which computes the graph of the spatial discretization + for the locally owned DOFs. + * \param[in] DGGeometry - Geometrical definition of the DG problem. + * \param[in] config - Definition of the particular problem. + */ + void DetermineGraphDOFs(const CMeshFEM *FEMGeometry, + CConfig *config); + + /*! + * \brief Function, which determines the meta data needed for the computation + of the Jacobian of the spatial residual. + * \param[in] DGGeometry - Geometrical definition of the DG problem. + * \param[in] colorLocalDOFs - Color of the locally stored DOFs. + */ + void MetaDataJacobianComputation(const CMeshFEM *FEMGeometry, + const vector &colorLocalDOFs); + + /*! + * \brief Function, which sets up the list of tasks to be carried out in the + computationally expensive part of the solver. + * \param[in] config - Definition of the particular problem. + */ + void SetUpTaskList(CConfig *config); + + /*! + * \brief Function, which sets up the persistent communication of the flow + variables in the DOFs. + * \param[in] DGGeometry - Geometrical definition of the DG problem. + * \param[in] config - Definition of the particular problem. + */ + void Prepare_MPI_Communication(const CMeshFEM *FEMGeometry, + CConfig *config); + + /*! + * \brief Function, which creates the final residual by summing up + the contributions for the DOFs of the elements considered. + * \param[in] timeLevel - Time level of the elements for which the + final residual must be created. + * \param[in] ownedElements - Whether owned or halo elements must be treated. + */ + void CreateFinalResidual(const unsigned short timeLevel, + const bool ownedElements); + + /*! + * \brief Function, which multiplies the residual by the inverse + of the (lumped) mass matrix. + * \param[in] config - Definition of the particular problem. + * \param[in] useADER - Whether or not the ADER residual must be multiplied. + * \param[in] elemBeg - Begin index of the element range to be computed. + * \param[in] elemEnd - End index (not included) of the element range to be computed. + * \param[out] workArray - Work array. + */ + void MultiplyResidualByInverseMassMatrix(CConfig *config, + const bool useADER, + const unsigned long elemBeg, + const unsigned long elemEnd, + su2double *workArray); + + /*! + * \brief Function, which computes the residual contribution from a boundary + face in an inviscid computation when the boundary conditions have + already been applied. + * \param[in] config - Definition of the particular problem. + * \param[in] nFaceSimul - Number of faces that are treated simultaneously + to improve performance. + * \param[in] NPad - Value of the padding parameter to obtain optimal + performance in the gemm computations. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] surfElem - Surface boundary element for which the + contribution to the residual must be computed. + * \param[in] solInt0 - Solution in the integration points of side 0. + It is not const, because the array is used for + temporary storage for the residual. + * \param[in] solInt1 - Solution in the integration points of side 1. + * \param[out] fluxes - Temporary storage for the fluxes in the + integration points. + * \param[out] resFaces - Array to store the residuals of the face. + * \param[in,out] indResFaces - Index in resFaces, where the current residual + should be stored. It is updated in the function + for the next boundary element. + */ + void ResidualInviscidBoundaryFace(CConfig *config, + const unsigned short nFaceSimul, + const unsigned short NPad, + CNumerics *conv_numerics, + const CSurfaceElementFEM *surfElem, + su2double *solInt0, + su2double *solInt1, + su2double *fluxes, + su2double *resFaces, + unsigned long &indResFaces); + +protected: + /*! + * \brief Template function, which determines some meta data for the chunk of + elements/faces that must be treated simulaneously. + * \param[in] elem - Const pointer the volume or face elements for which + the meta data must be computed. + * \param[in] l - Start index for the current chunk of elements/faces. + * \param[in] elemEnd - End index (index not included) of the elements to be + treated in the residual computation from which this + function is called. + * \param[in] nElemSimul - Desired number of elements/faces that must be treated + simultaneously for optimal performance. + * \param[in] nPadMin - Minimum number of the padding value in the gemm calls. + * \param[out] lEnd - Actual end index (not included) for this chunk of + elements. + * \param[out] ind - Index in the standard elements to which this chunk of + elements can be mapped. + * \param[out] llEnd - Actual number of elements/faces that are treated + simultaneously, llEnd = lEnd - l. + * \param[out] NPad - Actual padded N value in the gemm computations for + this chunk of elements. + */ + template + void MetaDataChunkOfElem(const TElemType *elem, + const unsigned long l, + const unsigned long elemEnd, + const unsigned short nElemSimul, + const unsigned short nPadMin, + unsigned long &lEnd, + unsigned short &ind, + unsigned short &llEnd, + unsigned short &NPad) { + + /* Determine the end index for this chunk of elements that must be + treated simulaneously. The elements of this chunk must have the + same standard element in order to make this work. */ + const unsigned long lEndMax = min(l+nElemSimul, elemEnd); + + ind = elem[l].indStandardElement; + for(lEnd=l+1; lEnd. + */ + + +#pragma once + +#include "CFEM_DG_EulerSolver.hpp" + +/*! + * \class CFEM_DG_NSSolver + * \brief Main class for defining the Navier-Stokes Discontinuous Galerkin finite element flow solver. + * \ingroup Navier_Stokes_Equations + * \author E. van der Weide, T. Economon, J. Alonso + * \version 7.0.0 "Blackbird" + */ +class CFEM_DG_NSSolver final : public CFEM_DG_EulerSolver { +private: + su2double Viscosity_Inf; /*!< \brief Viscosity at the infinity. */ + su2double Tke_Inf; /*!< \brief Turbulent kinetic energy at the infinity. */ + su2double Prandtl_Lam, /*!< \brief Laminar Prandtl number. */ + Prandtl_Turb; /*!< \brief Turbulent Prandtl number. */ + + CSGSModel *SGSModel; /*!< \brief LES Subgrid Scale model. */ + bool SGSModelUsed; /*!< \brief Whether or not an LES Subgrid Scale model is used. */ + + su2double + *CL_Visc, /*!< \brief Lift coefficient (viscous contribution) for each boundary. */ + *CD_Visc, /*!< \brief Drag coefficient (viscous contribution) for each boundary. */ + *CSF_Visc, /*!< \brief Side force coefficient (viscous contribution) for each boundary. */ + *CMx_Visc, /*!< \brief Moment x coefficient (viscous contribution) for each boundary. */ + *CMy_Visc, /*!< \brief Moment y coefficient (viscous contribution) for each boundary. */ + *CMz_Visc, /*!< \brief Moment z coefficient (viscous contribution) for each boundary. */ + *CFx_Visc, /*!< \brief Force x coefficient (viscous contribution) for each boundary. */ + *CFy_Visc, /*!< \brief Force y coefficient (viscous contribution) for each boundary. */ + *CFz_Visc, /*!< \brief Force z coefficient (viscous contribution) for each boundary. */ + *CEff_Visc, /*!< \brief Efficiency (Cl/Cd) (Viscous contribution) for each boundary. */ + *Surface_CL_Visc, /*!< \brief Lift coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CD_Visc, /*!< \brief Drag coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CSF_Visc, /*!< \brief Side-force coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CEff_Visc, /*!< \brief Side-force coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CFx_Visc, /*!< \brief Force x coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CFy_Visc, /*!< \brief Force y coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CFz_Visc, /*!< \brief Force z coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CMx_Visc, /*!< \brief Moment x coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CMy_Visc, /*!< \brief Moment y coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CMz_Visc, /*!< \brief Moment z coefficient (viscous contribution) for each monitoring surface. */ + *Heat_Visc, /*!< \brief Heat load (viscous contribution) for each boundary. */ + *MaxHeatFlux_Visc; /*!< \brief Maximum heat flux (viscous contribution) for each boundary. */ + + su2double + AllBound_CD_Visc, /*!< \brief Drag coefficient (viscous contribution) for all the boundaries. */ + AllBound_CL_Visc, /*!< \brief Lift coefficient (viscous contribution) for all the boundaries. */ + AllBound_CSF_Visc, /*!< \brief Sideforce coefficient (viscous contribution) for all the boundaries. */ + AllBound_CMx_Visc, /*!< \brief Moment x coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMy_Visc, /*!< \brief Moment y coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMz_Visc, /*!< \brief Moment z coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CEff_Visc, /*!< \brief Efficient coefficient (Viscous contribution) for all the boundaries. */ + AllBound_CFx_Visc, /*!< \brief Force x coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CFy_Visc, /*!< \brief Force y coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CFz_Visc, /*!< \brief Force z coefficient (inviscid contribution) for all the boundaries. */ + AllBound_HeatFlux_Visc, /*!< \brief Heat load (viscous contribution) for all the boundaries. */ + AllBound_MaxHeatFlux_Visc; /*!< \brief Maximum heat flux (viscous contribution) for all boundaries. */ + su2double StrainMag_Max, + Omega_Max; /*!< \brief Maximum Strain Rate magnitude and Omega. */ + +public: + + /*! + * \brief Constructor of the class. + */ + CFEM_DG_NSSolver(void); + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + CFEM_DG_NSSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); + + /*! + * \brief Destructor of the class. + */ + ~CFEM_DG_NSSolver(void); + + /*! + * \brief Function to compute the time step for solving the Navier-Stokes equations. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] Iteration - Value of the current iteration. + */ + void SetTime_Step(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned long Iteration) override; + + /*! + * \brief Compute the artificial viscosity for shock capturing in DG. + * \param[in] config - Definition of the particular problem. + * \param[in] elemBeg - Begin index of the element range to be computed. + * \param[in] elemEnd - End index (not included) of the element range to be computed. + * \param[out] workArray - Work array. + */ + void Shock_Capturing_DG(CConfig *config, + const unsigned long elemBeg, + const unsigned long elemEnd, + su2double *workArray) override; + + /*! + * \brief Per-Olof Persson's method for capturing shock in DG + * \param[in] elemBeg - Begin index of the element range to be computed. + * \param[in] elemEnd - End index (not included) of the element range to be computed. + * \param[out] workArray - Work array. + */ + void Shock_Capturing_DG_Persson(const unsigned long elemBeg, + const unsigned long elemEnd, + su2double *workArray); + + /*! + * \brief Compute the volume contributions to the spatial residual. + * \param[in] config - Definition of the particular problem. + * \param[in] elemBeg - Begin index of the element range to be computed. + * \param[in] elemEnd - End index (not included) of the element range to be computed. + * \param[out] workArray - Work array. + */ + void Volume_Residual(CConfig *config, + const unsigned long elemBeg, + const unsigned long elemEnd, + su2double *workArray) override; + + /*! + * \brief Compute the spatial residual for the given range of faces. + * \param[in] config - Definition of the particular problem. + * \param[in] indFaceBeg - Starting index in the matching faces. + * \param[in] indFaceEnd - End index in the matching faces. + * \param[in,out] indResFaces - Index where to store the residuals in + the vector of face residuals. + * \param[in] numerics - Description of the numerical method. + * \param[out] workArray - Work array. + */ + void ResidualFaces(CConfig *config, + const unsigned long indFaceBeg, + const unsigned long indFaceEnd, + unsigned long &indResFaces, + CNumerics *numerics, + su2double *workArray) override; + + /*! + * \brief Impose via the residual the Euler wall boundary condition. + * \param[in] config - Definition of the particular problem. + * \param[in] surfElemBeg - Start index in the list of surface elements. + * \param[in] surfElemEnd - End index (not included) in the list of surface elements. + * \param[in] surfElem - Array of surface elements for which the boundary + conditions must be imposed. + * \param[out] resFaces - Array where the residual contribution from the + surface elements must be stored. + * \param[in] conv_numerics - Description of the numerical method. + * \param[out] workArray - Work array. + */ + void BC_Euler_Wall(CConfig *config, + const unsigned long surfElemBeg, + const unsigned long surfElemEnd, + const CSurfaceElementFEM *surfElem, + su2double *resFaces, + CNumerics *conv_numerics, + su2double *workArray) override; + + /*! + * \brief Impose the far-field boundary condition. + * \param[in] config - Definition of the particular problem. + * \param[in] surfElemBeg - Start index in the list of surface elements. + * \param[in] surfElemEnd - End index (not included) in the list of surface elements. + * \param[in] surfElem - Array of surface elements for which the boundary + conditions must be imposed. + * \param[out] resFaces - Array where the residual contribution from the + surface elements must be stored. + * \param[in] conv_numerics - Description of the numerical method. + * \param[out] workArray - Work array. + */ + void BC_Far_Field(CConfig *config, + const unsigned long surfElemBeg, + const unsigned long surfElemEnd, + const CSurfaceElementFEM *surfElem, + su2double *resFaces, + CNumerics *conv_numerics, + su2double *workArray) override; + + /*! + * \brief Impose the symmetry boundary condition using the residual. + * \param[in] config - Definition of the particular problem. + * \param[in] surfElemBeg - Start index in the list of surface elements. + * \param[in] surfElemEnd - End index (not included) in the list of surface elements. + * \param[in] surfElem - Array of surface elements for which the boundary + conditions must be imposed. + * \param[out] resFaces - Array where the residual contribution from the + surface elements must be stored. + * \param[in] conv_numerics - Description of the numerical method. + * \param[out] workArray - Work array. + */ + void BC_Sym_Plane(CConfig *config, + const unsigned long surfElemBeg, + const unsigned long surfElemEnd, + const CSurfaceElementFEM *surfElem, + su2double *resFaces, + CNumerics *conv_numerics, + su2double *workArray) override; + + /*! + * \brief Impose the supersonic outlet boundary condition. + * \param[in] config - Definition of the particular problem. + * \param[in] surfElemBeg - Start index in the list of surface elements. + * \param[in] surfElemEnd - End index (not included) in the list of surface elements. + * \param[in] surfElem - Array of surface elements for which the boundary + conditions must be imposed. + * \param[out] resFaces - Array where the residual contribution from the + surface elements must be stored. + * \param[in] conv_numerics - Description of the numerical method. + * \param[out] workArray - Work array. + */ + void BC_Supersonic_Outlet(CConfig *config, + const unsigned long surfElemBeg, + const unsigned long surfElemEnd, + const CSurfaceElementFEM *surfElem, + su2double *resFaces, + CNumerics *conv_numerics, + su2double *workArray) override; + + /*! + * \brief Impose the subsonic inlet boundary condition. + * \param[in] config - Definition of the particular problem. + * \param[in] surfElemBeg - Start index in the list of surface elements. + * \param[in] surfElemEnd - End index (not included) in the list of surface elements. + * \param[in] surfElem - Array of surface elements for which the boundary + conditions must be imposed. + * \param[out] resFaces - Array where the residual contribution from the + surface elements must be stored. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + * \param[out] workArray - Work array. + */ + void BC_Inlet(CConfig *config, + const unsigned long surfElemBeg, + const unsigned long surfElemEnd, + const CSurfaceElementFEM *surfElem, + su2double *resFaces, + CNumerics *conv_numerics, + unsigned short val_marker, + su2double *workArray) override; + + /*! + * \brief Impose the outlet boundary condition. + * \param[in] config - Definition of the particular problem. + * \param[in] surfElemBeg - Start index in the list of surface elements. + * \param[in] surfElemEnd - End index (not included) in the list of surface elements. + * \param[in] surfElem - Array of surface elements for which the boundary + conditions must be imposed. + * \param[out] resFaces - Array where the residual contribution from the + surface elements must be stored. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + * \param[out] workArray - Work array. + */ + void BC_Outlet(CConfig *config, + const unsigned long surfElemBeg, + const unsigned long surfElemEnd, + const CSurfaceElementFEM *surfElem, + su2double *resFaces, + CNumerics *conv_numerics, + unsigned short val_marker, + su2double *workArray) override; + + /*! + * \brief Impose a constant heat-flux condition at the wall. + * \param[in] config - Definition of the particular problem. + * \param[in] surfElemBeg - Start index in the list of surface elements. + * \param[in] surfElemEnd - End index (not included) in the list of surface elements. + * \param[in] surfElem - Array of surface elements for which the boundary + conditions must be imposed. + * \param[out] resFaces - Array where the residual contribution from the + surface elements must be stored. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + * \param[out] workArray - Work array. + */ + void BC_HeatFlux_Wall(CConfig *config, + const unsigned long surfElemBeg, + const unsigned long surfElemEnd, + const CSurfaceElementFEM *surfElem, + su2double *resFaces, + CNumerics *conv_numerics, + unsigned short val_marker, + su2double *workArray) override; + + /*! + * \brief Impose an isothermal condition at the wall. + * \param[in] config - Definition of the particular problem. + * \param[in] surfElemBeg - Start index in the list of surface elements. + * \param[in] surfElemEnd - End index (not included) in the list of surface elements. + * \param[in] surfElem - Array of surface elements for which the boundary + conditions must be imposed. + * \param[out] resFaces - Array where the residual contribution from the + surface elements must be stored. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + * \param[out] workArray - Work array. + */ + void BC_Isothermal_Wall(CConfig *config, + const unsigned long surfElemBeg, + const unsigned long surfElemEnd, + const CSurfaceElementFEM *surfElem, + su2double *resFaces, + CNumerics *conv_numerics, + unsigned short val_marker, + su2double *workArray) override; + + /*! + * \brief Impose the boundary condition using characteristic reconstruction. + * \param[in] config - Definition of the particular problem. + * \param[in] surfElemBeg - Start index in the list of surface elements. + * \param[in] surfElemEnd - End index (not included) in the list of surface elements. + * \param[in] surfElem - Array of surface elements for which the boundary + conditions must be imposed. + * \param[out] resFaces - Array where the residual contribution from the + surface elements must be stored. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + * \param[out] workArray - Work array. + */ + void BC_Riemann(CConfig *config, + const unsigned long surfElemBeg, + const unsigned long surfElemEnd, + const CSurfaceElementFEM *surfElem, + su2double *resFaces, + CNumerics *conv_numerics, + unsigned short val_marker, + su2double *workArray) override; + + /*! + * \brief Impose the user customized boundary condition. + * \param[in] config - Definition of the particular problem. + * \param[in] surfElemBeg - Start index in the list of surface elements. + * \param[in] surfElemEnd - End index (not included) in the list of surface elements. + * \param[in] surfElem - Array of surface elements for which the boundary + conditions must be imposed. + * \param[out] resFaces - Array where the residual contribution from the + surface elements must be stored. + * \param[in] conv_numerics - Description of the numerical method. + * \param[out] workArray - Work array. + */ + void BC_Custom(CConfig *config, + const unsigned long surfElemBeg, + const unsigned long surfElemEnd, + const CSurfaceElementFEM *surfElem, + su2double *resFaces, + CNumerics *conv_numerics, + su2double *workArray) override; + + /*! + * \brief Compute the viscosity at the infinity. + * \return Value of the viscosity at the infinity. + */ + inline su2double GetViscosity_Inf(void) const override { return Viscosity_Inf; } + + /*! + * \brief Get the turbulent kinetic energy at the infinity. + * \return Value of the turbulent kinetic energy at the infinity. + */ + inline su2double GetTke_Inf(void) const override { return Tke_Inf; } + + /*! + * \brief Compute the viscous forces and all the addimensional coefficients. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Friction_Forces(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief Get the non dimensional lift coefficient (viscous contribution). + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the lift coefficient (viscous contribution) on the surface val_marker. + */ + inline su2double GetCL_Visc(unsigned short val_marker) const override { return CL_Visc[val_marker]; } + + /*! + * \brief Get the non dimensional sideforce coefficient (viscous contribution). + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the sideforce coefficient (viscous contribution) on the surface val_marker. + */ + inline su2double GetCSF_Visc(unsigned short val_marker) const override { return CSF_Visc[val_marker]; } + + /*! + * \brief Get the non dimensional drag coefficient (viscous contribution). + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the drag coefficient (viscous contribution) on the surface val_marker. + */ + inline su2double GetCD_Visc(unsigned short val_marker) const override { return CD_Visc[val_marker]; } + + /*! + * \brief Get the total non dimensional lift coefficient (viscous contribution). + * \return Value of the lift coefficient (viscous contribution). + */ + inline su2double GetAllBound_CL_Visc() const override { return AllBound_CL_Visc; } + + /*! + * \brief Get the total non dimensional sideforce coefficient (viscous contribution). + * \return Value of the lift coefficient (viscous contribution). + */ + inline su2double GetAllBound_CSF_Visc() const override { return AllBound_CSF_Visc; } + + /*! + * \brief Get the total non dimensional drag coefficient (viscous contribution). + * \return Value of the drag coefficient (viscous contribution). + */ + inline su2double GetAllBound_CD_Visc() const override { return AllBound_CD_Visc; } + + /*! + * \brief Get the max Omega. + * \return Value of the max Omega. + */ + inline su2double GetOmega_Max(void) const override { return Omega_Max; } + + /*! + * \brief Get the max Strain rate magnitude. + * \return Value of the max Strain rate magnitude. + */ + inline su2double GetStrainMag_Max(void) const override { return StrainMag_Max; } + + /*! + * \brief A virtual member. + * \return Value of the StrainMag_Max + */ + inline void SetStrainMag_Max(su2double val_strainmag_max) override { StrainMag_Max = val_strainmag_max; } + + /*! + * \brief A virtual member. + * \return Value of the Omega_Max + */ + inline void SetOmega_Max(su2double val_omega_max) override { Omega_Max = val_omega_max; } + +private: + + /*! + * \brief Function, which computes the spatial residual of the ADER-DG + predictor step for the given volume element and solution using an + aliased discretization in 2D. + * \param[in] config - Definition of the particular problem. + * \param[in] elem - Volume element for which the spatial residual of the + predictor step must be computed. + * \param[in] sol - Solution for which the residual must be computed. + * \param[in] nSimul - Number of entities (typically time integration points) + that are treated simultaneously. + * \param[in] NPad - Padded N value in the matrix multiplications to + obtain better performance. The solution sol is stored + with this padded value to avoid a memcpy. + * \param[out] res - Residual of the spatial DOFs to be computed by this + function. + * \param[out] work - Work array. + */ + void ADER_DG_AliasedPredictorResidual_2D(CConfig *config, + CVolumeElementFEM *elem, + const su2double *sol, + const unsigned short nSimul, + const unsigned short NPad, + su2double *res, + su2double *work) override; + +/*! + * \brief Function, which computes the spatial residual of the ADER-DG + predictor step for the given volume element and solution using an + aliased discretization in 3D. + * \param[in] config - Definition of the particular problem. + * \param[in] elem - Volume element for which the spatial residual of the + predictor step must be computed. + * \param[in] sol - Solution for which the residual must be computed. + * \param[in] nSimul - Number of entities (typically time integration points) + that are treated simultaneously. + * \param[in] NPad - Padded N value in the matrix multiplications to + obtain better performance. The solution sol is stored + with this padded value to avoid a memcpy. + * \param[out] res - Residual of the spatial DOFs to be computed by this + function. + * \param[out] work - Work array. + */ + void ADER_DG_AliasedPredictorResidual_3D(CConfig *config, + CVolumeElementFEM *elem, + const su2double *sol, + const unsigned short nSimul, + const unsigned short NPad, + su2double *res, + su2double *work) override; + /*! + * \brief Function, which computes the spatial residual of the ADER-DG + predictor step for the given volume element and solution using a + non-aliased discretization in 2D. + * \param[in] config - Definition of the particular problem. + * \param[in] elem - Volume element for which the spatial residual of the + predictor step must be computed. + * \param[in] sol - Solution for which the residual must be computed. + * \param[in] nSimul - Number of entities (typically time integration points) + that are treated simultaneously. + * \param[in] NPad - Padded N value in the matrix multiplications to + obtain better performance. The solution sol is stored + with this padded value to avoid a memcpy. + * \param[out] res - Residual of the spatial DOFs to be computed by this + function. + * \param[out] work - Work array. + */ + void ADER_DG_NonAliasedPredictorResidual_2D(CConfig *config, + CVolumeElementFEM *elem, + const su2double *sol, + const unsigned short nSimul, + const unsigned short NPad, + su2double *res, + su2double *work) override; + + /*! + * \brief Function, which computes the spatial residual of the ADER-DG + predictor step for the given volume element and solution using a + non-aliased discretization in 3D. + * \param[in] config - Definition of the particular problem. + * \param[in] elem - Volume element for which the spatial residual of the + predictor step must be computed. + * \param[in] sol - Solution for which the residual must be computed. + * \param[in] nSimul - Number of entities (typically time integration points) + that are treated simultaneously. + * \param[in] NPad - Padded N value in the matrix multiplications to + obtain better performance. The solution sol is stored + with this padded value to avoid a memcpy. + * \param[out] res - Residual of the spatial DOFs to be computed by this + function. + * \param[out] work - Work array. + */ + void ADER_DG_NonAliasedPredictorResidual_3D(CConfig *config, + CVolumeElementFEM *elem, + const su2double *sol, + const unsigned short nSimul, + const unsigned short NPad, + su2double *res, + su2double *work) override; + /*! + * \brief Function to compute the penalty terms in the integration + points of a face. + * \param[in] indFaceChunk - Index of the face in the chunk of fused faces. + * \param[in] nInt - Number of integration points of the face. + * \param[in] NPad - Value of the padding parameter to obtain optimal + performance in the gemm computations. + * \param[in] solInt0 - Solution in the integration points of side 0. + * \param[in] solInt1 - Solution in the integration points of side 1. + * \param[in] viscosityInt0 - Viscosity in the integration points of side 0. + * \param[in] viscosityInt1 - Viscosity in the integration points of side 1. + * \param[in] kOverCvInt0 - Heat conductivity divided by Cv in the + integration points of side 0. + * \param[in] kOverCvInt1 - Heat conductivity divided by Cv in the + integration points of side 1. + * \param[in] ConstPenFace - Penalty constant for this face. + * \param[in] lenScale0 - Length scale of the element of side 0. + * \param[in] lenScale1 - Length scale of the element of side 1. + * \param[in] metricNormalsFace - Metric terms in the integration points, which + contain the normals. + * \param[out] penaltyFluxes - Penalty fluxes in the integration points. + */ + void PenaltyTermsFluxFace(const unsigned short indFaceChunk, + const unsigned short nInt, + const unsigned short NPad, + const su2double *solInt0, + const su2double *solInt1, + const su2double *viscosityInt0, + const su2double *viscosityInt1, + const su2double *kOverCvInt0, + const su2double *kOverCvInt1, + const su2double ConstPenFace, + const su2double lenScale0, + const su2double lenScale1, + const su2double *metricNormalsFace, + su2double *penaltyFluxes); + + /*! + * \brief Function, which performs the treatment of the boundary faces for + the Navier-Stokes equations for the most of the boundary conditions. + * \param[in] config - Definition of the particular problem. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] nFaceSimul - Number of faces that are treated simultaneously + to improve performance. + * \param[in] NPad - Value of the padding parameter to obtain optimal + performance in the gemm computations. + * \param[in] Wall_HeatFlux - The value of the prescribed heat flux. + * \param[in] HeatFlux_Prescribed - Whether or not the heat flux is prescribed by + e.g. the boundary conditions. + * \param[in] Wall_Temperature - The value of the prescribed wall temperature. + * \param[in] Temperature_Prescribed - Whether or not the temperature is precribed + by e.g. the boundary conditions. + * \param[in] surfElem - Surface boundary elements for which the + residuals mut be computed. + * \param[in] solIntL - Left states in the integration points of the face. + * \param[in] solIntR - Right states in the integration points of the face. + * \param[out] workArray - Storage for the local arrays. + * \param[out] resFaces - Array to store the residuals of the face. + * \param[in,out] indResFaces - Index in resFaces, where the current residual + should be stored. It is updated in the function + for the next boundary element. + * \param[in,out] wallModel - Possible pointer to the wall model treatment. + NULL pointer indicates no wall model treatment. + */ + void ViscousBoundaryFacesBCTreatment(CConfig *config, + CNumerics *conv_numerics, + const unsigned short nFaceSimul, + const unsigned short NPad, + const su2double Wall_HeatFlux, + const bool HeatFlux_Prescribed, + const su2double Wall_Temperature, + const bool Temperature_Prescribed, + const CSurfaceElementFEM *surfElem, + const su2double *solIntL, + const su2double *solIntR, + su2double *workArray, + su2double *resFaces, + unsigned long &indResFaces, + CWallModel *wallModel); + + /*! + * \brief Function, which computes the viscous fluxes in the integration + points for the boundary faces that must be treated simulaneously. + This function uses the standard approach for computing the fluxes, + i.e. no wall modeling. + * \param[in] config - Definition of the particular problem. + * \param[in] nFaceSimul - Number of faces that are treated simultaneously + to improve performance. + * \param[in] NPad - Value of the padding parameter to obtain optimal + performance in the gemm computations. + * \param[in] nInt - Number of integration points on the face. + * \param[in] nDOFsElem - Number of DOFs of the adjacent element. + * \param[in] Wall_HeatFlux - The value of the prescribed heat flux. + * \param[in] HeatFlux_Prescribed - Whether or not the heat flux is prescribed by + e.g. the boundary conditions. + * \param[in] derBasisElem - Array, which contains the derivatives of the + basis functions of the adjacent element + in the integration points. + * \param[in] surfElem - Surface boundary elements for which the + viscous fluxes must be computed. + * \param[in] solIntL - Left states in the integration points of the face. + * \param[out] solElem - Storage for the solution in the adjacent elements. + * \param[out] gradSolInt - Storage for the gradients of the solution in the + integration points of the face. + * \param[out] viscFluxes - To be computed viscous fluxes in the + integration points. + * \param[out] viscosityInt - To be computed viscosity in the integration points. + * \param[out] kOverCvInt - To be computed thermal conductivity in the + integration points. + */ + void ComputeViscousFluxesBoundaryFaces(CConfig *config, + const unsigned short nFaceSimul, + const unsigned short NPad, + const unsigned short nInt, + const unsigned short nDOFsElem, + const su2double Wall_HeatFlux, + const bool HeatFlux_Prescribed, + const su2double *derBasisElem, + const CSurfaceElementFEM *surfElem, + const su2double *solIntL, + su2double *solElem, + su2double *gradSolInt, + su2double *viscFluxes, + su2double *viscosityInt, + su2double *kOverCvInt); + + /*! + * \brief Function, which computes the viscous fluxes in the integration + points for the boundary faces that must be treated simulaneously. + The viscous fluxes are computed via a wall modeling approach. + * \param[in] config - Definition of the particular problem. + * \param[in] nFaceSimul - Number of faces that are treated simultaneously + to improve performance. + * \param[in] NPad - Value of the padding parameter to obtain optimal + performance in the gemm computations. + * \param[in] nInt - Number of integration points on the face. + * \param[in] Wall_HeatFlux - The value of the prescribed heat flux. + * \param[in] HeatFlux_Prescribed - Whether or not the heat flux is prescribed by + the boundary conditions. + * \param[in] Wall_Temperature - The value of the prescribed wall temperature. + * \param[in] Temperature_Prescribed - Whether or not the temperature is precribed + by the boundary conditions + * \param[in] surfElem - Surface boundary elements for which the + viscous fluxes must be computed. + * \param[in] solIntL - Left states in the integration points of the face. + * \param[out] workArray - Storage array + * \param[out] viscFluxes - To be computed viscous fluxes in the + integration points. + * \param[out] viscosityInt - To be computed viscosity in the integration points. + * \param[out] kOverCvInt - To be computed thermal conductivity in the + integration points. + * \param[in,out] wallModel - Pointer to the wall model treatment. + */ + void WallTreatmentViscousFluxes(CConfig *config, + const unsigned short nFaceSimul, + const unsigned short NPad, + const unsigned short nInt, + const su2double Wall_HeatFlux, + const bool HeatFlux_Prescribed, + const su2double Wall_Temperature, + const bool Temperature_Prescribed, + const CSurfaceElementFEM *surfElem, + const su2double *solIntL, + su2double *workArray, + su2double *viscFluxes, + su2double *viscosityInt, + su2double *kOverCvInt, + CWallModel *wallModel); + + /*! + * \brief Function, which computes the residual contribution from a boundary + face in a viscous computation when the boundary conditions have + already been applied. + * \param[in] config - Definition of the particular problem. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] nFaceSimul - Number of fused faces, i.e. the number of faces + that are treated simultaneously to improve performance. + * \param[in] NPad - Value of the padding parameter to obtain optimal + performance in the gemm computations. + * \param[in] surfElem - Surface boundary elements for which the + contribution to the residual must be computed. + * \param[in] solInt0 - Solution in the integration points of side 0. + * \param[in] solInt1 - Solution in the integration points of side 1. + * \param[out] paramFluxes - Array used for temporary storage. + * \param[out] fluxes - Temporary storage for the fluxes in the + integration points. + * \param[in,out] viscFluxes - On input this array contains the viscous fluxes + in the integration points. It is also used for + temporary storage. + * \param[in] viscosityInt - Temporary storage for the viscosity in the + integration points. + * \param[in] kOverCvInt - Temporary storage for the thermal conductivity + over Cv in the integration points. + * \param[out] resFaces - Array to store the residuals of the face. + * \param[in,out] indResFaces - Index in resFaces, where the current residual + should be stored. It is updated in the function + for the next boundary element. + */ + void ResidualViscousBoundaryFace(CConfig *config, + CNumerics *conv_numerics, + const unsigned short nFaceSimul, + const unsigned short NPad, + const CSurfaceElementFEM *surfElem, + const su2double *solInt0, + const su2double *solInt1, + su2double *paramFluxes, + su2double *fluxes, + su2double *viscFluxes, + const su2double *viscosityInt, + const su2double *kOverCvInt, + su2double *resFaces, + unsigned long &indResFaces); + + /*! + * \brief Function to compute the symmetrizing terms in the integration + points of a face. + * \param[in] indFaceChunk - Index of the face in the chunk of fused faces. + * \param[in] nInt - Number of integration points of the face. + * \param[in] NPad - Value of the padding parameter to obtain optimal + performance in the gemm computations. + * \param[in] solInt0 - Solution in the integration points of side 0. + * \param[in] solInt1 - Solution in the integration points of side 1. + * \param[in] viscosityInt0 - Viscosity in the integration points of side 0. + * \param[in] viscosityInt1 - Viscosity in the integration points of side 1. + * \param[in] kOverCvInt0 - Heat conductivity divided by Cv in the + integration points of side 0. + * \param[in] kOverCvInt1 - Heat conductivity divided by Cv in the + integration points of side 1. + * \param[in] metricNormalsFace - Metric terms in the integration points, which + contain the normals. + * \param[out] symmFluxes - Symmetrizing fluxes in the integration points. + */ + void SymmetrizingFluxesFace(const unsigned short indFaceChunk, + const unsigned short nInt, + const unsigned short NPad, + const su2double *solInt0, + const su2double *solInt1, + const su2double *viscosityInt0, + const su2double *viscosityInt1, + const su2double *kOverCvInt0, + const su2double *kOverCvInt1, + const su2double *metricNormalsFace, + su2double *symmFluxes); + + /*! + * \brief Function, which transforms the symmetrizing fluxes in the integration points + such that they are suited to be multiplied by the parametric gradients of + the basis functions. + * \param[in] indFaceChunk - Index of the face in the chunk of fused faces. + * \param[in] nInt - Number of integration points of the face. + * \param[in] NPad - Value of the padding parameter to obtain optimal + performance in the gemm computations. + * \param[in] halfTheta - Half times the theta parameter in the symmetrizing terms. + * \param[in] symmFluxes - Symmetrizing fluxes to be multiplied by the Cartesian + gradients of the basis functions. + * \param[in] weights - Integration weights of the integration points. + * \param[in] metricCoorFace - Derivatives of the parametric coordinates w.r.t. the + Cartesian coordinates in the integration points of + the face. + * \param[out] paramFluxes - Parametric fluxes in the integration points. + */ + void TransformSymmetrizingFluxes(const unsigned short indFaceChunk, + const unsigned short nInt, + const unsigned short NPad, + const su2double halfTheta, + const su2double *symmFluxes, + const su2double *weights, + const su2double *metricCoorFace, + su2double *paramFluxes); + + /*! + * \brief Function to compute the viscous normal fluxes in the integration points of a face. + * \param[in] adjVolElem - Pointer to the adjacent volume. + * \param[in] indFaceChunk - Index of the face in the chunk of fused faces. + * \param[in] nInt - Number of integration points of the face. + * \param[in] NPad - Value of the padding parameter to obtain optimal + performance in the gemm computations. + * \param[in] Wall_HeatFlux - The value of the prescribed heat flux. + * \param[in] HeatFlux_Prescribed - Whether or not the heat flux is prescribed by + e.g. the boundary conditions. + * \param[in] solInt - Solution in the integration points. + * \param[in] gradSolInt - Gradient of the solution in the integration points. + * \param[in] metricCoorDerivFace - Metric terms in the integration points, which + contain the derivatives of the parametric + coordinates w.r.t. the Cartesian coordinates. + Needed to compute the Cartesian gradients. + * \param[in] metricNormalsFace - Metric terms in the integration points, which + contain the normals. + * \param[in] wallDistanceInt - Wall distances in the integration points of the face. + * \param[out] viscNormFluxes - Viscous normal fluxes in the integration points. + * \param[out] viscosityInt - Viscosity in the integration points, which is + needed for other terms in the discretization. + * \param[out] kOverCvInt - Thermal conductivity over Cv in the integration points, + which is needed for other terms in the discretization. + */ + void ViscousNormalFluxFace(const CVolumeElementFEM *adjVolElem, + const unsigned short indFaceChunk, + const unsigned short nInt, + const unsigned short NPad, + const su2double Wall_HeatFlux, + const bool HeatFlux_Prescribed, + const su2double *solInt, + const su2double *gradSolInt, + const su2double *metricCoorDerivFace, + const su2double *metricNormalsFace, + const su2double *wallDistanceInt, + su2double *viscNormFluxes, + su2double *viscosityInt, + su2double *kOverCvInt); + + /*! + * \brief Function to compute the viscous normal flux in one integration point for a + 2D simulation. + * \param[in] sol - Conservative variables. + * \param[in] solGradCart - Cartesian gradients of the conservative variables. + * \param[in] normal - Normal vector + * \param[in] HeatFlux - Value of the prescribed heat flux. If not + prescribed, this value should be zero. + * \param[in] factHeatFlux - Multiplication factor for the heat flux. It is zero + when the heat flux is prescribed and one when it has + to be computed. + * \param[in] wallDist - Distance to the nearest viscous wall, if appropriate. + * \param[in lenScale_LES - LES length scale, if appropriate. + * \param[out] Viscosity - Total viscosity, to be computed. + * \param[out] kOverCv - Total thermal conductivity over Cv, to be computed. + * \param[out] normalFlux - Viscous normal flux, to be computed. + */ + void ViscousNormalFluxIntegrationPoint_2D(const su2double *sol, + const su2double solGradCart[4][2], + const su2double *normal, + const su2double HeatFlux, + const su2double factHeatFlux, + const su2double wallDist, + const su2double lenScale_LES, + su2double &Viscosity, + su2double &kOverCv, + su2double *normalFlux); + + /*! + * \brief Function to compute the viscous normal flux in one integration point for a + 3D simulation. + * \param[in] sol - Conservative variables. + * \param[in] solGradCart - Cartesian gradients of the conservative variables. + * \param[in] normal - Normal vector + * \param[in] HeatFlux - Value of the prescribed heat flux. If not + prescribed, this value should be zero. + * \param[in] factHeatFlux - Multiplication factor for the heat flux. It is zero + when the heat flux is prescribed and one when it has + to be computed. + * \param[in] wallDist - Distance to the nearest viscous wall, if appropriate. + * \param[in lenScale_LES - LES length scale, if appropriate. + * \param[out] Viscosity - Total viscosity, to be computed. + * \param[out] kOverCv - Total thermal conductivity over Cv, to be computed. + * \param[out] normalFlux - Viscous normal flux, to be computed. + */ + void ViscousNormalFluxIntegrationPoint_3D(const su2double *sol, + const su2double solGradCart[5][3], + const su2double *normal, + const su2double HeatFlux, + const su2double factHeatFlux, + const su2double wallDist, + const su2double lenScale_LES, + su2double &Viscosity, + su2double &kOverCv, + su2double *normalFlux); +}; \ No newline at end of file diff --git a/SU2_CFD/include/solvers/CHeatSolverFVM.hpp b/SU2_CFD/include/solvers/CHeatSolverFVM.hpp new file mode 100644 index 000000000000..25f2c4b5a762 --- /dev/null +++ b/SU2_CFD/include/solvers/CHeatSolverFVM.hpp @@ -0,0 +1,383 @@ +/*! + * \file CHeatSolverFVM.hpp + * \brief Headers of the CHeatSolverFVM class + * \author O. Burghardt + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#pragma once + +#include "CSolver.hpp" +#include "../variables/CHeatFVMVariable.hpp" + +/*! \class CHeatSolverFVM + * \brief Main class for defining the finite-volume heat solver. + * \author O. Burghardt + * \date January 19, 2018. + */ +class CHeatSolverFVM final : public CSolver { +protected: + unsigned short nVarFlow, nMarker, CurrentMesh; + su2double **HeatFlux, *HeatFlux_per_Marker, *Surface_HF, Total_HeatFlux, AllBound_HeatFlux, + *AverageT_per_Marker, Total_AverageT, AllBound_AverageT, + *Primitive, *Primitive_Flow_i, *Primitive_Flow_j, + *Surface_Areas, Total_HeatFlux_Areas, Total_HeatFlux_Areas_Monitor; + su2double ***ConjugateVar, ***InterfaceVar; + + CHeatFVMVariable* nodes = nullptr; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ + + /*! + * \brief Return nodes to allow CSolver::base_nodes to be set. + */ + inline CVariable* GetBaseClassPointerToNodes() override { return nodes; } + +public: + + /*! + * \brief Constructor of the class. + */ + CHeatSolverFVM(void); + + /*! + * \brief Constructor of the class. + */ + CHeatSolverFVM(CGeometry *geometry, CConfig *config, unsigned short iMesh); + + /*! + * \brief Destructor of the class. + */ + virtual ~CHeatSolverFVM(void); + + /*! + * \brief Restart residual and compute gradients. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + * \param[in] Output - boolean to determine whether to print output. + */ + void Preprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep, + unsigned short RunTime_EqSystem, + bool Output) override; + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Postprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh) override; + + /*! + * \brief Load a solution from a restart file. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Container vector with all of the solvers. + * \param[in] config - Definition of the particular problem. + * \param[in] val_iter - Current external iteration number. + * \param[in] val_update_geo - Flag for updating coords and grid velocity. + */ + void LoadRestart(CGeometry **geometry, + CSolver ***solver, + CConfig *config, + int val_iter, + bool val_update_geo) override; + + /*! + * \brief Source term computation. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] second_numerics - Description of the second numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Source_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CNumerics *second_numerics, + CConfig *config, unsigned short iMesh) override; + + /*! + * \brief Compute the undivided laplacian for the solution. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void SetUndivided_Laplacian(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief Compute the spatial integration using a centered scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + void Centered_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep) override; + /*! + * \brief Compute the spatial integration using a upwind scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Upwind_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh) override; + + /*! + * \brief Compute the viscous residuals for the turbulent equation. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + void Viscous_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep) override; + + + void Set_Heatflux_Areas(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief Impose the Navier-Stokes boundary condition (strong). + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Isothermal_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose a constant heat-flux condition at the wall. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_HeatFlux_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the inlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Inlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + /*! + * \brief Impose the outlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Outlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the (received) conjugate heat variables. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_ConjugateHeat_Interface(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Set the conjugate heat variables. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + * \param[in] pos_var - variable position (in vector of all conjugate heat variables) + */ + inline su2double GetConjugateHeatVariable(unsigned short val_marker, + unsigned long val_vertex, + unsigned short pos_var) const override { + return ConjugateVar[val_marker][val_vertex][pos_var]; + } + + /*! + * \brief Set the conjugate heat variables. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + * \param[in] pos_var - variable position (in vector of all conjugate heat variables) + * \param[in] relaxation factor - relaxation factor for the change of the variables + * \param[in] val_var - value of the variable + */ + inline void SetConjugateHeatVariable(unsigned short val_marker, + unsigned long val_vertex, + unsigned short pos_var, + su2double relaxation_factor, + su2double val_var) override { + ConjugateVar[val_marker][val_vertex][pos_var] = relaxation_factor*val_var + (1.0-relaxation_factor)*ConjugateVar[val_marker][val_vertex][pos_var]; + } + + + /*! + * \brief Evaluate heat-flux related objectives. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void Heat_Fluxes(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) override; + + /*! + * \brief Get value of the heat load (integrated heat flux). + * \return Value of the heat load (integrated heat flux). + */ + inline su2double GetTotal_HeatFlux() const override { return Total_HeatFlux; } + + /*! + * \brief Get value of the integral-averaged temperature. + * \return Value of the integral-averaged temperature. + */ + inline su2double GetTotal_AvgTemperature() const override { return Total_AverageT; } + + /*! + * \brief Update the solution using an implicit solver. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void ImplicitEuler_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) override; + + /*! + * \brief Update the solution using an explicit solver. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void ExplicitEuler_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) override; + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] Iteration - Index of the current iteration. + */ + void SetTime_Step(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned long Iteration) override; + + /*! + * \brief Set the initial condition for the FEM structural problem. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] ExtIter - External iteration. + */ + void SetInitialCondition(CGeometry **geometry, + CSolver ***solver_container, + CConfig *config, + unsigned long TimeIter) override; + + /*! + * \brief Set the total residual adding the term that comes from the Dual Time-Stepping Strategy. + * \param[in] geometry - Geometric definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + */ + void SetResidual_DualTime(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iRKStep, + unsigned short iMesh, + unsigned short RunTime_EqSystem) override; + + /*! + * \brief Get the heat flux. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the heat flux. + */ + inline su2double GetHeatFlux(unsigned short val_marker, unsigned long val_vertex) const override { return HeatFlux[val_marker][val_vertex]; } + +}; \ No newline at end of file diff --git a/SU2_CFD/include/solvers/CIncEulerSolver.hpp b/SU2_CFD/include/solvers/CIncEulerSolver.hpp new file mode 100644 index 000000000000..ead44a472476 --- /dev/null +++ b/SU2_CFD/include/solvers/CIncEulerSolver.hpp @@ -0,0 +1,1532 @@ +/*! + * \file CIncEulerSolver.hpp + * \brief Headers of the CIncEulerSolver class + * \author F. Palacios, T. Economon, T. Albring + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + + +#pragma once + +#include "CSolver.hpp" +#include "../variables/CIncEulerVariable.hpp" + +/*! + * \class CIncEulerSolver + * \brief Main class for defining the incompressible Euler flow solver. + * \ingroup Euler_Equations + * \author F. Palacios, T. Economon, T. Albring + */ +class CIncEulerSolver : public CSolver { +protected: + + su2double + Density_Inf, /*!< \brief Density at the infinity. */ + Pressure_Inf, /*!< \brief Pressure at the infinity. */ + *Velocity_Inf, /*!< \brief Flow Velocity vector at the infinity. */ + Temperature_Inf; /*!< \brief Temperature at infinity. */ + + su2double + *CD_Inv, /*!< \brief Drag coefficient (inviscid contribution) for each boundary. */ + *CL_Inv, /*!< \brief Lift coefficient (inviscid contribution) for each boundary. */ + *CSF_Inv, /*!< \brief Sideforce coefficient (inviscid contribution) for each boundary. */ + *CMx_Inv, /*!< \brief x Moment coefficient (inviscid contribution) for each boundary. */ + *CMy_Inv, /*!< \brief y Moment coefficient (inviscid contribution) for each boundary. */ + *CMz_Inv, /*!< \brief z Moment coefficient (inviscid contribution) for each boundary. */ + *CoPx_Inv, /*!< \brief x Moment coefficient (inviscid contribution) for each boundary. */ + *CoPy_Inv, /*!< \brief y Moment coefficient (inviscid contribution) for each boundary. */ + *CoPz_Inv, /*!< \brief z Moment coefficient (inviscid contribution) for each boundary. */ + *CFx_Inv, /*!< \brief x Force coefficient (inviscid contribution) for each boundary. */ + *CFy_Inv, /*!< \brief y Force coefficient (inviscid contribution) for each boundary. */ + *CFz_Inv, /*!< \brief z Force coefficient (inviscid contribution) for each boundary. */ + *Surface_CL_Inv, /*!< \brief Lift coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CD_Inv, /*!< \brief Drag coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CSF_Inv, /*!< \brief Side-force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CEff_Inv, /*!< \brief Side-force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CFx_Inv, /*!< \brief x Force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CFy_Inv, /*!< \brief y Force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CFz_Inv, /*!< \brief z Force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CMx_Inv, /*!< \brief x Moment coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CMy_Inv, /*!< \brief y Moment coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CMz_Inv, /*!< \brief z Moment coefficient (inviscid contribution) for each monitoring surface. */ + *CEff_Inv, /*!< \brief Efficiency (Cl/Cd) (inviscid contribution) for each boundary. */ + *CMerit_Inv, /*!< \brief Rotor Figure of Merit (inviscid contribution) for each boundary. */ + *CT_Inv, /*!< \brief Thrust coefficient (force in -x direction, inviscid contribution) for each boundary. */ + *CQ_Inv, /*!< \brief Torque coefficient (moment in -x direction, inviscid contribution) for each boundary. */ + *CD_Mnt, /*!< \brief Drag coefficient (inviscid contribution) for each boundary. */ + *CL_Mnt, /*!< \brief Lift coefficient (inviscid contribution) for each boundary. */ + *CSF_Mnt, /*!< \brief Sideforce coefficient (inviscid contribution) for each boundary. */ + *CMx_Mnt, /*!< \brief x Moment coefficient (inviscid contribution) for each boundary. */ + *CMy_Mnt, /*!< \brief y Moment coefficient (inviscid contribution) for each boundary. */ + *CMz_Mnt, /*!< \brief z Moment coefficient (inviscid contribution) for each boundary. */ + *CoPx_Mnt, /*!< \brief x Moment coefficient (inviscid contribution) for each boundary. */ + *CoPy_Mnt, /*!< \brief y Moment coefficient (inviscid contribution) for each boundary. */ + *CoPz_Mnt, /*!< \brief z Moment coefficient (inviscid contribution) for each boundary. */ + *CFx_Mnt, /*!< \brief x Force coefficient (inviscid contribution) for each boundary. */ + *CFy_Mnt, /*!< \brief y Force coefficient (inviscid contribution) for each boundary. */ + *CFz_Mnt, /*!< \brief z Force coefficient (inviscid contribution) for each boundary. */ + *Surface_CL_Mnt, /*!< \brief Lift coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CD_Mnt, /*!< \brief Drag coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CSF_Mnt, /*!< \brief Side-force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CEff_Mnt, /*!< \brief Side-force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CFx_Mnt, /*!< \brief x Force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CFy_Mnt, /*!< \brief y Force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CFz_Mnt, /*!< \brief z Force coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CMx_Mnt, /*!< \brief x Moment coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CMy_Mnt, /*!< \brief y Moment coefficient (inviscid contribution) for each monitoring surface. */ + *Surface_CMz_Mnt, /*!< \brief z Moment coefficient (inviscid contribution) for each monitoring surface. */ + *CEff_Mnt, /*!< \brief Efficiency (Cl/Cd) (inviscid contribution) for each boundary. */ + *CMerit_Mnt, /*!< \brief Rotor Figure of Merit (inviscid contribution) for each boundary. */ + *CT_Mnt, /*!< \brief Thrust coefficient (force in -x direction, inviscid contribution) for each boundary. */ + *CQ_Mnt, /*!< \brief Torque coefficient (moment in -x direction, inviscid contribution) for each boundary. */ + **CPressure, /*!< \brief Pressure coefficient for each boundary and vertex. */ + **CPressureTarget, /*!< \brief Target Pressure coefficient for each boundary and vertex. */ + **HeatFlux, /*!< \brief Heat transfer coefficient for each boundary and vertex. */ + **HeatFluxTarget, /*!< \brief Heat transfer coefficient for each boundary and vertex. */ + **YPlus, /*!< \brief Yplus for each boundary and vertex. */ + ***CharacPrimVar, /*!< \brief Value of the characteristic variables at each boundary. */ + *ForceInviscid, /*!< \brief Inviscid force for each boundary. */ + *MomentInviscid, /*!< \brief Inviscid moment for each boundary. */ + *ForceMomentum, /*!< \brief Inviscid force for each boundary. */ + *MomentMomentum, /*!< \brief Inviscid moment for each boundary. */ + InverseDesign; /*!< \brief Inverse design functional for each boundary. */ + su2double + **Inlet_Ptotal, /*!< \brief Value of the Total P. */ + **Inlet_Ttotal, /*!< \brief Value of the Total T. */ + ***Inlet_FlowDir; /*!< \brief Value of the Flow Direction. */ + + su2double + AllBound_CD_Inv, /*!< \brief Total drag coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CL_Inv, /*!< \brief Total lift coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CSF_Inv, /*!< \brief Total sideforce coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMx_Inv, /*!< \brief Total x moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMy_Inv, /*!< \brief Total y moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMz_Inv, /*!< \brief Total z moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CFx_Inv, /*!< \brief Total x force coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CFy_Inv, /*!< \brief Total y force coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CFz_Inv, /*!< \brief Total z force coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CoPx_Inv, /*!< \brief Total x moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CoPy_Inv, /*!< \brief Total y moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CoPz_Inv, /*!< \brief Total z moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CEff_Inv, /*!< \brief Efficient coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMerit_Inv, /*!< \brief Rotor Figure of Merit (inviscid contribution) for all the boundaries. */ + AllBound_CT_Inv, /*!< \brief Total thrust coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CQ_Inv; /*!< \brief Total torque coefficient (inviscid contribution) for all the boundaries. */ + + + su2double + AllBound_CD_Mnt, /*!< \brief Total drag coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CL_Mnt, /*!< \brief Total lift coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CSF_Mnt, /*!< \brief Total sideforce coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMx_Mnt, /*!< \brief Total x moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMy_Mnt, /*!< \brief Total y moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMz_Mnt, /*!< \brief Total z moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CFx_Mnt, /*!< \brief Total x force coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CFy_Mnt, /*!< \brief Total y force coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CFz_Mnt, /*!< \brief Total z force coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CoPx_Mnt, /*!< \brief Total x moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CoPy_Mnt, /*!< \brief Total y moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CoPz_Mnt, /*!< \brief Total z moment coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CEff_Mnt, /*!< \brief Efficient coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMerit_Mnt, /*!< \brief Rotor Figure of Merit (inviscid contribution) for all the boundaries. */ + AllBound_CT_Mnt, /*!< \brief Total thrust coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CQ_Mnt; /*!< \brief Total torque coefficient (inviscid contribution) for all the boundaries. */ + + su2double + Total_ComboObj, /*!< \brief Total 'combo' objective for all monitored boundaries */ + Total_CD, /*!< \brief Total drag coefficient for all the boundaries. */ + Total_CL, /*!< \brief Total lift coefficient for all the boundaries. */ + Total_CSF, /*!< \brief Total sideforce coefficient for all the boundaries. */ + Total_CMx, /*!< \brief Total x moment coefficient for all the boundaries. */ + Total_CMy, /*!< \brief Total y moment coefficient for all the boundaries. */ + Total_CMz, /*!< \brief Total z moment coefficient for all the boundaries. */ + Total_CoPx, /*!< \brief Total x moment coefficient for all the boundaries. */ + Total_CoPy, /*!< \brief Total y moment coefficient for all the boundaries. */ + Total_CoPz, /*!< \brief Total z moment coefficient for all the boundaries. */ + Total_CFx, /*!< \brief Total x force coefficient for all the boundaries. */ + Total_CFy, /*!< \brief Total y force coefficient for all the boundaries. */ + Total_CFz, /*!< \brief Total z force coefficient for all the boundaries. */ + Total_CEff, /*!< \brief Total efficiency coefficient for all the boundaries. */ + Total_CMerit, /*!< \brief Total rotor Figure of Merit for all the boundaries. */ + Total_CT, /*!< \brief Total thrust coefficient for all the boundaries. */ + Total_CQ, /*!< \brief Total torque coefficient for all the boundaries. */ + Total_Heat, /*!< \brief Total heat load for all the boundaries. */ + Total_MaxHeat, /*!< \brief Maximum heat flux on all boundaries. */ + Total_CpDiff, /*!< \brief Total Equivalent Area coefficient for all the boundaries. */ + Total_HeatFluxDiff, /*!< \brief Total Equivalent Area coefficient for all the boundaries. */ + Total_Custom_ObjFunc, /*!< \brief Total custom objective function for all the boundaries. */ + Total_MassFlowRate; /*!< \brief Total Mass Flow Rate on monitored boundaries. */ + su2double + *Surface_CL, /*!< \brief Lift coefficient for each monitoring surface. */ + *Surface_CD, /*!< \brief Drag coefficient for each monitoring surface. */ + *Surface_CSF, /*!< \brief Side-force coefficient for each monitoring surface. */ + *Surface_CEff, /*!< \brief Side-force coefficient for each monitoring surface. */ + *Surface_CFx, /*!< \brief x Force coefficient for each monitoring surface. */ + *Surface_CFy, /*!< \brief y Force coefficient for each monitoring surface. */ + *Surface_CFz, /*!< \brief z Force coefficient for each monitoring surface. */ + *Surface_CMx, /*!< \brief x Moment coefficient for each monitoring surface. */ + *Surface_CMy, /*!< \brief y Moment coefficient for each monitoring surface. */ + *Surface_CMz, /*!< \brief z Moment coefficient for each monitoring surface. */ + *Surface_HF_Visc, /*!< \brief Total (integrated) heat flux for each monitored surface. */ + *Surface_MaxHF_Visc; /*!< \brief Maximum heat flux for each monitored surface. */ + + su2double *SecondaryVar_i, /*!< \brief Auxiliary vector for storing the solution at point i. */ + *SecondaryVar_j; /*!< \brief Auxiliary vector for storing the solution at point j. */ + su2double *PrimVar_i, /*!< \brief Auxiliary vector for storing the solution at point i. */ + *PrimVar_j; /*!< \brief Auxiliary vector for storing the solution at point j. */ + bool space_centered, /*!< \brief True if space centered scheeme used. */ + euler_implicit, /*!< \brief True if euler implicit scheme used. */ + least_squares; /*!< \brief True if computing gradients by least squares. */ + su2double Gamma; /*!< \brief Fluid's Gamma constant (ratio of specific heats). */ + su2double Gamma_Minus_One; /*!< \brief Fluids's Gamma - 1.0 . */ + + su2double *Primitive, /*!< \brief Auxiliary nPrimVar vector. */ + *Primitive_i, /*!< \brief Auxiliary nPrimVar vector for storing the primitive at point i. */ + *Primitive_j; /*!< \brief Auxiliary nPrimVar vector for storing the primitive at point j. */ + + CFluidModel *FluidModel; /*!< \brief fluid model used in the solver */ + su2double **Preconditioner; /*!< \brief Auxiliary matrix for storing the low speed preconditioner. */ + + /* Sliding meshes variables */ + + su2double ****SlidingState; + int **SlidingStateNodes; + + CIncEulerVariable* nodes = nullptr; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ + + /*! + * \brief Return nodes to allow CSolver::base_nodes to be set. + */ + inline CVariable* GetBaseClassPointerToNodes() final { return nodes; } + +public: + + /*! + * \brief Constructor of the class. + */ + CIncEulerSolver(void); + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + CIncEulerSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); + + /*! + * \brief Destructor of the class. + */ + virtual ~CIncEulerSolver(void); + + /*! + * \brief Set the solver nondimensionalization. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void SetNondimensionalization(CConfig *config, unsigned short iMesh) final; + + /*! + * \brief Compute the pressure at the infinity. + * \return Value of the pressure at the infinity. + */ + inline CFluidModel* GetFluidModel(void) const final { return FluidModel;} + + /*! + * \brief Compute the density at the infinity. + * \return Value of the density at the infinity. + */ + inline su2double GetDensity_Inf(void) const final { return Density_Inf; } + + /*! + * \brief Compute 2-norm of the velocity at the infinity. + * \return Value of the 2-norm of the velocity at the infinity. + */ + inline su2double GetModVelocity_Inf(void) const final { + su2double Vel2 = 0; + for (unsigned short iDim = 0; iDim < nDim; iDim++) + Vel2 += Velocity_Inf[iDim]*Velocity_Inf[iDim]; + return sqrt(Vel2); + } + + + /*! + * \brief Compute the pressure at the infinity. + * \return Value of the pressure at the infinity. + */ + inline su2double GetPressure_Inf(void) const final { return Pressure_Inf; } + + /*! + * \brief Get the temperature value at infinity. + * \return Value of the temperature at infinity. + */ + inline su2double GetTemperature_Inf(void) const { return Temperature_Inf; } + + /*! + * \brief Compute the density multiply by velocity at the infinity. + * \param[in] val_dim - Index of the velocity vector. + * \return Value of the density multiply by the velocity at the infinity. + */ + inline su2double GetDensity_Velocity_Inf(unsigned short val_dim) const final { return Density_Inf*Velocity_Inf[val_dim]; } + + /*! + * \brief Get the velocity at the infinity. + * \param[in] val_dim - Index of the velocity vector. + * \return Value of the velocity at the infinity. + */ + inline su2double GetVelocity_Inf(unsigned short val_dim) const final { return Velocity_Inf[val_dim]; } + + /*! + * \brief Get the velocity at the infinity. + * \return Value of the velocity at the infinity. + */ + inline su2double *GetVelocity_Inf(void) const final { return Velocity_Inf; } + + /*! + * \brief Set the velocity at infinity. + * \param[in] val_dim - Index of the velocity vector. + * \param[in] val_velocity - Value of the velocity. + */ + inline void SetVelocity_Inf(unsigned short val_dim, su2double val_velocity) final { + Velocity_Inf[val_dim] = val_velocity; + } + + /*! + * \brief Compute the time step for solving the Euler equations. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] Iteration - Value of the current iteration. + */ + void SetTime_Step(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned long Iteration) override; + + /*! + * \brief Compute the spatial integration using a centered scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + void Centered_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep) final; + + /*! + * \brief Compute the spatial integration using a upwind scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Upwind_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh) final; + + /*! + * \brief Source term integration. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] second_numerics - Description of the second numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Source_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CNumerics *second_numerics, + CConfig *config, unsigned short iMesh) final; + + /*! + * \brief Source term integration. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Source_Template(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh) final; + + /*! + * \brief Compute primitive variables and their gradients. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + * \param[in] Output - boolean to determine whether to print output. + */ + void Preprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep, + unsigned short RunTime_EqSystem, + bool Output) override; + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Postprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh) final; + + /*! + * \brief Compute the velocity^2, SoundSpeed, Pressure, Enthalpy, Viscosity. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] Output - boolean to determine whether to print output. + * \return - The number of non-physical points. + */ + unsigned long SetPrimitive_Variables(CSolver **solver_container, + CConfig *config, + bool Output) override; + + /*! + * \brief Compute a pressure sensor switch. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void SetCentered_Dissipation_Sensor(CGeometry *geometry, CConfig *config) final; + + /*! + * \brief Compute the gradient of the primitive variables using Green-Gauss method, + * and stores the result in the Gradient_Primitive variable. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] reconstruction - indicator that the gradient being computed is for upwind reconstruction. + */ + void SetPrimitive_Gradient_GG(CGeometry *geometry, + CConfig *config, + bool reconstruction = false) final; + + /*! + * \brief Compute the gradient of the primitive variables using a Least-Squares method, + * and stores the result in the Gradient_Primitive variable. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] reconstruction - indicator that the gradient being computed is for upwind reconstruction. + */ + void SetPrimitive_Gradient_LS(CGeometry *geometry, + CConfig *config, + bool reconstruction = false) final; + + /*! + * \brief Compute the limiter of the primitive variables. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void SetPrimitive_Limiter(CGeometry *geometry, CConfig *config) final; + + /*! + * \brief Compute the undivided laplacian for the solution, except the energy equation. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void SetUndivided_Laplacian(CGeometry *geometry, CConfig *config) final; + + /*! + * \brief Compute the max eigenvalue. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void SetMax_Eigenvalue(CGeometry *geometry, CConfig *config) final; + + /*! + * \author H. Kline + * \brief Compute weighted-sum "combo" objective output + * \param[in] config - Definition of the particular problem. + */ + void Evaluate_ObjFunc(CConfig *config) final; + + /*! + * \author: T. Kattmann + * \brief Impose via the residual the Euler wall boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Euler_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the far-field boundary condition using characteristics. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Far_Field(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose the symmetry boundary condition using the residual. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Sym_Plane(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose a subsonic inlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Inlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose a custom or verification boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the convective numerical method. + * \param[in] visc_numerics - Description of the viscous numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Custom(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose the outlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Outlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose the interface state across sliding meshes. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + void BC_Fluid_Interface(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config) final; + + /*! + * \brief Impose a periodic boundary condition by summing contributions from the complete control volume. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + void BC_Periodic(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config) final; + + /*! + * \brief compare to values. + * \param[in] a - value 1. + * \param[in] b - value 2. + */ + static bool Compareval(std::vector a,std::vector b); + + /*! + * \brief Update the solution using a Runge-Kutta scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + void ExplicitRK_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iRKStep) final; + + /*! + * \brief Update the solution using the explicit Euler scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void ExplicitEuler_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) final; + + /*! + * \brief Compute the pressure forces and all the adimensional coefficients. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Pressure_Forces(CGeometry *geometry, CConfig *config) final; + + /*! + * \brief Compute the pressure forces and all the adimensional coefficients. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Momentum_Forces(CGeometry *geometry, CConfig *config) final; + + /*! + * \brief Update the solution using an implicit Euler scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void ImplicitEuler_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) final; + + /*! + * \brief Compute a suitable under-relaxation parameter to limit the change in the solution variables over a nonlinear iteration for stability. + * \param[in] solver - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void ComputeUnderRelaxationFactor(CSolver **solver, CConfig *config) final; + + /*! + * \brief Provide the non dimensional lift coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the lift coefficient on the surface val_marker. + */ + inline su2double GetSurface_CL(unsigned short val_marker) const final { return Surface_CL[val_marker]; } + + /*! + * \brief Provide the non dimensional drag coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the drag coefficient on the surface val_marker. + */ + inline su2double GetSurface_CD(unsigned short val_marker) const final { return Surface_CD[val_marker]; } + + /*! + * \brief Provide the non dimensional side-force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side-force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CSF(unsigned short val_marker) const final { return Surface_CSF[val_marker]; } + + /*! + * \brief Provide the non dimensional side-force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side-force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CEff(unsigned short val_marker) const final { return Surface_CEff[val_marker]; } + + /*! + * \brief Provide the non dimensional x force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFx(unsigned short val_marker) const final { return Surface_CFx[val_marker]; } + + /*! + * \brief Provide the non dimensional y force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFy(unsigned short val_marker) const final { return Surface_CFy[val_marker]; } + + /*! + * \brief Provide the non dimensional z force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFz(unsigned short val_marker) const final { return Surface_CFz[val_marker]; } + + /*! + * \brief Provide the non dimensional x moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMx(unsigned short val_marker) const final { return Surface_CMx[val_marker]; } + + /*! + * \brief Provide the non dimensional y moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMy(unsigned short val_marker) const final { return Surface_CMy[val_marker]; } + + /*! + * \brief Provide the non dimensional z moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMz(unsigned short val_marker) const final { return Surface_CMz[val_marker]; } + + /*! + * \brief Provide the non dimensional lift coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the lift coefficient on the surface val_marker. + */ + inline su2double GetSurface_CL_Inv(unsigned short val_marker) const final { return Surface_CL_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional drag coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the drag coefficient on the surface val_marker. + */ + inline su2double GetSurface_CD_Inv(unsigned short val_marker) const final { return Surface_CD_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional side-force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side-force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CSF_Inv(unsigned short val_marker) const final { return Surface_CSF_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional side-force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side-force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CEff_Inv(unsigned short val_marker) const final { return Surface_CEff_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional x force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFx_Inv(unsigned short val_marker) const final { return Surface_CFx_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional y force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFy_Inv(unsigned short val_marker) const final { return Surface_CFy_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional z force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFz_Inv(unsigned short val_marker) const final { return Surface_CFz_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional x moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMx_Inv(unsigned short val_marker) const final { return Surface_CMx_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional y moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMy_Inv(unsigned short val_marker) const final { return Surface_CMy_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional z moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMz_Inv(unsigned short val_marker) const final { return Surface_CMz_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional lift coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the lift coefficient on the surface val_marker. + */ + inline su2double GetSurface_CL_Mnt(unsigned short val_marker) const final { return Surface_CL_Mnt[val_marker]; } + + /*! + * \brief Provide the non dimensional drag coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the drag coefficient on the surface val_marker. + */ + inline su2double GetSurface_CD_Mnt(unsigned short val_marker) const final { return Surface_CD_Mnt[val_marker]; } + + /*! + * \brief Provide the non dimensional side-force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side-force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CSF_Mnt(unsigned short val_marker) const final { return Surface_CSF_Mnt[val_marker]; } + + /*! + * \brief Provide the non dimensional side-force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side-force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CEff_Mnt(unsigned short val_marker) const final { return Surface_CEff_Mnt[val_marker]; } + + /*! + * \brief Provide the non dimensional x force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFx_Mnt(unsigned short val_marker) const final { return Surface_CFx_Mnt[val_marker]; } + + /*! + * \brief Provide the non dimensional y force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFy_Mnt(unsigned short val_marker) const final { return Surface_CFy_Mnt[val_marker]; } + + /*! + * \brief Provide the non dimensional z force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFz_Mnt(unsigned short val_marker) const final { return Surface_CFz_Mnt[val_marker]; } + + /*! + * \brief Provide the non dimensional x moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMx_Mnt(unsigned short val_marker) const final { return Surface_CMx_Mnt[val_marker]; } + + /*! + * \brief Provide the non dimensional y moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMy_Mnt(unsigned short val_marker) const final { return Surface_CMy_Mnt[val_marker]; } + + /*! + * \brief Provide the non dimensional z moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMz_Mnt(unsigned short val_marker) const final { return Surface_CMz_Mnt[val_marker]; } + + /*! + * \brief Provide the non dimensional drag coefficient (inviscid contribution). + * \param val_marker Surface where the coeficient is going to be computed. + * \return Value of the drag coefficient (inviscid contribution) on the surface val_marker. + */ + inline su2double GetCD_Inv(unsigned short val_marker) const final { return CD_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional sideforce coefficient (inviscid contribution). + * \param val_marker Surface where the coeficient is going to be computed. + * \return Value of the sideforce coefficient (inviscid contribution) on the surface val_marker. + */ + inline su2double GetCSF_Inv(unsigned short val_marker) const final { return CSF_Inv[val_marker]; } + + /*! + * \brief Provide the non dimensional efficiency coefficient (inviscid contribution). + * \param val_marker Surface where the coeficient is going to be computed. + * \return Value of the efficiency coefficient (inviscid contribution) on the surface val_marker. + */ + inline su2double GetCEff_Inv(unsigned short val_marker) const final { return CEff_Inv[val_marker]; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional sideforce coefficient. + * \return Value of the sideforce coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CSF() const final { return Total_CSF; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CEff() const final { return Total_CEff; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional Equivalent Area coefficient. + * \return Value of the Equivalent Area coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CpDiff() const final { return Total_CpDiff; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional Equivalent Area coefficient. + * \return Value of the Equivalent Area coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_HeatFluxDiff() const final { return Total_HeatFluxDiff; } + + /*! + * \brief Set the value of the Equivalent Area coefficient. + * \param[in] val_cequivarea - Value of the Equivalent Area coefficient. + */ + inline void SetTotal_CpDiff(su2double val_pressure) final { Total_CpDiff = val_pressure; } + + /*! + * \brief Set the value of the Equivalent Area coefficient. + * \param[in] val_cequivarea - Value of the Equivalent Area coefficient. + */ + inline void SetTotal_HeatFluxDiff(su2double val_heat) final { Total_HeatFluxDiff = val_heat; } + + /*! + * \brief Set the value of the custom objective function. + * \param[in] val_Total_Custom_ObjFunc - Value of the total custom objective function. + * \param[in] val_weight - Value of the weight for the custom objective function. + */ + inline void SetTotal_Custom_ObjFunc(su2double val_total_custom_objfunc, su2double val_weight) final { + Total_Custom_ObjFunc = val_total_custom_objfunc*val_weight; + } + + /*! + * \brief Add the value of the custom objective function. + * \param[in] val_Total_Custom_ObjFunc - Value of the total custom objective function. + * \param[in] val_weight - Value of the weight for the custom objective function. + */ + inline void AddTotal_Custom_ObjFunc(su2double val_total_custom_objfunc, su2double val_weight) final { + Total_Custom_ObjFunc += val_total_custom_objfunc*val_weight; + } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional lift coefficient. + * \return Value of the lift coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CL() const final { return Total_CL; } + + /*! + * \author H. Kline + * \brief Set the total "combo" objective (weighted sum of other values). + * \param[in] ComboObj - Value of the combined objective. + */ + inline void SetTotal_ComboObj(su2double ComboObj) final {Total_ComboObj = ComboObj; } + + /*! + * \author H. Kline + * \brief Provide the total "combo" objective (weighted sum of other values). + * \return Value of the "combo" objective values. + */ + inline su2double GetTotal_ComboObj() const final { return Total_ComboObj; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional drag coefficient. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CD() const final { return Total_CD; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional x moment coefficient. + * \return Value of the moment x coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CMx() const final { return Total_CMx; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional y moment coefficient. + * \return Value of the moment y coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CMy() const final { return Total_CMy; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional z moment coefficient. + * \return Value of the moment z coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CMz() const final { return Total_CMz; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional x moment coefficient. + * \return Value of the moment x coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CoPx() const final { return Total_CoPx; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional y moment coefficient. + * \return Value of the moment y coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CoPy() const final { return Total_CoPy; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional z moment coefficient. + * \return Value of the moment z coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CoPz() const final { return Total_CoPz; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional x force coefficient. + * \return Value of the force x coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CFx() const final { return Total_CFx; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional y force coefficient. + * \return Value of the force y coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CFy() const final { return Total_CFy; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional z force coefficient. + * \return Value of the force z coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CFz() const final { return Total_CFz; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional thrust coefficient. + * \return Value of the rotor efficiency coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CT() const final { return Total_CT; } + + /*! + * \brief Store the total (inviscid + viscous) non dimensional thrust coefficient. + * \param[in] val_Total_CT - Value of the total thrust coefficient. + */ + inline void SetTotal_CT(su2double val_Total_CT) final { Total_CT = val_Total_CT; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional torque coefficient. + * \return Value of the rotor efficiency coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CQ() const final { return Total_CQ; } + + /*! + * \brief Provide the total heat load. + * \return Value of the heat load (viscous contribution). + */ + inline su2double GetTotal_HeatFlux(void) const final { return Total_Heat; } + + /*! + * \brief Provide the total heat load. + * \return Value of the heat load (viscous contribution). + */ + inline su2double GetTotal_MaxHeatFlux() const final { return Total_MaxHeat; } + + /*! + * \brief Store the total (inviscid + viscous) non dimensional torque coefficient. + * \param[in] val_Total_CQ - Value of the total torque coefficient. + */ + inline void SetTotal_CQ(su2double val_Total_CQ) final { Total_CQ = val_Total_CQ; } + + /*! + * \brief Store the total heat load. + * \param[in] val_Total_Heat - Value of the heat load. + */ + inline void SetTotal_HeatFlux(su2double val_Total_Heat) final { Total_Heat = val_Total_Heat; } + + /*! + * \brief Store the total heat load. + * \param[in] val_Total_Heat - Value of the heat load. + */ + inline void SetTotal_MaxHeatFlux(su2double val_Total_MaxHeat) final { Total_MaxHeat = val_Total_MaxHeat; } + + /*! + * \brief Provide the total (inviscid + viscous) non dimensional rotor Figure of Merit. + * \return Value of the rotor efficiency coefficient (inviscid + viscous contribution). + */ + inline su2double GetTotal_CMerit() const final { return Total_CMerit; } + + /*! + * \brief Provide the total custom objective function. + * \return Value of the custom objective function. + */ + inline su2double GetTotal_Custom_ObjFunc() const final { return Total_Custom_ObjFunc; } + + /*! + * \brief Store the total (inviscid + viscous) non dimensional drag coefficient. + * \param[in] val_Total_CDrag - Value of the total drag coefficient. + */ + inline void SetTotal_CD(su2double val_Total_CD) final { Total_CD = val_Total_CD; } + + /*! + * \brief Get the inviscid contribution to the lift coefficient. + * \return Value of the lift coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CL_Inv() const final { return AllBound_CL_Inv; } + + /*! + * \brief Get the inviscid contribution to the drag coefficient. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CD_Inv() const final { return AllBound_CD_Inv; } + + /*! + * \brief Get the inviscid contribution to the sideforce coefficient. + * \return Value of the sideforce coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CSF_Inv() const final { return AllBound_CSF_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CEff_Inv() const final { return AllBound_CEff_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CMx_Inv() const final { return AllBound_CMx_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CMy_Inv() const final { return AllBound_CMy_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CMz_Inv() const final { return AllBound_CMz_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CoPx_Inv() const final { return AllBound_CoPx_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CoPy_Inv() const final { return AllBound_CoPy_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CoPz_Inv() const final { return AllBound_CoPz_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CFx_Inv() const final { return AllBound_CFx_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CFy_Inv() const final { return AllBound_CFy_Inv; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CFz_Inv() const final { return AllBound_CFz_Inv; } + + /*! + * \brief Get the inviscid contribution to the lift coefficient. + * \return Value of the lift coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CL_Mnt() const final { return AllBound_CL_Mnt; } + + /*! + * \brief Get the inviscid contribution to the drag coefficient. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CD_Mnt() const final { return AllBound_CD_Mnt; } + + /*! + * \brief Get the inviscid contribution to the sideforce coefficient. + * \return Value of the sideforce coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CSF_Mnt() const final { return AllBound_CSF_Mnt; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CEff_Mnt() const final { return AllBound_CEff_Mnt; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CMx_Mnt() const final { return AllBound_CMx_Mnt; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CMy_Mnt() const final { return AllBound_CMy_Mnt; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CMz_Mnt() const final { return AllBound_CMz_Mnt; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CoPx_Mnt() const final { return AllBound_CoPx_Mnt; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CoPy_Mnt() const final { return AllBound_CoPy_Mnt; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CoPz_Mnt() const final { return AllBound_CoPz_Mnt; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CFx_Mnt() const final { return AllBound_CFx_Mnt; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CFy_Mnt() const final { return AllBound_CFy_Mnt; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CFz_Mnt() const final { return AllBound_CFz_Mnt; } + + /*! + * \brief Provide the Pressure coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline su2double GetCPressure(unsigned short val_marker, unsigned long val_vertex) const final { + return CPressure[val_marker][val_vertex]; + } + + /*! + * \brief Provide the Target Pressure coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline su2double GetCPressureTarget(unsigned short val_marker, unsigned long val_vertex) const final { + return CPressureTarget[val_marker][val_vertex]; + } + + /*! + * \brief Set the value of the target Pressure coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline void SetCPressureTarget(unsigned short val_marker, + unsigned long val_vertex, + su2double val_pressure) final { + CPressureTarget[val_marker][val_vertex] = val_pressure; + } + + /*! + * \brief Value of the characteristic variables at the boundaries. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline su2double *GetCharacPrimVar(unsigned short val_marker, unsigned long val_vertex) const final { + return CharacPrimVar[val_marker][val_vertex]; + } + + /*! + * \brief Set the total residual adding the term that comes from the Dual Time Strategy. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + */ + void SetResidual_DualTime(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iRKStep, + unsigned short iMesh, + unsigned short RunTime_EqSystem) final; + + /*! + * \brief Load a solution from a restart file. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Container vector with all of the solvers. + * \param[in] config - Definition of the particular problem. + * \param[in] val_iter - Current external iteration number. + * \param[in] val_update_geo - Flag for updating coords and grid velocity. + */ + void LoadRestart(CGeometry **geometry, + CSolver ***solver, + CConfig *config, + int val_iter, + bool val_update_geo) final; + + /*! + * \brief Set the initial condition for the Euler Equations. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] ExtIter - External iteration. + */ + void SetInitialCondition(CGeometry **geometry, + CSolver ***solver_container, + CConfig *config, + unsigned long TimeIter) final; + + /*! + * \brief Set the freestream pressure. + * \param[in] Value of freestream pressure. + */ + inline void SetPressure_Inf(su2double p_inf) final { Pressure_Inf = p_inf; } + + /*! + * \brief Set the freestream temperature. + * \param[in] Value of freestream temperature. + */ + inline void SetTemperature_Inf(su2double t_inf) final { Temperature_Inf = t_inf; } + + /*! + * \brief Set the freestream temperature. + * \param[in] Value of freestream temperature. + */ + inline void SetDensity_Inf(su2double rho_inf) final { Density_Inf = rho_inf; } + + /*! + * \brief Set the solution using the Freestream values. + * \param[in] config - Definition of the particular problem. + */ + void SetFreeStream_Solution(CConfig *config) final; + + /*! + * \brief Update the Beta parameter for the incompressible preconditioner. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - current mesh level for the multigrid. + */ + void SetBeta_Parameter(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh) final; + + /*! + * \brief Compute the preconditioner for low-Mach flows. + * \param[in] iPoint - Index of the grid point + * \param[in] config - Definition of the particular problem. + */ + void SetPreconditioner(CConfig *config, unsigned long iPoint) final; + + /*! + * \brief Value of the total temperature at an inlet boundary. + * \param[in] val_marker - Surface marker where the total temperature is evaluated. + * \param[in] val_vertex - Vertex of the marker val_marker where the total temperature is evaluated. + * \return Value of the total temperature + */ + inline su2double GetInlet_Ttotal(unsigned short val_marker, unsigned long val_vertex) const final { return Inlet_Ttotal[val_marker][val_vertex]; } + + /*! + * \brief Value of the total pressure at an inlet boundary. + * \param[in] val_marker - Surface marker where the total pressure is evaluated. + * \param[in] val_vertex - Vertex of the marker val_marker where the total pressure is evaluated. + * \return Value of the total pressure + */ + inline su2double GetInlet_Ptotal(unsigned short val_marker, unsigned long val_vertex) const final { return Inlet_Ptotal[val_marker][val_vertex]; } + + /*! + * \brief A component of the unit vector representing the flow direction at an inlet boundary. + * \param[in] val_marker - Surface marker where the flow direction is evaluated + * \param[in] val_vertex - Vertex of the marker val_marker where the flow direction is evaluated + * \param[in] val_dim - The component of the flow direction unit vector to be evaluated + * \return Component of a unit vector representing the flow direction. + */ + inline su2double GetInlet_FlowDir(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_dim) const final { + return Inlet_FlowDir[val_marker][val_vertex][val_dim]; + } + + /*! + * \brief Set a uniform inlet profile + * + * The values at the inlet are set to match the values specified for + * inlets in the configuration file. + * + * \param[in] config - Definition of the particular problem. + * \param[in] iMarker - Surface marker where the coefficient is computed. + */ + void SetUniformInlet(CConfig* config, unsigned short iMarker) final; + + /*! + * \brief Store of a set of provided inlet profile values at a vertex. + * \param[in] val_inlet - vector containing the inlet values for the current vertex. + * \param[in] iMarker - Surface marker where the coefficient is computed. + * \param[in] iVertex - Vertex of the marker iMarker where the inlet is being set. + */ + void SetInletAtVertex(su2double *val_inlet, + unsigned short iMarker, + unsigned long iVertex) final; + + /*! + * \brief Get the set of value imposed at an inlet. + * \param[in] val_inlet - vector returning the inlet values for the current vertex. + * \param[in] val_inlet_point - Node index where the inlet is being set. + * \param[in] val_kind_marker - Enumerated type for the particular inlet type. + * \param[in] geometry - Geometrical definition of the problem. + * \param config - Definition of the particular problem. + * \return Value of the face area at the vertex. + */ + su2double GetInletAtVertex(su2double *val_inlet, + unsigned long val_inlet_point, + unsigned short val_kind_marker, + string val_marker, + CGeometry *geometry, + CConfig *config) const final; + + /*! + * \brief A virtual member. + */ + void GetOutlet_Properties(CGeometry *geometry, + CConfig *config, + unsigned short iMesh, + bool Output) final; + + /*! + * \brief Allocates the final pointer of SlidingState depending on how many donor vertex donate to it. That number is stored in SlidingStateNodes[val_marker][val_vertex]. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + */ + inline void SetSlidingStateStructure(unsigned short val_marker, unsigned long val_vertex) final { + int iVar; + + for( iVar = 0; iVar < nPrimVar+1; iVar++){ + if( SlidingState[val_marker][val_vertex][iVar] != NULL ) + delete [] SlidingState[val_marker][val_vertex][iVar]; + } + + for( iVar = 0; iVar < nPrimVar+1; iVar++) + SlidingState[val_marker][val_vertex][iVar] = new su2double[ GetnSlidingStates(val_marker, val_vertex) ]; + } + + + + + /*! + * \brief Set the outer state for fluid interface nodes. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + * \param[in] val_state - requested state component + * \param[in] donor_index - index of the donor node to set + * \param[in] component - set value + */ + inline void SetSlidingState(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_state, + unsigned long donor_index, + su2double component) final { + SlidingState[val_marker][val_vertex][val_state][donor_index] = component; + } + + + /*! + * \brief Set the number of outer state for fluid interface nodes. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + * \param[in] value - number of outer states + */ + inline void SetnSlidingStates(unsigned short val_marker, + unsigned long val_vertex, + int value) final { SlidingStateNodes[val_marker][val_vertex] = value; } + + /*! + * \brief Get the number of outer state for fluid interface nodes. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + */ + inline int GetnSlidingStates(unsigned short val_marker, unsigned long val_vertex) const final{ + return SlidingStateNodes[val_marker][val_vertex]; + } + + /*! + * \brief Get the outer state for fluid interface nodes. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + * \param[in] val_state - requested state component + * \param[in] donor_index- index of the donor node to get + */ + inline su2double GetSlidingState(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_state, + unsigned long donor_index) const final { + return SlidingState[val_marker][val_vertex][val_state][donor_index]; + } + + /*! + * \brief Compute the global error measures (L2, Linf) for verification cases. + * \param[in] geometry - Geometrical definition. + * \param[in] config - Definition of the particular problem. + */ + void ComputeVerificationError(CGeometry *geometry, CConfig *config) final; + +}; diff --git a/SU2_CFD/include/solvers/CIncNSSolver.hpp b/SU2_CFD/include/solvers/CIncNSSolver.hpp new file mode 100644 index 000000000000..628b799d987c --- /dev/null +++ b/SU2_CFD/include/solvers/CIncNSSolver.hpp @@ -0,0 +1,528 @@ +/*! + * \file CIncNSSolver.hpp + * \brief Headers of the CIncNSSolver class + * \author F. Palacios, T. Economon, T. Albring + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#pragma once + +#include "CIncEulerSolver.hpp" + +/*! + * \class CIncNSSolver + * \brief Main class for defining the incompressible Navier-Stokes flow solver. + * \ingroup Navier_Stokes_Equations + * \author F. Palacios, T. Economon, T. Albring + */ +class CIncNSSolver final : public CIncEulerSolver { +private: + su2double Viscosity_Inf; /*!< \brief Viscosity at the infinity. */ + su2double Tke_Inf; /*!< \brief Turbulent kinetic energy at the infinity. */ + su2double + *CD_Visc, /*!< \brief Drag coefficient (viscous contribution) for each boundary. */ + *CL_Visc, /*!< \brief Lift coefficient (viscous contribution) for each boundary. */ + *CSF_Visc, /*!< \brief Side force coefficient (viscous contribution) for each boundary. */ + *CMx_Visc, /*!< \brief Moment x coefficient (viscous contribution) for each boundary. */ + *CMy_Visc, /*!< \brief Moment y coefficient (viscous contribution) for each boundary. */ + *CMz_Visc, /*!< \brief Moment z coefficient (viscous contribution) for each boundary. */ + *CoPx_Visc, /*!< \brief Moment x coefficient (viscous contribution) for each boundary. */ + *CoPy_Visc, /*!< \brief Moment y coefficient (viscous contribution) for each boundary. */ + *CoPz_Visc, /*!< \brief Moment z coefficient (viscous contribution) for each boundary. */ + *CFx_Visc, /*!< \brief Force x coefficient (viscous contribution) for each boundary. */ + *CFy_Visc, /*!< \brief Force y coefficient (viscous contribution) for each boundary. */ + *CFz_Visc, /*!< \brief Force z coefficient (viscous contribution) for each boundary. */ + *Surface_CL_Visc, /*!< \brief Lift coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CD_Visc, /*!< \brief Drag coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CSF_Visc, /*!< \brief Side-force coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CEff_Visc, /*!< \brief Side-force coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CFx_Visc, /*!< \brief Force x coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CFy_Visc, /*!< \brief Force y coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CFz_Visc, /*!< \brief Force z coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CMx_Visc, /*!< \brief Moment x coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CMy_Visc, /*!< \brief Moment y coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CMz_Visc, /*!< \brief Moment z coefficient (viscous contribution) for each monitoring surface. */ + *CEff_Visc, /*!< \brief Efficiency (Cl/Cd) (Viscous contribution) for each boundary. */ + *CMerit_Visc, /*!< \brief Rotor Figure of Merit (Viscous contribution) for each boundary. */ + *CT_Visc, /*!< \brief Thrust coefficient (viscous contribution) for each boundary. */ + *CQ_Visc, /*!< \brief Torque coefficient (viscous contribution) for each boundary. */ + *HF_Visc, /*!< \brief Heat load (viscous contribution) for each boundary. */ + *MaxHF_Visc, /*!< \brief Maximum heat flux (viscous contribution) for each boundary. */ + ***HeatConjugateVar, /*!< \brief Conjugate heat transfer variables for each boundary and vertex. */ + ***CSkinFriction; /*!< \brief Skin friction coefficient for each boundary and vertex. */ + su2double + *ForceViscous, /*!< \brief Viscous force for each boundary. */ + *MomentViscous; /*!< \brief Inviscid moment for each boundary. */ + su2double + AllBound_CD_Visc, /*!< \brief Drag coefficient (viscous contribution) for all the boundaries. */ + AllBound_CL_Visc, /*!< \brief Lift coefficient (viscous contribution) for all the boundaries. */ + AllBound_CSF_Visc, /*!< \brief Sideforce coefficient (viscous contribution) for all the boundaries. */ + AllBound_CMx_Visc, /*!< \brief Moment x coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMy_Visc, /*!< \brief Moment y coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMz_Visc, /*!< \brief Moment z coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CoPx_Visc, /*!< \brief Moment x coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CoPy_Visc, /*!< \brief Moment y coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CoPz_Visc, /*!< \brief Moment z coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CEff_Visc, /*!< \brief Efficient coefficient (Viscous contribution) for all the boundaries. */ + AllBound_CFx_Visc, /*!< \brief Force x coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CFy_Visc, /*!< \brief Force y coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CFz_Visc, /*!< \brief Force z coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMerit_Visc, /*!< \brief Rotor Figure of Merit coefficient (Viscous contribution) for all the boundaries. */ + AllBound_CT_Visc, /*!< \brief Thrust coefficient (viscous contribution) for all the boundaries. */ + AllBound_CQ_Visc, /*!< \brief Torque coefficient (viscous contribution) for all the boundaries. */ + AllBound_HF_Visc, /*!< \brief Heat load (viscous contribution) for all the boundaries. */ + AllBound_MaxHF_Visc; /*!< \brief Maximum heat flux (viscous contribution) for all boundaries. */ + su2double + StrainMag_Max, + Omega_Max; /*!< \brief Maximum Strain Rate magnitude and Omega. */ + +public: + + /*! + * \brief Constructor of the class. + */ + CIncNSSolver(void); + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + CIncNSSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); + + /*! + * \brief Destructor of the class. + */ + ~CIncNSSolver(void); + + /*! + * \brief Provide the non dimensional lift coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the lift coefficient on the surface val_marker. + */ + inline su2double GetSurface_CL_Visc(unsigned short val_marker) const override { return Surface_CL_Visc[val_marker]; } + + /*! + * \brief Provide the non dimensional drag coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the drag coefficient on the surface val_marker. + */ + inline su2double GetSurface_CD_Visc(unsigned short val_marker) const override { return Surface_CD_Visc[val_marker]; } + + /*! + * \brief Provide the non dimensional side-force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side-force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CSF_Visc(unsigned short val_marker) const override { return Surface_CSF_Visc[val_marker]; } + + /*! + * \brief Provide the non dimensional side-force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side-force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CEff_Visc(unsigned short val_marker) const override { return Surface_CEff_Visc[val_marker]; } + + /*! + * \brief Provide the non dimensional x force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFx_Visc(unsigned short val_marker) const override { return Surface_CFx_Visc[val_marker]; } + + /*! + * \brief Provide the non dimensional y force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFy_Visc(unsigned short val_marker) const override { return Surface_CFy_Visc[val_marker]; } + + /*! + * \brief Provide the non dimensional z force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFz_Visc(unsigned short val_marker) const override { return Surface_CFz_Visc[val_marker]; } + + /*! + * \brief Provide the non dimensional x moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMx_Visc(unsigned short val_marker) const override { return Surface_CMx_Visc[val_marker]; } + + /*! + * \brief Provide the non dimensional y moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMy_Visc(unsigned short val_marker) const override { return Surface_CMy_Visc[val_marker]; } + + /*! + * \brief Provide the non dimensional z moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMz_Visc(unsigned short val_marker) const override { return Surface_CMz_Visc[val_marker]; } + + /*! + * \brief Get the inviscid contribution to the lift coefficient. + * \return Value of the lift coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CL_Visc() const override { return AllBound_CL_Visc; } + + /*! + * \brief Get the inviscid contribution to the drag coefficient. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CD_Visc() const override { return AllBound_CD_Visc; } + + /*! + * \brief Get the inviscid contribution to the sideforce coefficient. + * \return Value of the sideforce coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CSF_Visc() const override { return AllBound_CSF_Visc; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CEff_Visc() const override { return AllBound_CEff_Visc; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CMx_Visc() const override { return AllBound_CMx_Visc; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CMy_Visc() const override { return AllBound_CMy_Visc; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CMz_Visc() const override { return AllBound_CMz_Visc; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CoPx_Visc() const override { return AllBound_CoPx_Visc; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CoPy_Visc() const override { return AllBound_CoPy_Visc; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CoPz_Visc() const override { return AllBound_CoPz_Visc; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CFx_Visc() const override { return AllBound_CFx_Visc; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CFy_Visc() const override { return AllBound_CFy_Visc; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CFz_Visc() const override { return AllBound_CFz_Visc; } + + /*! + * \brief Compute the viscosity at the infinity. + * \return Value of the viscosity at the infinity. + */ + inline su2double GetViscosity_Inf(void) const override { return Viscosity_Inf; } + + /*! + * \brief Get the turbulent kinetic energy at the infinity. + * \return Value of the turbulent kinetic energy at the infinity. + */ + inline su2double GetTke_Inf(void) const override { return Tke_Inf; } + + /*! + * \brief Compute the time step for solving the Navier-Stokes equations with turbulence model. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] Iteration - Index of the current iteration. + */ + void SetTime_Step(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned long Iteration) override; + + /*! + * \brief Restart residual and compute gradients. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + * \param[in] Output - boolean to determine whether to print output. + */ + void Preprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep, + unsigned short RunTime_EqSystem, + bool Output) override; + + /*! + * \brief Compute the velocity^2, SoundSpeed, Pressure, Enthalpy, Viscosity. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] Output - boolean to determine whether to print output. + * \return - The number of non-physical points. + */ + unsigned long SetPrimitive_Variables(CSolver **solver_container, + CConfig *config, + bool Output) override; + + /*! + * \brief Impose a no-slip condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_HeatFlux_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose an isothermal temperature condition at the wall. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Isothermal_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the (received) conjugate heat variables. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_ConjugateHeat_Interface(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Set the conjugate heat variables. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + * \param[in] pos_var - variable position (in vector of all conjugate heat variables) + * \param[in] relaxation factor - relaxation factor for the change of the variables + * \param[in] val_var - value of the variable + */ + inline void SetConjugateHeatVariable(unsigned short val_marker, + unsigned long val_vertex, + unsigned short pos_var, + su2double relaxation_factor, + su2double val_var) override { + HeatConjugateVar[val_marker][val_vertex][pos_var] = relaxation_factor*val_var + (1.0-relaxation_factor)*HeatConjugateVar[val_marker][val_vertex][pos_var]; + } + + /*! + * \brief Set the conjugate heat variables. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + * \param[in] pos_var - variable position (in vector of all conjugate heat variables) + */ + inline su2double GetConjugateHeatVariable(unsigned short val_marker, + unsigned long val_vertex, + unsigned short pos_var) const override { + return HeatConjugateVar[val_marker][val_vertex][pos_var]; + } + + /*! + * \brief Compute the viscous forces and all the addimensional coefficients. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Friction_Forces(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief Get the total heat flux. + * \param[in] val_marker - Surface marker where the heat flux is computed. + * \return Value of the integrated heat flux (viscous contribution) on the surface val_marker. + */ + inline su2double GetSurface_HF_Visc(unsigned short val_marker) const override { return Surface_HF_Visc[val_marker]; } + + /*! + * \brief Get the maximum (per surface) heat flux. + * \param[in] val_marker - Surface marker where the heat flux is computed. + * \return Value of the maximum heat flux (viscous contribution) on the surface val_marker. + */ + inline su2double GetSurface_MaxHF_Visc(unsigned short val_marker) const override { return Surface_MaxHF_Visc[val_marker]; } + + /*! + * \brief Get the non dimensional lift coefficient (viscous contribution). + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the lift coefficient (viscous contribution) on the surface val_marker. + */ + inline su2double GetCL_Visc(unsigned short val_marker) const override { return CL_Visc[val_marker]; } + + /*! + * \brief Get the non dimensional sideforce coefficient (viscous contribution). + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the sideforce coefficient (viscous contribution) on the surface val_marker. + */ + inline su2double GetCSF_Visc(unsigned short val_marker) const override { return CSF_Visc[val_marker]; } + + /*! + * \brief Get the non dimensional drag coefficient (viscous contribution). + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the drag coefficient (viscous contribution) on the surface val_marker. + */ + inline su2double GetCD_Visc(unsigned short val_marker) const override { return CD_Visc[val_marker]; } + + /*! + * \brief Compute the viscous residuals. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + void Viscous_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep) override; + + /*! + * \brief Get the skin friction coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the skin friction coefficient. + */ + inline su2double GetCSkinFriction(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_dim) const override { + return CSkinFriction[val_marker][val_dim][val_vertex]; + } + + /*! + * \brief Get the skin friction coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the heat transfer coefficient. + */ + inline su2double GetHeatFlux(unsigned short val_marker, unsigned long val_vertex) const override { + return HeatFlux[val_marker][val_vertex]; + } + + /*! + * \brief Get the skin friction coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the heat transfer coefficient. + */ + inline su2double GetHeatFluxTarget(unsigned short val_marker, unsigned long val_vertex) const override { + return HeatFluxTarget[val_marker][val_vertex]; + } + + /*! + * \brief Set the value of the target Pressure coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline void SetHeatFluxTarget(unsigned short val_marker, + unsigned long val_vertex, + su2double val_heat) override { HeatFluxTarget[val_marker][val_vertex] = val_heat; } + + /*! + * \brief Get the y plus. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the y plus. + */ + inline su2double GetYPlus(unsigned short val_marker, unsigned long val_vertex) const override { + return YPlus[val_marker][val_vertex]; + } + + /*! + * \brief Get the max Omega. + * \return Value of the max Omega. + */ + inline su2double GetOmega_Max(void) const override { return Omega_Max; } + + /*! + * \brief Get the max Strain rate magnitude. + * \return Value of the max Strain rate magnitude. + */ + inline su2double GetStrainMag_Max(void) const override { return StrainMag_Max; } + + /*! + * \brief A virtual member. + * \return Value of the StrainMag_Max + */ + inline void SetStrainMag_Max(su2double val_strainmag_max) override { StrainMag_Max = val_strainmag_max; } + + /*! + * \brief A virtual member. + * \return Value of the Omega_Max + */ + inline void SetOmega_Max(su2double val_omega_max) override { Omega_Max = val_omega_max; } + +}; \ No newline at end of file diff --git a/SU2_CFD/include/solvers/CMeshSolver.hpp b/SU2_CFD/include/solvers/CMeshSolver.hpp index 5b97f6504b93..8ea2aaceb84d 100644 --- a/SU2_CFD/include/solvers/CMeshSolver.hpp +++ b/SU2_CFD/include/solvers/CMeshSolver.hpp @@ -71,7 +71,7 @@ class CMeshSolver final : public CFEASolver { * \param[in] config - Definition of the particular problem. */ void SetWallDistance(CGeometry *geometry, CConfig *config); - + /*! * \brief Update the value of the coordinates after the grid movement. * \param[in] geometry - Geometrical definition of the problem. @@ -118,21 +118,27 @@ class CMeshSolver final : public CFEASolver { * \param[in] geometry - Geometrical definition of the problem. * \param[in] config - Definition of the particular problem. */ - void DeformMesh(CGeometry **geometry, CNumerics **numerics, CConfig *config) override; + void DeformMesh(CGeometry **geometry, + CNumerics **numerics, + CConfig *config) override; /*! * \brief Set the stiffness of the mesh. * \param[in] geometry - Geometrical definition of the problem. * \param[in] config - Definition of the particular problem. */ - void SetMesh_Stiffness(CGeometry **geometry, CNumerics **numerics, CConfig *config) override; + void SetMesh_Stiffness(CGeometry **geometry, + CNumerics **numerics, + CConfig *config) override; /*! * \brief Get the value of the reference coordinate to set on the element structure. * \param[in] indexNode - Index of the node. * \param[in] iDim - Dimension required. */ - inline su2double Get_ValCoord(CGeometry*, unsigned long indexNode, unsigned short iDim) const override { + inline su2double Get_ValCoord(CGeometry*, + unsigned long indexNode, + unsigned short iDim) const override { return nodes->GetMesh_Coord(indexNode,iDim); } @@ -149,7 +155,11 @@ class CMeshSolver final : public CFEASolver { * \param[in] val_iter - Current external iteration number. * \param[in] val_update_geo - Flag for updating coords and grid velocity. */ - void LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo) override; + void LoadRestart(CGeometry **geometry, + CSolver ***solver, + CConfig *config, + int val_iter, + bool val_update_geo) override; /*! * \brief Load the geometries at the previous time states n and nM1. diff --git a/SU2_CFD/include/solvers/CNSSolver.hpp b/SU2_CFD/include/solvers/CNSSolver.hpp new file mode 100644 index 000000000000..86343ccbf0e9 --- /dev/null +++ b/SU2_CFD/include/solvers/CNSSolver.hpp @@ -0,0 +1,586 @@ +/*! + * \file CNSSolver.hpp + * \brief Headers of the CNSSolver class + * \author F. Palacios, T. Economon + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#pragma once + +#include "CEulerSolver.hpp" + +/*! + * \class CNSSolver + * \brief Main class for defining the Navier-Stokes flow solver. + * \ingroup Navier_Stokes_Equations + * \author F. Palacios + */ +class CNSSolver final : public CEulerSolver { +private: + su2double Viscosity_Inf; /*!< \brief Viscosity at the infinity. */ + su2double Tke_Inf; /*!< \brief Turbulent kinetic energy at the infinity. */ + su2double Prandtl_Lam, /*!< \brief Laminar Prandtl number. */ + Prandtl_Turb; /*!< \brief Turbulent Prandtl number. */ + su2double *CD_Visc, /*!< \brief Drag coefficient (viscous contribution) for each boundary. */ + *CL_Visc, /*!< \brief Lift coefficient (viscous contribution) for each boundary. */ + *CSF_Visc, /*!< \brief Side force coefficient (viscous contribution) for each boundary. */ + *CMx_Visc, /*!< \brief Moment x coefficient (viscous contribution) for each boundary. */ + *CMy_Visc, /*!< \brief Moment y coefficient (viscous contribution) for each boundary. */ + *CMz_Visc, /*!< \brief Moment z coefficient (viscous contribution) for each boundary. */ + *CoPx_Visc, /*!< \brief Moment x coefficient (viscous contribution) for each boundary. */ + *CoPy_Visc, /*!< \brief Moment y coefficient (viscous contribution) for each boundary. */ + *CoPz_Visc, /*!< \brief Moment z coefficient (viscous contribution) for each boundary. */ + *CFx_Visc, /*!< \brief Force x coefficient (viscous contribution) for each boundary. */ + *CFy_Visc, /*!< \brief Force y coefficient (viscous contribution) for each boundary. */ + *CFz_Visc, /*!< \brief Force z coefficient (viscous contribution) for each boundary. */ + *Surface_CL_Visc, /*!< \brief Lift coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CD_Visc, /*!< \brief Drag coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CSF_Visc, /*!< \brief Side-force coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CEff_Visc, /*!< \brief Side-force coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CFx_Visc, /*!< \brief Force x coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CFy_Visc, /*!< \brief Force y coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CFz_Visc, /*!< \brief Force z coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CMx_Visc, /*!< \brief Moment x coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CMy_Visc, /*!< \brief Moment y coefficient (viscous contribution) for each monitoring surface. */ + *Surface_CMz_Visc, /*!< \brief Moment z coefficient (viscous contribution) for each monitoring surface. */ + *Surface_Buffet_Metric, /*!< \brief Integrated separation sensor for each monitoring surface. */ + *CEff_Visc, /*!< \brief Efficiency (Cl/Cd) (Viscous contribution) for each boundary. */ + *CMerit_Visc, /*!< \brief Rotor Figure of Merit (Viscous contribution) for each boundary. */ + *Buffet_Metric, /*!< \brief Integrated separation sensor for each boundary. */ + *CT_Visc, /*!< \brief Thrust coefficient (viscous contribution) for each boundary. */ + *CQ_Visc, /*!< \brief Torque coefficient (viscous contribution) for each boundary. */ + *HF_Visc, /*!< \brief Heat load (viscous contribution) for each boundary. */ + *MaxHF_Visc, /*!< \brief Maximum heat flux (viscous contribution) for each boundary. */ + ***HeatConjugateVar, /*!< \brief Conjugate heat transfer variables for each boundary and vertex. */ + ***CSkinFriction, /*!< \brief Skin friction coefficient for each boundary and vertex. */ + **Buffet_Sensor; /*!< \brief Separation sensor for each boundary and vertex. */ + su2double Total_Buffet_Metric; /*!< \brief Integrated separation sensor for all the boundaries. */ + su2double *ForceViscous, /*!< \brief Viscous force for each boundary. */ + *MomentViscous; /*!< \brief Inviscid moment for each boundary. */ + su2double + AllBound_CD_Visc, /*!< \brief Drag coefficient (viscous contribution) for all the boundaries. */ + AllBound_CL_Visc, /*!< \brief Lift coefficient (viscous contribution) for all the boundaries. */ + AllBound_CSF_Visc, /*!< \brief Sideforce coefficient (viscous contribution) for all the boundaries. */ + AllBound_CMx_Visc, /*!< \brief Moment x coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMy_Visc, /*!< \brief Moment y coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMz_Visc, /*!< \brief Moment z coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CoPx_Visc, /*!< \brief Moment x coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CoPy_Visc, /*!< \brief Moment y coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CoPz_Visc, /*!< \brief Moment z coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CEff_Visc, /*!< \brief Efficient coefficient (Viscous contribution) for all the boundaries. */ + AllBound_CFx_Visc, /*!< \brief Force x coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CFy_Visc, /*!< \brief Force y coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CFz_Visc, /*!< \brief Force z coefficient (inviscid contribution) for all the boundaries. */ + AllBound_CMerit_Visc, /*!< \brief Rotor Figure of Merit coefficient (Viscous contribution) for all the boundaries. */ + AllBound_CT_Visc, /*!< \brief Thrust coefficient (viscous contribution) for all the boundaries. */ + AllBound_CQ_Visc, /*!< \brief Torque coefficient (viscous contribution) for all the boundaries. */ + AllBound_HF_Visc, /*!< \brief Heat load (viscous contribution) for all the boundaries. */ + AllBound_MaxHF_Visc; /*!< \brief Maximum heat flux (viscous contribution) for all boundaries. */ + su2double + StrainMag_Max, + Omega_Max; /*!< \brief Maximum Strain Rate magnitude and Omega. */ + +public: + + /*! + * \brief Constructor of the class. + */ + CNSSolver(void); + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + CNSSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); + + /*! + * \brief Destructor of the class. + */ + ~CNSSolver(void); + + /*! + * \brief Provide the non dimensional lift coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the lift coefficient on the surface val_marker. + */ + inline su2double GetSurface_CL_Visc(unsigned short val_marker) const override { return Surface_CL_Visc[val_marker]; } + + /*! + * \brief Provide the non dimensional drag coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the drag coefficient on the surface val_marker. + */ + inline su2double GetSurface_CD_Visc(unsigned short val_marker) const override { return Surface_CD_Visc[val_marker]; } + + /*! + * \brief Provide the non dimensional side-force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side-force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CSF_Visc(unsigned short val_marker) const override { return Surface_CSF_Visc[val_marker]; } + + /*! + * \brief Provide the non dimensional side-force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side-force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CEff_Visc(unsigned short val_marker) const override { return Surface_CEff_Visc[val_marker]; } + + /*! + * \brief Provide the non dimensional x force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFx_Visc(unsigned short val_marker) const override { return Surface_CFx_Visc[val_marker]; } + + /*! + * \brief Provide the non dimensional y force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFy_Visc(unsigned short val_marker) const override { return Surface_CFy_Visc[val_marker]; } + + /*! + * \brief Provide the non dimensional z force coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z force coefficient on the surface val_marker. + */ + inline su2double GetSurface_CFz_Visc(unsigned short val_marker) const override { return Surface_CFz_Visc[val_marker]; } + + /*! + * \brief Provide the non dimensional x moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMx_Visc(unsigned short val_marker) const override { return Surface_CMx_Visc[val_marker]; } + + /*! + * \brief Provide the non dimensional y moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMy_Visc(unsigned short val_marker) const override { return Surface_CMy_Visc[val_marker]; } + + /*! + * \brief Provide the non dimensional z moment coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z moment coefficient on the surface val_marker. + */ + inline su2double GetSurface_CMz_Visc(unsigned short val_marker) const override { return Surface_CMz_Visc[val_marker]; } + + /*! + * \brief Provide the buffet metric. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the buffet metric on the surface val_marker. + */ + inline su2double GetSurface_Buffet_Metric(unsigned short val_marker) const override { return Surface_Buffet_Metric[val_marker]; } + + /*! + * \brief Get the inviscid contribution to the lift coefficient. + * \return Value of the lift coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CL_Visc() const override { return AllBound_CL_Visc; } + + /*! + * \brief Get the inviscid contribution to the drag coefficient. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CD_Visc() const override { return AllBound_CD_Visc; } + + /*! + * \brief Get the inviscid contribution to the sideforce coefficient. + * \return Value of the sideforce coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CSF_Visc() const override { return AllBound_CSF_Visc; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CEff_Visc() const override { return AllBound_CEff_Visc; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CMx_Visc() const override { return AllBound_CMx_Visc; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CMy_Visc() const override { return AllBound_CMy_Visc; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CMz_Visc() const override { return AllBound_CMz_Visc; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CoPx_Visc() const override { return AllBound_CoPx_Visc; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CoPy_Visc() const override { return AllBound_CoPy_Visc; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CoPz_Visc() const override { return AllBound_CoPz_Visc; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CFx_Visc() const override { return AllBound_CFx_Visc; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CFy_Visc() const override { return AllBound_CFy_Visc; } + + /*! + * \brief Get the inviscid contribution to the efficiency coefficient. + * \return Value of the efficiency coefficient (inviscid contribution). + */ + inline su2double GetAllBound_CFz_Visc() const override { return AllBound_CFz_Visc; } + + /*! + * \brief Get the buffet metric. + * \return Value of the buffet metric. + */ + inline su2double GetTotal_Buffet_Metric() const override { return Total_Buffet_Metric; } + + /*! + * \brief Compute the viscosity at the infinity. + * \return Value of the viscosity at the infinity. + */ + inline su2double GetViscosity_Inf(void) const override { return Viscosity_Inf; } + + /*! + * \brief Get the turbulent kinetic energy at the infinity. + * \return Value of the turbulent kinetic energy at the infinity. + */ + inline su2double GetTke_Inf(void) const override { return Tke_Inf; } + + /*! + * \brief Compute the time step for solving the Navier-Stokes equations with turbulence model. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] Iteration - Index of the current iteration. + */ + void SetTime_Step(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned long Iteration) override; + + /*! + * \brief Restart residual and compute gradients. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + * \param[in] Output - boolean to determine whether to print output. + */ + void Preprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep, + unsigned short RunTime_EqSystem, + bool Output) override; + + /*! + * \brief Compute the velocity^2, SoundSpeed, Pressure, Enthalpy, Viscosity. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] Output - boolean to determine whether to print output. + * \return - The number of non-physical points. + */ + unsigned long SetPrimitive_Variables(CSolver **solver_container, + CConfig *config, + bool Output) override; + + /*! + * \brief Compute weighted-sum "combo" objective output + * \param[in] config - Definition of the particular problem. + */ + void Evaluate_ObjFunc(CConfig *config) override; + + /*! + * \brief Impose a constant heat-flux condition at the wall. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_HeatFlux_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the Navier-Stokes boundary condition (strong). + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Isothermal_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the Navier-Stokes boundary condition (strong) with values from a CHT coupling. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_ConjugateHeat_Interface(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Set the conjugate heat variables. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + * \param[in] pos_var - variable position (in vector of all conjugate heat variables) + */ + inline su2double GetConjugateHeatVariable(unsigned short val_marker, + unsigned long val_vertex, + unsigned short pos_var) const override { + return HeatConjugateVar[val_marker][val_vertex][pos_var]; + } + + /*! + * \brief Set the conjugate heat variables. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + * \param[in] pos_var - variable position (in vector of all conjugate heat variables) + * \param[in] relaxation factor - relaxation factor for the change of the variables + * \param[in] val_var - value of the variable + */ + inline void SetConjugateHeatVariable(unsigned short val_marker, + unsigned long val_vertex, + unsigned short pos_var, + su2double relaxation_factor, + su2double val_var) override { + HeatConjugateVar[val_marker][val_vertex][pos_var] = relaxation_factor*val_var + (1.0-relaxation_factor)*HeatConjugateVar[val_marker][val_vertex][pos_var]; + } + + /*! + * \brief Compute the viscous forces and all the addimensional coefficients. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Friction_Forces(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief Compute the buffet sensor. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Buffet_Monitoring(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief Get the total heat flux. + * \param[in] val_marker - Surface marker where the heat flux is computed. + * \return Value of the integrated heat flux (viscous contribution) on the surface val_marker. + */ + inline su2double GetSurface_HF_Visc(unsigned short val_marker) const override { return Surface_HF_Visc[val_marker]; } + + /*! + * \brief Get the maximum (per surface) heat flux. + * \param[in] val_marker - Surface marker where the heat flux is computed. + * \return Value of the maximum heat flux (viscous contribution) on the surface val_marker. + */ + inline su2double GetSurface_MaxHF_Visc(unsigned short val_marker) const override { return Surface_MaxHF_Visc[val_marker]; } + + /*! + * \brief Get the non dimensional lift coefficient (viscous contribution). + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the lift coefficient (viscous contribution) on the surface val_marker. + */ + inline su2double GetCL_Visc(unsigned short val_marker) const override { return CL_Visc[val_marker]; } + + /*! + * \brief Get the non dimensional sideforce coefficient (viscous contribution). + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the sideforce coefficient (viscous contribution) on the surface val_marker. + */ + inline su2double GetCSF_Visc(unsigned short val_marker) const override { return CSF_Visc[val_marker]; } + + /*! + * \brief Get the non dimensional drag coefficient (viscous contribution). + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the drag coefficient (viscous contribution) on the surface val_marker. + */ + inline su2double GetCD_Visc(unsigned short val_marker) const override { return CD_Visc[val_marker]; } + + /*! + * \brief Compute the viscous residuals. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + void Viscous_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep) override; + + /*! + * \brief Get the skin friction coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the skin friction coefficient. + */ + inline su2double GetCSkinFriction(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_dim) const override { + return CSkinFriction[val_marker][val_dim][val_vertex]; + } + + /*! + * \brief Get the skin friction coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the heat transfer coefficient. + */ + inline su2double GetHeatFlux(unsigned short val_marker, unsigned long val_vertex) const override { + return HeatFlux[val_marker][val_vertex]; + } + + /*! + * \brief Get the skin friction coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the heat transfer coefficient. + */ + inline su2double GetHeatFluxTarget(unsigned short val_marker, unsigned long val_vertex) const override { + return HeatFluxTarget[val_marker][val_vertex]; + } + + /*! + * \brief Set the value of the target Pressure coefficient. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline void SetHeatFluxTarget(unsigned short val_marker, + unsigned long val_vertex, + su2double val_heat) override { HeatFluxTarget[val_marker][val_vertex] = val_heat; } + + /*! + * \brief Get the value of the buffet sensor + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the buffet sensor. + */ + inline su2double GetBuffetSensor(unsigned short val_marker, unsigned long val_vertex) const override { + return Buffet_Sensor[val_marker][val_vertex]; + } + + /*! + * \brief Get the y plus. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the y plus. + */ + inline su2double GetYPlus(unsigned short val_marker, unsigned long val_vertex) const override { + return YPlus[val_marker][val_vertex]; + } + + /*! + * \brief Get the max Omega. + * \return Value of the max Omega. + */ + inline su2double GetOmega_Max(void) const override { return Omega_Max; } + + /*! + * \brief Get the max Strain rate magnitude. + * \return Value of the max Strain rate magnitude. + */ + inline su2double GetStrainMag_Max(void) const override { return StrainMag_Max; } + + /*! + * \brief A virtual member. + * \return Value of the StrainMag_Max + */ + inline void SetStrainMag_Max(su2double val_strainmag_max) override { StrainMag_Max = val_strainmag_max; } + + /*! + * \brief A virtual member. + * \return Value of the Omega_Max + */ + inline void SetOmega_Max(su2double val_omega_max) override { Omega_Max = val_omega_max; } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition. + * \param[in] config - Definition of the particular problem. + */ + void SetRoe_Dissipation(CGeometry *geometry, CConfig *config) override; + + /*! + * \brief Computes the wall shear stress (Tau_Wall) on the surface using a wall function. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void SetTauWall_WF(CGeometry *geometry, + CSolver** solver_container, + CConfig* config) override; + +}; \ No newline at end of file diff --git a/SU2_CFD/include/solvers/CSolver.hpp b/SU2_CFD/include/solvers/CSolver.hpp new file mode 100644 index 000000000000..de95bad8de77 --- /dev/null +++ b/SU2_CFD/include/solvers/CSolver.hpp @@ -0,0 +1,4837 @@ +/*! + * \file CSolver.hpp + * \brief Headers of the CSolver class which is inherited by all of the other + * solvers + * \author F. Palacios, T. Economon + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#pragma once + +#include "../../../Common/include/mpi_structure.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../fluid_model.hpp" +#include "../task_definition.hpp" +#include "../numerics_structure.hpp" +#include "../sgs_model.hpp" +#include "../../../Common/include/fem_geometry_structure.hpp" +#include "../../../Common/include/geometry/CGeometry.hpp" +#include "../../../Common/include/config_structure.hpp" +#include "../../../Common/include/linear_algebra/CSysMatrix.hpp" +#include "../../../Common/include/linear_algebra/CSysVector.hpp" +#include "../../../Common/include/linear_algebra/CSysSolve.hpp" +#include "../../../Common/include/grid_movement_structure.hpp" +#include "../../../Common/include/blas_structure.hpp" +#include "../../../Common/include/graph_coloring_structure.hpp" +#include "../../../Common/include/toolboxes/MMS/CVerificationSolution.hpp" +#include "../variables/CVariable.hpp" + +using namespace std; + +class CSolver { +protected: + int rank, /*!< \brief MPI Rank. */ + size; /*!< \brief MPI Size. */ + bool adjoint; /*!< \brief Boolean to determine whether solver is initialized as a direct or an adjoint solver. */ + unsigned short MGLevel; /*!< \brief Multigrid level of this solver object. */ + unsigned short IterLinSolver; /*!< \brief Linear solver iterations. */ + su2double ResLinSolver; /*!< \brief Final linear solver residual. */ + su2double NonLinRes_Value, /*!< \brief Summed value of the nonlinear residual indicator. */ + NonLinRes_Func; /*!< \brief Current value of the nonlinear residual indicator at one iteration. */ + unsigned short NonLinRes_Counter; /*!< \brief Number of elements of the nonlinear residual indicator series. */ + vector NonLinRes_Series; /*!< \brief Vector holding the nonlinear residual indicator series. */ + su2double Old_Func, /*!< \brief Old value of the nonlinear residual indicator. */ + New_Func; /*!< \brief Current value of the nonlinear residual indicator. */ + unsigned short nVar, /*!< \brief Number of variables of the problem. */ + nPrimVar, /*!< \brief Number of primitive variables of the problem. */ + nPrimVarGrad, /*!< \brief Number of primitive variables of the problem in the gradient computation. */ + nSecondaryVar, /*!< \brief Number of primitive variables of the problem. */ + nSecondaryVarGrad, /*!< \brief Number of primitive variables of the problem in the gradient computation. */ + nVarGrad, /*!< \brief Number of variables for deallocating the LS Cvector. */ + nDim; /*!< \brief Number of dimensions of the problem. */ + unsigned long nPoint; /*!< \brief Number of points of the computational grid. */ + unsigned long nPointDomain; /*!< \brief Number of points of the computational grid. */ + su2double Max_Delta_Time, /*!< \brief Maximum value of the delta time for all the control volumes. */ + Min_Delta_Time; /*!< \brief Minimum value of the delta time for all the control volumes. */ + su2double Max_CFL_Local; /*!< \brief Maximum value of the CFL across all the control volumes. */ + su2double Min_CFL_Local; /*!< \brief Minimum value of the CFL across all the control volumes. */ + su2double Avg_CFL_Local; /*!< \brief Average value of the CFL across all the control volumes. */ + su2double *Residual_RMS, /*!< \brief Vector with the mean residual for each variable. */ + *Residual_Max, /*!< \brief Vector with the maximal residual for each variable. */ + *Residual, /*!< \brief Auxiliary nVar vector. */ + *Residual_i, /*!< \brief Auxiliary nVar vector for storing the residual at point i. */ + *Residual_j; /*!< \brief Auxiliary nVar vector for storing the residual at point j. */ + su2double *Residual_BGS, /*!< \brief Vector with the mean residual for each variable for BGS subiterations. */ + *Residual_Max_BGS; /*!< \brief Vector with the maximal residual for each variable for BGS subiterations. */ + unsigned long *Point_Max; /*!< \brief Vector with the maximal residual for each variable. */ + unsigned long *Point_Max_BGS; /*!< \brief Vector with the maximal residual for each variable. */ + su2double **Point_Max_Coord; /*!< \brief Vector with pointers to the coords of the maximal residual for each variable. */ + su2double **Point_Max_Coord_BGS; /*!< \brief Vector with pointers to the coords of the maximal residual for each variable. */ + su2double *Solution, /*!< \brief Auxiliary nVar vector. */ + *Solution_i, /*!< \brief Auxiliary nVar vector for storing the solution at point i. */ + *Solution_j; /*!< \brief Auxiliary nVar vector for storing the solution at point j. */ + su2double *Vector, /*!< \brief Auxiliary nDim vector. */ + *Vector_i, /*!< \brief Auxiliary nDim vector to do the reconstruction of the variables at point i. */ + *Vector_j; /*!< \brief Auxiliary nDim vector to do the reconstruction of the variables at point j. */ + su2double *Res_Conv, /*!< \brief Auxiliary nVar vector for storing the convective residual. */ + *Res_Visc, /*!< \brief Auxiliary nVar vector for storing the viscous residual. */ + *Res_Sour, /*!< \brief Auxiliary nVar vector for storing the viscous residual. */ + *Res_Conv_i, /*!< \brief Auxiliary vector for storing the convective residual at point i. */ + *Res_Visc_i, /*!< \brief Auxiliary vector for storing the viscous residual at point i. */ + *Res_Conv_j, /*!< \brief Auxiliary vector for storing the convective residual at point j. */ + *Res_Visc_j; /*!< \brief Auxiliary vector for storing the viscous residual at point j. */ + su2double **Jacobian_i, /*!< \brief Auxiliary matrices for storing point to point Jacobians at point i. */ + **Jacobian_j; /*!< \brief Auxiliary matrices for storing point to point Jacobians at point j. */ + su2double **Jacobian_ii, /*!< \brief Auxiliary matrices for storing point to point Jacobians. */ + **Jacobian_ij, /*!< \brief Auxiliary matrices for storing point to point Jacobians. */ + **Jacobian_ji, /*!< \brief Auxiliary matrices for storing point to point Jacobians. */ + **Jacobian_jj; /*!< \brief Auxiliary matrices for storing point to point Jacobians. */ + su2double *iPoint_UndLapl, /*!< \brief Auxiliary variable for the undivided Laplacians. */ + *jPoint_UndLapl; /*!< \brief Auxiliary variable for the undivided Laplacians. */ + su2double **Smatrix, /*!< \brief Auxiliary structure for computing gradients by least-squares */ + **Cvector; /*!< \brief Auxiliary structure for computing gradients by least-squares */ + + int *Restart_Vars; /*!< \brief Auxiliary structure for holding the number of variables and points in a restart. */ + int Restart_ExtIter; /*!< \brief Auxiliary structure for holding the external iteration offset from a restart. */ + passivedouble *Restart_Data; /*!< \brief Auxiliary structure for holding the data values from a restart. */ + unsigned short nOutputVariables; /*!< \brief Number of variables to write. */ + + unsigned long nMarker, /*!< \brief Total number of markers using the grid information. */ + *nVertex; /*!< \brief Store nVertex at each marker for deallocation */ + + bool rotate_periodic; /*!< \brief Flag that controls whether the periodic solution needs to be rotated for the solver. */ + bool implicit_periodic; /*!< \brief Flag that controls whether the implicit system should be treated by the periodic BC comms. */ + + bool dynamic_grid; /*!< \brief Flag that determines whether the grid is dynamic (moving or deforming + grid velocities). */ + + su2double ***VertexTraction; /*- Temporary, this will be moved to a new postprocessing structure once in place -*/ + su2double ***VertexTractionAdjoint; /*- Also temporary -*/ + + string SolverName; /*!< \brief Store the name of the solver for output purposes. */ + + /*! + * \brief Pure virtual function, all derived solvers MUST implement a method returning their "nodes". + * \note Don't forget to call SetBaseClassPointerToNodes() in the constructor of the derived CSolver. + * \return Nodes of the solver, upcast to their base class (CVariable). + */ + virtual CVariable* GetBaseClassPointerToNodes() = 0; + + /*! + * \brief Call this method to set "base_nodes" after the "nodes" variable of the derived solver is instantiated. + * \note One could set base_nodes directly if it were not private but that could lead to confusion + */ + inline void SetBaseClassPointerToNodes() { base_nodes = GetBaseClassPointerToNodes(); } + +private: + + /*--- Private to prevent use by derived solvers, each solver MUST have its own "nodes" member of the + most derived type possible, e.g. CEulerVariable has nodes of CEulerVariable* and not CVariable*. + This variable is to avoid two virtual functions calls per call i.e. CSolver::GetNodes() returns + directly instead of calling GetBaseClassPointerToNodes() or doing something equivalent. ---*/ + CVariable* base_nodes; /*!< \brief Pointer to CVariable to allow polymorphic access to solver nodes. */ + +public: + + CSysVector LinSysSol; /*!< \brief vector to store iterative solution of implicit linear system. */ + CSysVector LinSysRes; /*!< \brief vector to store iterative residual of implicit linear system. */ + CSysVector LinSysAux; /*!< \brief vector to store iterative residual of implicit linear system. */ +#ifndef CODI_FORWARD_TYPE + CSysMatrix Jacobian; /*!< \brief Complete sparse Jacobian structure for implicit computations. */ + CSysSolve System; /*!< \brief Linear solver/smoother. */ +#else + CSysMatrix Jacobian; + CSysSolve System; +#endif + + CSysMatrix StiffMatrix; /*!< \brief Sparse structure for storing the stiffness matrix in Galerkin computations, and grid movement. */ + + CSysVector OutputVariables; /*!< \brief vector to store the extra variables to be written. */ + string* OutputHeadingNames; /*!< \brief vector of strings to store the headings for the exra variables */ + + CVerificationSolution *VerificationSolution; /*!< \brief Verification solution class used within the solver. */ + + vector fields; + /*! + * \brief Constructor of the class. + */ + CSolver(bool mesh_deform_mode = false); + + /*! + * \brief Destructor of the class. + */ + virtual ~CSolver(void); + + /*! + * \brief Allow outside access to the nodes of the solver, containing conservatives, primitives, etc. + * \return Nodes of the solver. + */ + inline CVariable* GetNodes() { + assert(base_nodes!=nullptr && "CSolver::base_nodes was not set properly, see brief for CSolver::SetBaseClassPointerToNodes()"); + return base_nodes; + } + + /*! + * \brief Routine to load a solver quantity into the data structures for MPI point-to-point communication and to launch non-blocking sends and recvs. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] commType - Enumerated type for the quantity to be communicated. + */ + void InitiateComms(CGeometry *geometry, + CConfig *config, + unsigned short commType); + + /*! + * \brief Routine to complete the set of non-blocking communications launched by InitiateComms() and unpacking of the data in the solver class. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] commType - Enumerated type for the quantity to be unpacked. + */ + void CompleteComms(CGeometry *geometry, + CConfig *config, + unsigned short commType); + + /*! + * \brief Routine to load a solver quantity into the data structures for MPI periodic communication and to launch non-blocking sends and recvs. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] val_periodic_index - Index for the periodic marker to be treated (first in a pair). + * \param[in] commType - Enumerated type for the quantity to be communicated. + */ + void InitiatePeriodicComms(CGeometry *geometry, + CConfig *config, + unsigned short val_periodic_index, + unsigned short commType); + + /*! + * \brief Routine to complete the set of non-blocking periodic communications launched by InitiatePeriodicComms() and unpacking of the data in the solver class. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] val_periodic_index - Index for the periodic marker to be treated (first in a pair). + * \param[in] commType - Enumerated type for the quantity to be unpacked. + */ + void CompletePeriodicComms(CGeometry *geometry, + CConfig *config, + unsigned short val_periodic_index, + unsigned short commType); + + /*! + * \brief Set number of linear solver iterations. + * \param[in] val_iterlinsolver - Number of linear iterations. + */ + inline void SetIterLinSolver(unsigned short val_iterlinsolver) { IterLinSolver = val_iterlinsolver; } + + /*! + * \brief Set the final linear solver residual. + * \param[in] val_reslinsolver - Value of final linear solver residual. + */ + inline void SetResLinSolver(su2double val_reslinsolver) { ResLinSolver = val_reslinsolver; } + + /*! + * \brief Set the value of the max residual and RMS residual. + * \param[in] val_iterlinsolver - Number of linear iterations. + */ + void SetResidual_RMS(CGeometry *geometry, CConfig *config); + + /*! + * \brief Communicate the value of the max residual and RMS residual. + * \param[in] val_iterlinsolver - Number of linear iterations. + */ + void SetResidual_BGS(CGeometry *geometry, CConfig *config); + + /*! + * \brief Set the value of the max residual and RMS residual. + * \param[in] val_iterlinsolver - Number of linear iterations. + */ + virtual void ComputeResidual_Multizone(CGeometry *geometry, CConfig *config); + + /*! + * \brief Move the mesh in time + */ + inline virtual void SetDualTime_Mesh(void){ } + + /*! + * \brief Store the BGS solution in the previous subiteration in the corresponding vector. + */ + void UpdateSolution_BGS(CGeometry *geometry, CConfig *config); + + /*! + * \brief Set the solver nondimensionalization. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + inline virtual void SetNondimensionalization(CConfig *config, unsigned short iMesh) { } + + /*! + * \brief Get information whether the initialization is an adjoint solver or not. + * \return TRUE means that it is an adjoint solver. + */ + inline bool GetAdjoint(void) const { return adjoint; } + + /*! + * \brief Compute the pressure at the infinity. + * \return Value of the pressure at the infinity. + */ + inline virtual CFluidModel* GetFluidModel(void) const { return NULL;} + + /*! + * \brief Get number of linear solver iterations. + * \return Number of linear solver iterations. + */ + inline unsigned short GetIterLinSolver(void) const { return IterLinSolver; } + + /*! + * \brief Get the final linear solver residual. + * \return Value of final linear solver residual. + */ + inline su2double GetResLinSolver(void) const { return ResLinSolver; } + + /*! + * \brief Get the value of the maximum delta time. + * \return Value of the maximum delta time. + */ + inline su2double GetMax_Delta_Time(void) const { return Max_Delta_Time; } + + /*! + * \brief Get the value of the minimum delta time. + * \return Value of the minimum delta time. + */ + inline su2double GetMin_Delta_Time(void) const { return Min_Delta_Time; } + + /*! + * \brief Get the value of the maximum local CFL number. + * \return Value of the maximum local CFL number. + */ + inline su2double GetMax_CFL_Local(void) const { return Max_CFL_Local; } + + /*! + * \brief Get the value of the minimum local CFL number. + * \return Value of the minimum local CFL number. + */ + inline su2double GetMin_CFL_Local(void) const { return Min_CFL_Local; } + + /*! + * \brief Get the value of the average local CFL number. + * \return Value of the average local CFL number. + */ + inline su2double GetAvg_CFL_Local(void) const { return Avg_CFL_Local; } + + /*! + * \brief Get the number of variables of the problem. + */ + inline unsigned short GetnVar(void) const { return nVar; } + + /*! + * \brief Get the number of variables of the problem. + */ + inline unsigned short GetnPrimVar(void) const { return nPrimVar; } + + /*! + * \brief Get the number of variables of the problem. + */ + inline unsigned short GetnPrimVarGrad(void) const { return nPrimVarGrad; } + + /*! + * \brief Get the number of variables of the problem. + */ + inline unsigned short GetnSecondaryVar(void) const { return nSecondaryVar; } + + /*! + * \brief Get the number of variables of the problem. + */ + inline unsigned short GetnSecondaryVarGrad(void) const { return nSecondaryVarGrad; } + + /*! + * \brief Get the number of variables of the problem. + */ + inline unsigned short GetnOutputVariables(void) const { return nOutputVariables; } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + */ + inline virtual void SetResidual_DualTime(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iRKStep, + unsigned short iMesh, + unsigned short RunTime_EqSystem) { } + + /*! + * \brief Set the maximal residual, this is useful for the convergence history. + * \param[in] val_var - Index of the variable. + * \param[in] val_residual - Value of the residual to store in the position val_var. + */ + inline void SetRes_RMS(unsigned short val_var, su2double val_residual) { Residual_RMS[val_var] = val_residual; } + + /*! + * \brief Adds the maximal residual, this is useful for the convergence history. + * \param[in] val_var - Index of the variable. + * \param[in] val_residual - Value of the residual to store in the position val_var. + */ + inline void AddRes_RMS(unsigned short val_var, su2double val_residual) { Residual_RMS[val_var] += val_residual; } + + /*! + * \brief Get the maximal residual, this is useful for the convergence history. + * \param[in] val_var - Index of the variable. + * \return Value of the biggest residual for the variable in the position val_var. + */ + inline su2double GetRes_RMS(unsigned short val_var) const { return Residual_RMS[val_var]; } + + /*! + * \brief Set the maximal residual, this is useful for the convergence history. + * \param[in] val_var - Index of the variable. + * \param[in] val_residual - Value of the residual to store in the position val_var. + */ + inline void SetRes_Max(unsigned short val_var, + su2double val_residual, + unsigned long val_point) { + Residual_Max[val_var] = val_residual; Point_Max[val_var] = val_point; + } + + /*! + * \brief Adds the maximal residual, this is useful for the convergence history (overload). + * \param[in] val_var - Index of the variable. + * \param[in] val_residual - Value of the residual to store in the position val_var. + * \param[in] val_point - Value of the point index for the max residual. + * \param[in] val_coord - Location (x, y, z) of the max residual point. + */ + inline void AddRes_Max(unsigned short val_var, + su2double val_residual, + unsigned long val_point, + const su2double* val_coord) { + if (val_residual > Residual_Max[val_var]) { + Residual_Max[val_var] = val_residual; + Point_Max[val_var] = val_point; + for (unsigned short iDim = 0; iDim < nDim; iDim++) + Point_Max_Coord[val_var][iDim] = val_coord[iDim]; + } + } + + + /*! + * \brief Get the maximal residual, this is useful for the convergence history. + * \param[in] val_var - Index of the variable. + * \return Value of the biggest residual for the variable in the position val_var. + */ + inline su2double GetRes_Max(unsigned short val_var) const { return Residual_Max[val_var]; } + + /*! + * \brief Set the residual for BGS subiterations. + * \param[in] val_var - Index of the variable. + * \param[in] val_residual - Value of the residual to store in the position val_var. + */ + inline void SetRes_BGS(unsigned short val_var, su2double val_residual) { Residual_BGS[val_var] = val_residual; } + + /*! + * \brief Adds the residual for BGS subiterations. + * \param[in] val_var - Index of the variable. + * \param[in] val_residual - Value of the residual to store in the position val_var. + */ + inline void AddRes_BGS(unsigned short val_var, su2double val_residual) { Residual_BGS[val_var] += val_residual; } + + /*! + * \brief Get the residual for BGS subiterations. + * \param[in] val_var - Index of the variable. + * \return Value of the biggest residual for the variable in the position val_var. + */ + inline su2double GetRes_BGS(unsigned short val_var) const { return Residual_BGS[val_var]; } + + /*! + * \brief Set the maximal residual for BGS subiterations. + * \param[in] val_var - Index of the variable. + * \param[in] val_residual - Value of the residual to store in the position val_var. + */ + inline void SetRes_Max_BGS(unsigned short val_var, + su2double val_residual, + unsigned long val_point) { + Residual_Max_BGS[val_var] = val_residual; Point_Max_BGS[val_var] = val_point; + } + + /*! + * \brief Adds the maximal residual for BGS subiterations. + * \param[in] val_var - Index of the variable. + * \param[in] val_residual - Value of the residual to store in the position val_var. + * \param[in] val_point - Value of the point index for the max residual. + * \param[in] val_coord - Location (x, y, z) of the max residual point. + */ + inline void AddRes_Max_BGS(unsigned short val_var, + su2double val_residual, + unsigned long val_point, + const su2double* val_coord) { + if (val_residual > Residual_Max_BGS[val_var]) { + Residual_Max_BGS[val_var] = val_residual; + Point_Max_BGS[val_var] = val_point; + for (unsigned short iDim = 0; iDim < nDim; iDim++) + Point_Max_Coord_BGS[val_var][iDim] = val_coord[iDim]; + } + } + + + /*! + * \brief Get the maximal residual for BGS subiterations. + * \param[in] val_var - Index of the variable. + * \return Value of the biggest residual for the variable in the position val_var. + */ + inline su2double GetRes_Max_BGS(unsigned short val_var) const { return Residual_Max_BGS[val_var]; } + + /*! + * \brief Get the residual for FEM structural analysis. + * \param[in] val_var - Index of the variable. + * \return Value of the residual for the variable in the position val_var. + */ + inline virtual su2double GetRes_FEM(unsigned short val_var) const { return 0.0; } + + /*! + * \brief Get the maximal residual, this is useful for the convergence history. + * \param[in] val_var - Index of the variable. + * \return Value of the biggest residual for the variable in the position val_var. + */ + inline unsigned long GetPoint_Max(unsigned short val_var) const { return Point_Max[val_var]; } + + /*! + * \brief Get the location of the maximal residual, this is useful for the convergence history. + * \param[in] val_var - Index of the variable. + * \return Pointer to the location (x, y, z) of the biggest residual for the variable val_var. + */ + inline su2double* GetPoint_Max_Coord(unsigned short val_var) const { return Point_Max_Coord[val_var]; } + + /*! + * \brief Get the maximal residual, this is useful for the convergence history. + * \param[in] val_var - Index of the variable. + * \return Value of the biggest residual for the variable in the position val_var. + */ + inline unsigned long GetPoint_Max_BGS(unsigned short val_var) const { return Point_Max_BGS[val_var]; } + + /*! + * \brief Get the location of the maximal residual, this is useful for the convergence history. + * \param[in] val_var - Index of the variable. + * \return Pointer to the location (x, y, z) of the biggest residual for the variable val_var. + */ + inline su2double* GetPoint_Max_Coord_BGS(unsigned short val_var) const { return Point_Max_Coord_BGS[val_var]; } + + /*! + * \brief Set Value of the residual due to the Geometric Conservation Law (GCL) for steady rotating frame problems. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void SetRotatingFrame_GCL(CGeometry *geometry, CConfig *config); + + /*! + * \brief Compute the Green-Gauss gradient of the auxiliary variable. + * \param[in] geometry - Geometrical definition of the problem. + */ + void SetAuxVar_Gradient_GG(CGeometry *geometry, CConfig *config); + + /*! + * \brief Compute the Least Squares gradient of the auxiliary variable. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void SetAuxVar_Gradient_LS(CGeometry *geometry, CConfig *config); + + /*! + * \brief Compute the Least Squares gradient of an auxiliar variable on the profile surface. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void SetAuxVar_Surface_Gradient(CGeometry *geometry, CConfig *config); + + /*! + * \brief Add External to Solution vector. + */ + void Add_External_To_Solution(); + + /*! + * \brief Add the current Solution vector to External. + */ + void Add_Solution_To_External(); + + /*! + * \brief Update a given cross-term with relaxation and the running total (External). + * \param[in] config - Definition of the particular problem. + * \param[in,out] cross_term - The cross-term being updated. + */ + void Update_Cross_Term(CConfig *config, su2passivematrix &cross_term); + + /*! + * \brief Compute the Green-Gauss gradient of the solution. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] reconstruction - indicator that the gradient being computed is for upwind reconstruction. + */ + void SetSolution_Gradient_GG(CGeometry *geometry, CConfig *config, bool reconstruction = false); + + /*! + * \brief Compute the Least Squares gradient of the solution. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] reconstruction - indicator that the gradient being computed is for upwind reconstruction. + */ + void SetSolution_Gradient_LS(CGeometry *geometry, CConfig *config, bool reconstruction = false); + + /*! + * \brief Compute the Least Squares gradient of the grid velocity. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void SetGridVel_Gradient(CGeometry *geometry, CConfig *config); + + /*! + * \brief Compute slope limiter. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void SetSolution_Limiter(CGeometry *geometry, CConfig *config); + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void SetPrimitive_Limiter(CGeometry *geometry, CConfig *config) { } + + /*! + * \brief Set the old solution variables to the current solution value for Runge-Kutta iteration. + It is a virtual function, because for the DG-FEM solver a different version is needed. + * \param[in] geometry - Geometrical definition of the problem. + */ + inline virtual void Set_OldSolution(CGeometry *geometry) { base_nodes->Set_OldSolution(); } + + /*! + * \brief Set the new solution variables to the current solution value for classical RK. + * \param[in] geometry - Geometrical definition of the problem. + */ + inline virtual void Set_NewSolution(CGeometry *geometry) { } + + /*! + * \brief Load the geometries at the previous time states n and nM1. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + virtual void Restart_OldGeometry(CGeometry *geometry, CConfig *config); + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] Iteration - Index of the current iteration. + */ + inline virtual void SetTime_Step(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned long Iteration) { } + + /*! + * \brief A virtual member. + * \param[in] config - Definition of the particular problem. + * \param[in] TimeSync - The synchronization time. + * \param[in,out] timeEvolved - On input the time evolved before the time step, + on output the time evolved after the time step. + * \param[out] syncTimeReached - Whether or not the synchronization time is reached. + */ + inline virtual void CheckTimeSynchronization(CConfig *config, + const su2double TimeSync, + su2double &timeEvolved, + bool &syncTimeReached) {} + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + inline virtual void ProcessTaskList_DG(CGeometry *geometry, + CSolver **solver_container, + CNumerics **numerics, + CConfig *config, + unsigned short iMesh) {} + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + inline virtual void ADER_SpaceTimeIntegration(CGeometry *geometry, + CSolver **solver_container, + CNumerics **numerics, + CConfig *config, + unsigned short iMesh, + unsigned short RunTime_EqSystem) {} + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + inline virtual void ComputeSpatialJacobian(CGeometry *geometry, CSolver **solver_container, + CNumerics **numerics, CConfig *config, + unsigned short iMesh, unsigned short RunTime_EqSystem) {} + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + inline virtual void Postprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh) { } + + /*! + * \brief A virtual member, overloaded. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + inline virtual void Postprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + CNumerics **numerics, + unsigned short iMesh) { } + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + inline virtual void Centered_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + inline virtual void Upwind_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + inline virtual void Convective_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + * \param[in] Output - boolean to determine whether to print output. + */ + inline virtual void Preprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep, + unsigned short RunTime_EqSystem, + bool Output) { } + + /*! + * \brief A virtual member overloaded. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Container vector of the numerics of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + * \param[in] Output - boolean to determine whether to print output. + */ + inline virtual void Preprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + CNumerics **numerics, + unsigned short iMesh, + unsigned long Iteration, + unsigned short RunTime_EqSystem, + bool Output) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void SetUndivided_Laplacian(CGeometry *geometry, CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Set_MPI_ActDisk(CSolver **solver_container, + CGeometry *geometry, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Set_MPI_Nearfield(CGeometry *geometry, CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void SetMax_Eigenvalue(CGeometry *geometry, CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void SetCentered_Dissipation_Sensor(CGeometry *geometry, CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void SetUpwind_Ducros_Sensor(CGeometry *geometry, CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Set_Heatflux_Areas(CGeometry *geometry, CConfig *config) { } + + /*! + * \author H. Kline + * \brief Compute weighted-sum "combo" objective output + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Evaluate_ObjFunc(CConfig *config) {}; + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_Euler_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + + inline virtual void BC_Clamped(CGeometry *geometry, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + + inline virtual void BC_Clamped_Post(CGeometry *geometry, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + + inline virtual void BC_DispDir(CGeometry *geometry, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + + inline virtual void BC_Normal_Displacement(CGeometry *geometry, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) { } + + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_Normal_Load(CGeometry *geometry, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + + inline virtual void BC_Dir_Load(CGeometry *geometry, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + + inline virtual void BC_Sine_Load(CGeometry *geometry, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_Damper(CGeometry *geometry, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + + inline virtual void BC_Deforming(CGeometry *geometry, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_Interface_Boundary(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_NearField_Boundary(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void BC_Periodic(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config) { } + + /*! + * \brief Impose the interface state across sliding meshes. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void BC_Fluid_Interface(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_ActDisk_Inlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_ActDisk_Outlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + * \param[in] val_inlet_surface - Boolean for whether val_marker is an inlet + */ + inline virtual void BC_ActDisk(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker, + bool val_inlet_surface) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_Isothermal_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_HeatFlux_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_Far_Field(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief Impose via the residual the Euler boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_Sym_Plane(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_Riemann(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_TurboRiemann(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief It computes Fourier transformation for the needed quantities along the pitch for each span in turbomachinery analysis. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] marker_flag - Surface marker flag where the function is applied. + */ + inline virtual void PreprocessBC_Giles(CGeometry *geometry, + CConfig *config, + CNumerics *conv_numerics, + unsigned short marker_flag) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_Giles(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_Inlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_Inlet_Turbo(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { } + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_Inlet_MixingPlane(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_Supersonic_Inlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_Supersonic_Outlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the convective numerical method. + * \param[in] visc_numerics - Description of the viscous numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_Custom(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_Outlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_Engine_Inflow(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_Engine_Exhaust(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief Impose the symmetry boundary condition using the residual. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_Dielec(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_Electrode(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + inline virtual void BC_ConjugateHeat_Interface(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief Get the outer state for fluid interface nodes. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + * \param[in] val_state - requested state component + * \param[in] donor_index- index of the donor node to get + */ + inline virtual su2double GetSlidingState(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_state, + unsigned long donor_index) const { return 0; } + + /*! + * \brief Allocates the final pointer of SlidingState depending on how many donor vertex donate to it. That number is stored in SlidingStateNodes[val_marker][val_vertex]. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + */ + inline virtual void SetSlidingStateStructure(unsigned short val_marker, unsigned long val_vertex){} + + /*! + * \brief Set the outer state for fluid interface nodes. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + * \param[in] val_state - requested state component + * \param[in] donor_index- index of the donor node to set + * \param[in] component - set value + */ + inline virtual void SetSlidingState(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_state, + unsigned long donor_index, + su2double component){ } + + /*! + * \brief Get the number of outer states for fluid interface nodes. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + */ + inline virtual int GetnSlidingStates(unsigned short val_marker, unsigned long val_vertex) const { return 0; } + + /*! + * \brief Set the number of outer states for fluid interface nodes. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + * \param[in] value - number of outer states + */ + inline virtual void SetnSlidingStates(unsigned short val_marker, unsigned long val_vertex, int value) { } + + /*! + * \brief Set the conjugate heat variables. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + * \param[in] pos_var - variable position (in vector of all conjugate heat variables) + * \param[in] relaxation factor - relaxation factor for the change of the variables + * \param[in] val_var - value of the variable + */ + inline virtual void SetConjugateHeatVariable(unsigned short val_marker, + unsigned long val_vertex, + unsigned short pos_var, + su2double relaxation_factor, + su2double val_var) { } + + /*! + * \brief Set the conjugate heat variables. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + * \param[in] pos_var - variable position (in vector of all conjugate heat variables) + */ + inline virtual su2double GetConjugateHeatVariable(unsigned short val_marker, + unsigned long val_vertex, + unsigned short pos_var) const { return 0.0; } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + inline virtual void ExplicitRK_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iRKStep) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + inline virtual void ClassicalRK4_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iRKStep) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void ExplicitEuler_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void ImplicitEuler_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] solver - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void ComputeUnderRelaxationFactor(CSolver **solver_container, CConfig *config) { } + + /*! + * \brief Adapt the CFL number based on the local under-relaxation parameters + * computed for each nonlinear iteration. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] solver_container - Container vector with all the solutions. + */ + void AdaptCFLNumber(CGeometry **geometry, CSolver ***solver_container, CConfig *config); + + /*! + * \brief Reset the local CFL adaption variables + */ + void ResetCFLAdapt(); + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void ImplicitNewmark_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void ImplicitNewmark_Update(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void ImplicitNewmark_Relaxation(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void GeneralizedAlpha_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void GeneralizedAlpha_UpdateDisp(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void GeneralizedAlpha_UpdateSolution(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void GeneralizedAlpha_UpdateLoads(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Pressure_Forces(CGeometry *geometry, CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Momentum_Forces(CGeometry *geometry, CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Friction_Forces(CGeometry *geometry, CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Buffet_Monitoring(CGeometry *geometry, CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Heat_Fluxes(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] reconstruction - indicator that the gradient being computed is for upwind reconstruction. + */ + inline virtual void SetPrimitive_Gradient_GG(CGeometry *geometry, + CConfig *config, + bool reconstruction = false) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] reconstruction - indicator that the gradient being computed is for upwind reconstruction. + */ + inline virtual void SetPrimitive_Gradient_LS(CGeometry *geometry, CConfig *config, bool reconstruction = false) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void SetPrimitive_Limiter_MPI(CGeometry *geometry, CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] iPoint - Index of the grid point. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void SetPreconditioner(CConfig *config, unsigned long iPoint) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + inline virtual void Viscous_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] second_numerics - Description of the second numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + inline virtual void Source_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CNumerics *second_numerics, + CConfig *config, + unsigned short iMesh) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + inline virtual void Source_Template(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh) { } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \param[in] val_sensitivity - Value of the sensitivity coefficient. + */ + inline virtual void SetCSensitivity(unsigned short val_marker, + unsigned long val_vertex, + su2double val_sensitivity) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void SetForceProj_Vector(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void SetIntBoundary_Jump(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline virtual void SetTotal_CD(su2double val_Total_CD) { } + + /*! + * \brief A virtual member. + * \param[in] val_Total_CL - Value of the total lift coefficient. + */ + inline virtual void SetTotal_CL(su2double val_Total_CL) { } + + /*! + * \brief A virtual member. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline virtual void SetTotal_NetThrust(su2double val_Total_NetThrust) { } + + /*! + * \brief A virtual member. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline virtual void SetTotal_Power(su2double val_Total_Power) { } + + /*! + * \brief A virtual member. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline virtual void SetTotal_SolidCD(su2double val_Total_SolidCD) { } + + /*! + * \brief A virtual member. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline virtual void SetTotal_ReverseFlow(su2double val_Total_ReverseFlow) { } + + /*! + * \brief A virtual member. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline virtual void SetTotal_MFR(su2double val_Total_MFR) { } + + /*! + * \brief A virtual member. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline virtual void SetTotal_Prop_Eff(su2double val_Total_Prop_Eff) { } + + /*! + * \brief A virtual member. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline virtual void SetTotal_ByPassProp_Eff(su2double val_Total_ByPassProp_Eff) { } + + /*! + * \brief A virtual member. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline virtual void SetTotal_Adiab_Eff(su2double val_Total_Adiab_Eff) { } + + /*! + * \brief A virtual member. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline virtual void SetTotal_Poly_Eff(su2double val_Total_Poly_Eff) { } + + /*! + * \brief A virtual member. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline virtual void SetTotal_IDC(su2double val_Total_IDC) { } + + /*! + * \brief A virtual member. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline virtual void SetTotal_IDC_Mach(su2double val_Total_IDC_Mach) { } + + /*! + * \brief A virtual member. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline virtual void SetTotal_IDR(su2double val_Total_IDR) { } + + /*! + * \brief A virtual member. + * \param[in] val_Total_CD - Value of the total drag coefficient. + */ + inline virtual void SetTotal_DC60(su2double val_Total_DC60) { } + + /*! + * \brief A virtual member. + * \param[in] val_Total_Custom_ObjFunc - Value of the total custom objective function. + * \param[in] val_weight - Value of the weight for the custom objective function. + */ + inline virtual void SetTotal_Custom_ObjFunc(su2double val_total_custom_objfunc, su2double val_weight) { } + + /*! + * \brief A virtual member. + * \param[in] val_Total_Custom_ObjFunc - Value of the total custom objective function. + * \param[in] val_weight - Value of the weight for the custom objective function. + */ + inline virtual void AddTotal_Custom_ObjFunc(su2double val_total_custom_objfunc, su2double val_weight) { } + + /*! + * \brief A virtual member. + * \param[in] val_Total_CT - Value of the total thrust coefficient. + */ + inline virtual void SetTotal_CT(su2double val_Total_CT) { } + + /*! + * \brief A virtual member. + * \param[in] val_Total_CQ - Value of the total torque coefficient. + */ + inline virtual void SetTotal_CQ(su2double val_Total_CQ) { } + + /*! + * \brief A virtual member. + * \param[in] val_Total_Heat - Value of the total heat load. + */ + inline virtual void SetTotal_HeatFlux(su2double val_Total_Heat) { } + + /*! + * \brief A virtual member. + * \param[in] val_Total_MaxHeat - Value of the total heat load. + */ + inline virtual void SetTotal_MaxHeatFlux(su2double val_Total_MaxHeat) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Inviscid_Sensitivity(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Smooth_Sensitivity(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Viscous_Sensitivity(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the lift coefficient (inviscid contribution) on the surface val_marker. + */ + inline virtual su2double GetCL_Inv(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the lift coefficient (viscous contribution) on the surface val_marker. + */ + inline virtual su2double GetCL_Visc(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the lift coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CL(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the drag coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CD(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side force coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CSF(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side force coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CEff(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x force coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CFx(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y force coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CFy(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z force coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CFz(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x moment coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CMx(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y moment coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CMy(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z moment coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CMz(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the lift coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CL_Inv(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the drag coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CD_Inv(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side force coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CSF_Inv(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side force coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CEff_Inv(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x force coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CFx_Inv(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y force coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CFy_Inv(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z force coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CFz_Inv(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x moment coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CMx_Inv(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y moment coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CMy_Inv(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z moment coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CMz_Inv(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the lift coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CL_Visc(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the drag coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CD_Visc(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side force coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CSF_Visc(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side force coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CEff_Visc(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x force coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CFx_Visc(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y force coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CFy_Visc(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z force coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CFz_Visc(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x moment coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CMx_Visc(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y moment coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CMy_Visc(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z moment coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CMz_Visc(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the buffet metric on the surface val_marker. + */ + inline virtual su2double GetSurface_Buffet_Metric(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the lift coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CL_Mnt(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the drag coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CD_Mnt(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side force coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CSF_Mnt(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the side force coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CEff_Mnt(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x force coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CFx_Mnt(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y force coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CFy_Mnt(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z force coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CFz_Mnt(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the x moment coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CMx_Mnt(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the y moment coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CMy_Mnt(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the z moment coefficient on the surface val_marker. + */ + inline virtual su2double GetSurface_CMz_Mnt(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the lift coefficient (viscous contribution) on the surface val_marker. + */ + inline virtual su2double GetCSF_Visc(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the drag coefficient (inviscid contribution) on the surface val_marker. + */ + inline virtual su2double GetCD_Inv(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the mass flow rate on the surface val_marker. + */ + inline virtual su2double GetInflow_MassFlow(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - current mesh level for the multigrid. + * \param[in] Output - boolean to determine whether to print output. + */ + inline virtual void GetPower_Properties(CGeometry *geometry, + CConfig *config, + unsigned short iMesh, + bool Output) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - current mesh level for the multigrid. + * \param[in] Output - boolean to determine whether to print output. + */ + inline virtual void GetOutlet_Properties(CGeometry *geometry, + CConfig *config, + unsigned short iMesh, + bool Output) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - current mesh level for the multigrid. + * \param[in] Output - boolean to determine whether to print output. + */ + inline virtual void SetFarfield_AoA(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + bool Output) { } + + /*! + * \brief A virtual member. + * \param[in] config - Definition of the particular problem. + * \param[in] convergence - boolean for whether the solution is converged + * \return boolean for whether the Fixed C_L mode is converged to target C_L + */ + inline virtual bool FixedCL_Convergence(CConfig *config, bool convergence) { return false; } + + /*! + * \brief A virtual member. + * \return boolean for whether the Fixed C_L mode is currently in finite-differencing mode + */ + inline virtual bool GetStart_AoA_FD(void) const { return false; } + + /*! + * \brief A virtual member. + * \return boolean for whether the Fixed C_L mode is currently in finite-differencing mode + */ + inline virtual bool GetEnd_AoA_FD(void) const { return false; } + + /*! + * \brief A virtual member. + * \return value for the last iteration that the AoA was updated + */ + inline virtual unsigned long GetIter_Update_AoA(void) const { return 0; } + + /*! + * \brief A virtual member. + * \return value of the AoA before most recent update + */ + inline virtual su2double GetPrevious_AoA(void) const { return 0.0; } + + /*! + * \brief A virtual member. + * \return value of CL Driver control command (AoA_inc) + */ + inline virtual su2double GetAoA_inc(void) const { return 0.0; } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - current mesh level for the multigrid. + * \param[in] Output - boolean to determine whether to print output. + */ + inline virtual void SetActDisk_BCThrust(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + bool Output) { } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the mass flow rate on the surface val_marker. + */ + inline virtual su2double GetExhaust_MassFlow(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the fan face pressure on the surface val_marker. + */ + inline virtual su2double GetInflow_Pressure(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the fan face mach on the surface val_marker. + */ + inline virtual su2double GetInflow_Mach(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the sideforce coefficient (inviscid contribution) on the surface val_marker. + */ + inline virtual su2double GetCSF_Inv(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the efficiency coefficient (inviscid contribution) on the surface val_marker. + */ + inline virtual su2double GetCEff_Inv(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the heat flux is computed. + * \return Value of the integrated heat flux (viscous contribution) on the surface val_marker. + */ + inline virtual su2double GetSurface_HF_Visc(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the heat flux is computed. + * \return Value of the maximum heat flux (viscous contribution) on the surface val_marker. + */ + inline virtual su2double GetSurface_MaxHF_Visc(unsigned short val_marker) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \return Value of the drag coefficient (viscous contribution) on the surface val_marker. + */ + inline virtual su2double GetCD_Visc(unsigned short val_marker) const { return 0; } + + /*! + * \author H. Kline + * \brief Set the total "combo" objective (weighted sum of other values). + * \param[in] ComboObj - Value of the combined objective. + */ + inline virtual void SetTotal_ComboObj(su2double ComboObj) {} + + /*! + * \author H. Kline + * \brief Provide the total "combo" objective (weighted sum of other values). + * \return Value of the "combo" objective values. + */ + inline virtual su2double GetTotal_ComboObj(void) const { return 0;} + + /*! + * \brief A virtual member. + * \return Value of the sideforce coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_CSF() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the efficiency coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_CEff() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the thrust coefficient (force in the -x direction, inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_CT() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the torque coefficient (moment in the -x direction, inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_CQ() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the heat load (integrated heat flux). + */ + inline virtual su2double GetTotal_HeatFlux() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the heat load (integrated heat flux). + */ + inline virtual su2double GetTotal_MaxHeatFlux() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the average temperature. + */ + inline virtual su2double GetTotal_AvgTemperature() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the rotor Figure of Merit (FM) (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_CMerit() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the Equivalent Area coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_CEquivArea() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the Aero drag (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_AeroCD() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the difference of the presure and the target pressure. + */ + inline virtual su2double GetTotal_CpDiff() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the difference of the heat and the target heat. + */ + inline virtual su2double GetTotal_HeatFluxDiff() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the FEA coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_CFEA() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the Near-Field Pressure coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_CNearFieldOF() const { return 0; } + + /*! + * \author H. Kline + * \brief Add to the value of the total 'combo' objective. + * \param[in] val_obj - Value of the contribution to the 'combo' objective. + */ + inline virtual void AddTotal_ComboObj(su2double val_obj) {} + + /*! + * \brief A virtual member. + * \return Value of the objective function for a reference geometry. + */ + inline virtual su2double GetTotal_OFRefGeom() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the objective function for a reference node. + */ + inline virtual su2double GetTotal_OFRefNode() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the objective function for the volume fraction. + */ + inline virtual su2double GetTotal_OFVolFrac() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the objective function for the structural compliance. + */ + inline virtual su2double GetTotal_OFCompliance() const { return 0; } + + /*! + * \brief A virtual member. + * \return Bool that defines whether the solution has an element-based file or not + */ + inline virtual bool IsElementBased(void) const { return false; } + + /*! + * \brief A virtual member. + * \param[in] val_cequivarea - Value of the Equivalent Area coefficient. + */ + inline virtual void SetTotal_CEquivArea(su2double val_cequivarea) { } + + /*! + * \brief A virtual member. + * \param[in] val_aerocd - Value of the aero drag. + */ + inline virtual void SetTotal_AeroCD(su2double val_aerocd) { } + + /*! + * \brief A virtual member. + * \param[in] val_pressure - Value of the difference between pressure and the target pressure. + */ + inline virtual void SetTotal_CpDiff(su2double val_pressure) { } + + /*! + * \brief A virtual member. + * \param[in] val_pressure - Value of the difference between heat and the target heat. + */ + inline virtual void SetTotal_HeatFluxDiff(su2double val_heat) { } + + /*! + * \brief A virtual member. + * \param[in] val_cfea - Value of the FEA coefficient. + */ + inline virtual void SetTotal_CFEA(su2double val_cfea) { } + + /*! + * \brief A virtual member. + * \param[in] val_ofrefgeom - Value of the objective function for a reference geometry. + */ + inline virtual void SetTotal_OFRefGeom(su2double val_ofrefgeom) { } + + /*! + * \brief A virtual member. + * \param[in] val_ofrefgeom - Value of the objective function for a reference node. + */ + inline virtual void SetTotal_OFRefNode(su2double val_ofrefnode) { } + + /*! + * \brief A virtual member. + * \param[in] val_cnearfieldpress - Value of the Near-Field pressure coefficient. + */ + inline virtual void SetTotal_CNearFieldOF(su2double val_cnearfieldpress) { } + + /*! + * \brief A virtual member. + * \return Value of the lift coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_CL() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_CD() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_NetThrust() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_Power() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_SolidCD() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_ReverseFlow() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_MFR() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_Prop_Eff() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_ByPassProp_Eff() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_Adiab_Eff() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_Poly_Eff() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_IDC() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_IDC_Mach() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_IDR() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_DC60() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the custom objective function. + */ + inline virtual su2double GetTotal_Custom_ObjFunc() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the moment x coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_CMx() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the moment y coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_CMy() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the moment y coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_CMz() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the moment x coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_CoPx() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the moment y coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_CoPy() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the moment y coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_CoPz() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the force x coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_CFx() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the force y coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_CFy() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the force y coefficient (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_CFz() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the lift coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CL_Inv() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CD_Inv() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CSF_Inv() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CEff_Inv() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CMx_Inv() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CMy_Inv() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CMz_Inv() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CoPx_Inv() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CoPy_Inv() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CoPz_Inv() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CFx_Inv() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CFy_Inv() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CFz_Inv() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the lift coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CL_Visc() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CD_Visc() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CSF_Visc() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CEff_Visc() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CMx_Visc() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CMy_Visc() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CMz_Visc() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CoPx_Visc() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CoPy_Visc() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CoPz_Visc() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CFx_Visc() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CFy_Visc() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CFz_Visc() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the lift coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CL_Mnt() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CD_Mnt() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CSF_Mnt() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CEff_Mnt() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CMx_Mnt() const { return 0; } + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CMy_Mnt() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CMz_Mnt() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CoPx_Mnt() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CoPy_Mnt() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CoPz_Mnt() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CFx_Mnt() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CFy_Mnt() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the drag coefficient (inviscid contribution). + */ + inline virtual su2double GetAllBound_CFz_Mnt() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the buffet metric. + */ + inline virtual su2double GetTotal_Buffet_Metric() const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline virtual su2double GetCPressure(unsigned short val_marker, unsigned long val_vertex) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline virtual su2double GetCPressureTarget(unsigned short val_marker, unsigned long val_vertex) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline virtual void SetCPressureTarget(unsigned short val_marker, + unsigned long val_vertex, + su2double val_pressure) { } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + + inline virtual void SetCharacPrimVar(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_var, + su2double val_value) { } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline virtual su2double *GetDonorPrimVar(unsigned short val_marker, unsigned long val_vertex) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline virtual void SetDonorPrimVar(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_var, + su2double val_value) { } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + + inline virtual void SetDonorAdjVar(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_var, + su2double val_value) { } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline virtual su2double GetDonorPrimVar(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_var) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + + inline virtual su2double *GetDonorAdjVar(unsigned short val_marker, unsigned long val_vertex) const { + return nullptr; + } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + + inline virtual su2double GetDonorAdjVar(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_var) const { + return 0; + } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline virtual unsigned long GetDonorGlobalIndex(unsigned short val_marker, + unsigned long val_vertex) const { + return 0; + } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline virtual void SetDonorGlobalIndex(unsigned short val_marker, + unsigned long val_vertex, + unsigned long val_index) { } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline virtual su2double *GetCharacPrimVar(unsigned short val_marker, + unsigned long val_vertex) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline virtual su2double GetActDisk_DeltaP(unsigned short val_marker, unsigned long val_vertex) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline virtual void SetActDisk_DeltaP(unsigned short val_marker, + unsigned long val_vertex, + su2double val_deltap) { } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline virtual su2double GetActDisk_DeltaT(unsigned short val_marker, unsigned long val_vertex) { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline virtual void SetActDisk_DeltaT(unsigned short val_marker, + unsigned long val_vertex, + su2double val_deltat) { } + + /*! + * \brief A virtual member + * \param[in] val_marker - Surface marker where the total temperature is evaluated. + * \param[in] val_vertex - Vertex of the marker val_marker where the total temperature is evaluated. + * \return Value of the total temperature + */ + inline virtual su2double GetInlet_Ttotal(unsigned short val_marker, unsigned long val_vertex) const { return 0; } + + /*! + * \brief A virtual member + * \param[in] val_marker - Surface marker where the total pressure is evaluated. + * \param[in] val_vertex - Vertex of the marker val_marker where the total pressure is evaluated. + * \return Value of the total pressure + */ + inline virtual su2double GetInlet_Ptotal(unsigned short val_marker, unsigned long val_vertex) const { return 0; } + + /*! + * \brief A virtual member + * \param[in] val_marker - Surface marker where the flow direction is evaluated + * \param[in] val_vertex - Vertex of the marker val_marker where the flow direction is evaluated + * \param[in] val_dim - The component of the flow direction unit vector to be evaluated + * \return Component of a unit vector representing the flow direction. + */ + inline virtual su2double GetInlet_FlowDir(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_dim) const { return 0; } + + /*! + * \brief A virtual member + * \param[in] val_marker - Surface marker where the total temperature is set. + * \param[in] val_vertex - Vertex of the marker val_marker where the total temperature is set. + * \param[in] val_ttotal - Value of the total temperature + */ + inline virtual void SetInlet_Ttotal(unsigned short val_marker, + unsigned long val_vertex, + su2double val_ttotal) { } + + /*! + * \brief A virtual member + * \param[in] val_marker - Surface marker where the total pressure is set. + * \param[in] val_vertex - Vertex of the marker val_marker where the total pressure is set. + * \param[in] val_ptotal - Value of the total pressure + */ + inline virtual void SetInlet_Ptotal(unsigned short val_marker, + unsigned long val_vertex, + su2double val_ptotal) { } + + /*! + * \brief A virtual member + * \param[in] val_marker - Surface marker where the flow direction is set. + * \param[in] val_vertex - Vertex of the marker val_marker where the flow direction is set. + * \param[in] val_dim - The component of the flow direction unit vector to be set + * \param[in] val_flowdir - Component of a unit vector representing the flow direction. + */ + inline virtual void SetInlet_FlowDir(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_dim, + su2double val_flowdir) { } + + /*! + * \brief A virtual member + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \param[in] iDim - Index of the turbulence variable (i.e. k is 0 in SST) + * \param[in] val_turb_var - Value of the turbulence variable to be used. + */ + inline virtual void SetInlet_TurbVar(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_dim, + su2double val_turb_var) { } + + /*! + * \brief A virtual member + * \param[in] config - Definition of the particular problem. + * \param[in] iMarker - Surface marker where the coefficient is computed. + */ + inline virtual void SetUniformInlet(CConfig* config, unsigned short iMarker) {}; + + /*! + * \brief A virtual member + * \param[in] val_inlet - vector containing the inlet values for the current vertex. + * \param[in] iMarker - Surface marker where the coefficient is computed. + * \param[in] iVertex - Vertex of the marker iMarker where the inlet is being set. + */ + inline virtual void SetInletAtVertex(su2double *val_inlet, + unsigned short iMarker, + unsigned long iVertex) { }; + + /*! + * \brief A virtual member + * \param[in] val_inlet - vector returning the inlet values for the current vertex. + * \param[in] val_inlet_point - Node index where the inlet is being set. + * \param[in] val_kind_marker - Enumerated type for the particular inlet type. + * \param[in] geometry - Geometrical definition of the problem. + * \param config - Definition of the particular problem. + * \return Value of the face area at the vertex. + */ + inline virtual su2double GetInletAtVertex(su2double *val_inlet, + unsigned long val_inlet_point, + unsigned short val_kind_marker, + string val_marker, + CGeometry *geometry, + CConfig *config) const { return 0; } + + /*! + * \brief Update the multi-grid structure for the customized boundary conditions + * \param geometry_container - Geometrical definition. + * \param config - Definition of the particular problem. + */ + inline virtual void UpdateCustomBoundaryConditions(CGeometry **geometry_container, CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the skin friction coefficient. + */ + inline virtual su2double GetCSkinFriction(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_dim) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the heat transfer coefficient. + */ + inline virtual su2double GetHeatFlux(unsigned short val_marker, unsigned long val_vertex) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the heat transfer coefficient. + */ + inline virtual su2double GetHeatFluxTarget(unsigned short val_marker, unsigned long val_vertex) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the pressure coefficient. + */ + inline virtual void SetHeatFluxTarget(unsigned short val_marker, + unsigned long val_vertex, + su2double val_heat) { } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the buffet sensor. + */ + inline virtual su2double GetBuffetSensor(unsigned short val_marker, unsigned long val_vertex) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the y plus. + */ + inline virtual su2double GetYPlus(unsigned short val_marker, unsigned long val_vertex) const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the StrainMag_Max + */ + inline virtual su2double GetStrainMag_Max(void) const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the Omega_Max + */ + inline virtual su2double GetOmega_Max(void) const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the StrainMag_Max + */ + inline virtual void SetStrainMag_Max(su2double val_strainmag_max) { } + + /*! + * \brief A virtual member. + * \return Value of the Omega_Max + */ + inline virtual void SetOmega_Max(su2double val_omega_max) { } + + /*! + * \brief A virtual member. + * \return Value of the adjoint density at the infinity. + */ + inline virtual su2double GetPsiRho_Inf(void) const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the adjoint energy at the infinity. + */ + inline virtual su2double GetPsiE_Inf(void) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_dim - Index of the adjoint velocity vector. + * \return Value of the adjoint velocity vector at the infinity. + */ + inline virtual su2double GetPhi_Inf(unsigned short val_dim) const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the geometrical sensitivity coefficient + * (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_Sens_Geo() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the Mach sensitivity coefficient + * (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_Sens_Mach() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the angle of attack sensitivity coefficient + * (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_Sens_AoA() const { return 0; } + + /*! + * \brief Set the total farfield pressure sensitivity coefficient. + * \return Value of the farfield pressure sensitivity coefficient + * (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_Sens_Press() const { return 0; } + + /*! + * \brief Set the total farfield temperature sensitivity coefficient. + * \return Value of the farfield temperature sensitivity coefficient + * (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_Sens_Temp() const { return 0; } + + /*! + * \author H. Kline + * \brief Get the total back pressure sensitivity coefficient. + * \return Value of the back pressure sensitivity coefficient + * (inviscid + viscous contribution). + */ + inline virtual su2double GetTotal_Sens_BPress() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the density sensitivity. + */ + inline virtual su2double GetTotal_Sens_Density() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the velocity magnitude sensitivity. + */ + inline virtual su2double GetTotal_Sens_ModVel() const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the density at the infinity. + */ + inline virtual su2double GetDensity_Inf(void) const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the velocity at the infinity. + */ + inline virtual su2double GetModVelocity_Inf(void) const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the density x energy at the infinity. + */ + inline virtual su2double GetDensity_Energy_Inf(void) const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the pressure at the infinity. + */ + inline virtual su2double GetPressure_Inf(void) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_dim - Index of the adjoint velocity vector. + * \return Value of the density x velocity at the infinity. + */ + inline virtual su2double GetDensity_Velocity_Inf(unsigned short val_dim) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] val_dim - Index of the velocity vector. + * \return Value of the velocity at the infinity. + */ + inline virtual su2double GetVelocity_Inf(unsigned short val_dim) const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the velocity at the infinity. + */ + inline virtual su2double *GetVelocity_Inf(void) const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the viscosity at the infinity. + */ + inline virtual su2double GetViscosity_Inf(void) const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of nu tilde at the far-field. + */ + inline virtual su2double GetNuTilde_Inf(void) const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the turbulent kinetic energy. + */ + inline virtual su2double GetTke_Inf(void) const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the turbulent frequency. + */ + inline virtual su2double GetOmega_Inf(void) const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the sensitivity coefficient for the Young Modulus E + */ + inline virtual su2double GetTotal_Sens_E(unsigned short iVal) const { return 0.0; } + + /*! + * \brief A virtual member. + * \return Value of the sensitivity for the Poisson's ratio Nu + */ + inline virtual su2double GetTotal_Sens_Nu(unsigned short iVal) const { return 0.0; } + + /*! + * \brief A virtual member. + * \return Value of the structural density sensitivity + */ + inline virtual su2double GetTotal_Sens_Rho(unsigned short iVal) const { return 0.0; } + + /*! + * \brief A virtual member. + * \return Value of the structural weight sensitivity + */ + inline virtual su2double GetTotal_Sens_Rho_DL(unsigned short iVal) const { return 0.0; } + + /*! + * \brief A virtual member. + * \return Value of the sensitivity coefficient for the Electric Field in the region iEField + */ + inline virtual su2double GetTotal_Sens_EField(unsigned short iEField) const { return 0.0; } + + /*! + * \brief A virtual member. + * \return Value of the sensitivity coefficient for the FEA DV in the region iDVFEA + */ + inline virtual su2double GetTotal_Sens_DVFEA(unsigned short iDVFEA) const { return 0.0; } + + /*! + * \brief A virtual member. + * \return Value of the sensitivity coefficient for the Young Modulus E + */ + inline virtual su2double GetGlobal_Sens_E(unsigned short iVal) const { return 0.0; } + + /*! + * \brief A virtual member. + * \return Value of the sensitivity coefficient for the Poisson's ratio Nu + */ + inline virtual su2double GetGlobal_Sens_Nu(unsigned short iVal) const { return 0.0; } + + /*! + * \brief A virtual member. + * \return Value of the structural density sensitivity + */ + inline virtual su2double GetGlobal_Sens_Rho(unsigned short iVal) const { return 0.0; } + + /*! + * \brief A virtual member. + * \return Value of the structural weight sensitivity + */ + inline virtual su2double GetGlobal_Sens_Rho_DL(unsigned short iVal) const { return 0.0; } + + /*! + * \brief A virtual member. + * \return Value of the sensitivity coefficient for the Electric Field in the region iEField + */ + inline virtual su2double GetGlobal_Sens_EField(unsigned short iEField) const { return 0.0; } + + /*! + * \brief A virtual member. + * \return Value of the sensitivity coefficient for the FEA DV in the region iDVFEA + */ + inline virtual su2double GetGlobal_Sens_DVFEA(unsigned short iDVFEA) const { return 0.0; } + + /*! + * \brief A virtual member. + * \return Value of the Young modulus from the adjoint solver + */ + inline virtual su2double GetVal_Young(unsigned short iVal) const { return 0.0; } + + /*! + * \brief A virtual member. + * \return Value of the Poisson's ratio from the adjoint solver + */ + inline virtual su2double GetVal_Poisson(unsigned short iVal) const { return 0.0; } + + /*! + * \brief A virtual member. + * \return Value of the density for inertial effects, from the adjoint solver + */ + inline virtual su2double GetVal_Rho(unsigned short iVal) const { return 0.0; } + + /*! + * \brief A virtual member. + * \return Value of the density for dead loads, from the adjoint solver + */ + inline virtual su2double GetVal_Rho_DL(unsigned short iVal) const { return 0.0; } + + /*! + * \brief A virtual member. + * \return Number of electric field variables from the adjoint solver + */ + inline virtual unsigned short GetnEField(void) const { return 0; } + + /*! + * \brief A virtual member. + * \return Number of design variables from the adjoint solver + */ + inline virtual unsigned short GetnDVFEA(void) const { return 0; } + + /*! + * \brief A virtual member. + */ + inline virtual void ReadDV(CConfig *config) { } + + /*! + * \brief A virtual member. + * \return Pointer to the values of the Electric Field + */ + inline virtual su2double GetVal_EField(unsigned short iVal) const { return 0.0; } + + /*! + * \brief A virtual member. + * \return Pointer to the values of the design variables + */ + inline virtual su2double GetVal_DVFEA(unsigned short iVal) const { return 0.0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - Surface marker where the coefficient is computed. + * \param[in] val_vertex - Vertex of the marker val_marker where the coefficient is evaluated. + * \return Value of the sensitivity coefficient. + */ + inline virtual su2double GetCSensitivity(unsigned short val_marker, + unsigned long val_vertex) const { + return 0; + } + + /*! + * \brief A virtual member. + * \return A pointer to an array containing a set of constants + */ + inline virtual su2double* GetConstants() const { return NULL; } + + /*! + * \brief A virtual member. + * \param[in] iBGS - Number of BGS iteration. + * \param[in] val_forcecoeff_history - Value of the force coefficient. + */ + inline virtual void SetForceCoeff(su2double val_forcecoeff_history) { } + + /*! + * \brief A virtual member. + * \param[in] val_relaxcoeff_history - Value of the force coefficient. + */ + inline virtual void SetRelaxCoeff(su2double val_relaxcoeff_history) { } + + /*! + * \brief A virtual member. + * \param[in] iBGS - Number of BGS iteration. + * \param[in] val_FSI_residual - Value of the residual. + */ + inline virtual void SetFSI_Residual(su2double val_FSI_residual) { } + + /*! + * \brief A virtual member. + * \param[out] val_forcecoeff_history - Value of the force coefficient. + */ + inline virtual su2double GetForceCoeff(void) const { return 0.0; } + + /*! + * \brief A virtual member. + * \param[out] val_relaxcoeff_history - Value of the relax coefficient. + */ + inline virtual su2double GetRelaxCoeff(void) const { return 0.0; } + + /*! + * \brief A virtual member. + * \param[out] val_FSI_residual - Value of the residual. + */ + inline virtual su2double GetFSI_Residual(void) const { return 0.0; } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] ExtIter - External iteration. + */ + inline virtual void SetInitialCondition(CGeometry **geometry, + CSolver ***solver_container, + CConfig *config, + unsigned long TimeIter) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] ExtIter - External iteration. + */ + inline virtual void ResetInitialCondition(CGeometry **geometry, + CSolver ***solver_container, + CConfig *config, + unsigned long TimeIter) { } + + /*! + * \brief A virtual member. + * \param[in] fea_geometry - Geometrical definition of the problem. + * \param[in] fea_config - Geometrical definition of the problem. + * \param[in] fea_geometry - Definition of the particular problem. + */ + inline virtual void PredictStruct_Displacement(CGeometry **fea_geometry, + CConfig *fea_config, + CSolver ***fea_solution) { } + + /*! + * \brief A virtual member. + * \param[in] fea_geometry - Geometrical definition of the problem. + * \param[in] fea_config - Geometrical definition of the problem. + * \param[in] fea_geometry - Definition of the particular problem. + */ + inline virtual void ComputeAitken_Coefficient(CGeometry **fea_geometry, + CConfig *fea_config, + CSolver ***fea_solution, + unsigned long iOuterIter) { } + + + /*! + * \brief A virtual member. + * \param[in] fea_geometry - Geometrical definition of the problem. + * \param[in] fea_config - Geometrical definition of the problem. + * \param[in] fea_geometry - Definition of the particular problem. + */ + inline virtual void SetAitken_Relaxation(CGeometry **fea_geometry, + CConfig *fea_config, + CSolver ***fea_solution) { } + + /*! + * \brief A virtual member. + * \param[in] fea_geometry - Geometrical definition of the problem. + * \param[in] fea_config - Geometrical definition of the problem. + * \param[in] fea_geometry - Definition of the particular problem. + */ + inline virtual void Update_StructSolution(CGeometry **fea_geometry, + CConfig *fea_config, + CSolver ***fea_solution) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Container vector with all of the solvers. + * \param[in] config - Definition of the particular problem. + * \param[in] val_iter - Current external iteration number. + * \param[in] val_update_geo - Flag for updating coords and grid velocity. + */ + inline virtual void LoadRestart(CGeometry **geometry, + CSolver ***solver, + CConfig *config, + int val_iter, + bool val_update_geo) { } + + /*! + * \brief Read a native SU2 restart file in ASCII format. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] val_filename - String name of the restart file. + */ + void Read_SU2_Restart_ASCII(CGeometry *geometry, + CConfig *config, + string val_filename); + + /*! + * \brief Read a native SU2 restart file in binary format. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] val_filename - String name of the restart file. + */ + void Read_SU2_Restart_Binary(CGeometry *geometry, + CConfig *config, + string val_filename); + + /*! + * \brief Read the metadata from a native SU2 restart file (ASCII or binary). + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] adjoint - Boolean to identify the restart file of an adjoint run. + * \param[in] val_filename - String name of the restart file. + */ + void Read_SU2_Restart_Metadata(CGeometry *geometry, + CConfig *config, + bool adjoint_run, + string val_filename); + + /*! + * \brief Load a inlet profile data from file into a particular solver. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Container vector with all of the solvers. + * \param[in] config - Definition of the particular problem. + * \param[in] val_iter - Current external iteration number. + * \param[in] val_kind_solver - Solver container position. + * \param[in] val_kind_marker - Kind of marker to apply the profiles. + */ + void LoadInletProfile(CGeometry **geometry, + CSolver ***solver, + CConfig *config, + int val_iter, + unsigned short val_kind_solver, + unsigned short val_kind_marker); + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Compute_OFRefGeom(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Compute_OFRefNode(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Compute_OFVolFrac(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Compute_OFCompliance(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Stiffness_Penalty(CGeometry *geometry, + CSolver **solver_container, + CNumerics **numerics_container, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] val_iter - Current external iteration number. + */ + inline virtual void LoadRestart_FSI(CGeometry *geometry, + CConfig *config, + int val_iter) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void RefGeom_Sensitivity(CGeometry *geometry, + CSolver **solver_container, + CConfig *config){ } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void DE_Sensitivity(CGeometry *geometry, + CSolver **solver_container, + CNumerics **numerics_container, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Stiffness_Sensitivity(CGeometry *geometry, + CSolver **solver_container, + CNumerics **numerics_container, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] iElem - element parameter. + * \param[out] iElem_iDe - ID of the Dielectric Elastomer region. + */ + inline virtual unsigned short Get_iElem_iDe(unsigned long iElem) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] i_DV - number of design variable. + * \param[in] val_EField - value of the design variable. + */ + inline virtual void Set_DV_Val(su2double val_EField, unsigned short i_DV) { } + + /*! + * \brief A virtual member. + * \param[in] i_DV - number of design variable. + * \param[out] DV_Val - value of the design variable. + */ + inline virtual su2double Get_DV_Val(unsigned short i_DV) const { return 0.0; } + + /*! + * \brief Gauss method for solving a linear system. + * \param[in] A - Matrix Ax = b. + * \param[in] rhs - Right hand side. + * \param[in] nVar - Number of variables. + */ + void Gauss_Elimination(su2double** A, + su2double* rhs, + unsigned short nVar); + + /*! + * \brief Prepares and solves the aeroelastic equations. + * \param[in] surface_movement - Surface movement classes of the problem. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] TimeIter - Physical iteration number. + */ + void Aeroelastic(CSurfaceMovement *surface_movement, + CGeometry *geometry, + CConfig *config, + unsigned long TimeIter); + + /*! + * \brief Sets up the generalized eigenvectors and eigenvalues needed to solve the aeroelastic equations. + * \param[in] PHI - Matrix of the generalized eigenvectors. + * \param[in] w - The eigenvalues of the generalized eigensystem. + * \param[in] config - Definition of the particular problem. + */ + void SetUpTypicalSectionWingModel(vector >& PHI, + vector& w, + CConfig *config); + + /*! + * \brief Solve the typical section wing model. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] Cl - Coefficient of lift at particular iteration. + * \param[in] Cm - Moment coefficient about z-axis at particular iteration. + * \param[in] config - Definition of the particular problem. + * \param[in] val_Marker - Surface that is being monitored. + * \param[in] displacements - solution of typical section wing model. + */ + void SolveTypicalSectionWingModel(CGeometry *geometry, + su2double Cl, su2double Cm, + CConfig *config, + unsigned short val_Marker, + vector& displacements); + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config_container - The particular config. + */ + inline virtual void RegisterSolution(CGeometry *geometry_container, CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config_container - The particular config. + */ + inline virtual void RegisterOutput(CGeometry *geometry_container, CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - The geometrical definition of the problem. + * \param[in] config - The particular config. + */ + inline virtual void SetAdjoint_Output(CGeometry *geometry, CConfig *config){} + + /*! + * \brief A virtual member. + * \param[in] geometry - The geometrical definition of the problem. + * \param[in] config - The particular config. + */ + inline virtual void SetAdjoint_OutputMesh(CGeometry *geometry, CConfig *config) {} + + /*! + * \brief A virtual member. + * \param[in] geometry - The geometrical definition of the problem. + * \param[in] solver_container - The solver container holding all solutions. + * \param[in] config - The particular config. + */ + inline virtual void ExtractAdjoint_Solution(CGeometry *geometry, CConfig *config){} + + /*! + * \brief A virtual member. + * \param[in] geometry - The geometrical definition of the problem. + * \param[in] solver_container - The solver container holding all solutions. + * \param[in] config - The particular config. + */ + inline virtual void ExtractAdjoint_Geometry(CGeometry *geometry, CConfig *config) {} + + /*! + * \brief A virtual member. + * \param[in] geometry - The geometrical definition of the problem. + * \param[in] solver_container - The solver container holding all solutions. + * \param[in] config - The particular config. + */ + inline virtual void ExtractAdjoint_CrossTerm(CGeometry *geometry, CConfig *config) {} + + /*! + * \brief A virtual member. + * \param[in] geometry - The geometrical definition of the problem. + * \param[in] solver_container - The solver container holding all solutions. + * \param[in] config - The particular config. + */ + inline virtual void ExtractAdjoint_CrossTerm_Geometry(CGeometry *geometry, CConfig *config) {} + + /*! + * \brief A virtual member. + * \param[in] geometry - The geometrical definition of the problem. + * \param[in] solver_container - The solver container holding all solutions. + * \param[in] config - The particular config. + */ + inline virtual void ExtractAdjoint_CrossTerm_Geometry_Flow(CGeometry *geometry, CConfig *config) {} + + /*! + * \brief A virtual member + * \param[in] geometry - The geometrical definition of the problem. + */ + inline virtual void RegisterObj_Func(CConfig *config){} + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void SetSurface_Sensitivity(CGeometry *geometry, CConfig *config) { } + + /*! + * \brief A virtual member. Extract and set the geometrical sensitivity. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - The solver container holding all terms of the solution. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void SetSensitivity(CGeometry *geometry, CSolver **solver, CConfig *config){ } + + /*! + * \brief A virtual member. Extract and set the derivative of objective function. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void SetAdj_ObjFunc(CGeometry *geometry, CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] Set value of interest: 0 - Initial value, 1 - Current value. + */ + inline virtual void SetFSI_ConvValue(unsigned short val_index, su2double val_criteria) { }; + + /*! + * \brief A virtual member. + * \param[in] Value of interest: 0 - Initial value, 1 - Current value. + * \return Values to compare + */ + inline virtual su2double GetFSI_ConvValue(unsigned short val_index)const { return 0.0; } + + /*! + * \brief A virtual member. + * \param[in] CurrentTime - Current time step. + * \param[in] RampTime - Time for application of the ramp.* + * \param[in] config - Definition of the particular problem. + */ + inline virtual su2double Compute_LoadCoefficient(su2double CurrentTime, + su2double RampTime, + CConfig *config) { return 0.0; } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Compute_StiffMatrix(CGeometry *geometry, + CNumerics **numerics, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Compute_StiffMatrix_NodalStressRes(CGeometry *geometry, + CNumerics **numerics, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Compute_MassMatrix(CGeometry *geometry, + CNumerics **numerics, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Compute_MassRes(CGeometry *geometry, + CNumerics **numerics, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Compute_NodalStressRes(CGeometry *geometry, + CNumerics **numerics, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + + inline virtual void Compute_NodalStress(CGeometry *geometry, + CNumerics **numerics, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] solver - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Compute_DeadLoad(CGeometry *geometry, + CNumerics **numerics, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with the solutions. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void Solve_System(CGeometry *geometry, CConfig *config) { } + + /*! + * \brief A virtual member. + * \return Value of the dynamic Aitken relaxation factor + */ + inline virtual su2double GetWAitken_Dyn(void) const { return 0; } + + /*! + * \brief A virtual member. + * \return Value of the last Aitken relaxation factor in the previous time step. + */ + inline virtual su2double GetWAitken_Dyn_tn1(void) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] Value of the dynamic Aitken relaxation factor + */ + inline virtual void SetWAitken_Dyn(su2double waitk) { } + + /*! + * \brief A virtual member. + * \param[in] Value of the last Aitken relaxation factor in the previous time step. + */ + inline virtual void SetWAitken_Dyn_tn1(su2double waitk_tn1) { } + + /*! + * \brief A virtual member. + * \param[in] Value of the load increment for nonlinear structural analysis + */ + inline virtual void SetLoad_Increment(su2double val_loadIncrement) { } + + /*! + * \brief A virtual member. + * \param[in] Value of the load increment for nonlinear structural analysis + */ + inline virtual su2double GetLoad_Increment() const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] Output - boolean to determine whether to print output. + */ + inline virtual unsigned long SetPrimitive_Variables(CSolver **solver_container, + CConfig *config, + bool Output) { return 0; } + + /*! + * \brief A virtual member. + * \param[in] Value of freestream pressure. + */ + inline virtual void SetPressure_Inf(su2double p_inf){} + + /*! + * \brief A virtual member. + * \param[in] Value of freestream temperature. + */ + inline virtual void SetTemperature_Inf(su2double t_inf){} + + /*! + * \brief A virtual member. + * \param[in] Value of freestream density. + */ + inline virtual void SetDensity_Inf(su2double rho_inf){} + + /*! + * \brief A virtual member. + * \param[in] val_dim - Index of the velocity vector. + * \param[in] val_velocity - Value of the velocity. + */ + inline virtual void SetVelocity_Inf(unsigned short val_dim, su2double val_velocity) { } + + /*! + * \brief A virtual member. + * \param[in] kind_recording - Kind of AD recording. + */ + inline virtual void SetRecording(CGeometry *geometry, CConfig *config){} + + /*! + * \brief A virtual member. + * \param[in] kind_recording - Kind of AD recording. + */ + inline virtual void SetMesh_Recording(CGeometry **geometry, + CVolumetricMovement *grid_movement, + CConfig *config) {} + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] reset - If true reset variables to their initial values. + */ + inline virtual void RegisterVariables(CGeometry *geometry, + CConfig *config, + bool reset = false) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void ExtractAdjoint_Variables(CGeometry *geometry, CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void SetFreeStream_Solution(CConfig *config) { } + + /*! + * \brief A virtual member. + */ + inline virtual su2double* GetVecSolDOFs(void) { return NULL; } + + /*! + * \brief A virtual member. + */ + inline virtual unsigned long GetnDOFsGlobal(void) const { return 0; } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void SetTauWall_WF(CGeometry *geometry, + CSolver** solver_container, + CConfig* config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void SetNuTilde_WF(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void InitTurboContainers(CGeometry *geometry, CConfig *config) { } + + /*! + * \brief virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the average is evaluated. + */ + inline virtual void PreprocessAverage(CSolver **solver, + CGeometry *geometry, + CConfig *config, + unsigned short marker_flag) { } + + /*! + * \brief virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the average is evaluated. + */ + inline virtual void TurboAverageProcess(CSolver **solver, + CGeometry *geometry, + CConfig *config, + unsigned short marker_flag) { } + + /*! + * \brief virtual member. + * \param[in] config - Definition of the particular problem. + * \param[in] geometry - Geometrical definition of the problem. + */ + inline virtual void GatherInOutAverageValues(CConfig *config, CGeometry *geometry) { } + + /*! + * \brief A virtual member. + * \param[in] val_marker - bound marker. + * \return Value of the Average Density on the surface val_marker. + */ + inline virtual su2double GetAverageDensity(unsigned short valMarker, unsigned short valSpan) const { return 0.0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - bound marker. + * \return Value of the Average Pressure on the surface val_marker. + */ + inline virtual su2double GetAveragePressure(unsigned short valMarker, unsigned short valSpan) const { return 0.0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - bound marker. + * \return Value of the Average Total Pressure on the surface val_marker. + */ + inline virtual su2double* GetAverageTurboVelocity(unsigned short valMarker, unsigned short valSpan) const { return nullptr; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - bound marker. + * \return Value of the Average Nu on the surface val_marker. + */ + inline virtual su2double GetAverageNu(unsigned short valMarker, unsigned short valSpan) const { return 0.0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - bound marker. + * \return Value of the Average Kine on the surface val_marker. + */ + inline virtual su2double GetAverageKine(unsigned short valMarker, unsigned short valSpan) const { return 0.0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - bound marker. + * \return Value of the Average Omega on the surface val_marker. + */ + inline virtual su2double GetAverageOmega(unsigned short valMarker, unsigned short valSpan) const { return 0.0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - bound marker. + * \return Value of the Average Nu on the surface val_marker. + */ + inline virtual su2double GetExtAverageNu(unsigned short valMarker, unsigned short valSpan) const { return 0.0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - bound marker. + * \return Value of the Average Kine on the surface val_marker. + */ + inline virtual su2double GetExtAverageKine(unsigned short valMarker, unsigned short valSpan) const { return 0.0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - bound marker. + * \return Value of the Average Omega on the surface val_marker. + */ + inline virtual su2double GetExtAverageOmega(unsigned short valMarker, unsigned short valSpan) const { return 0.0; } + + /*! + * \brief A virtual member. + * \param[in] val_marker - bound marker. + * \return Value of the Average Density on the surface val_marker. + */ + inline virtual void SetExtAverageDensity(unsigned short valMarker, + unsigned short valSpan, + su2double valDensity) { } + + /*! + * \brief A virtual member. + * \param[in] val_marker - bound marker. + * \return Value of the Average Pressure on the surface val_marker. + */ + inline virtual void SetExtAveragePressure(unsigned short valMarker, + unsigned short valSpan, + su2double valPressure) { } + + /*! + * \brief A virtual member. + * \param[in] val_marker - bound marker. + * \return Value of the Average Total Pressure on the surface val_marker. + */ + inline virtual void SetExtAverageTurboVelocity(unsigned short valMarker, + unsigned short valSpan, + unsigned short valIndex, + su2double valTurboVelocity) { } + + /*! + * \brief A virtual member. + * \param[in] val_marker - bound marker. + * \return Value of the Average Nu on the surface val_marker. + */ + inline virtual void SetExtAverageNu(unsigned short valMarker, + unsigned short valSpan, + su2double valNu) { } + + /*! + * \brief A virtual member. + * \param[in] val_marker - bound marker. + * \return Value of the Average Kine on the surface val_marker. + */ + inline virtual void SetExtAverageKine(unsigned short valMarker, + unsigned short valSpan, + su2double valKine) { } + + /*! + * \brief A virtual member. + * \param[in] val_marker - bound marker. + * \return Value of the Average Omega on the surface val_marker. + */ + inline virtual void SetExtAverageOmega(unsigned short valMarker, + unsigned short valSpan, + su2double valOmega) { } + + /*! + * \brief A virtual member. + * \param[in] inMarkerTP - bound marker. + * \return Value of the inlet density. + */ + inline virtual su2double GetDensityIn(unsigned short inMarkerTP, unsigned short valSpan) const {return 0;} + + /*! + * \brief A virtual member. + * \param[in] inMarkerTP - bound marker. + * \return Value of inlet pressure. + */ + inline virtual su2double GetPressureIn(unsigned short inMarkerTP, unsigned short valSpan) const {return 0;} + + /*! + * \brief A virtual member. + * \param[in] inMarkerTP - bound marker. + * \return Value of the inlet normal velocity. + */ + inline virtual su2double* GetTurboVelocityIn(unsigned short inMarkerTP, unsigned short valSpan) const {return NULL;} + + /*! + * \brief A virtual member. + * \param[in] inMarkerTP - bound marker. + * \return Value of the outlet density. + */ + inline virtual su2double GetDensityOut(unsigned short inMarkerTP, unsigned short valSpan) const {return 0;} + + /*! + * \brief A virtual member. + * \param[in] inMarkerTP - bound marker. + * \return Value of the outlet pressure. + */ + inline virtual su2double GetPressureOut(unsigned short inMarkerTP, unsigned short valSpan) const {return 0;} + + /*! + * \brief A virtual member. + * \param[in] inMarkerTP - bound marker. + * \return Value of the outlet normal velocity. + */ + inline virtual su2double* GetTurboVelocityOut(unsigned short inMarkerTP, unsigned short valSpan) const {return NULL;} + + /*! + * \brief A virtual member. + * \param[in] inMarkerTP - bound marker. + * \return Value of the inlet density. + */ + inline virtual su2double GetKineIn(unsigned short inMarkerTP, unsigned short valSpan) const {return 0;} + + /*! + * \brief A virtual member. + * \param[in] inMarkerTP - bound marker. + * \return Value of the inlet density. + */ + inline virtual su2double GetOmegaIn(unsigned short inMarkerTP, unsigned short valSpan) const {return 0;} + + /*! + * \brief A virtual member. + * \param[in] inMarkerTP - bound marker. + * \return Value of the inlet density. + */ + inline virtual su2double GetNuIn(unsigned short inMarkerTP, unsigned short valSpan) const {return 0;} + + /*! + * \brief A virtual member. + * \param[in] inMarkerTP - bound marker. + * \return Value of the inlet density. + */ + inline virtual su2double GetKineOut(unsigned short inMarkerTP, unsigned short valSpan) const {return 0;} + + /*! + * \brief A virtual member. + * \param[in] inMarkerTP - bound marker. + * \return Value of the inlet density. + */ + inline virtual su2double GetOmegaOut(unsigned short inMarkerTP, unsigned short valSpan) const {return 0;} + + /*! + * \brief A virtual member. + * \param[in] inMarkerTP - bound marker. + * \return Value of the inlet density. + */ + inline virtual su2double GetNuOut(unsigned short inMarkerTP, unsigned short valSpan) const {return 0;} + + /*! + * \brief A virtual member. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline virtual void SetDensityIn(su2double value, + unsigned short inMarkerTP, + unsigned short valSpan) { } + + /*! + * \brief A virtual member. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline virtual void SetPressureIn(su2double value, + unsigned short inMarkerTP, + unsigned short valSpan) { } + + /*! + * \brief A virtual member. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline virtual void SetTurboVelocityIn(su2double *value, + unsigned short inMarkerTP, + unsigned short valSpan) { } + + /*! + * \brief A virtual member. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline virtual void SetDensityOut(su2double value, + unsigned short inMarkerTP, + unsigned short valSpan) { } + + /*! + * \brief A virtual member. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline virtual void SetPressureOut(su2double value, + unsigned short inMarkerTP, + unsigned short valSpan) { } + + /*! + * \brief A virtual member. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline virtual void SetTurboVelocityOut(su2double *value, + unsigned short inMarkerTP, + unsigned short valSpan) { } + + /*! + * \brief A virtual member. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline virtual void SetKineIn(su2double value, + unsigned short inMarkerTP, + unsigned short valSpan) { } + + /*! + * \brief A virtual member. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline virtual void SetOmegaIn(su2double value, + unsigned short inMarkerTP, + unsigned short valSpan) { } + + /*! + * \brief A virtual member. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline virtual void SetNuIn(su2double value, + unsigned short inMarkerTP, + unsigned short valSpan) { } + + /*! + * \brief A virtual member. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline virtual void SetKineOut(su2double value, + unsigned short inMarkerTP, + unsigned short valSpan) { } + + /*! + * \brief A virtual member. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline virtual void SetOmegaOut(su2double value, + unsigned short inMarkerTP, + unsigned short valSpan) { } + + /*! + * \brief A virtual member. + * \param[in] value - turboperformance value to set. + * \param[in] inMarkerTP - turboperformance marker. + */ + inline virtual void SetNuOut(su2double value, + unsigned short inMarkerTP, + unsigned short valSpan) { } + + /*! + * \brief A virtual member. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void SetFreeStream_TurboSolution(CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - current mesh level for the multigrid. + */ + inline virtual void SetBeta_Parameter(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void SetRoe_Dissipation(CGeometry *geometry, CConfig *config) {} + + /*! + * \brief A virtual member. + * \param[in] solver - Solver container + * \param[in] geometry - Geometrical definition. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void SetDES_LengthScale(CSolver** solver, + CGeometry *geometry, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition. + * \param[in] config - Definition of the particular problem. + * \param[in] referenceCoord - Determine if the mesh is deformed from the reference or from the current coordinates. + */ + inline virtual void DeformMesh(CGeometry **geometry, + CNumerics **numerics, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition. + * \param[in] config - Definition of the particular problem. + * \param[in] referenceCoord - Determine if the mesh is deformed from the reference or from the current coordinates. + */ + inline virtual void SetMesh_Stiffness(CGeometry **geometry, + CNumerics **numerics, + CConfig *config) { } + + /*! + * \brief Routine that sets the flag controlling implicit treatment for periodic BCs. + * \param[in] val_implicit_periodic - Flag controlling implicit treatment for periodic BCs. + */ + inline void SetImplicitPeriodic(bool val_implicit_periodic) { implicit_periodic = val_implicit_periodic; } + + /*! + * \brief Routine that sets the flag controlling solution rotation for periodic BCs. + * \param[in] val_implicit_periodic - Flag controlling solution rotation for periodic BCs. + */ + inline void SetRotatePeriodic(bool val_rotate_periodic) { rotate_periodic = val_rotate_periodic; } + + /*! + * \brief Retrieve the solver name for output purposes. + * \param[out] val_solvername - Name of the solver. + */ + inline string GetSolverName(void) {return SolverName;} + + /*! + * \brief Get the solution fields. + * \return A vector containing the solution fields. + */ + inline vector GetSolutionFields(){return fields;} + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void ComputeVerificationError(CGeometry *geometry, CConfig *config) { } + + /*! + * \brief Initialize the vertex traction containers at the vertices. + * \param[in] geometry - Geometrical definition. + * \param[in] config - Definition of the particular problem. + */ + inline void InitVertexTractionContainer(CGeometry *geometry, CConfig *config){ + + unsigned long iVertex; + unsigned short iMarker; + + VertexTraction = new su2double** [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + VertexTraction[iMarker] = new su2double* [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + VertexTraction[iMarker][iVertex] = new su2double [nDim](); + } + } + } + + /*! + * \brief Initialize the adjoint vertex traction containers at the vertices. + * \param[in] geometry - Geometrical definition. + * \param[in] config - Definition of the particular problem. + */ + inline void InitVertexTractionAdjointContainer(CGeometry *geometry, CConfig *config){ + + unsigned long iVertex; + unsigned short iMarker; + + VertexTractionAdjoint = new su2double** [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + VertexTractionAdjoint[iMarker] = new su2double* [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + VertexTractionAdjoint[iMarker][iVertex] = new su2double [nDim](); + } + } + } + + /*! + * \brief Compute the tractions at the vertices. + * \param[in] geometry - Geometrical definition. + * \param[in] config - Definition of the particular problem. + */ + void ComputeVertexTractions(CGeometry *geometry, CConfig *config); + + /*! + * \brief Set the adjoints of the vertex tractions. + * \param[in] iMarker - Index of the marker + * \param[in] iVertex - Index of the relevant vertex + * \param[in] iDim - Dimension + */ + inline su2double GetVertexTractions(unsigned short iMarker, unsigned long iVertex, unsigned short iDim) const { + return VertexTraction[iMarker][iVertex][iDim]; + } + + /*! + * \brief Register the vertex tractions as output. + * \param[in] geometry - Geometrical definition. + * \param[in] config - Definition of the particular problem. + */ + void RegisterVertexTractions(CGeometry *geometry, CConfig *config); + + /*! + * \brief Store the adjoints of the vertex tractions. + * \param[in] iMarker - Index of the marker + * \param[in] iVertex - Index of the relevant vertex + * \param[in] iDim - Dimension + * \param[in] val_adjoint - Value received for the adjoint (from another solver) + */ + inline void StoreVertexTractionsAdjoint(unsigned short iMarker, + unsigned long iVertex, + unsigned short iDim, + su2double val_adjoint){ + VertexTractionAdjoint[iMarker][iVertex][iDim] = val_adjoint; + } + + /*! + * \brief Set the adjoints of the vertex tractions to the AD structure. + * \param[in] geometry - Geometrical definition. + * \param[in] config - Definition of the particular problem. + */ + void SetVertexTractionsAdjoint(CGeometry *geometry, CConfig *config); + + /*! + * \brief Get minimun volume in the mesh + * \return + */ + virtual su2double GetMinimum_Volume() const { return 0.0; } + + /*! + * \brief Get maximum volume in the mesh + * \return + */ + virtual su2double GetMaximum_Volume() const { return 0.0; } + +protected: + /*! + * \brief Allocate the memory for the verification solution, if necessary. + * \param[in] nDim - Number of dimensions of the problem. + * \param[in] nVar - Number of variables of the problem. + * \param[in] config - Definition of the particular problem. + */ + void SetVerificationSolution(unsigned short nDim, + unsigned short nVar, + CConfig *config); +}; diff --git a/SU2_CFD/include/solvers/CTemplateSolver.hpp b/SU2_CFD/include/solvers/CTemplateSolver.hpp new file mode 100644 index 000000000000..bff4927a5a24 --- /dev/null +++ b/SU2_CFD/include/solvers/CTemplateSolver.hpp @@ -0,0 +1,298 @@ +/*! + * \file CTemplateSolver.hpp + * \brief Headers of the CTemplateSolver class + * \author F. Palacios + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#pragma once + +#include "CSolver.hpp" + +/*! + * \class CTemplateSolver + * \brief Main class for defining the template model solver. + * \ingroup Template_Flow_Equation + * \author F. Palacios + */ +class CTemplateSolver final : public CSolver { +private: + + CVariable* nodes = nullptr; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ + + /*! + * \brief Return nodes to allow CSolver::base_nodes to be set. + */ + inline CVariable* GetBaseClassPointerToNodes() override { return nodes; } + +public: + + /*! + * \brief Constructor of the class. + */ + CTemplateSolver(void); + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + CTemplateSolver(CGeometry *geometry, CConfig *config); + + /*! + * \brief Destructor of the class. + */ + ~CTemplateSolver(void); + + /*! + * \brief Compute the velocity^2, SoundSpeed, Pressure. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + * \param[in] Output - boolean to determine whether to print output. + */ + void Preprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep, + unsigned short RunTime_EqSystem, + bool Output) override; + + /*! + * \brief Compute the time step for solving the Euler equations. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] Iteration - Index of the current iteration. + */ + void SetTime_Step(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned long Iteration) override; + + /*! + * \brief Compute the spatial integration using a centered scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + void Centered_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep) override; + + /*! + * \brief Compute the spatial integration using a upwind scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Upwind_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh) override; + + /*! + * \brief Source term integration. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] second_numerics - Description of the second numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Source_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CNumerics *second_numerics, + CConfig *config, unsigned short iMesh) override; + + /*! + * \brief Source term integration. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Source_Template(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh) override; + + /*! + * \brief Impose via the residual the Euler wall boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Euler_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the Navier-Stokes boundary condition (strong). + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_HeatFlux_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + /*! + * \brief Impose the far-field boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Far_Field(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the inlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Inlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + /*! + * \brief Impose the outlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Outlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + /*! + * \brief Impose the symmetry plane boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Sym_Plane(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose a custom or verification boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the convective numerical method. + * \param[in] visc_numerics - Description of the viscous numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Custom(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Update the solution using a Runge-Kutta scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + void ExplicitRK_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iRKStep) override; + + /*! + * \brief Update the solution using a explicit Euler scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void ExplicitEuler_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) override; + + /*! + * \brief Update the solution using an implicit solver. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void ImplicitEuler_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) override; + +}; \ No newline at end of file diff --git a/SU2_CFD/include/solvers/CTransLMSolver.hpp b/SU2_CFD/include/solvers/CTransLMSolver.hpp new file mode 100644 index 000000000000..158e0036ef5c --- /dev/null +++ b/SU2_CFD/include/solvers/CTransLMSolver.hpp @@ -0,0 +1,249 @@ +/*! + * \file CTransLMSolver.hpp + * \brief Headers of the CTransLMSolver class + * \author A. Aranake + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#pragma once + +#include "CTurbSolver.hpp" + +/*! + * \class CTransLMSolver + * \brief Main class for defining the turbulence model solver. + * \ingroup Turbulence_Model + * \author A. Aranake. + */ + +class CTransLMSolver final : public CTurbSolver { +private: + su2double Intermittency_Inf, REth_Inf; +public: + /*! + * \brief Constructor of the class. + */ + CTransLMSolver(void); + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); + + /*! + * \brief Destructor of the class. + */ + ~CTransLMSolver(void); + + /*! + * \brief Restart residual and compute gradients. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + * \param[in] Output - boolean to determine whether to print output. + */ + void Preprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep, + unsigned short RunTime_EqSystem, + bool Output) override; + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Postprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh) override; + + /*! + * \brief Compute the spatial integration using a upwind scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Upwind_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh) override; + + /*! + * \brief Compute the viscous residuals for the turbulent equation. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + void Viscous_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep) override; + + /*! + * \brief Source term computation. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] second_numerics - Description of the second numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Source_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CNumerics *second_numerics, + CConfig *config, unsigned short iMesh) override; + + /*! + * \brief Source term computation. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Source_Template(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh) override; + + /*! + * \brief Impose the Navier-Stokes wall boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_HeatFlux_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the Far Field boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Far_Field(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the inlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Inlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the outlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Outlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the symmetry condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Sym_Plane(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Update the solution using an implicit solver. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void ImplicitEuler_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) override; + + // Another set of matrix structures for the Lm equations + CSysMatrix JacobianItmc; /*!< \brief Complete sparse Jacobian structure for implicit computations. */ + su2double *LinSysSolItmc; /*!< \brief vector to store iterative solution of implicit linear system. */ + su2double *LinSysResItmc; /*!< \brief vector to store iterative residual of implicit linear system. */ + su2double *rhsItmc; /*!< \brief right hand side of implicit linear system. */ + CSysMatrix JacobianReth; /*!< \brief Complete sparse Jacobian structure for implicit computations. */ + su2double *LinSysSolReth; /*!< \brief vector to store iterative solution of implicit linear system. */ + su2double *LinSysResReth; /*!< \brief vector to store iterative residual of implicit linear system. */ + su2double *rhsReth; /*!< \brief right hand side of implicit linear system. */ +}; \ No newline at end of file diff --git a/SU2_CFD/include/solvers/CTurbSASolver.hpp b/SU2_CFD/include/solvers/CTurbSASolver.hpp new file mode 100644 index 000000000000..9b16dd487ecb --- /dev/null +++ b/SU2_CFD/include/solvers/CTurbSASolver.hpp @@ -0,0 +1,434 @@ +/*! + * \file CTurbSASolver.hpp + * \brief Headers of the CTurbSASolver class + * \author A. Bueno. + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + + +#pragma once + +#include "CTurbSolver.hpp" + +/*! + * \class CTurbSASolver + * \brief Main class for defining the turbulence model solver. + * \ingroup Turbulence_Model + * \author A. Bueno. + */ + +class CTurbSASolver final : public CTurbSolver { +private: + su2double nu_tilde_Inf, nu_tilde_Engine, nu_tilde_ActDisk; + +public: + /*! + * \brief Constructor of the class. + */ + CTurbSASolver(void); + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] FluidModel + */ + CTurbSASolver(CGeometry *geometry, CConfig *config, unsigned short iMesh, CFluidModel* FluidModel); + + /*! + * \brief Destructor of the class. + */ + ~CTurbSASolver(void); + + /*! + * \brief Restart residual and compute gradients. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + * \param[in] Output - boolean to determine whether to print output. + */ + void Preprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep, + unsigned short RunTime_EqSystem, + bool Output) override; + + /*! + * \brief A virtual member. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void Postprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh) override; + /*! + * \brief Source term computation. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] second_numerics - Description of the second numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Source_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CNumerics *second_numerics, + CConfig *config, unsigned short iMesh) override; + + /*! + * \brief Source term computation. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Source_Template(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh) override; + + /*! + * \brief Impose the Navier-Stokes wall boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_HeatFlux_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the Navier-Stokes wall boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Isothermal_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the Far Field boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Far_Field(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the inlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Inlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the inlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Inlet_Turbo(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the inlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Inlet_MixingPlane(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the outlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Outlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the engine inflow boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Engine_Inflow(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the engine exhaust boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Engine_Exhaust(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the interface boundary condition using the residual. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Interface_Boundary(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the fluid interface boundary condition using tranfer data. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + void BC_Fluid_Interface(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config) override; + + /*! + * \brief Impose the near-field boundary condition using the residual. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_NearField_Boundary(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose an actuator disk inlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_ActDisk_Inlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose an actuator disk outlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_ActDisk_Outlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose an actuator disk inlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + * \param[in] val_inlet_surface - Boolean for whether val_marker is an inlet + */ + void BC_ActDisk(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker, + bool val_inlet_surface) override; + + /*! + * \brief Set the solution using the Freestream values. + * \param[in] config - Definition of the particular problem. + */ + inline void SetFreeStream_Solution(CConfig *config) override { + for (unsigned long iPoint = 0; iPoint < nPoint; iPoint++) nodes->SetSolution(iPoint, 0, nu_tilde_Inf); + } + + + /*! + * \brief A virtual member. + * \param[in] solver - Solver container + * \param[in] geometry - Geometrical definition. + * \param[in] config - Definition of the particular problem. + */ + void SetDES_LengthScale(CSolver** solver, + CGeometry *geometry, + CConfig *config) override; + + /*! + * \brief Store of a set of provided inlet profile values at a vertex. + * \param[in] val_inlet - vector containing the inlet values for the current vertex. + * \param[in] iMarker - Surface marker where the coefficient is computed. + * \param[in] iVertex - Vertex of the marker iMarker where the inlet is being set. + */ + void SetInletAtVertex(su2double *val_inlet, + unsigned short iMarker, + unsigned long iVertex) override; + + /*! + * \brief Get the set of value imposed at an inlet. + * \param[in] val_inlet - vector returning the inlet values for the current vertex. + * \param[in] val_inlet_point - Node index where the inlet is being set. + * \param[in] val_kind_marker - Enumerated type for the particular inlet type. + * \param[in] geometry - Geometrical definition of the problem. + * \param config - Definition of the particular problem. + * \return Value of the face area at the vertex. + */ + su2double GetInletAtVertex(su2double *val_inlet, + unsigned long val_inlet_point, + unsigned short val_kind_marker, + string val_marker, + CGeometry *geometry, + CConfig *config) const override; + + /*! + * \brief Set a uniform inlet profile + * + * The values at the inlet are set to match the values specified for + * inlets in the configuration file. + * + * \param[in] config - Definition of the particular problem. + * \param[in] iMarker - Surface marker where the coefficient is computed. + */ + void SetUniformInlet(CConfig* config, unsigned short iMarker) override; + + /*! + * \brief Get the value of nu tilde at the far-field. + * \return Value of nu tilde at the far-field. + */ + inline su2double GetNuTilde_Inf(void) const override { return nu_tilde_Inf; } + + /*! + * \brief Compute nu tilde from the wall functions. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void SetNuTilde_WF(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; +}; \ No newline at end of file diff --git a/SU2_CFD/include/solvers/CTurbSSTSolver.hpp b/SU2_CFD/include/solvers/CTurbSSTSolver.hpp new file mode 100644 index 000000000000..0dc6391acd15 --- /dev/null +++ b/SU2_CFD/include/solvers/CTurbSSTSolver.hpp @@ -0,0 +1,312 @@ +/*! + * \file CTurbSSTSolver.hpp + * \brief Headers of the CTurbSSTSolver class + * \author A. Campos, F. Palacios, T. Economon + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#pragma once + +#include "CTurbSolver.hpp" + +/*! + * \class CTurbSSTSolver + * \brief Main class for defining the turbulence model solver. + * \ingroup Turbulence_Model + * \author A. Campos, F. Palacios, T. Economon + */ + +class CTurbSSTSolver final : public CTurbSolver { +private: + su2double *constants, /*!< \brief Constants for the model. */ + kine_Inf, /*!< \brief Free-stream turbulent kinetic energy. */ + omega_Inf; /*!< \brief Free-stream specific dissipation. */ + +public: + /*! + * \brief Constructor of the class. + */ + CTurbSSTSolver(void); + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + CTurbSSTSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); + + /*! + * \brief Destructor of the class. + */ + ~CTurbSSTSolver(void); + + /*! + * \brief Restart residual and compute gradients. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + * \param[in] Output - boolean to determine whether to print output. + */ + void Preprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep, + unsigned short RunTime_EqSystem, + bool Output) override; + + /*! + * \brief Computes the eddy viscosity. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Postprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh) override; + + /*! + * \brief Source term computation. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] second_numerics - Description of the second numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Source_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CNumerics *second_numerics, + CConfig *config, unsigned short iMesh) override; + + /*! + * \brief Source term computation. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Source_Template(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh) override; + + /*! + * \brief Impose the Navier-Stokes wall boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_HeatFlux_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + /*! + * \brief Impose the Navier-Stokes wall boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Isothermal_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the Far Field boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Far_Field(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the inlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Inlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the inlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Inlet_Turbo(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the inlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Inlet_MixingPlane(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + /*! + * \brief Impose the outlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Outlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + /*! + * \brief Impose the interface state across sliding meshes. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + void BC_Fluid_Interface(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config) override; + + /*! + * \brief Get the constants for the SST model. + * \return A pointer to an array containing a set of constants + */ + inline su2double* GetConstants() const override { return constants; } + + /*! + * \brief Set the solution using the Freestream values. + * \param[in] config - Definition of the particular problem. + */ + inline void SetFreeStream_Solution(CConfig *config) override { + for (unsigned long iPoint = 0; iPoint < nPoint; iPoint++){ + nodes->SetSolution(iPoint, 0, kine_Inf); + nodes->SetSolution(iPoint, 1, omega_Inf); + } + } + + + /*! + * \brief Store of a set of provided inlet profile values at a vertex. + * \param[in] val_inlet - vector containing the inlet values for the current vertex. + * \param[in] iMarker - Surface marker where the coefficient is computed. + * \param[in] iVertex - Vertex of the marker iMarker where the inlet is being set. + */ + void SetInletAtVertex(su2double *val_inlet, + unsigned short iMarker, + unsigned long iVertex) override; + + /*! + * \brief Get the set of value imposed at an inlet. + * \param[in] val_inlet - vector returning the inlet values for the current vertex. + * \param[in] val_inlet_point - Node index where the inlet is being set. + * \param[in] val_kind_marker - Enumerated type for the particular inlet type. + * \param[in] geometry - Geometrical definition of the problem. + * \param config - Definition of the particular problem. + * \return Value of the face area at the vertex. + */ + su2double GetInletAtVertex(su2double *val_inlet, + unsigned long val_inlet_point, + unsigned short val_kind_marker, + string val_marker, + CGeometry *geometry, + CConfig *config) const override; + /*! + * \brief Set a uniform inlet profile + * + * The values at the inlet are set to match the values specified for + * inlets in the configuration file. + * + * \param[in] config - Definition of the particular problem. + * \param[in] iMarker - Surface marker where the coefficient is computed. + */ + void SetUniformInlet(CConfig* config, unsigned short iMarker) override; + + /*! + * \brief Get the value of the turbulent kinetic energy. + * \return Value of the turbulent kinetic energy. + */ + inline su2double GetTke_Inf(void) const override { return kine_Inf; } + + /*! + * \brief Get the value of the turbulent frequency. + * \return Value of the turbulent frequency. + */ + inline su2double GetOmega_Inf(void) const override { return omega_Inf; } + +}; \ No newline at end of file diff --git a/SU2_CFD/include/solvers/CTurbSolver.hpp b/SU2_CFD/include/solvers/CTurbSolver.hpp new file mode 100644 index 000000000000..417f1ef382ae --- /dev/null +++ b/SU2_CFD/include/solvers/CTurbSolver.hpp @@ -0,0 +1,340 @@ +/*! + * \file CTurbSolver.hpp + * \brief Headers of the CTurbSolver class + * \author A. Bueno. + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#pragma once + +#include "CSolver.hpp" +#include "../variables/CTurbVariable.hpp" + +/*! + * \class CTurbSolver + * \brief Main class for defining the turbulence model solver. + * \ingroup Turbulence_Model + * \author A. Bueno. + */ +class CTurbSolver : public CSolver { +protected: + su2double *FlowPrimVar_i, /*!< \brief Store the flow solution at point i. */ + *FlowPrimVar_j, /*!< \brief Store the flow solution at point j. */ + *lowerlimit, /*!< \brief contains lower limits for turbulence variables. */ + *upperlimit; /*!< \brief contains upper limits for turbulence variables. */ + su2double Gamma; /*!< \brief Fluid's Gamma constant (ratio of specific heats). */ + su2double Gamma_Minus_One; /*!< \brief Fluids's Gamma - 1.0 . */ + su2double*** Inlet_TurbVars; /*!< \brief Turbulence variables at inlet profiles */ + + CTurbVariable* snode; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ + + /* Sliding meshes variables */ + + su2double ****SlidingState; + int **SlidingStateNodes; + + CTurbVariable* nodes = nullptr; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ + + /*! + * \brief Return nodes to allow CSolver::base_nodes to be set. + */ + inline CVariable* GetBaseClassPointerToNodes() final { return nodes; } + +public: + + /*! + * \brief Constructor of the class. + */ + CTurbSolver(void); + + /*! + * \brief Destructor of the class. + */ + virtual ~CTurbSolver(void); + + /*! + * \brief Constructor of the class. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + CTurbSolver(CGeometry* geometry, CConfig *config); + + /*! + * \brief Compute the spatial integration using a upwind scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + + void Upwind_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh) override; + + /*! + * \brief Compute the viscous residuals for the turbulent equation. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + void Viscous_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep) override; + + /*! + * \brief Impose the Symmetry Plane boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Sym_Plane(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose via the residual the Euler wall boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Euler_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + /*! + * \brief Impose via the residual the Euler wall boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Riemann(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose via the residual the Euler wall boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_TurboRiemann(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose via the residual the Euler wall boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Giles(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) final; + + /*! + * \brief Impose a periodic boundary condition by summing contributions from the complete control volume. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + void BC_Periodic(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config) final; + + /*! + * \brief Update the solution using an implicit solver. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void ImplicitEuler_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) override; + /*! + * \brief Set the total residual adding the term that comes from the Dual Time-Stepping Strategy. + * \param[in] geometry - Geometric definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + */ + void SetResidual_DualTime(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iRKStep, + unsigned short iMesh, + unsigned short RunTime_EqSystem) final; + + /*! + * \brief Compute a suitable under-relaxation parameter to limit the change in the solution variables over a nonlinear iteration for stability. + * \param[in] solver - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void ComputeUnderRelaxationFactor(CSolver **solver, CConfig *config) final; + + /*! + * \brief Load a solution from a restart file. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Container vector with all of the solvers. + * \param[in] config - Definition of the particular problem. + * \param[in] val_iter - Current external iteration number. + * \param[in] val_update_geo - Flag for updating coords and grid velocity. + */ + void LoadRestart(CGeometry **geometry, + CSolver ***solver, + CConfig *config, + int val_iter, + bool val_update_geo) final; + + /*! + * \brief Get the outer state for fluid interface nodes. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + * \param[in] val_state - requested state component + * \param[in] donor_index- index of the donor node to get + */ + inline su2double GetSlidingState(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_state, + unsigned long donor_index) const final { + return SlidingState[val_marker][val_vertex][val_state][donor_index]; + } + + /*! + * \brief Allocates the final pointer of SlidingState depending on how many donor vertex donate to it. That number is stored in SlidingStateNodes[val_marker][val_vertex]. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + */ + inline void SetSlidingStateStructure(unsigned short val_marker, unsigned long val_vertex) final { + int iVar; + + for( iVar = 0; iVar < nVar+1; iVar++){ + if( SlidingState[val_marker][val_vertex][iVar] != NULL ) + delete [] SlidingState[val_marker][val_vertex][iVar]; + } + + for( iVar = 0; iVar < nVar+1; iVar++) + SlidingState[val_marker][val_vertex][iVar] = new su2double[ GetnSlidingStates(val_marker, val_vertex) ]; + } + + + /*! + * \brief Set the outer state for fluid interface nodes. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + * \param[in] val_state - requested state component + * \param[in] donor_index - index of the donor node to set + * \param[in] component - set value + */ + inline void SetSlidingState(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_state, + unsigned long donor_index, + su2double component) final { + SlidingState[val_marker][val_vertex][val_state][donor_index] = component; + } + + + /*! + * \brief Set the number of outer state for fluid interface nodes. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + * \param[in] value - number of outer states + */ + inline void SetnSlidingStates(unsigned short val_marker, + unsigned long val_vertex, + int value) final { SlidingStateNodes[val_marker][val_vertex] = value; } + + /*! + * \brief Get the number of outer state for fluid interface nodes. + * \param[in] val_marker - marker index + * \param[in] val_vertex - vertex index + */ + inline int GetnSlidingStates(unsigned short val_marker, unsigned long val_vertex) const final { + return SlidingStateNodes[val_marker][val_vertex]; + } + + /*! + * \brief Set custom turbulence variables at the vertex of an inlet. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \param[in] iDim - Index of the turbulence variable (i.e. k is 0 in SST) + * \param[in] val_turb_var - Value of the turbulence variable to be used. + */ + inline void SetInlet_TurbVar(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_dim, + su2double val_turb_var) final { + /*--- Since this call can be accessed indirectly using python, do some error + * checking to prevent segmentation faults ---*/ + if (val_marker >= nMarker) + SU2_MPI::Error("Out-of-bounds marker index used on inlet.", CURRENT_FUNCTION); + else if (Inlet_TurbVars == NULL || Inlet_TurbVars[val_marker] == NULL) + SU2_MPI::Error("Tried to set custom inlet BC on an invalid marker.", CURRENT_FUNCTION); + else if (val_vertex >= nVertex[val_marker]) + SU2_MPI::Error("Out-of-bounds vertex index used on inlet.", CURRENT_FUNCTION); + else if (val_dim >= nVar) + SU2_MPI::Error("Out-of-bounds index used for inlet turbulence variable.", CURRENT_FUNCTION); + else + Inlet_TurbVars[val_marker][val_vertex][val_dim] = val_turb_var; + } + +}; \ No newline at end of file diff --git a/SU2_CFD/include/transport_model.inl b/SU2_CFD/include/transport_model.inl index e93a7351d8d2..adf4b2f63876 100644 --- a/SU2_CFD/include/transport_model.inl +++ b/SU2_CFD/include/transport_model.inl @@ -1,6 +1,6 @@ /*! * \file transport_model.inl - * \brief In-Line subroutines of the solver_structure.hpp file. + * \brief In-Line subroutines of the transport_model.hpp file. * \author S. Vitale, M. Pini, G. Gori, A. Guardone, P. Colonna * \version 7.0.0 "Blackbird" * diff --git a/SU2_CFD/include/variables/CMeshElement.hpp b/SU2_CFD/include/variables/CMeshElement.hpp index ff725c328446..fa090a7c2fbb 100644 --- a/SU2_CFD/include/variables/CMeshElement.hpp +++ b/SU2_CFD/include/variables/CMeshElement.hpp @@ -28,10 +28,6 @@ #pragma once -#include "../../../Common/include/mpi_structure.hpp" - -#include -#include #include #include "../../../Common/include/config_structure.hpp" diff --git a/SU2_CFD/obj/Makefile.am b/SU2_CFD/obj/Makefile.am index ebbd95221017..d5b16380a082 100644 --- a/SU2_CFD/obj/Makefile.am +++ b/SU2_CFD/obj/Makefile.am @@ -95,6 +95,7 @@ libSU2Core_sources = ../src/definition_structure.cpp \ ../src/output/filewriter/CSU2MeshFileWriter.cpp \ ../src/output/filewriter/CTecplotFileWriter.cpp \ ../src/output/filewriter/CTecplotBinaryFileWriter.cpp \ + ../src/output/tools/CWindowingTools.cpp \ ../src/output/COutput.cpp \ ../src/output/output_physics.cpp \ ../src/output/CMeshOutput.cpp \ @@ -112,21 +113,29 @@ libSU2Core_sources = ../src/definition_structure.cpp \ ../src/output/CMultizoneOutput.cpp \ ../src/output/output_structure_legacy.cpp \ ../src/python_wrapper_structure.cpp \ - ../src/solver_adjoint_mean.cpp \ - ../src/solver_adjoint_turbulent.cpp \ - ../src/solver_adjoint_discrete.cpp \ - ../src/solver_adjoint_elasticity.cpp \ + ../src/solvers/CAdjEulerSolver.cpp \ + ../src/solvers/CAdjNSSolver.cpp \ + ../src/solvers/CAdjTurbSolver.cpp \ + ../src/solvers/CBaselineSolver.cpp \ + ../src/solvers/CBaselineSolver_FEM.cpp \ + ../src/solvers/CDiscAdjFEASolver.cpp \ ../src/solvers/CDiscAdjMeshSolver.cpp \ - ../src/solver_direct_heat.cpp \ - ../src/solver_direct_mean.cpp \ - ../src/solver_direct_mean_fem.cpp \ - ../src/solver_direct_mean_inc.cpp \ - ../src/solver_direct_transition.cpp \ - ../src/solver_direct_turbulent.cpp \ - ../src/solvers/CMeshSolver.cpp \ + ../src/solvers/CDiscAdjSolver.cpp \ + ../src/solvers/CEulerSolver.cpp \ ../src/solvers/CFEASolver.cpp \ - ../src/solver_structure.cpp \ - ../src/solver_template.cpp \ + ../src/solvers/CFEM_DG_EulerSolver.cpp \ + ../src/solvers/CFEM_DG_NSSolver.cpp \ + ../src/solvers/CHeatSolverFVM.cpp \ + ../src/solvers/CIncEulerSolver.cpp \ + ../src/solvers/CIncNSSolver.cpp \ + ../src/solvers/CMeshSolver.cpp \ + ../src/solvers/CNSSolver.cpp \ + ../src/solvers/CSolver.cpp \ + ../src/solvers/CTemplateSolver.cpp \ + ../src/solvers/CTransLMSolver.cpp \ + ../src/solvers/CTurbSolver.cpp \ + ../src/solvers/CTurbSASolver.cpp \ + ../src/solvers/CTurbSSTSolver.cpp \ ../src/CMarkerProfileReaderFVM.cpp \ ../src/interfaces/CInterface.cpp \ ../src/interfaces/cfd/CConservativeVarsInterface.cpp \ diff --git a/SU2_CFD/src/SU2_CFD.cpp b/SU2_CFD/src/SU2_CFD.cpp index 89e1acc58a44..77ab6e560d03 100644 --- a/SU2_CFD/src/SU2_CFD.cpp +++ b/SU2_CFD/src/SU2_CFD.cpp @@ -43,6 +43,7 @@ int main(int argc, char *argv[]) { char config_file_name[MAX_STRING_SIZE]; bool dry_run = false; int num_threads = omp_get_max_threads(); + bool use_thread_mult = false; std::string filename = "default.cfg"; /*--- Command line parsing ---*/ @@ -51,6 +52,7 @@ int main(int argc, char *argv[]) { app.add_flag("-d,--dryrun", dry_run, "Enable dry run mode.\n" "Only execute preprocessing steps using a dummy geometry."); app.add_option("-t,--threads", num_threads, "Number of OpenMP threads per MPI rank."); + app.add_flag("--thread_multiple", use_thread_mult, "Request MPI_THREAD_MULTIPLE thread support."); app.add_option("configfile", filename, "A config file.")->check(CLI::ExistingFile); CLI11_PARSE(app, argc, argv) @@ -64,7 +66,10 @@ int main(int argc, char *argv[]) { char *buffptr; #ifdef HAVE_OMP int provided; - SU2_MPI::Init_thread(&argc, &argv, MPI_THREAD_FUNNELED, &provided); + if (use_thread_mult) + SU2_MPI::Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided); + else + SU2_MPI::Init_thread(&argc, &argv, MPI_THREAD_FUNNELED, &provided); #else SU2_MPI::Init(&argc, &argv); #endif diff --git a/SU2_CFD/src/drivers/CDriver.cpp b/SU2_CFD/src/drivers/CDriver.cpp index 98b54a255651..7ab36cc82283 100644 --- a/SU2_CFD/src/drivers/CDriver.cpp +++ b/SU2_CFD/src/drivers/CDriver.cpp @@ -41,6 +41,24 @@ #include "../../../Common/include/omp_structure.hpp" +#include "../../include/solvers/CEulerSolver.hpp" +#include "../../include/solvers/CIncEulerSolver.hpp" +#include "../../include/solvers/CNSSolver.hpp" +#include "../../include/solvers/CIncNSSolver.hpp" +#include "../../include/solvers/CTurbSASolver.hpp" +#include "../../include/solvers/CTurbSSTSolver.hpp" +#include "../../include/solvers/CTransLMSolver.hpp" +#include "../../include/solvers/CAdjEulerSolver.hpp" +#include "../../include/solvers/CAdjNSSolver.hpp" +#include "../../include/solvers/CAdjTurbSolver.hpp" +#include "../../include/solvers/CHeatSolverFVM.hpp" +#include "../../include/solvers/CFEASolver.hpp" +#include "../../include/solvers/CTemplateSolver.hpp" +#include "../../include/solvers/CDiscAdjSolver.hpp" +#include "../../include/solvers/CDiscAdjFEASolver.hpp" +#include "../../include/solvers/CFEM_DG_EulerSolver.hpp" +#include "../../include/solvers/CFEM_DG_NSSolver.hpp" + #include #ifdef VTUNEPROF diff --git a/SU2_CFD/src/integration_structure.cpp b/SU2_CFD/src/integration_structure.cpp index 5c26ef7ea3f7..454e84ff25f9 100644 --- a/SU2_CFD/src/integration_structure.cpp +++ b/SU2_CFD/src/integration_structure.cpp @@ -153,9 +153,6 @@ void CIntegration::Space_Integration(CGeometry *geometry, case DIELEC_BOUNDARY: solver_container[MainSolver]->BC_Dielec(geometry, solver_container, numerics[CONV_BOUND_TERM], config, iMarker); break; - case NEUMANN: - solver_container[MainSolver]->BC_Neumann(geometry, solver_container, numerics[CONV_BOUND_TERM], config, iMarker); - break; } } @@ -169,9 +166,6 @@ void CIntegration::Space_Integration(CGeometry *geometry, case HEAT_FLUX: solver_container[MainSolver]->BC_HeatFlux_Wall(geometry, solver_container, numerics[CONV_BOUND_TERM], numerics[VISC_BOUND_TERM], config, iMarker); break; - case DIRICHLET: - solver_container[MainSolver]->BC_Dirichlet(geometry, solver_container, config, iMarker); - break; case CUSTOM_BOUNDARY: solver_container[MainSolver]->BC_Custom(geometry, solver_container, numerics[CONV_BOUND_TERM], numerics[VISC_BOUND_TERM], config, iMarker); break; diff --git a/SU2_CFD/src/interfaces/cht/CConjugateHeatInterface.cpp b/SU2_CFD/src/interfaces/cht/CConjugateHeatInterface.cpp index 835ad3dcef25..0c0711cc80a7 100644 --- a/SU2_CFD/src/interfaces/cht/CConjugateHeatInterface.cpp +++ b/SU2_CFD/src/interfaces/cht/CConjugateHeatInterface.cpp @@ -60,8 +60,8 @@ void CConjugateHeatInterface::GetDonor_Variable(CSolver *donor_solution, CGeomet bool incompressible_flow = ((donor_config->GetKind_Solver() == INC_NAVIER_STOKES) || (donor_config->GetKind_Solver() == INC_RANS) || (donor_config->GetKind_Solver() == DISC_ADJ_INC_NAVIER_STOKES) - || (donor_config->GetKind_Solver() == DISC_ADJ_INC_RANS) - && (donor_config->GetEnergy_Equation())); + || (donor_config->GetKind_Solver() == DISC_ADJ_INC_RANS)) + && (donor_config->GetEnergy_Equation()); bool heat_equation = (donor_config->GetKind_Solver() == HEAT_EQUATION_FVM || donor_config->GetKind_Solver() == DISC_ADJ_HEAT); diff --git a/SU2_CFD/src/meson.build b/SU2_CFD/src/meson.build index a6ce318a4960..9b4a97977684 100644 --- a/SU2_CFD/src/meson.build +++ b/SU2_CFD/src/meson.build @@ -1,35 +1,23 @@ -su2_cfd_src = files(['solver_direct_transition.cpp', - 'solver_adjoint_turbulent.cpp', - 'integration_structure.cpp', - 'solver_direct_mean_fem.cpp', +su2_cfd_src = files(['integration_structure.cpp', 'numerics_adjoint_mean.cpp', 'transport_model.cpp', 'numerics_adjoint_turbulent.cpp', 'fluid_model_pvdw.cpp', 'integration_time.cpp', 'fluid_model_pig.cpp', - 'solver_direct_mean.cpp', 'iteration_structure.cpp', 'fluid_model_inc.cpp', - 'solver_adjoint_mean.cpp', - 'solver_adjoint_elasticity.cpp', - 'solver_structure.cpp', 'numerics_direct_turbulent.cpp', 'numerics_direct_transition.cpp', - 'solver_template.cpp', 'definition_structure.cpp', 'numerics_direct_mean_inc.cpp', - 'solver_direct_turbulent.cpp', 'fluid_model.cpp', - 'solver_direct_mean_inc.cpp', 'numerics_direct_mean.cpp', - 'solver_direct_heat.cpp', 'numerics_direct_heat.cpp', 'fluid_model_ppr.cpp', 'python_wrapper_structure.cpp', 'numerics_structure.cpp', 'numerics_template.cpp', - 'solver_adjoint_discrete.cpp', 'CMarkerProfileReaderFVM.cpp', 'SU2_CFD.cpp']) @@ -90,9 +78,29 @@ su2_cfd_src += files(['variables/CIncNSVariable.cpp', 'variables/CIncEulerVariable.cpp', 'variables/CEulerVariable.cpp']) -su2_cfd_src += files(['solvers/CMeshSolver.cpp', +su2_cfd_src += files(['solvers/CAdjEulerSolver.cpp', + 'solvers/CAdjNSSolver.cpp', + 'solvers/CAdjTurbSolver.cpp', + 'solvers/CBaselineSolver.cpp', + 'solvers/CBaselineSolver_FEM.cpp', + 'solvers/CDiscAdjFEASolver.cpp', 'solvers/CDiscAdjMeshSolver.cpp', - 'solvers/CFEASolver.cpp']) + 'solvers/CDiscAdjSolver.cpp', + 'solvers/CEulerSolver.cpp', + 'solvers/CFEASolver.cpp', + 'solvers/CFEM_DG_EulerSolver.cpp', + 'solvers/CFEM_DG_NSSolver.cpp', + 'solvers/CHeatSolverFVM.cpp', + 'solvers/CIncEulerSolver.cpp', + 'solvers/CIncNSSolver.cpp', + 'solvers/CMeshSolver.cpp', + 'solvers/CNSSolver.cpp', + 'solvers/CSolver.cpp', + 'solvers/CTemplateSolver.cpp', + 'solvers/CTransLMSolver.cpp', + 'solvers/CTurbSolver.cpp', + 'solvers/CTurbSASolver.cpp', + 'solvers/CTurbSSTSolver.cpp']) su2_cfd_src += files(['numerics/elasticity/CFEAElasticity.cpp', 'numerics/elasticity/CFEALinearElasticity.cpp', diff --git a/SU2_CFD/src/output/CAdjElasticityOutput.cpp b/SU2_CFD/src/output/CAdjElasticityOutput.cpp index 8e47cce60af0..c0fca696230b 100644 --- a/SU2_CFD/src/output/CAdjElasticityOutput.cpp +++ b/SU2_CFD/src/output/CAdjElasticityOutput.cpp @@ -29,7 +29,7 @@ #include "../../include/output/CAdjElasticityOutput.hpp" #include "../../../Common/include/geometry/CGeometry.hpp" -#include "../../include/solver_structure.hpp" +#include "../../include/solvers/CSolver.hpp" CAdjElasticityOutput::CAdjElasticityOutput(CConfig *config, unsigned short nDim) : COutput(config, nDim, false) { diff --git a/SU2_CFD/src/output/CAdjFlowCompOutput.cpp b/SU2_CFD/src/output/CAdjFlowCompOutput.cpp index 526416815a14..41dba829ba3a 100644 --- a/SU2_CFD/src/output/CAdjFlowCompOutput.cpp +++ b/SU2_CFD/src/output/CAdjFlowCompOutput.cpp @@ -29,7 +29,7 @@ #include "../../include/output/CAdjFlowOutput.hpp" #include "../../../Common/include/geometry/CGeometry.hpp" -#include "../../include/solver_structure.hpp" +#include "../../include/solvers/CSolver.hpp" CAdjFlowCompOutput::CAdjFlowCompOutput(CConfig *config, unsigned short nDim) : COutput(config, nDim, false) { diff --git a/SU2_CFD/src/output/CAdjFlowIncOutput.cpp b/SU2_CFD/src/output/CAdjFlowIncOutput.cpp index c10140927ac9..9def95f12849 100644 --- a/SU2_CFD/src/output/CAdjFlowIncOutput.cpp +++ b/SU2_CFD/src/output/CAdjFlowIncOutput.cpp @@ -29,7 +29,7 @@ #include "../../include/output/CAdjFlowIncOutput.hpp" #include "../../../Common/include/geometry/CGeometry.hpp" -#include "../../include/solver_structure.hpp" +#include "../../include/solvers/CSolver.hpp" CAdjFlowIncOutput::CAdjFlowIncOutput(CConfig *config, unsigned short nDim) : COutput(config, nDim, false) { diff --git a/SU2_CFD/src/output/CAdjHeatOutput.cpp b/SU2_CFD/src/output/CAdjHeatOutput.cpp index 2fc086d09643..5a8bbdaf50ed 100644 --- a/SU2_CFD/src/output/CAdjHeatOutput.cpp +++ b/SU2_CFD/src/output/CAdjHeatOutput.cpp @@ -29,7 +29,7 @@ #include "../../include/output/CAdjHeatOutput.hpp" #include "../../../Common/include/geometry/CGeometry.hpp" -#include "../../include/solver_structure.hpp" +#include "../../include/solvers/CSolver.hpp" CAdjHeatOutput::CAdjHeatOutput(CConfig *config, unsigned short nDim) : COutput(config, nDim, false) { diff --git a/SU2_CFD/src/output/CBaselineOutput.cpp b/SU2_CFD/src/output/CBaselineOutput.cpp index 7a8fde8e5ba7..fa0ed9b56c67 100644 --- a/SU2_CFD/src/output/CBaselineOutput.cpp +++ b/SU2_CFD/src/output/CBaselineOutput.cpp @@ -30,7 +30,7 @@ #include "../../include/output/CBaselineOutput.hpp" #include "../../../Common/include/geometry/CGeometry.hpp" -#include "../../include/solver_structure.hpp" +#include "../../include/solvers/CSolver.hpp" CBaselineOutput::CBaselineOutput(CConfig *config, unsigned short nDim, CSolver* solver) : COutput(config, nDim, false) { diff --git a/SU2_CFD/src/output/CElasticityOutput.cpp b/SU2_CFD/src/output/CElasticityOutput.cpp index d8c5db7b9956..876dec140790 100644 --- a/SU2_CFD/src/output/CElasticityOutput.cpp +++ b/SU2_CFD/src/output/CElasticityOutput.cpp @@ -29,7 +29,7 @@ #include "../../include/output/CElasticityOutput.hpp" #include "../../../Common/include/geometry/CGeometry.hpp" -#include "../../include/solver_structure.hpp" +#include "../../include/solvers/CSolver.hpp" CElasticityOutput::CElasticityOutput(CConfig *config, unsigned short nDim) : COutput(config, nDim, false) { diff --git a/SU2_CFD/src/output/CFlowCompFEMOutput.cpp b/SU2_CFD/src/output/CFlowCompFEMOutput.cpp index 26c494f08595..01bd5df6cd33 100644 --- a/SU2_CFD/src/output/CFlowCompFEMOutput.cpp +++ b/SU2_CFD/src/output/CFlowCompFEMOutput.cpp @@ -29,7 +29,7 @@ #include "../../include/output/CFlowCompFEMOutput.hpp" #include "../../../Common/include/geometry/CGeometry.hpp" -#include "../../include/solver_structure.hpp" +#include "../../include/solvers/CSolver.hpp" CFlowCompFEMOutput::CFlowCompFEMOutput(CConfig *config, unsigned short nDim) : CFlowOutput(config, nDim, true) { diff --git a/SU2_CFD/src/output/CFlowCompOutput.cpp b/SU2_CFD/src/output/CFlowCompOutput.cpp index de4f4d1e4775..5674b7784410 100644 --- a/SU2_CFD/src/output/CFlowCompOutput.cpp +++ b/SU2_CFD/src/output/CFlowCompOutput.cpp @@ -29,7 +29,7 @@ #include "../../include/output/CFlowCompOutput.hpp" #include "../../../Common/include/geometry/CGeometry.hpp" -#include "../../include/solver_structure.hpp" +#include "../../include/solvers/CSolver.hpp" CFlowCompOutput::CFlowCompOutput(CConfig *config, unsigned short nDim) : CFlowOutput(config, nDim, false) { diff --git a/SU2_CFD/src/output/CFlowIncOutput.cpp b/SU2_CFD/src/output/CFlowIncOutput.cpp index 2c4e1e59da8d..a255a836a929 100644 --- a/SU2_CFD/src/output/CFlowIncOutput.cpp +++ b/SU2_CFD/src/output/CFlowIncOutput.cpp @@ -29,7 +29,7 @@ #include "../../include/output/CFlowIncOutput.hpp" #include "../../../Common/include/geometry/CGeometry.hpp" -#include "../../include/solver_structure.hpp" +#include "../../include/solvers/CSolver.hpp" CFlowIncOutput::CFlowIncOutput(CConfig *config, unsigned short nDim) : CFlowOutput(config, nDim, false) { diff --git a/SU2_CFD/src/output/CFlowOutput.cpp b/SU2_CFD/src/output/CFlowOutput.cpp index 576dbd74310e..cfc8419f030d 100644 --- a/SU2_CFD/src/output/CFlowOutput.cpp +++ b/SU2_CFD/src/output/CFlowOutput.cpp @@ -27,7 +27,7 @@ #include "../../include/output/CFlowOutput.hpp" #include "../../../Common/include/geometry/CGeometry.hpp" -#include "../../include/solver_structure.hpp" +#include "../../include/solvers/CSolver.hpp" CFlowOutput::CFlowOutput(CConfig *config, unsigned short nDim, bool fem_output) : COutput (config, nDim, fem_output){ diff --git a/SU2_CFD/src/output/CHeatOutput.cpp b/SU2_CFD/src/output/CHeatOutput.cpp index 7996de870a0f..f88b27d562c9 100644 --- a/SU2_CFD/src/output/CHeatOutput.cpp +++ b/SU2_CFD/src/output/CHeatOutput.cpp @@ -28,7 +28,7 @@ #include "../../include/output/CHeatOutput.hpp" #include "../../../Common/include/geometry/CGeometry.hpp" -#include "../../include/solver_structure.hpp" +#include "../../include/solvers/CSolver.hpp" CHeatOutput::CHeatOutput(CConfig *config, unsigned short nDim) : COutput(config, nDim, false) { diff --git a/SU2_CFD/src/output/COutput.cpp b/SU2_CFD/src/output/COutput.cpp index 8440978fec61..a04c98c3da31 100644 --- a/SU2_CFD/src/output/COutput.cpp +++ b/SU2_CFD/src/output/COutput.cpp @@ -42,7 +42,7 @@ #include "../../../Common/include/geometry/CGeometry.hpp" -#include "../../include/solver_structure.hpp" +#include "../../include/solvers/CSolver.hpp" COutput::COutput(CConfig *config, unsigned short nDim, bool fem_output): femOutput(fem_output) { diff --git a/SU2_CFD/src/output/output_physics.cpp b/SU2_CFD/src/output/output_physics.cpp index 67e6a0707409..749c3e8eb881 100644 --- a/SU2_CFD/src/output/output_physics.cpp +++ b/SU2_CFD/src/output/output_physics.cpp @@ -29,7 +29,7 @@ #include "../../include/output/COutputLegacy.hpp" #include "../../../Common/include/geometry/CGeometry.hpp" -#include "../../include/solver_structure.hpp" +#include "../../include/solvers/CSolver.hpp" void COutputLegacy::ComputeTurboPerformance(CSolver *solver_container, CGeometry *geometry, CConfig *config) { diff --git a/SU2_CFD/src/output/output_structure_legacy.cpp b/SU2_CFD/src/output/output_structure_legacy.cpp index 9322fde5514c..334cdd5e0361 100644 --- a/SU2_CFD/src/output/output_structure_legacy.cpp +++ b/SU2_CFD/src/output/output_structure_legacy.cpp @@ -29,7 +29,7 @@ #include "../../include/output/COutputLegacy.hpp" #include "../../../Common/include/geometry/CGeometry.hpp" -#include "../../include/solver_structure.hpp" +#include "../../include/solvers/CBaselineSolver.hpp" COutputLegacy::COutputLegacy(CConfig *config) { @@ -18415,7 +18415,7 @@ void COutputLegacy::SpecialOutput_AnalyzeSurface(CSolver *solver, CGeometry *geo unsigned short iDim, iMarker, iMarker_Analyze; unsigned long iVertex, iPoint; su2double Mach = 0.0, Pressure, Temperature = 0.0, TotalPressure = 0.0, TotalTemperature = 0.0, - Enthalpy, Velocity[3], TangVel[3], Velocity2, MassFlow, Density, Area, + Enthalpy, Velocity[3]= {0.0}, TangVel[3], Velocity2, MassFlow, Density, Area, AxiFactor = 1.0, SoundSpeed, Vn, Vn2, Vtang2, Weight = 1.0; su2double Gas_Constant = config->GetGas_ConstantND(); diff --git a/SU2_CFD/src/solver_adjoint_mean.cpp b/SU2_CFD/src/solvers/CAdjEulerSolver.cpp similarity index 66% rename from SU2_CFD/src/solver_adjoint_mean.cpp rename to SU2_CFD/src/solvers/CAdjEulerSolver.cpp index beb94c4c1ba6..f033221e3f6d 100644 --- a/SU2_CFD/src/solver_adjoint_mean.cpp +++ b/SU2_CFD/src/solvers/CAdjEulerSolver.cpp @@ -1,12 +1,12 @@ /*! - * \file solution_adjoint_mean.cpp - * \brief Main subroutines for solving adjoint problems (Euler, Navier-Stokes, etc.). + * \file CAdjEulerSolver.cpp + * \brief Main subroutines for solving Euler adjoint problems. * \author F. Palacios, T. Economon, H. Kline * \version 7.0.0 "Blackbird" * * SU2 Project Website: https://su2code.github.io * - * The SU2 Project is maintained by the SU2 Foundation + * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) @@ -26,12 +26,10 @@ */ -#include "../include/solver_structure.hpp" -#include "../include/variables/CAdjEulerVariable.hpp" -#include "../include/variables/CAdjNSVariable.hpp" +#include "../../include/solvers/CAdjEulerSolver.hpp" CAdjEulerSolver::CAdjEulerSolver(void) : CSolver() { - + /*--- Array initialization ---*/ Phi_Inf = NULL; Sens_Mach = NULL; @@ -64,7 +62,7 @@ CAdjEulerSolver::CAdjEulerSolver(CGeometry *geometry, CConfig *config, unsigned bool restart = config->GetRestart(); bool axisymmetric = config->GetAxisymmetric(); - + su2double RefArea = config->GetRefArea(); su2double RefDensity = config->GetDensity_FreeStreamND(); su2double Gas_Constant = config->GetGas_ConstantND(); @@ -76,7 +74,7 @@ CAdjEulerSolver::CAdjEulerSolver(CGeometry *geometry, CConfig *config, unsigned bool grid_movement = config->GetGrid_Movement(); /*--- Array initialization ---*/ - + Phi_Inf = NULL; Sens_Mach = NULL; Sens_AoA = NULL; @@ -96,19 +94,19 @@ CAdjEulerSolver::CAdjEulerSolver(CGeometry *geometry, CConfig *config, unsigned /*--- Set the gamma value ---*/ Gamma = config->GetGamma(); Gamma_Minus_One = Gamma - 1.0; - + /*--- Define geometry constans in the solver structure ---*/ nDim = geometry->GetnDim(); nMarker = config->GetnMarker_All(); nPoint = geometry->GetnPoint(); nPointDomain = geometry->GetnPointDomain(); - + nVar = nDim + 2; - + /*--- Initialize nVarGrad for deallocation ---*/ - + nVarGrad = nVar; - + /*--- Define some auxiliary vectors related to the residual ---*/ Residual = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = 0.0; Residual_RMS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_RMS[iVar] = 0.0; @@ -125,12 +123,12 @@ CAdjEulerSolver::CAdjEulerSolver(CGeometry *geometry, CConfig *config, unsigned Res_Visc_i = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Visc_i[iVar] = 0.0; Res_Conv_j = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Conv_j[iVar] = 0.0; Res_Visc_j = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Visc_j[iVar] = 0.0; - + /*--- Define some auxiliary vectors related to the solution ---*/ Solution = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution[iVar] = 0.0; Solution_i = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution_i[iVar] = 0.0; Solution_j = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution_j[iVar] = 0.0; - + /*--- Define some auxiliary arrays related to the flow solution ---*/ FlowPrimVar_i = new su2double[nDim+7]; for (iVar = 0; iVar < nDim+7; iVar++) FlowPrimVar_i[iVar] = 0.0; FlowPrimVar_j = new su2double[nDim+7]; for (iVar = 0; iVar < nDim+7; iVar++) FlowPrimVar_j[iVar] = 0.0; @@ -139,16 +137,16 @@ CAdjEulerSolver::CAdjEulerSolver(CGeometry *geometry, CConfig *config, unsigned Vector = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = 0.0; Vector_i = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector_i[iDim] = 0.0; Vector_j = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector_j[iDim] = 0.0; - + /*--- Define some auxiliary vectors related to the undivided lapalacian ---*/ if (config->GetKind_ConvNumScheme_AdjFlow() == SPACE_CENTERED) { iPoint_UndLapl = new su2double [nPoint]; jPoint_UndLapl = new su2double [nPoint]; } - + /*--- Define some auxiliary vectors related to the geometry ---*/ Vector_i = new su2double[nDim]; Vector_j = new su2double[nDim]; - + /*--- Point to point Jacobians. These are always defined because they are also used for sensitivity calculations. ---*/ Jacobian_i = new su2double* [nVar]; @@ -157,10 +155,10 @@ CAdjEulerSolver::CAdjEulerSolver(CGeometry *geometry, CConfig *config, unsigned Jacobian_i[iVar] = new su2double [nVar]; Jacobian_j[iVar] = new su2double [nVar]; } - + LinSysSol.Initialize(nPoint, nPointDomain, nVar, 0.0); LinSysRes.Initialize(nPoint, nPointDomain, nVar, 0.0); - + /*--- Jacobians and vector structures for implicit computations ---*/ if (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT) { Jacobian_ii = new su2double* [nVar]; @@ -173,16 +171,16 @@ CAdjEulerSolver::CAdjEulerSolver(CGeometry *geometry, CConfig *config, unsigned Jacobian_ji[iVar] = new su2double [nVar]; Jacobian_jj[iVar] = new su2double [nVar]; } - + if (rank == MASTER_NODE) cout << "Initialize Jacobian structure (Adjoint Euler). MG level: " << iMesh <<"." << endl; Jacobian.Initialize(nPoint, nPointDomain, nVar, nVar, true, geometry, config); - + if (config->GetKind_Linear_Solver_Prec() == LINELET) { nLineLets = Jacobian.BuildLineletPreconditioner(geometry, config); if (rank == MASTER_NODE) cout << "Compute linelet structure. " << nLineLets << " elements in each line (average)." << endl; } - + if (axisymmetric) { Jacobian_Axisymmetric = new su2double* [nVar]; for (iVar = 0; iVar < nVar; iVar++) @@ -192,7 +190,7 @@ CAdjEulerSolver::CAdjEulerSolver(CGeometry *geometry, CConfig *config, unsigned if (rank == MASTER_NODE) cout << "Explicit scheme. No Jacobian structure (Adjoint Euler). MG level: " << iMesh <<"." << endl; } - + /*--- Computation of gradients by least squares ---*/ if (config->GetLeastSquaresRequired()) { /*--- S matrix := inv(R)*traspose(inv(R)) ---*/ @@ -204,15 +202,15 @@ CAdjEulerSolver::CAdjEulerSolver(CGeometry *geometry, CConfig *config, unsigned for (iVar = 0; iVar < nVar; iVar++) Cvector[iVar] = new su2double [nDim]; } - + /*--- Sensitivity definition and coefficient in all the markers ---*/ CSensitivity = new su2double* [nMarker]; for (iMarker = 0; iMarker < nMarker; iMarker++) { CSensitivity[iMarker] = new su2double [geometry->nVertex[iMarker]]; } - + /*--- Store the value of the characteristic primitive variables at the boundaries ---*/ - + DonorAdjVar = new su2double** [nMarker]; for (iMarker = 0; iMarker < nMarker; iMarker++) { DonorAdjVar[iMarker] = new su2double* [geometry->nVertex[iMarker]]; @@ -223,9 +221,9 @@ CAdjEulerSolver::CAdjEulerSolver(CGeometry *geometry, CConfig *config, unsigned } } } - + /*--- Store the value of the characteristic primitive variables index at the boundaries ---*/ - + DonorGlobalIndex = new unsigned long* [nMarker]; for (iMarker = 0; iMarker < nMarker; iMarker++) { DonorGlobalIndex[iMarker] = new unsigned long [geometry->nVertex[iMarker]]; @@ -233,14 +231,14 @@ CAdjEulerSolver::CAdjEulerSolver(CGeometry *geometry, CConfig *config, unsigned DonorGlobalIndex[iMarker][iVertex] = 0; } } - + Sens_Geo = new su2double[nMarker]; Sens_Mach = new su2double[nMarker]; Sens_AoA = new su2double[nMarker]; Sens_Press = new su2double[nMarker]; Sens_Temp = new su2double[nMarker]; Sens_BPress = new su2double[nMarker]; - + for (iMarker = 0; iMarker < nMarker; iMarker++) { Sens_Geo[iMarker] = 0.0; Sens_Mach[iMarker] = 0.0; @@ -257,7 +255,7 @@ CAdjEulerSolver::CAdjEulerSolver(CGeometry *geometry, CConfig *config, unsigned Phi_Inf = new su2double [nDim]; Phi_Inf[0] = 0.0; Phi_Inf[1] = 0.0; if (nDim == 3) Phi_Inf[2] = 0.0; - + /*--- If outflow objective, nonzero initialization ---*/ if ((config->GetKind_ObjFunc() == SURFACE_TOTAL_PRESSURE)) { su2double SoundSpeed,*vel_inf,R,vel2,vel; @@ -372,12 +370,12 @@ CAdjEulerSolver::CAdjEulerSolver(CGeometry *geometry, CConfig *config, unsigned InitiateComms(geometry, config, SOLUTION); CompleteComms(geometry, config, SOLUTION); - + } CAdjEulerSolver::~CAdjEulerSolver(void) { unsigned short iVar, iMarker; - + if (Phi_Inf != NULL) delete [] Phi_Inf; if (Sens_Mach != NULL) delete [] Sens_Mach; if (Sens_AoA != NULL) delete [] Sens_AoA; @@ -387,19 +385,19 @@ CAdjEulerSolver::~CAdjEulerSolver(void) { if (Sens_BPress != NULL) delete [] Sens_BPress; if (FlowPrimVar_i != NULL) delete [] FlowPrimVar_i; if (FlowPrimVar_j != NULL) delete [] FlowPrimVar_j; - + if (Jacobian_Axisymmetric != NULL) { for (iVar = 0; iVar < nVar; iVar++) delete Jacobian_Axisymmetric[iVar]; delete [] Jacobian_Axisymmetric; } - + if (CSensitivity != NULL) { for (iMarker = 0; iMarker < nMarker; iMarker++) delete [] CSensitivity[iMarker]; delete [] CSensitivity; } - + if (nodes != nullptr) delete nodes; } @@ -413,53 +411,53 @@ void CAdjEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contain } void CAdjEulerSolver::Set_MPI_ActDisk(CSolver **solver_container, CGeometry *geometry, CConfig *config) { - + unsigned long iter, iPoint, iVertex, jVertex, iPointTotal, Buffer_Send_nPointTotal = 0, iGlobalIndex, iGlobal; unsigned short iVar, iMarker, jMarker; long nDomain = 0, iDomain, jDomain; #ifdef HAVE_MPI - + /*--- MPI status and request arrays for non-blocking communications ---*/ - + SU2_MPI::Status status, status_; - + #endif - + /*--- Define buffer vector interior domain ---*/ - + su2double *Buffer_Send_AdjVar = NULL; su2double *iAdjVar = new su2double [nVar]; - + unsigned long *nPointTotal_s = new unsigned long[size]; unsigned long *nPointTotal_r = new unsigned long[size]; - + unsigned long Buffer_Size_AdjVar = 0; unsigned long PointTotal_Counter = 0; - + /*--- Allocate the memory that we only need if we have MPI support ---*/ - + su2double *Buffer_Receive_AdjVar = NULL; - + /*--- Basic dimensionalization ---*/ - + nDomain = size; - + /*--- This loop gets the array sizes of points for each rank to send to each other rank. ---*/ - + for (iDomain = 0; iDomain < nDomain; iDomain++) { - + /*--- Loop over the markers to perform the dimensionalizaton of the domain variables ---*/ - + Buffer_Send_nPointTotal = 0; - + /*--- Loop over all of the markers and count the number of each type of point and element that needs to be sent. ---*/ - + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) == ACTDISK_INLET) || (config->GetMarker_All_KindBC(iMarker) == ACTDISK_OUTLET)) { @@ -472,257 +470,257 @@ void CAdjEulerSolver::Set_MPI_ActDisk(CSolver **solver_container, CGeometry *geo } } } - + /*--- Store the counts on a partition by partition basis. ---*/ - + nPointTotal_s[iDomain] = Buffer_Send_nPointTotal; - + /*--- Total counts for allocating send buffers below ---*/ - + Buffer_Size_AdjVar += nPointTotal_s[iDomain]*(nVar+3); - + } - + /*--- Allocate the buffer vectors in the appropiate domain (master, iDomain) ---*/ - + Buffer_Send_AdjVar = new su2double[Buffer_Size_AdjVar]; - + /*--- Now that we know the sizes of the point, we can allocate and send the information in large chunks to all processors. ---*/ - + for (iDomain = 0; iDomain < nDomain; iDomain++) { - + /*--- A rank does not communicate with itself through MPI ---*/ - + if (rank != iDomain) { - + #ifdef HAVE_MPI - + /*--- Communicate the counts to iDomain with non-blocking sends ---*/ - + SU2_MPI::Bsend(&nPointTotal_s[iDomain], 1, MPI_UNSIGNED_LONG, iDomain, iDomain, MPI_COMM_WORLD); - + #endif - + } else { - + /*--- If iDomain = rank, we simply copy values into place in memory ---*/ - + nPointTotal_r[iDomain] = nPointTotal_s[iDomain]; - + } - + /*--- Receive the counts. All processors are sending their counters to iDomain up above, so only iDomain needs to perform the recv here from all other ranks. ---*/ - + if (rank == iDomain) { - + for (jDomain = 0; jDomain < size; jDomain++) { - + /*--- A rank does not communicate with itself through MPI ---*/ - + if (rank != jDomain) { - + #ifdef HAVE_MPI - + /*--- Recv the data by probing for the current sender, jDomain, first and then receiving the values from it. ---*/ - + SU2_MPI::Recv(&nPointTotal_r[jDomain], 1, MPI_UNSIGNED_LONG, jDomain, rank, MPI_COMM_WORLD, &status); - + #endif - + } } - + } } - + /*--- Wait for the non-blocking sends to complete. ---*/ - + #ifdef HAVE_MPI - + SU2_MPI::Barrier(MPI_COMM_WORLD); - + #endif - + /*--- Initialize the counters for the larger send buffers (by domain) ---*/ - + PointTotal_Counter = 0; - + for (iDomain = 0; iDomain < nDomain; iDomain++) { - + /*--- Set the value of the interior geometry. Initialize counters. ---*/ - + iPointTotal = 0; - + /*--- Load up the actual values into the buffers for sending. ---*/ - + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { - + if ((config->GetMarker_All_KindBC(iMarker) == ACTDISK_INLET) || (config->GetMarker_All_KindBC(iMarker) == ACTDISK_OUTLET)) { - + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); jDomain = geometry->vertex[iMarker][iVertex]->GetDonorProcessor(); if ((iDomain == jDomain) && (geometry->node[iPoint]->GetDomain())) { - + iGlobalIndex = geometry->node[iPoint]->GetGlobalIndex(); jVertex = geometry->vertex[iMarker][iVertex]->GetDonorVertex(); jMarker = geometry->vertex[iMarker][iVertex]->GetDonorMarker(); - + for (iVar = 0; iVar < nVar; iVar++) { Buffer_Send_AdjVar[(nVar+3)*(PointTotal_Counter+iPointTotal)+iVar] = nodes->GetSolution(iPoint,iVar); } Buffer_Send_AdjVar[(nVar+3)*(PointTotal_Counter+iPointTotal)+(nVar+0)] = su2double(iGlobalIndex); Buffer_Send_AdjVar[(nVar+3)*(PointTotal_Counter+iPointTotal)+(nVar+1)] = su2double(jVertex); Buffer_Send_AdjVar[(nVar+3)*(PointTotal_Counter+iPointTotal)+(nVar+2)] = su2double(jMarker); - + iPointTotal++; - + } - + } - + } - + } - + /*--- Send the buffers with the geometrical information ---*/ - + if (iDomain != rank) { - + #ifdef HAVE_MPI - + /*--- Communicate the coordinates, global index, colors, and element date to iDomain with non-blocking sends. ---*/ - + SU2_MPI::Bsend(&Buffer_Send_AdjVar[PointTotal_Counter*(nVar+3)], nPointTotal_s[iDomain]*(nVar+3), MPI_DOUBLE, iDomain, iDomain, MPI_COMM_WORLD); - + #endif - + } - + else { - + /*--- Allocate local memory for the local recv of the elements ---*/ - + Buffer_Receive_AdjVar = new su2double[nPointTotal_s[iDomain]*(nVar+3)]; - + for (iter = 0; iter < nPointTotal_s[iDomain]*(nVar+3); iter++) Buffer_Receive_AdjVar[iter] = Buffer_Send_AdjVar[PointTotal_Counter*(nVar+3)+iter]; - + /*--- Recv the point data from ourselves (same procedure as above) ---*/ - + for (iPoint = 0; iPoint < nPointTotal_r[iDomain]; iPoint++) { - + iGlobal = SU2_TYPE::Int(Buffer_Receive_AdjVar[iPoint*(nVar+3)+(nVar+0)]); iVertex = SU2_TYPE::Int(Buffer_Receive_AdjVar[iPoint*(nVar+3)+(nVar+1)]); iMarker = SU2_TYPE::Int(Buffer_Receive_AdjVar[iPoint*(nVar+3)+(nVar+2)]); for (iVar = 0; iVar < nVar; iVar++) iAdjVar[iVar] = Buffer_Receive_AdjVar[iPoint*(nVar+3)+iVar]; - + for (iVar = 0; iVar < nVar; iVar++) SetDonorAdjVar(iMarker, iVertex, iVar, iAdjVar[iVar]); - + SetDonorGlobalIndex(iMarker, iVertex, iGlobal); - + } - + /*--- Delete memory for recv the point stuff ---*/ - + delete [] Buffer_Receive_AdjVar; - + } - + /*--- Increment the counters for the send buffers (iDomain loop) ---*/ - + PointTotal_Counter += iPointTotal; - + } - + /*--- Wait for the non-blocking sends to complete. ---*/ - + #ifdef HAVE_MPI - + SU2_MPI::Barrier(MPI_COMM_WORLD); - + #endif - + /*--- The next section begins the recv of all data for the interior points/elements in the mesh. First, create the domain structures for the points on this rank. First, we recv all of the point data ---*/ - + for (iDomain = 0; iDomain < size; iDomain++) { - + if (rank != iDomain) { - + #ifdef HAVE_MPI - + /*--- Allocate the receive buffer vector. Send the colors so that we know whether what we recv is an owned or halo node. ---*/ - + Buffer_Receive_AdjVar = new su2double [nPointTotal_r[iDomain]*nVar]; - + /*--- Receive the buffers with the coords, global index, and colors ---*/ - + SU2_MPI::Recv(Buffer_Receive_AdjVar, nPointTotal_r[iDomain]*(nVar+3) , MPI_DOUBLE, iDomain, rank, MPI_COMM_WORLD, &status_); - + /*--- Loop over all of the points that we have recv'd and store the coords, global index vertex and markers ---*/ - + for (iPoint = 0; iPoint < nPointTotal_r[iDomain]; iPoint++) { - + iGlobal = SU2_TYPE::Int(Buffer_Receive_AdjVar[iPoint*(nVar+3)+(nVar+0)]); iVertex = SU2_TYPE::Int(Buffer_Receive_AdjVar[iPoint*(nVar+3)+(nVar+1)]); iMarker = SU2_TYPE::Int(Buffer_Receive_AdjVar[iPoint*(nVar+3)+(nVar+2)]); for (iVar = 0; iVar < nVar; iVar++) iAdjVar[iVar] = Buffer_Receive_AdjVar[iPoint*(nVar+3)+iVar]; - + for (iVar = 0; iVar < nVar; iVar++) SetDonorAdjVar(iMarker, iVertex, iVar, iAdjVar[iVar]); - + SetDonorGlobalIndex(iMarker, iVertex, iGlobal); - + } - + /*--- Delete memory for recv the point stuff ---*/ - + delete [] Buffer_Receive_AdjVar; - + #endif - + } - + } - + /*--- Wait for the non-blocking sends to complete. ---*/ - + #ifdef HAVE_MPI - + SU2_MPI::Barrier(MPI_COMM_WORLD); - + #endif - + /*--- Free all of the memory used for communicating points and elements ---*/ - + delete[] Buffer_Send_AdjVar; - + /*--- Release all of the temporary memory ---*/ - + delete [] nPointTotal_s; delete [] nPointTotal_r; delete [] iAdjVar; - + } void CAdjEulerSolver::Set_MPI_Nearfield(CGeometry *geometry, CConfig *config) { - + unsigned long iter, iPoint, iVertex, jVertex, iPointTotal, Buffer_Send_nPointTotal = 0, iGlobalIndex, iGlobal; unsigned short iVar, iMarker, jMarker; @@ -731,52 +729,52 @@ void CAdjEulerSolver::Set_MPI_Nearfield(CGeometry *geometry, CConfig *config) { #ifdef HAVE_MPI /*--- MPI status and request arrays for non-blocking communications ---*/ - + SU2_MPI::Status status, status_; - + #endif - + /*--- Define buffer vector interior domain ---*/ - + su2double *Buffer_Send_AdjVar = NULL; - + unsigned long *nPointTotal_s = new unsigned long[size]; unsigned long *nPointTotal_r = new unsigned long[size]; su2double *iAdjVar = new su2double [nVar]; - + unsigned long Buffer_Size_AdjVar = 0; - + unsigned long PointTotal_Counter = 0; - + /*--- Allocate the memory that we only need if we have MPI support ---*/ - - + + su2double *Buffer_Receive_AdjVar = NULL; - + /*--- Basic dimensionalization ---*/ - + nDomain = size; - + #ifdef HAVE_MPI - + SU2_MPI::Barrier(MPI_COMM_WORLD); - + #endif - + /*--- This loop gets the array sizes of points for each rank to send to each other rank. ---*/ - + for (iDomain = 0; iDomain < nDomain; iDomain++) { - + /*--- Loop over the markers to perform the dimensionalizaton of the domain variables ---*/ - + Buffer_Send_nPointTotal = 0; - + /*--- Loop over all of the markers and count the number of each type of point and element that needs to be sent. ---*/ - + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { if (config->GetMarker_All_KindBC(iMarker) == NEARFIELD_BOUNDARY) { for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { @@ -788,257 +786,257 @@ void CAdjEulerSolver::Set_MPI_Nearfield(CGeometry *geometry, CConfig *config) { } } } - + /*--- Store the counts on a partition by partition basis. ---*/ - + nPointTotal_s[iDomain] = Buffer_Send_nPointTotal; - + /*--- Total counts for allocating send buffers below ---*/ - + Buffer_Size_AdjVar += nPointTotal_s[iDomain]*(nVar+3); - + } - + /*--- Allocate the buffer vectors in the appropiate domain (master, iDomain) ---*/ - + Buffer_Send_AdjVar = new su2double[Buffer_Size_AdjVar]; - + /*--- Now that we know the sizes of the point, we can allocate and send the information in large chunks to all processors. ---*/ - + for (iDomain = 0; iDomain < nDomain; iDomain++) { - + /*--- A rank does not communicate with itself through MPI ---*/ - + if (rank != iDomain) { - + #ifdef HAVE_MPI - + /*--- Communicate the counts to iDomain with non-blocking sends ---*/ - + SU2_MPI::Bsend(&nPointTotal_s[iDomain], 1, MPI_UNSIGNED_LONG, iDomain, iDomain, MPI_COMM_WORLD); - + #endif - + } else { - + /*--- If iDomain = rank, we simply copy values into place in memory ---*/ - + nPointTotal_r[iDomain] = nPointTotal_s[iDomain]; - + } - + /*--- Receive the counts. All processors are sending their counters to iDomain up above, so only iDomain needs to perform the recv here from all other ranks. ---*/ - + if (rank == iDomain) { - + for (jDomain = 0; jDomain < size; jDomain++) { - + /*--- A rank does not communicate with itself through MPI ---*/ - + if (rank != jDomain) { - + #ifdef HAVE_MPI - + /*--- Recv the data by probing for the current sender, jDomain, first and then receiving the values from it. ---*/ - + SU2_MPI::Recv(&nPointTotal_r[jDomain], 1, MPI_UNSIGNED_LONG, jDomain, rank, MPI_COMM_WORLD, &status); - + #endif - + } } - + } } - + /*--- Wait for the non-blocking sends to complete. ---*/ - + #ifdef HAVE_MPI - + SU2_MPI::Barrier(MPI_COMM_WORLD); - + #endif - + /*--- Initialize the counters for the larger send buffers (by domain) ---*/ - + PointTotal_Counter = 0; - + for (iDomain = 0; iDomain < nDomain; iDomain++) { - + /*--- Set the value of the interior geometry. Initialize counters. ---*/ - + iPointTotal = 0; - + /*--- Load up the actual values into the buffers for sending. ---*/ - + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { - + if (config->GetMarker_All_KindBC(iMarker) == NEARFIELD_BOUNDARY) { - + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); jDomain = geometry->vertex[iMarker][iVertex]->GetDonorProcessor(); if ((iDomain == jDomain) && (geometry->node[iPoint]->GetDomain())) { - + iGlobalIndex = geometry->node[iPoint]->GetGlobalIndex(); jVertex = geometry->vertex[iMarker][iVertex]->GetDonorVertex(); jMarker = geometry->vertex[iMarker][iVertex]->GetDonorMarker(); - + for (iVar = 0; iVar < nVar; iVar++) { Buffer_Send_AdjVar[(nVar+3)*(PointTotal_Counter+iPointTotal)+iVar] = nodes->GetSolution(iPoint,iVar); } Buffer_Send_AdjVar[(nVar+3)*(PointTotal_Counter+iPointTotal)+(nVar+0)] = su2double(iGlobalIndex); Buffer_Send_AdjVar[(nVar+3)*(PointTotal_Counter+iPointTotal)+(nVar+1)] = su2double(jVertex); Buffer_Send_AdjVar[(nVar+3)*(PointTotal_Counter+iPointTotal)+(nVar+2)] = su2double(jMarker); - + iPointTotal++; - + } - + } - + } - + } - + /*--- Send the buffers with the geometrical information ---*/ - + if (iDomain != rank) { - + #ifdef HAVE_MPI - + /*--- Communicate the coordinates, global index, colors, and element date to iDomain with non-blocking sends. ---*/ - + SU2_MPI::Bsend(&Buffer_Send_AdjVar[PointTotal_Counter*(nVar+3)], nPointTotal_s[iDomain]*(nVar+3), MPI_DOUBLE, iDomain, iDomain, MPI_COMM_WORLD); - + #endif - + } - + else { - + /*--- Allocate local memory for the local recv of the elements ---*/ - + Buffer_Receive_AdjVar = new su2double[nPointTotal_s[iDomain]*(nVar+3)]; - + for (iter = 0; iter < nPointTotal_s[iDomain]*(nVar+3); iter++) Buffer_Receive_AdjVar[iter] = Buffer_Send_AdjVar[PointTotal_Counter*(nVar+3)+iter]; - + /*--- Recv the point data from ourselves (same procedure as above) ---*/ - + for (iPoint = 0; iPoint < nPointTotal_r[iDomain]; iPoint++) { - + iGlobal = SU2_TYPE::Int(Buffer_Receive_AdjVar[iPoint*(nVar+3)+(nVar+0)]); iVertex = SU2_TYPE::Int(Buffer_Receive_AdjVar[iPoint*(nVar+3)+(nVar+1)]); iMarker = SU2_TYPE::Int(Buffer_Receive_AdjVar[iPoint*(nVar+3)+(nVar+2)]); for (iVar = 0; iVar < nVar; iVar++) iAdjVar[iVar] = Buffer_Receive_AdjVar[iPoint*(nVar+3)+iVar]; - + for (iVar = 0; iVar < nVar; iVar++) SetDonorAdjVar(iMarker, iVertex, iVar, iAdjVar[iVar]); - + SetDonorGlobalIndex(iMarker, iVertex, iGlobal); - + } - + /*--- Delete memory for recv the point stuff ---*/ - + delete [] Buffer_Receive_AdjVar; - + } - + /*--- Increment the counters for the send buffers (iDomain loop) ---*/ - + PointTotal_Counter += iPointTotal; - + } - + /*--- Wait for the non-blocking sends to complete. ---*/ - + #ifdef HAVE_MPI - + SU2_MPI::Barrier(MPI_COMM_WORLD); - + #endif - + /*--- The next section begins the recv of all data for the interior points/elements in the mesh. First, create the domain structures for the points on this rank. First, we recv all of the point data ---*/ - + for (iDomain = 0; iDomain < size; iDomain++) { - + if (rank != iDomain) { - + #ifdef HAVE_MPI - + /*--- Allocate the receive buffer vector. Send the colors so that we know whether what we recv is an owned or halo node. ---*/ - + Buffer_Receive_AdjVar = new su2double [nPointTotal_r[iDomain]*(nVar+3)]; - + /*--- Receive the buffers with the coords, global index, and colors ---*/ - + SU2_MPI::Recv(Buffer_Receive_AdjVar, nPointTotal_r[iDomain]*(nVar+3) , MPI_DOUBLE, iDomain, rank, MPI_COMM_WORLD, &status_); - - + + /*--- Loop over all of the points that we have recv'd and store the coords, global index vertex and markers ---*/ - + for (iPoint = 0; iPoint < nPointTotal_r[iDomain]; iPoint++) { - + iGlobal = SU2_TYPE::Int(Buffer_Receive_AdjVar[iPoint*(nVar+3)+(nVar+0)]); iVertex = SU2_TYPE::Int(Buffer_Receive_AdjVar[iPoint*(nVar+3)+(nVar+1)]); iMarker = SU2_TYPE::Int(Buffer_Receive_AdjVar[iPoint*(nVar+3)+(nVar+2)]); for (iVar = 0; iVar < nVar; iVar++) iAdjVar[iVar] = Buffer_Receive_AdjVar[iPoint*(nVar+3)+iVar]; - + for (iVar = 0; iVar < nVar; iVar++) SetDonorAdjVar(iMarker, iVertex, iVar, iAdjVar[iVar]); - + SetDonorGlobalIndex(iMarker, iVertex, iGlobal); - + } - + /*--- Delete memory for recv the point stuff ---*/ - + delete [] Buffer_Receive_AdjVar; - + #endif - + } - + } - + /*--- Wait for the non-blocking sends to complete. ---*/ - + #ifdef HAVE_MPI - + SU2_MPI::Barrier(MPI_COMM_WORLD); - + #endif - + /*--- Free all of the memory used for communicating points and elements ---*/ - + delete[] Buffer_Send_AdjVar; - + /*--- Release all of the temporary memory ---*/ - + delete [] nPointTotal_s; delete [] nPointTotal_r; delete [] iAdjVar; - + } void CAdjEulerSolver::SetForceProj_Vector(CGeometry *geometry, CSolver **solver_container, CConfig *config) { - + su2double *ForceProj_Vector, x = 0.0, y = 0.0, z = 0.0, *Normal, CD, CL, Cp, CpTarget, CT, CQ, x_origin, y_origin, z_origin, WDrag, Area, invCD, CLCD2, invCQ, CTRCQ2; unsigned short iMarker,jMarker,iMarker_Monitoring, iDim; @@ -1046,7 +1044,7 @@ void CAdjEulerSolver::SetForceProj_Vector(CGeometry *geometry, CSolver **solver_ string Marker_Tag, Monitoring_Tag; su2double Weight_ObjFunc=1.0; su2double *ForceProj_Vector2; - + su2double Alpha = (config->GetAoA()*PI_NUMBER)/180.0; su2double Beta = (config->GetAoS()*PI_NUMBER)/180.0; su2double RefLength = config->GetRefLength(); @@ -1060,21 +1058,21 @@ void CAdjEulerSolver::SetForceProj_Vector(CGeometry *geometry, CSolver **solver_ bool Fixed_CM = config->GetFixed_CM_Mode(); ForceProj_Vector = new su2double[nDim]; - + /*--- Compute coefficients needed for objective function evaluation. ---*/ - + CD = solver_container[FLOW_SOL]->GetTotal_CD(); CL = solver_container[FLOW_SOL]->GetTotal_CL(); CT = solver_container[FLOW_SOL]->GetTotal_CT(); CQ = solver_container[FLOW_SOL]->GetTotal_CQ(); invCD = 1.0/CD; CLCD2 = CL/(CD*CD); invCQ = 1.0/CQ; CTRCQ2 = CT/(RefLength*CQ*CQ); - + x_origin = RefOriginMoment[0]; y_origin = RefOriginMoment[1]; z_origin = RefOriginMoment[2]; - + /*--- Evaluate the boundary condition coefficients, Since there may be more than one objective per marker, first we have to set all Force projection vectors to 0 ---*/ - + for (iMarker = 0; iMarkerGetMarker_All_KindBC(iMarker) != SEND_RECEIVE) && (config->GetMarker_All_Monitoring(iMarker) == YES)) @@ -1097,17 +1095,17 @@ void CAdjEulerSolver::SetForceProj_Vector(CGeometry *geometry, CSolver **solver_ iMarker = jMarker; } - + if ((iMarkerGetMarker_All_KindBC(iMarker) != SEND_RECEIVE) && (config->GetMarker_All_Monitoring(iMarker) == YES)) { for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - + x = geometry->node[iPoint]->GetCoord(0); y = geometry->node[iPoint]->GetCoord(1); if (nDim == 3) z = geometry->node[iPoint]->GetCoord(2); - + Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); ForceProj_Vector2 = nodes->GetForceProj_Vector(iPoint); for (iDim=0; iDimGetKind_ObjFunc(iMarker_Monitoring)) { case DRAG_COEFFICIENT : if (nDim == 2) { - + ForceProj_Vector[0] += Weight_ObjFunc*cos(Alpha); ForceProj_Vector[1] += Weight_ObjFunc*sin(Alpha); - + /*--- Modification to run at a fixed CL and CM value ---*/ - + if (Fixed_CL) { ForceProj_Vector[0] += dCD_dCL*Weight_ObjFunc*sin(Alpha); ForceProj_Vector[1] -= dCD_dCL*Weight_ObjFunc*cos(Alpha); } if (Fixed_CM) { ForceProj_Vector[0] -= dCD_dCMy*Weight_ObjFunc*(y - y_origin)/RefLength; ForceProj_Vector[1] += dCD_dCMy*Weight_ObjFunc*(x - x_origin)/RefLength; } } if (nDim == 3) { - + ForceProj_Vector[0] += Weight_ObjFunc*cos(Alpha)*cos(Beta); ForceProj_Vector[1] += Weight_ObjFunc*sin(Beta); ForceProj_Vector[2] += Weight_ObjFunc*sin(Alpha)*cos(Beta); - + /*--- Modification to run at a fixed CL value ---*/ - + if (Fixed_CL) { ForceProj_Vector[0] += dCD_dCL*Weight_ObjFunc*sin(Alpha); ForceProj_Vector[1] -= 0.0; ForceProj_Vector[2] -= dCD_dCL*Weight_ObjFunc*cos(Alpha); } if (Fixed_CM) { ForceProj_Vector[0] += dCD_dCMy*Weight_ObjFunc*(z - z_origin)/RefLength; ForceProj_Vector[1] += 0.0; ForceProj_Vector[2] -= dCD_dCMy*Weight_ObjFunc*(x - x_origin)/RefLength; } - + } break; case LIFT_COEFFICIENT : @@ -1158,50 +1156,50 @@ void CAdjEulerSolver::SetForceProj_Vector(CGeometry *geometry, CSolver **solver_ case MOMENT_X_COEFFICIENT : if (nDim == 2) { SU2_MPI::Error("This functional is not possible in 2D!!", CURRENT_FUNCTION);} if (nDim == 3) { - + ForceProj_Vector[0] += 0.0; ForceProj_Vector[1] += -Weight_ObjFunc*(z - z_origin)/RefLength; ForceProj_Vector[2] += Weight_ObjFunc*(y - y_origin)/RefLength; - + /*--- Modification to run at a fixed CL value ---*/ - + if (Fixed_CL) { ForceProj_Vector[0] += dCMx_dCL*Weight_ObjFunc*sin(Alpha); ForceProj_Vector[1] -= 0.0; ForceProj_Vector[2] -= dCMx_dCL*Weight_ObjFunc*cos(Alpha); } - + } break; case MOMENT_Y_COEFFICIENT : if (nDim == 2) { SU2_MPI::Error("This functional is not possible in 2D!!", CURRENT_FUNCTION);} if (nDim == 3) { - + ForceProj_Vector[0] += Weight_ObjFunc*(z - z_origin)/RefLength; ForceProj_Vector[1] += 0.0; ForceProj_Vector[2] += -Weight_ObjFunc*(x - x_origin)/RefLength; - + /*--- Modification to run at a fixed CL value ---*/ - + if (Fixed_CL) { ForceProj_Vector[0] += dCMy_dCL*Weight_ObjFunc*sin(Alpha); ForceProj_Vector[1] -= 0.0; ForceProj_Vector[2] -= dCMy_dCL*Weight_ObjFunc*cos(Alpha); } } break; case MOMENT_Z_COEFFICIENT : if (nDim == 2) { - + ForceProj_Vector[0] += -Weight_ObjFunc*(y - y_origin)/RefLength; ForceProj_Vector[1] += Weight_ObjFunc*(x - x_origin)/RefLength; - + /*--- Modification to run at a fixed CL and CM value ---*/ - + if (Fixed_CL) { ForceProj_Vector[0] += dCMz_dCL*Weight_ObjFunc*sin(Alpha); ForceProj_Vector[1] -= dCMz_dCL*Weight_ObjFunc*cos(Alpha); } } if (nDim == 3) { - + ForceProj_Vector[0] += -Weight_ObjFunc*(y - y_origin)/RefLength; ForceProj_Vector[1] += Weight_ObjFunc*(x - x_origin)/RefLength; ForceProj_Vector[2] += 0; - + /*--- Modification to run at a fixed CL value ---*/ - + if (Fixed_CL) { ForceProj_Vector[0] += dCMz_dCL*Weight_ObjFunc*sin(Alpha); ForceProj_Vector[1] -= 0.0; ForceProj_Vector[2] -= dCMz_dCL*Weight_ObjFunc*cos(Alpha); } } @@ -1252,16 +1250,16 @@ void CAdjEulerSolver::SetForceProj_Vector(CGeometry *geometry, CSolver **solver_ default : break; } - + /*--- Store the force projection vector at this node ---*/ - + nodes->SetForceProj_Vector(iPoint,ForceProj_Vector); - + } } } delete [] ForceProj_Vector; - + } void CAdjEulerSolver::SetIntBoundary_Jump(CGeometry *geometry, CSolver **solver_container, CConfig *config) { @@ -1275,11 +1273,11 @@ void CAdjEulerSolver::SetIntBoundary_Jump(CGeometry *geometry, CSolver **solver_ vector > NearFieldWeight; vector CoordNF; vector IndexNF; - + IntBound_Vector = new su2double [nVar]; - + /*--- Allocate vectors and matrices ---*/ - + b = new su2double [nVar]; A = new su2double* [nVar]; M = new su2double* [nVar]; @@ -1289,27 +1287,27 @@ void CAdjEulerSolver::SetIntBoundary_Jump(CGeometry *geometry, CSolver **solver_ M[iVar] = new su2double [nVar]; AM[iVar] = new su2double [nVar]; } - + /*--- If equivalent area objective function, read the value of the derivative from a file, this is a preprocess of the direct solution ---*/ - + if (config->GetKind_ObjFunc() == EQUIVALENT_AREA) { - + /*--- Read derivative of the objective function at the NearField from file ---*/ index_file.open("WeightNF.dat", ios::in); if (index_file.fail()) { SU2_MPI::Error("There is no Weight Nearfield Pressure file (WeightNF.dat).", CURRENT_FUNCTION); } - + nPointNearField = 0; - + while (index_file) { string line; getline(index_file, line); istringstream is(line); - + /*--- The first row provides the azimuthal angle ---*/ - + if (nPointNearField == 0) { is >> data; // The first column is related with the coordinate while (is.good()) { is >> data; IndexNF.push_back(SU2_TYPE::Int(data)); } @@ -1322,14 +1320,14 @@ void CAdjEulerSolver::SetIntBoundary_Jump(CGeometry *geometry, CSolver **solver_ } nPointNearField++; } - + /*--- Note tha the first row is the azimuthal angle ---*/ - + nPointNearField = nPointNearField - 1; - + for (AngleInt = 0; AngleInt < 180; AngleInt++) IndexNF_inv[AngleInt] = -1; - + if (IndexNF.size() <= 180) { for (iIndex = 0; iIndex < IndexNF.size(); iIndex++) IndexNF_inv[IndexNF[iIndex]] = iIndex; @@ -1337,76 +1335,76 @@ void CAdjEulerSolver::SetIntBoundary_Jump(CGeometry *geometry, CSolver **solver_ else { SU2_MPI::Error("", CURRENT_FUNCTION); } - + } - + /*--- Compute the jump on the adjoint variables for the upper and the lower side ---*/ - + for (iMarker = 0; iMarker < nMarker; iMarker++) - + if (config->GetMarker_All_KindBC(iMarker) == NEARFIELD_BOUNDARY) - + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt (Area); - + for (iDim = 0; iDim < nDim; iDim++) UnitNormal[iDim] = Normal[iDim]/Area; - + if (geometry->node[iPoint]->GetDomain()) { - + coord = geometry->node[iPoint]->GetCoord(); DerivativeOF = 0.0; - + /*--- Just in case the functional depend also on the surface pressure ---*/ - + WeightSB = 1.0-config->GetWeightCd(); - + su2double AoA, XcoordRot = 0.0, YcoordRot = 0.0, ZcoordRot = 0.0; - + if (nDim == 2) XcoordRot = coord[0]; if (nDim == 3) { - + /*--- Rotate the nearfield cylinder ---*/ - + AoA = -(config->GetAoA()*PI_NUMBER/180.0); XcoordRot = coord[0]*cos(AoA) - coord[2]*sin(AoA); YcoordRot = coord[1]; ZcoordRot = coord[0]*sin(AoA) + coord[2]*cos(AoA); } - + switch (config->GetKind_ObjFunc()) { case EQUIVALENT_AREA : - + if (nDim == 2) AngleInt = 0; - + if (nDim == 3) { - + /*--- Compute the azimuthal angle of the iPoint ---*/ - + AngleDouble = fabs(atan(-YcoordRot/ZcoordRot)*180.0/PI_NUMBER); - + /*--- Fix an azimuthal line due to misalignments of the near-field ---*/ - + su2double FixAzimuthalLine = config->GetFixAzimuthalLine(); - + if ((AngleDouble >= FixAzimuthalLine - 0.1) && (AngleDouble <= FixAzimuthalLine + 0.1)) AngleDouble = FixAzimuthalLine - 0.1; - + AngleInt = SU2_TYPE::Short(floor(AngleDouble + 0.5)); if (AngleInt < 0) AngleInt = 180 + AngleInt; - + } - + if (AngleInt <= 60) { iColumn = IndexNF_inv[AngleInt]; - + /*--- An azimuthal angle is not defined... this happens with MG levels ---*/ - + if (iColumn < 0.0) { if (IndexNF_inv[AngleInt+1] > 0) { iColumn = IndexNF_inv[AngleInt+1]; goto end; } if (IndexNF_inv[AngleInt-1] > 0) { iColumn = IndexNF_inv[AngleInt-1]; goto end; } @@ -1417,13 +1415,13 @@ void CAdjEulerSolver::SetIntBoundary_Jump(CGeometry *geometry, CSolver **solver_ if (IndexNF_inv[AngleInt+4] > 0) { iColumn = IndexNF_inv[AngleInt+4]; goto end; } if (IndexNF_inv[AngleInt-4] > 0) { iColumn = IndexNF_inv[AngleInt-4]; goto end; } } - + end: - + if (iColumn < 0.0) { cout <<" An azimuthal angle is not defined..." << endl; } - + /*--- Find the value of the weight in the table, using the azimuthal angle ---*/ - + MinDist = 1E6; for (iPointNearField = 0; iPointNearField < nPointNearField; iPointNearField++) { Dist = fabs(CoordNF[iPointNearField] - XcoordRot); @@ -1434,69 +1432,69 @@ void CAdjEulerSolver::SetIntBoundary_Jump(CGeometry *geometry, CSolver **solver_ } } else DerivativeOF = 0.0; - + if ((MinDist > 1E-6) || (coord[nDim-1] > 0.0)) DerivativeOF = 0.0; - + break; - + case NEARFIELD_PRESSURE : - + DerivativeOF = factor*WeightSB*(solver_container[FLOW_SOL]->GetNodes()->GetPressure(iPoint) - solver_container[FLOW_SOL]->GetPressure_Inf()); - + break; - + } - + /*--- Compute the jump of the adjoint variables (2D, and 3D problems) --*/ - + FlowSolution = solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint); - + Rho = FlowSolution[0]; Energy = FlowSolution[nVar-1]/FlowSolution[0]; - + sqvel = 0.0; proj_vel = 0.0; for (iDim = 0; iDim < nDim; iDim++) { velocity[iDim] = FlowSolution[iDim+1]/FlowSolution[0]; sqvel += velocity[iDim]*velocity[iDim]; proj_vel += velocity[iDim]*UnitNormal[iDim]; } - + if (nDim == 2) { - + /*--- Compute the projected Jacobian ---*/ - + A[0][0] = 0.0; A[0][1] = 0.0; A[0][2] = 1.0; A[0][3] = 0.0; A[1][0] = -velocity[0]*velocity[1]; A[1][1] = velocity[1]; A[1][2] = velocity[0]; A[1][3] = 0.0; A[2][0] = 0.5*(Gamma-3.0)*velocity[1]*velocity[1]+0.5*Gamma_Minus_One*velocity[0]*velocity[0]; A[2][1] = -Gamma_Minus_One*velocity[0]; A[2][2] = (3.0-Gamma)*velocity[1]; A[2][3] = Gamma_Minus_One; A[3][0] = -Gamma*velocity[1]*Energy+Gamma_Minus_One*velocity[1]*sqvel; A[3][1] = -Gamma_Minus_One*velocity[0]*velocity[1]; A[3][2] = Gamma*Energy-0.5*Gamma_Minus_One*(velocity[0]*velocity[0]+3.0*velocity[1]*velocity[1]); A[3][3] = Gamma*velocity[1]; - + /*--- Compute the transformation matrix ---*/ - + M[0][0] = 1.0; M[0][1] = 0.0; M[0][2] = 0.0; M[0][3] = 0.0; M[1][0] = velocity[0]; M[1][1] = Rho; M[1][2] = 0.0; M[1][3] = 0.0; M[2][0] = velocity[1]; M[2][1] = 0.0; M[2][2] = Rho; M[2][3] = 0.0; M[3][0] = 0.5*sqvel; M[3][1] = Rho*velocity[0]; M[3][2] = Rho*velocity[1]; M[3][3] = 1.0/Gamma_Minus_One; - + /*--- Create the soruce term (AM)^T X = b ---*/ - + b[0] = 0.0; b[1] = 0.0; b[2] = 0.0; b[3] = DerivativeOF; - + } - + if (nDim == 3) { - - + + /*--- Compute the projected Jacobian ---*/ - + phi = 0.5*Gamma_Minus_One*sqvel; a1 = Gamma*Energy-phi; a2 = Gamma-1.0; - + A[0][0] = 0.0; for (iDim = 0; iDim < nDim; iDim++) A[0][iDim+1] = UnitNormal[iDim]; A[0][nDim+1] = 0.0; - + for (iDim = 0; iDim < nDim; iDim++) { A[iDim+1][0] = (UnitNormal[iDim]*phi - velocity[iDim]*proj_vel); for (jDim = 0; jDim < nDim; jDim++) @@ -1504,29 +1502,29 @@ void CAdjEulerSolver::SetIntBoundary_Jump(CGeometry *geometry, CSolver **solver_ A[iDim+1][iDim+1] += proj_vel; A[iDim+1][nDim+1] = a2*UnitNormal[iDim]; } - + A[nDim+1][0] = proj_vel*(phi-a1); for (iDim = 0; iDim < nDim; iDim++) A[nDim+1][iDim+1] = (UnitNormal[iDim]*a1-a2*velocity[iDim]*proj_vel); A[nDim+1][nDim+1] = Gamma*proj_vel; - + /*--- Compute the transformation matrix ---*/ - + M[0][0] = 1.0; M[0][1] = 0.0; M[0][2] = 0.0; M[0][3] = 0.0; M[0][4] = 0.0; M[1][0] = velocity[0]; M[1][1] = Rho; M[1][2] = 0.0; M[1][3] = 0.0; M[1][4] = 0.0; M[2][0] = velocity[1]; M[2][1] = 0.0; M[2][2] = Rho; M[2][3] = 0.0; M[2][4] = 0.0; M[3][0] = velocity[2]; M[3][1] = 0.0; M[3][2] = 0.0; M[3][3] = Rho; M[3][4] = 0.0; M[4][0] = 0.5*sqvel; M[4][1] = Rho*velocity[0]; M[4][2] = Rho*velocity[1]; M[4][3] = Rho*velocity[2]; M[4][4] = 1.0/Gamma_Minus_One; - + /*--- Create the soruce term (AM)^T X = b ---*/ - + b[0] = 0.0; b[1] = 0.0; b[2] = 0.0; b[3] = 0.0; b[4] = DerivativeOF; - + } - + /*--- Compute A times M ---*/ - + for (iVar = 0; iVar < nVar; iVar++) for (jVar = 0; jVar < nVar; jVar++) { aux = 0.0; @@ -1534,31 +1532,31 @@ void CAdjEulerSolver::SetIntBoundary_Jump(CGeometry *geometry, CSolver **solver_ aux += A[iVar][kVar]*M[kVar][jVar]; AM[iVar][jVar] = aux; } - + /*--- Compute the transpose matrix ---*/ - + for (iVar = 0; iVar < nVar; iVar++) for (jVar = 0; jVar < nVar; jVar++) A[iVar][jVar] = AM[jVar][iVar]; - + /*--- Solve the linear system using a LU descomposition --*/ - + Gauss_Elimination(A, b, nVar); - + /*--- Update the internal boundary jump --*/ - + for (iVar = 0; iVar < nVar; iVar++) IntBound_Vector[iVar] = b[iVar]; - + nodes->SetIntBoundary_Jump(iPoint,IntBound_Vector); - + } } - + delete [] IntBound_Vector; - + /*--- Deallocate the linear system ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { delete [] A[iVar]; delete [] M[iVar]; @@ -1568,18 +1566,18 @@ void CAdjEulerSolver::SetIntBoundary_Jump(CGeometry *geometry, CSolver **solver_ delete [] M; delete [] AM; delete [] b; - + } void CAdjEulerSolver::SetInitialCondition(CGeometry **geometry, CSolver ***solver_container, CConfig *config, unsigned long TimeIter) { unsigned long iPoint, Point_Fine; unsigned short iMesh, iChildren, iVar; su2double Area_Children, Area_Parent, *Solution, *Solution_Fine; - + bool restart = config->GetRestart(); bool dual_time = ((config->GetTime_Marching() == DT_STEPPING_1ST) || (config->GetTime_Marching() == DT_STEPPING_2ND)); - + /*--- If restart solution, then interpolate the flow solution to all the multigrid levels, this is important with the dual time strategy ---*/ if (restart) { @@ -1597,14 +1595,14 @@ void CAdjEulerSolver::SetInitialCondition(CGeometry **geometry, CSolver ***solve } } solver_container[iMesh][ADJFLOW_SOL]->GetNodes()->SetSolution(iPoint, Solution); - + } solver_container[iMesh][ADJFLOW_SOL]->InitiateComms(geometry[iMesh], config, SOLUTION); solver_container[iMesh][ADJFLOW_SOL]->CompleteComms(geometry[iMesh], config, SOLUTION); } delete [] Solution; } - + /*--- The value of the solution for the first iteration of the dual time ---*/ for (iMesh = 0; iMesh <= config->GetnMGLevels(); iMesh++) { if ((TimeIter == 0) && (dual_time)) { @@ -1612,18 +1610,18 @@ void CAdjEulerSolver::SetInitialCondition(CGeometry **geometry, CSolver ***solve solver_container[iMesh][ADJFLOW_SOL]->GetNodes()->Set_Solution_time_n1(); } } - + } void CAdjEulerSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output) { - + unsigned long iPoint, nonPhysicalPoints = 0; su2double SharpEdge_Distance; bool physical = true; - + /*--- Retrieve information about the spatial and temporal integration for the adjoint equations (note that the flow problem may use different methods). ---*/ - + bool implicit = (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); bool muscl = config->GetMUSCL_AdjFlow(); bool limiter = (config->GetKind_SlopeLimit_AdjFlow() != NO_LIMITER); @@ -1633,51 +1631,51 @@ void CAdjEulerSolver::Preprocessing(CGeometry *geometry, CSolver **solver_contai bool eval_dof_dcx = config->GetEval_dOF_dCX(); /*--- Update the objective function coefficient to guarantee zero gradient. ---*/ - + if (fixed_cl && eval_dof_dcx) { SetFarfield_AoA(geometry, solver_container, config, iMesh, Output); } - + /*--- Residual initialization ---*/ - + for (iPoint = 0; iPoint < nPoint; iPoint ++) { - + /*--- Get the distance form a sharp edge ---*/ - + SharpEdge_Distance = geometry->node[iPoint]->GetSharpEdge_Distance(); /*--- Set the primitive variables compressible adjoint variables ---*/ - + physical = nodes->SetPrimVar(iPoint,SharpEdge_Distance, false, config); /* Check for non-realizable states for reporting. */ - + if (!physical) nonPhysicalPoints++; - + /*--- Initialize the convective residual vector ---*/ - + if (!Output) LinSysRes.SetBlock_Zero(iPoint); - + } - + if ((muscl) && (iMesh == MESH_0)) { - + /*--- Gradient computation for MUSCL reconstruction. ---*/ - + if (config->GetKind_Gradient_Method_Recon() == GREEN_GAUSS) SetSolution_Gradient_GG(geometry, config, true); if (config->GetKind_Gradient_Method_Recon() == LEAST_SQUARES) SetSolution_Gradient_LS(geometry, config, true); if (config->GetKind_Gradient_Method_Recon() == WEIGHTED_LEAST_SQUARES) SetSolution_Gradient_LS(geometry, config, true); - + /*--- Limiter computation ---*/ - + if (limiter && !Output) SetSolution_Limiter(geometry, config); - + } - + /*--- Artificial dissipation for centered schemes ---*/ - + if (center) { if ((center_jst) && (iMesh == MESH_0)) { SetCentered_Dissipation_Sensor(geometry, config); @@ -1686,13 +1684,13 @@ void CAdjEulerSolver::Preprocessing(CGeometry *geometry, CSolver **solver_contai if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) SetSolution_Gradient_LS(geometry, config); } } - + /*--- Initialize the Jacobian for implicit integration ---*/ - + if (implicit) Jacobian.SetValZero(); - + /*--- Error message ---*/ - + if (config->GetComm_Level() == COMM_FULL) { #ifdef HAVE_MPI unsigned long MyErrorCounter = nonPhysicalPoints; nonPhysicalPoints = 0; @@ -1700,138 +1698,138 @@ void CAdjEulerSolver::Preprocessing(CGeometry *geometry, CSolver **solver_contai #endif if (iMesh == MESH_0) config->SetNonphysical_Points(nonPhysicalPoints); } - + } void CAdjEulerSolver::Centered_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short iMesh, unsigned short iRKStep) { - + unsigned long iEdge, iPoint, jPoint; - + bool implicit = (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); bool jst_scheme = ((config->GetKind_Centered_AdjFlow() == JST) && (iMesh == MESH_0)); bool grid_movement = config->GetGrid_Movement(); for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - + /*--- Points in edge, normal, and neighbors---*/ - + iPoint = geometry->edge[iEdge]->GetNode(0); jPoint = geometry->edge[iEdge]->GetNode(1); numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); numerics->SetNeighbor(geometry->node[iPoint]->GetnNeighbor(), geometry->node[jPoint]->GetnNeighbor()); - + /*--- Adjoint variables w/o reconstruction ---*/ numerics->SetAdjointVar(nodes->GetSolution(iPoint), nodes->GetSolution(jPoint)); - + /*--- Conservative variables w/o reconstruction ---*/ numerics->SetConservative(solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint), solver_container[FLOW_SOL]->GetNodes()->GetSolution(jPoint)); - + numerics->SetSoundSpeed(solver_container[FLOW_SOL]->GetNodes()->GetSoundSpeed(iPoint), solver_container[FLOW_SOL]->GetNodes()->GetSoundSpeed(jPoint)); numerics->SetEnthalpy(solver_container[FLOW_SOL]->GetNodes()->GetEnthalpy(iPoint), solver_container[FLOW_SOL]->GetNodes()->GetEnthalpy(jPoint)); - + numerics->SetLambda(solver_container[FLOW_SOL]->GetNodes()->GetLambda(iPoint), solver_container[FLOW_SOL]->GetNodes()->GetLambda(jPoint)); - + if (jst_scheme) { numerics->SetUndivided_Laplacian(nodes->GetUndivided_Laplacian(iPoint), nodes->GetUndivided_Laplacian(jPoint)); numerics->SetSensor(nodes->GetSensor(iPoint), nodes->GetSensor(jPoint)); } - + /*--- Mesh motion ---*/ - + if (grid_movement) { numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[jPoint]->GetGridVel()); } - + /*--- Compute residuals ---*/ numerics->ComputeResidual(Res_Conv_i, Res_Visc_i, Res_Conv_j, Res_Visc_j, Jacobian_ii, Jacobian_ij, Jacobian_ji, Jacobian_jj, config); - + /*--- Update convective and artificial dissipation residuals ---*/ LinSysRes.SubtractBlock(iPoint, Res_Conv_i); LinSysRes.SubtractBlock(jPoint, Res_Conv_j); LinSysRes.SubtractBlock(iPoint, Res_Visc_i); LinSysRes.SubtractBlock(jPoint, Res_Visc_j); - + /*--- Implicit contribution to the residual ---*/ - + if (implicit) { Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_ii); Jacobian.SubtractBlock(iPoint, jPoint, Jacobian_ij); Jacobian.SubtractBlock(jPoint, iPoint, Jacobian_ji); Jacobian.SubtractBlock(jPoint, jPoint, Jacobian_jj); } - + } } void CAdjEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short iMesh) { - + su2double **Gradient_i, **Gradient_j, Project_Grad_i, Project_Grad_j, *Limiter_i = NULL, *Limiter_j = NULL, *Psi_i = NULL, *Psi_j = NULL, *V_i, *V_j; unsigned long iEdge, iPoint, jPoint, counter_local = 0, counter_global = 0; unsigned short iDim, iVar; - + bool implicit = (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); bool muscl = (config->GetMUSCL_AdjFlow() && (iMesh == MESH_0)); bool limiter = (config->GetKind_SlopeLimit_AdjFlow() != NO_LIMITER); bool grid_movement = config->GetGrid_Movement(); - + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - + /*--- Points in edge and normal vectors ---*/ - + iPoint = geometry->edge[iEdge]->GetNode(0); jPoint = geometry->edge[iEdge]->GetNode(1); numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); - + /*--- Adjoint variables w/o reconstruction ---*/ - + Psi_i = nodes->GetSolution(iPoint); Psi_j = nodes->GetSolution(jPoint); numerics->SetAdjointVar(Psi_i, Psi_j); - + /*--- Primitive variables w/o reconstruction ---*/ - + V_i = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); V_j = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(jPoint); numerics->SetPrimitive(V_i, V_j); - + /*--- Grid velocities for dynamic meshes ---*/ - + if (grid_movement) { numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[jPoint]->GetGridVel()); } - + /*--- High order reconstruction using MUSCL strategy ---*/ - + if (muscl) { - + for (iDim = 0; iDim < nDim; iDim++) { Vector_i[iDim] = 0.5*(geometry->node[jPoint]->GetCoord(iDim) - geometry->node[iPoint]->GetCoord(iDim)); Vector_j[iDim] = 0.5*(geometry->node[iPoint]->GetCoord(iDim) - geometry->node[jPoint]->GetCoord(iDim)); } - + /*--- Adjoint variables using gradient reconstruction and limiters ---*/ Gradient_i = nodes->GetGradient_Reconstruction(iPoint); Gradient_j = nodes->GetGradient_Reconstruction(jPoint); - + if (limiter) { Limiter_i = nodes->GetLimiter(iPoint); Limiter_j = nodes->GetLimiter(jPoint); } - + for (iVar = 0; iVar < nVar; iVar++) { Project_Grad_i = 0; Project_Grad_j = 0; for (iDim = 0; iDim < nDim; iDim++) { @@ -1847,23 +1845,23 @@ void CAdjEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_cont Solution_j[iVar] = Psi_j[iVar] + Project_Grad_j; } } - + /* Check our reconstruction for exceeding bounds on the adjoint density. */ - + su2double adj_limit = config->GetAdjointLimit(); bool phi_bound_i = (fabs(Solution_i[0]) > adj_limit); bool phi_bound_j = (fabs(Solution_j[0]) > adj_limit); if (phi_bound_i) nodes->SetNon_Physical(iPoint, true); else nodes->SetNon_Physical(iPoint, false); - + if (phi_bound_j) nodes->SetNon_Physical(jPoint, true); else nodes->SetNon_Physical(jPoint, false); - + /* Lastly, check for existing first-order points still active from previous iterations. */ - + if (nodes->GetNon_Physical(iPoint)) { counter_local++; for (iVar = 0; iVar < nVar; iVar++) @@ -1876,31 +1874,31 @@ void CAdjEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_cont } numerics->SetAdjointVar(Solution_i, Solution_j); - + } - + /*--- Compute the residual---*/ - + numerics->ComputeResidual(Residual_i, Residual_j, Jacobian_ii, Jacobian_ij, Jacobian_ji, Jacobian_jj, config); - + /*--- Add and Subtract Residual ---*/ - + LinSysRes.SubtractBlock(iPoint, Residual_i); LinSysRes.SubtractBlock(jPoint, Residual_j); - + /*--- Implicit contribution to the residual ---*/ - + if (implicit) { Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_ii); Jacobian.SubtractBlock(iPoint, jPoint, Jacobian_ij); Jacobian.SubtractBlock(jPoint, iPoint, Jacobian_ji); Jacobian.SubtractBlock(jPoint, jPoint, Jacobian_jj); } - + } - + /*--- Warning message about non-physical reconstructions. ---*/ - + if (config->GetComm_Level() == COMM_FULL) { #ifdef HAVE_MPI SU2_MPI::Reduce(&counter_local, &counter_global, 1, MPI_UNSIGNED_LONG, MPI_SUM, MASTER_NODE, MPI_COMM_WORLD); @@ -1909,12 +1907,12 @@ void CAdjEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_cont #endif if (iMesh == MESH_0) config->SetNonphysical_Reconstr(counter_global); } - + } void CAdjEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CNumerics *second_numerics, CConfig *config, unsigned short iMesh) { - + unsigned short iVar; unsigned long iPoint; bool implicit = (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); @@ -1922,97 +1920,97 @@ void CAdjEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont bool axisymmetric = config->GetAxisymmetric(); // bool gravity = (config->GetGravityForce() == YES); bool harmonic_balance = (config->GetTime_Marching() == HARMONIC_BALANCE); - + /*--- Initialize the source residual to zero ---*/ for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = 0.0; - + if (rotating_frame) { - + /*--- Loop over all points ---*/ for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /*--- Load the adjoint variables ---*/ numerics->SetAdjointVar(nodes->GetSolution(iPoint), nodes->GetSolution(iPoint)); - + /*--- Load the volume of the dual mesh cell ---*/ numerics->SetVolume(geometry->node[iPoint]->GetVolume()); - + /*--- Compute the adjoint rotating frame source residual ---*/ numerics->ComputeResidual(Residual, Jacobian_i, config); - + /*--- Add the source residual to the total ---*/ LinSysRes.AddBlock(iPoint, Residual); - + /*--- Add the implicit Jacobian contribution ---*/ if (implicit) Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - + } } - + if (harmonic_balance) { - + su2double Volume, Source; - + /*--- loop over points ---*/ for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /*--- Get control volume ---*/ Volume = geometry->node[iPoint]->GetVolume(); - + /*--- Get stored harmonic balance source term ---*/ for (iVar = 0; iVar < nVar; iVar++) { Source = nodes->GetHarmonicBalance_Source(iPoint,iVar); Residual[iVar] = Source*Volume; } - + /*--- Add Residual ---*/ LinSysRes.AddBlock(iPoint, Residual); - + } } - + if (axisymmetric) { - + /*--- Zero out Jacobian structure ---*/ if (implicit) { for (iVar = 0; iVar < nVar; iVar ++) for (unsigned short jVar = 0; jVar < nVar; jVar ++) Jacobian_i[iVar][jVar] = 0.0; } - + /*--- loop over points ---*/ for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /*--- Set solution ---*/ numerics->SetConservative(solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint), solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint)); - + /*--- Set adjoint variables ---*/ numerics->SetAdjointVar(nodes->GetSolution(iPoint), nodes->GetSolution(iPoint)); - + /*--- Set control volume ---*/ numerics->SetVolume(geometry->node[iPoint]->GetVolume()); - + /*--- Set coordinate ---*/ numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[iPoint]->GetCoord()); - + /*--- Compute Source term Residual ---*/ numerics->ComputeResidual(Residual, Jacobian_i, config); - + /*--- Add Residual ---*/ LinSysRes.AddBlock(iPoint, Residual); - + /*--- Implicit part ---*/ if (implicit) Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - + } } - + // if (gravity) { // // } - + } void CAdjEulerSolver::Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, @@ -2023,130 +2021,130 @@ void CAdjEulerSolver::SetUndivided_Laplacian(CGeometry *geometry, CConfig *confi unsigned long iPoint, jPoint, iEdge; unsigned short iVar; su2double *Diff; - + Diff = new su2double[nVar]; - + nodes->SetUnd_LaplZero(); - + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { iPoint = geometry->edge[iEdge]->GetNode(0); jPoint = geometry->edge[iEdge]->GetNode(1); - + for (iVar = 0; iVar < nVar; iVar++) Diff[iVar] = nodes->GetSolution(iPoint,iVar) - nodes->GetSolution(jPoint,iVar); - + #ifdef STRUCTURED_GRID - + if (geometry->node[iPoint]->GetDomain()) nodes->SubtractUnd_Lapl(iPoint, Diff); if (geometry->node[jPoint]->GetDomain()) nodes->AddUnd_Lapl(jPoint, Diff); - + #else - + bool boundary_i = geometry->node[iPoint]->GetPhysicalBoundary(); bool boundary_j = geometry->node[jPoint]->GetPhysicalBoundary(); - + /*--- Both points inside the domain, or both in the boundary ---*/ if ((!boundary_i && !boundary_j) || (boundary_i && boundary_j)) { if (geometry->node[iPoint]->GetDomain()) nodes->SubtractUnd_Lapl(iPoint, Diff); if (geometry->node[jPoint]->GetDomain()) nodes->AddUnd_Lapl(jPoint, Diff); } - + /*--- iPoint inside the domain, jPoint on the boundary ---*/ if (!boundary_i && boundary_j) if (geometry->node[iPoint]->GetDomain()) nodes->SubtractUnd_Lapl(iPoint, Diff); - + /*--- jPoint inside the domain, iPoint on the boundary ---*/ if (boundary_i && !boundary_j) if (geometry->node[jPoint]->GetDomain()) nodes->AddUnd_Lapl(jPoint, Diff); - + #endif - + } - + #ifdef STRUCTURED_GRID - + unsigned long Point_Normal = 0, iVertex; unsigned short iMarker; su2double *Psi_mirror; - + Psi_mirror = new su2double[nVar]; - + /*--- Loop over all boundaries and include an extra contribution from a halo node. Find the nearest normal, interior point for a boundary node and make a linear approximation. ---*/ for (iMarker = 0; iMarker < nMarker; iMarker++) { - + if (config->GetMarker_All_KindBC(iMarker) != SEND_RECEIVE && config->GetMarker_All_KindBC(iMarker) != INTERFACE_BOUNDARY && config->GetMarker_All_KindBC(iMarker) != NEARFIELD_BOUNDARY) { - + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - + if (geometry->node[iPoint]->GetDomain()) { - + Point_Normal = geometry->vertex[iMarker][iVertex]->GetNormal_Neighbor(); - + /*--- Interpolate & compute difference in the conserved variables ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { Psi_mirror[iVar] = 2.0*node[iPoint]->GetSolution(iVar) - nodes->GetSolution(Point_Normal, iVar); Diff[iVar] = nodes->GetSolution(iPoint,iVar) - Psi_mirror[iVar]; } - + /*--- Subtract contribution at the boundary node only ---*/ - + nodes->SubtractUnd_Lapl(iPoint,Diff); } } } } - + delete [] Psi_mirror; - + #endif - + delete [] Diff; - + /*--- MPI parallelization ---*/ - + InitiateComms(geometry, config, UNDIVIDED_LAPLACIAN); CompleteComms(geometry, config, UNDIVIDED_LAPLACIAN); - + } void CAdjEulerSolver::SetCentered_Dissipation_Sensor(CGeometry *geometry, CConfig *config) { - + unsigned long iPoint; su2double SharpEdge_Distance, eps, ds, scale, Sensor, Param_Kappa_2, Param_Kappa_4; - + eps = config->GetVenkat_LimiterCoeff()*config->GetRefElemLength(); Param_Kappa_2 = config->GetKappa_2nd_AdjFlow(); Param_Kappa_4 = config->GetKappa_4th_AdjFlow(); - + if (Param_Kappa_2 != 0.0) scale = 2.0 * Param_Kappa_4 / Param_Kappa_2; else scale = 0.0; - + for (iPoint = 0; iPoint < nPoint; iPoint++) { - + SharpEdge_Distance = (geometry->node[iPoint]->GetSharpEdge_Distance() - config->GetAdjSharp_LimiterCoeff()*eps); - + ds = 0.0; if (SharpEdge_Distance < -eps) ds = 1.0; if (fabs(SharpEdge_Distance) <= eps) ds = 1.0 - (0.5*(1.0+(SharpEdge_Distance/eps)+(1.0/PI_NUMBER)*sin(PI_NUMBER*SharpEdge_Distance/eps))); if (SharpEdge_Distance > eps) ds = 0.0; - + Sensor = scale * ds; - + nodes->SetSensor(iPoint,Sensor); - + } - + /*--- MPI parallelization ---*/ - + InitiateComms(geometry, config, SENSOR); CompleteComms(geometry, config, SENSOR); - + } void CAdjEulerSolver::ExplicitRK_Iteration(CGeometry *geometry, CSolver **solver_container, @@ -2154,105 +2152,105 @@ void CAdjEulerSolver::ExplicitRK_Iteration(CGeometry *geometry, CSolver **solver su2double *Residual, *Res_TruncError, Vol, Delta, Res; unsigned short iVar; unsigned long iPoint; - + su2double RK_AlphaCoeff = config->Get_Alpha_RKStep(iRKStep); - + for (iVar = 0; iVar < nVar; iVar++) { SetRes_RMS(iVar, 0.0); SetRes_Max(iVar, 0.0, 0); } - + /*--- Update the solution ---*/ for (iPoint = 0; iPoint < nPointDomain; iPoint++) { Vol = geometry->node[iPoint]->GetVolume(); Delta = solver_container[FLOW_SOL]->GetNodes()->GetDelta_Time(iPoint) / Vol; - + Res_TruncError = nodes->GetResTruncError(iPoint); Residual = LinSysRes.GetBlock(iPoint); - + for (iVar = 0; iVar < nVar; iVar++) { Res = Residual[iVar] + Res_TruncError[iVar]; nodes->AddSolution(iPoint,iVar, -Res*Delta*RK_AlphaCoeff); AddRes_RMS(iVar, Res*Res); AddRes_Max(iVar, fabs(Res), geometry->node[iPoint]->GetGlobalIndex(), geometry->node[iPoint]->GetCoord()); } - + } - + /*--- MPI solution ---*/ - + InitiateComms(geometry, config, SOLUTION); CompleteComms(geometry, config, SOLUTION); - + /*--- Compute the root mean square residual ---*/ SetResidual_RMS(geometry, config); - + } void CAdjEulerSolver::ExplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { su2double *local_Residual, *local_Res_TruncError, Vol, Delta, Res; unsigned short iVar; unsigned long iPoint; - + for (iVar = 0; iVar < nVar; iVar++) { SetRes_RMS(iVar, 0.0); SetRes_Max(iVar, 0.0, 0); } - + /*--- Update the solution ---*/ for (iPoint = 0; iPoint < nPointDomain; iPoint++) { Vol = geometry->node[iPoint]->GetVolume(); Delta = solver_container[FLOW_SOL]->GetNodes()->GetDelta_Time(iPoint) / Vol; - + local_Res_TruncError = nodes->GetResTruncError(iPoint); local_Residual = LinSysRes.GetBlock(iPoint); - + for (iVar = 0; iVar < nVar; iVar++) { Res = local_Residual[iVar] + local_Res_TruncError[iVar]; nodes->AddSolution(iPoint,iVar, -Res*Delta); AddRes_RMS(iVar, Res*Res); AddRes_Max(iVar, fabs(Res), geometry->node[iPoint]->GetGlobalIndex(), geometry->node[iPoint]->GetCoord()); } - + } - + /*--- MPI solution ---*/ - + InitiateComms(geometry, config, SOLUTION); CompleteComms(geometry, config, SOLUTION); - + /*--- Compute the root mean square residual ---*/ SetResidual_RMS(geometry, config); - + } void CAdjEulerSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { - + unsigned short iVar; unsigned long iPoint, total_index; su2double Delta, *local_Res_TruncError, Vol; - + /*--- Set maximum residual to zero ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { SetRes_RMS(iVar, 0.0); SetRes_Max(iVar, 0.0, 0); } - + /*--- Build implicit system ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /*--- Read the residual ---*/ - + local_Res_TruncError = nodes->GetResTruncError(iPoint); - + /*--- Read the volume ---*/ - + Vol = geometry->node[iPoint]->GetVolume(); - + /*--- Modify matrix diagonal to assure diagonal dominance ---*/ - + if (solver_container[FLOW_SOL]->GetNodes()->GetDelta_Time(iPoint) != 0.0) { Delta = Vol / solver_container[FLOW_SOL]->GetNodes()->GetDelta_Time(iPoint); Jacobian.AddVal2Diag(iPoint, Delta); @@ -2265,9 +2263,9 @@ void CAdjEulerSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **sol local_Res_TruncError[iVar] = 0.0; } } - + /*--- Right hand side of the system (-Residual) and initial guess (x = 0) ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { total_index = iPoint*nVar+iVar; LinSysRes[total_index] = -(LinSysRes[total_index] + local_Res_TruncError[iVar]); @@ -2275,11 +2273,11 @@ void CAdjEulerSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **sol AddRes_RMS(iVar, LinSysRes[total_index]*LinSysRes[total_index]); AddRes_Max(iVar, fabs(LinSysRes[total_index]), geometry->node[iPoint]->GetGlobalIndex(), geometry->node[iPoint]->GetCoord()); } - + } - + /*--- Initialize residual and solution at the ghost points ---*/ - + for (iPoint = nPointDomain; iPoint < nPoint; iPoint++) { for (iVar = 0; iVar < nVar; iVar++) { total_index = iPoint*nVar + iVar; @@ -2287,31 +2285,31 @@ void CAdjEulerSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **sol LinSysSol[total_index] = 0.0; } } - + /*--- Solve or smooth the linear system ---*/ - + System.Solve(Jacobian, LinSysRes, LinSysSol, geometry, config); - + /*--- Update solution (system written in terms of increments) ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) for (iVar = 0; iVar < nVar; iVar++) { nodes->AddSolution(iPoint,iVar, config->GetRelaxation_Factor_AdjFlow()*LinSysSol[iPoint*nVar+iVar]); } - + /*--- MPI solution ---*/ - + InitiateComms(geometry, config, SOLUTION); CompleteComms(geometry, config, SOLUTION); - + /*--- Compute the root mean square residual ---*/ - + SetResidual_RMS(geometry, config); - + } void CAdjEulerSolver::Inviscid_Sensitivity(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config) { - + unsigned long iVertex, iPoint, Neigh; unsigned short iPos, jPos; unsigned short iDim, iMarker, iNeigh; @@ -2322,7 +2320,7 @@ void CAdjEulerSolver::Inviscid_Sensitivity(CGeometry *geometry, CSolver **solver dp_drw, dp_drE, dH_dr, dH_dru, dH_drv, dH_drw, dH_drE, H, *USens, D[3][3], Dd[3], scale = 1.0; su2double RefVel2, RefDensity, Mach2Vel, *Velocity_Inf, factor; su2double Vn, SoundSpeed, *Velocity; - + USens = new su2double[nVar]; Velocity = new su2double[nDim]; @@ -2334,12 +2332,12 @@ void CAdjEulerSolver::Inviscid_Sensitivity(CGeometry *geometry, CSolver **solver if (config->GetSystemMeasurements() == US) scale = 1.0/12.0; else scale = 1.0; - - /*--- Compute non-dimensional factor. For dynamic meshes, use the motion Mach - number as a reference value for computing the force coefficients. + + /*--- Compute non-dimensional factor. For dynamic meshes, use the motion Mach + number as a reference value for computing the force coefficients. Otherwise, use the freestream values, which is the standard convention. ---*/ - + if (grid_movement) { Mach2Vel = sqrt(Gamma*Gas_Constant*config->GetTemperature_FreeStreamND()); RefVel2 = (Mach_Motion*Mach2Vel)*(Mach_Motion*Mach2Vel); @@ -2350,7 +2348,7 @@ void CAdjEulerSolver::Inviscid_Sensitivity(CGeometry *geometry, CSolver **solver for (iDim = 0; iDim < nDim; iDim++) RefVel2 += Velocity_Inf[iDim]*Velocity_Inf[iDim]; } - + RefDensity = config->GetDensity_FreeStreamND(); factor = 1.0; @@ -2367,22 +2365,22 @@ void CAdjEulerSolver::Inviscid_Sensitivity(CGeometry *geometry, CSolver **solver } /*--- Initialize sensitivities to zero ---*/ - + Total_Sens_Geo = 0.0; Total_Sens_Mach = 0.0; Total_Sens_AoA = 0.0; Total_Sens_Press = 0.0; Total_Sens_Temp = 0.0; Total_Sens_BPress = 0.0; - + /*--- Loop over boundary markers to select those for Euler walls ---*/ - + for (iMarker = 0; iMarker < nMarker; iMarker++) if (config->GetMarker_All_KindBC(iMarker) == EULER_WALL) - + /*--- Loop over points on the surface to store the auxiliary variable ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); if (geometry->node[iPoint]->GetDomain()) { @@ -2391,11 +2389,11 @@ void CAdjEulerSolver::Inviscid_Sensitivity(CGeometry *geometry, CSolver **solver Enthalpy = solver_container[FLOW_SOL]->GetNodes()->GetEnthalpy(iPoint); conspsi = U[0]*Psi[0] + U[0]*Enthalpy*Psi[nDim+1]; for (iDim = 0; iDim < nDim; iDim++) conspsi += U[iDim+1]*Psi[iDim+1]; - + nodes->SetAuxVar(iPoint,conspsi); - + /*--- Also load the auxiliary variable for first neighbors ---*/ - + for (iNeigh = 0; iNeigh < geometry->node[iPoint]->GetnPoint(); iNeigh++) { Neigh = geometry->node[iPoint]->GetPoint(iNeigh); Psi = nodes->GetSolution(Neigh); @@ -2407,81 +2405,81 @@ void CAdjEulerSolver::Inviscid_Sensitivity(CGeometry *geometry, CSolver **solver } } } - + /*--- Compute surface gradients of the auxiliary variable ---*/ - + SetAuxVar_Surface_Gradient(geometry, config); - + /*--- Evaluate the shape sensitivity ---*/ - + for (iMarker = 0; iMarker < nMarker; iMarker++) { Sens_Geo[iMarker] = 0.0; - + if (config->GetMarker_All_KindBC(iMarker) == EULER_WALL) { for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); if (geometry->node[iPoint]->GetDomain()) { - + d = nodes->GetForceProj_Vector(iPoint); Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); Area = 0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); - + PrimVar_Grad = solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint); ConsPsi_Grad = nodes->GetAuxVarGradient(iPoint); ConsPsi = nodes->GetAuxVar(iPoint); - + d_press = 0.0; grad_v = 0.0; v_gradconspsi = 0.0; for (iDim = 0; iDim < nDim; iDim++) { - + /*-- Retrieve the value of the pressure gradient ---*/ - + d_press += d[iDim]*PrimVar_Grad[nDim+1][iDim]; - + /*-- Retrieve the value of the velocity gradient ---*/ - + grad_v += PrimVar_Grad[iDim+1][iDim]*ConsPsi; - + /*-- Retrieve the value of the theta gradient ---*/ - + v_gradconspsi += solver_container[FLOW_SOL]->GetNodes()->GetVelocity(iPoint, iDim) * ConsPsi_Grad[iDim]; - + /*--- Additional sensitivity term for grid movement ---*/ - + if (grid_movement) { GridVel = geometry->node[iPoint]->GetGridVel(); v_gradconspsi -= GridVel[iDim] * ConsPsi_Grad[iDim]; } - + } - + /*--- Compute sensitivity for each surface point ---*/ - + CSensitivity[iMarker][iVertex] = (d_press + grad_v + v_gradconspsi) * Area * scale * factor; - + /*--- If sharp edge, set the sensitivity to 0 on that region ---*/ - + if (config->GetSens_Remove_Sharp()) { eps = config->GetVenkat_LimiterCoeff()*config->GetRefElemLength(); if ( geometry->node[iPoint]->GetSharpEdge_Distance() < config->GetAdjSharp_LimiterCoeff()*eps ) CSensitivity[iMarker][iVertex] = 0.0; } - + Sens_Geo[iMarker] -= CSensitivity[iMarker][iVertex]; - + } } - + Total_Sens_Geo += Sens_Geo[iMarker]; - + } } - - + + /*--- Farfield Sensitivity (Mach, AoA, Press, Temp), only for compressible flows ---*/ - + for (iMarker = 0; iMarker < nMarker; iMarker++) { Sens_BPress[iMarker] = 0.0; @@ -2761,58 +2759,58 @@ void CAdjEulerSolver::Inviscid_Sensitivity(CGeometry *geometry, CSolver **solver } } - + #ifdef HAVE_MPI - + su2double MyTotal_Sens_Geo = Total_Sens_Geo; Total_Sens_Geo = 0.0; su2double MyTotal_Sens_Mach = Total_Sens_Mach; Total_Sens_Mach = 0.0; su2double MyTotal_Sens_AoA = Total_Sens_AoA; Total_Sens_AoA = 0.0; su2double MyTotal_Sens_Press = Total_Sens_Press; Total_Sens_Press = 0.0; su2double MyTotal_Sens_Temp = Total_Sens_Temp; Total_Sens_Temp = 0.0; su2double MyTotal_Sens_BPress = Total_Sens_BPress; Total_Sens_BPress = 0.0; - + SU2_MPI::Allreduce(&MyTotal_Sens_Geo, &Total_Sens_Geo, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); SU2_MPI::Allreduce(&MyTotal_Sens_Mach, &Total_Sens_Mach, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); SU2_MPI::Allreduce(&MyTotal_Sens_AoA, &Total_Sens_AoA, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); SU2_MPI::Allreduce(&MyTotal_Sens_Press, &Total_Sens_Press, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); SU2_MPI::Allreduce(&MyTotal_Sens_Temp, &Total_Sens_Temp, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); SU2_MPI::Allreduce(&MyTotal_Sens_BPress, &Total_Sens_BPress, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - + #endif - + delete [] USens; delete [] Velocity; - + } void CAdjEulerSolver::Smooth_Sensitivity(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config) { unsigned short iMarker; unsigned long iVertex, jVertex, nVertex, iPoint; su2double **A, *b, Sens, *ArchLength, *Coord_begin, *Coord_end, dist; - + for (iMarker = 0; iMarker < nMarker; iMarker++) { if (config->GetMarker_All_KindBC(iMarker) == EULER_WALL) { nVertex = geometry->nVertex[iMarker]; - + /*--- Allocate the linear system ---*/ - + A = new su2double* [nVertex]; b = new su2double [nVertex]; ArchLength = new su2double [nVertex]; for (iVertex = 0; iVertex < nVertex; iVertex++) { A[iVertex] = new su2double [nVertex]; } - + /*--- Initialization ---*/ - + for (iVertex = 0; iVertex < nVertex; iVertex++) { b[iVertex] = 0.0; ArchLength[iVertex] = 0.0; for (jVertex = 0; jVertex < nVertex; jVertex++) A[iVertex][jVertex] = 0.0; } - + /*--- Set the arch length ---*/ - + ArchLength[0] = 0.0; for (iVertex = 1; iVertex < nVertex; iVertex++) { iPoint = geometry->vertex[iMarker][iVertex-1]->GetNode(); @@ -2822,39 +2820,39 @@ void CAdjEulerSolver::Smooth_Sensitivity(CGeometry *geometry, CSolver **solver_c dist = sqrt (pow( Coord_end[0]-Coord_begin[0], 2.0) + pow( Coord_end[1]-Coord_begin[1], 2.0)); ArchLength[iVertex] = ArchLength[iVertex-1] + dist; } - + /*--- Remove the trailing edge effect ---*/ - + su2double MinPosSens = 0.0; su2double MinNegSens = 0.0; for (iVertex = 0; iVertex < nVertex; iVertex++) { Sens = CSensitivity[iMarker][iVertex]; if (ArchLength[iVertex] > ArchLength[nVertex-1]*0.01) { MinNegSens = Sens; break; } } - + for (iVertex = 0; iVertex < nVertex; iVertex++) { Sens = CSensitivity[iMarker][iVertex]; if (ArchLength[iVertex] > ArchLength[nVertex-1]*0.99) { MinPosSens = Sens; break; } } - + for (iVertex = 0; iVertex < nVertex; iVertex++) { if (ArchLength[iVertex] < ArchLength[nVertex-1]*0.01) CSensitivity[iMarker][iVertex] = MinNegSens; if (ArchLength[iVertex] > ArchLength[nVertex-1]*0.99) CSensitivity[iMarker][iVertex] = MinPosSens; } - + /*--- Set the right hand side of the system ---*/ - + for (iVertex = 0; iVertex < nVertex; iVertex++) { b[iVertex] = CSensitivity[iMarker][iVertex]; } - + /*--- Set the mass matrix ---*/ - + su2double Coeff = 0.0, BackDiff = 0.0, ForwDiff = 0.0, CentDiff = 0.0; su2double epsilon = 5E-5; for (iVertex = 0; iVertex < nVertex; iVertex++) { - + if ((iVertex != nVertex-1) && (iVertex != 0)) { BackDiff = (ArchLength[iVertex]-ArchLength[iVertex-1]); ForwDiff = (ArchLength[iVertex+1]-ArchLength[iVertex]); @@ -2870,98 +2868,98 @@ void CAdjEulerSolver::Smooth_Sensitivity(CGeometry *geometry, CSolver **solver_c ForwDiff = (ArchLength[1]-ArchLength[0]); CentDiff = (ArchLength[1]-ArchLength[nVertex-1]); } - + Coeff = epsilon*2.0/(BackDiff*ForwDiff*CentDiff); - + A[iVertex][iVertex] = Coeff*CentDiff; - + if (iVertex != 0) A[iVertex][iVertex-1] = -Coeff*ForwDiff; else A[iVertex][nVertex-1] = -Coeff*ForwDiff; - + if (iVertex != nVertex-1) A[iVertex][iVertex+1] = -Coeff*BackDiff; else A[iVertex][0] = -Coeff*BackDiff; - + } - + /*--- Add the gradient value in the main diagonal ---*/ - + for (iVertex = 0; iVertex < nVertex; iVertex++) A[iVertex][iVertex] += 1.0; - + /*--- Dirichlet boundary condition ---*/ - + unsigned long iVertex = SU2_TYPE::Int(nVertex/2); A[iVertex][iVertex] = 1.0; A[iVertex][iVertex+1] = 0.0; A[iVertex][iVertex-1] = 0.0; - + Gauss_Elimination(A, b, (unsigned short)nVertex); - + /*--- Set the new value of the sensitiviy ---*/ - + for (iVertex = 0; iVertex < nVertex; iVertex++) CSensitivity[iMarker][iVertex] = b[iVertex]; - + /*--- Deallocate the linear system ---*/ - + for (iVertex = 0; iVertex < nVertex; iVertex++) delete [] A[iVertex]; delete [] A; delete [] b; delete [] ArchLength; - + } } - - + + } void CAdjEulerSolver::SetFarfield_AoA(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, bool Output) { - + unsigned long Iter_Fixed_CL = config->GetUpdate_AoA_Iter_Limit(); unsigned long InnerIter = config->GetInnerIter(); bool Update_AoA = false; su2double dCL_dAlpha = config->GetdCL_dAlpha()*180.0/PI_NUMBER; //unsigned long Update_Alpha = config->GetUpdate_Alpha(); - + //if (ExtIter == 0) AoA_Counter = 0; - + /*--- Only the fine mesh level should check the convergence criteria ---*/ - + if ((iMesh == MESH_0) && Output) { - + /*--- Initialize the update flag to false ---*/ - + Update_AoA = false; - + /*--- Reevaluate the lift derivative with respect to Angle of Attack at a fix number of iterations ---*/ - + if ((InnerIter % Iter_Fixed_CL == 0) && (InnerIter != 0)) { //AoA_Counter++; //if ((AoA_Counter <= Update_Alpha)) Update_AoA = true; Update_AoA = true; } - + /*--- Store the update boolean for use on other mesh levels in the MG ---*/ - + config->SetUpdate_AoA(Update_AoA); - + } - + else { Update_AoA = config->GetUpdate_AoA(); } - + /*--- If we are within two digits of convergence in the CL coefficient, compute an updated value for the AoA at the farfield. We are iterating on the AoA in order to match the specified fixed lift coefficient. ---*/ - + if (Update_AoA && Output) { - + /*--- Retrieve the old ACoeff ---*/ - + if (config->GetKind_ObjFunc() == DRAG_COEFFICIENT) ACoeff_old = config->GetdCD_dCL(); else if (config->GetKind_ObjFunc() == MOMENT_X_COEFFICIENT) ACoeff_old = config->GetdCMx_dCL(); else if (config->GetKind_ObjFunc() == MOMENT_Y_COEFFICIENT) ACoeff_old = config->GetdCMy_dCL(); @@ -2970,13 +2968,13 @@ void CAdjEulerSolver::SetFarfield_AoA(CGeometry *geometry, CSolver **solver_cont /*--- Estimate the increment in the A coeff, (note that the slope is negative, a decrease in * the CL derivative requires an increase in the A coeff ---*/ - + /*--- A good estimation to d(dOF/dalpha)/dA_coeff is dCL_dAlpha ---*/ - + ACoeff_inc = (1.0/dCL_dAlpha)*Total_Sens_AoA; - + /*--- Compute a new value for the A coeff based on the fine mesh only (radians)---*/ - + if (iMesh == MESH_0) { ACoeff = ACoeff_old + ACoeff_inc; } else { if (config->GetKind_ObjFunc() == DRAG_COEFFICIENT) ACoeff = config->GetdCD_dCL(); @@ -2985,9 +2983,9 @@ void CAdjEulerSolver::SetFarfield_AoA(CGeometry *geometry, CSolver **solver_cont else if (config->GetKind_ObjFunc() == MOMENT_Z_COEFFICIENT) ACoeff = config->GetdCMz_dCL(); else ACoeff = 0.0; } - + /*--- Only the fine mesh stores the updated values for ACoeff in config ---*/ - + if (iMesh == MESH_0) { if (config->GetKind_ObjFunc() == DRAG_COEFFICIENT) config->SetdCD_dCL(ACoeff); else if (config->GetKind_ObjFunc() == MOMENT_X_COEFFICIENT) config->SetdCMx_dCL(ACoeff); @@ -2995,15 +2993,15 @@ void CAdjEulerSolver::SetFarfield_AoA(CGeometry *geometry, CSolver **solver_cont else if (config->GetKind_ObjFunc() == MOMENT_Z_COEFFICIENT) config->SetdCMz_dCL(ACoeff); else { config->SetdCD_dCL(0.0); config->SetdCMx_dCL(0.0); config->SetdCMy_dCL(0.0); config->SetdCMz_dCL(0.0); } } - + /*--- Compute the adjoint boundary condition ---*/ - + SetForceProj_Vector(geometry, solver_container, config); - + } - + /*--- Output some information to the console with the headers ---*/ - + bool write_heads = ((InnerIter % Iter_Fixed_CL == 0) && (InnerIter != 0)); if ((rank == MASTER_NODE) && (iMesh == MESH_0) && write_heads && Output) { cout.precision(7); @@ -3017,8 +3015,8 @@ void CAdjEulerSolver::SetFarfield_AoA(CGeometry *geometry, CSolver **solver_cont else cout << endl; cout << "-------------------------------------------------------------------------" << endl << endl; } - - + + } @@ -3033,30 +3031,30 @@ void CAdjEulerSolver::BC_Euler_Wall(CGeometry *geometry, su2double *d = NULL, *Normal, *U, *Psi_Aux, ProjVel = 0.0, bcn, vn = 0.0, Area, *UnitNormal; su2double *Velocity, *Psi, Enthalpy = 0.0, sq_vel, phin, phis1, phis2; unsigned short iDim, iVar, jDim; - + bool implicit = (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); bool grid_movement = config->GetGrid_Movement(); - + UnitNormal = new su2double[nDim]; Velocity = new su2double[nDim]; Psi = new su2double[nVar]; - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + if (geometry->node[iPoint]->GetDomain()) { Normal = geometry->vertex[val_marker][iVertex]->GetNormal(); - + /*--- Create a copy of the adjoint solution ---*/ Psi_Aux = nodes->GetSolution(iPoint); for (iVar = 0; iVar < nVar; iVar++) Psi[iVar] = Psi_Aux[iVar]; - + /*--- Flow solution ---*/ U = solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint); - + /*--- Read the value of the objective function ---*/ d = nodes->GetForceProj_Vector(iPoint); - + /*--- Normal vector computation ---*/ Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); @@ -3156,25 +3154,25 @@ void CAdjEulerSolver::BC_Euler_Wall(CGeometry *geometry, /*--- Update residual ---*/ LinSysRes.SubtractBlock(iPoint, Residual); - + } } - + delete [] Velocity; delete [] UnitNormal; delete [] Psi; - + } void CAdjEulerSolver::BC_Sym_Plane(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + unsigned long iVertex, iPoint; su2double *Normal, ProjVel = 0.0, vn = 0.0, Area, *UnitNormal, *Psi_domain, *Psi_sym, *Velocity, Enthalpy = 0.0, sq_vel, phin, phis1, phis2; unsigned short iDim, iVar, jDim; - + bool implicit = (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); bool grid_movement = config->GetGrid_Movement(); @@ -3183,19 +3181,19 @@ void CAdjEulerSolver::BC_Sym_Plane(CGeometry *geometry, CSolver **solver_contain Velocity = new su2double[nDim]; Psi_domain = new su2double[nVar]; Psi_sym = new su2double[nVar]; - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + if (geometry->node[iPoint]->GetDomain()) { - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); - + Area = 0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); - + for (iDim = 0; iDim < nDim; iDim++) UnitNormal[iDim] = -Normal[iDim]/Area; @@ -3263,15 +3261,15 @@ void CAdjEulerSolver::BC_Sym_Plane(CGeometry *geometry, CSolver **solver_contain Residual_i[iDim+1] -= ProjGridVel*Psi_domain[iDim+1]; Residual_i[nVar-1] -= ProjGridVel*Psi_domain[nVar-1]; } - + /*--- Update residual ---*/ - + LinSysRes.SubtractBlock(iPoint, Residual_i); - + /*--- Implicit stuff ---*/ - + if (implicit) { - + /*--- Adjoint density ---*/ Jacobian_ii[0][0] = 0.0; @@ -3308,94 +3306,94 @@ void CAdjEulerSolver::BC_Sym_Plane(CGeometry *geometry, CSolver **solver_contain Jacobian_ii[iDim+1][iDim+1] -= ProjGridVel; Jacobian_ii[nVar-1][nVar-1] -= ProjGridVel; } - + /*--- Update jacobian ---*/ - + Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_ii); - + } } } - + delete [] Velocity; delete [] Psi_domain; delete [] Psi_sym; delete [] Normal; delete [] UnitNormal; - + } void CAdjEulerSolver::BC_Interface_Boundary(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short val_marker) { - + unsigned long iVertex, iPoint, GlobalIndex_iPoint, GlobalIndex_jPoint; unsigned short iDim, iVar; su2double *V_i; - + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); - + su2double *Normal = new su2double[nDim]; su2double *Psi_i = new su2double[nVar]; su2double *Psi_j = new su2double[nVar]; - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); GlobalIndex_iPoint = geometry->node[iPoint]->GetGlobalIndex(); GlobalIndex_jPoint = GetDonorGlobalIndex(val_marker, iVertex); - + if ((geometry->node[iPoint]->GetDomain()) && (GlobalIndex_iPoint != GlobalIndex_jPoint)) { - + /*--- Store the solution for both points ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { Psi_i[iVar] = nodes->GetSolution(iPoint,iVar); Psi_j[iVar] = GetDonorAdjVar(val_marker, iVertex, iVar); } - + /*--- Set adjoint Variables ---*/ - + numerics->SetAdjointVar(Psi_i, Psi_j); - + /*--- Conservative variables w/o reconstruction (the same at both points) ---*/ - + V_i = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); numerics->SetPrimitive(V_i, V_i); - + /*--- Set Normal ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; numerics->SetNormal(Normal); - + /*--- Compute the convective residual using an upwind scheme ---*/ numerics->ComputeResidual(Res_Conv_i, Res_Conv_j, Jacobian_ii, Jacobian_ij, Jacobian_ji, Jacobian_jj, config); - + /*--- Add Residuals and Jacobians ---*/ - + LinSysRes.SubtractBlock(iPoint, Res_Conv_i); if (implicit) Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_ii); - + } } - - + + delete[] Normal; delete[] Psi_i; delete[] Psi_j; - + } void CAdjEulerSolver::BC_NearField_Boundary(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short val_marker) { - + unsigned long iVertex, iPoint, GlobalIndex_iPoint, GlobalIndex_jPoint; unsigned short iDim, iVar; su2double *V_i, *IntBoundary_Jump; - + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); - + su2double *Normal = new su2double[nDim]; su2double *Psi_i = new su2double[nVar]; su2double *Psi_j = new su2double[nVar]; @@ -3403,39 +3401,39 @@ void CAdjEulerSolver::BC_NearField_Boundary(CGeometry *geometry, CSolver **solve su2double *Psi_in = new su2double[nVar]; su2double *Psi_out_ghost = new su2double[nVar]; su2double *Psi_in_ghost = new su2double[nVar]; - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); GlobalIndex_iPoint = geometry->node[iPoint]->GetGlobalIndex(); GlobalIndex_jPoint = GetDonorGlobalIndex(val_marker, iVertex); - + if ((geometry->node[iPoint]->GetDomain()) && (GlobalIndex_iPoint != GlobalIndex_jPoint)) { - + /*--- Store the solution for both points ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { Psi_i[iVar] = nodes->GetSolution(iPoint,iVar); Psi_j[iVar] = GetDonorAdjVar(val_marker, iVertex, iVar); } - + /*--- Set Normal ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; numerics->SetNormal(Normal); - + /*--- If equivalent area or nearfield pressure condition ---*/ - + if ((config->GetKind_ObjFunc() == EQUIVALENT_AREA) || (config->GetKind_ObjFunc() == NEARFIELD_PRESSURE)) { - + /*--- Read the jump ---*/ - + IntBoundary_Jump = nodes->GetIntBoundary_Jump(iPoint); - + /*--- Inner point ---*/ - + if (Normal[nDim-1] < 0.0) { for (iVar = 0; iVar < nVar; iVar++) { Psi_in[iVar] = Psi_i[iVar]; Psi_out[iVar] = Psi_j[iVar]; @@ -3443,9 +3441,9 @@ void CAdjEulerSolver::BC_NearField_Boundary(CGeometry *geometry, CSolver **solve } numerics->SetAdjointVar(Psi_in, Psi_in_ghost); } - + /*--- Outer point ---*/ - + else { for (iVar = 0; iVar < nVar; iVar++) { Psi_in[iVar] = Psi_j[iVar]; Psi_out[iVar] = Psi_i[iVar]; @@ -3455,30 +3453,30 @@ void CAdjEulerSolver::BC_NearField_Boundary(CGeometry *geometry, CSolver **solve } } else { - + /*--- Just do a periodic BC ---*/ - + numerics->SetAdjointVar(Psi_i, Psi_j); - + } - + /*--- Conservative variables w/o reconstruction (the same at both points) ---*/ - + V_i = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); numerics->SetPrimitive(V_i, V_i); - + /*--- Compute residual ---*/ - + numerics->ComputeResidual(Res_Conv_i, Res_Conv_j, Jacobian_ii, Jacobian_ij, Jacobian_ji, Jacobian_jj, config); - + /*--- Add Residuals and Jacobians ---*/ - + LinSysRes.SubtractBlock(iPoint, Res_Conv_i); if (implicit) Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_ii); - + } } - + delete[] Normal; delete[] Psi_i; delete[] Psi_j; @@ -3486,110 +3484,110 @@ void CAdjEulerSolver::BC_NearField_Boundary(CGeometry *geometry, CSolver **solve delete[] Psi_in; delete[] Psi_out_ghost; delete[] Psi_in_ghost; - + } void CAdjEulerSolver::BC_Far_Field(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + unsigned long iVertex, iPoint, Point_Normal; unsigned short iVar, iDim; su2double *Normal, *V_domain, *V_infty, *Psi_domain, *Psi_infty; - + bool implicit = (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); bool grid_movement = config->GetGrid_Movement(); Normal = new su2double[nDim]; Psi_domain = new su2double[nVar]; Psi_infty = new su2double[nVar]; - + /*--- Loop over all the vertices ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- If the node belongs to the domain ---*/ - + if (geometry->node[iPoint]->GetDomain()) { - + /*--- Index of the closest interior node ---*/ - + Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); /*--- Set the normal vector ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); - + /*--- Allocate the value at the infinity ---*/ - + V_infty = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); - + /*--- Retrieve solution at the farfield boundary node ---*/ - + V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); - + conv_numerics->SetPrimitive(V_domain, V_infty); - + /*--- Adjoint flow solution at the wall ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { Psi_domain[iVar] = nodes->GetSolution(iPoint,iVar); Psi_infty[iVar] = 0.0; } conv_numerics->SetAdjointVar(Psi_domain, Psi_infty); - + /*--- Grid Movement ---*/ - + if (grid_movement) conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); - + /*--- Compute the upwind flux ---*/ - + conv_numerics->ComputeResidual(Residual_i, Residual_j, Jacobian_ii, Jacobian_ij, Jacobian_ji, Jacobian_jj, config); - + /*--- Add and Subtract Residual ---*/ - + LinSysRes.SubtractBlock(iPoint, Residual_i); - + /*--- Implicit contribution to the residual ---*/ - + if (implicit) Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_ii); - + /*--- Viscous residual contribution, it doesn't work ---*/ - + if (config->GetViscous()) { - + /*--- Points in edge, coordinates and normal vector---*/ - + visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[Point_Normal]->GetCoord()); visc_numerics->SetNormal(Normal); - + /*--- Conservative variables w/o reconstruction and adjoint variables w/o reconstruction---*/ - + visc_numerics->SetPrimitive(V_domain, V_infty); visc_numerics->SetAdjointVar(Psi_domain, Psi_infty); - + /*--- Gradient and limiter of Adjoint Variables ---*/ - + visc_numerics->SetAdjointVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(iPoint)); - + /*--- Compute residual ---*/ - + visc_numerics->ComputeResidual(Residual_i, Residual_j, Jacobian_ii, Jacobian_ij, Jacobian_ji, Jacobian_jj, config); - + /*--- Update adjoint viscous residual ---*/ - + LinSysRes.SubtractBlock(iPoint, Residual_i); - + if (implicit) Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_ii); - + } - + } } - + delete [] Normal; delete [] Psi_domain; delete [] Psi_infty; } @@ -3668,7 +3666,7 @@ void CAdjEulerSolver::BC_Supersonic_Inlet(CGeometry *geometry, CSolver **solver_ /*--- Viscous residual contribution, it doesn't work ---*/ if (config->GetViscous()) { - + /*--- Index of the closest interior node ---*/ Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); @@ -3706,7 +3704,7 @@ void CAdjEulerSolver::BC_Supersonic_Inlet(CGeometry *geometry, CSolver **solver_ delete [] Normal; delete [] Psi_domain; delete [] Psi_inlet; - + } void CAdjEulerSolver::BC_Supersonic_Outlet(CGeometry *geometry, CSolver **solver_container, @@ -3714,80 +3712,80 @@ void CAdjEulerSolver::BC_Supersonic_Outlet(CGeometry *geometry, CSolver **solver unsigned short iVar, iDim; unsigned long iVertex, iPoint, Point_Normal; su2double *V_outlet, *V_domain, *Normal, *Psi_domain, *Psi_outlet; - + bool implicit = (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); bool grid_movement = config->GetGrid_Movement(); string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - + Normal = new su2double[nDim]; Psi_domain = new su2double[nVar]; Psi_outlet = new su2double[nVar]; - + /*--- Loop over all the vertices on this boundary marker ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check that the node belongs to the domain (i.e., not a halo node) ---*/ - + if (geometry->node[iPoint]->GetDomain()) { - + /*--- Normal vector for this vertex (negate for outward convention) ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); - + /*--- Allocate the value at the inlet ---*/ - + V_outlet = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); - + /*--- Retrieve solution at the boundary node ---*/ - + V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); - + /*--- Adjoint flow solution at the boundary ---*/ - + for (iVar = 0; iVar < nVar; iVar++) Psi_domain[iVar] = nodes->GetSolution(iPoint,iVar); - + /*--- Construct the flow & adjoint states at the inlet ---*/ - + for (iVar = 0; iVar < nVar; iVar++) Psi_outlet[iVar] = 0.0; - + /*--- Set the flow and adjoint states in the solver ---*/ - + conv_numerics->SetPrimitive(V_domain, V_outlet); conv_numerics->SetAdjointVar(Psi_domain, Psi_outlet); - + /*--- Grid Movement ---*/ - + if (grid_movement) conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); - + /*--- Compute the residual using an upwind scheme ---*/ - + conv_numerics->ComputeResidual(Residual_i, Residual_j, Jacobian_ii, Jacobian_ij, Jacobian_ji, Jacobian_jj, config); - + /*--- Add and Subtract Residual ---*/ - + LinSysRes.SubtractBlock(iPoint, Residual_i); - + /*--- Implicit contribution to the residual ---*/ - + if (implicit) Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_ii); - + /*--- Viscous residual contribution (check again, Point_Normal was not being initialized before) ---*/ if (config->GetViscous()) { /*--- Index of the closest interior node ---*/ - + Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); - + /*--- Points in edge, coordinates and normal vector---*/ visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[Point_Normal]->GetCoord()); @@ -3816,16 +3814,16 @@ void CAdjEulerSolver::BC_Supersonic_Outlet(CGeometry *geometry, CSolver **solver } } } - + /*--- Free locally allocated memory ---*/ - + delete [] Normal; delete [] Psi_domain; delete [] Psi_outlet; - + } void CAdjEulerSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + unsigned short iVar, iDim; unsigned long iVertex, iPoint, Point_Normal; su2double Velocity[3], bcn, phin, Area, UnitNormal[3], @@ -3836,46 +3834,46 @@ void CAdjEulerSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, bool implicit = (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); bool grid_movement = config->GetGrid_Movement(); string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - + Normal = new su2double[nDim]; Psi_domain = new su2double[nVar]; Psi_inlet = new su2double[nVar]; - + /*--- Loop over all the vertices on this boundary marker ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check that the node belongs to the domain (i.e., not a halo node) ---*/ - + if (geometry->node[iPoint]->GetDomain()) { - + /*--- Normal vector for this vertex (negate for outward convention) ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); - + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt (Area); - + for (iDim = 0; iDim < nDim; iDim++) UnitNormal[iDim] = Normal[iDim]/Area; - + /*--- Allocate the value at the inlet ---*/ - + V_inlet = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); - + /*--- Retrieve solution at the boundary node ---*/ - + V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); - + /*--- Adjoint flow solution at the boundary ---*/ - + for (iVar = 0; iVar < nVar; iVar++) Psi_domain[iVar] = nodes->GetSolution(iPoint,iVar); - + /*--- Construct the flow & adjoint states at the inlet ---*/ /*--- Subsonic, compressible inflow: first build the flow state @@ -3930,32 +3928,32 @@ void CAdjEulerSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, break; } - + /*--- Set the flow and adjoint states in the solver ---*/ - + conv_numerics->SetPrimitive(V_domain, V_inlet); conv_numerics->SetAdjointVar(Psi_domain, Psi_inlet); - + /*--- Grid Movement ---*/ - + if (grid_movement) conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); - + /*--- Compute the residual using an upwind scheme ---*/ - + conv_numerics->ComputeResidual(Residual_i, Residual_j, Jacobian_ii, Jacobian_ij, Jacobian_ji, Jacobian_jj, config); - + /*--- Add and Subtract Residual ---*/ - + LinSysRes.SubtractBlock(iPoint, Residual_i); - + /*--- Implicit contribution to the residual ---*/ - + if (implicit) Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_ii); - + /*--- Viscous residual contribution, it doesn't work ---*/ if (config->GetViscous()) { @@ -3991,16 +3989,16 @@ void CAdjEulerSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, } } } - + /*--- Free locally allocated memory ---*/ - + delete [] Normal; delete [] Psi_domain; delete [] Psi_inlet; - + } void CAdjEulerSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + unsigned short iVar, iDim; unsigned long iVertex, iPoint, Point_Normal; su2double Pressure=0.0, P_Exit=0.0, Velocity2 = 0.0, Area=0.0, Density=0.0, @@ -4014,7 +4012,7 @@ void CAdjEulerSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, bool implicit = (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); bool grid_movement = config->GetGrid_Movement(); - su2double Weight_ObjFunc = 1.0; + su2double Weight_ObjFunc = 1.0; string Marker_Tag = config->GetMarker_All_TagBound(val_marker); string Monitoring_Tag; unsigned short jMarker=0, iMarker_Monitoring=0; @@ -4278,68 +4276,68 @@ void CAdjEulerSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, } } } - + /*--- Free locally allocated memory ---*/ - + delete [] Normal; delete [] Psi_domain; delete [] Psi_outlet; - + } void CAdjEulerSolver::BC_Engine_Inflow(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + su2double *Normal, *V_domain, *V_inflow, *Psi_domain, *Psi_inflow, P_Fan, Velocity[3], Velocity2, Density, Vn, UnitNormal[3], Area, a1; unsigned short iVar, iDim; unsigned long iVertex, iPoint; - + bool implicit = (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - + Normal = new su2double[nDim]; Psi_domain = new su2double[nVar]; Psi_inflow = new su2double[nVar]; - + /*--- Loop over all the vertices ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- If the node belong to the domain ---*/ - + if (geometry->node[iPoint]->GetDomain()) { - + /*--- Normal vector for this vertex (negate for outward convention) ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); - + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt (Area); - + for (iDim = 0; iDim < nDim; iDim++) UnitNormal[iDim] = Normal[iDim]/Area; - + /*--- Allocate the value at the inflow ---*/ - + V_inflow = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); - + /*--- Retrieve solution at the boundary node ---*/ - + V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); - + /*--- Adjoint flow solution at the boundary ---*/ - + for (iVar = 0; iVar < nVar; iVar++) Psi_domain[iVar] = nodes->GetSolution(iPoint,iVar); - + /*--- Subsonic flow is assumed, note that there is no non-dimensionalization. ---*/ - + P_Fan = config->GetInflow_Pressure(Marker_Tag); - + Density = V_domain[nDim+2]; Velocity2 = 0.0; Vn = 0.0; for (iDim = 0; iDim < nDim; iDim++) { @@ -4347,18 +4345,18 @@ void CAdjEulerSolver::BC_Engine_Inflow(CGeometry *geometry, CSolver **solver_con Velocity2 += Velocity[iDim]*Velocity[iDim]; Vn += Velocity[iDim]*UnitNormal[iDim]; } - + /*---Subsonic Case(s) using Riemann invariants ---*/ - + // Pressure = V_domain[nDim+1]; // SoundSpeed = sqrt(Pressure*Gamma/Density); // Mach_Fan = sqrt(Velocity2)/SoundSpeed; // Entropy = Pressure*pow(1.0/Density, Gamma); // Riemann = Vn + 2.0*SoundSpeed/Gamma_Minus_One; - + // /*--- Compute (Vn - Ubn).n term for use in the BC. // Compute the new fictious state at the outlet ---*/ - + // Density = pow(P_Fan/Entropy,1.0/Gamma); // SoundSpeed = sqrt(Gamma*P_Fan/Density); // Vn_Fan = Riemann - 2.0*SoundSpeed/Gamma_Minus_One; @@ -4367,180 +4365,180 @@ void CAdjEulerSolver::BC_Engine_Inflow(CGeometry *geometry, CSolver **solver_con // Velocity[iDim] = Velocity[iDim] + (Vn_Fan-Vn)*UnitNormal[iDim]; // Velocity2 += Velocity[iDim]*Velocity[iDim]; // } - + /*--- Shorthand for repeated term in the boundary conditions ---*/ - + a1 = sqrt(Gamma*P_Fan/Density)/(Gamma_Minus_One); - + /*--- Impose values for PsiRho & Phi using PsiE from domain. ---*/ - + Psi_inflow[nVar-1] = Psi_domain[nVar-1]; Psi_inflow[0] = 0.5*Psi_inflow[nVar-1]*Velocity2; for (iDim = 0; iDim < nDim; iDim++) { Psi_inflow[0] += Psi_inflow[nVar-1]*a1*Velocity[iDim]*UnitNormal[iDim]; Psi_inflow[iDim+1] = -Psi_inflow[nVar-1]*(a1*UnitNormal[iDim] + Velocity[iDim]); } - + /*--- Set the flow and adjoint states in the solver ---*/ - + conv_numerics->SetPrimitive(V_domain, V_inflow); conv_numerics->SetAdjointVar(Psi_domain, Psi_inflow); - + /*--- Compute the residual ---*/ - + conv_numerics->ComputeResidual(Residual_i, Residual_j, Jacobian_ii, Jacobian_ij, Jacobian_ji, Jacobian_jj, config); - + /*--- Add and Subtract Residual ---*/ - + LinSysRes.SubtractBlock(iPoint, Residual_i); - + /*--- Implicit contribution to the residual ---*/ - + if (implicit) Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_ii); - + } } - + /*--- Free locally allocated memory ---*/ - + delete [] Normal; delete [] Psi_domain; delete [] Psi_inflow; - + } void CAdjEulerSolver::BC_Engine_Exhaust(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + unsigned long iVertex, iPoint, Point_Normal; su2double Area, *Normal, *V_domain, *V_exhaust, *Psi_domain, *Psi_exhaust; unsigned short iVar, iDim; - + bool implicit = (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - + Normal = new su2double[nDim]; Psi_domain = new su2double[nVar]; Psi_exhaust = new su2double[nVar]; - + /*--- Loop over all the vertices on this boundary marker ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check that the node belongs to the domain (i.e., not a halo node) ---*/ - + if (geometry->node[iPoint]->GetDomain()) { - + /*--- Normal vector for this vertex (negate for outward convention) ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); - + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt (Area); /*--- Index of the closest interior node ---*/ - + Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); - + /*--- Allocate the value at the exhaust ---*/ - + V_exhaust = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); - + /*--- Retrieve solution at the boundary node ---*/ - + V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); - + /*--- Adjoint flow solution at the boundary ---*/ - + for (iVar = 0; iVar < nVar; iVar++) Psi_domain[iVar] = nodes->GetSolution(iPoint,iVar); - + /*--- Adjoint flow solution at the exhaust (this should be improved using characteristics bc) ---*/ - + Psi_exhaust[0] = 0.0; for (iDim = 0; iDim < nDim; iDim++) Psi_exhaust[iDim+1] = nodes->GetSolution(Point_Normal,iDim+1); Psi_exhaust[nDim+1] = 0.0; - + /*--- Set the flow and adjoint states in the solver ---*/ - + conv_numerics->SetPrimitive(V_domain, V_exhaust); conv_numerics->SetAdjointVar(Psi_domain, Psi_exhaust); - + /*--- Compute the residual using an upwind scheme ---*/ - + conv_numerics->ComputeResidual(Residual_i, Residual_j, Jacobian_ii, Jacobian_ij, Jacobian_ji, Jacobian_jj, config); - + /*--- Add and Subtract Residual ---*/ - + LinSysRes.SubtractBlock(iPoint, Residual_i); - + /*--- Implicit contribution to the residual ---*/ - + if (implicit) Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_ii); - + } } - + delete [] Normal; delete [] Psi_domain; delete [] Psi_exhaust; - + } void CAdjEulerSolver::BC_ActDisk_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + su2double *Normal, *V_domain, *V_inlet, *Psi_domain, *Psi_inlet; unsigned short iVar, iDim; unsigned long iVertex, iPoint, GlobalIndex_inlet, GlobalIndex; - + bool implicit = (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); - + Normal = new su2double[nDim]; Psi_domain = new su2double[nVar]; Psi_inlet = new su2double[nVar]; - + /*--- Loop over all the vertices ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + GlobalIndex_inlet = solver_container[FLOW_SOL]->GetDonorGlobalIndex(val_marker, iVertex); - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); GlobalIndex = geometry->node[iPoint]->GetGlobalIndex(); - + /*--- If the node belong to the domain ---*/ - + if ((geometry->node[iPoint]->GetDomain()) && (GlobalIndex != GlobalIndex_inlet)) { - + /*--- Normal vector for this vertex (negate for outward convention) ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); - + /*--- Allocate the value at the inlet ---*/ - + V_inlet = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); - + /*--- Retrieve solution at the boundary node ---*/ - + V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); - + /*--- Adjoint flow solution at the boundary ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { Psi_domain[iVar] = nodes->GetSolution(iPoint,iVar); Psi_inlet[iVar] = 0.0;// nodes->GetSolution(iPoint,iVar); } - + #ifdef CHECK su2double UnitNormal[3], Area=0.0; - + for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt (Area); @@ -4549,9 +4547,9 @@ void CAdjEulerSolver::BC_ActDisk_Inlet(CGeometry *geometry, CSolver **solver_con UnitNormal[iDim] = Normal[iDim]/Area; /*--- Subsonic flow is assumed, note that there is no non-dimensionalization. ---*/ - + P_Fan = V_domain[nDim+1] ; - + Density = V_domain[nDim+2]; Velocity2 = 0.0; Vn = 0.0; for (iDim = 0; iDim < nDim; iDim++) { @@ -4559,164 +4557,164 @@ void CAdjEulerSolver::BC_ActDisk_Inlet(CGeometry *geometry, CSolver **solver_con Velocity2 += Velocity[iDim]*Velocity[iDim]; Vn += Velocity[iDim]*UnitNormal[iDim]; } - + /*---Subsonic Case(s) using Riemann invariants ---*/ - + Pressure = V_domain[nDim+1]; SoundSpeed = sqrt(Pressure*Gamma/Density); - + Entropy = Pressure*pow(1.0/Density, Gamma); Riemann = Vn + 2.0*SoundSpeed/Gamma_Minus_One; - + /*--- Compute (Vn - Ubn).n term for use in the BC. Compute the new fictious state at the outlet ---*/ - + Density = pow(P_Fan/Entropy,1.0/Gamma); SoundSpeed = sqrt(Gamma*P_Fan/Density); Vn_Fan = Riemann - 2.0*SoundSpeed/Gamma_Minus_One; - + Velocity2 = 0.0; for (iDim = 0; iDim < nDim; iDim++) { Velocity[iDim] = Velocity[iDim] + (Vn_Fan-Vn)*UnitNormal[iDim]; Velocity2 += Velocity[iDim]*Velocity[iDim]; } - + /*--- Impose values for PsiRho & Phi using PsiE from domain. ---*/ - + Psi_inlet[nVar-1] = Psi_domain[nVar-1]; - + a1 = SoundSpeed*SoundSpeed/Gamma_Minus_One/Vn; - + Psi_inlet[0] = Psi_inlet[nVar-1]*(Velocity2*0.5+Vn_Fan*a1); Psi_inlet[iDim+1] = 0.0; for (iDim = 0; iDim < nDim; iDim++) { Psi_inlet[iDim+1] += -Psi_inlet[nVar-1]*(a1*UnitNormal[iDim] + Velocity[iDim]); } - + #endif - + /*--- Set the flow and adjoint states in the solver ---*/ - + conv_numerics->SetPrimitive(V_domain, V_inlet); conv_numerics->SetAdjointVar(Psi_domain, Psi_inlet); - + /*--- Compute the residual ---*/ - + conv_numerics->ComputeResidual(Residual_i, Residual_j, Jacobian_ii, Jacobian_ij, Jacobian_ji, Jacobian_jj, config); - + /*--- Add and Subtract Residual ---*/ - + LinSysRes.SubtractBlock(iPoint, Residual_i); - + /*--- Implicit contribution to the residual ---*/ - + if (implicit) Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_ii); - + } } - + /*--- Free locally allocated memory ---*/ - + delete [] Normal; delete [] Psi_domain; delete [] Psi_inlet; - + } void CAdjEulerSolver::BC_ActDisk_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + unsigned long iVertex, iPoint, GlobalIndex_inlet, GlobalIndex; su2double *Normal, *V_domain, *V_outlet, *Psi_domain, *Psi_outlet; unsigned short iVar, iDim; - + bool implicit = (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); - + Normal = new su2double[nDim]; Psi_domain = new su2double[nVar]; Psi_outlet = new su2double[nVar]; - + /*--- Loop over all the vertices on this boundary marker ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + GlobalIndex_inlet = solver_container[FLOW_SOL]->GetDonorGlobalIndex(val_marker, iVertex); - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); GlobalIndex = geometry->node[iPoint]->GetGlobalIndex(); - + /*--- Check that the node belongs to the domain (i.e., not a halo node) and to discard the perimeter ---*/ - + if ((geometry->node[iPoint]->GetDomain()) && (GlobalIndex != GlobalIndex_inlet)) { - + /*--- Normal vector for this vertex (negate for outward convention) ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); /*--- Allocate the value at the outlet ---*/ - + V_outlet = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); - + /*--- Retrieve solution at the boundary node ---*/ - + V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); - + /*--- Adjoint flow solution at the boundary ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { Psi_domain[iVar] = nodes->GetSolution(iPoint,iVar); Psi_outlet[iVar] = 0.0; //nodes->GetSolution(iPoint,iVar); } - + #ifdef CHECK unsigned long Point_Normal; /*--- Index of the closest interior node ---*/ Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); - + /*--- Adjoint flow solution at the outlet (this should be improved using characteristics bc) ---*/ - + Psi_outlet[0] = 0.0; for (iDim = 0; iDim < nDim; iDim++) Psi_outlet[iDim+1] = nodes->GetSolution(Point_Normal,iDim+1); Psi_outlet[nDim+1] = 0.0; - + #endif - + /*--- Set the flow and adjoint states in the solver ---*/ - + conv_numerics->SetPrimitive(V_domain, V_outlet); conv_numerics->SetAdjointVar(Psi_domain, Psi_outlet); - + /*--- Compute the residual using an upwind scheme ---*/ - + conv_numerics->ComputeResidual(Residual_i, Residual_j, Jacobian_ii, Jacobian_ij, Jacobian_ji, Jacobian_jj, config); - + /*--- Add and Subtract Residual ---*/ - + LinSysRes.SubtractBlock(iPoint, Residual_i); - + /*--- Implicit contribution to the residual ---*/ - + if (implicit) Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_ii); - + } - + } - + delete [] Normal; delete [] Psi_domain; delete [] Psi_outlet; - + } void CAdjEulerSolver::BC_ActDisk(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker, bool val_inlet_surface) { - + } void CAdjEulerSolver::SetResidual_DualTime(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iRKStep, @@ -4724,18 +4722,18 @@ void CAdjEulerSolver::SetResidual_DualTime(CGeometry *geometry, CSolver **solver unsigned short iVar, jVar; unsigned long iPoint; su2double *U_time_nM1, *U_time_n, *U_time_nP1, Volume_nM1, Volume_n, Volume_nP1, TimeStep; - + bool implicit = (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); bool Grid_Movement = config->GetGrid_Movement(); - + /*--- loop over points ---*/ for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /*--- Solution at time n-1, n and n+1 ---*/ U_time_nM1 = nodes->GetSolution_time_n1(iPoint); U_time_n = nodes->GetSolution_time_n(iPoint); U_time_nP1 = nodes->GetSolution(iPoint); - + /*--- Volume at time n-1 and n ---*/ if (Grid_Movement) { Volume_nM1 = geometry->node[iPoint]->GetVolume_nM1(); @@ -4747,10 +4745,10 @@ void CAdjEulerSolver::SetResidual_DualTime(CGeometry *geometry, CSolver **solver Volume_n = geometry->node[iPoint]->GetVolume(); Volume_nP1 = geometry->node[iPoint]->GetVolume(); } - + /*--- Time Step ---*/ TimeStep = config->GetDelta_UnstTimeND(); - + /*--- Compute Residual ---*/ for (iVar = 0; iVar < nVar; iVar++) { if (config->GetTime_Marching() == DT_STEPPING_1ST) @@ -4759,15 +4757,15 @@ void CAdjEulerSolver::SetResidual_DualTime(CGeometry *geometry, CSolver **solver Residual[iVar] = ( 3.0*U_time_nP1[iVar]*Volume_nP1 - 4.0*U_time_n[iVar]*Volume_n + 1.0*U_time_nM1[iVar]*Volume_nM1 ) / (2.0*TimeStep); } - + /*--- Add Residual ---*/ LinSysRes.AddBlock(iPoint, Residual); - + if (implicit) { for (iVar = 0; iVar < nVar; iVar++) { for (jVar = 0; jVar < nVar; jVar++) Jacobian_i[iVar][jVar] = 0.0; - + if (config->GetTime_Marching() == DT_STEPPING_1ST) Jacobian_i[iVar][iVar] = Volume_nP1 / TimeStep; if (config->GetTime_Marching() == DT_STEPPING_2ND) @@ -4776,7 +4774,7 @@ void CAdjEulerSolver::SetResidual_DualTime(CGeometry *geometry, CSolver **solver Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); } } - + } void CAdjEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo) { @@ -4817,7 +4815,7 @@ void CAdjEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConf unsigned short rbuf_NotMatching = 0, sbuf_NotMatching = 0; for (iPoint_Global = 0; iPoint_Global < geometry[MESH_0]->GetGlobal_nPointDomain(); iPoint_Global++ ) { - + /*--- Retrieve local index. If this node from the restart file lives on the current processor, we will load and instantiate the vars. ---*/ @@ -4856,7 +4854,7 @@ void CAdjEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConf /*--- Communicate the loaded solution on the fine grid before we transfer it down to the coarse levels. We also call the preprocessing routine on the fine level in order to have all necessary quantities updated. ---*/ - + solver[MESH_0][ADJFLOW_SOL]->InitiateComms(geometry[MESH_0], config, SOLUTION); solver[MESH_0][ADJFLOW_SOL]->CompleteComms(geometry[MESH_0], config, SOLUTION); solver[MESH_0][ADJFLOW_SOL]->Preprocessing(geometry[MESH_0], solver[MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); @@ -4890,1886 +4888,4 @@ void CAdjEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConf if (Restart_Data != NULL) delete [] Restart_Data; Restart_Vars = NULL; Restart_Data = NULL; -} - -CAdjNSSolver::CAdjNSSolver(void) : CAdjEulerSolver() { } - -CAdjNSSolver::CAdjNSSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh) : CAdjEulerSolver() { - unsigned long iPoint, iVertex; - string text_line, mesh_filename; - unsigned short iDim, iVar, iMarker, nLineLets; - ifstream restart_file; - string filename, AdjExt; - - su2double RefArea = config->GetRefArea(); - su2double RefDensity = config->GetDensity_FreeStreamND(); - su2double Gas_Constant = config->GetGas_ConstantND(); - su2double Mach_Motion = config->GetMach_Motion(); - su2double Area=0.0, *Normal = NULL, myArea_Monitored; - su2double RefVel2, Mach2Vel, Weight_ObjFunc, factor; - su2double *Velocity_Inf; - - string Marker_Tag, Monitoring_Tag; - unsigned short iMarker_Monitoring, jMarker, ObjFunc; - bool grid_movement = config->GetGrid_Movement(); - bool restart = config->GetRestart(); - - /*--- Norm heat flux objective test ---*/ - pnorm = 1.0; - if (config->GetKind_ObjFunc()==MAXIMUM_HEATFLUX) - pnorm = 8.0; // Matches MaxNorm defined in solver_direct_mean. - - /*--- Set the gamma value ---*/ - - Gamma = config->GetGamma(); - Gamma_Minus_One = Gamma - 1.0; - - /*--- Define geometry constants in the solver structure ---*/ - - nDim = geometry->GetnDim(); - nMarker = config->GetnMarker_All(); - nPoint = geometry->GetnPoint(); - nPointDomain = geometry->GetnPointDomain(); - - nVar = nDim + 2; - - /*--- Initialize nVarGrad for deallocation ---*/ - - nVarGrad = nVar; - - /*--- Define some auxiliary arrays related to the residual ---*/ - - Point_Max = new unsigned long[nVar]; for (iVar = 0; iVar < nVar; iVar++) Point_Max[iVar] = 0; - Point_Max_Coord = new su2double*[nVar]; - for (iVar = 0; iVar < nVar; iVar++) { - Point_Max_Coord[iVar] = new su2double[nDim]; - for (iDim = 0; iDim < nDim; iDim++) Point_Max_Coord[iVar][iDim] = 0.0; - } - Residual = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = 0.0; - Residual_RMS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_RMS[iVar] = 0.0; - Residual_Max = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_Max[iVar] = 0.0; - Residual_i = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_i[iVar] = 0.0; - Residual_j = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_j[iVar] = 0.0; - Res_Conv_i = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Conv_i[iVar] = 0.0; - Res_Visc_i = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Visc_i[iVar] = 0.0; - Res_Conv_j = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Conv_j[iVar] = 0.0; - Res_Visc_j = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Visc_j[iVar] = 0.0; - - /*--- Define some auxiliary arrays related to the solution ---*/ - - Solution = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution[iVar] = 0.0; - Solution_i = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution_i[iVar] = 0.0; - Solution_j = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution_j[iVar] = 0.0; - - /*--- Define some auxiliary arrays related to the flow solution ---*/ - - FlowPrimVar_i = new su2double[nDim+7]; for (iVar = 0; iVar < nDim+7; iVar++) FlowPrimVar_i[iVar] = 0.0; - FlowPrimVar_j = new su2double[nDim+7]; for (iVar = 0; iVar < nDim+7; iVar++) FlowPrimVar_j[iVar] = 0.0; - - /*--- Define some auxiliary vectors related to the geometry ---*/ - - Vector = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = 0.0; - Vector_i = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector_i[iDim] = 0.0; - Vector_j = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector_j[iDim] = 0.0; - - /*--- Point to point Jacobians. These are always defined because - they are also used for sensitivity calculations. ---*/ - - Jacobian_i = new su2double* [nVar]; - Jacobian_j = new su2double* [nVar]; - for (iVar = 0; iVar < nVar; iVar++) { - Jacobian_i[iVar] = new su2double [nVar]; - Jacobian_j[iVar] = new su2double [nVar]; - } - - /*--- Solution and residual vectors ---*/ - - LinSysSol.Initialize(nPoint, nPointDomain, nVar, 0.0); - LinSysRes.Initialize(nPoint, nPointDomain, nVar, 0.0); - - /*--- Jacobians and vector structures for implicit computations ---*/ - - if (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT) { - Jacobian_ii = new su2double*[nVar]; - Jacobian_ij = new su2double*[nVar]; - Jacobian_ji = new su2double*[nVar]; - Jacobian_jj = new su2double*[nVar]; - for (iVar = 0; iVar < nVar; iVar++) { - Jacobian_ii[iVar] = new su2double[nVar]; - Jacobian_ij[iVar] = new su2double[nVar]; - Jacobian_ji[iVar] = new su2double[nVar]; - Jacobian_jj[iVar] = new su2double[nVar]; - } - if (rank == MASTER_NODE) - cout << "Initialize Jacobian structure (Adjoint N-S). MG level: " << iMesh <<"." << endl; - Jacobian.Initialize(nPoint, nPointDomain, nVar, nVar, true, geometry, config); - - if (config->GetKind_Linear_Solver_Prec() == LINELET) { - nLineLets = Jacobian.BuildLineletPreconditioner(geometry, config); - if (rank == MASTER_NODE) cout << "Compute linelet structure. " << nLineLets << " elements in each line (average)." << endl; - } - - } else { - if (rank == MASTER_NODE) - cout << "Explicit scheme. No Jacobian structure (Adjoint N-S). MG level: " << iMesh <<"." << endl; - } - - /*--- Array structures for computation of gradients by least squares ---*/ - if (config->GetLeastSquaresRequired()) { - /*--- S matrix := inv(R)*traspose(inv(R)) ---*/ - Smatrix = new su2double* [nDim]; - for (iDim = 0; iDim < nDim; iDim++) - Smatrix[iDim] = new su2double [nDim]; - /*--- c vector := transpose(WA)*(Wb) ---*/ - Cvector = new su2double* [nVar]; - for (iVar = 0; iVar < nVar; iVar++) - Cvector[iVar] = new su2double [nDim]; - } - - /*--- Sensitivity definition and coefficient on all markers ---*/ - CSensitivity = new su2double* [nMarker]; - for (iMarker=0; iMarkernVertex[iMarker]]; - } - - /*--- Store the value of the characteristic primitive variables at the boundaries ---*/ - - DonorAdjVar = new su2double** [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - DonorAdjVar[iMarker] = new su2double* [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - DonorAdjVar[iMarker][iVertex] = new su2double [nVar]; - for (iVar = 0; iVar < nVar; iVar++) { - DonorAdjVar[iMarker][iVertex][iVar] = 0.0; - } - } - } - - /*--- Store the value of the characteristic primitive variables at the boundaries ---*/ - - DonorGlobalIndex = new unsigned long* [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - DonorGlobalIndex[iMarker] = new unsigned long [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - DonorGlobalIndex[iMarker][iVertex] = 0; - } - } - - Sens_Geo = new su2double[nMarker]; - Sens_Mach = new su2double[nMarker]; - Sens_AoA = new su2double[nMarker]; - Sens_Press = new su2double[nMarker]; - Sens_Temp = new su2double[nMarker]; - Sens_BPress = new su2double[nMarker]; - - /*--- Initialize sensitivities to zero ---*/ - for (iMarker = 0; iMarker < nMarker; iMarker++) { - Sens_Geo[iMarker] = 0.0; - Sens_Mach[iMarker] = 0.0; - Sens_AoA[iMarker] = 0.0; - Sens_Press[iMarker] = 0.0; - Sens_Temp[iMarker] = 0.0; - Sens_BPress[iMarker] = 0.0; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) - CSensitivity[iMarker][iVertex] = 0.0; - } - - /*--- Initialize the adjoint variables to zero (infinity state) ---*/ - PsiRho_Inf = 0.0; - if ((config->GetKind_ObjFunc() == TOTAL_HEATFLUX) || - (config->GetKind_ObjFunc() == MAXIMUM_HEATFLUX) || - (config->GetKind_ObjFunc() == INVERSE_DESIGN_HEATFLUX)) - PsiE_Inf = 1.0; - else - PsiE_Inf = 0.0; - Phi_Inf = new su2double [nDim]; - Phi_Inf[0] = 0.0; Phi_Inf[1] = 0.0; - if (nDim == 3) Phi_Inf[2] = 0.0; - - /*--- Initialize the solution to the far-field state everywhere. ---*/ - - nodes = new CAdjNSVariable(PsiRho_Inf, Phi_Inf, PsiE_Inf, nPoint, nDim, nVar, config); - SetBaseClassPointerToNodes(); - - /*--- Read the restart metadata. ---*/ - - if (restart && (iMesh == MESH_0)) { - mesh_filename = config->GetSolution_AdjFileName(); - filename = config->GetObjFunc_Extension(mesh_filename); -// Read_SU2_Restart_Metadata(geometry, config, true, filename); - } - - /*--- Calculate area monitored for area-averaged-outflow-quantity-based objectives ---*/ - myArea_Monitored = 0.0; - for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { - if (config->GetKind_ObjFunc(iMarker_Monitoring)==SURFACE_TOTAL_PRESSURE || - config->GetKind_ObjFunc(iMarker_Monitoring)==SURFACE_STATIC_PRESSURE) { - - Monitoring_Tag = config->GetMarker_Monitoring_TagBound(iMarker_Monitoring); - /*-- Find the marker index ---*/ - iMarker = 0; - for (jMarker= 0; jMarker < config->GetnMarker_All(); jMarker++) { - Marker_Tag = config->GetMarker_All_TagBound(jMarker); - if (Marker_Tag == Monitoring_Tag) { - iMarker = jMarker; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - if (geometry->node[iPoint]->GetDomain()) { - Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - Area = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - Area += Normal[iDim]*Normal[iDim]; - myArea_Monitored += sqrt (Area); - } - } - break; - } - } - } - } - - - #ifdef HAVE_MPI - Area_Monitored = 0.0; - SU2_MPI::Allreduce(&myArea_Monitored, &Area_Monitored, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - #else - Area_Monitored = myArea_Monitored; - #endif - - if (config->GetnObj() > 1 && iMesh == MESH_0) { - if (grid_movement) { - Mach2Vel = sqrt(Gamma*Gas_Constant*config->GetTemperature_FreeStreamND()); - RefVel2 = (Mach_Motion*Mach2Vel)*(Mach_Motion*Mach2Vel); - } - else { - Velocity_Inf = config->GetVelocity_FreeStreamND(); - RefVel2 = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - RefVel2 += Velocity_Inf[iDim]*Velocity_Inf[iDim]; - } - - /*--- Objective scaling: a factor must be applied to certain objectives ---*/ - for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { - Weight_ObjFunc = config->GetWeight_ObjFunc(iMarker_Monitoring); - - factor = 1.0/(0.5*RefDensity*RefArea*RefVel2); - - ObjFunc = config->GetKind_ObjFunc(iMarker_Monitoring); - if ((ObjFunc == INVERSE_DESIGN_HEATFLUX) || - (ObjFunc == TOTAL_HEATFLUX) || (ObjFunc == MAXIMUM_HEATFLUX) || - (ObjFunc == SURFACE_MASSFLOW) ) factor = 1.0; - - if ((ObjFunc == SURFACE_TOTAL_PRESSURE) || (ObjFunc == SURFACE_STATIC_PRESSURE)) - factor = 1.0/Area_Monitored; - - Weight_ObjFunc = Weight_ObjFunc*factor; - config->SetWeight_ObjFunc(iMarker_Monitoring, Weight_ObjFunc); - - } - } - - /*--- MPI solution ---*/ - - InitiateComms(geometry, config, SOLUTION); - CompleteComms(geometry, config, SOLUTION); - -} - -CAdjNSSolver::~CAdjNSSolver(void) { - -} - - -void CAdjNSSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh, unsigned long Iteration) { - - /*--- Use the flow solution to update the time step - * The time step depends on the characteristic velocity, which is the same - * for the adjoint and flow solutions, albeit in the opposite direction. ---*/ - solver_container[FLOW_SOL]->SetTime_Step(geometry, solver_container, config, iMesh, Iteration); - -} - -void CAdjNSSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output) { - - unsigned long iPoint, nonPhysicalPoints = 0; - su2double SharpEdge_Distance; - bool physical = true; - - /*--- Retrieve information about the spatial and temporal integration for the - adjoint equations (note that the flow problem may use different methods). ---*/ - - bool implicit = (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); - bool limiter = (config->GetKind_SlopeLimit_AdjFlow() != NO_LIMITER); - bool center_jst = (config->GetKind_Centered_AdjFlow() == JST); - bool fixed_cl = config->GetFixed_CL_Mode(); - bool eval_dof_dcx = config->GetEval_dOF_dCX(); - - /*--- Update the objective function coefficient to guarantee zero gradient. ---*/ - - if (fixed_cl && eval_dof_dcx) { SetFarfield_AoA(geometry, solver_container, config, iMesh, Output); } - - /*--- Residual initialization ---*/ - - for (iPoint = 0; iPoint < nPoint; iPoint ++) { - - /*--- Get the distance form a sharp edge ---*/ - - SharpEdge_Distance = geometry->node[iPoint]->GetSharpEdge_Distance(); - - /*--- Set the primitive variables compressible - adjoint variables ---*/ - - physical = nodes->SetPrimVar(iPoint,SharpEdge_Distance, false, config); - - /* Check for non-realizable states for reporting. */ - - if (!physical) nonPhysicalPoints++; - - /*--- Initialize the convective residual vector ---*/ - - if (!Output) LinSysRes.SetBlock_Zero(iPoint); - - } - - /*--- Compute gradients adj for solution reconstruction and viscous term ---*/ - - if (config->GetReconstructionGradientRequired()) { - if (config->GetKind_Gradient_Method_Recon() == GREEN_GAUSS) - SetSolution_Gradient_GG(geometry, config, true); - if (config->GetKind_Gradient_Method_Recon() == LEAST_SQUARES) - SetSolution_Gradient_LS(geometry, config, true); - if (config->GetKind_Gradient_Method_Recon() == WEIGHTED_LEAST_SQUARES) - SetSolution_Gradient_LS(geometry, config, true); - } - if (config->GetKind_Gradient_Method() == GREEN_GAUSS) SetSolution_Gradient_GG(geometry, config); - if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) SetSolution_Gradient_LS(geometry, config); - - /*--- Limiter computation (upwind reconstruction) ---*/ - - if (limiter && !Output) SetSolution_Limiter(geometry, config); - - /*--- Compute gradients adj for viscous term coupling ---*/ - - if ((config->GetKind_Solver() == ADJ_RANS) && (!config->GetFrozen_Visc_Cont())) { - if (config->GetKind_Gradient_Method() == GREEN_GAUSS) solver_container[ADJTURB_SOL]->SetSolution_Gradient_GG(geometry, config); - if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) solver_container[ADJTURB_SOL]->SetSolution_Gradient_LS(geometry, config); - } - - /*--- Artificial dissipation for centered schemes ---*/ - - if (center_jst && (iMesh == MESH_0)) { - SetCentered_Dissipation_Sensor(geometry, config); - SetUndivided_Laplacian(geometry, config); - } - - /*--- Initialize the Jacobian for implicit integration ---*/ - - if (implicit) Jacobian.SetValZero(); - - /*--- Error message ---*/ - - if (config->GetComm_Level() == COMM_FULL) { -#ifdef HAVE_MPI - unsigned long MyErrorCounter = nonPhysicalPoints; nonPhysicalPoints = 0; - SU2_MPI::Allreduce(&MyErrorCounter, &nonPhysicalPoints, 1, MPI_UNSIGNED_LONG, MPI_SUM, MPI_COMM_WORLD); -#endif - if (iMesh == MESH_0) config->SetNonphysical_Points(nonPhysicalPoints); - } - -} - -void CAdjNSSolver::Viscous_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh, unsigned short iRKStep) { - unsigned long iPoint, jPoint, iEdge; - - bool implicit = (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); - - for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - - /*--- Points in edge, coordinates and normal vector---*/ - - iPoint = geometry->edge[iEdge]->GetNode(0); - jPoint = geometry->edge[iEdge]->GetNode(1); - - numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[jPoint]->GetCoord()); - numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); - - /*--- Primitive variables w/o reconstruction and adjoint variables w/o reconstruction---*/ - - numerics->SetPrimitive(solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint), - solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(jPoint)); - - numerics->SetAdjointVar(nodes->GetSolution(iPoint), nodes->GetSolution(jPoint)); - - /*--- Gradient and limiter of Adjoint Variables ---*/ - - numerics->SetAdjointVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(jPoint)); - - /*--- Compute residual ---*/ - - numerics->ComputeResidual(Residual_i, Residual_j, Jacobian_ii, Jacobian_ij, Jacobian_ji, Jacobian_jj, config); - - /*--- Update adjoint viscous residual ---*/ - - LinSysRes.SubtractBlock(iPoint, Residual_i); - LinSysRes.AddBlock(jPoint, Residual_j); - - if (implicit) { - Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_ii); - Jacobian.SubtractBlock(iPoint, jPoint, Jacobian_ij); - Jacobian.AddBlock(jPoint, iPoint, Jacobian_ji); - Jacobian.AddBlock(jPoint, jPoint, Jacobian_jj); - } - - } - -} - -void CAdjNSSolver::Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CNumerics *second_numerics, - CConfig *config, unsigned short iMesh) { - - unsigned long iPoint, jPoint, iEdge; - - bool implicit = (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); - bool rotating_frame = config->GetRotating_Frame(); - - /*--- Loop over all the points, note that we are supposing that primitive and - adjoint gradients have been computed previously ---*/ - - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - - /*--- Primitive variables w/o reconstruction, and its gradient ---*/ - - numerics->SetPrimitive(solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint), NULL); - - numerics->SetPrimVarGradient(solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint), NULL); - - /*--- Gradient of adjoint variables ---*/ - - numerics->SetAdjointVarGradient(nodes->GetGradient(iPoint), NULL); - - /*--- Set volume ---*/ - - numerics->SetVolume(geometry->node[iPoint]->GetVolume()); - - /*--- If turbulence computation we must add some coupling terms to the NS adjoint eq. ---*/ - - if ((config->GetKind_Solver() == ADJ_RANS) && (!config->GetFrozen_Visc_Cont())) { - - /*--- Turbulent variables w/o reconstruction and its gradient ---*/ - - numerics->SetTurbVar(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint), NULL); - - numerics->SetTurbVarGradient(solver_container[TURB_SOL]->GetNodes()->GetGradient(iPoint), NULL); - - /*--- Turbulent adjoint variables w/o reconstruction and its gradient ---*/ - - numerics->SetTurbAdjointVar(solver_container[ADJTURB_SOL]->GetNodes()->GetSolution(iPoint), NULL); - - numerics->SetTurbAdjointGradient(solver_container[ADJTURB_SOL]->GetNodes()->GetGradient(iPoint), NULL); - - /*--- Set distance to the surface ---*/ - - numerics->SetDistance(geometry->node[iPoint]->GetWall_Distance(), 0.0); - - } - - /*--- Compute residual ---*/ - - numerics->ComputeResidual(Residual, config); - - /*--- Add to the residual ---*/ - - LinSysRes.AddBlock(iPoint, Residual); - - } - - /*--- If turbulence computation we must add some coupling terms to the NS adjoint eq. ---*/ - - if ((config->GetKind_Solver() == ADJ_RANS) && (!config->GetFrozen_Visc_Cont())) { - - for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - - /*--- Points in edge, and normal vector ---*/ - - iPoint = geometry->edge[iEdge]->GetNode(0); - jPoint = geometry->edge[iEdge]->GetNode(1); - second_numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); - - /*--- Conservative variables w/o reconstruction ---*/ - - second_numerics->SetConservative(solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint), - solver_container[FLOW_SOL]->GetNodes()->GetSolution(jPoint)); - - /*--- Gradient of primitive variables w/o reconstruction ---*/ - - second_numerics->SetPrimVarGradient(solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint), - solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(jPoint)); - - /*--- Viscosity ---*/ - - second_numerics->SetLaminarViscosity(solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint), - solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(jPoint)); - - /*--- Turbulent variables w/o reconstruction ---*/ - - second_numerics->SetTurbVar(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint), - solver_container[TURB_SOL]->GetNodes()->GetSolution(jPoint)); - - /*--- Turbulent adjoint variables w/o reconstruction ---*/ - - second_numerics->SetTurbAdjointVar(solver_container[ADJTURB_SOL]->GetNodes()->GetSolution(iPoint), - solver_container[ADJTURB_SOL]->GetNodes()->GetSolution(jPoint)); - - /*--- Set distance to the surface ---*/ - - second_numerics->SetDistance(geometry->node[iPoint]->GetWall_Distance(), geometry->node[jPoint]->GetWall_Distance()); - - /*--- Update adjoint viscous residual ---*/ - - second_numerics->ComputeResidual(Residual, config); - - LinSysRes.AddBlock(iPoint, Residual); - LinSysRes.SubtractBlock(jPoint, Residual); - } - - } - - // WARNING: The rotating frame source term has been placed in the second - // source term container since the section below is commented. This needs a - // permanent fix asap! - - if (rotating_frame) { - - /*--- Loop over all points ---*/ - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - - /*--- Load the adjoint variables ---*/ - second_numerics->SetAdjointVar(nodes->GetSolution(iPoint), - nodes->GetSolution(iPoint)); - - /*--- Load the volume of the dual mesh cell ---*/ - second_numerics->SetVolume(geometry->node[iPoint]->GetVolume()); - - /*--- Compute the adjoint rotating frame source residual ---*/ - second_numerics->ComputeResidual(Residual, Jacobian_i, config); - - /*--- Add the source residual to the total ---*/ - LinSysRes.AddBlock(iPoint, Residual); - - /*--- Add the implicit Jacobian contribution ---*/ - if (implicit) Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - - } - } -} - -void CAdjNSSolver::Viscous_Sensitivity(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config) { - - unsigned long iVertex, iPoint; - unsigned short iDim, jDim, iMarker, iPos, jPos; - su2double *d = NULL, **PsiVar_Grad = NULL, **PrimVar_Grad = NULL, div_phi, *Normal = NULL, Area, - normal_grad_psi5, normal_grad_T, sigma_partial, Laminar_Viscosity = 0.0, heat_flux_factor, temp_sens = 0.0, *Psi = NULL, *U = NULL, Enthalpy, **GridVel_Grad, gradPsi5_v, psi5_tau_partial, psi5_tau_grad_vel, source_v_1, Density, Pressure = 0.0, div_vel, val_turb_ke, vartheta, vartheta_partial, psi5_p_div_vel, Omega[3], rho_v[3] = {0.0,0.0,0.0}, CrossProduct[3], delta[3][3] = {{1.0, 0.0, 0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}}, r, ru, rv, rw, rE, p, T, dp_dr, dp_dru, dp_drv, dp_drw, dp_drE, dH_dr, dH_dru, dH_drv, dH_drw, dH_drE, H, D[3][3], Dd[3], Mach_Inf, eps, scale = 1.0; - su2double RefVel2, RefDensity, Mach2Vel, *Velocity_Inf, factor; - - su2double *USens = new su2double[nVar]; - su2double *UnitNormal = new su2double[nDim]; - su2double *normal_grad_vel = new su2double[nDim]; - su2double *tang_deriv_psi5 = new su2double[nDim]; - su2double *tang_deriv_T = new su2double[nDim]; - su2double **Sigma = new su2double* [nDim]; - - for (iDim = 0; iDim < nDim; iDim++) - Sigma[iDim] = new su2double [nDim]; - - su2double *normal_grad_gridvel = new su2double[nDim]; - su2double *normal_grad_v_ux =new su2double[nDim]; - su2double **Sigma_Psi5v = new su2double* [nDim]; - for (iDim = 0; iDim < nDim; iDim++) - Sigma_Psi5v[iDim] = new su2double [nDim]; - su2double **tau = new su2double* [nDim]; - for (iDim = 0; iDim < nDim; iDim++) - tau[iDim] = new su2double [nDim]; - su2double *Velocity = new su2double[nDim]; - - bool rotating_frame = config->GetRotating_Frame(); - bool grid_movement = config->GetGrid_Movement(); - su2double RefArea = config->GetRefArea(); - su2double Mach_Motion = config->GetMach_Motion(); - unsigned short ObjFunc = config->GetKind_ObjFunc(); - su2double Gas_Constant = config->GetGas_ConstantND(); - su2double Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; - su2double Prandtl_Lam = config->GetPrandtl_Lam(); - - if (config->GetSystemMeasurements() == US) scale = 1.0/12.0; - else scale = 1.0; - - /*--- Compute non-dimensional factor. For dynamic meshes, use the motion Mach - number as a reference value for computing the force coefficients. - Otherwise, use the freestream values, - which is the standard convention. ---*/ - - if (grid_movement) { - Mach2Vel = sqrt(Gamma*Gas_Constant*config->GetTemperature_FreeStreamND()); - RefVel2 = (Mach_Motion*Mach2Vel)*(Mach_Motion*Mach2Vel); - } - else { - Velocity_Inf = config->GetVelocity_FreeStreamND(); - RefVel2 = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - RefVel2 += Velocity_Inf[iDim]*Velocity_Inf[iDim]; - } - - RefDensity = config->GetDensity_FreeStreamND(); - - factor = 1.0; - /*-- For multi-objective problems these scaling factors are applied before solution ---*/ - if (config->GetnObj()==1) { - factor = 1.0/(0.5*RefDensity*RefArea*RefVel2); - - if ((ObjFunc == INVERSE_DESIGN_HEATFLUX) || - (ObjFunc == TOTAL_HEATFLUX) || (ObjFunc == MAXIMUM_HEATFLUX) || - (ObjFunc == SURFACE_MASSFLOW)) - factor = 1.0; - - if ((ObjFunc == SURFACE_TOTAL_PRESSURE) || (ObjFunc == SURFACE_STATIC_PRESSURE)) - factor = 1.0/Area_Monitored; - - } - - - /*--- Compute gradient of the grid velocity, if applicable ---*/ - - if (grid_movement) - SetGridVel_Gradient(geometry, config); - - Total_Sens_Geo = 0.0; - Total_Sens_Mach = 0.0; - Total_Sens_AoA = 0.0; - Total_Sens_Press = 0.0; - Total_Sens_Temp = 0.0; - - for (iMarker = 0; iMarker < nMarker; iMarker++) { - - Sens_Geo[iMarker] = 0.0; - - if ((config->GetMarker_All_KindBC(iMarker) == HEAT_FLUX) || - (config->GetMarker_All_KindBC(iMarker) == ISOTHERMAL)) { - - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - - iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - - if (geometry->node[iPoint]->GetDomain()) { - - PsiVar_Grad = nodes->GetGradient(iPoint); - PrimVar_Grad = solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint); - - Laminar_Viscosity = solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); - - heat_flux_factor = Cp * Laminar_Viscosity / Prandtl_Lam; - - /*--- Compute face area and the unit normal to the surface ---*/ - - Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) { Area += Normal[iDim]*Normal[iDim]; } Area = sqrt(Area); - for (iDim = 0; iDim < nDim; iDim++) { UnitNormal[iDim] = Normal[iDim] / Area; } - - /*--- Compute the sensitivity related to the temperature ---*/ - - - normal_grad_psi5 = 0.0; normal_grad_T = 0.0; - for (iDim = 0; iDim < nDim; iDim++) { - normal_grad_psi5 += PsiVar_Grad[nVar-1][iDim]*UnitNormal[iDim]; - normal_grad_T += PrimVar_Grad[0][iDim]*UnitNormal[iDim]; - } - - temp_sens = 0.0; - if (config->GetMarker_All_KindBC(iMarker) == HEAT_FLUX) { - - /*--- Heat Flux Term: temp_sens = (\partial_tg \psi_5)\cdot (k \partial_tg T) ---*/ - - for (iDim = 0; iDim < nDim; iDim++) { - tang_deriv_psi5[iDim] = PsiVar_Grad[nVar-1][iDim] - normal_grad_psi5*UnitNormal[iDim]; - tang_deriv_T[iDim] = PrimVar_Grad[0][iDim] - normal_grad_T*UnitNormal[iDim]; - } - for (iDim = 0; iDim < nDim; iDim++) - temp_sens += heat_flux_factor * tang_deriv_psi5[iDim] * tang_deriv_T[iDim]; - - } else if (config->GetMarker_All_KindBC(iMarker) == ISOTHERMAL) { - - /*--- Isothermal Term: temp_sens = - k * \partial_n(\psi_5) * \partial_n(T) ---*/ - - temp_sens = - heat_flux_factor * normal_grad_psi5 * normal_grad_T; - - } - - - /*--- Term: sigma_partial = \Sigma_{ji} n_i \partial_n v_j ---*/ - - div_phi = 0.0; - for (iDim = 0; iDim < nDim; iDim++) { - div_phi += PsiVar_Grad[iDim+1][iDim]; - for (jDim = 0; jDim < nDim; jDim++) - Sigma[iDim][jDim] = Laminar_Viscosity * (PsiVar_Grad[iDim+1][jDim]+PsiVar_Grad[jDim+1][iDim]); - } - for (iDim = 0; iDim < nDim; iDim++) - Sigma[iDim][iDim] -= TWO3*Laminar_Viscosity * div_phi; - - - for (iDim = 0; iDim < nDim; iDim++) { - normal_grad_vel[iDim] = 0.0; - for (jDim = 0; jDim < nDim; jDim++) - normal_grad_vel[iDim] += PrimVar_Grad[iDim+1][jDim]*UnitNormal[jDim]; - } - - sigma_partial = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - for (jDim = 0; jDim < nDim; jDim++) - sigma_partial += UnitNormal[iDim]*Sigma[iDim][jDim]*normal_grad_vel[jDim]; - - /*--- Compute additional terms in the surface sensitivity for - moving walls in a rotating frame or dynamic mesh problem. ---*/ - - if (grid_movement) { - - Psi = nodes->GetSolution(iPoint); - U = solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint); - Density = U[0]; - Pressure = solver_container[FLOW_SOL]->GetNodes()->GetPressure(iPoint); - Enthalpy = solver_container[FLOW_SOL]->GetNodes()->GetEnthalpy(iPoint); - - /*--- Turbulent kinetic energy ---*/ - - if ((config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST)) - val_turb_ke = solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0); - else - val_turb_ke = 0.0; - - div_vel = 0.0; - for (iDim = 0 ; iDim < nDim; iDim++) { - Velocity[iDim] = U[iDim+1]/Density; - div_vel += PrimVar_Grad[iDim+1][iDim]; - } - - for (iDim = 0 ; iDim < nDim; iDim++) - for (jDim = 0 ; jDim < nDim; jDim++) - tau[iDim][jDim] = Laminar_Viscosity*(PrimVar_Grad[jDim+1][iDim] + PrimVar_Grad[iDim+1][jDim]) - - TWO3*Laminar_Viscosity*div_vel*delta[iDim][jDim] - - TWO3*Density*val_turb_ke*delta[iDim][jDim]; - - /*--- Form normal_grad_gridvel = \partial_n (u_omega) ---*/ - - GridVel_Grad = geometry->node[iPoint]->GetGridVel_Grad(); - for (iDim = 0; iDim < nDim; iDim++) { - normal_grad_gridvel[iDim] = 0.0; - for (jDim = 0; jDim < nDim; jDim++) - normal_grad_gridvel[iDim] += GridVel_Grad[iDim][jDim]*UnitNormal[jDim]; - } - - /*--- Form normal_grad_v_ux = \partial_n (v - u_omega) ---*/ - - for (iDim = 0; iDim < nDim; iDim++) - normal_grad_v_ux[iDim] = normal_grad_vel[iDim] - normal_grad_gridvel[iDim]; - - /*--- Form Sigma_Psi5v ---*/ - - gradPsi5_v = 0.0; - for (iDim = 0; iDim < nDim; iDim++) { - gradPsi5_v += PsiVar_Grad[nDim+1][iDim]*Velocity[iDim]; - for (jDim = 0; jDim < nDim; jDim++) - Sigma_Psi5v[iDim][jDim] = Laminar_Viscosity * (PsiVar_Grad[nDim+1][iDim]*Velocity[jDim]+PsiVar_Grad[nDim+1][jDim]*Velocity[iDim]); - } - for (iDim = 0; iDim < nDim; iDim++) - Sigma_Psi5v[iDim][iDim] -= TWO3*Laminar_Viscosity * gradPsi5_v; - - - /*--- Now compute terms of the surface sensitivity ---*/ - - /*--- Form vartheta_partial = \vartheta * \partial_n (v - u_x) . n ---*/ - vartheta = Density*Psi[0] + Density*Enthalpy*Psi[nDim+1]; - for (iDim = 0; iDim < nDim; iDim++) { - vartheta += U[iDim+1]*Psi[iDim+1]; - } - vartheta_partial = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - vartheta_partial += vartheta * normal_grad_v_ux[iDim] * UnitNormal[iDim]; - - /*--- Form sigma_partial = n_i ( \Sigma_Phi_{ij} + \Sigma_Psi5v_{ij} ) \partial_n (v - u_x)_j ---*/ - - sigma_partial = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - for (jDim = 0; jDim < nDim; jDim++) - sigma_partial += UnitNormal[iDim]*(Sigma[iDim][jDim]+Sigma_Psi5v[iDim][jDim])*normal_grad_v_ux[jDim]; - - /*--- Form psi5_tau_partial = \Psi_5 * \partial_n (v - u_x)_i * tau_{ij} * n_j ---*/ - - psi5_tau_partial = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - for (jDim = 0; jDim < nDim; jDim++) - psi5_tau_partial -= Psi[nDim+1]*normal_grad_v_ux[iDim]*tau[iDim][jDim]*UnitNormal[jDim]; - - /*--- Form psi5_p_div_vel = ---*/ - - psi5_p_div_vel = -Psi[nDim+1]*Pressure*div_vel; - - /*--- Form psi5_tau_grad_vel = \Psi_5 * tau_{ij} : \nabla( v ) ---*/ - - psi5_tau_grad_vel = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - for (jDim = 0; jDim < nDim; jDim++) - psi5_tau_grad_vel += Psi[nDim+1]*tau[iDim][jDim]*PrimVar_Grad[iDim+1][jDim]; - - /*--- Retrieve the angular velocity vector ---*/ - - source_v_1 = 0.0; - if (rotating_frame) { - - for (iDim = 0; iDim < 3; iDim++){ - Omega[iDim] = config->GetRotation_Rate(iDim)/config->GetOmega_Ref(); - } - - /*--- Calculate momentum source terms as: rho * ( Omega X V ) ---*/ - - for (iDim = 0; iDim < nDim; iDim++) - rho_v[iDim] = U[iDim+1]; - if (nDim == 2) rho_v[2] = 0.0; - - CrossProduct[0] = Omega[1]*rho_v[2] - Omega[2]*rho_v[1]; - CrossProduct[1] = Omega[2]*rho_v[0] - Omega[0]*rho_v[2]; - CrossProduct[2] = Omega[0]*rho_v[1] - Omega[1]*rho_v[0]; - - - for (iDim = 0; iDim < nDim; iDim++) { - source_v_1 += Psi[iDim+1]*CrossProduct[iDim]; - } - } - - /*--- For simplicity, store all additional terms within sigma_partial ---*/ - - sigma_partial = sigma_partial + vartheta_partial + psi5_tau_partial + psi5_p_div_vel + psi5_tau_grad_vel + source_v_1; - - } - - /*--- Compute sensitivity for each surface point ---*/ - - CSensitivity[iMarker][iVertex] = (sigma_partial - temp_sens) * Area * scale * factor; - - /*--- If sharp edge, set the sensitivity to 0 on that region ---*/ - - if (config->GetSens_Remove_Sharp()) { - eps = config->GetVenkat_LimiterCoeff()*config->GetRefElemLength(); - if ( geometry->node[iPoint]->GetSharpEdge_Distance() < config->GetAdjSharp_LimiterCoeff()*eps ) - CSensitivity[iMarker][iVertex] = 0.0; - } - - Sens_Geo[iMarker] -= CSensitivity[iMarker][iVertex]; - - } - } - - Total_Sens_Geo += Sens_Geo[iMarker]; - - } - } - - /*--- Farfield Sensitivity (Mach, AoA, Press, Temp), only for compressible flows ---*/ - - for (iMarker = 0; iMarker < nMarker; iMarker++) { - - if (config->GetMarker_All_KindBC(iMarker) == FAR_FIELD || config->GetMarker_All_KindBC(iMarker) == INLET_FLOW || - config->GetMarker_All_KindBC(iMarker) == SUPERSONIC_INLET || config->GetMarker_All_KindBC(iMarker) == SUPERSONIC_OUTLET || - config->GetMarker_All_KindBC(iMarker) == ENGINE_INFLOW ) { - - Sens_Mach[iMarker] = 0.0; - Sens_AoA[iMarker] = 0.0; - Sens_Press[iMarker] = 0.0; - Sens_Temp[iMarker] = 0.0; - Sens_BPress[iMarker] = 0.0; - - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - - if (geometry->node[iPoint]->GetDomain()) { - Psi = nodes->GetSolution(iPoint); - U = solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint); - Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - - Mach_Inf = config->GetMach(); - if (grid_movement) Mach_Inf = config->GetMach_Motion(); - - r = U[0]; ru = U[1]; rv = U[2]; - if (nDim == 2) { rw = 0.0; rE = U[3]; } - else { rw = U[3]; rE = U[4]; } - p = Gamma_Minus_One*(rE-(ru*ru + rv*rv + rw*rw)/(2*r)); - - Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; - Area = sqrt(Area); - for (iDim = 0; iDim < nDim; iDim++) UnitNormal[iDim] = -Normal[iDim]/Area; - - H = (rE + p)/r; - - dp_dr = Gamma_Minus_One*(ru*ru + rv*rv + rw*rw)/(2*r*r); - dp_dru = -Gamma_Minus_One*ru/r; - dp_drv = -Gamma_Minus_One*rv/r; - if (nDim == 2) { dp_drw = 0.0; dp_drE = Gamma_Minus_One; } - else { dp_drw = -Gamma_Minus_One*rw/r; dp_drE = Gamma_Minus_One; } - - dH_dr = (-H + dp_dr)/r; dH_dru = dp_dru/r; dH_drv = dp_drv/r; - if (nDim == 2) { dH_drw = 0.0; dH_drE = (1 + dp_drE)/r; } - else { dH_drw = dp_drw/r; dH_drE = (1 + dp_drE)/r; } - - if (nDim == 2) { - Jacobian_j[0][0] = 0.0; - Jacobian_j[1][0] = Area*UnitNormal[0]; - Jacobian_j[2][0] = Area*UnitNormal[1]; - Jacobian_j[3][0] = 0.0; - - Jacobian_j[0][1] = (-(ru*ru)/(r*r) + dp_dr)*Area*UnitNormal[0] + (-(ru*rv)/(r*r))*Area*UnitNormal[1]; - Jacobian_j[1][1] = (2*ru/r + dp_dru)*Area*UnitNormal[0] + (rv/r)*Area*UnitNormal[1]; - Jacobian_j[2][1] = (dp_drv)*Area*UnitNormal[0] + (ru/r)*Area*UnitNormal[1]; - Jacobian_j[3][1] = (dp_drE)*Area*UnitNormal[0]; - - Jacobian_j[0][2] = (-(ru*rv)/(r*r))*Area*UnitNormal[0] + (-(rv*rv)/(r*r) + dp_dr)*Area*UnitNormal[1]; - Jacobian_j[1][2] = (rv/r)*Area*UnitNormal[0] + (dp_dru)*Area*UnitNormal[1]; - Jacobian_j[2][2] = (ru/r)*Area*UnitNormal[0] + (2*rv/r + dp_drv)*Area*UnitNormal[1]; - Jacobian_j[3][2] = (dp_drE)*Area*UnitNormal[1]; - - Jacobian_j[0][3] = (ru*dH_dr)*Area*UnitNormal[0] + (rv*dH_dr)*Area*UnitNormal[1]; - Jacobian_j[1][3] = (H + ru*dH_dru)*Area*UnitNormal[0] + (rv*dH_dru)*Area*UnitNormal[1]; - Jacobian_j[2][3] = (ru*dH_drv)*Area*UnitNormal[0] + (H + rv*dH_drv)*Area*UnitNormal[1]; - Jacobian_j[3][3] = (ru*dH_drE)*Area*UnitNormal[0] + (rv*dH_drE)*Area*UnitNormal[1]; - } - else { - Jacobian_j[0][0] = 0.0; - Jacobian_j[1][0] = Area*UnitNormal[0]; - Jacobian_j[2][0] = Area*UnitNormal[1]; - Jacobian_j[3][0] = Area*UnitNormal[2]; - Jacobian_j[4][0] = 0.0; - - Jacobian_j[0][1] = (-(ru*ru)/(r*r) + dp_dr)*Area*UnitNormal[0] + (-(ru*rv)/(r*r))*Area*UnitNormal[1] + (-(ru*rw)/(r*r))*Area*UnitNormal[2]; - Jacobian_j[1][1] = (2*ru/r + dp_dru)*Area*UnitNormal[0] + (rv/r)*Area*UnitNormal[1] + (rw/r)*Area*UnitNormal[2]; - Jacobian_j[2][1] = (dp_drv)*Area*UnitNormal[0] + (ru/r)*Area*UnitNormal[1]; - Jacobian_j[3][1] = (dp_drw)*Area*UnitNormal[0] + (ru/r)*Area*UnitNormal[2]; - Jacobian_j[4][1] = (dp_drE)*Area*UnitNormal[0]; - - Jacobian_j[0][2] = (-(ru*rv)/(r*r))*Area*UnitNormal[0] + (-(rv*rv)/(r*r) + dp_dr)*Area*UnitNormal[1] + (-(rv*rw)/(r*r))*Area*UnitNormal[2]; - Jacobian_j[1][2] = (rv/r)*Area*UnitNormal[0] + (dp_dru)*Area*UnitNormal[1]; - Jacobian_j[2][2] = (ru/r)*Area*UnitNormal[0] + (2*rv/r + dp_drv)*Area*UnitNormal[1] + (rw/r)*Area*UnitNormal[2]; - Jacobian_j[3][2] = (dp_drw)*Area*UnitNormal[1] + (rv/r)*Area*UnitNormal[2]; - Jacobian_j[4][2] = (dp_drE)*Area*UnitNormal[1]; - - Jacobian_j[0][3] = (-(ru*rw)/(r*r))*Area*UnitNormal[0] + (-(rv*rw)/(r*r))*Area*UnitNormal[1] + (-(rw*rw)/(r*r) + dp_dr)*Area*UnitNormal[2]; - Jacobian_j[1][3] = (rw/r)*Area*UnitNormal[0] + (dp_dru)*Area*UnitNormal[2]; - Jacobian_j[2][3] = (rw/r)*Area*UnitNormal[1] + (dp_drv)*Area*UnitNormal[2]; - Jacobian_j[3][3] = (ru/r)*Area*UnitNormal[0] + (rv/r)*Area*UnitNormal[1] + (2*rw/r + dp_drw)*Area*UnitNormal[2]; - Jacobian_j[4][3] = (dp_drE)*Area*UnitNormal[2]; - - Jacobian_j[0][4] = (ru*dH_dr)*Area*UnitNormal[0] + (rv*dH_dr)*Area*UnitNormal[1] + (rw*dH_dr)*Area*UnitNormal[2]; - Jacobian_j[1][4] = (H + ru*dH_dru)*Area*UnitNormal[0] + (rv*dH_dru)*Area*UnitNormal[1] + (rw*dH_dru)*Area*UnitNormal[2]; - Jacobian_j[2][4] = (ru*dH_drv)*Area*UnitNormal[0] + (H + rv*dH_drv)*Area*UnitNormal[1] + (rw*dH_drv)*Area*UnitNormal[2]; - Jacobian_j[3][4] = (ru*dH_drw)*Area*UnitNormal[0] + (rv*dH_drw)*Area*UnitNormal[1] + (H + rw*dH_drw)*Area*UnitNormal[2]; - Jacobian_j[4][4] = (ru*dH_drE)*Area*UnitNormal[0] + (rv*dH_drE)*Area*UnitNormal[1] + (rw*dH_drE)*Area*UnitNormal[2]; - } - - /*--- Mach number sensitivity ---*/ - - USens[0] = 0.0; USens[1] = ru/Mach_Inf; USens[2] = rv/Mach_Inf; - if (nDim == 2) { USens[3] = Gamma*Mach_Inf*p; } - else { USens[3] = rw/Mach_Inf; USens[4] = Gamma*Mach_Inf*p; } - for (iPos = 0; iPos < nVar; iPos++) { - for (jPos = 0; jPos < nVar; jPos++) { - Sens_Mach[iMarker] += Psi[iPos]*Jacobian_j[jPos][iPos]*USens[jPos]; - } - } - - /*--- AoA sensitivity ---*/ - - USens[0] = 0.0; - if (nDim == 2) { USens[1] = -rv; USens[2] = ru; USens[3] = 0.0; } - else { USens[1] = -rw; USens[2] = 0.0; USens[3] = ru; USens[4] = 0.0; } - for (iPos = 0; iPos < nVar; iPos++) { - for (jPos = 0; jPos < nVar; jPos++) { - Sens_AoA[iMarker] += Psi[iPos]*Jacobian_j[jPos][iPos]*USens[jPos]; - } - } - - /*--- Pressure sensitivity ---*/ - - USens[0] = r/p; USens[1] = ru/p; USens[2] = rv/p; - if (nDim == 2) { USens[3] = rE/p; } - else { USens[3] = rw/p; USens[4] = rE/p; } - for (iPos = 0; iPos < nVar; iPos++) { - for (jPos = 0; jPos < nVar; jPos++) { - Sens_Press[iMarker] += Psi[iPos]*Jacobian_j[jPos][iPos]*USens[jPos]; - } - } - - /*--- Temperature sensitivity ---*/ - - T = p/(r*Gas_Constant); - USens[0] = -r/T; USens[1] = 0.5*ru/T; USens[2] = 0.5*rv/T; - if (nDim == 2) { USens[3] = (ru*ru + rv*rv + rw*rw)/(r*T); } - else { USens[3] = 0.5*rw/T; USens[4] = (ru*ru + rv*rv + rw*rw)/(r*T); } - for (iPos = 0; iPos < nVar; iPos++) { - for (jPos = 0; jPos < nVar; jPos++) { - Sens_Temp[iMarker] += Psi[iPos]*Jacobian_j[jPos][iPos]*USens[jPos]; - } - } - } - } - - Total_Sens_Mach -= Sens_Mach[iMarker] * scale * factor; - Total_Sens_AoA -= Sens_AoA[iMarker] * scale * factor; - Total_Sens_Press -= Sens_Press[iMarker] * scale * factor; - Total_Sens_Temp -= Sens_Temp[iMarker] * scale * factor; - - } - - } - - /*--- Explicit contribution from objective function quantity ---*/ - - for (iMarker = 0; iMarker < nMarker; iMarker++) { - - if ((config->GetMarker_All_KindBC(iMarker) == HEAT_FLUX) || - (config->GetMarker_All_KindBC(iMarker) == ISOTHERMAL)) { - - Sens_Mach[iMarker] = 0.0; - Sens_AoA[iMarker] = 0.0; - Sens_Press[iMarker] = 0.0; - Sens_Temp[iMarker] = 0.0; - Sens_BPress[iMarker] = 0.0; - - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - - if (geometry->node[iPoint]->GetDomain()) { - - Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - p = solver_container[FLOW_SOL]->GetNodes()->GetPressure(iPoint); - - Mach_Inf = config->GetMach(); - if (grid_movement) Mach_Inf = config->GetMach_Motion(); - - d = nodes->GetForceProj_Vector(iPoint); - Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; - Area = sqrt(Area); - for (iDim = 0; iDim < nDim; iDim++) UnitNormal[iDim] = -Normal[iDim]/Area; - - /*--- Mach number sensitivity ---*/ - - for (iPos = 0; iPos < nDim; iPos++) Dd[iPos] = -(2.0/Mach_Inf)*d[iPos]; - for (iPos = 0; iPos < nDim; iPos++) Sens_Mach[iMarker] += p*Dd[iPos]*Area*UnitNormal[iPos]; - - /*--- AoA sensitivity ---*/ - - if (config->GetKind_ObjFunc() == DRAG_COEFFICIENT || - config->GetKind_ObjFunc() == LIFT_COEFFICIENT || - config->GetKind_ObjFunc() == SIDEFORCE_COEFFICIENT || - config->GetKind_ObjFunc() == EQUIVALENT_AREA || - config->GetKind_ObjFunc() == NEARFIELD_PRESSURE) { - if (nDim == 2) { - D[0][0] = 0.0; D[0][1] = -1.0; - D[1][0] = 1.0; D[1][1] = 0.0; - } - else { - D[0][0] = 0.0; D[0][1] = 0.0; D[0][2] = -1.0; - D[1][0] = 0.0; D[1][1] = 0.0; D[1][2] = 0.0; - D[2][0] = 1.0; D[2][1] = 0.0; D[2][2] = 0.0; - } - for (iPos = 0; iPos < nDim; iPos++) Dd[iPos] = 0.0; - for (iPos = 0; iPos < nDim; iPos++) { - for (jPos = 0; jPos < nDim; jPos++) - Dd[iPos] += D[iPos][jPos]*d[jPos]; - } - } - - /*--- Coefficients with no explicit AoA dependece ---*/ - - else { - for (iPos = 0; iPosGetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); - bool grid_movement = config->GetGrid_Movement(); - - su2double Prandtl_Lam = config->GetPrandtl_Lam(); - su2double Prandtl_Turb = config->GetPrandtl_Turb(); - - su2double *Psi = new su2double[nVar]; - su2double **Tau = new su2double*[nDim]; - for (iDim = 0; iDim < nDim; iDim++) - Tau[iDim] = new su2double [nDim]; - su2double *Velocity = new su2double[nDim]; - su2double *Normal = new su2double[nDim]; - su2double *Edge_Vector = new su2double[nDim]; - su2double **GradPhi = new su2double*[nDim]; - for (iDim = 0; iDim < nDim; iDim++) - GradPhi[iDim] = new su2double [nDim]; - su2double *GradPsiE = new su2double [nDim]; - - /*--- Loop over all of the vertices on this boundary marker ---*/ - - for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - - iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - - /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ - - if (geometry->node[iPoint]->GetDomain()) { - - /*--- Normal vector for this vertex (negate for outward convention) ---*/ - - geometry->vertex[val_marker][iVertex]->GetNormal(Normal); - for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; - - /*--- Initialize the convective & viscous residuals to zero ---*/ - - for (iVar = 0; iVar < nVar; iVar++) { - Res_Conv_i[iVar] = 0.0; Res_Visc_i[iVar] = 0.0; - if (implicit) { for (jVar = 0; jVar < nVar; jVar ++) Jacobian_ii[iVar][jVar] = 0.0; } - } - - /*--- Retrieve adjoint solution at the wall boundary node ---*/ - - for (iVar = 0; iVar < nVar; iVar++) - Psi[iVar] = nodes->GetSolution(iPoint,iVar); - - /*--- Get the force projection vector (based on the objective function) ---*/ - - d = nodes->GetForceProj_Vector(iPoint); - - /*--- Set the adjoint velocity BC ---*/ - - for (iDim = 0; iDim < nDim; iDim++) { phi[iDim] = d[iDim]; } - - /*--- Correct the adjoint velocity BC for dynamic meshes ---*/ - - if (grid_movement) { - GridVel = geometry->node[iPoint]->GetGridVel(); - for (iDim = 0; iDim < nDim; iDim++) - phi[iDim] -= Psi[nDim+1]*GridVel[iDim]; - } - - /*--- Impose the value of the adjoint velocity as a strong boundary - condition (Dirichlet). Fix the adjoint velocity and remove any addtional - contribution to the residual at this node. ---*/ - - for (iDim = 0; iDim < nDim; iDim++) - nodes->SetSolution_Old(iPoint,iDim+1, phi[iDim]); - - for (iDim = 0; iDim < nDim; iDim++) - LinSysRes.SetBlock_Zero(iPoint, iDim+1); - nodes->SetVel_ResTruncError_Zero(iPoint); - - /*--- Compute additional contributions to the adjoint density and energy - equations which will be added to the residual (weak imposition) ---*/ - - /*--- Energy residual due to the convective term ---*/ - - l1psi = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - l1psi += Normal[iDim]*d[iDim]; - Res_Conv_i[nDim+1] = l1psi*Gamma_Minus_One; - - /*--- Flux contribution and Jacobian contributions for moving - walls. Note that these are only for the adjoint density and - adjoint energy equations (the adjoint vel. uses a strong BC). ---*/ - - if (grid_movement) { - - /*--- Get the grid velocity at this node and impose v = u_wall ---*/ - - GridVel = geometry->node[iPoint]->GetGridVel(); - for (iDim = 0; iDim < nDim; iDim++) Velocity[iDim] = GridVel[iDim]; - - /*--- Get some additional quantities from the flow solution ---*/ - - Density = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); - Pressure = solver_container[FLOW_SOL]->GetNodes()->GetPressure(iPoint); - Enthalpy = solver_container[FLOW_SOL]->GetNodes()->GetEnthalpy(iPoint); - Laminar_Viscosity = solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); - Eddy_Viscosity = solver_container[FLOW_SOL]->GetNodes()->GetEddyViscosity(iPoint); // Should be zero at the wall - - ViscDens = (Laminar_Viscosity + Eddy_Viscosity) / Density; - XiDens = Gamma * (Laminar_Viscosity/Prandtl_Lam + Eddy_Viscosity/Prandtl_Turb) / Density; - - /*--- Compute projections, velocity squared divided by two, and - other inner products. Note that we are imposing v = u_wall from - the direct problem and that phi = d - \psi_5 * v ---*/ - - ProjGridVel = 0.0; sq_vel = 0.0; - vartheta = Psi[0] + Psi[nDim+1]*Enthalpy; - for (iDim = 0; iDim < nDim; iDim++) { - ProjGridVel += GridVel[iDim]*Normal[iDim]; - sq_vel += 0.5*GridVel[iDim]*GridVel[iDim]; - vartheta += GridVel[iDim]*phi[iDim]; - } - - /*--- Convective flux at the wall node (adjoint density) ---*/ - - Res_Conv_i[0] = -vartheta*ProjGridVel + l1psi*Gamma_Minus_One*sq_vel; - - /*--- Implicit contributions from convective part ---*/ - - if (implicit) { - Jacobian_ii[0][0] += -ProjGridVel; - Jacobian_ii[0][nVar-1] += -ProjGridVel * Enthalpy; - } - - /*--- Viscous flux contributions at the wall node. Impose dPhiE_dn = 0 - (adiabatic walls with frozen viscosity). ---*/ - - dPhiE_dn = 0.0; - - /*--- Store the adjoint velocity and energy gradients for clarity ---*/ - - PsiVar_Grad = nodes->GetGradient(iPoint); - for (iDim = 0; iDim < nDim; iDim++) { - GradPsiE[iDim] = PsiVar_Grad[nVar-1][iDim]; - for (jDim = 0; jDim < nDim; jDim++) - GradPhi[iDim][jDim] = PsiVar_Grad[iDim+1][jDim]; - } - - if (nDim == 2) { - - /*--- Compute the adjoint stress tensor ---*/ - - Sigma_xx = ViscDens * (FOUR3 * GradPhi[0][0] - TWO3 * GradPhi[1][1]); - Sigma_yy = ViscDens * (-TWO3 * GradPhi[0][0] + FOUR3 * GradPhi[1][1]); - Sigma_xy = ViscDens * (GradPhi[1][0] + GradPhi[0][1]); - Sigma_xx5 = ViscDens * ( FOUR3 * Velocity[0] * GradPsiE[0] - TWO3 * Velocity[1] * GradPsiE[1]); - Sigma_yy5 = ViscDens * (- TWO3 * Velocity[0] * GradPsiE[0] + FOUR3 * Velocity[1] * GradPsiE[1]); - Sigma_xy5 = ViscDens * (Velocity[0] * GradPsiE[1] + Velocity[1] * GradPsiE[0]); - Sigma_5 = XiDens * dPhiE_dn; - eta_xx = Sigma_xx + Sigma_xx5; - eta_yy = Sigma_yy + Sigma_yy5; - eta_xy = Sigma_xy + Sigma_xy5; - - /*--- Viscous flux at the wall node (adjoint density & energy only) ---*/ - - Res_Visc_i[0] = - (Velocity[0] * Normal[0] * eta_xx + Velocity[1] * Normal[1] * eta_yy - + (Velocity[0] * Normal[1] + Velocity[1] * Normal[0]) * eta_xy - - (sq_vel - Pressure/(Density*Gamma_Minus_One)) * Sigma_5); - Res_Visc_i[nDim+1] = Sigma_5; - - /*--- Computation of the Jacobians at Point i---*/ - - if (implicit) { - - /*--- Compute closest normal neighbor ---*/ - - Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); - - /*--- Get coordinates of i & nearest normal and compute distance ---*/ - - Coord_i = geometry->node[iPoint]->GetCoord(); - Coord_j = geometry->node[Point_Normal]->GetCoord(); - dist_ij_2 = 0.0; - for (iDim = 0; iDim < nDim; iDim++) { - Edge_Vector[iDim] = Coord_j[iDim]-Coord_i[iDim]; - dist_ij_2 += Edge_Vector[iDim]*Edge_Vector[iDim]; - } - - dSigmaxx_phi1 = -FOUR3 * ViscDens * Edge_Vector[0]/dist_ij_2; - dSigmaxx_phi2 = TWO3 * ViscDens * Edge_Vector[1]/dist_ij_2; - dSigmayy_phi1 = TWO3 * ViscDens * Edge_Vector[0]/dist_ij_2; - dSigmayy_phi2 = -FOUR3 * ViscDens * Edge_Vector[1]/dist_ij_2; - dSigmaxy_phi1 = -ViscDens * Edge_Vector[1]/dist_ij_2; - dSigmaxy_phi2 = -ViscDens * Edge_Vector[0]/dist_ij_2; - - // dSigmaxx5_psi5 = -ViscDens * ( FOUR3*Velocity[0]*Edge_Vector[0] - TWO3*Velocity[1]*Edge_Vector[1] )/dist_ij_2; - // dSigmayy5_psi5 = -ViscDens * (- TWO3*Velocity[0]*Edge_Vector[0] + FOUR3*Velocity[1]*Edge_Vector[1] )/dist_ij_2; - // dSigmaxy5_psi5 = -ViscDens * ( Velocity[0]*Edge_Vector[1] + Velocity[1]*Edge_Vector[0] )/dist_ij_2; - dSigma5_psi5 = -XiDens * ( Edge_Vector[0]*Normal[0] + Edge_Vector[1]*Normal[1] )/dist_ij_2; - - Jacobian_ii[0][0] += 0.0; - Jacobian_ii[0][1] += -( Velocity[0]*Normal[0]*dSigmaxx_phi1 + Velocity[1]*Normal[1]*dSigmayy_phi1 - + (Velocity[0]*Normal[1] + Velocity[1]*Normal[0])*dSigmaxy_phi1 ); - Jacobian_ii[0][2] += -( Velocity[0]*Normal[0]*dSigmaxx_phi2 + Velocity[1]*Normal[1]*dSigmayy_phi2 - + (Velocity[0]*Normal[1] + Velocity[1]*Normal[0])*dSigmaxy_phi2 ); - Jacobian_ii[0][3] += (sq_vel - Pressure/(Density*Gamma_Minus_One)) * dSigma5_psi5; - - Jacobian_ii[3][0] += 0.0; - Jacobian_ii[3][1] += 0.0; - Jacobian_ii[3][2] += 0.0; - Jacobian_ii[3][3] += dSigma5_psi5; - - } - - - } else if (nDim == 3) { - - /*--- Compute the adjoint stress tensor ---*/ - Sigma_xx = ViscDens * (FOUR3 * GradPhi[0][0] - TWO3 * GradPhi[1][1] - TWO3 * GradPhi[2][2]); - Sigma_yy = ViscDens * (-TWO3 * GradPhi[0][0] + FOUR3 * GradPhi[1][1] - TWO3 * GradPhi[2][2]); - Sigma_zz = ViscDens * (-TWO3 * GradPhi[0][0] - TWO3 * GradPhi[1][1] + FOUR3 * GradPhi[2][2]); - Sigma_xy = ViscDens * (GradPhi[1][0] + GradPhi[0][1]); - Sigma_xz = ViscDens * (GradPhi[2][0] + GradPhi[0][2]); - Sigma_yz = ViscDens * (GradPhi[2][1] + GradPhi[1][2]); - Sigma_xx5 = ViscDens * ( FOUR3 * Velocity[0] * GradPsiE[0] - TWO3 * Velocity[1] * GradPsiE[1] - TWO3 * Velocity[2] * GradPsiE[2]); - Sigma_yy5 = ViscDens * (- TWO3 * Velocity[0] * GradPsiE[0] + FOUR3 * Velocity[1] * GradPsiE[1] - TWO3 * Velocity[2] * GradPsiE[2]); - Sigma_zz5 = ViscDens * (- TWO3 * Velocity[0] * GradPsiE[0] - TWO3 * Velocity[1] * GradPsiE[1] + FOUR3 * Velocity[2] * GradPsiE[2]); - Sigma_xy5 = ViscDens * (Velocity[0] * GradPsiE[1] + Velocity[1] * GradPsiE[0]); - Sigma_xz5 = ViscDens * (Velocity[0] * GradPsiE[2] + Velocity[2] * GradPsiE[0]); - Sigma_yz5 = ViscDens * (Velocity[1] * GradPsiE[2] + Velocity[2] * GradPsiE[1]); - Sigma_5 = XiDens * dPhiE_dn; - eta_xx = Sigma_xx + Sigma_xx5; eta_yy = Sigma_yy + Sigma_yy5; eta_zz = Sigma_zz + Sigma_zz5; - eta_xy = Sigma_xy + Sigma_xy5; eta_xz = Sigma_xz + Sigma_xz5; eta_yz = Sigma_yz + Sigma_yz5; - - /*--- Viscous flux at the wall node (adjoint density & energy only) ---*/ - - Res_Visc_i[0] = - (Velocity[0] * Normal[0] * eta_xx + Velocity[1] * Normal[1] * eta_yy + Velocity[2] * Normal[2] * eta_zz - + (Velocity[0] * Normal[1] + Velocity[1] * Normal[0]) * eta_xy - + (Velocity[0] * Normal[2] + Velocity[2] * Normal[0]) * eta_xz - + (Velocity[2] * Normal[1] + Velocity[1] * Normal[2]) * eta_yz - - (sq_vel - Pressure/(Density*Gamma_Minus_One)) * Sigma_5); - Res_Visc_i[nDim+1] = Sigma_5; - - /*--- Computation of the Jacobians at Point i---*/ - - if (implicit) { - - /*--- Compute closest normal neighbor ---*/ - - Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); - - /*--- Get coordinates of i & nearest normal and compute distance ---*/ - - Coord_i = geometry->node[iPoint]->GetCoord(); - Coord_j = geometry->node[Point_Normal]->GetCoord(); - dist_ij_2 = 0.0; - for (iDim = 0; iDim < nDim; iDim++) { - Edge_Vector[iDim] = Coord_j[iDim]-Coord_i[iDim]; - dist_ij_2 += Edge_Vector[iDim]*Edge_Vector[iDim]; - } - - dSigmaxx_phi1 = -FOUR3 * ViscDens * Edge_Vector[0]/dist_ij_2; - dSigmaxx_phi2 = TWO3 * ViscDens * Edge_Vector[1]/dist_ij_2; - dSigmaxx_phi3 = TWO3 * ViscDens * Edge_Vector[2]/dist_ij_2; - dSigmayy_phi1 = TWO3 * ViscDens * Edge_Vector[0]/dist_ij_2; - dSigmayy_phi2 = -FOUR3 * ViscDens * Edge_Vector[1]/dist_ij_2; - dSigmayy_phi3 = TWO3 * ViscDens * Edge_Vector[2]/dist_ij_2; - dSigmazz_phi1 = TWO3 * ViscDens * Edge_Vector[0]/dist_ij_2; - dSigmazz_phi2 = TWO3 * ViscDens * Edge_Vector[1]/dist_ij_2; - dSigmazz_phi3 = -FOUR3 * ViscDens * Edge_Vector[2]/dist_ij_2; - dSigmaxy_phi1 = -ViscDens * Edge_Vector[1]/dist_ij_2; - dSigmaxy_phi2 = -ViscDens * Edge_Vector[0]/dist_ij_2; - dSigmaxy_phi3 = 0; - dSigmaxz_phi1 = -ViscDens * Edge_Vector[2]/dist_ij_2; - dSigmaxz_phi2 = 0; - dSigmaxz_phi3 = -ViscDens * Edge_Vector[0]/dist_ij_2; - dSigmayz_phi1 = 0; - dSigmayz_phi2 = -ViscDens * Edge_Vector[2]/dist_ij_2; - dSigmayz_phi3 = -ViscDens * Edge_Vector[1]/dist_ij_2; - - // dSigmaxx5_psi5 = -ViscDens * ( FOUR3*Velocity[0]*Edge_Vector[0] - TWO3*Velocity[1]*Edge_Vector[1] - TWO3*Velocity[2]*Edge_Vector[2])/dist_ij_2; - // dSigmayy5_psi5 = -ViscDens * (- TWO3*Velocity[0]*Edge_Vector[0] + FOUR3*Velocity[1]*Edge_Vector[1] - TWO3*Velocity[2]*Edge_Vector[2])/dist_ij_2; - // dSigmazz5_psi5 = -ViscDens * (- TWO3*Velocity[0]*Edge_Vector[0] - TWO3*Velocity[1]*Edge_Vector[1] + FOUR3*Velocity[2]*Edge_Vector[2])/dist_ij_2; - // dSigmaxy5_psi5 = -ViscDens * ( Velocity[0]*Edge_Vector[1] + Velocity[1]*Edge_Vector[0] )/dist_ij_2; - // dSigmaxz5_psi5 = -ViscDens * ( Velocity[0]*Edge_Vector[2] + Velocity[2]*Edge_Vector[0] )/dist_ij_2; - // dSigmayz5_psi5 = -ViscDens * ( Velocity[1]*Edge_Vector[2] + Velocity[2]*Edge_Vector[1] )/dist_ij_2; - dSigma5_psi5 = -XiDens * ( Edge_Vector[0]*Normal[0] + Edge_Vector[1]*Normal[1] + Edge_Vector[2]*Normal[2] )/dist_ij_2; - - Jacobian_ii[0][0] += 0.0; - Jacobian_ii[0][1] += -( Velocity[0]*Normal[0]*dSigmaxx_phi1 + Velocity[1]*Normal[1]*dSigmayy_phi1 + Velocity[2]*Normal[2]*dSigmazz_phi1 - + (Velocity[0]*Normal[1] + Velocity[1]*Normal[0])*dSigmaxy_phi1 - + (Velocity[0]*Normal[2] + Velocity[2]*Normal[0])*dSigmaxz_phi1 - + (Velocity[2]*Normal[1] + Velocity[1]*Normal[2])*dSigmayz_phi1 ); - Jacobian_ii[0][2] += -( Velocity[0]*Normal[0]*dSigmaxx_phi2 + Velocity[1]*Normal[1]*dSigmayy_phi2 + Velocity[2]*Normal[2]*dSigmazz_phi2 - + (Velocity[0]*Normal[1] + Velocity[1]*Normal[0])*dSigmaxy_phi2 - + (Velocity[0]*Normal[2] + Velocity[2]*Normal[0])*dSigmaxz_phi2 - + (Velocity[2]*Normal[1] + Velocity[1]*Normal[2])*dSigmayz_phi2 ); - Jacobian_ii[0][3] += -( Velocity[0]*Normal[0]*dSigmaxx_phi3 + Velocity[1]*Normal[1]*dSigmayy_phi3 + Velocity[2]*Normal[2]*dSigmazz_phi3 - + (Velocity[0]*Normal[1] + Velocity[1]*Normal[0])*dSigmaxy_phi3 - + (Velocity[0]*Normal[2] + Velocity[2]*Normal[0])*dSigmaxz_phi3 - + (Velocity[2]*Normal[1] + Velocity[1]*Normal[2])*dSigmayz_phi3 ); - Jacobian_ii[0][4] += (sq_vel - Pressure/(Density*Gamma_Minus_One)) * dSigma5_psi5; - - Jacobian_ii[4][0] += 0.0; - Jacobian_ii[4][1] += 0.0; - Jacobian_ii[4][2] += 0.0; - Jacobian_ii[4][3] += 0.0; - Jacobian_ii[4][4] += dSigma5_psi5; - - } - } - } - - /*--- Convective contribution to the residual at the wall ---*/ - - LinSysRes.SubtractBlock(iPoint, Res_Conv_i); - - /*--- Viscous contribution to the residual at the wall ---*/ - - LinSysRes.SubtractBlock(iPoint, Res_Visc_i); - - /*--- Enforce the no-slip boundary condition in a strong way by - modifying the velocity-rows of the Jacobian (1 on the diagonal). ---*/ - - if (implicit) { - Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_ii); - for (iVar = 1; iVar <= nDim; iVar++) { - total_index = iPoint*nVar+iVar; - Jacobian.DeleteValsRowi(total_index); - } - } - - } - - } - - for (iDim = 0; iDim < nDim; iDim++) - delete [] Tau[iDim]; - delete [] Tau; - delete [] Psi; - delete [] Velocity; - delete [] Normal; - delete [] Edge_Vector; - delete [] GradPsiE; - for (iDim = 0; iDim < nDim; iDim++) - delete [] GradPhi[iDim]; - delete [] GradPhi; - -} - - -void CAdjNSSolver::BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - - unsigned long iVertex, iPoint, total_index; - unsigned short iDim, iVar, jVar, jDim; - su2double *d, q, *U, dVisc_T, rho, pressure, div_phi, - force_stress, Sigma_5, **PsiVar_Grad, phi[3] = {0.0,0.0,0.0}; - su2double phis1, phis2, sq_vel, ProjVel, Enthalpy, *GridVel, phi_u, d_n; - su2double Energy, ViscDens, XiDens, Density, SoundSpeed, Pressure, dPhiE_dn, Laminar_Viscosity, Eddy_Viscosity, - Sigma_xx, Sigma_yy, Sigma_zz, Sigma_xy, Sigma_xz, Sigma_yz, - Sigma_xx5, Sigma_yy5, Sigma_zz5, Sigma_xy5, Sigma_xz5, - Sigma_yz5, eta_xx, eta_yy, eta_zz, eta_xy, eta_xz, eta_yz; - su2double kGTdotn=0.0, Area=0.0, Xi=0.0; - - su2double *Psi = new su2double[nVar]; - su2double **Tau = new su2double* [nDim]; - for (iDim = 0; iDim < nDim; iDim++) - Tau[iDim] = new su2double [nDim]; - su2double *Velocity = new su2double[nDim]; - su2double *Normal = new su2double[nDim]; - - su2double **GradPhi = new su2double* [nDim]; - for (iDim = 0; iDim < nDim; iDim++) - GradPhi[iDim] = new su2double [nDim]; - su2double *GradPsiE = new su2double [nDim]; - su2double *GradT;// = new su2double[nDim]; - su2double *GradP; - su2double *GradDens; - su2double *dPoRho2 = new su2double[nDim]; - - bool implicit = (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); - bool grid_movement = config->GetGrid_Movement(); - bool heat_flux_obj; - - su2double Prandtl_Lam = config->GetPrandtl_Lam(); - su2double Prandtl_Turb = config->GetPrandtl_Turb(); - su2double Gas_Constant = config->GetGas_ConstantND(); - su2double Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; - su2double Thermal_Conductivity; - su2double invrho3; - su2double Volume; - su2double mu2; - su2double gpsiAv2; - su2double gpsi5n; - - string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - string Monitoring_Tag; - unsigned short jMarker, iMarker_Monitoring=0; - su2double Weight_ObjFunc = 1.0; - - /*--- Identify marker monitoring index ---*/ - for (jMarker = 0; jMarker < config->GetnMarker_Monitoring(); jMarker++) { - Monitoring_Tag = config->GetMarker_Monitoring_TagBound(jMarker); - if (Monitoring_Tag==Marker_Tag) - iMarker_Monitoring = jMarker; - } - /*-- Get objective weight --*/ - Weight_ObjFunc = config->GetWeight_ObjFunc(iMarker_Monitoring); - heat_flux_obj = ((config->GetKind_ObjFunc(iMarker_Monitoring) == TOTAL_HEATFLUX) || - (config->GetKind_ObjFunc(iMarker_Monitoring) == MAXIMUM_HEATFLUX) || - (config->GetKind_ObjFunc(iMarker_Monitoring) == INVERSE_DESIGN_HEATFLUX)); - - for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - - iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - - if (geometry->node[iPoint]->GetDomain()) { - - /*--- Initialize the convective & viscous residuals to zero ---*/ - for (iVar = 0; iVar < nVar; iVar++) { - Res_Conv_i[iVar] = 0.0; - Res_Visc_i[iVar] = 0.0; - if (implicit) { - for (jVar = 0; jVar < nVar; jVar ++) - Jacobian_ii[iVar][jVar] = 0.0; - } - } - - /*--- Retrieve adjoint solution at the wall boundary node ---*/ - for (iVar = 0; iVar < nVar; iVar++) - Psi[iVar] = nodes->GetSolution(iPoint,iVar); - - /*--- Normal vector for this vertex (negate for outward convention) ---*/ - geometry->vertex[val_marker][iVertex]->GetNormal(Normal); - Volume = geometry->node[iPoint]->GetVolume(); - for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; - - /*--- Get the force projection vector (based on the objective function) ---*/ - d = nodes->GetForceProj_Vector(iPoint); - - /*--- Adjustments to strong boundary condition for dynamic meshes ---*/ - if ( grid_movement) { - GridVel = geometry->node[iPoint]->GetGridVel(); - for (iDim = 0; iDim < nDim; iDim++) { - phi[iDim] = d[iDim] - Psi[nVar-1]*GridVel[iDim]; - } - } else { - for (iDim = 0; iDim < nDim; iDim++) { - phi[iDim] = d[iDim]; - } - } - - /*--- Strong BC imposition for the adjoint velocity equations ---*/ - for (iDim = 0; iDim < nDim; iDim++) - LinSysRes.SetBlock_Zero(iPoint, iDim+1); - nodes->SetVel_ResTruncError_Zero(iPoint); - for (iDim = 0; iDim < nDim; iDim++) - nodes->SetSolution_Old(iPoint,iDim+1, phi[iDim]); - if (implicit) { - for (iVar = 1; iVar <= nDim; iVar++) { - total_index = iPoint*nVar+iVar; - Jacobian.DeleteValsRowi(total_index); - } - } - - /*--- Get transport coefficient information ---*/ - Laminar_Viscosity = solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); - Eddy_Viscosity = solver_container[FLOW_SOL]->GetNodes()->GetEddyViscosity(iPoint); - Thermal_Conductivity = Cp * ( Laminar_Viscosity/Prandtl_Lam - +Eddy_Viscosity/Prandtl_Turb); - -// GradV = solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint); - - /*--- Calculate Dirichlet condition for energy equation ---*/ - if (!heat_flux_obj) { - q = 0.0; - } - else { - - Area = 0.0; - for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; - Area = sqrt(Area); - - /*--- Temperature gradient term ---*/ - GradT = solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint)[0]; - kGTdotn = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - kGTdotn += Cp * Laminar_Viscosity/Prandtl_Lam*GradT[iDim]*Normal[iDim]/Area; - // Cp * Viscosity/Prandtl_Lam matches term used in solver_direct_mean - /*--- constant term to multiply max heat flux objective ---*/ - Xi = solver_container[FLOW_SOL]->GetTotal_HeatFlux(); // versions for max heat flux - Xi = pow(Xi, 1.0/pnorm-1.0)/pnorm; - - /*--- Boundary condition value ---*/ - q = Xi * pnorm * pow(kGTdotn, pnorm-1.0)*Area*Weight_ObjFunc; - } - - /*--- Strong BC enforcement of the energy equation ---*/ - LinSysRes.SetBlock_Zero(iPoint, nVar-1); - nodes->SetEnergy_ResTruncError_Zero(iPoint); - nodes->SetSolution_Old(iPoint,nDim+1, q); - if (implicit) { - iVar = nDim+1; - total_index = iPoint*nVar+iVar; - Jacobian.DeleteValsRowi(total_index); - } - - /*--- Additional contributions to adjoint density (weak imposition) ---*/ - - /*--- Acquire gradient information ---*/ - PsiVar_Grad = nodes->GetGradient(iPoint); - GradP = solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint)[nVar-1]; - GradDens = solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint)[nVar]; - - /*--- Acqure flow information ---*/ - rho = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); - pressure = solver_container[FLOW_SOL]->GetNodes()->GetPressure(iPoint); - invrho3 = (1.0/rho)*(1.0/rho)*(1.0/rho); - - /*--- Calculate supporting quantities ---*/ - mu2 = Thermal_Conductivity/Cp; - gpsiAv2 = 0.0; - gpsi5n = 0.0; - for (iDim = 0; iDim < nDim; iDim++) { - dPoRho2[iDim] = (GradP[iDim]*rho - 2.0*GradDens[iDim]*pressure)*invrho3; - gpsiAv2 += -mu2*Gamma/Gamma_Minus_One * PsiVar_Grad[nVar-1][iDim]*dPoRho2[iDim]; - gpsi5n += PsiVar_Grad[nVar-1][iDim]*Normal[iDim]; - } - - /*--- Apply first order term to boundary ---*/ - Res_Conv_i[0] = gpsiAv2*Volume; - - /*--- Apply second order term to boundary ---*/ - Res_Visc_i[0] = -mu2*Gamma/(rho*Gamma_Minus_One)*(pressure/rho)*gpsi5n; - - /*--- Components of the effective and adjoint stress tensors ---*/ - PsiVar_Grad = nodes->GetGradient(iPoint); - div_phi = 0; - for (iDim = 0; iDim < nDim; iDim++) { - div_phi += PsiVar_Grad[iDim+1][iDim]; - for (jDim = 0; jDim < nDim; jDim++) - Tau[iDim][jDim] = (PsiVar_Grad[iDim+1][jDim]+PsiVar_Grad[jDim+1][iDim]); - } - for (iDim = 0; iDim < nDim; iDim++) - Tau[iDim][iDim] -= TWO3*div_phi; - - /*--- force_stress = n_i \Tau_{ij} d_j ---*/ - force_stress = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - for (jDim = 0; jDim < nDim; jDim++) - force_stress += Normal[iDim]*Tau[iDim][jDim]*d[jDim]; - - /*--- \partial \mu_dyn \partial T ---*/ - // mu_dyn = solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); - // Temp = solver_container[FLOW_SOL]->GetNodes()->GetTemperature(iPoint); - dVisc_T = 0.0; // dVisc_T = mu_dyn*(Temp+3.0*mu2)/(2.0*Temp*(Temp+mu2)); - - /*--- \Sigma_5 Check Area computation for Res_Conv[0] ---*/ - Sigma_5 = (Gamma/Cp)*dVisc_T*force_stress; - - /*--- Imposition of residuals ---*/ - rho = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); - pressure = solver_container[FLOW_SOL]->GetNodes()->GetPressure(iPoint); - Res_Conv_i[0] = pressure*Sigma_5/(Gamma_Minus_One*rho*rho); - - /*--- Flux contribution and Jacobian contributions for moving - walls. Note that these are only for the adjoint density and - adjoint energy equations (the adjoint vel. uses a strong BC). ---*/ - if (grid_movement) { - - /*--- Get the appropriate grid velocity at this node ---*/ - GridVel = geometry->node[iPoint]->GetGridVel(); - - /*--- Get the enthalpy from the direct solution ---*/ - Enthalpy = solver_container[FLOW_SOL]->GetNodes()->GetEnthalpy(iPoint); - - /*--- Compute projections, velocity squared divided by two, and - other inner products. Note that we are imposing v = u_wall from - the direct problem and that phi = d - \psi_5 * v ---*/ - ProjVel = 0.0; sq_vel = 0.0; phi_u = 0.0; d_n = 0.0; - phis1 = 0.0; phis2 = Psi[0] + Enthalpy * Psi[nVar-1]; - for (iDim = 0; iDim < nDim; iDim++) { - ProjVel += GridVel[iDim]*Normal[iDim]; - sq_vel += 0.5*GridVel[iDim]*GridVel[iDim]; - phis1 += Normal[iDim]*phi[iDim]; - phis2 += GridVel[iDim]*phi[iDim]; - phi_u += GridVel[iDim]*phi[iDim]; - d_n += d[iDim]*Normal[iDim]; - } - // phis1 += ProjVel * Psi[nVar-1]; - - /*--- Convective flux at the wall node (adjoint density & energy only) ---*/ - - /*--- Version 1 (full) ---*/ - //Res_Conv_i[0] = ProjVel * Psi[0] - phis2 * ProjVel + phis1 * Gamma_Minus_One * sq_vel - ProjVel*Psi[0]; - //Res_Conv_i[nVar-1] = ProjVel * Psi[nVar-1] + phis1 * Gamma_Minus_One - ProjVel*Psi[nVar-1]; - - /*--- Simplified version ---*/ - Res_Conv_i[0] = -(Psi[0] + phi_u + Psi[nVar-1]*Enthalpy)*ProjVel + d_n*Gamma_Minus_One*sq_vel; - - /*--- TO DO: Implicit contributions for convective part ---*/ - - - /*--- Viscous flux contributions at the wall node ---*/ - U = solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint); - Laminar_Viscosity = solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); - Eddy_Viscosity = solver_container[FLOW_SOL]->GetNodes()->GetEddyViscosity(iPoint); // Should be zero at the wall - Density = U[0]; - for (iDim = 0; iDim < nDim; iDim++) { - Velocity[iDim] = GridVel[iDim]; - } - Energy = U[nDim+1] / Density; - SoundSpeed = sqrt(Gamma*Gamma_Minus_One*(Energy-sq_vel)); - Pressure = (SoundSpeed * SoundSpeed * Density) / Gamma; - ViscDens = (Laminar_Viscosity + Eddy_Viscosity) / Density; - XiDens = Gamma * (Laminar_Viscosity/Prandtl_Lam + Eddy_Viscosity/Prandtl_Turb) / Density; - - /*--- Average of the derivatives of the adjoint variables ---*/ - PsiVar_Grad = nodes->GetGradient(iPoint); - - for (iDim = 0; iDim < nDim; iDim++) { - GradPsiE[iDim] = PsiVar_Grad[nVar-1][iDim]; - for (jDim = 0; jDim < nDim; jDim++) - GradPhi[iDim][jDim] = PsiVar_Grad[iDim+1][jDim]; - } - - /*--- Impose dPhiE_dn = 0 (adiabatic walls with frozen viscosity). Note - that this is where a different adjoint boundary condition for temperature - could be imposed. ---*/ - dPhiE_dn = 0.0; - - if (nDim ==2) { - - /*--- Compute the adjoint stress tensor ---*/ - Sigma_xx = ViscDens * (FOUR3 * GradPhi[0][0] - TWO3 * GradPhi[1][1]); - Sigma_yy = ViscDens * (-TWO3 * GradPhi[0][0] + FOUR3 * GradPhi[1][1]); - Sigma_xy = ViscDens * (GradPhi[1][0] + GradPhi[0][1]); - Sigma_xx5 = ViscDens * ( FOUR3 * Velocity[0] * GradPsiE[0] - TWO3 * Velocity[1] * GradPsiE[1]); - Sigma_yy5 = ViscDens * (- TWO3 * Velocity[0] * GradPsiE[0] + FOUR3 * Velocity[1] * GradPsiE[1]); - Sigma_xy5 = ViscDens * (Velocity[0] * GradPsiE[1] + Velocity[1] * GradPsiE[0]); - Sigma_5 = XiDens * dPhiE_dn; - eta_xx = Sigma_xx + Sigma_xx5; - eta_yy = Sigma_yy + Sigma_yy5; - eta_xy = Sigma_xy + Sigma_xy5; - - /*--- Viscous flux at the wall node (adjoint density & energy only) ---*/ - Res_Visc_i[0] = - (Velocity[0] * Normal[0] * eta_xx + Velocity[1] * Normal[1] * eta_yy - + (Velocity[0] * Normal[1] + Velocity[1] * Normal[0]) * eta_xy - - (sq_vel - Pressure/(Density*Gamma_Minus_One)) * Sigma_5); - Res_Visc_i[1] = 0.0; - Res_Visc_i[2] = 0.0; - - } else if (nDim == 3) { - - /*--- Compute the adjoint stress tensor ---*/ - Sigma_xx = ViscDens * (FOUR3 * GradPhi[0][0] - TWO3 * GradPhi[1][1] - TWO3 * GradPhi[2][2]); - Sigma_yy = ViscDens * (-TWO3 * GradPhi[0][0] + FOUR3 * GradPhi[1][1] - TWO3 * GradPhi[2][2]); - Sigma_zz = ViscDens * (-TWO3 * GradPhi[0][0] - TWO3 * GradPhi[1][1] + FOUR3 * GradPhi[2][2]); - Sigma_xy = ViscDens * (GradPhi[1][0] + GradPhi[0][1]); - Sigma_xz = ViscDens * (GradPhi[2][0] + GradPhi[0][2]); - Sigma_yz = ViscDens * (GradPhi[2][1] + GradPhi[1][2]); - Sigma_xx5 = ViscDens * ( FOUR3 * Velocity[0] * GradPsiE[0] - TWO3 * Velocity[1] * GradPsiE[1] - TWO3 * Velocity[2] * GradPsiE[2]); - Sigma_yy5 = ViscDens * (- TWO3 * Velocity[0] * GradPsiE[0] + FOUR3 * Velocity[1] * GradPsiE[1] - TWO3 * Velocity[2] * GradPsiE[2]); - Sigma_zz5 = ViscDens * (- TWO3 * Velocity[0] * GradPsiE[0] - TWO3 * Velocity[1] * GradPsiE[1] + FOUR3 * Velocity[2] * GradPsiE[2]); - Sigma_xy5 = ViscDens * (Velocity[0] * GradPsiE[1] + Velocity[1] * GradPsiE[0]); - Sigma_xz5 = ViscDens * (Velocity[0] * GradPsiE[2] + Velocity[2] * GradPsiE[0]); - Sigma_yz5 = ViscDens * (Velocity[1] * GradPsiE[2] + Velocity[2] * GradPsiE[1]); - Sigma_5 = XiDens * dPhiE_dn; - eta_xx = Sigma_xx + Sigma_xx5; eta_yy = Sigma_yy + Sigma_yy5; eta_zz = Sigma_zz + Sigma_zz5; - eta_xy = Sigma_xy + Sigma_xy5; eta_xz = Sigma_xz + Sigma_xz5; eta_yz = Sigma_yz + Sigma_yz5; - - /*--- Viscous flux at the wall node (adjoint density & energy only) ---*/ - Res_Visc_i[0] = - (Velocity[0] * Normal[0] * eta_xx + Velocity[1] * Normal[1] * eta_yy + Velocity[2] * Normal[2] * eta_zz - + (Velocity[0] * Normal[1] + Velocity[1] * Normal[0]) * eta_xy - + (Velocity[0] * Normal[2] + Velocity[2] * Normal[0]) * eta_xz - + (Velocity[2] * Normal[1] + Velocity[1] * Normal[2]) * eta_yz - - (sq_vel - Pressure/(Density*Gamma_Minus_One)) * Sigma_5); - Res_Visc_i[1] = 0.0; - Res_Visc_i[2] = 0.0; - Res_Visc_i[3] = 0.0; - } - } - - /*--- Update convective and viscous residuals ---*/ - LinSysRes.AddBlock(iPoint, Res_Conv_i); - LinSysRes.SubtractBlock(iPoint, Res_Visc_i); - if (implicit) { - Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_ii); - } - - } - - } - - for (iDim = 0; iDim < nDim; iDim++) - delete [] Tau[iDim]; - delete [] Tau; - delete [] Psi; - delete [] Velocity; - delete [] Normal; - delete [] GradPsiE; - for (iDim = 0; iDim < nDim; iDim++) - delete [] GradPhi[iDim]; - delete [] GradPhi; - delete [] dPoRho2; -} - +} \ No newline at end of file diff --git a/SU2_CFD/src/solvers/CAdjNSSolver.cpp b/SU2_CFD/src/solvers/CAdjNSSolver.cpp new file mode 100644 index 000000000000..ec4ffd182bd4 --- /dev/null +++ b/SU2_CFD/src/solvers/CAdjNSSolver.cpp @@ -0,0 +1,1911 @@ +/*! + * \file CAdjNSSolver.cpp + * \brief Main subroutines for solving Navier-Stokes adjoint problems. + * \author F. Palacios, T. Economon, H. Kline + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + + +#include "../../include/solvers/CAdjNSSolver.hpp" +#include "../../include/variables/CAdjNSVariable.hpp" + +CAdjNSSolver::CAdjNSSolver(void) : CAdjEulerSolver() { } + +CAdjNSSolver::CAdjNSSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh) : CAdjEulerSolver() { + unsigned long iPoint, iVertex; + string text_line, mesh_filename; + unsigned short iDim, iVar, iMarker, nLineLets; + ifstream restart_file; + string filename, AdjExt; + + su2double RefArea = config->GetRefArea(); + su2double RefDensity = config->GetDensity_FreeStreamND(); + su2double Gas_Constant = config->GetGas_ConstantND(); + su2double Mach_Motion = config->GetMach_Motion(); + su2double Area=0.0, *Normal = NULL, myArea_Monitored; + su2double RefVel2, Mach2Vel, Weight_ObjFunc, factor; + su2double *Velocity_Inf; + + string Marker_Tag, Monitoring_Tag; + unsigned short iMarker_Monitoring, jMarker, ObjFunc; + bool grid_movement = config->GetGrid_Movement(); + bool restart = config->GetRestart(); + + /*--- Norm heat flux objective test ---*/ + pnorm = 1.0; + if (config->GetKind_ObjFunc()==MAXIMUM_HEATFLUX) + pnorm = 8.0; // Matches MaxNorm defined in solver_direct_mean. + + /*--- Set the gamma value ---*/ + + Gamma = config->GetGamma(); + Gamma_Minus_One = Gamma - 1.0; + + /*--- Define geometry constants in the solver structure ---*/ + + nDim = geometry->GetnDim(); + nMarker = config->GetnMarker_All(); + nPoint = geometry->GetnPoint(); + nPointDomain = geometry->GetnPointDomain(); + + nVar = nDim + 2; + + /*--- Initialize nVarGrad for deallocation ---*/ + + nVarGrad = nVar; + + /*--- Define some auxiliary arrays related to the residual ---*/ + + Point_Max = new unsigned long[nVar]; for (iVar = 0; iVar < nVar; iVar++) Point_Max[iVar] = 0; + Point_Max_Coord = new su2double*[nVar]; + for (iVar = 0; iVar < nVar; iVar++) { + Point_Max_Coord[iVar] = new su2double[nDim]; + for (iDim = 0; iDim < nDim; iDim++) Point_Max_Coord[iVar][iDim] = 0.0; + } + Residual = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = 0.0; + Residual_RMS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_RMS[iVar] = 0.0; + Residual_Max = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_Max[iVar] = 0.0; + Residual_i = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_i[iVar] = 0.0; + Residual_j = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_j[iVar] = 0.0; + Res_Conv_i = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Conv_i[iVar] = 0.0; + Res_Visc_i = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Visc_i[iVar] = 0.0; + Res_Conv_j = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Conv_j[iVar] = 0.0; + Res_Visc_j = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Visc_j[iVar] = 0.0; + + /*--- Define some auxiliary arrays related to the solution ---*/ + + Solution = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution[iVar] = 0.0; + Solution_i = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution_i[iVar] = 0.0; + Solution_j = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution_j[iVar] = 0.0; + + /*--- Define some auxiliary arrays related to the flow solution ---*/ + + FlowPrimVar_i = new su2double[nDim+7]; for (iVar = 0; iVar < nDim+7; iVar++) FlowPrimVar_i[iVar] = 0.0; + FlowPrimVar_j = new su2double[nDim+7]; for (iVar = 0; iVar < nDim+7; iVar++) FlowPrimVar_j[iVar] = 0.0; + + /*--- Define some auxiliary vectors related to the geometry ---*/ + + Vector = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = 0.0; + Vector_i = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector_i[iDim] = 0.0; + Vector_j = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector_j[iDim] = 0.0; + + /*--- Point to point Jacobians. These are always defined because + they are also used for sensitivity calculations. ---*/ + + Jacobian_i = new su2double* [nVar]; + Jacobian_j = new su2double* [nVar]; + for (iVar = 0; iVar < nVar; iVar++) { + Jacobian_i[iVar] = new su2double [nVar]; + Jacobian_j[iVar] = new su2double [nVar]; + } + + /*--- Solution and residual vectors ---*/ + + LinSysSol.Initialize(nPoint, nPointDomain, nVar, 0.0); + LinSysRes.Initialize(nPoint, nPointDomain, nVar, 0.0); + + /*--- Jacobians and vector structures for implicit computations ---*/ + + if (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT) { + Jacobian_ii = new su2double*[nVar]; + Jacobian_ij = new su2double*[nVar]; + Jacobian_ji = new su2double*[nVar]; + Jacobian_jj = new su2double*[nVar]; + for (iVar = 0; iVar < nVar; iVar++) { + Jacobian_ii[iVar] = new su2double[nVar]; + Jacobian_ij[iVar] = new su2double[nVar]; + Jacobian_ji[iVar] = new su2double[nVar]; + Jacobian_jj[iVar] = new su2double[nVar]; + } + if (rank == MASTER_NODE) + cout << "Initialize Jacobian structure (Adjoint N-S). MG level: " << iMesh <<"." << endl; + Jacobian.Initialize(nPoint, nPointDomain, nVar, nVar, true, geometry, config); + + if (config->GetKind_Linear_Solver_Prec() == LINELET) { + nLineLets = Jacobian.BuildLineletPreconditioner(geometry, config); + if (rank == MASTER_NODE) cout << "Compute linelet structure. " << nLineLets << " elements in each line (average)." << endl; + } + + } else { + if (rank == MASTER_NODE) + cout << "Explicit scheme. No Jacobian structure (Adjoint N-S). MG level: " << iMesh <<"." << endl; + } + + /*--- Array structures for computation of gradients by least squares ---*/ + if (config->GetLeastSquaresRequired()) { + /*--- S matrix := inv(R)*traspose(inv(R)) ---*/ + Smatrix = new su2double* [nDim]; + for (iDim = 0; iDim < nDim; iDim++) + Smatrix[iDim] = new su2double [nDim]; + /*--- c vector := transpose(WA)*(Wb) ---*/ + Cvector = new su2double* [nVar]; + for (iVar = 0; iVar < nVar; iVar++) + Cvector[iVar] = new su2double [nDim]; + } + + /*--- Sensitivity definition and coefficient on all markers ---*/ + CSensitivity = new su2double* [nMarker]; + for (iMarker=0; iMarkernVertex[iMarker]]; + } + + /*--- Store the value of the characteristic primitive variables at the boundaries ---*/ + + DonorAdjVar = new su2double** [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + DonorAdjVar[iMarker] = new su2double* [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + DonorAdjVar[iMarker][iVertex] = new su2double [nVar]; + for (iVar = 0; iVar < nVar; iVar++) { + DonorAdjVar[iMarker][iVertex][iVar] = 0.0; + } + } + } + + /*--- Store the value of the characteristic primitive variables at the boundaries ---*/ + + DonorGlobalIndex = new unsigned long* [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + DonorGlobalIndex[iMarker] = new unsigned long [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + DonorGlobalIndex[iMarker][iVertex] = 0; + } + } + + Sens_Geo = new su2double[nMarker]; + Sens_Mach = new su2double[nMarker]; + Sens_AoA = new su2double[nMarker]; + Sens_Press = new su2double[nMarker]; + Sens_Temp = new su2double[nMarker]; + Sens_BPress = new su2double[nMarker]; + + /*--- Initialize sensitivities to zero ---*/ + for (iMarker = 0; iMarker < nMarker; iMarker++) { + Sens_Geo[iMarker] = 0.0; + Sens_Mach[iMarker] = 0.0; + Sens_AoA[iMarker] = 0.0; + Sens_Press[iMarker] = 0.0; + Sens_Temp[iMarker] = 0.0; + Sens_BPress[iMarker] = 0.0; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) + CSensitivity[iMarker][iVertex] = 0.0; + } + + /*--- Initialize the adjoint variables to zero (infinity state) ---*/ + PsiRho_Inf = 0.0; + if ((config->GetKind_ObjFunc() == TOTAL_HEATFLUX) || + (config->GetKind_ObjFunc() == MAXIMUM_HEATFLUX) || + (config->GetKind_ObjFunc() == INVERSE_DESIGN_HEATFLUX)) + PsiE_Inf = 1.0; + else + PsiE_Inf = 0.0; + Phi_Inf = new su2double [nDim]; + Phi_Inf[0] = 0.0; Phi_Inf[1] = 0.0; + if (nDim == 3) Phi_Inf[2] = 0.0; + + /*--- Initialize the solution to the far-field state everywhere. ---*/ + + nodes = new CAdjNSVariable(PsiRho_Inf, Phi_Inf, PsiE_Inf, nPoint, nDim, nVar, config); + SetBaseClassPointerToNodes(); + + /*--- Read the restart metadata. ---*/ + + if (restart && (iMesh == MESH_0)) { + mesh_filename = config->GetSolution_AdjFileName(); + filename = config->GetObjFunc_Extension(mesh_filename); +// Read_SU2_Restart_Metadata(geometry, config, true, filename); + } + + /*--- Calculate area monitored for area-averaged-outflow-quantity-based objectives ---*/ + myArea_Monitored = 0.0; + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { + if (config->GetKind_ObjFunc(iMarker_Monitoring)==SURFACE_TOTAL_PRESSURE || + config->GetKind_ObjFunc(iMarker_Monitoring)==SURFACE_STATIC_PRESSURE) { + + Monitoring_Tag = config->GetMarker_Monitoring_TagBound(iMarker_Monitoring); + /*-- Find the marker index ---*/ + iMarker = 0; + for (jMarker= 0; jMarker < config->GetnMarker_All(); jMarker++) { + Marker_Tag = config->GetMarker_All_TagBound(jMarker); + if (Marker_Tag == Monitoring_Tag) { + iMarker = jMarker; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + if (geometry->node[iPoint]->GetDomain()) { + Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); + Area = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + Area += Normal[iDim]*Normal[iDim]; + myArea_Monitored += sqrt (Area); + } + } + break; + } + } + } + } + + + #ifdef HAVE_MPI + Area_Monitored = 0.0; + SU2_MPI::Allreduce(&myArea_Monitored, &Area_Monitored, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + #else + Area_Monitored = myArea_Monitored; + #endif + + if (config->GetnObj() > 1 && iMesh == MESH_0) { + if (grid_movement) { + Mach2Vel = sqrt(Gamma*Gas_Constant*config->GetTemperature_FreeStreamND()); + RefVel2 = (Mach_Motion*Mach2Vel)*(Mach_Motion*Mach2Vel); + } + else { + Velocity_Inf = config->GetVelocity_FreeStreamND(); + RefVel2 = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + RefVel2 += Velocity_Inf[iDim]*Velocity_Inf[iDim]; + } + + /*--- Objective scaling: a factor must be applied to certain objectives ---*/ + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { + Weight_ObjFunc = config->GetWeight_ObjFunc(iMarker_Monitoring); + + factor = 1.0/(0.5*RefDensity*RefArea*RefVel2); + + ObjFunc = config->GetKind_ObjFunc(iMarker_Monitoring); + if ((ObjFunc == INVERSE_DESIGN_HEATFLUX) || + (ObjFunc == TOTAL_HEATFLUX) || (ObjFunc == MAXIMUM_HEATFLUX) || + (ObjFunc == SURFACE_MASSFLOW) ) factor = 1.0; + + if ((ObjFunc == SURFACE_TOTAL_PRESSURE) || (ObjFunc == SURFACE_STATIC_PRESSURE)) + factor = 1.0/Area_Monitored; + + Weight_ObjFunc = Weight_ObjFunc*factor; + config->SetWeight_ObjFunc(iMarker_Monitoring, Weight_ObjFunc); + + } + } + + /*--- MPI solution ---*/ + + InitiateComms(geometry, config, SOLUTION); + CompleteComms(geometry, config, SOLUTION); + +} + +CAdjNSSolver::~CAdjNSSolver(void) { + +} + + +void CAdjNSSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, + unsigned short iMesh, unsigned long Iteration) { + + /*--- Use the flow solution to update the time step + * The time step depends on the characteristic velocity, which is the same + * for the adjoint and flow solutions, albeit in the opposite direction. ---*/ + solver_container[FLOW_SOL]->SetTime_Step(geometry, solver_container, config, iMesh, Iteration); + +} + +void CAdjNSSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output) { + + unsigned long iPoint, nonPhysicalPoints = 0; + su2double SharpEdge_Distance; + bool physical = true; + + /*--- Retrieve information about the spatial and temporal integration for the + adjoint equations (note that the flow problem may use different methods). ---*/ + + bool implicit = (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); + bool limiter = (config->GetKind_SlopeLimit_AdjFlow() != NO_LIMITER); + bool center_jst = (config->GetKind_Centered_AdjFlow() == JST); + bool fixed_cl = config->GetFixed_CL_Mode(); + bool eval_dof_dcx = config->GetEval_dOF_dCX(); + + /*--- Update the objective function coefficient to guarantee zero gradient. ---*/ + + if (fixed_cl && eval_dof_dcx) { SetFarfield_AoA(geometry, solver_container, config, iMesh, Output); } + + /*--- Residual initialization ---*/ + + for (iPoint = 0; iPoint < nPoint; iPoint ++) { + + /*--- Get the distance form a sharp edge ---*/ + + SharpEdge_Distance = geometry->node[iPoint]->GetSharpEdge_Distance(); + + /*--- Set the primitive variables compressible + adjoint variables ---*/ + + physical = nodes->SetPrimVar(iPoint,SharpEdge_Distance, false, config); + + /* Check for non-realizable states for reporting. */ + + if (!physical) nonPhysicalPoints++; + + /*--- Initialize the convective residual vector ---*/ + + if (!Output) LinSysRes.SetBlock_Zero(iPoint); + + } + + /*--- Compute gradients adj for solution reconstruction and viscous term ---*/ + + if (config->GetReconstructionGradientRequired()) { + if (config->GetKind_Gradient_Method_Recon() == GREEN_GAUSS) + SetSolution_Gradient_GG(geometry, config, true); + if (config->GetKind_Gradient_Method_Recon() == LEAST_SQUARES) + SetSolution_Gradient_LS(geometry, config, true); + if (config->GetKind_Gradient_Method_Recon() == WEIGHTED_LEAST_SQUARES) + SetSolution_Gradient_LS(geometry, config, true); + } + if (config->GetKind_Gradient_Method() == GREEN_GAUSS) SetSolution_Gradient_GG(geometry, config); + if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) SetSolution_Gradient_LS(geometry, config); + + /*--- Limiter computation (upwind reconstruction) ---*/ + + if (limiter && !Output) SetSolution_Limiter(geometry, config); + + /*--- Compute gradients adj for viscous term coupling ---*/ + + if ((config->GetKind_Solver() == ADJ_RANS) && (!config->GetFrozen_Visc_Cont())) { + if (config->GetKind_Gradient_Method() == GREEN_GAUSS) solver_container[ADJTURB_SOL]->SetSolution_Gradient_GG(geometry, config); + if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) solver_container[ADJTURB_SOL]->SetSolution_Gradient_LS(geometry, config); + } + + /*--- Artificial dissipation for centered schemes ---*/ + + if (center_jst && (iMesh == MESH_0)) { + SetCentered_Dissipation_Sensor(geometry, config); + SetUndivided_Laplacian(geometry, config); + } + + /*--- Initialize the Jacobian for implicit integration ---*/ + + if (implicit) Jacobian.SetValZero(); + + /*--- Error message ---*/ + + if (config->GetComm_Level() == COMM_FULL) { +#ifdef HAVE_MPI + unsigned long MyErrorCounter = nonPhysicalPoints; nonPhysicalPoints = 0; + SU2_MPI::Allreduce(&MyErrorCounter, &nonPhysicalPoints, 1, MPI_UNSIGNED_LONG, MPI_SUM, MPI_COMM_WORLD); +#endif + if (iMesh == MESH_0) config->SetNonphysical_Points(nonPhysicalPoints); + } + +} + +void CAdjNSSolver::Viscous_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, + CConfig *config, unsigned short iMesh, unsigned short iRKStep) { + unsigned long iPoint, jPoint, iEdge; + + bool implicit = (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); + + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { + + /*--- Points in edge, coordinates and normal vector---*/ + + iPoint = geometry->edge[iEdge]->GetNode(0); + jPoint = geometry->edge[iEdge]->GetNode(1); + + numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[jPoint]->GetCoord()); + numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); + + /*--- Primitive variables w/o reconstruction and adjoint variables w/o reconstruction---*/ + + numerics->SetPrimitive(solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint), + solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(jPoint)); + + numerics->SetAdjointVar(nodes->GetSolution(iPoint), nodes->GetSolution(jPoint)); + + /*--- Gradient and limiter of Adjoint Variables ---*/ + + numerics->SetAdjointVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(jPoint)); + + /*--- Compute residual ---*/ + + numerics->ComputeResidual(Residual_i, Residual_j, Jacobian_ii, Jacobian_ij, Jacobian_ji, Jacobian_jj, config); + + /*--- Update adjoint viscous residual ---*/ + + LinSysRes.SubtractBlock(iPoint, Residual_i); + LinSysRes.AddBlock(jPoint, Residual_j); + + if (implicit) { + Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_ii); + Jacobian.SubtractBlock(iPoint, jPoint, Jacobian_ij); + Jacobian.AddBlock(jPoint, iPoint, Jacobian_ji); + Jacobian.AddBlock(jPoint, jPoint, Jacobian_jj); + } + + } + +} + +void CAdjNSSolver::Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CNumerics *second_numerics, + CConfig *config, unsigned short iMesh) { + + unsigned long iPoint, jPoint, iEdge; + + bool implicit = (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); + bool rotating_frame = config->GetRotating_Frame(); + + /*--- Loop over all the points, note that we are supposing that primitive and + adjoint gradients have been computed previously ---*/ + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + /*--- Primitive variables w/o reconstruction, and its gradient ---*/ + + numerics->SetPrimitive(solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint), NULL); + + numerics->SetPrimVarGradient(solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint), NULL); + + /*--- Gradient of adjoint variables ---*/ + + numerics->SetAdjointVarGradient(nodes->GetGradient(iPoint), NULL); + + /*--- Set volume ---*/ + + numerics->SetVolume(geometry->node[iPoint]->GetVolume()); + + /*--- If turbulence computation we must add some coupling terms to the NS adjoint eq. ---*/ + + if ((config->GetKind_Solver() == ADJ_RANS) && (!config->GetFrozen_Visc_Cont())) { + + /*--- Turbulent variables w/o reconstruction and its gradient ---*/ + + numerics->SetTurbVar(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint), NULL); + + numerics->SetTurbVarGradient(solver_container[TURB_SOL]->GetNodes()->GetGradient(iPoint), NULL); + + /*--- Turbulent adjoint variables w/o reconstruction and its gradient ---*/ + + numerics->SetTurbAdjointVar(solver_container[ADJTURB_SOL]->GetNodes()->GetSolution(iPoint), NULL); + + numerics->SetTurbAdjointGradient(solver_container[ADJTURB_SOL]->GetNodes()->GetGradient(iPoint), NULL); + + /*--- Set distance to the surface ---*/ + + numerics->SetDistance(geometry->node[iPoint]->GetWall_Distance(), 0.0); + + } + + /*--- Compute residual ---*/ + + numerics->ComputeResidual(Residual, config); + + /*--- Add to the residual ---*/ + + LinSysRes.AddBlock(iPoint, Residual); + + } + + /*--- If turbulence computation we must add some coupling terms to the NS adjoint eq. ---*/ + + if ((config->GetKind_Solver() == ADJ_RANS) && (!config->GetFrozen_Visc_Cont())) { + + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { + + /*--- Points in edge, and normal vector ---*/ + + iPoint = geometry->edge[iEdge]->GetNode(0); + jPoint = geometry->edge[iEdge]->GetNode(1); + second_numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); + + /*--- Conservative variables w/o reconstruction ---*/ + + second_numerics->SetConservative(solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint), + solver_container[FLOW_SOL]->GetNodes()->GetSolution(jPoint)); + + /*--- Gradient of primitive variables w/o reconstruction ---*/ + + second_numerics->SetPrimVarGradient(solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint), + solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(jPoint)); + + /*--- Viscosity ---*/ + + second_numerics->SetLaminarViscosity(solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint), + solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(jPoint)); + + /*--- Turbulent variables w/o reconstruction ---*/ + + second_numerics->SetTurbVar(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint), + solver_container[TURB_SOL]->GetNodes()->GetSolution(jPoint)); + + /*--- Turbulent adjoint variables w/o reconstruction ---*/ + + second_numerics->SetTurbAdjointVar(solver_container[ADJTURB_SOL]->GetNodes()->GetSolution(iPoint), + solver_container[ADJTURB_SOL]->GetNodes()->GetSolution(jPoint)); + + /*--- Set distance to the surface ---*/ + + second_numerics->SetDistance(geometry->node[iPoint]->GetWall_Distance(), geometry->node[jPoint]->GetWall_Distance()); + + /*--- Update adjoint viscous residual ---*/ + + second_numerics->ComputeResidual(Residual, config); + + LinSysRes.AddBlock(iPoint, Residual); + LinSysRes.SubtractBlock(jPoint, Residual); + } + + } + + // WARNING: The rotating frame source term has been placed in the second + // source term container since the section below is commented. This needs a + // permanent fix asap! + + if (rotating_frame) { + + /*--- Loop over all points ---*/ + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + /*--- Load the adjoint variables ---*/ + second_numerics->SetAdjointVar(nodes->GetSolution(iPoint), + nodes->GetSolution(iPoint)); + + /*--- Load the volume of the dual mesh cell ---*/ + second_numerics->SetVolume(geometry->node[iPoint]->GetVolume()); + + /*--- Compute the adjoint rotating frame source residual ---*/ + second_numerics->ComputeResidual(Residual, Jacobian_i, config); + + /*--- Add the source residual to the total ---*/ + LinSysRes.AddBlock(iPoint, Residual); + + /*--- Add the implicit Jacobian contribution ---*/ + if (implicit) Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); + + } + } +} + +void CAdjNSSolver::Viscous_Sensitivity(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config) { + + unsigned long iVertex, iPoint; + unsigned short iDim, jDim, iMarker, iPos, jPos; + su2double *d = NULL, **PsiVar_Grad = NULL, **PrimVar_Grad = NULL, div_phi, *Normal = NULL, Area, + normal_grad_psi5, normal_grad_T, sigma_partial, Laminar_Viscosity = 0.0, heat_flux_factor, temp_sens = 0.0, *Psi = NULL, *U = NULL, Enthalpy, **GridVel_Grad, gradPsi5_v, psi5_tau_partial, psi5_tau_grad_vel, source_v_1, Density, Pressure = 0.0, div_vel, val_turb_ke, vartheta, vartheta_partial, psi5_p_div_vel, Omega[3], rho_v[3] = {0.0,0.0,0.0}, CrossProduct[3], delta[3][3] = {{1.0, 0.0, 0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}}, r, ru, rv, rw, rE, p, T, dp_dr, dp_dru, dp_drv, dp_drw, dp_drE, dH_dr, dH_dru, dH_drv, dH_drw, dH_drE, H, D[3][3], Dd[3], Mach_Inf, eps, scale = 1.0; + su2double RefVel2, RefDensity, Mach2Vel, *Velocity_Inf, factor; + + su2double *USens = new su2double[nVar]; + su2double *UnitNormal = new su2double[nDim]; + su2double *normal_grad_vel = new su2double[nDim]; + su2double *tang_deriv_psi5 = new su2double[nDim]; + su2double *tang_deriv_T = new su2double[nDim]; + su2double **Sigma = new su2double* [nDim]; + + for (iDim = 0; iDim < nDim; iDim++) + Sigma[iDim] = new su2double [nDim]; + + su2double *normal_grad_gridvel = new su2double[nDim]; + su2double *normal_grad_v_ux =new su2double[nDim]; + su2double **Sigma_Psi5v = new su2double* [nDim]; + for (iDim = 0; iDim < nDim; iDim++) + Sigma_Psi5v[iDim] = new su2double [nDim]; + su2double **tau = new su2double* [nDim]; + for (iDim = 0; iDim < nDim; iDim++) + tau[iDim] = new su2double [nDim]; + su2double *Velocity = new su2double[nDim]; + + bool rotating_frame = config->GetRotating_Frame(); + bool grid_movement = config->GetGrid_Movement(); + su2double RefArea = config->GetRefArea(); + su2double Mach_Motion = config->GetMach_Motion(); + unsigned short ObjFunc = config->GetKind_ObjFunc(); + su2double Gas_Constant = config->GetGas_ConstantND(); + su2double Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; + su2double Prandtl_Lam = config->GetPrandtl_Lam(); + + if (config->GetSystemMeasurements() == US) scale = 1.0/12.0; + else scale = 1.0; + + /*--- Compute non-dimensional factor. For dynamic meshes, use the motion Mach + number as a reference value for computing the force coefficients. + Otherwise, use the freestream values, + which is the standard convention. ---*/ + + if (grid_movement) { + Mach2Vel = sqrt(Gamma*Gas_Constant*config->GetTemperature_FreeStreamND()); + RefVel2 = (Mach_Motion*Mach2Vel)*(Mach_Motion*Mach2Vel); + } + else { + Velocity_Inf = config->GetVelocity_FreeStreamND(); + RefVel2 = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + RefVel2 += Velocity_Inf[iDim]*Velocity_Inf[iDim]; + } + + RefDensity = config->GetDensity_FreeStreamND(); + + factor = 1.0; + /*-- For multi-objective problems these scaling factors are applied before solution ---*/ + if (config->GetnObj()==1) { + factor = 1.0/(0.5*RefDensity*RefArea*RefVel2); + + if ((ObjFunc == INVERSE_DESIGN_HEATFLUX) || + (ObjFunc == TOTAL_HEATFLUX) || (ObjFunc == MAXIMUM_HEATFLUX) || + (ObjFunc == SURFACE_MASSFLOW)) + factor = 1.0; + + if ((ObjFunc == SURFACE_TOTAL_PRESSURE) || (ObjFunc == SURFACE_STATIC_PRESSURE)) + factor = 1.0/Area_Monitored; + + } + + + /*--- Compute gradient of the grid velocity, if applicable ---*/ + + if (grid_movement) + SetGridVel_Gradient(geometry, config); + + Total_Sens_Geo = 0.0; + Total_Sens_Mach = 0.0; + Total_Sens_AoA = 0.0; + Total_Sens_Press = 0.0; + Total_Sens_Temp = 0.0; + + for (iMarker = 0; iMarker < nMarker; iMarker++) { + + Sens_Geo[iMarker] = 0.0; + + if ((config->GetMarker_All_KindBC(iMarker) == HEAT_FLUX) || + (config->GetMarker_All_KindBC(iMarker) == ISOTHERMAL)) { + + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + if (geometry->node[iPoint]->GetDomain()) { + + PsiVar_Grad = nodes->GetGradient(iPoint); + PrimVar_Grad = solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint); + + Laminar_Viscosity = solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); + + heat_flux_factor = Cp * Laminar_Viscosity / Prandtl_Lam; + + /*--- Compute face area and the unit normal to the surface ---*/ + + Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) { Area += Normal[iDim]*Normal[iDim]; } Area = sqrt(Area); + for (iDim = 0; iDim < nDim; iDim++) { UnitNormal[iDim] = Normal[iDim] / Area; } + + /*--- Compute the sensitivity related to the temperature ---*/ + + + normal_grad_psi5 = 0.0; normal_grad_T = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + normal_grad_psi5 += PsiVar_Grad[nVar-1][iDim]*UnitNormal[iDim]; + normal_grad_T += PrimVar_Grad[0][iDim]*UnitNormal[iDim]; + } + + temp_sens = 0.0; + if (config->GetMarker_All_KindBC(iMarker) == HEAT_FLUX) { + + /*--- Heat Flux Term: temp_sens = (\partial_tg \psi_5)\cdot (k \partial_tg T) ---*/ + + for (iDim = 0; iDim < nDim; iDim++) { + tang_deriv_psi5[iDim] = PsiVar_Grad[nVar-1][iDim] - normal_grad_psi5*UnitNormal[iDim]; + tang_deriv_T[iDim] = PrimVar_Grad[0][iDim] - normal_grad_T*UnitNormal[iDim]; + } + for (iDim = 0; iDim < nDim; iDim++) + temp_sens += heat_flux_factor * tang_deriv_psi5[iDim] * tang_deriv_T[iDim]; + + } else if (config->GetMarker_All_KindBC(iMarker) == ISOTHERMAL) { + + /*--- Isothermal Term: temp_sens = - k * \partial_n(\psi_5) * \partial_n(T) ---*/ + + temp_sens = - heat_flux_factor * normal_grad_psi5 * normal_grad_T; + + } + + + /*--- Term: sigma_partial = \Sigma_{ji} n_i \partial_n v_j ---*/ + + div_phi = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + div_phi += PsiVar_Grad[iDim+1][iDim]; + for (jDim = 0; jDim < nDim; jDim++) + Sigma[iDim][jDim] = Laminar_Viscosity * (PsiVar_Grad[iDim+1][jDim]+PsiVar_Grad[jDim+1][iDim]); + } + for (iDim = 0; iDim < nDim; iDim++) + Sigma[iDim][iDim] -= TWO3*Laminar_Viscosity * div_phi; + + + for (iDim = 0; iDim < nDim; iDim++) { + normal_grad_vel[iDim] = 0.0; + for (jDim = 0; jDim < nDim; jDim++) + normal_grad_vel[iDim] += PrimVar_Grad[iDim+1][jDim]*UnitNormal[jDim]; + } + + sigma_partial = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + for (jDim = 0; jDim < nDim; jDim++) + sigma_partial += UnitNormal[iDim]*Sigma[iDim][jDim]*normal_grad_vel[jDim]; + + /*--- Compute additional terms in the surface sensitivity for + moving walls in a rotating frame or dynamic mesh problem. ---*/ + + if (grid_movement) { + + Psi = nodes->GetSolution(iPoint); + U = solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint); + Density = U[0]; + Pressure = solver_container[FLOW_SOL]->GetNodes()->GetPressure(iPoint); + Enthalpy = solver_container[FLOW_SOL]->GetNodes()->GetEnthalpy(iPoint); + + /*--- Turbulent kinetic energy ---*/ + + if ((config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST)) + val_turb_ke = solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0); + else + val_turb_ke = 0.0; + + div_vel = 0.0; + for (iDim = 0 ; iDim < nDim; iDim++) { + Velocity[iDim] = U[iDim+1]/Density; + div_vel += PrimVar_Grad[iDim+1][iDim]; + } + + for (iDim = 0 ; iDim < nDim; iDim++) + for (jDim = 0 ; jDim < nDim; jDim++) + tau[iDim][jDim] = Laminar_Viscosity*(PrimVar_Grad[jDim+1][iDim] + PrimVar_Grad[iDim+1][jDim]) + - TWO3*Laminar_Viscosity*div_vel*delta[iDim][jDim] + - TWO3*Density*val_turb_ke*delta[iDim][jDim]; + + /*--- Form normal_grad_gridvel = \partial_n (u_omega) ---*/ + + GridVel_Grad = geometry->node[iPoint]->GetGridVel_Grad(); + for (iDim = 0; iDim < nDim; iDim++) { + normal_grad_gridvel[iDim] = 0.0; + for (jDim = 0; jDim < nDim; jDim++) + normal_grad_gridvel[iDim] += GridVel_Grad[iDim][jDim]*UnitNormal[jDim]; + } + + /*--- Form normal_grad_v_ux = \partial_n (v - u_omega) ---*/ + + for (iDim = 0; iDim < nDim; iDim++) + normal_grad_v_ux[iDim] = normal_grad_vel[iDim] - normal_grad_gridvel[iDim]; + + /*--- Form Sigma_Psi5v ---*/ + + gradPsi5_v = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + gradPsi5_v += PsiVar_Grad[nDim+1][iDim]*Velocity[iDim]; + for (jDim = 0; jDim < nDim; jDim++) + Sigma_Psi5v[iDim][jDim] = Laminar_Viscosity * (PsiVar_Grad[nDim+1][iDim]*Velocity[jDim]+PsiVar_Grad[nDim+1][jDim]*Velocity[iDim]); + } + for (iDim = 0; iDim < nDim; iDim++) + Sigma_Psi5v[iDim][iDim] -= TWO3*Laminar_Viscosity * gradPsi5_v; + + + /*--- Now compute terms of the surface sensitivity ---*/ + + /*--- Form vartheta_partial = \vartheta * \partial_n (v - u_x) . n ---*/ + vartheta = Density*Psi[0] + Density*Enthalpy*Psi[nDim+1]; + for (iDim = 0; iDim < nDim; iDim++) { + vartheta += U[iDim+1]*Psi[iDim+1]; + } + vartheta_partial = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + vartheta_partial += vartheta * normal_grad_v_ux[iDim] * UnitNormal[iDim]; + + /*--- Form sigma_partial = n_i ( \Sigma_Phi_{ij} + \Sigma_Psi5v_{ij} ) \partial_n (v - u_x)_j ---*/ + + sigma_partial = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + for (jDim = 0; jDim < nDim; jDim++) + sigma_partial += UnitNormal[iDim]*(Sigma[iDim][jDim]+Sigma_Psi5v[iDim][jDim])*normal_grad_v_ux[jDim]; + + /*--- Form psi5_tau_partial = \Psi_5 * \partial_n (v - u_x)_i * tau_{ij} * n_j ---*/ + + psi5_tau_partial = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + for (jDim = 0; jDim < nDim; jDim++) + psi5_tau_partial -= Psi[nDim+1]*normal_grad_v_ux[iDim]*tau[iDim][jDim]*UnitNormal[jDim]; + + /*--- Form psi5_p_div_vel = ---*/ + + psi5_p_div_vel = -Psi[nDim+1]*Pressure*div_vel; + + /*--- Form psi5_tau_grad_vel = \Psi_5 * tau_{ij} : \nabla( v ) ---*/ + + psi5_tau_grad_vel = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + for (jDim = 0; jDim < nDim; jDim++) + psi5_tau_grad_vel += Psi[nDim+1]*tau[iDim][jDim]*PrimVar_Grad[iDim+1][jDim]; + + /*--- Retrieve the angular velocity vector ---*/ + + source_v_1 = 0.0; + if (rotating_frame) { + + for (iDim = 0; iDim < 3; iDim++){ + Omega[iDim] = config->GetRotation_Rate(iDim)/config->GetOmega_Ref(); + } + + /*--- Calculate momentum source terms as: rho * ( Omega X V ) ---*/ + + for (iDim = 0; iDim < nDim; iDim++) + rho_v[iDim] = U[iDim+1]; + if (nDim == 2) rho_v[2] = 0.0; + + CrossProduct[0] = Omega[1]*rho_v[2] - Omega[2]*rho_v[1]; + CrossProduct[1] = Omega[2]*rho_v[0] - Omega[0]*rho_v[2]; + CrossProduct[2] = Omega[0]*rho_v[1] - Omega[1]*rho_v[0]; + + + for (iDim = 0; iDim < nDim; iDim++) { + source_v_1 += Psi[iDim+1]*CrossProduct[iDim]; + } + } + + /*--- For simplicity, store all additional terms within sigma_partial ---*/ + + sigma_partial = sigma_partial + vartheta_partial + psi5_tau_partial + psi5_p_div_vel + psi5_tau_grad_vel + source_v_1; + + } + + /*--- Compute sensitivity for each surface point ---*/ + + CSensitivity[iMarker][iVertex] = (sigma_partial - temp_sens) * Area * scale * factor; + + /*--- If sharp edge, set the sensitivity to 0 on that region ---*/ + + if (config->GetSens_Remove_Sharp()) { + eps = config->GetVenkat_LimiterCoeff()*config->GetRefElemLength(); + if ( geometry->node[iPoint]->GetSharpEdge_Distance() < config->GetAdjSharp_LimiterCoeff()*eps ) + CSensitivity[iMarker][iVertex] = 0.0; + } + + Sens_Geo[iMarker] -= CSensitivity[iMarker][iVertex]; + + } + } + + Total_Sens_Geo += Sens_Geo[iMarker]; + + } + } + + /*--- Farfield Sensitivity (Mach, AoA, Press, Temp), only for compressible flows ---*/ + + for (iMarker = 0; iMarker < nMarker; iMarker++) { + + if (config->GetMarker_All_KindBC(iMarker) == FAR_FIELD || config->GetMarker_All_KindBC(iMarker) == INLET_FLOW || + config->GetMarker_All_KindBC(iMarker) == SUPERSONIC_INLET || config->GetMarker_All_KindBC(iMarker) == SUPERSONIC_OUTLET || + config->GetMarker_All_KindBC(iMarker) == ENGINE_INFLOW ) { + + Sens_Mach[iMarker] = 0.0; + Sens_AoA[iMarker] = 0.0; + Sens_Press[iMarker] = 0.0; + Sens_Temp[iMarker] = 0.0; + Sens_BPress[iMarker] = 0.0; + + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + if (geometry->node[iPoint]->GetDomain()) { + Psi = nodes->GetSolution(iPoint); + U = solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint); + Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); + + Mach_Inf = config->GetMach(); + if (grid_movement) Mach_Inf = config->GetMach_Motion(); + + r = U[0]; ru = U[1]; rv = U[2]; + if (nDim == 2) { rw = 0.0; rE = U[3]; } + else { rw = U[3]; rE = U[4]; } + p = Gamma_Minus_One*(rE-(ru*ru + rv*rv + rw*rw)/(2*r)); + + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; + Area = sqrt(Area); + for (iDim = 0; iDim < nDim; iDim++) UnitNormal[iDim] = -Normal[iDim]/Area; + + H = (rE + p)/r; + + dp_dr = Gamma_Minus_One*(ru*ru + rv*rv + rw*rw)/(2*r*r); + dp_dru = -Gamma_Minus_One*ru/r; + dp_drv = -Gamma_Minus_One*rv/r; + if (nDim == 2) { dp_drw = 0.0; dp_drE = Gamma_Minus_One; } + else { dp_drw = -Gamma_Minus_One*rw/r; dp_drE = Gamma_Minus_One; } + + dH_dr = (-H + dp_dr)/r; dH_dru = dp_dru/r; dH_drv = dp_drv/r; + if (nDim == 2) { dH_drw = 0.0; dH_drE = (1 + dp_drE)/r; } + else { dH_drw = dp_drw/r; dH_drE = (1 + dp_drE)/r; } + + if (nDim == 2) { + Jacobian_j[0][0] = 0.0; + Jacobian_j[1][0] = Area*UnitNormal[0]; + Jacobian_j[2][0] = Area*UnitNormal[1]; + Jacobian_j[3][0] = 0.0; + + Jacobian_j[0][1] = (-(ru*ru)/(r*r) + dp_dr)*Area*UnitNormal[0] + (-(ru*rv)/(r*r))*Area*UnitNormal[1]; + Jacobian_j[1][1] = (2*ru/r + dp_dru)*Area*UnitNormal[0] + (rv/r)*Area*UnitNormal[1]; + Jacobian_j[2][1] = (dp_drv)*Area*UnitNormal[0] + (ru/r)*Area*UnitNormal[1]; + Jacobian_j[3][1] = (dp_drE)*Area*UnitNormal[0]; + + Jacobian_j[0][2] = (-(ru*rv)/(r*r))*Area*UnitNormal[0] + (-(rv*rv)/(r*r) + dp_dr)*Area*UnitNormal[1]; + Jacobian_j[1][2] = (rv/r)*Area*UnitNormal[0] + (dp_dru)*Area*UnitNormal[1]; + Jacobian_j[2][2] = (ru/r)*Area*UnitNormal[0] + (2*rv/r + dp_drv)*Area*UnitNormal[1]; + Jacobian_j[3][2] = (dp_drE)*Area*UnitNormal[1]; + + Jacobian_j[0][3] = (ru*dH_dr)*Area*UnitNormal[0] + (rv*dH_dr)*Area*UnitNormal[1]; + Jacobian_j[1][3] = (H + ru*dH_dru)*Area*UnitNormal[0] + (rv*dH_dru)*Area*UnitNormal[1]; + Jacobian_j[2][3] = (ru*dH_drv)*Area*UnitNormal[0] + (H + rv*dH_drv)*Area*UnitNormal[1]; + Jacobian_j[3][3] = (ru*dH_drE)*Area*UnitNormal[0] + (rv*dH_drE)*Area*UnitNormal[1]; + } + else { + Jacobian_j[0][0] = 0.0; + Jacobian_j[1][0] = Area*UnitNormal[0]; + Jacobian_j[2][0] = Area*UnitNormal[1]; + Jacobian_j[3][0] = Area*UnitNormal[2]; + Jacobian_j[4][0] = 0.0; + + Jacobian_j[0][1] = (-(ru*ru)/(r*r) + dp_dr)*Area*UnitNormal[0] + (-(ru*rv)/(r*r))*Area*UnitNormal[1] + (-(ru*rw)/(r*r))*Area*UnitNormal[2]; + Jacobian_j[1][1] = (2*ru/r + dp_dru)*Area*UnitNormal[0] + (rv/r)*Area*UnitNormal[1] + (rw/r)*Area*UnitNormal[2]; + Jacobian_j[2][1] = (dp_drv)*Area*UnitNormal[0] + (ru/r)*Area*UnitNormal[1]; + Jacobian_j[3][1] = (dp_drw)*Area*UnitNormal[0] + (ru/r)*Area*UnitNormal[2]; + Jacobian_j[4][1] = (dp_drE)*Area*UnitNormal[0]; + + Jacobian_j[0][2] = (-(ru*rv)/(r*r))*Area*UnitNormal[0] + (-(rv*rv)/(r*r) + dp_dr)*Area*UnitNormal[1] + (-(rv*rw)/(r*r))*Area*UnitNormal[2]; + Jacobian_j[1][2] = (rv/r)*Area*UnitNormal[0] + (dp_dru)*Area*UnitNormal[1]; + Jacobian_j[2][2] = (ru/r)*Area*UnitNormal[0] + (2*rv/r + dp_drv)*Area*UnitNormal[1] + (rw/r)*Area*UnitNormal[2]; + Jacobian_j[3][2] = (dp_drw)*Area*UnitNormal[1] + (rv/r)*Area*UnitNormal[2]; + Jacobian_j[4][2] = (dp_drE)*Area*UnitNormal[1]; + + Jacobian_j[0][3] = (-(ru*rw)/(r*r))*Area*UnitNormal[0] + (-(rv*rw)/(r*r))*Area*UnitNormal[1] + (-(rw*rw)/(r*r) + dp_dr)*Area*UnitNormal[2]; + Jacobian_j[1][3] = (rw/r)*Area*UnitNormal[0] + (dp_dru)*Area*UnitNormal[2]; + Jacobian_j[2][3] = (rw/r)*Area*UnitNormal[1] + (dp_drv)*Area*UnitNormal[2]; + Jacobian_j[3][3] = (ru/r)*Area*UnitNormal[0] + (rv/r)*Area*UnitNormal[1] + (2*rw/r + dp_drw)*Area*UnitNormal[2]; + Jacobian_j[4][3] = (dp_drE)*Area*UnitNormal[2]; + + Jacobian_j[0][4] = (ru*dH_dr)*Area*UnitNormal[0] + (rv*dH_dr)*Area*UnitNormal[1] + (rw*dH_dr)*Area*UnitNormal[2]; + Jacobian_j[1][4] = (H + ru*dH_dru)*Area*UnitNormal[0] + (rv*dH_dru)*Area*UnitNormal[1] + (rw*dH_dru)*Area*UnitNormal[2]; + Jacobian_j[2][4] = (ru*dH_drv)*Area*UnitNormal[0] + (H + rv*dH_drv)*Area*UnitNormal[1] + (rw*dH_drv)*Area*UnitNormal[2]; + Jacobian_j[3][4] = (ru*dH_drw)*Area*UnitNormal[0] + (rv*dH_drw)*Area*UnitNormal[1] + (H + rw*dH_drw)*Area*UnitNormal[2]; + Jacobian_j[4][4] = (ru*dH_drE)*Area*UnitNormal[0] + (rv*dH_drE)*Area*UnitNormal[1] + (rw*dH_drE)*Area*UnitNormal[2]; + } + + /*--- Mach number sensitivity ---*/ + + USens[0] = 0.0; USens[1] = ru/Mach_Inf; USens[2] = rv/Mach_Inf; + if (nDim == 2) { USens[3] = Gamma*Mach_Inf*p; } + else { USens[3] = rw/Mach_Inf; USens[4] = Gamma*Mach_Inf*p; } + for (iPos = 0; iPos < nVar; iPos++) { + for (jPos = 0; jPos < nVar; jPos++) { + Sens_Mach[iMarker] += Psi[iPos]*Jacobian_j[jPos][iPos]*USens[jPos]; + } + } + + /*--- AoA sensitivity ---*/ + + USens[0] = 0.0; + if (nDim == 2) { USens[1] = -rv; USens[2] = ru; USens[3] = 0.0; } + else { USens[1] = -rw; USens[2] = 0.0; USens[3] = ru; USens[4] = 0.0; } + for (iPos = 0; iPos < nVar; iPos++) { + for (jPos = 0; jPos < nVar; jPos++) { + Sens_AoA[iMarker] += Psi[iPos]*Jacobian_j[jPos][iPos]*USens[jPos]; + } + } + + /*--- Pressure sensitivity ---*/ + + USens[0] = r/p; USens[1] = ru/p; USens[2] = rv/p; + if (nDim == 2) { USens[3] = rE/p; } + else { USens[3] = rw/p; USens[4] = rE/p; } + for (iPos = 0; iPos < nVar; iPos++) { + for (jPos = 0; jPos < nVar; jPos++) { + Sens_Press[iMarker] += Psi[iPos]*Jacobian_j[jPos][iPos]*USens[jPos]; + } + } + + /*--- Temperature sensitivity ---*/ + + T = p/(r*Gas_Constant); + USens[0] = -r/T; USens[1] = 0.5*ru/T; USens[2] = 0.5*rv/T; + if (nDim == 2) { USens[3] = (ru*ru + rv*rv + rw*rw)/(r*T); } + else { USens[3] = 0.5*rw/T; USens[4] = (ru*ru + rv*rv + rw*rw)/(r*T); } + for (iPos = 0; iPos < nVar; iPos++) { + for (jPos = 0; jPos < nVar; jPos++) { + Sens_Temp[iMarker] += Psi[iPos]*Jacobian_j[jPos][iPos]*USens[jPos]; + } + } + } + } + + Total_Sens_Mach -= Sens_Mach[iMarker] * scale * factor; + Total_Sens_AoA -= Sens_AoA[iMarker] * scale * factor; + Total_Sens_Press -= Sens_Press[iMarker] * scale * factor; + Total_Sens_Temp -= Sens_Temp[iMarker] * scale * factor; + + } + + } + + /*--- Explicit contribution from objective function quantity ---*/ + + for (iMarker = 0; iMarker < nMarker; iMarker++) { + + if ((config->GetMarker_All_KindBC(iMarker) == HEAT_FLUX) || + (config->GetMarker_All_KindBC(iMarker) == ISOTHERMAL)) { + + Sens_Mach[iMarker] = 0.0; + Sens_AoA[iMarker] = 0.0; + Sens_Press[iMarker] = 0.0; + Sens_Temp[iMarker] = 0.0; + Sens_BPress[iMarker] = 0.0; + + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + if (geometry->node[iPoint]->GetDomain()) { + + Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); + p = solver_container[FLOW_SOL]->GetNodes()->GetPressure(iPoint); + + Mach_Inf = config->GetMach(); + if (grid_movement) Mach_Inf = config->GetMach_Motion(); + + d = nodes->GetForceProj_Vector(iPoint); + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; + Area = sqrt(Area); + for (iDim = 0; iDim < nDim; iDim++) UnitNormal[iDim] = -Normal[iDim]/Area; + + /*--- Mach number sensitivity ---*/ + + for (iPos = 0; iPos < nDim; iPos++) Dd[iPos] = -(2.0/Mach_Inf)*d[iPos]; + for (iPos = 0; iPos < nDim; iPos++) Sens_Mach[iMarker] += p*Dd[iPos]*Area*UnitNormal[iPos]; + + /*--- AoA sensitivity ---*/ + + if (config->GetKind_ObjFunc() == DRAG_COEFFICIENT || + config->GetKind_ObjFunc() == LIFT_COEFFICIENT || + config->GetKind_ObjFunc() == SIDEFORCE_COEFFICIENT || + config->GetKind_ObjFunc() == EQUIVALENT_AREA || + config->GetKind_ObjFunc() == NEARFIELD_PRESSURE) { + if (nDim == 2) { + D[0][0] = 0.0; D[0][1] = -1.0; + D[1][0] = 1.0; D[1][1] = 0.0; + } + else { + D[0][0] = 0.0; D[0][1] = 0.0; D[0][2] = -1.0; + D[1][0] = 0.0; D[1][1] = 0.0; D[1][2] = 0.0; + D[2][0] = 1.0; D[2][1] = 0.0; D[2][2] = 0.0; + } + for (iPos = 0; iPos < nDim; iPos++) Dd[iPos] = 0.0; + for (iPos = 0; iPos < nDim; iPos++) { + for (jPos = 0; jPos < nDim; jPos++) + Dd[iPos] += D[iPos][jPos]*d[jPos]; + } + } + + /*--- Coefficients with no explicit AoA dependece ---*/ + + else { + for (iPos = 0; iPosGetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); + bool grid_movement = config->GetGrid_Movement(); + + su2double Prandtl_Lam = config->GetPrandtl_Lam(); + su2double Prandtl_Turb = config->GetPrandtl_Turb(); + + su2double *Psi = new su2double[nVar]; + su2double **Tau = new su2double*[nDim]; + for (iDim = 0; iDim < nDim; iDim++) + Tau[iDim] = new su2double [nDim]; + su2double *Velocity = new su2double[nDim]; + su2double *Normal = new su2double[nDim]; + su2double *Edge_Vector = new su2double[nDim]; + su2double **GradPhi = new su2double*[nDim]; + for (iDim = 0; iDim < nDim; iDim++) + GradPhi[iDim] = new su2double [nDim]; + su2double *GradPsiE = new su2double [nDim]; + + /*--- Loop over all of the vertices on this boundary marker ---*/ + + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { + + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); + + /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ + + if (geometry->node[iPoint]->GetDomain()) { + + /*--- Normal vector for this vertex (negate for outward convention) ---*/ + + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); + for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; + + /*--- Initialize the convective & viscous residuals to zero ---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + Res_Conv_i[iVar] = 0.0; Res_Visc_i[iVar] = 0.0; + if (implicit) { for (jVar = 0; jVar < nVar; jVar ++) Jacobian_ii[iVar][jVar] = 0.0; } + } + + /*--- Retrieve adjoint solution at the wall boundary node ---*/ + + for (iVar = 0; iVar < nVar; iVar++) + Psi[iVar] = nodes->GetSolution(iPoint,iVar); + + /*--- Get the force projection vector (based on the objective function) ---*/ + + d = nodes->GetForceProj_Vector(iPoint); + + /*--- Set the adjoint velocity BC ---*/ + + for (iDim = 0; iDim < nDim; iDim++) { phi[iDim] = d[iDim]; } + + /*--- Correct the adjoint velocity BC for dynamic meshes ---*/ + + if (grid_movement) { + GridVel = geometry->node[iPoint]->GetGridVel(); + for (iDim = 0; iDim < nDim; iDim++) + phi[iDim] -= Psi[nDim+1]*GridVel[iDim]; + } + + /*--- Impose the value of the adjoint velocity as a strong boundary + condition (Dirichlet). Fix the adjoint velocity and remove any addtional + contribution to the residual at this node. ---*/ + + for (iDim = 0; iDim < nDim; iDim++) + nodes->SetSolution_Old(iPoint,iDim+1, phi[iDim]); + + for (iDim = 0; iDim < nDim; iDim++) + LinSysRes.SetBlock_Zero(iPoint, iDim+1); + nodes->SetVel_ResTruncError_Zero(iPoint); + + /*--- Compute additional contributions to the adjoint density and energy + equations which will be added to the residual (weak imposition) ---*/ + + /*--- Energy residual due to the convective term ---*/ + + l1psi = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + l1psi += Normal[iDim]*d[iDim]; + Res_Conv_i[nDim+1] = l1psi*Gamma_Minus_One; + + /*--- Flux contribution and Jacobian contributions for moving + walls. Note that these are only for the adjoint density and + adjoint energy equations (the adjoint vel. uses a strong BC). ---*/ + + if (grid_movement) { + + /*--- Get the grid velocity at this node and impose v = u_wall ---*/ + + GridVel = geometry->node[iPoint]->GetGridVel(); + for (iDim = 0; iDim < nDim; iDim++) Velocity[iDim] = GridVel[iDim]; + + /*--- Get some additional quantities from the flow solution ---*/ + + Density = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + Pressure = solver_container[FLOW_SOL]->GetNodes()->GetPressure(iPoint); + Enthalpy = solver_container[FLOW_SOL]->GetNodes()->GetEnthalpy(iPoint); + Laminar_Viscosity = solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); + Eddy_Viscosity = solver_container[FLOW_SOL]->GetNodes()->GetEddyViscosity(iPoint); // Should be zero at the wall + + ViscDens = (Laminar_Viscosity + Eddy_Viscosity) / Density; + XiDens = Gamma * (Laminar_Viscosity/Prandtl_Lam + Eddy_Viscosity/Prandtl_Turb) / Density; + + /*--- Compute projections, velocity squared divided by two, and + other inner products. Note that we are imposing v = u_wall from + the direct problem and that phi = d - \psi_5 * v ---*/ + + ProjGridVel = 0.0; sq_vel = 0.0; + vartheta = Psi[0] + Psi[nDim+1]*Enthalpy; + for (iDim = 0; iDim < nDim; iDim++) { + ProjGridVel += GridVel[iDim]*Normal[iDim]; + sq_vel += 0.5*GridVel[iDim]*GridVel[iDim]; + vartheta += GridVel[iDim]*phi[iDim]; + } + + /*--- Convective flux at the wall node (adjoint density) ---*/ + + Res_Conv_i[0] = -vartheta*ProjGridVel + l1psi*Gamma_Minus_One*sq_vel; + + /*--- Implicit contributions from convective part ---*/ + + if (implicit) { + Jacobian_ii[0][0] += -ProjGridVel; + Jacobian_ii[0][nVar-1] += -ProjGridVel * Enthalpy; + } + + /*--- Viscous flux contributions at the wall node. Impose dPhiE_dn = 0 + (adiabatic walls with frozen viscosity). ---*/ + + dPhiE_dn = 0.0; + + /*--- Store the adjoint velocity and energy gradients for clarity ---*/ + + PsiVar_Grad = nodes->GetGradient(iPoint); + for (iDim = 0; iDim < nDim; iDim++) { + GradPsiE[iDim] = PsiVar_Grad[nVar-1][iDim]; + for (jDim = 0; jDim < nDim; jDim++) + GradPhi[iDim][jDim] = PsiVar_Grad[iDim+1][jDim]; + } + + if (nDim == 2) { + + /*--- Compute the adjoint stress tensor ---*/ + + Sigma_xx = ViscDens * (FOUR3 * GradPhi[0][0] - TWO3 * GradPhi[1][1]); + Sigma_yy = ViscDens * (-TWO3 * GradPhi[0][0] + FOUR3 * GradPhi[1][1]); + Sigma_xy = ViscDens * (GradPhi[1][0] + GradPhi[0][1]); + Sigma_xx5 = ViscDens * ( FOUR3 * Velocity[0] * GradPsiE[0] - TWO3 * Velocity[1] * GradPsiE[1]); + Sigma_yy5 = ViscDens * (- TWO3 * Velocity[0] * GradPsiE[0] + FOUR3 * Velocity[1] * GradPsiE[1]); + Sigma_xy5 = ViscDens * (Velocity[0] * GradPsiE[1] + Velocity[1] * GradPsiE[0]); + Sigma_5 = XiDens * dPhiE_dn; + eta_xx = Sigma_xx + Sigma_xx5; + eta_yy = Sigma_yy + Sigma_yy5; + eta_xy = Sigma_xy + Sigma_xy5; + + /*--- Viscous flux at the wall node (adjoint density & energy only) ---*/ + + Res_Visc_i[0] = - (Velocity[0] * Normal[0] * eta_xx + Velocity[1] * Normal[1] * eta_yy + + (Velocity[0] * Normal[1] + Velocity[1] * Normal[0]) * eta_xy + - (sq_vel - Pressure/(Density*Gamma_Minus_One)) * Sigma_5); + Res_Visc_i[nDim+1] = Sigma_5; + + /*--- Computation of the Jacobians at Point i---*/ + + if (implicit) { + + /*--- Compute closest normal neighbor ---*/ + + Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); + + /*--- Get coordinates of i & nearest normal and compute distance ---*/ + + Coord_i = geometry->node[iPoint]->GetCoord(); + Coord_j = geometry->node[Point_Normal]->GetCoord(); + dist_ij_2 = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + Edge_Vector[iDim] = Coord_j[iDim]-Coord_i[iDim]; + dist_ij_2 += Edge_Vector[iDim]*Edge_Vector[iDim]; + } + + dSigmaxx_phi1 = -FOUR3 * ViscDens * Edge_Vector[0]/dist_ij_2; + dSigmaxx_phi2 = TWO3 * ViscDens * Edge_Vector[1]/dist_ij_2; + dSigmayy_phi1 = TWO3 * ViscDens * Edge_Vector[0]/dist_ij_2; + dSigmayy_phi2 = -FOUR3 * ViscDens * Edge_Vector[1]/dist_ij_2; + dSigmaxy_phi1 = -ViscDens * Edge_Vector[1]/dist_ij_2; + dSigmaxy_phi2 = -ViscDens * Edge_Vector[0]/dist_ij_2; + + // dSigmaxx5_psi5 = -ViscDens * ( FOUR3*Velocity[0]*Edge_Vector[0] - TWO3*Velocity[1]*Edge_Vector[1] )/dist_ij_2; + // dSigmayy5_psi5 = -ViscDens * (- TWO3*Velocity[0]*Edge_Vector[0] + FOUR3*Velocity[1]*Edge_Vector[1] )/dist_ij_2; + // dSigmaxy5_psi5 = -ViscDens * ( Velocity[0]*Edge_Vector[1] + Velocity[1]*Edge_Vector[0] )/dist_ij_2; + dSigma5_psi5 = -XiDens * ( Edge_Vector[0]*Normal[0] + Edge_Vector[1]*Normal[1] )/dist_ij_2; + + Jacobian_ii[0][0] += 0.0; + Jacobian_ii[0][1] += -( Velocity[0]*Normal[0]*dSigmaxx_phi1 + Velocity[1]*Normal[1]*dSigmayy_phi1 + + (Velocity[0]*Normal[1] + Velocity[1]*Normal[0])*dSigmaxy_phi1 ); + Jacobian_ii[0][2] += -( Velocity[0]*Normal[0]*dSigmaxx_phi2 + Velocity[1]*Normal[1]*dSigmayy_phi2 + + (Velocity[0]*Normal[1] + Velocity[1]*Normal[0])*dSigmaxy_phi2 ); + Jacobian_ii[0][3] += (sq_vel - Pressure/(Density*Gamma_Minus_One)) * dSigma5_psi5; + + Jacobian_ii[3][0] += 0.0; + Jacobian_ii[3][1] += 0.0; + Jacobian_ii[3][2] += 0.0; + Jacobian_ii[3][3] += dSigma5_psi5; + + } + + + } else if (nDim == 3) { + + /*--- Compute the adjoint stress tensor ---*/ + Sigma_xx = ViscDens * (FOUR3 * GradPhi[0][0] - TWO3 * GradPhi[1][1] - TWO3 * GradPhi[2][2]); + Sigma_yy = ViscDens * (-TWO3 * GradPhi[0][0] + FOUR3 * GradPhi[1][1] - TWO3 * GradPhi[2][2]); + Sigma_zz = ViscDens * (-TWO3 * GradPhi[0][0] - TWO3 * GradPhi[1][1] + FOUR3 * GradPhi[2][2]); + Sigma_xy = ViscDens * (GradPhi[1][0] + GradPhi[0][1]); + Sigma_xz = ViscDens * (GradPhi[2][0] + GradPhi[0][2]); + Sigma_yz = ViscDens * (GradPhi[2][1] + GradPhi[1][2]); + Sigma_xx5 = ViscDens * ( FOUR3 * Velocity[0] * GradPsiE[0] - TWO3 * Velocity[1] * GradPsiE[1] - TWO3 * Velocity[2] * GradPsiE[2]); + Sigma_yy5 = ViscDens * (- TWO3 * Velocity[0] * GradPsiE[0] + FOUR3 * Velocity[1] * GradPsiE[1] - TWO3 * Velocity[2] * GradPsiE[2]); + Sigma_zz5 = ViscDens * (- TWO3 * Velocity[0] * GradPsiE[0] - TWO3 * Velocity[1] * GradPsiE[1] + FOUR3 * Velocity[2] * GradPsiE[2]); + Sigma_xy5 = ViscDens * (Velocity[0] * GradPsiE[1] + Velocity[1] * GradPsiE[0]); + Sigma_xz5 = ViscDens * (Velocity[0] * GradPsiE[2] + Velocity[2] * GradPsiE[0]); + Sigma_yz5 = ViscDens * (Velocity[1] * GradPsiE[2] + Velocity[2] * GradPsiE[1]); + Sigma_5 = XiDens * dPhiE_dn; + eta_xx = Sigma_xx + Sigma_xx5; eta_yy = Sigma_yy + Sigma_yy5; eta_zz = Sigma_zz + Sigma_zz5; + eta_xy = Sigma_xy + Sigma_xy5; eta_xz = Sigma_xz + Sigma_xz5; eta_yz = Sigma_yz + Sigma_yz5; + + /*--- Viscous flux at the wall node (adjoint density & energy only) ---*/ + + Res_Visc_i[0] = - (Velocity[0] * Normal[0] * eta_xx + Velocity[1] * Normal[1] * eta_yy + Velocity[2] * Normal[2] * eta_zz + + (Velocity[0] * Normal[1] + Velocity[1] * Normal[0]) * eta_xy + + (Velocity[0] * Normal[2] + Velocity[2] * Normal[0]) * eta_xz + + (Velocity[2] * Normal[1] + Velocity[1] * Normal[2]) * eta_yz + - (sq_vel - Pressure/(Density*Gamma_Minus_One)) * Sigma_5); + Res_Visc_i[nDim+1] = Sigma_5; + + /*--- Computation of the Jacobians at Point i---*/ + + if (implicit) { + + /*--- Compute closest normal neighbor ---*/ + + Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); + + /*--- Get coordinates of i & nearest normal and compute distance ---*/ + + Coord_i = geometry->node[iPoint]->GetCoord(); + Coord_j = geometry->node[Point_Normal]->GetCoord(); + dist_ij_2 = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + Edge_Vector[iDim] = Coord_j[iDim]-Coord_i[iDim]; + dist_ij_2 += Edge_Vector[iDim]*Edge_Vector[iDim]; + } + + dSigmaxx_phi1 = -FOUR3 * ViscDens * Edge_Vector[0]/dist_ij_2; + dSigmaxx_phi2 = TWO3 * ViscDens * Edge_Vector[1]/dist_ij_2; + dSigmaxx_phi3 = TWO3 * ViscDens * Edge_Vector[2]/dist_ij_2; + dSigmayy_phi1 = TWO3 * ViscDens * Edge_Vector[0]/dist_ij_2; + dSigmayy_phi2 = -FOUR3 * ViscDens * Edge_Vector[1]/dist_ij_2; + dSigmayy_phi3 = TWO3 * ViscDens * Edge_Vector[2]/dist_ij_2; + dSigmazz_phi1 = TWO3 * ViscDens * Edge_Vector[0]/dist_ij_2; + dSigmazz_phi2 = TWO3 * ViscDens * Edge_Vector[1]/dist_ij_2; + dSigmazz_phi3 = -FOUR3 * ViscDens * Edge_Vector[2]/dist_ij_2; + dSigmaxy_phi1 = -ViscDens * Edge_Vector[1]/dist_ij_2; + dSigmaxy_phi2 = -ViscDens * Edge_Vector[0]/dist_ij_2; + dSigmaxy_phi3 = 0; + dSigmaxz_phi1 = -ViscDens * Edge_Vector[2]/dist_ij_2; + dSigmaxz_phi2 = 0; + dSigmaxz_phi3 = -ViscDens * Edge_Vector[0]/dist_ij_2; + dSigmayz_phi1 = 0; + dSigmayz_phi2 = -ViscDens * Edge_Vector[2]/dist_ij_2; + dSigmayz_phi3 = -ViscDens * Edge_Vector[1]/dist_ij_2; + + // dSigmaxx5_psi5 = -ViscDens * ( FOUR3*Velocity[0]*Edge_Vector[0] - TWO3*Velocity[1]*Edge_Vector[1] - TWO3*Velocity[2]*Edge_Vector[2])/dist_ij_2; + // dSigmayy5_psi5 = -ViscDens * (- TWO3*Velocity[0]*Edge_Vector[0] + FOUR3*Velocity[1]*Edge_Vector[1] - TWO3*Velocity[2]*Edge_Vector[2])/dist_ij_2; + // dSigmazz5_psi5 = -ViscDens * (- TWO3*Velocity[0]*Edge_Vector[0] - TWO3*Velocity[1]*Edge_Vector[1] + FOUR3*Velocity[2]*Edge_Vector[2])/dist_ij_2; + // dSigmaxy5_psi5 = -ViscDens * ( Velocity[0]*Edge_Vector[1] + Velocity[1]*Edge_Vector[0] )/dist_ij_2; + // dSigmaxz5_psi5 = -ViscDens * ( Velocity[0]*Edge_Vector[2] + Velocity[2]*Edge_Vector[0] )/dist_ij_2; + // dSigmayz5_psi5 = -ViscDens * ( Velocity[1]*Edge_Vector[2] + Velocity[2]*Edge_Vector[1] )/dist_ij_2; + dSigma5_psi5 = -XiDens * ( Edge_Vector[0]*Normal[0] + Edge_Vector[1]*Normal[1] + Edge_Vector[2]*Normal[2] )/dist_ij_2; + + Jacobian_ii[0][0] += 0.0; + Jacobian_ii[0][1] += -( Velocity[0]*Normal[0]*dSigmaxx_phi1 + Velocity[1]*Normal[1]*dSigmayy_phi1 + Velocity[2]*Normal[2]*dSigmazz_phi1 + + (Velocity[0]*Normal[1] + Velocity[1]*Normal[0])*dSigmaxy_phi1 + + (Velocity[0]*Normal[2] + Velocity[2]*Normal[0])*dSigmaxz_phi1 + + (Velocity[2]*Normal[1] + Velocity[1]*Normal[2])*dSigmayz_phi1 ); + Jacobian_ii[0][2] += -( Velocity[0]*Normal[0]*dSigmaxx_phi2 + Velocity[1]*Normal[1]*dSigmayy_phi2 + Velocity[2]*Normal[2]*dSigmazz_phi2 + + (Velocity[0]*Normal[1] + Velocity[1]*Normal[0])*dSigmaxy_phi2 + + (Velocity[0]*Normal[2] + Velocity[2]*Normal[0])*dSigmaxz_phi2 + + (Velocity[2]*Normal[1] + Velocity[1]*Normal[2])*dSigmayz_phi2 ); + Jacobian_ii[0][3] += -( Velocity[0]*Normal[0]*dSigmaxx_phi3 + Velocity[1]*Normal[1]*dSigmayy_phi3 + Velocity[2]*Normal[2]*dSigmazz_phi3 + + (Velocity[0]*Normal[1] + Velocity[1]*Normal[0])*dSigmaxy_phi3 + + (Velocity[0]*Normal[2] + Velocity[2]*Normal[0])*dSigmaxz_phi3 + + (Velocity[2]*Normal[1] + Velocity[1]*Normal[2])*dSigmayz_phi3 ); + Jacobian_ii[0][4] += (sq_vel - Pressure/(Density*Gamma_Minus_One)) * dSigma5_psi5; + + Jacobian_ii[4][0] += 0.0; + Jacobian_ii[4][1] += 0.0; + Jacobian_ii[4][2] += 0.0; + Jacobian_ii[4][3] += 0.0; + Jacobian_ii[4][4] += dSigma5_psi5; + + } + } + } + + /*--- Convective contribution to the residual at the wall ---*/ + + LinSysRes.SubtractBlock(iPoint, Res_Conv_i); + + /*--- Viscous contribution to the residual at the wall ---*/ + + LinSysRes.SubtractBlock(iPoint, Res_Visc_i); + + /*--- Enforce the no-slip boundary condition in a strong way by + modifying the velocity-rows of the Jacobian (1 on the diagonal). ---*/ + + if (implicit) { + Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_ii); + for (iVar = 1; iVar <= nDim; iVar++) { + total_index = iPoint*nVar+iVar; + Jacobian.DeleteValsRowi(total_index); + } + } + + } + + } + + for (iDim = 0; iDim < nDim; iDim++) + delete [] Tau[iDim]; + delete [] Tau; + delete [] Psi; + delete [] Velocity; + delete [] Normal; + delete [] Edge_Vector; + delete [] GradPsiE; + for (iDim = 0; iDim < nDim; iDim++) + delete [] GradPhi[iDim]; + delete [] GradPhi; + +} + + +void CAdjNSSolver::BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { + + unsigned long iVertex, iPoint, total_index; + unsigned short iDim, iVar, jVar, jDim; + su2double *d, q, *U, dVisc_T, rho, pressure, div_phi, + force_stress, Sigma_5, **PsiVar_Grad, phi[3] = {0.0,0.0,0.0}; + su2double phis1, phis2, sq_vel, ProjVel, Enthalpy, *GridVel, phi_u, d_n; + su2double Energy, ViscDens, XiDens, Density, SoundSpeed, Pressure, dPhiE_dn, Laminar_Viscosity, Eddy_Viscosity, + Sigma_xx, Sigma_yy, Sigma_zz, Sigma_xy, Sigma_xz, Sigma_yz, + Sigma_xx5, Sigma_yy5, Sigma_zz5, Sigma_xy5, Sigma_xz5, + Sigma_yz5, eta_xx, eta_yy, eta_zz, eta_xy, eta_xz, eta_yz; + su2double kGTdotn=0.0, Area=0.0, Xi=0.0; + + su2double *Psi = new su2double[nVar]; + su2double **Tau = new su2double* [nDim]; + for (iDim = 0; iDim < nDim; iDim++) + Tau[iDim] = new su2double [nDim]; + su2double *Velocity = new su2double[nDim]; + su2double *Normal = new su2double[nDim]; + + su2double **GradPhi = new su2double* [nDim]; + for (iDim = 0; iDim < nDim; iDim++) + GradPhi[iDim] = new su2double [nDim]; + su2double *GradPsiE = new su2double [nDim]; + su2double *GradT;// = new su2double[nDim]; + su2double *GradP; + su2double *GradDens; + su2double *dPoRho2 = new su2double[nDim]; + + bool implicit = (config->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); + bool grid_movement = config->GetGrid_Movement(); + bool heat_flux_obj; + + su2double Prandtl_Lam = config->GetPrandtl_Lam(); + su2double Prandtl_Turb = config->GetPrandtl_Turb(); + su2double Gas_Constant = config->GetGas_ConstantND(); + su2double Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; + su2double Thermal_Conductivity; + su2double invrho3; + su2double Volume; + su2double mu2; + su2double gpsiAv2; + su2double gpsi5n; + + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); + string Monitoring_Tag; + unsigned short jMarker, iMarker_Monitoring=0; + su2double Weight_ObjFunc = 1.0; + + /*--- Identify marker monitoring index ---*/ + for (jMarker = 0; jMarker < config->GetnMarker_Monitoring(); jMarker++) { + Monitoring_Tag = config->GetMarker_Monitoring_TagBound(jMarker); + if (Monitoring_Tag==Marker_Tag) + iMarker_Monitoring = jMarker; + } + /*-- Get objective weight --*/ + Weight_ObjFunc = config->GetWeight_ObjFunc(iMarker_Monitoring); + heat_flux_obj = ((config->GetKind_ObjFunc(iMarker_Monitoring) == TOTAL_HEATFLUX) || + (config->GetKind_ObjFunc(iMarker_Monitoring) == MAXIMUM_HEATFLUX) || + (config->GetKind_ObjFunc(iMarker_Monitoring) == INVERSE_DESIGN_HEATFLUX)); + + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { + + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); + + if (geometry->node[iPoint]->GetDomain()) { + + /*--- Initialize the convective & viscous residuals to zero ---*/ + for (iVar = 0; iVar < nVar; iVar++) { + Res_Conv_i[iVar] = 0.0; + Res_Visc_i[iVar] = 0.0; + if (implicit) { + for (jVar = 0; jVar < nVar; jVar ++) + Jacobian_ii[iVar][jVar] = 0.0; + } + } + + /*--- Retrieve adjoint solution at the wall boundary node ---*/ + for (iVar = 0; iVar < nVar; iVar++) + Psi[iVar] = nodes->GetSolution(iPoint,iVar); + + /*--- Normal vector for this vertex (negate for outward convention) ---*/ + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); + Volume = geometry->node[iPoint]->GetVolume(); + for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; + + /*--- Get the force projection vector (based on the objective function) ---*/ + d = nodes->GetForceProj_Vector(iPoint); + + /*--- Adjustments to strong boundary condition for dynamic meshes ---*/ + if ( grid_movement) { + GridVel = geometry->node[iPoint]->GetGridVel(); + for (iDim = 0; iDim < nDim; iDim++) { + phi[iDim] = d[iDim] - Psi[nVar-1]*GridVel[iDim]; + } + } else { + for (iDim = 0; iDim < nDim; iDim++) { + phi[iDim] = d[iDim]; + } + } + + /*--- Strong BC imposition for the adjoint velocity equations ---*/ + for (iDim = 0; iDim < nDim; iDim++) + LinSysRes.SetBlock_Zero(iPoint, iDim+1); + nodes->SetVel_ResTruncError_Zero(iPoint); + for (iDim = 0; iDim < nDim; iDim++) + nodes->SetSolution_Old(iPoint,iDim+1, phi[iDim]); + if (implicit) { + for (iVar = 1; iVar <= nDim; iVar++) { + total_index = iPoint*nVar+iVar; + Jacobian.DeleteValsRowi(total_index); + } + } + + /*--- Get transport coefficient information ---*/ + Laminar_Viscosity = solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); + Eddy_Viscosity = solver_container[FLOW_SOL]->GetNodes()->GetEddyViscosity(iPoint); + Thermal_Conductivity = Cp * ( Laminar_Viscosity/Prandtl_Lam + +Eddy_Viscosity/Prandtl_Turb); + +// GradV = solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint); + + /*--- Calculate Dirichlet condition for energy equation ---*/ + if (!heat_flux_obj) { + q = 0.0; + } + else { + + Area = 0.0; + for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; + Area = sqrt(Area); + + /*--- Temperature gradient term ---*/ + GradT = solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint)[0]; + kGTdotn = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + kGTdotn += Cp * Laminar_Viscosity/Prandtl_Lam*GradT[iDim]*Normal[iDim]/Area; + // Cp * Viscosity/Prandtl_Lam matches term used in solver_direct_mean + /*--- constant term to multiply max heat flux objective ---*/ + Xi = solver_container[FLOW_SOL]->GetTotal_HeatFlux(); // versions for max heat flux + Xi = pow(Xi, 1.0/pnorm-1.0)/pnorm; + + /*--- Boundary condition value ---*/ + q = Xi * pnorm * pow(kGTdotn, pnorm-1.0)*Area*Weight_ObjFunc; + } + + /*--- Strong BC enforcement of the energy equation ---*/ + LinSysRes.SetBlock_Zero(iPoint, nVar-1); + nodes->SetEnergy_ResTruncError_Zero(iPoint); + nodes->SetSolution_Old(iPoint,nDim+1, q); + if (implicit) { + iVar = nDim+1; + total_index = iPoint*nVar+iVar; + Jacobian.DeleteValsRowi(total_index); + } + + /*--- Additional contributions to adjoint density (weak imposition) ---*/ + + /*--- Acquire gradient information ---*/ + PsiVar_Grad = nodes->GetGradient(iPoint); + GradP = solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint)[nVar-1]; + GradDens = solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint)[nVar]; + + /*--- Acqure flow information ---*/ + rho = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + pressure = solver_container[FLOW_SOL]->GetNodes()->GetPressure(iPoint); + invrho3 = (1.0/rho)*(1.0/rho)*(1.0/rho); + + /*--- Calculate supporting quantities ---*/ + mu2 = Thermal_Conductivity/Cp; + gpsiAv2 = 0.0; + gpsi5n = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + dPoRho2[iDim] = (GradP[iDim]*rho - 2.0*GradDens[iDim]*pressure)*invrho3; + gpsiAv2 += -mu2*Gamma/Gamma_Minus_One * PsiVar_Grad[nVar-1][iDim]*dPoRho2[iDim]; + gpsi5n += PsiVar_Grad[nVar-1][iDim]*Normal[iDim]; + } + + /*--- Apply first order term to boundary ---*/ + Res_Conv_i[0] = gpsiAv2*Volume; + + /*--- Apply second order term to boundary ---*/ + Res_Visc_i[0] = -mu2*Gamma/(rho*Gamma_Minus_One)*(pressure/rho)*gpsi5n; + + /*--- Components of the effective and adjoint stress tensors ---*/ + PsiVar_Grad = nodes->GetGradient(iPoint); + div_phi = 0; + for (iDim = 0; iDim < nDim; iDim++) { + div_phi += PsiVar_Grad[iDim+1][iDim]; + for (jDim = 0; jDim < nDim; jDim++) + Tau[iDim][jDim] = (PsiVar_Grad[iDim+1][jDim]+PsiVar_Grad[jDim+1][iDim]); + } + for (iDim = 0; iDim < nDim; iDim++) + Tau[iDim][iDim] -= TWO3*div_phi; + + /*--- force_stress = n_i \Tau_{ij} d_j ---*/ + force_stress = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + for (jDim = 0; jDim < nDim; jDim++) + force_stress += Normal[iDim]*Tau[iDim][jDim]*d[jDim]; + + /*--- \partial \mu_dyn \partial T ---*/ + // mu_dyn = solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); + // Temp = solver_container[FLOW_SOL]->GetNodes()->GetTemperature(iPoint); + dVisc_T = 0.0; // dVisc_T = mu_dyn*(Temp+3.0*mu2)/(2.0*Temp*(Temp+mu2)); + + /*--- \Sigma_5 Check Area computation for Res_Conv[0] ---*/ + Sigma_5 = (Gamma/Cp)*dVisc_T*force_stress; + + /*--- Imposition of residuals ---*/ + rho = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + pressure = solver_container[FLOW_SOL]->GetNodes()->GetPressure(iPoint); + Res_Conv_i[0] = pressure*Sigma_5/(Gamma_Minus_One*rho*rho); + + /*--- Flux contribution and Jacobian contributions for moving + walls. Note that these are only for the adjoint density and + adjoint energy equations (the adjoint vel. uses a strong BC). ---*/ + if (grid_movement) { + + /*--- Get the appropriate grid velocity at this node ---*/ + GridVel = geometry->node[iPoint]->GetGridVel(); + + /*--- Get the enthalpy from the direct solution ---*/ + Enthalpy = solver_container[FLOW_SOL]->GetNodes()->GetEnthalpy(iPoint); + + /*--- Compute projections, velocity squared divided by two, and + other inner products. Note that we are imposing v = u_wall from + the direct problem and that phi = d - \psi_5 * v ---*/ + ProjVel = 0.0; sq_vel = 0.0; phi_u = 0.0; d_n = 0.0; + phis1 = 0.0; phis2 = Psi[0] + Enthalpy * Psi[nVar-1]; + for (iDim = 0; iDim < nDim; iDim++) { + ProjVel += GridVel[iDim]*Normal[iDim]; + sq_vel += 0.5*GridVel[iDim]*GridVel[iDim]; + phis1 += Normal[iDim]*phi[iDim]; + phis2 += GridVel[iDim]*phi[iDim]; + phi_u += GridVel[iDim]*phi[iDim]; + d_n += d[iDim]*Normal[iDim]; + } + // phis1 += ProjVel * Psi[nVar-1]; + + /*--- Convective flux at the wall node (adjoint density & energy only) ---*/ + + /*--- Version 1 (full) ---*/ + //Res_Conv_i[0] = ProjVel * Psi[0] - phis2 * ProjVel + phis1 * Gamma_Minus_One * sq_vel - ProjVel*Psi[0]; + //Res_Conv_i[nVar-1] = ProjVel * Psi[nVar-1] + phis1 * Gamma_Minus_One - ProjVel*Psi[nVar-1]; + + /*--- Simplified version ---*/ + Res_Conv_i[0] = -(Psi[0] + phi_u + Psi[nVar-1]*Enthalpy)*ProjVel + d_n*Gamma_Minus_One*sq_vel; + + /*--- TO DO: Implicit contributions for convective part ---*/ + + + /*--- Viscous flux contributions at the wall node ---*/ + U = solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint); + Laminar_Viscosity = solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); + Eddy_Viscosity = solver_container[FLOW_SOL]->GetNodes()->GetEddyViscosity(iPoint); // Should be zero at the wall + Density = U[0]; + for (iDim = 0; iDim < nDim; iDim++) { + Velocity[iDim] = GridVel[iDim]; + } + Energy = U[nDim+1] / Density; + SoundSpeed = sqrt(Gamma*Gamma_Minus_One*(Energy-sq_vel)); + Pressure = (SoundSpeed * SoundSpeed * Density) / Gamma; + ViscDens = (Laminar_Viscosity + Eddy_Viscosity) / Density; + XiDens = Gamma * (Laminar_Viscosity/Prandtl_Lam + Eddy_Viscosity/Prandtl_Turb) / Density; + + /*--- Average of the derivatives of the adjoint variables ---*/ + PsiVar_Grad = nodes->GetGradient(iPoint); + + for (iDim = 0; iDim < nDim; iDim++) { + GradPsiE[iDim] = PsiVar_Grad[nVar-1][iDim]; + for (jDim = 0; jDim < nDim; jDim++) + GradPhi[iDim][jDim] = PsiVar_Grad[iDim+1][jDim]; + } + + /*--- Impose dPhiE_dn = 0 (adiabatic walls with frozen viscosity). Note + that this is where a different adjoint boundary condition for temperature + could be imposed. ---*/ + dPhiE_dn = 0.0; + + if (nDim ==2) { + + /*--- Compute the adjoint stress tensor ---*/ + Sigma_xx = ViscDens * (FOUR3 * GradPhi[0][0] - TWO3 * GradPhi[1][1]); + Sigma_yy = ViscDens * (-TWO3 * GradPhi[0][0] + FOUR3 * GradPhi[1][1]); + Sigma_xy = ViscDens * (GradPhi[1][0] + GradPhi[0][1]); + Sigma_xx5 = ViscDens * ( FOUR3 * Velocity[0] * GradPsiE[0] - TWO3 * Velocity[1] * GradPsiE[1]); + Sigma_yy5 = ViscDens * (- TWO3 * Velocity[0] * GradPsiE[0] + FOUR3 * Velocity[1] * GradPsiE[1]); + Sigma_xy5 = ViscDens * (Velocity[0] * GradPsiE[1] + Velocity[1] * GradPsiE[0]); + Sigma_5 = XiDens * dPhiE_dn; + eta_xx = Sigma_xx + Sigma_xx5; + eta_yy = Sigma_yy + Sigma_yy5; + eta_xy = Sigma_xy + Sigma_xy5; + + /*--- Viscous flux at the wall node (adjoint density & energy only) ---*/ + Res_Visc_i[0] = - (Velocity[0] * Normal[0] * eta_xx + Velocity[1] * Normal[1] * eta_yy + + (Velocity[0] * Normal[1] + Velocity[1] * Normal[0]) * eta_xy + - (sq_vel - Pressure/(Density*Gamma_Minus_One)) * Sigma_5); + Res_Visc_i[1] = 0.0; + Res_Visc_i[2] = 0.0; + + } else if (nDim == 3) { + + /*--- Compute the adjoint stress tensor ---*/ + Sigma_xx = ViscDens * (FOUR3 * GradPhi[0][0] - TWO3 * GradPhi[1][1] - TWO3 * GradPhi[2][2]); + Sigma_yy = ViscDens * (-TWO3 * GradPhi[0][0] + FOUR3 * GradPhi[1][1] - TWO3 * GradPhi[2][2]); + Sigma_zz = ViscDens * (-TWO3 * GradPhi[0][0] - TWO3 * GradPhi[1][1] + FOUR3 * GradPhi[2][2]); + Sigma_xy = ViscDens * (GradPhi[1][0] + GradPhi[0][1]); + Sigma_xz = ViscDens * (GradPhi[2][0] + GradPhi[0][2]); + Sigma_yz = ViscDens * (GradPhi[2][1] + GradPhi[1][2]); + Sigma_xx5 = ViscDens * ( FOUR3 * Velocity[0] * GradPsiE[0] - TWO3 * Velocity[1] * GradPsiE[1] - TWO3 * Velocity[2] * GradPsiE[2]); + Sigma_yy5 = ViscDens * (- TWO3 * Velocity[0] * GradPsiE[0] + FOUR3 * Velocity[1] * GradPsiE[1] - TWO3 * Velocity[2] * GradPsiE[2]); + Sigma_zz5 = ViscDens * (- TWO3 * Velocity[0] * GradPsiE[0] - TWO3 * Velocity[1] * GradPsiE[1] + FOUR3 * Velocity[2] * GradPsiE[2]); + Sigma_xy5 = ViscDens * (Velocity[0] * GradPsiE[1] + Velocity[1] * GradPsiE[0]); + Sigma_xz5 = ViscDens * (Velocity[0] * GradPsiE[2] + Velocity[2] * GradPsiE[0]); + Sigma_yz5 = ViscDens * (Velocity[1] * GradPsiE[2] + Velocity[2] * GradPsiE[1]); + Sigma_5 = XiDens * dPhiE_dn; + eta_xx = Sigma_xx + Sigma_xx5; eta_yy = Sigma_yy + Sigma_yy5; eta_zz = Sigma_zz + Sigma_zz5; + eta_xy = Sigma_xy + Sigma_xy5; eta_xz = Sigma_xz + Sigma_xz5; eta_yz = Sigma_yz + Sigma_yz5; + + /*--- Viscous flux at the wall node (adjoint density & energy only) ---*/ + Res_Visc_i[0] = - (Velocity[0] * Normal[0] * eta_xx + Velocity[1] * Normal[1] * eta_yy + Velocity[2] * Normal[2] * eta_zz + + (Velocity[0] * Normal[1] + Velocity[1] * Normal[0]) * eta_xy + + (Velocity[0] * Normal[2] + Velocity[2] * Normal[0]) * eta_xz + + (Velocity[2] * Normal[1] + Velocity[1] * Normal[2]) * eta_yz + - (sq_vel - Pressure/(Density*Gamma_Minus_One)) * Sigma_5); + Res_Visc_i[1] = 0.0; + Res_Visc_i[2] = 0.0; + Res_Visc_i[3] = 0.0; + } + } + + /*--- Update convective and viscous residuals ---*/ + LinSysRes.AddBlock(iPoint, Res_Conv_i); + LinSysRes.SubtractBlock(iPoint, Res_Visc_i); + if (implicit) { + Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_ii); + } + + } + + } + + for (iDim = 0; iDim < nDim; iDim++) + delete [] Tau[iDim]; + delete [] Tau; + delete [] Psi; + delete [] Velocity; + delete [] Normal; + delete [] GradPsiE; + for (iDim = 0; iDim < nDim; iDim++) + delete [] GradPhi[iDim]; + delete [] GradPhi; + delete [] dPoRho2; +} \ No newline at end of file diff --git a/SU2_CFD/src/solver_adjoint_turbulent.cpp b/SU2_CFD/src/solvers/CAdjTurbSolver.cpp similarity index 96% rename from SU2_CFD/src/solver_adjoint_turbulent.cpp rename to SU2_CFD/src/solvers/CAdjTurbSolver.cpp index bacdcc3502c3..95c1549784e2 100644 --- a/SU2_CFD/src/solver_adjoint_turbulent.cpp +++ b/SU2_CFD/src/solvers/CAdjTurbSolver.cpp @@ -1,12 +1,12 @@ /*! - * \file solution_adjoint_turbulent.cpp - * \brief Main subrotuines for solving adjoint problems (Euler, Navier-Stokes, etc.). + * \file CAdjTurbVariable.cpp + * \brief Main subrotuines for solving turbulent adjoint problems. * \author F. Palacios, A. Bueno, T. Economon * \version 7.0.0 "Blackbird" * * SU2 Project Website: https://su2code.github.io * - * The SU2 Project is maintained by the SU2 Foundation + * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) @@ -26,8 +26,7 @@ */ -#include "../include/solver_structure.hpp" -#include "../include/variables/CAdjTurbVariable.hpp" +#include "../../include/solvers/CAdjTurbSolver.hpp" CAdjTurbSolver::CAdjTurbSolver(void) : CSolver() {} @@ -40,7 +39,7 @@ CAdjTurbSolver::CAdjTurbSolver(CGeometry *geometry, CConfig *config, unsigned sh nDim = geometry->GetnDim(); Gamma = config->GetGamma(); Gamma_Minus_One = Gamma - 1.0; - + /*--- Dimension of the problem ---*/ switch (config->GetKind_Turb_Model()) { case SA : nVar = 1; break; @@ -51,14 +50,14 @@ CAdjTurbSolver::CAdjTurbSolver(CGeometry *geometry, CConfig *config, unsigned sh case SST : nVar = 2; break; case SST_SUST : nVar = 2; break; } - + /*--- Initialize nVarGrad for deallocation ---*/ - + nVarGrad = nVar+1; - + nPoint = geometry->GetnPoint(); nPointDomain = geometry->GetnPointDomain(); - + Residual = new su2double [nVar]; Residual_RMS = new su2double[nVar]; Residual_i = new su2double [nVar]; Residual_j = new su2double [nVar]; Residual_Max = new su2double [nVar]; Point_Max = new unsigned long[nVar]; @@ -67,17 +66,17 @@ CAdjTurbSolver::CAdjTurbSolver(CGeometry *geometry, CConfig *config, unsigned sh Point_Max_Coord[iVar] = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Point_Max_Coord[iVar][iDim] = 0.0; } - + Solution = new su2double [nVar]; Solution_i = new su2double [nVar]; Solution_j = new su2double [nVar]; - + /*--- Define some auxiliar vector related with the geometry ---*/ Vector_i = new su2double[nDim]; Vector_j = new su2double[nDim]; - + /*--- Define some auxiliar vector related with the flow solution ---*/ FlowSolution_i = new su2double [nDim+2]; FlowSolution_j = new su2double [nDim+2]; - + /*--- Point to point Jacobians ---*/ Jacobian_ii = new su2double* [nVar]; Jacobian_ij = new su2double* [nVar]; @@ -89,19 +88,19 @@ CAdjTurbSolver::CAdjTurbSolver(CGeometry *geometry, CConfig *config, unsigned sh Jacobian_ji[iVar] = new su2double [nVar]; Jacobian_jj[iVar] = new su2double [nVar]; } - + /*--- Initialization of the structure of the whole Jacobian ---*/ Jacobian.Initialize(nPoint, nPointDomain, nVar, nVar, true, geometry, config); - + if (config->GetKind_Linear_Solver_Prec() == LINELET) { nLineLets = Jacobian.BuildLineletPreconditioner(geometry, config); if (rank == MASTER_NODE) cout << "Compute linelet structure. " << nLineLets << " elements in each line (average)." << endl; } - + Jacobian.SetValZero(); LinSysSol.Initialize(nPoint, nPointDomain, nVar, 0.0); LinSysRes.Initialize(nPoint, nPointDomain, nVar, 0.0); - + /*--- Computation of gradients by least squares ---*/ if (config->GetLeastSquaresRequired()) { /*--- S matrix := inv(R)*traspose(inv(R)) ---*/ @@ -113,7 +112,7 @@ CAdjTurbSolver::CAdjTurbSolver(CGeometry *geometry, CConfig *config, unsigned sh for (iVar = 0; iVar < nVar+1; iVar++) Cvector[iVar] = new su2double [nDim]; } - + /*--- Far-Field values and initizalization ---*/ bool restart = config->GetRestart(); @@ -125,30 +124,30 @@ CAdjTurbSolver::CAdjTurbSolver(CGeometry *geometry, CConfig *config, unsigned sh su2double dull_val; string filename, AdjExt, text_line; ifstream restart_file; - + /*--- Restart the solution from file information ---*/ string mesh_filename = config->GetSolution_AdjFileName(); filename = config->GetObjFunc_Extension(mesh_filename); restart_file.open(filename.data(), ios::in); - + /*--- In case there is no file ---*/ if (restart_file.fail()) { SU2_MPI::Error(string("There is no adjoint restart file ") + filename, CURRENT_FUNCTION); } - + /*--- Read all lines in the restart file ---*/ long iPoint_Local; unsigned long iPoint_Global = 0; unsigned long iPoint_Global_Local = 0; unsigned short rbuf_NotMatching = 0, sbuf_NotMatching = 0; /*--- The first line is the header ---*/ - + getline (restart_file, text_line); - + for (iPoint_Global = 0; iPoint_Global < geometry->GetGlobal_nPointDomain(); iPoint_Global++ ) { - + getline (restart_file, text_line); - + istringstream point_line(text_line); /*--- Retrieve local index. If this node from the restart file lives @@ -157,7 +156,7 @@ CAdjTurbSolver::CAdjTurbSolver(CGeometry *geometry, CConfig *config, unsigned sh iPoint_Local = geometry->GetGlobal_to_Local_Point(iPoint_Global); if (iPoint_Local > -1) { - + if (nDim == 2) point_line >> index >> dull_val >> dull_val >> dull_val >> dull_val >> dull_val >> dull_val >> Solution[0]; if (nDim == 3) point_line >> index >> dull_val >> dull_val >> dull_val >> dull_val >> dull_val >> dull_val >> dull_val >> dull_val >> Solution[0]; nodes->SetSolution(iPoint_Local,0,Solution[0]); @@ -166,11 +165,11 @@ CAdjTurbSolver::CAdjTurbSolver(CGeometry *geometry, CConfig *config, unsigned sh } } - + /*--- Detect a wrong solution file ---*/ - + if (iPoint_Global_Local < nPointDomain) { sbuf_NotMatching = 1; } - + #ifndef HAVE_MPI rbuf_NotMatching = sbuf_NotMatching; #else @@ -180,16 +179,16 @@ CAdjTurbSolver::CAdjTurbSolver(CGeometry *geometry, CConfig *config, unsigned sh SU2_MPI::Error(string("The solution file ") + filename + string(" doesn't match with the mesh file!\n") + string("It could be empty lines at the end of the file."), CURRENT_FUNCTION); } - + /*--- Close the restart file ---*/ restart_file.close(); } - + /*--- MPI solution ---*/ - + InitiateComms(geometry, config, SOLUTION); CompleteComms(geometry, config, SOLUTION); - + } CAdjTurbSolver::~CAdjTurbSolver(void) { @@ -197,138 +196,138 @@ CAdjTurbSolver::~CAdjTurbSolver(void) { } void CAdjTurbSolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + unsigned long iPoint, iVertex; - + for (iVertex = 0; iVertexnVertex[val_marker]; iVertex++) { iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ if (geometry->node[iPoint]->GetDomain()) { - + Solution[0] = 0.0; - + /*--- Set the solution values and zero the residual ---*/ nodes->SetSolution_Old(iPoint,Solution); LinSysRes.SetBlock_Zero(iPoint); - + /*--- Change rows of the Jacobian (includes 1 in the diagonal) ---*/ Jacobian.DeleteValsRowi(iPoint); - + } } - + } void CAdjTurbSolver::BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + unsigned long iPoint, iVertex; - + for (iVertex = 0; iVertexnVertex[val_marker]; iVertex++) { iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ if (geometry->node[iPoint]->GetDomain()) { - + Solution[0] = 0.0; - + /*--- Set the solution values and zero the residual ---*/ nodes->SetSolution_Old(iPoint,Solution); LinSysRes.SetBlock_Zero(iPoint); - + /*--- Change rows of the Jacobian (includes 1 in the diagonal) ---*/ Jacobian.DeleteValsRowi(iPoint); - + } } - + } void CAdjTurbSolver::BC_Far_Field(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { unsigned long iPoint, iVertex; - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Set Normal ---*/ conv_numerics->SetNormal(geometry->vertex[val_marker][iVertex]->GetNormal()); /*--- Set Conservative variables (for convection) ---*/ su2double* U_i = solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint); conv_numerics->SetConservative(U_i, NULL); - + /*--- Turbulent adjoint variables w/o reconstruction ---*/ su2double* TurbPsi_i = nodes->GetSolution(iPoint); conv_numerics->SetTurbAdjointVar(TurbPsi_i, NULL); - + /*--- Add Residuals and Jacobians ---*/ conv_numerics->ComputeResidual(Residual, Jacobian_ii, NULL, config); LinSysRes.AddBlock(iPoint, Residual); Jacobian.AddBlock(iPoint, iPoint, Jacobian_ii); - + } - + } void CAdjTurbSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output) { unsigned long iPoint; - + for (iPoint = 0; iPoint < nPoint; iPoint++) { - + /*--- Initialize the residual vector ---*/ LinSysRes.SetBlock_Zero(iPoint); - + } - - + + /*--- Initialize the Jacobian matrices ---*/ Jacobian.SetValZero(); - + /*--- Gradient of the adjoint turbulent variables ---*/ if (config->GetKind_Gradient_Method() == GREEN_GAUSS) SetSolution_Gradient_GG(geometry, config); if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) SetSolution_Gradient_LS(geometry, config); - + /*--- Gradient of the turbulent variables ---*/ if (config->GetKind_Gradient_Method() == GREEN_GAUSS) solver_container[TURB_SOL]->SetSolution_Gradient_GG(geometry, config); if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) solver_container[TURB_SOL]->SetSolution_Gradient_LS(geometry, config); - + } void CAdjTurbSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short iMesh) { - + unsigned long iEdge, iPoint, jPoint; su2double *U_i, *U_j, *TurbPsi_i, *TurbPsi_j, **TurbVar_Grad_i, **TurbVar_Grad_j; - + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - + /*--- Points in edge ---*/ iPoint = geometry->edge[iEdge]->GetNode(0); jPoint = geometry->edge[iEdge]->GetNode(1); - + /*--- Conservative variables w/o reconstruction ---*/ U_i = solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint); U_j = solver_container[FLOW_SOL]->GetNodes()->GetSolution(jPoint); numerics->SetConservative(U_i, U_j); - + /*--- Set normal vectors and length ---*/ numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); - + /*--- Turbulent adjoint variables w/o reconstruction ---*/ TurbPsi_i = nodes->GetSolution(iPoint); TurbPsi_j = nodes->GetSolution(jPoint); numerics->SetTurbAdjointVar(TurbPsi_i, TurbPsi_j); - + /*--- Gradient of turbulent variables w/o reconstruction ---*/ TurbVar_Grad_i = solver_container[TURB_SOL]->GetNodes()->GetGradient(iPoint); TurbVar_Grad_j = solver_container[TURB_SOL]->GetNodes()->GetGradient(jPoint); numerics->SetTurbVarGradient(TurbVar_Grad_i, TurbVar_Grad_j); - + /*--- Set normal vectors and length ---*/ numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); - + numerics->ComputeResidual(Residual_i, Residual_j, Jacobian_ii, Jacobian_ij, Jacobian_ji, Jacobian_jj, config); - + /*--- Add and Subtract Residual ---*/ LinSysRes.AddBlock(iPoint, Residual_i); LinSysRes.AddBlock(jPoint, Residual_j); @@ -336,88 +335,88 @@ void CAdjTurbSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_conta Jacobian.AddBlock(iPoint, jPoint, Jacobian_ij); Jacobian.AddBlock(jPoint, iPoint, Jacobian_ji); Jacobian.AddBlock(jPoint, jPoint, Jacobian_jj); - + } - + } void CAdjTurbSolver::Viscous_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short iMesh, unsigned short iRKStep) { unsigned long iEdge, iPoint, jPoint; su2double *Coord_i, *Coord_j; - + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - + /*--- Points in edge ---*/ iPoint = geometry->edge[iEdge]->GetNode(0); jPoint = geometry->edge[iEdge]->GetNode(1); - + /*--- Points coordinates, and set normal vectors and length ---*/ Coord_i = geometry->node[iPoint]->GetCoord(); Coord_j = geometry->node[jPoint]->GetCoord(); numerics->SetCoord(Coord_i, Coord_j); numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); - + /*--- Conservative variables w/o reconstruction, turbulent variables w/o reconstruction, and turbulent adjoint variables w/o reconstruction ---*/ numerics->SetConservative(solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint), solver_container[FLOW_SOL]->GetNodes()->GetSolution(jPoint)); numerics->SetTurbVar(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint), solver_container[TURB_SOL]->GetNodes()->GetSolution(jPoint)); numerics->SetTurbAdjointVar(nodes->GetSolution(iPoint), nodes->GetSolution(jPoint)); - + /*--- Viscosity ---*/ numerics->SetLaminarViscosity(solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint), solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(jPoint)); - + /*--- Turbulent adjoint variables w/o reconstruction ---*/ numerics->SetTurbAdjointGradient(nodes->GetGradient(iPoint), nodes->GetGradient(jPoint)); - + /*--- Compute residual in a non-conservative way, and update ---*/ numerics->ComputeResidual(Residual_i, Residual_j, Jacobian_ii, Jacobian_ij, Jacobian_ji, Jacobian_jj, config); - + /*--- Update adjoint viscous residual ---*/ LinSysRes.AddBlock(iPoint, Residual_i); LinSysRes.AddBlock(jPoint, Residual_j); - + Jacobian.AddBlock(iPoint, iPoint, Jacobian_ii); Jacobian.AddBlock(iPoint, jPoint, Jacobian_ij); Jacobian.AddBlock(jPoint, iPoint, Jacobian_ji); Jacobian.AddBlock(jPoint, jPoint, Jacobian_jj); - + } - + } void CAdjTurbSolver::Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CNumerics *second_numerics, CConfig *config, unsigned short iMesh) { unsigned long iPoint; su2double *U_i, **GradPrimVar_i, *TurbVar_i; su2double **TurbVar_Grad_i, *TurbPsi_i, **PsiVar_Grad_i; // Gradients - + /*--- Piecewise source term ---*/ for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /*--- Conservative variables w/o reconstruction ---*/ U_i = solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint); numerics->SetConservative(U_i, NULL); - + /*--- Gradient of primitive variables w/o reconstruction ---*/ GradPrimVar_i = solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint); numerics->SetPrimVarGradient(GradPrimVar_i, NULL); - + /*--- Laminar viscosity of the fluid ---*/ numerics->SetLaminarViscosity(solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint), 0.0); - + /*--- Turbulent variables w/o reconstruction ---*/ TurbVar_i = solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint); numerics->SetTurbVar(TurbVar_i, NULL); - + /*--- Gradient of Turbulent Variables w/o reconstruction ---*/ TurbVar_Grad_i = solver_container[TURB_SOL]->GetNodes()->GetGradient(iPoint); numerics->SetTurbVarGradient(TurbVar_Grad_i, NULL); - + /*--- Turbulent adjoint variables w/o reconstruction ---*/ TurbPsi_i = nodes->GetSolution(iPoint); numerics->SetTurbAdjointVar(TurbPsi_i, NULL); - + /*--- Gradient of Adjoint flow variables w/o reconstruction (for non-conservative terms depending on gradients of flow adjoint vars.) ---*/ PsiVar_Grad_i = solver_container[ADJFLOW_SOL]->GetNodes()->GetGradient(iPoint); @@ -426,37 +425,37 @@ void CAdjTurbSolver::Source_Residual(CGeometry *geometry, CSolver **solver_conta /*--- Set volume and distances to the surface ---*/ numerics->SetVolume(geometry->node[iPoint]->GetVolume()); numerics->SetDistance(geometry->node[iPoint]->GetWall_Distance(), 0.0); - + /*--- Add and Subtract Residual ---*/ numerics->ComputeResidual(Residual, Jacobian_ii, NULL, config); LinSysRes.AddBlock(iPoint, Residual); Jacobian.AddBlock(iPoint, iPoint, Jacobian_ii); - + } - + // /*--- Conservative Source Term ---*/ // su2double **TurbVar_Grad_j; // unsigned long jPoint, iEdge; // // for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { -// +// // /*--- Points in edge ---*/ // iPoint = geometry->edge[iEdge]->GetNode(0); // jPoint = geometry->edge[iEdge]->GetNode(1); -// +// // /*--- Gradient of turbulent variables w/o reconstruction ---*/ // TurbVar_Grad_i = solver_container[TURB_SOL]->GetNodes()->GetGradient(iPoint); // TurbVar_Grad_j = solver_container[TURB_SOL]->GetNodes()->GetGradient(jPoint); // second_numerics->SetTurbVarGradient(TurbVar_Grad_i, TurbVar_Grad_j); -// +// // /*--- Turbulent adjoint variables w/o reconstruction ---*/ // TurbPsi_i = nodes->GetSolution(iPoint); // TurbPsi_j = nodes->GetSolution(jPoint); // second_numerics->SetTurbAdjointVar(TurbPsi_i, TurbPsi_j); -// +// // /*--- Set normal vectors and length ---*/ // second_numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); -// +// // /*--- Add and Subtract Residual ---*/ // second_numerics->ComputeResidual(Residual, Jacobian_ii, Jacobian_jj, config); // LinSysRes.AddBlock(iPoint, Residual); @@ -465,40 +464,40 @@ void CAdjTurbSolver::Source_Residual(CGeometry *geometry, CSolver **solver_conta // Jacobian.AddBlock(iPoint, jPoint, Jacobian_jj); // Jacobian.SubtractBlock(jPoint, iPoint, Jacobian_ii); // Jacobian.SubtractBlock(jPoint, jPoint, Jacobian_jj); -// +// // } - + } void CAdjTurbSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { - + unsigned short iVar; unsigned long iPoint, total_index; su2double Delta, Vol; - + /*--- Set maximum residual to zero ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { SetRes_RMS(iVar, 0.0); SetRes_Max(iVar, 0.0, 0); } - + /*--- Build implicit system ---*/ - + for (iPoint = 0; iPoint < nPoint; iPoint++) { - + /*--- Read the volume ---*/ - + Vol = geometry->node[iPoint]->GetVolume(); - + /*--- Modify matrix diagonal to assure diagonal dominance ---*/ - + Delta = Vol / (config->GetCFLRedCoeff_AdjTurb()*solver_container[FLOW_SOL]->GetNodes()->GetDelta_Time(iPoint)); - + Jacobian.AddVal2Diag(iPoint, Delta); - + /*--- Right hand side of the system (-Residual) and initial guess (x = 0) ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { total_index = iPoint*nVar+iVar; LinSysRes[total_index] = -LinSysRes[total_index]; @@ -506,11 +505,11 @@ void CAdjTurbSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solv AddRes_RMS(iVar, LinSysRes[total_index]*LinSysRes[total_index]); AddRes_Max(iVar, fabs(LinSysRes[total_index]), geometry->node[iPoint]->GetGlobalIndex(), geometry->node[iPoint]->GetCoord()); } - + } - + /*--- Initialize residual and solution at the ghost points ---*/ - + for (iPoint = nPointDomain; iPoint < nPoint; iPoint++) { for (iVar = 0; iVar < nVar; iVar++) { total_index = iPoint*nVar + iVar; @@ -518,25 +517,25 @@ void CAdjTurbSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solv LinSysSol[total_index] = 0.0; } } - + /*--- Solve or smooth the linear system ---*/ - + System.Solve(Jacobian, LinSysRes, LinSysSol, geometry, config); - + /*--- Update solution (system written in terms of increments) ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { for (iVar = 0; iVar < nVar; iVar++) nodes->AddSolution(iPoint,iVar, LinSysSol[iPoint*nVar+iVar]); } - + /*--- MPI solution ---*/ - + InitiateComms(geometry, config, SOLUTION); CompleteComms(geometry, config, SOLUTION); - + /*--- Compute the root mean square residual ---*/ - + SetResidual_RMS(geometry, config); - + } diff --git a/SU2_CFD/src/solvers/CBaselineSolver.cpp b/SU2_CFD/src/solvers/CBaselineSolver.cpp new file mode 100644 index 000000000000..4459f6f1f411 --- /dev/null +++ b/SU2_CFD/src/solvers/CBaselineSolver.cpp @@ -0,0 +1,559 @@ +/*! + * \file CBaselineSolver.cpp + * \brief Main subroutines for CBaselineSolver class. + * \author F. Palacios, T. Economon + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + + +#include "../../include/solvers/CBaselineSolver.hpp" +#include "../../../Common/include/toolboxes/printing_toolbox.hpp" + +CBaselineSolver::CBaselineSolver(void) : CSolver() { } + +CBaselineSolver::CBaselineSolver(CGeometry *geometry, CConfig *config) { + + nPoint = geometry->GetnPoint(); + + /*--- Define geometry constants in the solver structure ---*/ + + nDim = geometry->GetnDim(); + + /*--- Routines to access the number of variables and string names. ---*/ + + SetOutputVariables(geometry, config); + + /*--- Initialize a zero solution and instantiate the CVariable class. ---*/ + + Solution = new su2double[nVar]; + for (unsigned short iVar = 0; iVar < nVar; iVar++) Solution[iVar] = 0.0; + + nodes = new CBaselineVariable(nPoint, nVar, config); + SetBaseClassPointerToNodes(); + + dynamic_grid = config->GetDynamic_Grid(); +} + +CBaselineSolver::CBaselineSolver(CGeometry *geometry, CConfig *config, unsigned short val_nvar, vector field_names) { + + /*--- Define geometry constants in the solver structure ---*/ + + nPoint = geometry->GetnPoint(); + nDim = geometry->GetnDim(); + nVar = val_nvar; + fields = field_names; + + /*--- Allocate the node variables ---*/ + + nodes = new CBaselineVariable(nPoint, nVar, config); + SetBaseClassPointerToNodes(); + + dynamic_grid = config->GetDynamic_Grid(); + +} + +void CBaselineSolver::SetOutputVariables(CGeometry *geometry, CConfig *config) { + + /*--- Open the restart file and extract the nVar and field names. ---*/ + + string Tag, text_line; + + ifstream restart_file; + string filename; + + /*--- Retrieve filename from config ---*/ + + if (config->GetContinuous_Adjoint() || config->GetDiscrete_Adjoint()) { + filename = config->GetSolution_AdjFileName(); + filename = config->GetObjFunc_Extension(filename); + } else { + filename = config->GetSolution_FileName(); + } + + + /*--- Read only the number of variables in the restart file. ---*/ + + if (config->GetRead_Binary_Restart()) { + + /*--- Multizone problems require the number of the zone to be appended. ---*/ + + filename = config->GetFilename(filename, ".dat", config->GetTimeIter()); + + char fname[100]; + strcpy(fname, filename.c_str()); + int nVar_Buf = 5; + int var_buf[5]; + +#ifndef HAVE_MPI + + /*--- Serial binary input. ---*/ + + FILE *fhw; + fhw = fopen(fname,"rb"); + size_t ret; + + /*--- Error check for opening the file. ---*/ + + if (!fhw) { + SU2_MPI::Error(string("Unable to open SU2 restart file ") + string(fname), CURRENT_FUNCTION); + } + + /*--- First, read the number of variables and points. ---*/ + + ret = fread(var_buf, sizeof(int), nVar_Buf, fhw); + if (ret != (unsigned long)nVar_Buf) { + SU2_MPI::Error("Error reading restart file.", CURRENT_FUNCTION); + } + + /*--- Check that this is an SU2 binary file. SU2 binary files + have the hex representation of "SU2" as the first int in the file. ---*/ + + if (var_buf[0] != 535532) { + SU2_MPI::Error(string("File ") + string(fname) + string(" is not a binary SU2 restart file.\n") + + string("SU2 reads/writes binary restart files by default.\n") + + string("Note that backward compatibility for ASCII restart files is\n") + + string("possible with the WRT_BINARY_RESTART / READ_BINARY_RESTART options."), CURRENT_FUNCTION); + } + + /*--- Close the file. ---*/ + + fclose(fhw); + + /*--- Set the number of variables, one per field in the + restart file (without including the PointID) ---*/ + + nVar = var_buf[1]; +#else + + /*--- Parallel binary input using MPI I/O. ---*/ + + MPI_File fhw; + int ierr; + MPI_Offset disp; + unsigned short iVar; + unsigned long index, iChar; + string field_buf; + char str_buf[CGNS_STRING_SIZE]; + + /*--- All ranks open the file using MPI. ---*/ + + ierr = MPI_File_open(MPI_COMM_WORLD, fname, MPI_MODE_RDONLY, MPI_INFO_NULL, &fhw); + + /*--- Error check opening the file. ---*/ + + if (ierr) { + SU2_MPI::Error(string("Unable to open SU2 restart file ") + string(fname), CURRENT_FUNCTION); + } + + /*--- First, read the number of variables and points (i.e., cols and rows), + which we will need in order to read the file later. Also, read the + variable string names here. Only the master rank reads the header. ---*/ + + if (rank == MASTER_NODE) { + MPI_File_read(fhw, var_buf, nVar_Buf, MPI_INT, MPI_STATUS_IGNORE); + } + + /*--- Broadcast the number of variables to all procs and store more clearly. ---*/ + + SU2_MPI::Bcast(var_buf, nVar_Buf, MPI_INT, MASTER_NODE, MPI_COMM_WORLD); + + /*--- Check that this is an SU2 binary file. SU2 binary files + have the hex representation of "SU2" as the first int in the file. ---*/ + + if (var_buf[0] != 535532) { + SU2_MPI::Error(string("File ") + string(fname) + string(" is not a binary SU2 restart file.\n") + + string("SU2 reads/writes binary restart files by default.\n") + + string("Note that backward compatibility for ASCII restart files is\n") + + string("possible with the WRT_BINARY_RESTART / READ_BINARY_RESTART options."), CURRENT_FUNCTION); + } + + + + /*--- Set the number of variables, one per field in the + restart file (without including the PointID) ---*/ + + nVar = var_buf[1]; + + /*--- Read the variable names from the file. Note that we are adopting a + fixed length of 33 for the string length to match with CGNS. This is + needed for when we read the strings later. ---*/ + + char *mpi_str_buf = new char[nVar*CGNS_STRING_SIZE]; + if (rank == MASTER_NODE) { + disp = nVar_Buf*sizeof(int); + MPI_File_read_at(fhw, disp, mpi_str_buf, nVar*CGNS_STRING_SIZE, + MPI_CHAR, MPI_STATUS_IGNORE); + } + + /*--- Broadcast the string names of the variables. ---*/ + + SU2_MPI::Bcast(mpi_str_buf, nVar*CGNS_STRING_SIZE, MPI_CHAR, + MASTER_NODE, MPI_COMM_WORLD); + + fields.push_back("Point_ID"); + + for (iVar = 0; iVar < nVar; iVar++) { + index = iVar*CGNS_STRING_SIZE; + field_buf.append("\""); + for (iChar = 0; iChar < (unsigned long)CGNS_STRING_SIZE; iChar++) { + str_buf[iChar] = mpi_str_buf[index + iChar]; + } + field_buf.append(str_buf); + field_buf.append("\""); + fields.push_back(field_buf.c_str()); + field_buf.clear(); + } + + /*--- All ranks close the file after writing. ---*/ + + MPI_File_close(&fhw); + +#endif + } else { + + /*--- Multizone problems require the number of the zone to be appended. ---*/ + + filename = config->GetFilename(filename, ".csv", config->GetTimeIter()); + + /*--- First, check that this is not a binary restart file. ---*/ + + char fname[100]; + strcpy(fname, filename.c_str()); + int magic_number; + +#ifndef HAVE_MPI + + /*--- Serial binary input. ---*/ + + FILE *fhw; + fhw = fopen(fname,"rb"); + size_t ret; + + /*--- Error check for opening the file. ---*/ + + if (!fhw) { + SU2_MPI::Error(string("Unable to open SU2 restart file ") + string(fname), CURRENT_FUNCTION); + } + + /*--- Attempt to read the first int, which should be our magic number. ---*/ + + ret = fread(&magic_number, sizeof(int), 1, fhw); + if (ret != 1) { + SU2_MPI::Error("Error reading restart file.", CURRENT_FUNCTION); + } + + /*--- Check that this is an SU2 binary file. SU2 binary files + have the hex representation of "SU2" as the first int in the file. ---*/ + + if (magic_number == 535532) { + SU2_MPI::Error(string("File ") + string(fname) + string(" is a binary SU2 restart file, expected ASCII.\n") + + string("SU2 reads/writes binary restart files by default.\n") + + string("Note that backward compatibility for ASCII restart files is\n") + + string("possible with the WRT_BINARY_RESTART / READ_BINARY_RESTART options."), CURRENT_FUNCTION); + } + + fclose(fhw); + +#else + + /*--- Parallel binary input using MPI I/O. ---*/ + + MPI_File fhw; + int ierr; + + /*--- All ranks open the file using MPI. ---*/ + + ierr = MPI_File_open(MPI_COMM_WORLD, fname, MPI_MODE_RDONLY, MPI_INFO_NULL, &fhw); + + /*--- Error check opening the file. ---*/ + + if (ierr) { + SU2_MPI::Error(string("Unable to open SU2 restart file ") + string(fname), CURRENT_FUNCTION); + } + + /*--- Have the master attempt to read the magic number. ---*/ + + if (rank == MASTER_NODE) + MPI_File_read(fhw, &magic_number, 1, MPI_INT, MPI_STATUS_IGNORE); + + /*--- Broadcast the number of variables to all procs and store clearly. ---*/ + + SU2_MPI::Bcast(&magic_number, 1, MPI_INT, MASTER_NODE, MPI_COMM_WORLD); + + /*--- Check that this is an SU2 binary file. SU2 binary files + have the hex representation of "SU2" as the first int in the file. ---*/ + + if (magic_number == 535532) { + SU2_MPI::Error(string("File ") + string(fname) + string(" is a binary SU2 restart file, expected ASCII.\n") + + string("SU2 reads/writes binary restart files by default.\n") + + string("Note that backward compatibility for ASCII restart files is\n") + + string("possible with the WRT_BINARY_RESTART / READ_BINARY_RESTART options."), CURRENT_FUNCTION); + } + + MPI_File_close(&fhw); + +#endif + + /*--- Open the restart file ---*/ + + restart_file.open(filename.data(), ios::in); + + /*--- In case there is no restart file ---*/ + + if (restart_file.fail()) { + SU2_MPI::Error(string("SU2 solution file ") + filename + string(" not found"), CURRENT_FUNCTION); + } + + /*--- Identify the number of fields (and names) in the restart file ---*/ + + getline (restart_file, text_line); + + fields = PrintingToolbox::split(text_line, ','); + + for (unsigned short iField = 0; iField < fields.size(); iField++){ + PrintingToolbox::trim(fields[iField]); + } + + /*--- Close the file (the solution date is read later). ---*/ + + restart_file.close(); + + /*--- Set the number of variables, one per field in the + restart file (without including the PointID) ---*/ + + nVar = fields.size() - 1; + + } + +} + +void CBaselineSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo) { + + /*--- Restart the solution from file information ---*/ + + string filename; + unsigned long index; + unsigned short iDim, iVar; + bool adjoint = ( config->GetContinuous_Adjoint() || config->GetDiscrete_Adjoint() ); + unsigned short iInst = config->GetiInst(); + bool steady_restart = config->GetSteadyRestart(); + unsigned short turb_model = config->GetKind_Turb_Model(); + + su2double *Coord = new su2double [nDim]; + for (iDim = 0; iDim < nDim; iDim++) + Coord[iDim] = 0.0; + + /*--- Skip coordinates ---*/ + + unsigned short skipVars = geometry[iInst]->GetnDim(); + + /*--- Retrieve filename from config ---*/ + + if (adjoint) { + filename = config->GetSolution_AdjFileName(); + filename = config->GetObjFunc_Extension(filename); + } else { + filename = config->GetSolution_FileName(); + } + + filename = config->GetFilename(filename, "", val_iter); + + /*--- Output the file name to the console. ---*/ + + if (rank == MASTER_NODE) + cout << "Reading and storing the solution from " << filename + << "." << endl; + + /*--- Read the restart data from either an ASCII or binary SU2 file. ---*/ + + if (config->GetRead_Binary_Restart()) { + Read_SU2_Restart_Binary(geometry[iInst], config, filename); + } else { + Read_SU2_Restart_ASCII(geometry[iInst], config, filename); + } + + int counter = 0; + long iPoint_Local = 0; unsigned long iPoint_Global = 0; + + /*--- Load data from the restart into correct containers. ---*/ + + for (iPoint_Global = 0; iPoint_Global < geometry[iInst]->GetGlobal_nPointDomain(); iPoint_Global++ ) { + + /*--- Retrieve local index. If this node from the restart file lives + on the current processor, we will load and instantiate the vars. ---*/ + + iPoint_Local = geometry[iInst]->GetGlobal_to_Local_Point(iPoint_Global); + + if (iPoint_Local > -1) { + + /*--- We need to store this point's data, so jump to the correct + offset in the buffer of data from the restart file and load it. ---*/ + + index = counter*Restart_Vars[1]; + for (iVar = 0; iVar < nVar; iVar++) Solution[iVar] = Restart_Data[index+iVar]; + nodes->SetSolution(iPoint_Local,Solution); + + /*--- For dynamic meshes, read in and store the + grid coordinates and grid velocities for each node. ---*/ + + if (dynamic_grid && val_update_geo) { + + /*--- First, remove any variables for the turbulence model that + appear in the restart file before the grid velocities. ---*/ + + if (turb_model == SA || turb_model == SA_NEG) { + index++; + } else if (turb_model == SST) { + index+=2; + } + + /*--- Read in the next 2 or 3 variables which are the grid velocities ---*/ + /*--- If we are restarting the solution from a previously computed static calculation (no grid movement) ---*/ + /*--- the grid velocities are set to 0. This is useful for FSI computations ---*/ + + su2double GridVel[3] = {0.0,0.0,0.0}; + if (!steady_restart) { + + /*--- Rewind the index to retrieve the Coords. ---*/ + index = counter*Restart_Vars[1]; + for (iDim = 0; iDim < nDim; iDim++) { Coord[iDim] = Restart_Data[index+iDim]; } + + /*--- Move the index forward to get the grid velocities. ---*/ + index = counter*Restart_Vars[1] + skipVars + nVar; + for (iDim = 0; iDim < nDim; iDim++) { GridVel[iDim] = Restart_Data[index+iDim]; } + } + + for (iDim = 0; iDim < nDim; iDim++) { + geometry[iInst]->node[iPoint_Local]->SetCoord(iDim, Coord[iDim]); + geometry[iInst]->node[iPoint_Local]->SetGridVel(iDim, GridVel[iDim]); + } + } + + /*--- Increment the overall counter for how many points have been loaded. ---*/ + counter++; + } + + } + + /*--- MPI solution ---*/ + + InitiateComms(geometry[iInst], config, SOLUTION); + CompleteComms(geometry[iInst], config, SOLUTION); + + /*--- Update the geometry for flows on dynamic meshes ---*/ + + if (dynamic_grid && val_update_geo) { + + /*--- Communicate the new coordinates and grid velocities at the halos ---*/ + + geometry[iInst]->InitiateComms(geometry[iInst], config, COORDINATES); + geometry[iInst]->CompleteComms(geometry[iInst], config, COORDINATES); + + geometry[iInst]->InitiateComms(geometry[iInst], config, GRID_VELOCITY); + geometry[iInst]->CompleteComms(geometry[iInst], config, GRID_VELOCITY); + + } + + delete [] Coord; + + /*--- Delete the class memory that is used to load the restart. ---*/ + + if (Restart_Vars != NULL) delete [] Restart_Vars; + if (Restart_Data != NULL) delete [] Restart_Data; + Restart_Vars = NULL; Restart_Data = NULL; + +} + +void CBaselineSolver::LoadRestart_FSI(CGeometry *geometry, CConfig *config, int val_iter) { + + /*--- Restart the solution from file information ---*/ + string filename; + unsigned long index; + unsigned short iVar; + bool adjoint = (config->GetContinuous_Adjoint() || config->GetDiscrete_Adjoint()); + + /*--- Retrieve filename from config ---*/ + if (adjoint) { + filename = config->GetSolution_AdjFileName(); + filename = config->GetObjFunc_Extension(filename); + } else { + filename = config->GetSolution_FileName(); + } + + /*--- Multizone problems require the number of the zone to be appended. ---*/ + + filename = config->GetFilename(filename, "", val_iter); + + /*--- Output the file name to the console. ---*/ + + if (rank == MASTER_NODE) + cout << "Reading and storing the solution from " << filename + << "." << endl; + + /*--- Read the restart data from either an ASCII or binary SU2 file. ---*/ + + if (config->GetRead_Binary_Restart()) { + Read_SU2_Restart_Binary(geometry, config, filename); + } else { + Read_SU2_Restart_ASCII(geometry, config, filename); + } + + unsigned short nVar_Local = Restart_Vars[1]; + su2double *Solution_Local = new su2double[nVar_Local]; + + int counter = 0; + long iPoint_Local = 0; unsigned long iPoint_Global = 0; + + /*--- Load data from the restart into correct containers. ---*/ + + for (iPoint_Global = 0; iPoint_Global < geometry->GetGlobal_nPointDomain(); iPoint_Global++ ) { + + /*--- Retrieve local index. If this node from the restart file lives + on the current processor, we will load and instantiate the vars. ---*/ + + iPoint_Local = geometry->GetGlobal_to_Local_Point(iPoint_Global); + + if (iPoint_Local > -1) { + + /*--- We need to store this point's data, so jump to the correct + offset in the buffer of data from the restart file and load it. ---*/ + + index = counter*Restart_Vars[1]; + for (iVar = 0; iVar < nVar_Local; iVar++) Solution[iVar] = Restart_Data[index+iVar]; + nodes->SetSolution(iPoint_Local,Solution); + + /*--- Increment the overall counter for how many points have been loaded. ---*/ + + counter++; + + } + + } + + delete [] Solution_Local; + +} + +CBaselineSolver::~CBaselineSolver(void) { + if (nodes != nullptr) delete nodes; +} diff --git a/SU2_CFD/src/solvers/CBaselineSolver_FEM.cpp b/SU2_CFD/src/solvers/CBaselineSolver_FEM.cpp new file mode 100644 index 000000000000..ceb8ec70b715 --- /dev/null +++ b/SU2_CFD/src/solvers/CBaselineSolver_FEM.cpp @@ -0,0 +1,388 @@ +/*! + * \file CBaselineSolver_FEM.cpp + * \brief Main subroutines for CBaselineSolver_FEM class. + * \author F. Palacios, T. Economon + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + + +#include "../../include/solvers/CBaselineSolver_FEM.hpp" + + +CBaselineSolver_FEM::CBaselineSolver_FEM(void) : CSolver() { } + +CBaselineSolver_FEM::CBaselineSolver_FEM(CGeometry *geometry, CConfig *config) { + + /*--- Define geometry constants in the solver structure ---*/ + + nDim = geometry->GetnDim(); + + /*--- Create an object of the class CMeshFEM_DG and retrieve the necessary + geometrical information for the FEM DG solver. If necessary, it is + possible to increase nMatchingFacesWithHaloElem a bit, such that + the computation of the external faces may be more efficient when + using multiple threads. ---*/ + + CMeshFEM_DG *DGGeometry = dynamic_cast(geometry); + + nVolElemTot = DGGeometry->GetNVolElemTot(); + nVolElemOwned = DGGeometry->GetNVolElemOwned(); + volElem = DGGeometry->GetVolElem(); + + /*--- Routines to access the number of variables and string names. ---*/ + + SetOutputVariables(geometry, config); + + /*--- Determine the total number of DOFs stored on this rank and allocate the memory + to store the conservative variables. ---*/ + nDOFsLocOwned = 0; + for(unsigned long i=0; iSetnPointDomain(nDOFsLocOwned); + geometry->SetGlobal_nPointDomain(nDOFsGlobal); + + /*--- Initialize the solution to zero. ---*/ + + unsigned long ii = 0; + for(unsigned long i=0; iGetTimeIter(); + + ifstream restart_file; + string filename; + + /*--- Retrieve filename from config ---*/ + + filename = config->GetSolution_FileName(); + + /*--- Unsteady problems require an iteration number to be appended. ---*/ + + if (config->GetTime_Domain()) { + filename = config->GetUnsteady_FileName(filename, SU2_TYPE::Int(TimeIter), ".dat"); + } + + /*--- Read only the number of variables in the restart file. ---*/ + + if (config->GetRead_Binary_Restart()) { + + int nVar_Buf = 5; + int var_buf[5]; + +#ifndef HAVE_MPI + + /*--- Serial binary input. ---*/ + + FILE *fhw; + fhw = fopen(filename.c_str(),"rb"); + size_t ret; + + /*--- Error check for opening the file. ---*/ + + if (!fhw) + SU2_MPI::Error(string("Unable to open SU2 restart file ") + filename, + CURRENT_FUNCTION); + + /*--- First, read the number of variables and points. ---*/ + + ret = fread(var_buf, sizeof(int), nVar_Buf, fhw); + if (ret != (unsigned long)nVar_Buf) { + SU2_MPI::Error("Error reading restart file.", CURRENT_FUNCTION); + } + + /*--- Check that this is an SU2 binary file. SU2 binary files + have the hex representation of "SU2" as the first int in the file. ---*/ + + if (var_buf[0] != 535532) + SU2_MPI::Error(string("File ") + filename + string(" is not a binary SU2 restart file.\n") + + string("SU2 reads/writes binary restart files by default.\n") + + string("Note that backward compatibility for ASCII restart files is\n") + + string("possible with the WRT_BINARY_RESTART / READ_BINARY_RESTART options."), CURRENT_FUNCTION); + + /*--- Close the file. ---*/ + + fclose(fhw); + +#else + + /*--- Parallel binary input using MPI I/O. ---*/ + + MPI_File fhw; + int ierr; + + /*--- All ranks open the file using MPI. ---*/ + + char fname[100]; + strcpy(fname, filename.c_str()); + ierr = MPI_File_open(MPI_COMM_WORLD, fname, MPI_MODE_RDONLY, MPI_INFO_NULL, &fhw); + + /*--- Error check opening the file. ---*/ + + if (ierr) + SU2_MPI::Error(string("Unable to open SU2 restart file ") + filename, + CURRENT_FUNCTION); + + /*--- First, read the number of variables and points (i.e., cols and rows), + which we will need in order to read the file later. Also, read the + variable string names here. Only the master rank reads the header. ---*/ + + if (rank == MASTER_NODE) + MPI_File_read(fhw, var_buf, nVar_Buf, MPI_INT, MPI_STATUS_IGNORE); + + /*--- Broadcast the number of variables to all procs and store more clearly. ---*/ + + SU2_MPI::Bcast(var_buf, nVar_Buf, MPI_INT, MASTER_NODE, MPI_COMM_WORLD); + + /*--- Check that this is an SU2 binary file. SU2 binary files + have the hex representation of "SU2" as the first int in the file. ---*/ + + if (var_buf[0] != 535532) + SU2_MPI::Error(string("File ") + filename + string(" is not a binary SU2 restart file.\n") + + string("SU2 reads/writes binary restart files by default.\n") + + string("Note that backward compatibility for ASCII restart files is\n") + + string("possible with the WRT_BINARY_RESTART / READ_BINARY_RESTART options."), CURRENT_FUNCTION); + + /*--- All ranks close the file after writing. ---*/ + + MPI_File_close(&fhw); + +#endif + + /*--- Set the number of variables, one per field in the + restart file (without including the PointID) ---*/ + + nVar = var_buf[1]; + + } else { + + /*--- First, check that this is not a binary restart file. ---*/ + + int magic_number; + +#ifndef HAVE_MPI + + /*--- Serial binary input. ---*/ + + FILE *fhw; + fhw = fopen(filename.c_str(), "rb"); + size_t ret; + + /*--- Error check for opening the file. ---*/ + + if (!fhw) + SU2_MPI::Error(string("Unable to open SU2 restart file ") + filename, + CURRENT_FUNCTION); + + /*--- Attempt to read the first int, which should be our magic number. ---*/ + + ret = fread(&magic_number, sizeof(int), 1, fhw); + if (ret != 1) { + SU2_MPI::Error("Error reading restart file.", CURRENT_FUNCTION); + } + + /*--- Check that this is an SU2 binary file. SU2 binary files + have the hex representation of "SU2" as the first int in the file. ---*/ + + if (magic_number == 535532) + SU2_MPI::Error(string("File ") + filename + string(" is a binary SU2 restart file, expected ASCII.\n") + + string("SU2 reads/writes binary restart files by default.\n") + + string("Note that backward compatibility for ASCII restart files is\n") + + string("possible with the WRT_BINARY_RESTART / READ_BINARY_RESTART options."), CURRENT_FUNCTION); + fclose(fhw); + +#else + + /*--- Parallel binary input using MPI I/O. ---*/ + + MPI_File fhw; + int ierr; + + /*--- All ranks open the file using MPI. ---*/ + + char fname[100]; + strcpy(fname, filename.c_str()); + ierr = MPI_File_open(MPI_COMM_WORLD, fname, MPI_MODE_RDONLY, MPI_INFO_NULL, &fhw); + + /*--- Error check opening the file. ---*/ + + if (ierr) + SU2_MPI::Error(string("Unable to open SU2 restart file ") + filename, + CURRENT_FUNCTION); + + /*--- Have the master attempt to read the magic number. ---*/ + + if (rank == MASTER_NODE) + MPI_File_read(fhw, &magic_number, 1, MPI_INT, MPI_STATUS_IGNORE); + + /*--- Broadcast the number of variables to all procs and store clearly. ---*/ + + SU2_MPI::Bcast(&magic_number, 1, MPI_INT, MASTER_NODE, MPI_COMM_WORLD); + + /*--- Check that this is an SU2 binary file. SU2 binary files + have the hex representation of "SU2" as the first int in the file. ---*/ + + if (magic_number == 535532) + SU2_MPI::Error(string("File ") + filename + string(" is a binary SU2 restart file, expected ASCII.\n") + + string("SU2 reads/writes binary restart files by default.\n") + + string("Note that backward compatibility for ASCII restart files is\n") + + string("possible with the WRT_BINARY_RESTART / READ_BINARY_RESTART options."), CURRENT_FUNCTION); + + MPI_File_close(&fhw); + +#endif + + /*--- Open the restart file ---*/ + + restart_file.open(filename.data(), ios::in); + + /*--- In case there is no restart file ---*/ + + if (restart_file.fail()) + SU2_MPI::Error(string("SU2 solution file ") + filename + string(" not found"), CURRENT_FUNCTION); + + /*--- Identify the number of fields (and names) in the restart file ---*/ + + getline (restart_file, text_line); + + stringstream ss(text_line); + while (ss >> Tag) { + config->fields.push_back(Tag); + if (ss.peek() == ',') ss.ignore(); + } + + /*--- Close the file (the solution date is read later). ---*/ + + restart_file.close(); + + /*--- Set the number of variables, one per field in the + restart file (without including the PointID) ---*/ + + nVar = config->fields.size() - 1; + + /*--- Clear the fields vector since we'll read it again. ---*/ + + config->fields.clear(); + + } + +} + +void CBaselineSolver_FEM::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo) { + + /*--- Restart the solution from file information ---*/ + unsigned short iVar; + unsigned long index; + + string restart_filename = config->GetSolution_FileName(); + + if (config->GetTime_Domain()) { + restart_filename = config->GetUnsteady_FileName(restart_filename, SU2_TYPE::Int(val_iter), ""); + } + + int counter = 0; + long iPoint_Local = 0; unsigned long iPoint_Global = 0; + unsigned short rbuf_NotMatching = 0; + unsigned long nDOF_Read = 0; + + /*--- Read the restart data from either an ASCII or binary SU2 file. ---*/ + + if (config->GetRead_Binary_Restart()) { + Read_SU2_Restart_Binary(geometry[MESH_0], config, restart_filename); + } else { + Read_SU2_Restart_ASCII(geometry[MESH_0], config, restart_filename); + } + + /*--- Load data from the restart into correct containers. ---*/ + + counter = 0; + for (iPoint_Global = 0; iPoint_Global < geometry[MESH_0]->GetGlobal_nPointDomain(); iPoint_Global++) { + + /*--- Retrieve local index. If this node from the restart file lives + on the current processor, we will load and instantiate the vars. ---*/ + + iPoint_Local = geometry[MESH_0]->GetGlobal_to_Local_Point(iPoint_Global); + + if (iPoint_Local > -1) { + + /*--- We need to store this point's data, so jump to the correct + offset in the buffer of data from the restart file and load it. ---*/ + + index = counter*Restart_Vars[1]; + for (iVar = 0; iVar < nVar; iVar++) { + VecSolDOFs[nVar*iPoint_Local+iVar] = Restart_Data[index+iVar]; + } + /*--- Update the local counter nDOF_Read. ---*/ + ++nDOF_Read; + + /*--- Increment the overall counter for how many points have been loaded. ---*/ + counter++; + } + + } + + /*--- Detect a wrong solution file ---*/ + if(nDOF_Read < nDOFsLocOwned) rbuf_NotMatching = 1; + +#ifdef HAVE_MPI + unsigned short sbuf_NotMatching = rbuf_NotMatching; + SU2_MPI::Allreduce(&sbuf_NotMatching, &rbuf_NotMatching, 1, MPI_UNSIGNED_SHORT, MPI_MAX, MPI_COMM_WORLD); +#endif + + if (rbuf_NotMatching != 0) + SU2_MPI::Error(string("The solution file ") + restart_filename + + string(" doesn't match with the mesh file!\n") + + string("It could be empty lines at the end of the file."), + CURRENT_FUNCTION); + + /*--- Delete the class memory that is used to load the restart. ---*/ + + if (Restart_Vars != NULL) delete [] Restart_Vars; + if (Restart_Data != NULL) delete [] Restart_Data; + Restart_Vars = NULL; Restart_Data = NULL; + +} + +CBaselineSolver_FEM::~CBaselineSolver_FEM(void) { } diff --git a/SU2_CFD/src/solver_adjoint_elasticity.cpp b/SU2_CFD/src/solvers/CDiscAdjFEASolver.cpp similarity index 97% rename from SU2_CFD/src/solver_adjoint_elasticity.cpp rename to SU2_CFD/src/solvers/CDiscAdjFEASolver.cpp index 73d94d57efde..84c202848524 100644 --- a/SU2_CFD/src/solver_adjoint_elasticity.cpp +++ b/SU2_CFD/src/solvers/CDiscAdjFEASolver.cpp @@ -1,12 +1,12 @@ /*! - * \file solver_adjoint_elasticity.cpp + * \file CDiscAdjFEASolver.cpp * \brief Main subroutines for solving adjoint FEM elasticity problems. * \author R. Sanchez * \version 7.0.0 "Blackbird" * * SU2 Project Website: https://su2code.github.io * - * The SU2 Project is maintained by the SU2 Foundation + * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) @@ -26,9 +26,8 @@ */ -#include "../include/solver_structure.hpp" -#include "../include/variables/CDiscAdjFEAVariable.hpp" -#include "../include/variables/CDiscAdjFEABoundVariable.hpp" +#include "../../include/solvers/CDiscAdjFEASolver.hpp" +#include "../../include/variables/CDiscAdjFEAVariable.hpp" CDiscAdjFEASolver::CDiscAdjFEASolver(void) : CSolver (){ @@ -264,7 +263,7 @@ CDiscAdjFEASolver::CDiscAdjFEASolver(CGeometry *geometry, CConfig *config, CSolv Global_Sens_EField = NULL; Total_Sens_EField = NULL; AD_Idx_EField = NULL; - + if (de_effects) { nEField = config->GetnElectric_Field(); @@ -446,12 +445,12 @@ void CDiscAdjFEASolver::RegisterSolution(CGeometry *geometry, CConfig *config){ if (dynamic) { /*--- Register acceleration (u'') and velocity (u') at time step n ---*/ - + direct_solver->GetNodes()->RegisterSolution_Accel(input); direct_solver->GetNodes()->RegisterSolution_Vel(input); - + /*--- Register solution (u), acceleration (u'') and velocity (u') at time step n-1 ---*/ - + direct_solver->GetNodes()->Register_femSolution_time_n(); direct_solver->GetNodes()->RegisterSolution_Accel_time_n(); direct_solver->GetNodes()->RegisterSolution_Vel_time_n(); @@ -597,7 +596,7 @@ void CDiscAdjFEASolver::RegisterObj_Func(CConfig *config){ void CDiscAdjFEASolver::SetAdj_ObjFunc(CGeometry *geometry, CConfig *config){ - + bool dynamic = (config->GetTime_Domain()); unsigned long IterAvg_Obj = config->GetIter_Avg_Objective(); unsigned long TimeIter = config->GetTimeIter(); @@ -665,7 +664,7 @@ void CDiscAdjFEASolver::ExtractAdjoint_Solution(CGeometry *geometry, CConfig *co /*--- FIRST: The acceleration solution ---*/ /*--- Set the old acceleration solution ---*/ - nodes->Set_OldSolution_Accel(); + nodes->Set_OldSolution_Accel(); for (iPoint = 0; iPoint < nPoint; iPoint++){ @@ -683,7 +682,7 @@ void CDiscAdjFEASolver::ExtractAdjoint_Solution(CGeometry *geometry, CConfig *co /*--- Set the old velocity solution ---*/ nodes->Set_OldSolution_Vel(); - + for (iPoint = 0; iPoint < nPoint; iPoint++){ /*--- Extract the adjoint velocity solution u'' ---*/ @@ -932,7 +931,7 @@ void CDiscAdjFEASolver::ExtractAdjoint_CrossTerm_Geometry(CGeometry *geometry, C unsigned short iVar; unsigned long iPoint; - + su2double relax = config->GetAitkenStatRelax(); for (iPoint = 0; iPoint < nPoint; iPoint++){ @@ -940,9 +939,9 @@ void CDiscAdjFEASolver::ExtractAdjoint_CrossTerm_Geometry(CGeometry *geometry, C /*--- Extract the adjoint solution ---*/ direct_solver->GetNodes()->GetAdjointSolution_LocalIndex(iPoint,Solution); - + /*--- Relax and set the solution ---*/ - + for(iVar = 0; iVar < nVar; iVar++) Solution[iVar] = relax*Solution[iVar] + (1.0-relax)*nodes->GetGeometry_CrossTerm_Derivative(iPoint,iVar); @@ -1040,20 +1039,6 @@ void CDiscAdjFEASolver::ComputeResidual_Multizone(CGeometry *geometry, CConfig * } -void CDiscAdjFEASolver::UpdateSolution_BGS(CGeometry *geometry, CConfig *config){ - - unsigned long iPoint; - unsigned short iVar; - - /*--- To nPoint: The solution must be communicated beforehand ---*/ - /*--- As there are geometrical crossed dependencies, we need to use the full BGS solution and not just the node Solution ---*/ - for (iPoint = 0; iPoint < nPoint; iPoint++){ - for (iVar = 0; iVar < nVar; iVar++) - nodes->Set_BGSSolution_k(iPoint, iVar, nodes->Get_BGSSolution(iPoint, iVar)); - } - -} - void CDiscAdjFEASolver::ReadDV(CConfig *config) { unsigned long index; @@ -1229,4 +1214,4 @@ void CDiscAdjFEASolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CCo } - + diff --git a/SU2_CFD/src/solvers/CDiscAdjMeshSolver.cpp b/SU2_CFD/src/solvers/CDiscAdjMeshSolver.cpp index fc9ffce780bb..347cc6c54157 100644 --- a/SU2_CFD/src/solvers/CDiscAdjMeshSolver.cpp +++ b/SU2_CFD/src/solvers/CDiscAdjMeshSolver.cpp @@ -6,7 +6,7 @@ * * SU2 Project Website: https://su2code.github.io * - * The SU2 Project is maintained by the SU2 Foundation + * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) diff --git a/SU2_CFD/src/solver_adjoint_discrete.cpp b/SU2_CFD/src/solvers/CDiscAdjSolver.cpp similarity index 97% rename from SU2_CFD/src/solver_adjoint_discrete.cpp rename to SU2_CFD/src/solvers/CDiscAdjSolver.cpp index 2d0ca3ce9f6f..f45e63ad88dd 100644 --- a/SU2_CFD/src/solver_adjoint_discrete.cpp +++ b/SU2_CFD/src/solvers/CDiscAdjSolver.cpp @@ -1,12 +1,12 @@ /*! - * \file solver_adjoint_discrete.cpp + * \file CDiscAdjSolver.cpp * \brief Main subroutines for solving the discrete adjoint problem. * \author T. Albring * \version 7.0.0 "Blackbird" * * SU2 Project Website: https://su2code.github.io * - * The SU2 Project is maintained by the SU2 Foundation + * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) @@ -25,8 +25,7 @@ * License along with SU2. If not, see . */ -#include "../include/solver_structure.hpp" -#include "../include/variables/CDiscAdjVariable.hpp" +#include "../../include/solvers/CDiscAdjSolver.hpp" CDiscAdjSolver::CDiscAdjSolver(void) : CSolver () { @@ -114,7 +113,7 @@ CDiscAdjSolver::CDiscAdjSolver(CGeometry *geometry, CConfig *config, CSolver *di for (iMarker = 0; iMarker < nMarker; iMarker++) { unsigned long nVertex = geometry->nVertex[iMarker]; CSensitivity[iMarker] = new su2double [nVertex]; - + for (iVertex = 0; iVertex < nVertex; iVertex++) CSensitivity[iMarker][iVertex] = 0.0; } @@ -140,7 +139,7 @@ CDiscAdjSolver::CDiscAdjSolver(CGeometry *geometry, CConfig *config, CSolver *di } } -CDiscAdjSolver::~CDiscAdjSolver(void) { +CDiscAdjSolver::~CDiscAdjSolver(void) { unsigned short iMarker; @@ -278,7 +277,7 @@ void CDiscAdjSolver::RegisterVariables(CGeometry *geometry, CConfig *config, boo Temperature = config->GetTemperature_FreeStreamND(); su2double SoundSpeed = 0.0; - + if (nDim == 2) { SoundSpeed = config->GetVelocity_FreeStreamND()[0]*Velocity_Ref/(cos(Alpha)*Mach); } if (nDim == 3) { SoundSpeed = config->GetVelocity_FreeStreamND()[0]*Velocity_Ref/(cos(Alpha)*cos(Beta)*Mach); } @@ -527,7 +526,7 @@ void CDiscAdjSolver::ExtractAdjoint_Solution(CGeometry *geometry, CConfig *confi } void CDiscAdjSolver::ExtractAdjoint_Variables(CGeometry *geometry, CConfig *config) { - + /*--- Extract the adjoint values of the farfield values ---*/ if ((config->GetKind_Regime() == COMPRESSIBLE) && (KindDirect_Solver == RUNTIME_FLOW_SYS) && !config->GetBoolTurbomachinery()) { @@ -557,7 +556,7 @@ void CDiscAdjSolver::ExtractAdjoint_Variables(CGeometry *geometry, CConfig *conf if ((config->GetKind_Regime() == INCOMPRESSIBLE) && (KindDirect_Solver == RUNTIME_FLOW_SYS && (!config->GetBoolTurbomachinery()))) { - + su2double Local_Sens_ModVel, Local_Sens_BPress, Local_Sens_Temp; Local_Sens_ModVel = SU2_TYPE::GetDerivative(ModVel); @@ -828,7 +827,7 @@ void CDiscAdjSolver::SetSurface_Sensitivity(CGeometry *geometry, CConfig *config for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { Sens_Geo[iMarker_Monitoring] = 0.0; } - + for (iMarker = 0; iMarker < nMarker; iMarker++) { /*--- Loop over boundary markers to select those for Euler walls and NS walls ---*/ @@ -897,7 +896,7 @@ void CDiscAdjSolver::SetSurface_Sensitivity(CGeometry *geometry, CConfig *config Sens_Geo[iMarker_Monitoring] = sqrt(Sens_Geo[iMarker_Monitoring]); Total_Sens_Geo += Sens_Geo[iMarker_Monitoring]; } - + delete [] Sens_Geo; } @@ -930,14 +929,14 @@ void CDiscAdjSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfi bool compressible = (config->GetKind_Regime() == COMPRESSIBLE); bool incompressible = (config->GetKind_Regime() == INCOMPRESSIBLE); - + /*--- Restart the solution from file information ---*/ filename = config->GetSolution_AdjFileName(); restart_filename = config->GetObjFunc_Extension(filename); - + restart_filename = config->GetFilename(restart_filename, "", val_iter); - + /*--- Read and store the restart metadata. ---*/ @@ -1071,19 +1070,4 @@ void CDiscAdjSolver::ComputeResidual_Multizone(CGeometry *geometry, CConfig *con SetResidual_BGS(geometry, config); -} - -void CDiscAdjSolver::UpdateSolution_BGS(CGeometry *geometry, CConfig *config){ - - unsigned long iPoint; - unsigned short iVar; - - /*--- To nPoint: The solution must be communicated beforehand ---*/ - /*--- As there might be crossed dependencies, we need to use the full BGS solution and not just the node Solution ---*/ - for (iPoint = 0; iPoint < nPoint; iPoint++){ - for (iVar = 0; iVar < nVar; iVar++) - nodes->Set_BGSSolution_k(iPoint, iVar, nodes->Get_BGSSolution(iPoint, iVar)); - } - -} - +} \ No newline at end of file diff --git a/SU2_CFD/src/solver_direct_mean.cpp b/SU2_CFD/src/solvers/CEulerSolver.cpp similarity index 79% rename from SU2_CFD/src/solver_direct_mean.cpp rename to SU2_CFD/src/solvers/CEulerSolver.cpp index d96bd40782b8..34b334096ce2 100644 --- a/SU2_CFD/src/solver_direct_mean.cpp +++ b/SU2_CFD/src/solvers/CEulerSolver.cpp @@ -1,12 +1,12 @@ /*! - * \file solution_direct_mean.cpp - * \brief Main subrotuines for solving direct problems (Euler, Navier-Stokes, etc.). + * \file CEulerSolver.cpp + * \brief Main subrotuines for solving Finite-Volume Euler flow problems. * \author F. Palacios, T. Economon * \version 7.0.0 "Blackbird" * * SU2 Project Website: https://su2code.github.io * - * The SU2 Project is maintained by the SU2 Foundation + * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) @@ -26,19 +26,16 @@ */ -#include "../include/solver_structure.hpp" -#include "../../Common/include/toolboxes/printing_toolbox.hpp" -#include "../include/variables/CEulerVariable.hpp" -#include "../include/variables/CNSVariable.hpp" -#include "../include/gradients/computeGradientsGreenGauss.hpp" -#include "../include/gradients/computeGradientsLeastSquares.hpp" -#include "../include/limiters/computeLimiters.hpp" - +#include "../../include/solvers/CEulerSolver.hpp" +#include "../../../Common/include/toolboxes/printing_toolbox.hpp" +#include "../../include/gradients/computeGradientsGreenGauss.hpp" +#include "../../include/gradients/computeGradientsLeastSquares.hpp" +#include "../../include/limiters/computeLimiters.hpp" CEulerSolver::CEulerSolver(void) : CSolver() { - + /*--- Basic array initialization ---*/ - + CD_Inv = NULL; CL_Inv = NULL; CSF_Inv = NULL; CEff_Inv = NULL; CMx_Inv = NULL; CMy_Inv = NULL; CMz_Inv = NULL; CFx_Inv = NULL; CFy_Inv = NULL; CFz_Inv = NULL; @@ -54,7 +51,7 @@ CEulerSolver::CEulerSolver(void) : CSolver() { ForceMomentum = NULL; MomentMomentum = NULL; /*--- Surface based array initialization ---*/ - + Surface_CL_Inv = NULL; Surface_CD_Inv = NULL; Surface_CSF_Inv = NULL; Surface_CEff_Inv = NULL; Surface_CFx_Inv = NULL; Surface_CFy_Inv = NULL; Surface_CFz_Inv = NULL; Surface_CMx_Inv = NULL; Surface_CMy_Inv = NULL; Surface_CMz_Inv = NULL; @@ -68,25 +65,25 @@ CEulerSolver::CEulerSolver(void) : CSolver() { Surface_CMx = NULL; Surface_CMy = NULL; Surface_CMz = NULL; /*--- Rotorcraft simulation array initialization ---*/ - + CMerit_Inv = NULL; CT_Inv = NULL; CQ_Inv = NULL; - + CMerit_Mnt = NULL; CT_Mnt = NULL; CQ_Mnt = NULL; /*--- Supersonic simulation array initialization ---*/ - + CEquivArea_Inv = NULL; CNearFieldOF_Inv = NULL; - + /*--- Engine simulation array initialization ---*/ - + Inflow_MassFlow = NULL; Inflow_Pressure = NULL; Inflow_Mach = NULL; Inflow_Area = NULL; Exhaust_Pressure = NULL; Exhaust_Temperature = NULL; Exhaust_MassFlow = NULL; Exhaust_Area = NULL; - + /*--- Numerical methods array initialization ---*/ - + LowMach_Precontioner = NULL; Primitive = NULL; Primitive_i = NULL; Primitive_j = NULL; CharacPrimVar = NULL; @@ -98,23 +95,23 @@ CEulerSolver::CEulerSolver(void) : CSolver() { nVertex = NULL; Smatrix = NULL; Cvector = NULL; - + Secondary = NULL; Secondary_i = NULL; Secondary_j = NULL; /*--- Fixed CL mode initialization ---*/ - + Start_AoA_FD = false; End_AoA_FD = false; Update_AoA = false; Iter_Update_AoA = 0; FluidModel = NULL; - + SlidingState = NULL; SlidingStateNodes = NULL; /*--- Initialize quantities for the average process for internal flow ---*/ - + AverageVelocity = NULL; AverageTurboVelocity = NULL; OldAverageTurboVelocity = NULL; @@ -162,7 +159,7 @@ CEulerSolver::CEulerSolver(void) : CSolver() { } CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh) : CSolver() { - + unsigned long iPoint, counter_local = 0, counter_global = 0, iVertex; unsigned short iVar, iDim, iMarker, nLineLets; su2double StaticEnergy, Density, Velocity2, Pressure, Temperature; @@ -210,7 +207,7 @@ CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config, unsigned short if (adjoint) Unst_RestartIter = SU2_TYPE::Int(config->GetUnst_AdjointIter())-1; else Unst_RestartIter = SU2_TYPE::Int(config->GetRestart_Iter())-1; } - + filename_ = config->GetFilename(filename_, ".meta", Unst_RestartIter); /*--- Read and store the restart metadata. ---*/ @@ -238,7 +235,7 @@ CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config, unsigned short ForceMomentum = NULL; MomentMomentum = NULL; /*--- Surface based array initialization ---*/ - + Surface_CL_Inv = NULL; Surface_CD_Inv = NULL; Surface_CSF_Inv = NULL; Surface_CEff_Inv = NULL; Surface_CFx_Inv = NULL; Surface_CFy_Inv = NULL; Surface_CFz_Inv = NULL; Surface_CMx_Inv = NULL; Surface_CMy_Inv = NULL; Surface_CMz_Inv = NULL; @@ -258,19 +255,19 @@ CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config, unsigned short CMerit_Mnt = NULL; CT_Mnt = NULL; CQ_Mnt = NULL; /*--- Supersonic simulation array initialization ---*/ - + CEquivArea_Inv = NULL; CNearFieldOF_Inv = NULL; - + /*--- Engine simulation array initialization ---*/ - + Inflow_MassFlow = NULL; Inflow_Pressure = NULL; Inflow_Mach = NULL; Inflow_Area = NULL; Exhaust_Pressure = NULL; Exhaust_Temperature = NULL; Exhaust_MassFlow = NULL; Exhaust_Area = NULL; - + /*--- Numerical methods array initialization ---*/ - + iPoint_UndLapl = NULL; jPoint_UndLapl = NULL; LowMach_Precontioner = NULL; @@ -284,14 +281,14 @@ CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config, unsigned short Secondary=NULL; Secondary_i=NULL; Secondary_j=NULL; /*--- Fixed CL mode initialization ---*/ - + Start_AoA_FD = false; End_AoA_FD = false; Update_AoA = false; Iter_Update_AoA = 0; FluidModel = NULL; - + /*--- Initialize quantities for the average process for internal flow ---*/ AverageVelocity = NULL; @@ -338,49 +335,49 @@ CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config, unsigned short CkOutflow2 = NULL; /*--- Set the gamma value ---*/ - + Gamma = config->GetGamma(); Gamma_Minus_One = Gamma - 1.0; - + /*--- Define geometry constants in the solver structure Compressible flow, primitive variables (T, vx, vy, vz, P, rho, h, c, lamMu, EddyMu, ThCond, Cp). ---*/ - + nDim = geometry->GetnDim(); nVar = nDim+2; nPrimVar = nDim+9; nPrimVarGrad = nDim+4; nSecondaryVar = 2; nSecondaryVarGrad = 2; - + /*--- Initialize nVarGrad for deallocation ---*/ - + nVarGrad = nPrimVarGrad; - + nMarker = config->GetnMarker_All(); nPoint = geometry->GetnPoint(); nPointDomain = geometry->GetnPointDomain(); - + /*--- Store the number of vertices on each marker for deallocation later ---*/ nVertex = new unsigned long[nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) + for (iMarker = 0; iMarker < nMarker; iMarker++) nVertex[iMarker] = geometry->nVertex[iMarker]; - + /*--- Perform the non-dimensionalization for the flow equations using the specified reference values. ---*/ - + SetNondimensionalization(config, iMesh); - + /*--- Check if we are executing a verification case. If so, the VerificationSolution object will be instantiated for a particular option from the available library of verification solutions. Note that this is done after SetNondim(), as problem-specific initial parameters are needed by the solution constructors. ---*/ - + SetVerificationSolution(nDim, nVar, config); - + /*--- Define some auxiliary vectors related to the residual ---*/ - + Residual = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = 0.0; Residual_RMS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_RMS[iVar] = 0.0; Residual_Max = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_Max[iVar] = 0.0; @@ -389,103 +386,103 @@ CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config, unsigned short Res_Conv = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Conv[iVar] = 0.0; Res_Visc = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Visc[iVar] = 0.0; Res_Sour = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Sour[iVar] = 0.0; - + /*--- Define some structures for locating max residuals ---*/ - + Point_Max = new unsigned long[nVar]; for (iVar = 0; iVar < nVar; iVar++) Point_Max[iVar] = 0; Point_Max_Coord = new su2double*[nVar]; for (iVar = 0; iVar < nVar; iVar++) { Point_Max_Coord[iVar] = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Point_Max_Coord[iVar][iDim] = 0.0; } - + /*--- Define some auxiliary vectors related to the solution ---*/ - + Solution = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution[iVar] = 0.0; Solution_i = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution_i[iVar] = 0.0; Solution_j = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution_j[iVar] = 0.0; - + /*--- Define some auxiliary vectors related to the geometry ---*/ - + Vector = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = 0.0; Vector_i = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector_i[iDim] = 0.0; Vector_j = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector_j[iDim] = 0.0; - + /*--- Define some auxiliary vectors related to the primitive solution ---*/ - + Primitive = new su2double[nPrimVar]; for (iVar = 0; iVar < nPrimVar; iVar++) Primitive[iVar] = 0.0; Primitive_i = new su2double[nPrimVar]; for (iVar = 0; iVar < nPrimVar; iVar++) Primitive_i[iVar] = 0.0; Primitive_j = new su2double[nPrimVar]; for (iVar = 0; iVar < nPrimVar; iVar++) Primitive_j[iVar] = 0.0; - + /*--- Define some auxiliary vectors related to the Secondary solution ---*/ - + Secondary = new su2double[nSecondaryVar]; for (iVar = 0; iVar < nSecondaryVar; iVar++) Secondary[iVar] = 0.0; Secondary_i = new su2double[nSecondaryVar]; for (iVar = 0; iVar < nSecondaryVar; iVar++) Secondary_i[iVar] = 0.0; Secondary_j = new su2double[nSecondaryVar]; for (iVar = 0; iVar < nSecondaryVar; iVar++) Secondary_j[iVar] = 0.0; - + /*--- Define some auxiliary vectors related to the undivided lapalacian ---*/ - + if (config->GetKind_ConvNumScheme_Flow() == SPACE_CENTERED) { iPoint_UndLapl = new su2double [nPoint]; jPoint_UndLapl = new su2double [nPoint]; } - + /*--- Define some auxiliary vectors related to low-speed preconditioning ---*/ - + if (roe_turkel || low_mach_prec) { LowMach_Precontioner = new su2double* [nVar]; for (iVar = 0; iVar < nVar; iVar ++) LowMach_Precontioner[iVar] = new su2double[nVar]; } - + /*--- Initialize the solution and right hand side vectors for storing the residuals and updating the solution (always needed even for explicit schemes). ---*/ - + LinSysSol.Initialize(nPoint, nPointDomain, nVar, 0.0); LinSysRes.Initialize(nPoint, nPointDomain, nVar, 0.0); - + /*--- Jacobians and vector structures for implicit computations ---*/ - + if (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT) { - + Jacobian_i = new su2double* [nVar]; Jacobian_j = new su2double* [nVar]; for (iVar = 0; iVar < nVar; iVar++) { Jacobian_i[iVar] = new su2double [nVar]; Jacobian_j[iVar] = new su2double [nVar]; } - + if (rank == MASTER_NODE) cout << "Initialize Jacobian structure (Euler). MG level: " << iMesh <<"." << endl; Jacobian.Initialize(nPoint, nPointDomain, nVar, nVar, true, geometry, config); - + if (config->GetKind_Linear_Solver_Prec() == LINELET) { nLineLets = Jacobian.BuildLineletPreconditioner(geometry, config); if (rank == MASTER_NODE) cout << "Compute linelet structure. " << nLineLets << " elements in each line (average)." << endl; } - + } - + else { if (rank == MASTER_NODE) cout << "Explicit scheme. No Jacobian structure (Euler). MG level: " << iMesh <<"." << endl; } - + /*--- Define some auxiliary vectors for computing flow variable gradients by least squares, S matrix := inv(R)*traspose(inv(R)), c vector := transpose(WA)*(Wb) ---*/ - + if (config->GetLeastSquaresRequired()) { Smatrix = new su2double* [nDim]; for (iDim = 0; iDim < nDim; iDim++) Smatrix[iDim] = new su2double [nDim]; - + Cvector = new su2double* [nPrimVarGrad]; for (iVar = 0; iVar < nPrimVarGrad; iVar++) Cvector[iVar] = new su2double [nDim]; } - + /*--- Store the value of the characteristic primitive variables at the boundaries ---*/ - + CharacPrimVar = new su2double** [nMarker]; for (iMarker = 0; iMarker < nMarker; iMarker++) { CharacPrimVar[iMarker] = new su2double* [geometry->nVertex[iMarker]]; @@ -496,10 +493,10 @@ CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config, unsigned short } } } - + /*--- Store the value of the primitive variables + 2 turb variables at the boundaries, used for IO with a donor cell ---*/ - + DonorPrimVar = new su2double** [nMarker]; for (iMarker = 0; iMarker < nMarker; iMarker++) { DonorPrimVar[iMarker] = new su2double* [geometry->nVertex[iMarker]]; @@ -518,9 +515,9 @@ CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config, unsigned short } } } - + /*--- Store the value of the characteristic primitive variables index at the boundaries ---*/ - + DonorGlobalIndex = new unsigned long* [nMarker]; for (iMarker = 0; iMarker < nMarker; iMarker++) { DonorGlobalIndex[iMarker] = new unsigned long [geometry->nVertex[iMarker]]; @@ -528,9 +525,9 @@ CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config, unsigned short DonorGlobalIndex[iMarker][iVertex] = 0; } } - + /*--- Store the value of the Delta P at the Actuator Disk ---*/ - + ActDisk_DeltaP = new su2double* [nMarker]; for (iMarker = 0; iMarker < nMarker; iMarker++) { ActDisk_DeltaP[iMarker] = new su2double [geometry->nVertex[iMarker]]; @@ -538,9 +535,9 @@ CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config, unsigned short ActDisk_DeltaP[iMarker][iVertex] = 0; } } - + /*--- Store the value of the Delta T at the Actuator Disk ---*/ - + ActDisk_DeltaT = new su2double* [nMarker]; for (iMarker = 0; iMarker < nMarker; iMarker++) { ActDisk_DeltaT[iMarker] = new su2double [geometry->nVertex[iMarker]]; @@ -583,7 +580,7 @@ CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config, unsigned short } /*--- Force definition and coefficient arrays for all of the markers ---*/ - + CPressure = new su2double* [nMarker]; CPressureTarget = new su2double* [nMarker]; for (iMarker = 0; iMarker < nMarker; iMarker++) { @@ -594,9 +591,9 @@ CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config, unsigned short CPressureTarget[iMarker][iVertex] = 0.0; } } - + /*--- Non-dimensional coefficients ---*/ - + ForceInviscid = new su2double[nDim]; MomentInviscid = new su2double[3]; CD_Inv = new su2double[nMarker]; @@ -612,7 +609,7 @@ CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config, unsigned short CoPx_Inv = new su2double[nMarker]; CoPy_Inv = new su2double[nMarker]; CoPz_Inv = new su2double[nMarker]; - + ForceMomentum = new su2double[nDim]; MomentMomentum = new su2double[3]; CD_Mnt = new su2double[nMarker]; @@ -663,34 +660,34 @@ CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config, unsigned short Surface_CMz = new su2double[config->GetnMarker_Monitoring()]; /*--- Rotorcraft coefficients ---*/ - + CT_Inv = new su2double[nMarker]; CQ_Inv = new su2double[nMarker]; CMerit_Inv = new su2double[nMarker]; - + CT_Mnt = new su2double[nMarker]; CQ_Mnt = new su2double[nMarker]; CMerit_Mnt = new su2double[nMarker]; /*--- Supersonic coefficients ---*/ - + CEquivArea_Inv = new su2double[nMarker]; CNearFieldOF_Inv = new su2double[nMarker]; - + /*--- Engine simulation ---*/ - + Inflow_MassFlow = new su2double[nMarker]; Inflow_Pressure = new su2double[nMarker]; Inflow_Mach = new su2double[nMarker]; Inflow_Area = new su2double[nMarker]; - + Exhaust_MassFlow = new su2double[nMarker]; Exhaust_Pressure = new su2double[nMarker]; Exhaust_Temperature = new su2double[nMarker]; Exhaust_Area = new su2double[nMarker]; - + /*--- Init total coefficients ---*/ - + Total_CD = 0.0; Total_CL = 0.0; Total_CSF = 0.0; Total_CMx = 0.0; Total_CMy = 0.0; Total_CMz = 0.0; Total_CoPx = 0.0; Total_CoPy = 0.0; Total_CoPz = 0.0; @@ -706,16 +703,16 @@ CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config, unsigned short Total_AeroCD = 0.0; Total_SolidCD = 0.0; Total_IDR = 0.0; Total_IDC = 0.0; /*--- Read farfield conditions ---*/ - + Density_Inf = config->GetDensity_FreeStreamND(); Pressure_Inf = config->GetPressure_FreeStreamND(); Velocity_Inf = config->GetVelocity_FreeStreamND(); Energy_Inf = config->GetEnergy_FreeStreamND(); Temperature_Inf = config->GetTemperature_FreeStreamND(); Mach_Inf = config->GetMach(); - + /*--- Initialize the secondary values for direct derivative approxiations ---*/ - + switch(direct_diff) { case NO_DERIVATIVE: /*--- Default ---*/ @@ -746,18 +743,18 @@ CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config, unsigned short Inflow_Mach[iMarker] = Mach_Inf; Inflow_Pressure[iMarker] = Pressure_Inf; Inflow_Area[iMarker] = 0.0; - + Exhaust_MassFlow[iMarker] = 0.0; Exhaust_Temperature[iMarker] = Temperature_Inf; Exhaust_Pressure[iMarker] = Pressure_Inf; Exhaust_Area[iMarker] = 0.0; } - + /*--- Initializate quantities for SlidingMesh Interface ---*/ - + SlidingState = new su2double*** [nMarker]; SlidingStateNodes = new int* [nMarker]; - + for (iMarker = 0; iMarker < nMarker; iMarker++){ SlidingState[iMarker] = NULL; SlidingStateNodes[iMarker] = NULL; @@ -863,10 +860,10 @@ CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config, unsigned short if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) least_squares = true; else least_squares = false; - + /*--- Communicate and store volume and the number of neighbors for any dual CVs that lie on on periodic markers. ---*/ - + for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_VOLUME); CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_VOLUME); @@ -875,14 +872,14 @@ CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config, unsigned short } SetImplicitPeriodic(euler_implicit); if (iMesh == MESH_0) SetRotatePeriodic(true); - + /*--- Perform the MPI communication of the solution ---*/ - + InitiateComms(geometry, config, SOLUTION); CompleteComms(geometry, config, SOLUTION); - + /* Store the initial CFL number for all grid points. */ - + const su2double CFL = config->GetCFL(MGLevel); for (iPoint = 0; iPoint < nPoint; iPoint++) { nodes->SetLocalCFL(iPoint, CFL); @@ -966,7 +963,7 @@ CEulerSolver::~CEulerSolver(void) { if (CQ_Inv != NULL) delete [] CQ_Inv; if (CEquivArea_Inv != NULL) delete [] CEquivArea_Inv; if (CNearFieldOF_Inv != NULL) delete [] CNearFieldOF_Inv; - + if (CEff_Mnt != NULL) delete [] CEff_Mnt; if (CMerit_Mnt != NULL) delete [] CMerit_Mnt; if (CT_Mnt != NULL) delete [] CT_Mnt; @@ -999,19 +996,19 @@ CEulerSolver::~CEulerSolver(void) { delete [] LowMach_Precontioner[iVar]; delete [] LowMach_Precontioner; } - + if (CPressure != NULL) { for (iMarker = 0; iMarker < nMarker; iMarker++) delete [] CPressure[iMarker]; delete [] CPressure; } - + if (CPressureTarget != NULL) { for (iMarker = 0; iMarker < nMarker; iMarker++) delete [] CPressureTarget[iMarker]; delete [] CPressureTarget; } - + if (CharacPrimVar != NULL) { for (iMarker = 0; iMarker < nMarker; iMarker++) { for (iVertex = 0; iVertex < nVertex[iMarker]; iVertex++) @@ -1035,11 +1032,11 @@ CEulerSolver::~CEulerSolver(void) { } delete [] SlidingState; } - + if ( SlidingStateNodes != NULL ){ for (iMarker = 0; iMarker < nMarker; iMarker++){ if (SlidingStateNodes[iMarker] != NULL) - delete [] SlidingStateNodes[iMarker]; + delete [] SlidingStateNodes[iMarker]; } delete [] SlidingStateNodes; } @@ -1052,7 +1049,7 @@ CEulerSolver::~CEulerSolver(void) { } delete [] DonorPrimVar; } - + if (DonorGlobalIndex != NULL) { for (iMarker = 0; iMarker < nMarker; iMarker++) delete [] DonorGlobalIndex[iMarker]; @@ -1102,14 +1099,14 @@ CEulerSolver::~CEulerSolver(void) { } delete [] HeatFlux; } - + if (HeatFluxTarget != NULL) { for (iMarker = 0; iMarker < nMarker; iMarker++) { delete [] HeatFluxTarget[iMarker]; } delete [] HeatFluxTarget; } - + if (YPlus != NULL) { for (iMarker = 0; iMarker < nMarker; iMarker++) { delete [] YPlus[iMarker]; @@ -1537,7 +1534,7 @@ void CEulerSolver::InitTurboContainers(CGeometry *geometry, CConfig *config){ } void CEulerSolver::Set_MPI_ActDisk(CSolver **solver_container, CGeometry *geometry, CConfig *config) { - + unsigned long iter, iPoint, iVertex, jVertex, iPointTotal, Buffer_Send_nPointTotal = 0; long iGlobalIndex, iGlobal; @@ -1545,54 +1542,54 @@ void CEulerSolver::Set_MPI_ActDisk(CSolver **solver_container, CGeometry *geomet long nDomain = 0, iDomain, jDomain; //bool ActDisk_Perimeter; bool rans = (config->GetKind_Turb_Model() != NONE); - + unsigned short nPrimVar_ = nPrimVar; if (rans) nPrimVar_ += 2; // Add two extra variables for the turbulence. - + #ifdef HAVE_MPI - + /*--- MPI status and request arrays for non-blocking communications ---*/ - + SU2_MPI::Status status; - + #endif - + /*--- Define buffer vector interior domain ---*/ - + su2double *Buffer_Send_PrimVar = NULL; long *Buffer_Send_Data = NULL; - + unsigned long *nPointTotal_s = new unsigned long[size]; unsigned long *nPointTotal_r = new unsigned long[size]; su2double *iPrimVar = new su2double [nPrimVar_]; - + unsigned long Buffer_Size_PrimVar = 0; unsigned long Buffer_Size_Data = 0; - + unsigned long PointTotal_Counter = 0; - + /*--- Allocate the memory that we only need if we have MPI support ---*/ - + su2double *Buffer_Receive_PrimVar = NULL; long *Buffer_Receive_Data = NULL; - + /*--- Basic dimensionalization ---*/ - + nDomain = size; - + /*--- This loop gets the array sizes of points for each rank to send to each other rank. ---*/ - + for (iDomain = 0; iDomain < nDomain; iDomain++) { - + /*--- Loop over the markers to perform the dimensionalizaton of the domain variables ---*/ - + Buffer_Send_nPointTotal = 0; - + /*--- Loop over all of the markers and count the number of each type of point and element that needs to be sent. ---*/ - + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) == ACTDISK_INLET) || (config->GetMarker_All_KindBC(iMarker) == ACTDISK_OUTLET)) { @@ -1607,108 +1604,108 @@ void CEulerSolver::Set_MPI_ActDisk(CSolver **solver_container, CGeometry *geomet } } } - + /*--- Store the counts on a partition by partition basis. ---*/ - + nPointTotal_s[iDomain] = Buffer_Send_nPointTotal; - + /*--- Total counts for allocating send buffers below ---*/ - + Buffer_Size_PrimVar += nPointTotal_s[iDomain]*(nPrimVar_); Buffer_Size_Data += nPointTotal_s[iDomain]*(3); - + } - + /*--- Allocate the buffer vectors in the appropiate domain (master, iDomain) ---*/ - + Buffer_Send_PrimVar = new su2double[Buffer_Size_PrimVar]; Buffer_Send_Data = new long[Buffer_Size_Data]; - + /*--- Now that we know the sizes of the point, we can allocate and send the information in large chunks to all processors. ---*/ - + for (iDomain = 0; iDomain < nDomain; iDomain++) { - + /*--- A rank does not communicate with itself through MPI ---*/ - + if (rank != iDomain) { - + #ifdef HAVE_MPI - + /*--- Communicate the counts to iDomain with non-blocking sends ---*/ - + SU2_MPI::Bsend(&nPointTotal_s[iDomain], 1, MPI_UNSIGNED_LONG, iDomain, iDomain, MPI_COMM_WORLD); - + #endif - + } else { - + /*--- If iDomain = rank, we simply copy values into place in memory ---*/ - + nPointTotal_r[iDomain] = nPointTotal_s[iDomain]; - + } - + /*--- Receive the counts. All processors are sending their counters to iDomain up above, so only iDomain needs to perform the recv here from all other ranks. ---*/ - + if (rank == iDomain) { - + for (jDomain = 0; jDomain < size; jDomain++) { - + /*--- A rank does not communicate with itself through MPI ---*/ - + if (rank != jDomain) { - + #ifdef HAVE_MPI - + /*--- Recv the data by probing for the current sender, jDomain, first and then receiving the values from it. ---*/ - + SU2_MPI::Recv(&nPointTotal_r[jDomain], 1, MPI_UNSIGNED_LONG, jDomain, rank, MPI_COMM_WORLD, &status); - + #endif - + } } - + } } - + /*--- Wait for the non-blocking sends to complete. ---*/ - + #ifdef HAVE_MPI - + SU2_MPI::Barrier(MPI_COMM_WORLD); - + #endif - + /*--- Initialize the counters for the larger send buffers (by domain) ---*/ - + PointTotal_Counter = 0; - + for (iDomain = 0; iDomain < nDomain; iDomain++) { - + /*--- Set the value of the interior geometry. Initialize counters. ---*/ - + iPointTotal = 0; - + /*--- Load up the actual values into the buffers for sending. ---*/ - + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { - + if ((config->GetMarker_All_KindBC(iMarker) == ACTDISK_INLET) || (config->GetMarker_All_KindBC(iMarker) == ACTDISK_OUTLET)) { for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - + jDomain = geometry->vertex[iMarker][iVertex]->GetDonorProcessor(); //ActDisk_Perimeter = geometry->vertex[iMarker][iVertex]->GetActDisk_Perimeter(); - + // if ((iDomain == jDomain) && (geometry->node[iPoint]->GetDomain()) && (!ActDisk_Perimeter)) { if ((iDomain == jDomain) && (geometry->node[iPoint]->GetDomain())) { - + for (iVar = 0; iVar < nPrimVar; iVar++) { Buffer_Send_PrimVar[(nPrimVar_)*(PointTotal_Counter+iPointTotal)+iVar] = nodes->GetPrimitive(iPoint,iVar); } @@ -1716,225 +1713,225 @@ void CEulerSolver::Set_MPI_ActDisk(CSolver **solver_container, CGeometry *geomet Buffer_Send_PrimVar[(nPrimVar_)*(PointTotal_Counter+iPointTotal)+nPrimVar] = solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0); Buffer_Send_PrimVar[(nPrimVar_)*(PointTotal_Counter+iPointTotal)+(nPrimVar+1)] = 0.0; } - + iGlobalIndex = geometry->node[iPoint]->GetGlobalIndex(); jVertex = geometry->vertex[iMarker][iVertex]->GetDonorVertex(); jMarker = geometry->vertex[iMarker][iVertex]->GetDonorMarker(); - + Buffer_Send_Data[(3)*(PointTotal_Counter+iPointTotal)+(0)] = iGlobalIndex; Buffer_Send_Data[(3)*(PointTotal_Counter+iPointTotal)+(1)] = jVertex; Buffer_Send_Data[(3)*(PointTotal_Counter+iPointTotal)+(2)] = jMarker; - + iPointTotal++; - + } - + } - + } - + } - + /*--- Send the buffers with the geometrical information ---*/ - + if (iDomain != rank) { - + #ifdef HAVE_MPI - + /*--- Communicate the coordinates, global index, colors, and element date to iDomain with non-blocking sends. ---*/ - + SU2_MPI::Bsend(&Buffer_Send_PrimVar[PointTotal_Counter*(nPrimVar_)], nPointTotal_s[iDomain]*(nPrimVar_), MPI_DOUBLE, iDomain, iDomain, MPI_COMM_WORLD); - + SU2_MPI::Bsend(&Buffer_Send_Data[PointTotal_Counter*(3)], nPointTotal_s[iDomain]*(3), MPI_LONG, iDomain, iDomain+nDomain, MPI_COMM_WORLD); - + #endif - + } - + else { - + /*--- Allocate local memory for the local recv of the elements ---*/ - + Buffer_Receive_PrimVar = new su2double[nPointTotal_s[iDomain]*(nPrimVar_)]; Buffer_Receive_Data = new long[nPointTotal_s[iDomain]*(3)]; - + for (iter = 0; iter < nPointTotal_s[iDomain]*(nPrimVar_); iter++) Buffer_Receive_PrimVar[iter] = Buffer_Send_PrimVar[PointTotal_Counter*(nPrimVar_)+iter]; - + for (iter = 0; iter < nPointTotal_s[iDomain]*(3); iter++) Buffer_Receive_Data[iter] = Buffer_Send_Data[PointTotal_Counter*(3)+iter]; - - + + /*--- Recv the point data from ourselves (same procedure as above) ---*/ - + for (iPoint = 0; iPoint < nPointTotal_r[iDomain]; iPoint++) { - + for (iVar = 0; iVar < nPrimVar_; iVar++) iPrimVar[iVar] = Buffer_Receive_PrimVar[iPoint*(nPrimVar_)+iVar]; - + iGlobal = Buffer_Receive_Data[iPoint*(3)+(0)]; iVertex = Buffer_Receive_Data[iPoint*(3)+(1)]; iMarker = Buffer_Receive_Data[iPoint*(3)+(2)]; - + for (iVar = 0; iVar < nPrimVar_; iVar++) SetDonorPrimVar(iMarker, iVertex, iVar, iPrimVar[iVar]); - + SetDonorGlobalIndex(iMarker, iVertex, iGlobal); - + } - + /*--- Delete memory for recv the point stuff ---*/ - + delete [] Buffer_Receive_PrimVar; delete [] Buffer_Receive_Data; - + } - + /*--- Increment the counters for the send buffers (iDomain loop) ---*/ - + PointTotal_Counter += iPointTotal; - + } - + /*--- Wait for the non-blocking sends to complete. ---*/ - + #ifdef HAVE_MPI - + SU2_MPI::Barrier(MPI_COMM_WORLD); - + #endif - + /*--- The next section begins the recv of all data for the interior points/elements in the mesh. First, create the domain structures for the points on this rank. First, we recv all of the point data ---*/ - + for (iDomain = 0; iDomain < size; iDomain++) { - + if (rank != iDomain) { - + #ifdef HAVE_MPI - + /*--- Allocate the receive buffer vector. Send the colors so that we know whether what we recv is an owned or halo node. ---*/ - + Buffer_Receive_PrimVar = new su2double [nPointTotal_r[iDomain]*(nPrimVar_)]; Buffer_Receive_Data = new long [nPointTotal_r[iDomain]*(3)]; - + /*--- Receive the buffers with the coords, global index, and colors ---*/ - + SU2_MPI::Recv(Buffer_Receive_PrimVar, nPointTotal_r[iDomain]*(nPrimVar_) , MPI_DOUBLE, iDomain, rank, MPI_COMM_WORLD, &status); - + SU2_MPI::Recv(Buffer_Receive_Data, nPointTotal_r[iDomain]*(3) , MPI_LONG, iDomain, rank+nDomain, MPI_COMM_WORLD, &status); - + /*--- Loop over all of the points that we have recv'd and store the coords, global index vertex and markers ---*/ - + for (iPoint = 0; iPoint < nPointTotal_r[iDomain]; iPoint++) { - + iGlobal = Buffer_Receive_Data[iPoint*(3)+(0)]; iVertex = Buffer_Receive_Data[iPoint*(3)+(1)]; iMarker = Buffer_Receive_Data[iPoint*(3)+(2)]; - + for (iVar = 0; iVar < nPrimVar_; iVar++) iPrimVar[iVar] = Buffer_Receive_PrimVar[iPoint*(nPrimVar_)+iVar]; - + for (iVar = 0; iVar < nPrimVar_; iVar++) { SetDonorPrimVar(iMarker, iVertex, iVar, iPrimVar[iVar]); } - + SetDonorGlobalIndex(iMarker, iVertex, iGlobal); - + } - + /*--- Delete memory for recv the point stuff ---*/ - + delete [] Buffer_Receive_PrimVar; delete [] Buffer_Receive_Data; - + #endif - + } - + } - + /*--- Wait for the non-blocking sends to complete. ---*/ - + #ifdef HAVE_MPI - + SU2_MPI::Barrier(MPI_COMM_WORLD); - + #endif - + /*--- Free all of the memory used for communicating points and elements ---*/ - + delete[] Buffer_Send_PrimVar; delete[] Buffer_Send_Data; - + /*--- Release all of the temporary memory ---*/ - + delete [] nPointTotal_s; delete [] nPointTotal_r; delete [] iPrimVar; - + } void CEulerSolver::Set_MPI_Nearfield(CGeometry *geometry, CConfig *config) { - + unsigned long iter, iPoint, iVertex, jVertex, iPointTotal, Buffer_Send_nPointTotal = 0; long iGlobalIndex, iGlobal; unsigned short iVar, iMarker, jMarker; long nDomain = 0, iDomain, jDomain; - + #ifdef HAVE_MPI - + /*--- MPI status and request arrays for non-blocking communications ---*/ - + SU2_MPI::Status status, status_; - + #endif - + /*--- Define buffer vector interior domain ---*/ - + su2double *Buffer_Send_PrimVar = NULL; - + unsigned long *nPointTotal_s = new unsigned long[size]; unsigned long *nPointTotal_r = new unsigned long[size]; su2double *iPrimVar = new su2double [nPrimVar]; - + unsigned long Buffer_Size_PrimVar = 0; - + unsigned long PointTotal_Counter = 0; - + /*--- Allocate the memory that we only need if we have MPI support ---*/ - + su2double *Buffer_Receive_PrimVar = NULL; - + /*--- Basic dimensionalization ---*/ - + nDomain = size; - + /*--- This loop gets the array sizes of points for each rank to send to each other rank. ---*/ - + for (iDomain = 0; iDomain < nDomain; iDomain++) { - + /*--- Loop over the markers to perform the dimensionalizaton of the domain variables ---*/ - + Buffer_Send_nPointTotal = 0; - + /*--- Loop over all of the markers and count the number of each type of point and element that needs to be sent. ---*/ - + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { if (config->GetMarker_All_KindBC(iMarker) == NEARFIELD_BOUNDARY) { for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { @@ -1946,97 +1943,97 @@ void CEulerSolver::Set_MPI_Nearfield(CGeometry *geometry, CConfig *config) { } } } - + /*--- Store the counts on a partition by partition basis. ---*/ - + nPointTotal_s[iDomain] = Buffer_Send_nPointTotal; - + /*--- Total counts for allocating send buffers below ---*/ - + Buffer_Size_PrimVar += nPointTotal_s[iDomain]*(nPrimVar+3); - + } - + /*--- Allocate the buffer vectors in the appropiate domain (master, iDomain) ---*/ - + Buffer_Send_PrimVar = new su2double[Buffer_Size_PrimVar]; - + /*--- Now that we know the sizes of the point, we can allocate and send the information in large chunks to all processors. ---*/ - + for (iDomain = 0; iDomain < nDomain; iDomain++) { - + /*--- A rank does not communicate with itself through MPI ---*/ - + if (rank != iDomain) { - + #ifdef HAVE_MPI - + /*--- Communicate the counts to iDomain with non-blocking sends ---*/ - + SU2_MPI::Bsend(&nPointTotal_s[iDomain], 1, MPI_UNSIGNED_LONG, iDomain, iDomain, MPI_COMM_WORLD); - + #endif - + } else { - + /*--- If iDomain = rank, we simply copy values into place in memory ---*/ - + nPointTotal_r[iDomain] = nPointTotal_s[iDomain]; - + } - + /*--- Receive the counts. All processors are sending their counters to iDomain up above, so only iDomain needs to perform the recv here from all other ranks. ---*/ - + if (rank == iDomain) { - + for (jDomain = 0; jDomain < size; jDomain++) { - + /*--- A rank does not communicate with itself through MPI ---*/ - + if (rank != jDomain) { - + #ifdef HAVE_MPI - + /*--- Recv the data by probing for the current sender, jDomain, first and then receiving the values from it. ---*/ - + SU2_MPI::Recv(&nPointTotal_r[jDomain], 1, MPI_UNSIGNED_LONG, jDomain, rank, MPI_COMM_WORLD, &status); - + #endif - + } } - + } } - + /*--- Wait for the non-blocking sends to complete. ---*/ - + #ifdef HAVE_MPI - + SU2_MPI::Barrier(MPI_COMM_WORLD); - + #endif - + /*--- Initialize the counters for the larger send buffers (by domain) ---*/ - + PointTotal_Counter = 0; - + for (iDomain = 0; iDomain < nDomain; iDomain++) { - + /*--- Set the value of the interior geometry. Initialize counters. ---*/ - + iPointTotal = 0; - + /*--- Load up the actual values into the buffers for sending. ---*/ - + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { - + if (config->GetMarker_All_KindBC(iMarker) == NEARFIELD_BOUNDARY) { - + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); jDomain = geometry->vertex[iMarker][iVertex]->GetDonorProcessor(); @@ -2050,162 +2047,162 @@ void CEulerSolver::Set_MPI_Nearfield(CGeometry *geometry, CConfig *config) { Buffer_Send_PrimVar[(nPrimVar+3)*(PointTotal_Counter+iPointTotal)+(nPrimVar+0)] = su2double(iGlobalIndex); Buffer_Send_PrimVar[(nPrimVar+3)*(PointTotal_Counter+iPointTotal)+(nPrimVar+1)] = su2double(jVertex); Buffer_Send_PrimVar[(nPrimVar+3)*(PointTotal_Counter+iPointTotal)+(nPrimVar+2)] = su2double(jMarker); - + iPointTotal++; - + } - + } - + } - + } - + /*--- Send the buffers with the geometrical information ---*/ - + if (iDomain != rank) { - + #ifdef HAVE_MPI - + /*--- Communicate the coordinates, global index, colors, and element date to iDomain with non-blocking sends. ---*/ - + SU2_MPI::Bsend(&Buffer_Send_PrimVar[PointTotal_Counter*(nPrimVar+3)], nPointTotal_s[iDomain]*(nPrimVar+3), MPI_DOUBLE, iDomain, iDomain, MPI_COMM_WORLD); - + #endif - + } - + else { - + /*--- Allocate local memory for the local recv of the elements ---*/ - + Buffer_Receive_PrimVar = new su2double[nPointTotal_s[iDomain]*(nPrimVar+3)]; - + for (iter = 0; iter < nPointTotal_s[iDomain]*(nPrimVar+3); iter++) Buffer_Receive_PrimVar[iter] = Buffer_Send_PrimVar[PointTotal_Counter*(nPrimVar+3)+iter]; - + /*--- Recv the point data from ourselves (same procedure as above) ---*/ - + for (iPoint = 0; iPoint < nPointTotal_r[iDomain]; iPoint++) { - + iGlobal = SU2_TYPE::Int(Buffer_Receive_PrimVar[iPoint*(nPrimVar+3)+(nPrimVar+0)]); iVertex = SU2_TYPE::Int(Buffer_Receive_PrimVar[iPoint*(nPrimVar+3)+(nPrimVar+1)]); iMarker = SU2_TYPE::Int(Buffer_Receive_PrimVar[iPoint*(nPrimVar+3)+(nPrimVar+2)]); for (iVar = 0; iVar < nPrimVar; iVar++) iPrimVar[iVar] = Buffer_Receive_PrimVar[iPoint*(nPrimVar+3)+iVar]; - + if (iVertex < 0.0) cout <<" Negative iVertex (receive)" << endl; if (iMarker < 0.0) cout <<" Negative iMarker (receive)" << endl; - + if (iMarker > nMarker) cout << "ERROR" << endl; if (iVertex > geometry->nVertex[iMarker]) cout << "ERROR" << endl; - + for (iVar = 0; iVar < nPrimVar; iVar++) SetDonorPrimVar(iMarker, iVertex, iVar, iPrimVar[iVar]); - + SetDonorGlobalIndex(iMarker, iVertex, iGlobal); - + } - + /*--- Delete memory for recv the point stuff ---*/ - + delete [] Buffer_Receive_PrimVar; - + } - + /*--- Increment the counters for the send buffers (iDomain loop) ---*/ - + PointTotal_Counter += iPointTotal; - + } - + /*--- Wait for the non-blocking sends to complete. ---*/ - + #ifdef HAVE_MPI - + SU2_MPI::Barrier(MPI_COMM_WORLD); - + #endif - + /*--- The next section begins the recv of all data for the interior points/elements in the mesh. First, create the domain structures for the points on this rank. First, we recv all of the point data ---*/ - + for (iDomain = 0; iDomain < size; iDomain++) { - + if (rank != iDomain) { - + #ifdef HAVE_MPI - + /*--- Allocate the receive buffer vector. Send the colors so that we know whether what we recv is an owned or halo node. ---*/ - + Buffer_Receive_PrimVar = new su2double [nPointTotal_r[iDomain]*(nPrimVar+3)]; - + /*--- Receive the buffers with the coords, global index, and colors ---*/ - + SU2_MPI::Recv(Buffer_Receive_PrimVar, nPointTotal_r[iDomain]*(nPrimVar+3) , MPI_DOUBLE, iDomain, rank, MPI_COMM_WORLD, &status_); - + /*--- Loop over all of the points that we have recv'd and store the coords, global index vertex and markers ---*/ - + for (iPoint = 0; iPoint < nPointTotal_r[iDomain]; iPoint++) { - + iGlobal = SU2_TYPE::Int(Buffer_Receive_PrimVar[iPoint*(nPrimVar+3)+(nPrimVar+0)]); iVertex = SU2_TYPE::Int(Buffer_Receive_PrimVar[iPoint*(nPrimVar+3)+(nPrimVar+1)]); iMarker = SU2_TYPE::Int(Buffer_Receive_PrimVar[iPoint*(nPrimVar+3)+(nPrimVar+2)]); for (iVar = 0; iVar < nPrimVar; iVar++) iPrimVar[iVar] = Buffer_Receive_PrimVar[iPoint*(nPrimVar+3)+iVar]; - + if (iVertex < 0.0) cout <<" Negative iVertex (receive)" << endl; if (iMarker < 0.0) cout <<" Negative iMarker (receive)" << endl; - + if (iMarker > nMarker) cout << "ERROR" << endl; if (iVertex > geometry->nVertex[iMarker]) cout << "ERROR" << endl; - + for (iVar = 0; iVar < nPrimVar; iVar++) SetDonorPrimVar(iMarker, iVertex, iVar, iPrimVar[iVar]); - + SetDonorGlobalIndex(iMarker, iVertex, iGlobal); - + } - + /*--- Delete memory for recv the point stuff ---*/ - + delete [] Buffer_Receive_PrimVar; - + #endif - + } - + } - + /*--- Wait for the non-blocking sends to complete. ---*/ - + #ifdef HAVE_MPI - + SU2_MPI::Barrier(MPI_COMM_WORLD); - + #endif - + /*--- Free all of the memory used for communicating points and elements ---*/ - + delete[] Buffer_Send_PrimVar; - + /*--- Release all of the temporary memory ---*/ - + delete [] nPointTotal_s; delete [] nPointTotal_r; delete [] iPrimVar; - + } void CEulerSolver::SetNondimensionalization(CConfig *config, unsigned short iMesh) { - + su2double Temperature_FreeStream = 0.0, Mach2Vel_FreeStream = 0.0, ModVel_FreeStream = 0.0, Energy_FreeStream = 0.0, ModVel_FreeStreamND = 0.0, Velocity_Reynolds = 0.0, Omega_FreeStream = 0.0, Omega_FreeStreamND = 0.0, Viscosity_FreeStream = 0.0, @@ -2222,7 +2219,7 @@ void CEulerSolver::SetNondimensionalization(CConfig *config, unsigned short iMes unsigned short iDim; /*--- Local variables ---*/ - + su2double Alpha = config->GetAoA()*PI_NUMBER/180.0; su2double Beta = config->GetAoS()*PI_NUMBER/180.0; su2double Mach = config->GetMach(); @@ -2235,7 +2232,7 @@ void CEulerSolver::SetNondimensionalization(CConfig *config, unsigned short iMes bool free_stream_temp = (config->GetKind_FreeStreamOption() == TEMPERATURE_FS); bool reynolds_init = (config->GetKind_InitOption() == REYNOLDS); bool aeroelastic = config->GetAeroelastic_Simulation(); - + /*--- Set temperature via the flutter speed index ---*/ if (aeroelastic) { su2double vf = config->GetAeroelastic_Flutter_Speed_Index(); @@ -2245,7 +2242,7 @@ void CEulerSolver::SetNondimensionalization(CConfig *config, unsigned short iMes // The temperature times gamma times the gas constant. Depending on the FluidModel temp is calculated below. TgammaR = ((vf*vf)*(b*b)*(w_alpha*w_alpha)*mu) / (Mach*Mach); } - + /*--- Compressible non dimensionalization ---*/ /*--- Compute the Free Stream velocity, using the Mach number ---*/ @@ -2456,105 +2453,105 @@ void CEulerSolver::SetNondimensionalization(CConfig *config, unsigned short iMes Viscosity_Ref = config->GetDensity_Ref()*Velocity_Ref*Length_Ref; config->SetViscosity_Ref(Viscosity_Ref); Conductivity_Ref = Viscosity_Ref*Gas_Constant_Ref; config->SetConductivity_Ref(Conductivity_Ref); Froude = ModVel_FreeStream/sqrt(STANDARD_GRAVITY*Length_Ref); config->SetFroude(Froude); - + /*--- Divide by reference values, to compute the non-dimensional free-stream values ---*/ - + Pressure_FreeStreamND = Pressure_FreeStream/config->GetPressure_Ref(); config->SetPressure_FreeStreamND(Pressure_FreeStreamND); Density_FreeStreamND = Density_FreeStream/config->GetDensity_Ref(); config->SetDensity_FreeStreamND(Density_FreeStreamND); - + for (iDim = 0; iDim < nDim; iDim++) { Velocity_FreeStreamND[iDim] = config->GetVelocity_FreeStream()[iDim]/Velocity_Ref; config->SetVelocity_FreeStreamND(Velocity_FreeStreamND[iDim], iDim); } - + Temperature_FreeStreamND = Temperature_FreeStream/config->GetTemperature_Ref(); config->SetTemperature_FreeStreamND(Temperature_FreeStreamND); - + Gas_ConstantND = config->GetGas_Constant()/Gas_Constant_Ref; config->SetGas_ConstantND(Gas_ConstantND); - - + + ModVel_FreeStreamND = 0.0; for (iDim = 0; iDim < nDim; iDim++) ModVel_FreeStreamND += Velocity_FreeStreamND[iDim]*Velocity_FreeStreamND[iDim]; ModVel_FreeStreamND = sqrt(ModVel_FreeStreamND); config->SetModVel_FreeStreamND(ModVel_FreeStreamND); - + Viscosity_FreeStreamND = Viscosity_FreeStream / Viscosity_Ref; config->SetViscosity_FreeStreamND(Viscosity_FreeStreamND); - + Tke_FreeStream = 3.0/2.0*(ModVel_FreeStream*ModVel_FreeStream*config->GetTurbulenceIntensity_FreeStream()*config->GetTurbulenceIntensity_FreeStream()); config->SetTke_FreeStream(Tke_FreeStream); - + Tke_FreeStreamND = 3.0/2.0*(ModVel_FreeStreamND*ModVel_FreeStreamND*config->GetTurbulenceIntensity_FreeStream()*config->GetTurbulenceIntensity_FreeStream()); config->SetTke_FreeStreamND(Tke_FreeStreamND); - + Omega_FreeStream = Density_FreeStream*Tke_FreeStream/(Viscosity_FreeStream*config->GetTurb2LamViscRatio_FreeStream()); config->SetOmega_FreeStream(Omega_FreeStream); - + Omega_FreeStreamND = Density_FreeStreamND*Tke_FreeStreamND/(Viscosity_FreeStreamND*config->GetTurb2LamViscRatio_FreeStream()); config->SetOmega_FreeStreamND(Omega_FreeStreamND); - + /*--- Initialize the dimensionless Fluid Model that will be used to solve the dimensionless problem ---*/ - + /*--- Delete the original (dimensional) FluidModel object before replacing. ---*/ - + delete FluidModel; - + switch (config->GetKind_FluidModel()) { - + case STANDARD_AIR: FluidModel = new CIdealGas(1.4, Gas_ConstantND); FluidModel->SetEnergy_Prho(Pressure_FreeStreamND, Density_FreeStreamND); break; - + case IDEAL_GAS: FluidModel = new CIdealGas(Gamma, Gas_ConstantND); FluidModel->SetEnergy_Prho(Pressure_FreeStreamND, Density_FreeStreamND); break; - + case VW_GAS: FluidModel = new CVanDerWaalsGas(Gamma, Gas_ConstantND, config->GetPressure_Critical() /config->GetPressure_Ref(), config->GetTemperature_Critical()/config->GetTemperature_Ref()); FluidModel->SetEnergy_Prho(Pressure_FreeStreamND, Density_FreeStreamND); break; - + case PR_GAS: FluidModel = new CPengRobinson(Gamma, Gas_ConstantND, config->GetPressure_Critical() /config->GetPressure_Ref(), config->GetTemperature_Critical()/config->GetTemperature_Ref(), config->GetAcentric_Factor()); FluidModel->SetEnergy_Prho(Pressure_FreeStreamND, Density_FreeStreamND); break; - + } - + Energy_FreeStreamND = FluidModel->GetStaticEnergy() + 0.5*ModVel_FreeStreamND*ModVel_FreeStreamND; - + if (viscous) { - + /*--- Constant viscosity model ---*/ config->SetMu_ConstantND(config->GetMu_Constant()/Viscosity_Ref); - + /*--- Sutherland's model ---*/ - + config->SetMu_RefND(config->GetMu_Ref()/Viscosity_Ref); config->SetMu_SND(config->GetMu_S()/config->GetTemperature_Ref()); config->SetMu_Temperature_RefND(config->GetMu_Temperature_Ref()/config->GetTemperature_Ref()); - + /* constant thermal conductivity model */ config->SetKt_ConstantND(config->GetKt_Constant()/Conductivity_Ref); - + FluidModel->SetLaminarViscosityModel(config); FluidModel->SetThermalConductivityModel(config); - + } - + if (tkeNeeded) { Energy_FreeStreamND += Tke_FreeStreamND; }; config->SetEnergy_FreeStreamND(Energy_FreeStreamND); - + Energy_Ref = Energy_FreeStream/Energy_FreeStreamND; config->SetEnergy_Ref(Energy_Ref); - + Total_UnstTimeND = config->GetTotal_UnstTime() / Time_Ref; config->SetTotal_UnstTimeND(Total_UnstTimeND); Delta_UnstTimeND = config->GetDelta_UnstTime() / Time_Ref; config->SetDelta_UnstTimeND(Delta_UnstTimeND); - + /*--- Write output to the console if this is the master node and first domain ---*/ - + if ((rank == MASTER_NODE) && (MGLevel == MESH_0)) { - + cout.precision(6); - + if (viscous) { cout << "Viscous flow: Computing pressure using the ideal gas law" << endl; cout << "based on the free-stream temperature and a density computed" << endl; @@ -2563,13 +2560,13 @@ void CEulerSolver::SetNondimensionalization(CConfig *config, unsigned short iMes cout << "Inviscid flow: Computing density based on free-stream" << endl; cout << "temperature and pressure using the ideal gas law." << endl; } - + if (dynamic_grid) cout << "Force coefficients computed using MACH_MOTION." << endl; else cout << "Force coefficients computed using free-stream values." << endl; - + stringstream NonDimTableOut, ModelTableOut; - stringstream Unit; - + stringstream Unit; + cout << endl; PrintingToolbox::CTablePrinter ModelTable(&ModelTableOut); ModelTableOut <<"-- Models:"<< endl; @@ -2579,21 +2576,21 @@ void CEulerSolver::SetNondimensionalization(CConfig *config, unsigned short iMes ModelTable.AddColumn("Fluid Model", 25); ModelTable.SetAlign(PrintingToolbox::CTablePrinter::RIGHT); ModelTable.PrintHeader(); - - PrintingToolbox::CTablePrinter NonDimTable(&NonDimTableOut); + + PrintingToolbox::CTablePrinter NonDimTable(&NonDimTableOut); NonDimTable.AddColumn("Name", 22); NonDimTable.AddColumn("Dim. value", 14); NonDimTable.AddColumn("Ref. value", 14); NonDimTable.AddColumn("Unit", 10); NonDimTable.AddColumn("Non-dim. value", 14); NonDimTable.SetAlign(PrintingToolbox::CTablePrinter::RIGHT); - + NonDimTableOut <<"-- Fluid properties:"<< endl; - + NonDimTable.PrintHeader(); if (viscous) { - + switch(config->GetKind_ViscosityModel()){ case CONSTANT_VISCOSITY: ModelTable << "CONSTANT_VISCOSITY"; @@ -2603,9 +2600,9 @@ void CEulerSolver::SetNondimensionalization(CConfig *config, unsigned short iMes Unit.str(""); NonDimTable.PrintFooter(); break; - + case SUTHERLAND: - ModelTable << "SUTHERLAND"; + ModelTable << "SUTHERLAND"; if (config->GetSystemMeasurements() == SI) Unit << "N.s/m^2"; else if (config->GetSystemMeasurements() == US) Unit << "lbf.s/ft^2"; NonDimTable << "Ref. Viscosity" << config->GetMu_Ref() << config->GetViscosity_Ref() << Unit.str() << config->GetMu_RefND(); @@ -2620,26 +2617,26 @@ void CEulerSolver::SetNondimensionalization(CConfig *config, unsigned short iMes Unit.str(""); NonDimTable.PrintFooter(); break; - + } switch(config->GetKind_ConductivityModel()){ case CONSTANT_PRANDTL: ModelTable << "CONSTANT_PRANDTL"; - NonDimTable << "Prandtl (Lam.)" << "-" << "-" << "-" << config->GetPrandtl_Lam(); + NonDimTable << "Prandtl (Lam.)" << "-" << "-" << "-" << config->GetPrandtl_Lam(); Unit.str(""); - NonDimTable << "Prandtl (Turb.)" << "-" << "-" << "-" << config->GetPrandtl_Turb(); + NonDimTable << "Prandtl (Turb.)" << "-" << "-" << "-" << config->GetPrandtl_Turb(); Unit.str(""); NonDimTable.PrintFooter(); break; - + case CONSTANT_CONDUCTIVITY: ModelTable << "CONSTANT_CONDUCTIVITY"; Unit << "W/m^2.K"; - NonDimTable << "Molecular Cond." << config->GetKt_Constant() << config->GetKt_Constant()/config->GetKt_ConstantND() << Unit.str() << config->GetKt_ConstantND(); + NonDimTable << "Molecular Cond." << config->GetKt_Constant() << config->GetKt_Constant()/config->GetKt_ConstantND() << Unit.str() << config->GetKt_ConstantND(); Unit.str(""); NonDimTable.PrintFooter(); break; - + } } else { ModelTable << "-" << "-"; @@ -2653,7 +2650,7 @@ void CEulerSolver::SetNondimensionalization(CConfig *config, unsigned short iMes else if (config->GetSystemMeasurements() == US) Unit << "lbf.ft/slug.R"; NonDimTable << "Spec. Heat Ratio" << "-" << "-" << "-" << Gamma; Unit.str(""); - + switch(config->GetKind_FluidModel()){ case STANDARD_AIR: ModelTable << "STANDARD_AIR"; @@ -2668,7 +2665,7 @@ void CEulerSolver::SetNondimensionalization(CConfig *config, unsigned short iMes ModelTable << "PR_GAS"; break; } - + if (config->GetKind_FluidModel() == VW_GAS || config->GetKind_FluidModel() == PR_GAS){ NonDimTable << "Critical Pressure" << config->GetPressure_Critical() << config->GetPressure_Ref() << Unit.str() << config->GetPressure_Critical() /config->GetPressure_Ref(); Unit.str(""); @@ -2677,11 +2674,11 @@ void CEulerSolver::SetNondimensionalization(CConfig *config, unsigned short iMes Unit.str(""); } NonDimTable.PrintFooter(); - + NonDimTableOut <<"-- Initial and free-stream conditions:"<< endl; - + NonDimTable.PrintHeader(); - + if (config->GetSystemMeasurements() == SI) Unit << "Pa"; else if (config->GetSystemMeasurements() == US) Unit << "psf"; NonDimTable << "Static Pressure" << config->GetPressure_FreeStream() << config->GetPressure_Ref() << Unit.str() << config->GetPressure_FreeStreamND(); @@ -2729,21 +2726,21 @@ void CEulerSolver::SetNondimensionalization(CConfig *config, unsigned short iMes Unit.str(""); } } - + NonDimTable.PrintFooter(); NonDimTable << "Mach Number" << "-" << "-" << "-" << config->GetMach(); if (viscous){ - NonDimTable << "Reynolds Number" << "-" << "-" << "-" << config->GetReynolds(); + NonDimTable << "Reynolds Number" << "-" << "-" << "-" << config->GetReynolds(); } if (gravity) { - NonDimTable << "Froude Number" << "-" << "-" << "-" << Froude; + NonDimTable << "Froude Number" << "-" << "-" << "-" << Froude; NonDimTable << "Wave Length" << "-" << "-" << "-" << 2.0*PI_NUMBER*Froude*Froude; } NonDimTable.PrintFooter(); ModelTable.PrintFooter(); - + if (unsteady){ - NonDimTableOut << "-- Unsteady conditions" << endl; + NonDimTableOut << "-- Unsteady conditions" << endl; NonDimTable.PrintHeader(); NonDimTable << "Total Time" << config->GetMax_Time() << config->GetTime_Ref() << "s" << config->GetMax_Time()/config->GetTime_Ref(); Unit.str(""); @@ -2751,12 +2748,12 @@ void CEulerSolver::SetNondimensionalization(CConfig *config, unsigned short iMes Unit.str(""); NonDimTable.PrintFooter(); } - + cout << ModelTableOut.str(); cout << NonDimTableOut.str(); - + } - + } void CEulerSolver::SetInitialCondition(CGeometry **geometry, CSolver ***solver_container, CConfig *config, unsigned long TimeIter) { @@ -2766,7 +2763,7 @@ void CEulerSolver::SetInitialCondition(CGeometry **geometry, CSolver ***solver_c su2double X0[3] = {0.0,0.0,0.0}, X1[3] = {0.0,0.0,0.0}, X2[3] = {0.0,0.0,0.0}, X1_X0[3] = {0.0,0.0,0.0}, X2_X0[3] = {0.0,0.0,0.0}, X2_X1[3] = {0.0,0.0,0.0}, CP[3] = {0.0,0.0,0.0}, Distance, DotCheck, Radius; - + unsigned short nDim = geometry[MESH_0]->GetnDim(); bool restart = (config->GetRestart() || config->GetRestart_Flow()); bool rans = (config->GetKind_Turb_Model() != NONE); @@ -2779,64 +2776,64 @@ void CEulerSolver::SetInitialCondition(CGeometry **geometry, CSolver ***solver_c /*--- Loop over the multigrid levels. ---*/ for (iMesh = 0; iMesh <= config->GetnMGLevels(); iMesh++) { - + /*--- Loop over all grid points. ---*/ for (iPoint = 0; iPoint < geometry[iMesh]->GetnPoint(); iPoint++) { - + /* Set the pointers to the coordinates and solution of this DOF. */ const su2double *coor = geometry[iMesh]->node[iPoint]->GetCoord(); su2double *solDOF = solver_container[iMesh][FLOW_SOL]->GetNodes()->GetSolution(iPoint); - + /* Set the solution in this DOF to the initial condition provided by the verification solution class. This can be the exact solution, but this is not necessary. */ VerificationSolution->GetInitialCondition(coor, solDOF); - + } } } - + /*--- Set subsonic initial condition for engine intakes ---*/ - + if (SubsonicEngine) { - + /*--- Set initial boundary condition at iteration 0 ---*/ - + if ((TimeIter == 0) && (!restart)) { - + su2double Velocity_Cyl[3] = {0.0, 0.0, 0.0}, Velocity_CylND[3] = {0.0, 0.0, 0.0}, Viscosity_Cyl, Density_Cyl, Density_CylND, Pressure_CylND, ModVel_Cyl, ModVel_CylND, Energy_CylND, T_ref = 0.0, S = 0.0, Mu_ref = 0.0, *Coord, *SubsonicEngine_Cyl, *SubsonicEngine_Values; - + SubsonicEngine_Values = config->GetSubsonicEngine_Values(); su2double Mach_Cyl = SubsonicEngine_Values[0]; su2double Alpha_Cyl = SubsonicEngine_Values[1]; su2double Beta_Cyl = SubsonicEngine_Values[2]; su2double Pressure_Cyl = SubsonicEngine_Values[3]; su2double Temperature_Cyl = SubsonicEngine_Values[4]; - + su2double Alpha = Alpha_Cyl*PI_NUMBER/180.0; su2double Beta = Beta_Cyl*PI_NUMBER/180.0; - + su2double Gamma_Minus_One = Gamma - 1.0; su2double Gas_Constant = config->GetGas_Constant(); - + su2double Mach2Vel_Cyl = sqrt(Gamma*Gas_Constant*Temperature_Cyl); - + for (iMesh = 0; iMesh <= config->GetnMGLevels(); iMesh++) { - + for (iPoint = 0; iPoint < geometry[iMesh]->GetnPoint(); iPoint++) { - + Velocity_Cyl[0] = cos(Alpha)*cos(Beta)*Mach_Cyl*Mach2Vel_Cyl; Velocity_Cyl[1] = sin(Beta)*Mach_Cyl*Mach2Vel_Cyl; Velocity_Cyl[2] = sin(Alpha)*cos(Beta)*Mach_Cyl*Mach2Vel_Cyl; - + ModVel_Cyl = 0.0; for (iDim = 0; iDim < nDim; iDim++) { ModVel_Cyl += Velocity_Cyl[iDim]*Velocity_Cyl[iDim]; } ModVel_Cyl = sqrt(ModVel_Cyl); - + if (config->GetViscous()) { if (config->GetSystemMeasurements() == SI) { T_ref = 273.15; S = 110.4; Mu_ref = 1.716E-5; } if (config->GetSystemMeasurements() == US) { @@ -2851,65 +2848,65 @@ void CEulerSolver::SetInitialCondition(CGeometry **geometry, CSolver ***solver_c else { Density_Cyl = Pressure_Cyl/(Gas_Constant*Temperature_Cyl); } - + Density_CylND = Density_Cyl/config->GetDensity_Ref(); Pressure_CylND = Pressure_Cyl/config->GetPressure_Ref(); - + for (iDim = 0; iDim < nDim; iDim++) { Velocity_CylND[iDim] = Velocity_Cyl[iDim]/config->GetVelocity_Ref(); } - + ModVel_CylND = 0.0; for (iDim = 0; iDim < nDim; iDim++) { ModVel_CylND += Velocity_CylND[iDim]*Velocity_CylND[iDim]; } ModVel_CylND = sqrt(ModVel_CylND); - + Energy_CylND = Pressure_CylND/(Density_CylND*Gamma_Minus_One)+0.5*ModVel_CylND*ModVel_CylND; - + Coord = geometry[iMesh]->node[iPoint]->GetCoord(); - + SubsonicEngine_Cyl = config->GetSubsonicEngine_Cyl(); - + X0[0] = Coord[0]; X0[1] = Coord[1]; X0[2] = Coord[2]; X1[0] = SubsonicEngine_Cyl[0]; X1[1] = SubsonicEngine_Cyl[1]; X1[2] = SubsonicEngine_Cyl[2]; X2[0] = SubsonicEngine_Cyl[3]; X2[1] = SubsonicEngine_Cyl[4]; X2[2] = SubsonicEngine_Cyl[5]; Radius = SubsonicEngine_Cyl[6]; - + for (iDim = 0; iDim < nDim; iDim++) { X2_X1[iDim]= X1[iDim] - X2[iDim]; X1_X0[iDim]= X0[iDim] - X1[iDim]; X2_X0[iDim]= X0[iDim] - X2[iDim]; } - + CP[0] = (X2_X1[1]*X1_X0[2] - X2_X1[2]*X1_X0[1]); CP[1] = (X2_X1[2]*X1_X0[0] - X2_X1[0]*X1_X0[2]); CP[2] = (X2_X1[0]*X1_X0[1] - X2_X1[1]*X1_X0[0]); - + Distance = sqrt((CP[0]*CP[0]+CP[1]*CP[1]+CP[2]*CP[2])/(X2_X1[0]*X2_X1[0]+X2_X1[1]*X2_X1[1]+X2_X1[2]*X2_X1[2])); - + DotCheck = -(X1_X0[0]*X2_X1[0]+X1_X0[1]*X2_X1[1]+X1_X0[2]*X2_X1[2]); if (DotCheck < 0.0) Distance = sqrt(X1_X0[0]*X1_X0[0]+X1_X0[1]*X1_X0[1]+X1_X0[2]*X1_X0[2]); - + DotCheck = (X2_X0[0]*X2_X1[0]+X2_X0[1]*X2_X1[1]+X2_X0[2]*X2_X1[2]); if (DotCheck < 0.0) Distance = sqrt(X2_X0[0]*X2_X0[0]+X2_X0[1]*X2_X0[1]+X2_X0[2]*X2_X0[2]); - + if (Distance < Radius) { - + solver_container[iMesh][FLOW_SOL]->GetNodes()->SetSolution(iPoint, 0, Density_CylND); for (iDim = 0; iDim < nDim; iDim++) solver_container[iMesh][FLOW_SOL]->GetNodes()->SetSolution(iPoint, iDim+1, Density_CylND*Velocity_CylND[iDim]); solver_container[iMesh][FLOW_SOL]->GetNodes()->SetSolution(iPoint, nVar-1, Density_CylND*Energy_CylND); - + solver_container[iMesh][FLOW_SOL]->GetNodes()->SetSolution_Old(iPoint, 0, Density_CylND); for (iDim = 0; iDim < nDim; iDim++) solver_container[iMesh][FLOW_SOL]->GetNodes()->SetSolution_Old(iPoint, iDim+1, Density_CylND*Velocity_CylND[iDim]); solver_container[iMesh][FLOW_SOL]->GetNodes()->SetSolution_Old(iPoint, nVar-1, Density_CylND*Energy_CylND); - + } - + } - + /*--- Set the MPI communication ---*/ solver_container[iMesh][FLOW_SOL]->InitiateComms(geometry[iMesh], config, SOLUTION); @@ -2917,21 +2914,21 @@ void CEulerSolver::SetInitialCondition(CGeometry **geometry, CSolver ***solver_c solver_container[iMesh][FLOW_SOL]->InitiateComms(geometry[iMesh], config, SOLUTION_OLD); solver_container[iMesh][FLOW_SOL]->CompleteComms(geometry[iMesh], config, SOLUTION_OLD); - + } - + } - + } - + /*--- Make sure that the solution is well initialized for unsteady calculations with dual time-stepping (load additional restarts for 2nd-order). ---*/ - + if (dual_time && (TimeIter == 0 || (restart && (long)TimeIter == (long)config->GetRestart_Iter()))) { - + /*--- Push back the initial condition to previous solution containers for a 1st-order restart or when simply intitializing to freestream. ---*/ - + for (iMesh = 0; iMesh <= config->GetnMGLevels(); iMesh++) { solver_container[iMesh][FLOW_SOL]->GetNodes()->Set_Solution_time_n(); solver_container[iMesh][FLOW_SOL]->GetNodes()->Set_Solution_time_n1(); @@ -2940,20 +2937,20 @@ void CEulerSolver::SetInitialCondition(CGeometry **geometry, CSolver ***solver_c solver_container[iMesh][TURB_SOL]->GetNodes()->Set_Solution_time_n1(); } } - + if ((restart && (long)TimeIter == (long)config->GetRestart_Iter()) && (config->GetTime_Marching() == DT_STEPPING_2ND)) { - + /*--- Load an additional restart file for a 2nd-order restart ---*/ - + solver_container[MESH_0][FLOW_SOL]->LoadRestart(geometry, solver_container, config, SU2_TYPE::Int(config->GetRestart_Iter()-1), true); - + /*--- Load an additional restart file for the turbulence model ---*/ if (rans) solver_container[MESH_0][TURB_SOL]->LoadRestart(geometry, solver_container, config, SU2_TYPE::Int(config->GetRestart_Iter()-1), false); - + /*--- Push back this new solution to time level N. ---*/ - + for (iMesh = 0; iMesh <= config->GetnMGLevels(); iMesh++) { solver_container[iMesh][FLOW_SOL]->GetNodes()->Set_Solution_time_n(); if (rans) { @@ -2966,9 +2963,9 @@ void CEulerSolver::SetInitialCondition(CGeometry **geometry, CSolver ***solver_c } void CEulerSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output) { - + unsigned long ErrorCounter = 0; - + unsigned long InnerIter = config->GetInnerIter(); bool cont_adjoint = config->GetContinuous_Adjoint(); bool disc_adjoint = config->GetDiscrete_Adjoint(); @@ -2989,11 +2986,11 @@ void CEulerSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container config->GetKind_Upwind_Flow() == SLAU2); /*--- Update the angle of attack at the far-field for fixed CL calculations (only direct problem). ---*/ - + if ((fixed_cl) && (!disc_adjoint) && (!cont_adjoint)) { SetFarfield_AoA(geometry, solver_container, config, iMesh, Output); } /*--- Set the primitive variables ---*/ - + ErrorCounter = SetPrimitive_Variables(solver_container, config, Output); /*--- Compute the engine properties ---*/ @@ -3012,11 +3009,11 @@ void CEulerSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container if (nearfield) { Set_MPI_Nearfield(geometry, config); } - + /*--- Upwind second order reconstruction ---*/ - + if ((muscl && !center) && (iMesh == MESH_0) && !Output) { - + /*--- Gradient computation for MUSCL reconstruction. ---*/ if (config->GetKind_Gradient_Method_Recon() == GREEN_GAUSS) @@ -3025,16 +3022,16 @@ void CEulerSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container SetPrimitive_Gradient_LS(geometry, config, true); if (config->GetKind_Gradient_Method_Recon() == WEIGHTED_LEAST_SQUARES) SetPrimitive_Gradient_LS(geometry, config, true); - + /*--- Limiter computation ---*/ - + if (limiter && (iMesh == MESH_0) && !Output && !van_albada) { SetPrimitive_Limiter(geometry, config); } - + } - + /*--- Artificial dissipation ---*/ - + if (center && !Output) { SetMax_Eigenvalue(geometry, config); if ((center_jst) && (iMesh == MESH_0)) { @@ -3042,22 +3039,22 @@ void CEulerSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container SetUndivided_Laplacian(geometry, config); } } - + /*--- Roe Low Dissipation Sensor ---*/ - + if (roe_low_dissipation){ SetRoe_Dissipation(geometry, config); if (kind_row_dissipation == FD_DUCROS || kind_row_dissipation == NTS_DUCROS){ SetUpwind_Ducros_Sensor(geometry, config); } } - + /*--- Initialize the Jacobian matrices ---*/ - + if (implicit && !disc_adjoint) Jacobian.SetValZero(); - + /*--- Error message ---*/ - + if (config->GetComm_Level() == COMM_FULL) { #ifdef HAVE_MPI unsigned long MyErrorCounter = ErrorCounter; ErrorCounter = 0; @@ -3065,74 +3062,74 @@ void CEulerSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container #endif if (iMesh == MESH_0) config->SetNonphysical_Points(ErrorCounter); } - + } void CEulerSolver::Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh) { } unsigned long CEulerSolver::SetPrimitive_Variables(CSolver **solver_container, CConfig *config, bool Output) { - + unsigned long iPoint, nonPhysicalPoints = 0; bool physical = true; - + for (iPoint = 0; iPoint < nPoint; iPoint ++) { - + /*--- Compressible flow, primitive variables nDim+5, (T, vx, vy, vz, P, rho, h, c, lamMu, eddyMu, ThCond, Cp) ---*/ - + physical = nodes->SetPrimVar(iPoint, FluidModel); nodes->SetSecondaryVar(iPoint, FluidModel); /* Check for non-realizable states for reporting. */ - + if (!physical) nonPhysicalPoints++; - + /*--- Initialize the convective, source and viscous residual vector ---*/ - + if (!Output) LinSysRes.SetBlock_Zero(iPoint); - + } - + return nonPhysicalPoints; } void CEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned long Iteration) { - + su2double *Normal, Area, Vol, Mean_SoundSpeed = 0.0, Mean_ProjVel = 0.0, Lambda, Local_Delta_Time, Global_Delta_Time = 1E6, Global_Delta_UnstTimeND, ProjVel, ProjVel_i, ProjVel_j; unsigned long iEdge, iVertex, iPoint, jPoint; unsigned short iDim, iMarker; - + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); bool time_stepping = config->GetTime_Marching() == TIME_STEPPING; bool dual_time = ((config->GetTime_Marching() == DT_STEPPING_1ST) || (config->GetTime_Marching() == DT_STEPPING_2ND)); - + Min_Delta_Time = 1.E30; Max_Delta_Time = 0.0; - + /*--- Set maximum inviscid eigenvalue to zero, and compute sound speed ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) nodes->SetMax_Lambda_Inv(iPoint,0.0); - + /*--- Loop interior edges ---*/ for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - + /*--- Point identification, Normal vector and area ---*/ - + iPoint = geometry->edge[iEdge]->GetNode(0); jPoint = geometry->edge[iEdge]->GetNode(1); - + Normal = geometry->edge[iEdge]->GetNormal(); Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); - + /*--- Mean Values ---*/ - + Mean_ProjVel = 0.5 * (nodes->GetProjVel(iPoint,Normal) + nodes->GetProjVel(jPoint,Normal)); Mean_SoundSpeed = 0.5 * (nodes->GetSoundSpeed(iPoint) + nodes->GetSoundSpeed(jPoint)) * Area; - + /*--- Adjustment for grid movement ---*/ - + if (dynamic_grid) { su2double *GridVel_i = geometry->node[iPoint]->GetGridVel(); su2double *GridVel_j = geometry->node[jPoint]->GetGridVel(); @@ -3143,35 +3140,35 @@ void CEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, } Mean_ProjVel -= 0.5 * (ProjVel_i + ProjVel_j); } - + /*--- Inviscid contribution ---*/ - + Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; if (geometry->node[iPoint]->GetDomain()) nodes->AddMax_Lambda_Inv(iPoint,Lambda); if (geometry->node[jPoint]->GetDomain()) nodes->AddMax_Lambda_Inv(jPoint,Lambda); - + } - + /*--- Loop boundary edges ---*/ - + for (iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) != INTERNAL_BOUNDARY) && (config->GetMarker_All_KindBC(iMarker) != PERIODIC_BOUNDARY)) { for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { - + /*--- Point identification, Normal vector and area ---*/ - + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); - + /*--- Mean Values ---*/ - + Mean_ProjVel = nodes->GetProjVel(iPoint,Normal); Mean_SoundSpeed = nodes->GetSoundSpeed(iPoint) * Area; /*--- Adjustment for grid movement ---*/ - + if (dynamic_grid) { su2double *GridVel = geometry->node[iPoint]->GetGridVel(); ProjVel = 0.0; @@ -3179,7 +3176,7 @@ void CEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, ProjVel += GridVel[iDim]*Normal[iDim]; Mean_ProjVel -= ProjVel; } - + /*--- Inviscid contribution ---*/ Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; if (geometry->node[iPoint]->GetDomain()) { @@ -3188,13 +3185,13 @@ void CEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, } } } - + /*--- Each element uses their own speed, steady state simulation ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + Vol = geometry->node[iPoint]->GetVolume(); - + if (Vol != 0.0) { Local_Delta_Time = nodes->GetLocalCFL(iPoint)*Vol / nodes->GetMax_Lambda_Inv(iPoint); Global_Delta_Time = min(Global_Delta_Time, Local_Delta_Time); @@ -3207,10 +3204,10 @@ void CEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, else { nodes->SetDelta_Time(iPoint,0.0); } - + } - - + + /*--- Compute the max and the min dt (in parallel) ---*/ if (config->GetComm_Level() == COMM_FULL) { #ifdef HAVE_MPI @@ -3219,16 +3216,16 @@ void CEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, MPI_COMM_WORLD); SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); Min_Delta_Time = rbuf_time; - + sbuf_time = Max_Delta_Time; SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MAX, MASTER_NODE, MPI_COMM_WORLD); SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); Max_Delta_Time = rbuf_time; #endif } - + /*--- For exact time solution use the minimum delta time of the whole mesh ---*/ - + if (time_stepping) { #ifdef HAVE_MPI su2double rbuf_time, sbuf_time; @@ -3240,33 +3237,33 @@ void CEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, /*--- If the unsteady CFL is set to zero, it uses the defined unsteady time step, otherwise it computes the time step based on the unsteady CFL ---*/ - + if (config->GetUnst_CFL() == 0.0) { Global_Delta_Time = config->GetDelta_UnstTime(); } config->SetDelta_UnstTimeND(Global_Delta_Time); for (iPoint = 0; iPoint < nPointDomain; iPoint++){ - + /*--- Sets the regular CFL equal to the unsteady CFL ---*/ - + nodes->SetLocalCFL(iPoint, config->GetUnst_CFL()); nodes->SetDelta_Time(iPoint, Global_Delta_Time); Min_Delta_Time = Global_Delta_Time; Max_Delta_Time = Global_Delta_Time; - + } } - + /*--- Recompute the unsteady time step for the dual time strategy if the unsteady CFL is diferent from 0 ---*/ - + if ((dual_time) && (Iteration == 0) && (config->GetUnst_CFL() != 0.0) && (iMesh == MESH_0)) { Global_Delta_UnstTimeND = 1e30; for (iPoint = 0; iPoint < nPointDomain; iPoint++){ Global_Delta_UnstTimeND = min(Global_Delta_UnstTimeND,config->GetUnst_CFL()*Global_Delta_Time/nodes->GetLocalCFL(iPoint)); } - + #ifdef HAVE_MPI su2double rbuf_time, sbuf_time; sbuf_time = Global_Delta_UnstTimeND; @@ -3276,9 +3273,9 @@ void CEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, #endif config->SetDelta_UnstTimeND(Global_Delta_UnstTimeND); } - + /*--- The pseudo local time (explicit integration) cannot be greater than the physical time ---*/ - + if (dual_time) for (iPoint = 0; iPoint < nPointDomain; iPoint++) { if (!implicit) { @@ -3286,55 +3283,55 @@ void CEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, nodes->SetDelta_Time(iPoint,Local_Delta_Time); } } - + } void CEulerSolver::Centered_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short iMesh, unsigned short iRKStep) { - + unsigned long iEdge, iPoint, jPoint; - + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); bool jst_scheme = ((config->GetKind_Centered_Flow() == JST) && (iMesh == MESH_0)); - + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - + /*--- Points in edge, set normal vectors, and number of neighbors ---*/ - + iPoint = geometry->edge[iEdge]->GetNode(0); jPoint = geometry->edge[iEdge]->GetNode(1); numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); numerics->SetNeighbor(geometry->node[iPoint]->GetnNeighbor(), geometry->node[jPoint]->GetnNeighbor()); - + /*--- Set primitive variables w/o reconstruction ---*/ - + numerics->SetPrimitive(nodes->GetPrimitive(iPoint), nodes->GetPrimitive(jPoint)); - + /*--- Set the largest convective eigenvalue ---*/ - + numerics->SetLambda(nodes->GetLambda(iPoint), nodes->GetLambda(jPoint)); - + /*--- Set undivided laplacian an pressure based sensor ---*/ - + if (jst_scheme) { numerics->SetUndivided_Laplacian(nodes->GetUndivided_Laplacian(iPoint), nodes->GetUndivided_Laplacian(jPoint)); numerics->SetSensor(nodes->GetSensor(iPoint), nodes->GetSensor(jPoint)); } - + /*--- Grid movement ---*/ - + if (dynamic_grid) { numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[jPoint]->GetGridVel()); } - + /*--- Compute residuals, and Jacobians ---*/ - + numerics->ComputeResidual(Res_Conv, Jacobian_i, Jacobian_j, config); - + /*--- Update convective and artificial dissipation residuals ---*/ - + LinSysRes.AddBlock(iPoint, Res_Conv); LinSysRes.SubtractBlock(jPoint, Res_Conv); - + /*--- Set implicit computation ---*/ if (implicit) { Jacobian.UpdateBlocks(iEdge, iPoint, jPoint, Jacobian_i, Jacobian_j); @@ -3345,17 +3342,17 @@ void CEulerSolver::Centered_Residual(CGeometry *geometry, CSolver **solver_conta void CEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short iMesh) { - + su2double **Gradient_i, **Gradient_j, Project_Grad_i, Project_Grad_j, RoeVelocity[3] = {0.0,0.0,0.0}, R, sq_vel, RoeEnthalpy, *V_i, *V_j, *S_i, *S_j, *Limiter_i = NULL, *Limiter_j = NULL, sqvel, Sensor_i, Sensor_j, Dissipation_i, Dissipation_j, *Coord_i, *Coord_j; - + su2double z, velocity2_i, velocity2_j, mach_i, mach_j, vel_i_corr[3], vel_j_corr[3]; - + unsigned long iEdge, iPoint, jPoint, counter_local = 0, counter_global = 0; unsigned short iDim, iVar; - + bool neg_density_i = false, neg_density_j = false, neg_pressure_i = false, neg_pressure_j = false, neg_sound_speed = false; - + unsigned long InnerIter = config->GetInnerIter(); bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); bool muscl = (config->GetMUSCL_Flow() && (iMesh == MESH_0)); @@ -3365,44 +3362,44 @@ void CEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_contain bool van_albada = config->GetKind_SlopeLimit_Flow() == VAN_ALBADA_EDGE; bool low_mach_corr = config->Low_Mach_Correction(); unsigned short kind_dissipation = config->GetKind_RoeLowDiss(); - + /*--- Loop over all the edges ---*/ for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - + /*--- Points in edge and normal vectors ---*/ - + iPoint = geometry->edge[iEdge]->GetNode(0); jPoint = geometry->edge[iEdge]->GetNode(1); numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); - + /*--- Roe Turkel preconditioning ---*/ - + if (roe_turkel) { sqvel = 0.0; for (iDim = 0; iDim < nDim; iDim ++) sqvel += config->GetVelocity_FreeStream()[iDim]*config->GetVelocity_FreeStream()[iDim]; numerics->SetVelocity2_Inf(sqvel); } - + /*--- Grid movement ---*/ - + if (dynamic_grid) numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[jPoint]->GetGridVel()); - + /*--- Get primitive variables ---*/ - + V_i = nodes->GetPrimitive(iPoint); V_j = nodes->GetPrimitive(jPoint); S_i = nodes->GetSecondary(iPoint); S_j = nodes->GetSecondary(jPoint); /*--- High order reconstruction using MUSCL strategy ---*/ - + if (muscl) { - + for (iDim = 0; iDim < nDim; iDim++) { Vector_i[iDim] = 0.5*(geometry->node[jPoint]->GetCoord(iDim) - geometry->node[iPoint]->GetCoord(iDim)); Vector_j[iDim] = 0.5*(geometry->node[iPoint]->GetCoord(iDim) - geometry->node[jPoint]->GetCoord(iDim)); } - + Gradient_i = nodes->GetGradient_Reconstruction(iPoint); Gradient_j = nodes->GetGradient_Reconstruction(jPoint); @@ -3410,7 +3407,7 @@ void CEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_contain Limiter_i = nodes->GetLimiter_Primitive(iPoint); Limiter_j = nodes->GetLimiter_Primitive(jPoint); } - + for (iVar = 0; iVar < nPrimVarGrad; iVar++) { Project_Grad_i = 0.0; Project_Grad_j = 0.0; for (iDim = 0; iDim < nDim; iDim++) { @@ -3442,7 +3439,7 @@ void CEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_contain velocity2_i = 0.0; velocity2_j = 0.0; - + for (iDim = 0; iDim < nDim; iDim++) { velocity2_i += Primitive_i[iDim+1]*Primitive_i[iDim+1]; velocity2_j += Primitive_j[iDim+1]*Primitive_j[iDim+1]; @@ -3468,18 +3465,18 @@ void CEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_contain FluidModel->SetEnergy_Prho(Primitive_i[nDim+1],Primitive_i[nDim+2]); Primitive_i[nDim+3]= FluidModel->GetStaticEnergy() + Primitive_i[nDim+1]/Primitive_i[nDim+2] + 0.5*velocity2_i; - + FluidModel->SetEnergy_Prho(Primitive_j[nDim+1],Primitive_j[nDim+2]); Primitive_j[nDim+3]= FluidModel->GetStaticEnergy() + Primitive_j[nDim+1]/Primitive_j[nDim+2] + 0.5*velocity2_j; - + } - + /*--- Check for non-physical solutions after reconstruction. If found, use the cell-average value of the solution. This results in a locally first-order approximation, but this is typically only active - during the start-up of a calculation. If non-physical, use the + during the start-up of a calculation. If non-physical, use the cell-averaged state. ---*/ - + neg_pressure_i = (Primitive_i[nDim+1] < 0.0); neg_pressure_j = (Primitive_j[nDim+1] < 0.0); neg_density_i = (Primitive_i[nDim+2] < 0.0); neg_density_j = (Primitive_j[nDim+2] < 0.0); @@ -3514,13 +3511,13 @@ void CEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_contain nodes->SetNon_Physical(jPoint, true); Secondary_j[0] = S_j[0]; Secondary_j[1] = S_j[1]; } - + if (!neg_sound_speed && !neg_density_i && !neg_pressure_i) nodes->SetNon_Physical(iPoint, false); - + if (!neg_sound_speed && !neg_density_j && !neg_pressure_j) nodes->SetNon_Physical(jPoint, false); - + /* Lastly, check for existing first-order points still active from previous iterations. */ @@ -3537,25 +3534,25 @@ void CEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_contain numerics->SetPrimitive(Primitive_i, Primitive_j); numerics->SetSecondary(Secondary_i, Secondary_j); - + } else { - + /*--- Set conservative variables without reconstruction ---*/ - + numerics->SetPrimitive(V_i, V_j); numerics->SetSecondary(S_i, S_j); - + } - + /*--- Roe Low Dissipation Scheme ---*/ - + if (kind_dissipation != NO_ROELOWDISS){ - + Dissipation_i = nodes->GetRoe_Dissipation(iPoint); Dissipation_j = nodes->GetRoe_Dissipation(jPoint); numerics->SetDissipation(Dissipation_i, Dissipation_j); - + if (kind_dissipation == FD_DUCROS || kind_dissipation == NTS_DUCROS){ Sensor_i = nodes->GetSensor(iPoint); Sensor_j = nodes->GetSensor(jPoint); @@ -3567,33 +3564,33 @@ void CEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_contain numerics->SetCoord(Coord_i, Coord_j); } } - + /*--- Compute the residual ---*/ - + numerics->ComputeResidual(Res_Conv, Jacobian_i, Jacobian_j, config); /*--- Update residual value ---*/ - + LinSysRes.AddBlock(iPoint, Res_Conv); LinSysRes.SubtractBlock(jPoint, Res_Conv); - + /*--- Set implicit Jacobians ---*/ - + if (implicit) { Jacobian.UpdateBlocks(iEdge, iPoint, jPoint, Jacobian_i, Jacobian_j); } /*--- Set the final value of the Roe dissipation coefficient ---*/ - + if (kind_dissipation != NO_ROELOWDISS){ nodes->SetRoe_Dissipation(iPoint,numerics->GetDissipation()); - nodes->SetRoe_Dissipation(jPoint,numerics->GetDissipation()); + nodes->SetRoe_Dissipation(jPoint,numerics->GetDissipation()); } - + } /*--- Warning message about non-physical reconstructions ---*/ - + if (config->GetComm_Level() == COMM_FULL) { #ifdef HAVE_MPI SU2_MPI::Reduce(&counter_local, &counter_global, 1, MPI_UNSIGNED_LONG, MPI_SUM, MASTER_NODE, MPI_COMM_WORLD); @@ -3605,45 +3602,45 @@ void CEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_contain } void CEulerSolver::ComputeConsExtrapolation(CConfig *config) { - + unsigned short iDim; - + su2double density_i = Primitive_i[nDim+2]; su2double pressure_i = Primitive_i[nDim+1]; su2double velocity2_i = 0.0; for (iDim = 0; iDim < nDim; iDim++) { velocity2_i += Primitive_i[iDim+1]*Primitive_i[iDim+1]; } - + FluidModel->SetTDState_Prho(pressure_i, density_i); - + Primitive_i[0]= FluidModel->GetTemperature(); Primitive_i[nDim+3]= FluidModel->GetStaticEnergy() + Primitive_i[nDim+1]/Primitive_i[nDim+2] + 0.5*velocity2_i; Primitive_i[nDim+4]= FluidModel->GetSoundSpeed(); Secondary_i[0]=FluidModel->GetdPdrho_e(); Secondary_i[1]=FluidModel->GetdPde_rho(); - - + + su2double density_j = Primitive_j[nDim+2]; su2double pressure_j = Primitive_j[nDim+1]; su2double velocity2_j = 0.0; for (iDim = 0; iDim < nDim; iDim++) { velocity2_j += Primitive_j[iDim+1]*Primitive_j[iDim+1]; } - + FluidModel->SetTDState_Prho(pressure_j, density_j); - + Primitive_j[0]= FluidModel->GetTemperature(); Primitive_j[nDim+3]= FluidModel->GetStaticEnergy() + Primitive_j[nDim+1]/Primitive_j[nDim+2] + 0.5*velocity2_j; Primitive_j[nDim+4]=FluidModel->GetSoundSpeed(); Secondary_j[0]=FluidModel->GetdPdrho_e(); Secondary_j[1]=FluidModel->GetdPde_rho(); - + } void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CNumerics *second_numerics, CConfig *config, unsigned short iMesh) { - + unsigned short iVar; unsigned long iPoint; bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); @@ -3675,7 +3672,7 @@ void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_contain /*--- Add the source residual to the total ---*/ LinSysRes.AddBlock(iPoint, Residual); - + } } @@ -3683,218 +3680,218 @@ void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_contain /*--- Include the residual contribution from GCL due to the static mesh movement that is set for rotating frame. ---*/ - + SetRotatingFrame_GCL(geometry, config); /*--- Loop over all points ---*/ for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /*--- Load the conservative variables ---*/ numerics->SetConservative(nodes->GetSolution(iPoint), nodes->GetSolution(iPoint)); - + /*--- Load the volume of the dual mesh cell ---*/ numerics->SetVolume(geometry->node[iPoint]->GetVolume()); - + /*--- Compute the rotating frame source residual ---*/ numerics->ComputeResidual(Residual, Jacobian_i, config); - + /*--- Add the source residual to the total ---*/ LinSysRes.AddBlock(iPoint, Residual); /*--- Add the implicit Jacobian contribution ---*/ if (implicit) Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - + } } - + if (axisymmetric) { - + /*--- Zero out Jacobian structure ---*/ if (implicit) { for (iVar = 0; iVar < nVar; iVar ++) for (unsigned short jVar = 0; jVar < nVar; jVar ++) Jacobian_i[iVar][jVar] = 0.0; } - + /*--- loop over points ---*/ for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /*--- Set solution ---*/ numerics->SetConservative(nodes->GetSolution(iPoint), nodes->GetSolution(iPoint)); /*--- Set control volume ---*/ numerics->SetVolume(geometry->node[iPoint]->GetVolume()); - + /*--- Set y coordinate ---*/ numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[iPoint]->GetCoord()); - + /*--- Compute Source term Residual ---*/ numerics->ComputeResidual(Residual, Jacobian_i, config); - + /*--- Add Residual ---*/ LinSysRes.AddBlock(iPoint, Residual); - + /*--- Implicit part ---*/ if (implicit) Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); } } - + if (gravity) { - + /*--- loop over points ---*/ for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /*--- Set solution ---*/ numerics->SetConservative(nodes->GetSolution(iPoint), nodes->GetSolution(iPoint)); - + /*--- Set control volume ---*/ numerics->SetVolume(geometry->node[iPoint]->GetVolume()); - + /*--- Compute Source term Residual ---*/ numerics->ComputeResidual(Residual, config); - + /*--- Add Residual ---*/ LinSysRes.AddBlock(iPoint, Residual); - + } - + } - + if (harmonic_balance) { - + su2double Volume, Source; - + /*--- loop over points ---*/ for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /*--- Get control volume ---*/ Volume = geometry->node[iPoint]->GetVolume(); - + /*--- Get stored time spectral source term ---*/ for (iVar = 0; iVar < nVar; iVar++) { - Source = nodes->GetHarmonicBalance_Source(iPoint,iVar); + Source = nodes->GetHarmonicBalance_Source(iPoint,iVar); Residual[iVar] = Source*Volume; } - + /*--- Add Residual ---*/ LinSysRes.AddBlock(iPoint, Residual); - + } } - + if (windgust) { - + /*--- Loop over all points ---*/ for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /*--- Load the wind gust ---*/ numerics->SetWindGust(nodes->GetWindGust(iPoint), nodes->GetWindGust(iPoint)); - + /*--- Load the wind gust derivatives ---*/ numerics->SetWindGustDer(nodes->GetWindGustDer(iPoint), nodes->GetWindGustDer(iPoint)); - + /*--- Load the primitive variables ---*/ numerics->SetPrimitive(nodes->GetPrimitive(iPoint), nodes->GetPrimitive(iPoint)); - + /*--- Load the volume of the dual mesh cell ---*/ numerics->SetVolume(geometry->node[iPoint]->GetVolume()); - + /*--- Compute the rotating frame source residual ---*/ numerics->ComputeResidual(Residual, Jacobian_i, config); - + /*--- Add the source residual to the total ---*/ LinSysRes.AddBlock(iPoint, Residual); - + /*--- Add the implicit Jacobian contribution ---*/ if (implicit) Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - + } } - + /*--- Check if a verification solution is to be computed. ---*/ - + if ( VerificationSolution ) { if ( VerificationSolution->IsManufacturedSolution() ) { - + /*--- Get the physical time. ---*/ su2double time = 0.0; if (config->GetTime_Marching()) time = config->GetPhysicalTime(); - + /*--- Loop over points ---*/ for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /*--- Get control volume size. ---*/ su2double Volume = geometry->node[iPoint]->GetVolume(); - + /*--- Get the current point coordinates. ---*/ const su2double *coor = geometry->node[iPoint]->GetCoord(); - + /*--- Get the MMS source term. ---*/ vector sourceMan(nVar,0.0); VerificationSolution->GetMMSSourceTerm(coor, time, sourceMan.data()); - + /*--- Compute the residual for this control volume. ---*/ for (iVar = 0; iVar < nVar; iVar++) { Residual[iVar] = sourceMan[iVar]*Volume; } - + /*--- Subtract Residual ---*/ LinSysRes.SubtractBlock(iPoint, Residual); - + } } } - + } void CEulerSolver::Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short iMesh) { - + /* This method should be used to call any new source terms for a particular problem*/ /* This method calls the new child class in CNumerics, where the new source term should be implemented. */ - + /* Next we describe how to get access to some important quanties for this method */ /* Access to all points in the current geometric mesh by saying: nPointDomain */ /* Get the vector of conservative variables at some point iPoint = nodes->GetSolution(iPoint) */ /* Get the volume (or area in 2D) associated with iPoint = nodes->GetVolume(iPoint) */ /* Get the vector of geometric coordinates of point iPoint = nodes->GetCoord(iPoint) */ - + } void CEulerSolver::SetMax_Eigenvalue(CGeometry *geometry, CConfig *config) { - + su2double *Normal, Area, Mean_SoundSpeed = 0.0, Mean_ProjVel = 0.0, Lambda, ProjVel, ProjVel_i, ProjVel_j, *GridVel, *GridVel_i, *GridVel_j; unsigned long iEdge, iVertex, iPoint, jPoint; unsigned short iDim, iMarker; - + /*--- Set maximum inviscid eigenvalue to zero, and compute sound speed ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { nodes->SetLambda(iPoint,0.0); } - + /*--- Loop interior edges ---*/ - + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - + /*--- Point identification, Normal vector and area ---*/ - + iPoint = geometry->edge[iEdge]->GetNode(0); jPoint = geometry->edge[iEdge]->GetNode(1); - + Normal = geometry->edge[iEdge]->GetNormal(); Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); - + /*--- Mean Values ---*/ - + Mean_ProjVel = 0.5 * (nodes->GetProjVel(iPoint,Normal) + nodes->GetProjVel(jPoint,Normal)); Mean_SoundSpeed = 0.5 * (nodes->GetSoundSpeed(iPoint) + nodes->GetSoundSpeed(jPoint)) * Area; /*--- Adjustment for grid movement ---*/ - + if (dynamic_grid) { GridVel_i = geometry->node[iPoint]->GetGridVel(); GridVel_j = geometry->node[jPoint]->GetGridVel(); @@ -3905,35 +3902,35 @@ void CEulerSolver::SetMax_Eigenvalue(CGeometry *geometry, CConfig *config) { } Mean_ProjVel -= 0.5 * (ProjVel_i + ProjVel_j); } - + /*--- Inviscid contribution ---*/ - + Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; if (geometry->node[iPoint]->GetDomain()) nodes->AddLambda(iPoint, Lambda); if (geometry->node[jPoint]->GetDomain()) nodes->AddLambda(jPoint, Lambda); - + } - + /*--- Loop boundary edges ---*/ - + for (iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) != INTERNAL_BOUNDARY) && (config->GetMarker_All_KindBC(iMarker) != PERIODIC_BOUNDARY)) { for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { - + /*--- Point identification, Normal vector and area ---*/ - + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); - + /*--- Mean Values ---*/ - + Mean_ProjVel = nodes->GetProjVel(iPoint,Normal); Mean_SoundSpeed = nodes->GetSoundSpeed(iPoint) * Area; /*--- Adjustment for grid movement ---*/ - + if (dynamic_grid) { GridVel = geometry->node[iPoint]->GetGridVel(); ProjVel = 0.0; @@ -3941,9 +3938,9 @@ void CEulerSolver::SetMax_Eigenvalue(CGeometry *geometry, CConfig *config) { ProjVel += GridVel[iDim]*Normal[iDim]; Mean_ProjVel -= ProjVel; } - + /*--- Inviscid contribution ---*/ - + Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; if (geometry->node[iPoint]->GetDomain()) { nodes->AddLambda(iPoint,Lambda); @@ -3951,7 +3948,7 @@ void CEulerSolver::SetMax_Eigenvalue(CGeometry *geometry, CConfig *config) { } } } - + /*--- Correct the eigenvalue values across any periodic boundaries. ---*/ for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { @@ -3960,217 +3957,217 @@ void CEulerSolver::SetMax_Eigenvalue(CGeometry *geometry, CConfig *config) { } /*--- MPI parallelization ---*/ - + InitiateComms(geometry, config, MAX_EIGENVALUE); CompleteComms(geometry, config, MAX_EIGENVALUE); - + } void CEulerSolver::SetUndivided_Laplacian(CGeometry *geometry, CConfig *config) { - + unsigned long iPoint, jPoint, iEdge; su2double Pressure_i = 0, Pressure_j = 0, *Diff; unsigned short iVar; bool boundary_i, boundary_j; - + Diff = new su2double[nVar]; - + nodes->SetUnd_LaplZero(); - + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - + iPoint = geometry->edge[iEdge]->GetNode(0); jPoint = geometry->edge[iEdge]->GetNode(1); - + /*--- Solution differences ---*/ - + for (iVar = 0; iVar < nVar; iVar++) Diff[iVar] = nodes->GetSolution(iPoint,iVar) - nodes->GetSolution(jPoint,iVar); - + /*--- Correction for compressible flows which use the enthalpy ---*/ - + Pressure_i = nodes->GetPressure(iPoint); Pressure_j = nodes->GetPressure(jPoint); Diff[nVar-1] = (nodes->GetSolution(iPoint,nVar-1) + Pressure_i) - (nodes->GetSolution(jPoint,nVar-1) + Pressure_j); - + boundary_i = geometry->node[iPoint]->GetPhysicalBoundary(); boundary_j = geometry->node[jPoint]->GetPhysicalBoundary(); - + /*--- Both points inside the domain, or both in the boundary ---*/ - + if ((!boundary_i && !boundary_j) || (boundary_i && boundary_j)) { if (geometry->node[iPoint]->GetDomain()) nodes->SubtractUnd_Lapl(iPoint, Diff); if (geometry->node[jPoint]->GetDomain()) nodes->AddUnd_Lapl(jPoint, Diff); } - + /*--- iPoint inside the domain, jPoint on the boundary ---*/ - + if (!boundary_i && boundary_j) if (geometry->node[iPoint]->GetDomain()) nodes->SubtractUnd_Lapl(iPoint, Diff); - + /*--- jPoint inside the domain, iPoint on the boundary ---*/ - + if (boundary_i && !boundary_j) if (geometry->node[jPoint]->GetDomain()) nodes->AddUnd_Lapl(jPoint, Diff); - + } - + /*--- Correct the Laplacian values across any periodic boundaries. ---*/ for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_LAPLACIAN); CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_LAPLACIAN); } - + /*--- MPI parallelization ---*/ - + InitiateComms(geometry, config, UNDIVIDED_LAPLACIAN); CompleteComms(geometry, config, UNDIVIDED_LAPLACIAN); - + delete [] Diff; - + } void CEulerSolver::SetCentered_Dissipation_Sensor(CGeometry *geometry, CConfig *config) { - + unsigned long iEdge, iPoint, jPoint; su2double Pressure_i = 0.0, Pressure_j = 0.0; bool boundary_i, boundary_j; - + /*--- Reset variables to store the undivided pressure ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { iPoint_UndLapl[iPoint] = 0.0; jPoint_UndLapl[iPoint] = 0.0; } - + /*--- Evaluate the pressure sensor ---*/ - + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - + iPoint = geometry->edge[iEdge]->GetNode(0); jPoint = geometry->edge[iEdge]->GetNode(1); - + Pressure_i = nodes->GetPressure(iPoint); Pressure_j = nodes->GetPressure(jPoint); - + boundary_i = geometry->node[iPoint]->GetPhysicalBoundary(); boundary_j = geometry->node[jPoint]->GetPhysicalBoundary(); - + /*--- Both points inside the domain, or both on the boundary ---*/ - + if ((!boundary_i && !boundary_j) || (boundary_i && boundary_j)) { if (geometry->node[iPoint]->GetDomain()) { iPoint_UndLapl[iPoint] += (Pressure_j - Pressure_i); jPoint_UndLapl[iPoint] += (Pressure_i + Pressure_j); } if (geometry->node[jPoint]->GetDomain()) { iPoint_UndLapl[jPoint] += (Pressure_i - Pressure_j); jPoint_UndLapl[jPoint] += (Pressure_i + Pressure_j); } } - + /*--- iPoint inside the domain, jPoint on the boundary ---*/ - + if (!boundary_i && boundary_j) if (geometry->node[iPoint]->GetDomain()) { iPoint_UndLapl[iPoint] += (Pressure_j - Pressure_i); jPoint_UndLapl[iPoint] += (Pressure_i + Pressure_j); } - + /*--- jPoint inside the domain, iPoint on the boundary ---*/ - + if (boundary_i && !boundary_j) if (geometry->node[jPoint]->GetDomain()) { iPoint_UndLapl[jPoint] += (Pressure_i - Pressure_j); jPoint_UndLapl[jPoint] += (Pressure_i + Pressure_j); } - + } - + /*--- Correct the sensor values across any periodic boundaries. ---*/ for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_SENSOR); CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_SENSOR); } - + /*--- Set pressure switch for each point ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) nodes->SetSensor(iPoint,fabs(iPoint_UndLapl[iPoint]) / jPoint_UndLapl[iPoint]); - + /*--- MPI parallelization ---*/ - + InitiateComms(geometry, config, SENSOR); CompleteComms(geometry, config, SENSOR); - + } void CEulerSolver::SetUpwind_Ducros_Sensor(CGeometry *geometry, CConfig *config){ - + unsigned long iPoint, jPoint; unsigned short iNeigh, iDim; - + su2double *Vorticity; - + su2double uixi = 0.0, Ducros_i = 0.0, Ducros_j = 0.0, Omega = 0.0; - + for (iPoint = 0; iPoint < geometry->GetnPoint(); iPoint++){ - + /*---- Dilatation for iPoint ---*/ - + uixi=0.0; for(iDim = 0; iDim < nDim; iDim++){ uixi += nodes->GetGradient_Primitive(iPoint,iDim+1, iDim); - } - + } + /*--- Compute norm of vorticity ---*/ - - Vorticity = nodes->GetVorticity(iPoint); + + Vorticity = nodes->GetVorticity(iPoint); Omega = 0.0; for (iDim = 0; iDim < nDim; iDim++){ Omega += Vorticity[iDim]*Vorticity[iDim]; } Omega = sqrt(Omega); - + /*---- Ducros sensor for iPoint ---*/ - + if (config->GetKind_RoeLowDiss() == FD_DUCROS){ Ducros_i = -uixi / (fabs(uixi) + Omega + 1e-20); } else if (config->GetKind_RoeLowDiss() == NTS_DUCROS){ Ducros_i = pow(uixi,2.0) /(pow(uixi,2.0)+ pow(Omega,2.0) + 1e-20); } - + nodes->SetSensor(iPoint,Ducros_i); - + /*---- Ducros sensor for neighbor points of iPoint to avoid lower the dissipation in regions near the shock ---*/ - + for (iNeigh = 0; iNeigh > geometry->node[iPoint]->GetnNeighbor(); iNeigh++){ - + jPoint = geometry->node[iPoint]->GetPoint(iNeigh); - + /*---- Dilatation for jPoint ---*/ - + uixi=0.0; for(iDim = 0; iDim < nDim; iDim++){ uixi += nodes->GetGradient_Primitive(jPoint,iDim+1, iDim); - } - + } + /*--- Compute norm of vorticity ---*/ - - Vorticity = nodes->GetVorticity(jPoint); + + Vorticity = nodes->GetVorticity(jPoint); Omega = 0.0; for (iDim = 0; iDim < nDim; iDim++){ Omega += Vorticity[iDim]*Vorticity[iDim]; } Omega = sqrt(Omega); - + if (config->GetKind_RoeLowDiss() == FD_DUCROS){ Ducros_j = -uixi / (fabs(uixi) + Omega + 1e-20); } else if (config->GetKind_RoeLowDiss() == NTS_DUCROS){ Ducros_j = pow(uixi,2.0) /(pow(uixi,2.0)+ pow(Omega,2.0) + 1e-20); - } + } nodes->SetSensor(iPoint, max(nodes->GetSensor(iPoint), Ducros_j)); } } - + InitiateComms(geometry, config, SENSOR); CompleteComms(geometry, config, SENSOR); - + } void CEulerSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { - + unsigned long iVertex, iPoint; unsigned short iDim, iMarker, Boundary, Monitoring, iMarker_Monitoring; su2double Pressure = 0.0, *Normal = NULL, MomentDist[3] = {0.0,0.0,0.0}, *Coord, @@ -4183,7 +4180,7 @@ void CEulerSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { #ifdef HAVE_MPI su2double MyAllBound_CD_Inv, MyAllBound_CL_Inv, MyAllBound_CSF_Inv, MyAllBound_CMx_Inv, MyAllBound_CMy_Inv, MyAllBound_CMz_Inv, MyAllBound_CoPx_Inv, MyAllBound_CoPy_Inv, MyAllBound_CoPz_Inv, MyAllBound_CFx_Inv, MyAllBound_CFy_Inv, MyAllBound_CFz_Inv, MyAllBound_CT_Inv, MyAllBound_CQ_Inv, MyAllBound_CNearFieldOF_Inv, *MySurface_CL_Inv = NULL, *MySurface_CD_Inv = NULL, *MySurface_CSF_Inv = NULL, *MySurface_CEff_Inv = NULL, *MySurface_CFx_Inv = NULL, *MySurface_CFy_Inv = NULL, *MySurface_CFz_Inv = NULL, *MySurface_CMx_Inv = NULL, *MySurface_CMy_Inv = NULL, *MySurface_CMz_Inv = NULL; #endif - + su2double Alpha = config->GetAoA()*PI_NUMBER/180.0; su2double Beta = config->GetAoS()*PI_NUMBER/180.0; su2double RefArea = config->GetRefArea(); @@ -4199,7 +4196,7 @@ void CEulerSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { For dynamic meshes, use the motion Mach number as a reference value for computing the force coefficients. Otherwise, use the freestream values, which is the standard convention. ---*/ - + RefTemp = Temperature_Inf; RefDensity = Density_Inf; RefPressure = Pressure_Inf; @@ -4213,25 +4210,25 @@ void CEulerSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { for (iDim = 0; iDim < nDim; iDim++) RefVel2 += Velocity_Inf[iDim]*Velocity_Inf[iDim]; } - + factor = 1.0 / (0.5*RefDensity*RefArea*RefVel2); - + /*-- Variables initialization ---*/ - + Total_CD = 0.0; Total_CL = 0.0; Total_CSF = 0.0; Total_CEff = 0.0; Total_CMx = 0.0; Total_CMy = 0.0; Total_CMz = 0.0; Total_CoPx = 0.0; Total_CoPy = 0.0; Total_CoPz = 0.0; Total_CFx = 0.0; Total_CFy = 0.0; Total_CFz = 0.0; Total_CT = 0.0; Total_CQ = 0.0; Total_CMerit = 0.0; Total_CNearFieldOF = 0.0; Total_Heat = 0.0; Total_MaxHeat = 0.0; - + AllBound_CD_Inv = 0.0; AllBound_CL_Inv = 0.0; AllBound_CSF_Inv = 0.0; AllBound_CMx_Inv = 0.0; AllBound_CMy_Inv = 0.0; AllBound_CMz_Inv = 0.0; AllBound_CoPx_Inv = 0.0; AllBound_CoPy_Inv = 0.0; AllBound_CoPz_Inv = 0.0; AllBound_CFx_Inv = 0.0; AllBound_CFy_Inv = 0.0; AllBound_CFz_Inv = 0.0; AllBound_CT_Inv = 0.0; AllBound_CQ_Inv = 0.0; AllBound_CMerit_Inv = 0.0; AllBound_CNearFieldOF_Inv = 0.0; AllBound_CEff_Inv = 0.0; - + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { Surface_CL_Inv[iMarker_Monitoring] = 0.0; Surface_CD_Inv[iMarker_Monitoring] = 0.0; Surface_CSF_Inv[iMarker_Monitoring] = 0.0; Surface_CEff_Inv[iMarker_Monitoring] = 0.0; @@ -4244,16 +4241,16 @@ void CEulerSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { Surface_CFz[iMarker_Monitoring] = 0.0; Surface_CMx[iMarker_Monitoring] = 0.0; Surface_CMy[iMarker_Monitoring] = 0.0; Surface_CMz[iMarker_Monitoring] = 0.0; } - + /*--- Loop over the Euler and Navier-Stokes markers ---*/ - + for (iMarker = 0; iMarker < nMarker; iMarker++) { - + Boundary = config->GetMarker_All_KindBC(iMarker); Monitoring = config->GetMarker_All_Monitoring(iMarker); - + /*--- Obtain the origin for the moment computation for a particular marker ---*/ - + if (Monitoring == YES) { for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { Monitoring_Tag = config->GetMarker_Monitoring_TagBound(iMarker_Monitoring); @@ -4262,23 +4259,23 @@ void CEulerSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { Origin = config->GetRefOriginMoment(iMarker_Monitoring); } } - + if ((Boundary == EULER_WALL) || (Boundary == HEAT_FLUX) || (Boundary == ISOTHERMAL) || (Boundary == NEARFIELD_BOUNDARY) || (Boundary == CHT_WALL_INTERFACE) || (Boundary == INLET_FLOW) || (Boundary == OUTLET_FLOW) || (Boundary == ACTDISK_INLET) || (Boundary == ACTDISK_OUTLET)|| (Boundary == ENGINE_INFLOW) || (Boundary == ENGINE_EXHAUST)) { - + /*--- Forces initialization at each Marker ---*/ - + CD_Inv[iMarker] = 0.0; CL_Inv[iMarker] = 0.0; CSF_Inv[iMarker] = 0.0; CMx_Inv[iMarker] = 0.0; CMy_Inv[iMarker] = 0.0; CMz_Inv[iMarker] = 0.0; CoPx_Inv[iMarker] = 0.0; CoPy_Inv[iMarker] = 0.0; CoPz_Inv[iMarker] = 0.0; CFx_Inv[iMarker] = 0.0; CFy_Inv[iMarker] = 0.0; CFz_Inv[iMarker] = 0.0; CT_Inv[iMarker] = 0.0; CQ_Inv[iMarker] = 0.0; CMerit_Inv[iMarker] = 0.0; CNearFieldOF_Inv[iMarker] = 0.0; CEff_Inv[iMarker] = 0.0; - + for (iDim = 0; iDim < nDim; iDim++) ForceInviscid[iDim] = 0.0; MomentInviscid[0] = 0.0; MomentInviscid[1] = 0.0; MomentInviscid[2] = 0.0; MomentX_Force[0] = 0.0; MomentX_Force[1] = 0.0; MomentX_Force[2] = 0.0; @@ -4286,34 +4283,34 @@ void CEulerSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { MomentZ_Force[0] = 0.0; MomentZ_Force[1] = 0.0; MomentZ_Force[2] = 0.0; NFPressOF = 0.0; - + /*--- Loop over the vertices to compute the forces ---*/ - + for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { - + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - + Pressure = nodes->GetPressure(iPoint); - + CPressure[iMarker][iVertex] = (Pressure - RefPressure)*factor*RefArea; - + /*--- Note that the pressure coefficient is computed at the halo cells (for visualization purposes), but not the forces ---*/ - + if ( (geometry->node[iPoint]->GetDomain()) && (Monitoring == YES) ) { - + Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); Coord = geometry->node[iPoint]->GetCoord(); - + /*--- Quadratic objective function for the near-field. This uses the infinity pressure regardless of Mach number. ---*/ - + NFPressOF += 0.5*(Pressure - Pressure_Inf)*(Pressure - Pressure_Inf)*Normal[nDim-1]; - + for (iDim = 0; iDim < nDim; iDim++) { MomentDist[iDim] = Coord[iDim] - Origin[iDim]; } - + /*--- Axisymmetric simulations ---*/ if (axisymmetric) AxiFactor = 2.0*PI_NUMBER*geometry->node[iPoint]->GetCoord(1); @@ -4321,14 +4318,14 @@ void CEulerSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { /*--- Force computation, note the minus sign due to the orientation of the normal (outward) ---*/ - + for (iDim = 0; iDim < nDim; iDim++) { Force[iDim] = -(Pressure - Pressure_Inf) * Normal[iDim] * factor * AxiFactor; ForceInviscid[iDim] += Force[iDim]; } - + /*--- Moment with respect to the reference axis ---*/ - + if (nDim == 3) { MomentInviscid[0] += (Force[2]*MomentDist[1]-Force[1]*MomentDist[2])/RefLength; MomentX_Force[1] += (-Force[1]*Coord[2]); @@ -4342,13 +4339,13 @@ void CEulerSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { MomentZ_Force[0] += (-Force[0]*Coord[1]); MomentZ_Force[1] += (Force[1]*Coord[0]); } - + } - + /*--- Project forces and store the non-dimensional coefficients ---*/ - + if (Monitoring == YES) { - + if (Boundary != NEARFIELD_BOUNDARY) { if (nDim == 2) { CD_Inv[iMarker] = ForceInviscid[0]*cos(Alpha) + ForceInviscid[1]*sin(Alpha); @@ -4380,7 +4377,7 @@ void CEulerSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { CQ_Inv[iMarker] = -CMz_Inv[iMarker]; CMerit_Inv[iMarker] = CT_Inv[iMarker] / (CQ_Inv[iMarker] + EPS); } - + AllBound_CD_Inv += CD_Inv[iMarker]; AllBound_CL_Inv += CL_Inv[iMarker]; AllBound_CSF_Inv += CSF_Inv[iMarker]; @@ -4397,9 +4394,9 @@ void CEulerSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { AllBound_CT_Inv += CT_Inv[iMarker]; AllBound_CQ_Inv += CQ_Inv[iMarker]; AllBound_CMerit_Inv = AllBound_CT_Inv / (AllBound_CQ_Inv + EPS); - + /*--- Compute the coefficients per surface ---*/ - + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { Monitoring_Tag = config->GetMarker_Monitoring_TagBound(iMarker_Monitoring); Marker_Tag = config->GetMarker_All_TagBound(iMarker); @@ -4416,26 +4413,26 @@ void CEulerSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { Surface_CMz_Inv[iMarker_Monitoring] += CMz_Inv[iMarker]; } } - + } - + /*--- At the Nearfield SU2 only cares about the pressure coeffient ---*/ - + else { CNearFieldOF_Inv[iMarker] = NFPressOF; AllBound_CNearFieldOF_Inv += CNearFieldOF_Inv[iMarker]; } - + } - - + + } } - + #ifdef HAVE_MPI - + /*--- Add AllBound information using all the nodes ---*/ - + MyAllBound_CD_Inv = AllBound_CD_Inv; AllBound_CD_Inv = 0.0; MyAllBound_CL_Inv = AllBound_CL_Inv; AllBound_CL_Inv = 0.0; MyAllBound_CSF_Inv = AllBound_CSF_Inv; AllBound_CSF_Inv = 0.0; @@ -4453,7 +4450,7 @@ void CEulerSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { MyAllBound_CQ_Inv = AllBound_CQ_Inv; AllBound_CQ_Inv = 0.0; AllBound_CMerit_Inv = 0.0; MyAllBound_CNearFieldOF_Inv = AllBound_CNearFieldOF_Inv; AllBound_CNearFieldOF_Inv = 0.0; - + if (config->GetComm_Level() == COMM_FULL) { SU2_MPI::Allreduce(&MyAllBound_CD_Inv, &AllBound_CD_Inv, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); SU2_MPI::Allreduce(&MyAllBound_CL_Inv, &AllBound_CL_Inv, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); @@ -4473,9 +4470,9 @@ void CEulerSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { AllBound_CMerit_Inv = AllBound_CT_Inv / (AllBound_CQ_Inv + EPS); SU2_MPI::Allreduce(&MyAllBound_CNearFieldOF_Inv, &AllBound_CNearFieldOF_Inv, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); } - + /*--- Add the forces on the surfaces using all the nodes ---*/ - + MySurface_CL_Inv = new su2double[config->GetnMarker_Monitoring()]; MySurface_CD_Inv = new su2double[config->GetnMarker_Monitoring()]; MySurface_CSF_Inv = new su2double[config->GetnMarker_Monitoring()]; @@ -4510,7 +4507,7 @@ void CEulerSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { Surface_CMy_Inv[iMarker_Monitoring] = 0.0; Surface_CMz_Inv[iMarker_Monitoring] = 0.0; } - + if (config->GetComm_Level() == COMM_FULL) { SU2_MPI::Allreduce(MySurface_CL_Inv, Surface_CL_Inv, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); SU2_MPI::Allreduce(MySurface_CD_Inv, Surface_CD_Inv, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); @@ -4524,16 +4521,16 @@ void CEulerSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { SU2_MPI::Allreduce(MySurface_CMy_Inv, Surface_CMy_Inv, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); SU2_MPI::Allreduce(MySurface_CMz_Inv, Surface_CMz_Inv, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); } - + delete [] MySurface_CL_Inv; delete [] MySurface_CD_Inv; delete [] MySurface_CSF_Inv; delete [] MySurface_CEff_Inv; delete [] MySurface_CFx_Inv; delete [] MySurface_CFy_Inv; delete [] MySurface_CFz_Inv; delete [] MySurface_CMx_Inv; delete [] MySurface_CMy_Inv; delete [] MySurface_CMz_Inv; - + #endif - + /*--- Update the total coefficients (note that all the nodes have the same value) ---*/ - + Total_CD = AllBound_CD_Inv; Total_CL = AllBound_CL_Inv; Total_CSF = AllBound_CSF_Inv; @@ -4551,9 +4548,9 @@ void CEulerSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { Total_CQ = AllBound_CQ_Inv; Total_CMerit = Total_CT / (Total_CQ + EPS); Total_CNearFieldOF = AllBound_CNearFieldOF_Inv; - + /*--- Update the total coefficients per surface (note that all the nodes have the same value)---*/ - + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { Surface_CL[iMarker_Monitoring] = Surface_CL_Inv[iMarker_Monitoring]; Surface_CD[iMarker_Monitoring] = Surface_CD_Inv[iMarker_Monitoring]; @@ -4566,11 +4563,11 @@ void CEulerSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { Surface_CMy[iMarker_Monitoring] = Surface_CMy_Inv[iMarker_Monitoring]; Surface_CMz[iMarker_Monitoring] = Surface_CMz_Inv[iMarker_Monitoring]; } - + } void CEulerSolver::Momentum_Forces(CGeometry *geometry, CConfig *config) { - + unsigned long iVertex, iPoint; unsigned short iDim, iMarker, Boundary, Monitoring, iMarker_Monitoring; su2double *Normal = NULL, MomentDist[3] = {0.0,0.0,0.0}, *Coord, Area, @@ -4579,7 +4576,7 @@ void CEulerSolver::Momentum_Forces(CGeometry *geometry, CConfig *config) { string Marker_Tag, Monitoring_Tag; su2double MomentX_Force[3] = {0.0,0.0,0.0}, MomentY_Force[3] = {0.0,0.0,0.0}, MomentZ_Force[3] = {0.0,0.0,0.0}; su2double AxiFactor; - + #ifdef HAVE_MPI su2double MyAllBound_CD_Mnt, MyAllBound_CL_Mnt, MyAllBound_CSF_Mnt, MyAllBound_CMx_Mnt, MyAllBound_CMy_Mnt, MyAllBound_CMz_Mnt, @@ -4591,7 +4588,7 @@ void CEulerSolver::Momentum_Forces(CGeometry *geometry, CConfig *config) { *MySurface_CFz_Mnt = NULL, *MySurface_CMx_Mnt = NULL, *MySurface_CMy_Mnt = NULL, *MySurface_CMz_Mnt = NULL; #endif - + su2double Alpha = config->GetAoA()*PI_NUMBER/180.0; su2double Beta = config->GetAoS()*PI_NUMBER/180.0; su2double RefArea = config->GetRefArea(); @@ -4602,12 +4599,12 @@ void CEulerSolver::Momentum_Forces(CGeometry *geometry, CConfig *config) { Origin = config->GetRefOriginMoment(0); } bool axisymmetric = config->GetAxisymmetric(); - + /*--- Evaluate reference values for non-dimensionalization. For dynamic meshes, use the motion Mach number as a reference value for computing the force coefficients. Otherwise, use the freestream values, which is the standard convention. ---*/ - + RefTemp = Temperature_Inf; RefDensity = Density_Inf; if (dynamic_grid) { @@ -4620,18 +4617,18 @@ void CEulerSolver::Momentum_Forces(CGeometry *geometry, CConfig *config) { for (iDim = 0; iDim < nDim; iDim++) RefVel2 += Velocity_Inf[iDim]*Velocity_Inf[iDim]; } - + factor = 1.0 / (0.5*RefDensity*RefArea*RefVel2); - + /*-- Variables initialization ---*/ - + AllBound_CD_Mnt = 0.0; AllBound_CL_Mnt = 0.0; AllBound_CSF_Mnt = 0.0; AllBound_CMx_Mnt = 0.0; AllBound_CMy_Mnt = 0.0; AllBound_CMz_Mnt = 0.0; AllBound_CoPx_Mnt = 0.0; AllBound_CoPy_Mnt = 0.0; AllBound_CoPz_Mnt = 0.0; AllBound_CFx_Mnt = 0.0; AllBound_CFy_Mnt = 0.0; AllBound_CFz_Mnt = 0.0; AllBound_CT_Mnt = 0.0; AllBound_CQ_Mnt = 0.0; AllBound_CMerit_Mnt = 0.0; AllBound_CEff_Mnt = 0.0; - + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { Surface_CL_Mnt[iMarker_Monitoring] = 0.0; Surface_CD_Mnt[iMarker_Monitoring] = 0.0; Surface_CSF_Mnt[iMarker_Monitoring] = 0.0; Surface_CEff_Mnt[iMarker_Monitoring] = 0.0; @@ -4639,16 +4636,16 @@ void CEulerSolver::Momentum_Forces(CGeometry *geometry, CConfig *config) { Surface_CFz_Mnt[iMarker_Monitoring] = 0.0; Surface_CMx_Mnt[iMarker_Monitoring] = 0.0; Surface_CMy_Mnt[iMarker_Monitoring] = 0.0; Surface_CMz_Mnt[iMarker_Monitoring] = 0.0; } - + /*--- Loop over the Inlet -Outlet Markers ---*/ - + for (iMarker = 0; iMarker < nMarker; iMarker++) { - + Boundary = config->GetMarker_All_KindBC(iMarker); Monitoring = config->GetMarker_All_Monitoring(iMarker); - + /*--- Obtain the origin for the moment computation for a particular marker ---*/ - + if (Monitoring == YES) { for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { Monitoring_Tag = config->GetMarker_Monitoring_TagBound(iMarker_Monitoring); @@ -4657,73 +4654,73 @@ void CEulerSolver::Momentum_Forces(CGeometry *geometry, CConfig *config) { Origin = config->GetRefOriginMoment(iMarker_Monitoring); } } - + if ((Boundary == INLET_FLOW) || (Boundary == OUTLET_FLOW) || (Boundary == ACTDISK_INLET) || (Boundary == ACTDISK_OUTLET)|| (Boundary == ENGINE_INFLOW) || (Boundary == ENGINE_EXHAUST)) { - + /*--- Forces initialization at each Marker ---*/ - + CD_Mnt[iMarker] = 0.0; CL_Mnt[iMarker] = 0.0; CSF_Mnt[iMarker] = 0.0; CFx_Mnt[iMarker] = 0.0; CFy_Mnt[iMarker] = 0.0; CFz_Mnt[iMarker] = 0.0; CMx_Mnt[iMarker] = 0.0; CMy_Mnt[iMarker] = 0.0; CMz_Mnt[iMarker] = 0.0; CoPx_Mnt[iMarker] = 0.0; CoPy_Mnt[iMarker] = 0.0; CoPz_Mnt[iMarker] = 0.0; CT_Mnt[iMarker] = 0.0; CQ_Mnt[iMarker] = 0.0; CMerit_Mnt[iMarker] = 0.0; CEff_Mnt[iMarker] = 0.0; - + for (iDim = 0; iDim < nDim; iDim++) ForceMomentum[iDim] = 0.0; MomentMomentum[0] = 0.0; MomentMomentum[1] = 0.0; MomentMomentum[2] = 0.0; MomentX_Force[0] = 0.0; MomentX_Force[1] = 0.0; MomentX_Force[2] = 0.0; MomentY_Force[0] = 0.0; MomentY_Force[1] = 0.0; MomentY_Force[2] = 0.0; MomentZ_Force[0] = 0.0; MomentZ_Force[1] = 0.0; MomentZ_Force[2] = 0.0; - + /*--- Loop over the vertices to compute the forces ---*/ - + for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { - + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - + /*--- Note that the pressure coefficient is computed at the halo cells (for visualization purposes), but not the forces ---*/ - + if ( (geometry->node[iPoint]->GetDomain()) && (Monitoring == YES) ) { - + Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); Coord = geometry->node[iPoint]->GetCoord(); Density = nodes->GetDensity(iPoint); - + /*--- Quadratic objective function for the near-field. This uses the infinity pressure regardless of Mach number. ---*/ - + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); - + MassFlow = 0.0; for (iDim = 0; iDim < nDim; iDim++) { Velocity[iDim] = nodes->GetVelocity(iPoint,iDim); MomentDist[iDim] = Coord[iDim] - Origin[iDim]; MassFlow -= Normal[iDim]*Velocity[iDim]*Density; } - + /*--- Axisymmetric simulations ---*/ - + if (axisymmetric) AxiFactor = 2.0*PI_NUMBER*geometry->node[iPoint]->GetCoord(1); else AxiFactor = 1.0; - + /*--- Force computation, note the minus sign due to the orientation of the normal (outward) ---*/ - + for (iDim = 0; iDim < nDim; iDim++) { Force[iDim] = MassFlow * Velocity[iDim] * factor * AxiFactor; ForceMomentum[iDim] += Force[iDim]; } - + /*--- Moment with respect to the reference axis ---*/ - + if (iDim == 3) { MomentMomentum[0] += (Force[2]*MomentDist[1]-Force[1]*MomentDist[2])/RefLength; MomentX_Force[1] += (-Force[1]*Coord[2]); MomentX_Force[2] += (Force[2]*Coord[1]); - + MomentMomentum[1] += (Force[0]*MomentDist[2]-Force[2]*MomentDist[0])/RefLength; MomentY_Force[2] += (-Force[2]*Coord[0]); MomentY_Force[0] += (Force[0]*Coord[2]); @@ -4731,15 +4728,15 @@ void CEulerSolver::Momentum_Forces(CGeometry *geometry, CConfig *config) { MomentMomentum[2] += (Force[1]*MomentDist[0]-Force[0]*MomentDist[1])/RefLength; MomentZ_Force[0] += (-Force[0]*Coord[1]); MomentZ_Force[1] += (Force[1]*Coord[0]); - + } - + } - + /*--- Project forces and store the non-dimensional coefficients ---*/ - + if (Monitoring == YES) { - + if (nDim == 2) { CD_Mnt[iMarker] = ForceMomentum[0]*cos(Alpha) + ForceMomentum[1]*sin(Alpha); CL_Mnt[iMarker] = -ForceMomentum[0]*sin(Alpha) + ForceMomentum[1]*cos(Alpha); @@ -4770,7 +4767,7 @@ void CEulerSolver::Momentum_Forces(CGeometry *geometry, CConfig *config) { CQ_Mnt[iMarker] = -CMz_Mnt[iMarker]; CMerit_Mnt[iMarker] = CT_Mnt[iMarker] / (CQ_Mnt[iMarker] + EPS); } - + AllBound_CD_Mnt += CD_Mnt[iMarker]; AllBound_CL_Mnt += CL_Mnt[iMarker]; AllBound_CSF_Mnt += CSF_Mnt[iMarker]; @@ -4786,9 +4783,9 @@ void CEulerSolver::Momentum_Forces(CGeometry *geometry, CConfig *config) { AllBound_CT_Mnt += CT_Mnt[iMarker]; AllBound_CQ_Mnt += CQ_Mnt[iMarker]; AllBound_CMerit_Mnt += AllBound_CT_Mnt / (AllBound_CQ_Mnt + EPS); - + /*--- Compute the coefficients per surface ---*/ - + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { Monitoring_Tag = config->GetMarker_Monitoring_TagBound(iMarker_Monitoring); Marker_Tag = config->GetMarker_All_TagBound(iMarker); @@ -4805,17 +4802,17 @@ void CEulerSolver::Momentum_Forces(CGeometry *geometry, CConfig *config) { Surface_CMz_Mnt[iMarker_Monitoring] += CMz_Mnt[iMarker]; } } - + } - - + + } } - + #ifdef HAVE_MPI - + /*--- Add AllBound information using all the nodes ---*/ - + MyAllBound_CD_Mnt = AllBound_CD_Mnt; AllBound_CD_Mnt = 0.0; MyAllBound_CL_Mnt = AllBound_CL_Mnt; AllBound_CL_Mnt = 0.0; MyAllBound_CSF_Mnt = AllBound_CSF_Mnt; AllBound_CSF_Mnt = 0.0; @@ -4830,7 +4827,7 @@ void CEulerSolver::Momentum_Forces(CGeometry *geometry, CConfig *config) { MyAllBound_CoPz_Mnt = AllBound_CoPz_Mnt; AllBound_CoPz_Mnt = 0.0; MyAllBound_CT_Mnt = AllBound_CT_Mnt; AllBound_CT_Mnt = 0.0; MyAllBound_CQ_Mnt = AllBound_CQ_Mnt; AllBound_CQ_Mnt = 0.0; - + if (config->GetComm_Level() == COMM_FULL) { SU2_MPI::Allreduce(&MyAllBound_CD_Mnt, &AllBound_CD_Mnt, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); SU2_MPI::Allreduce(&MyAllBound_CL_Mnt, &AllBound_CL_Mnt, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); @@ -4849,9 +4846,9 @@ void CEulerSolver::Momentum_Forces(CGeometry *geometry, CConfig *config) { SU2_MPI::Allreduce(&MyAllBound_CQ_Mnt, &AllBound_CQ_Mnt, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); AllBound_CMerit_Mnt = AllBound_CT_Mnt / (AllBound_CQ_Mnt + EPS); } - + /*--- Add the forces on the surfaces using all the nodes ---*/ - + MySurface_CL_Mnt = new su2double[config->GetnMarker_Monitoring()]; MySurface_CD_Mnt = new su2double[config->GetnMarker_Monitoring()]; MySurface_CSF_Mnt = new su2double[config->GetnMarker_Monitoring()]; @@ -4862,7 +4859,7 @@ void CEulerSolver::Momentum_Forces(CGeometry *geometry, CConfig *config) { MySurface_CMx_Mnt = new su2double[config->GetnMarker_Monitoring()]; MySurface_CMy_Mnt = new su2double[config->GetnMarker_Monitoring()]; MySurface_CMz_Mnt = new su2double[config->GetnMarker_Monitoring()]; - + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { MySurface_CL_Mnt[iMarker_Monitoring] = Surface_CL_Mnt[iMarker_Monitoring]; MySurface_CD_Mnt[iMarker_Monitoring] = Surface_CD_Mnt[iMarker_Monitoring]; @@ -4874,7 +4871,7 @@ void CEulerSolver::Momentum_Forces(CGeometry *geometry, CConfig *config) { MySurface_CMx_Mnt[iMarker_Monitoring] = Surface_CMx_Mnt[iMarker_Monitoring]; MySurface_CMy_Mnt[iMarker_Monitoring] = Surface_CMy_Mnt[iMarker_Monitoring]; MySurface_CMz_Mnt[iMarker_Monitoring] = Surface_CMz_Mnt[iMarker_Monitoring]; - + Surface_CL_Mnt[iMarker_Monitoring] = 0.0; Surface_CD_Mnt[iMarker_Monitoring] = 0.0; Surface_CSF_Mnt[iMarker_Monitoring] = 0.0; @@ -4886,7 +4883,7 @@ void CEulerSolver::Momentum_Forces(CGeometry *geometry, CConfig *config) { Surface_CMy_Mnt[iMarker_Monitoring] = 0.0; Surface_CMz_Mnt[iMarker_Monitoring] = 0.0; } - + if (config->GetComm_Level() == COMM_FULL) { SU2_MPI::Allreduce(MySurface_CL_Mnt, Surface_CL_Mnt, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); SU2_MPI::Allreduce(MySurface_CD_Mnt, Surface_CD_Mnt, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); @@ -4900,16 +4897,16 @@ void CEulerSolver::Momentum_Forces(CGeometry *geometry, CConfig *config) { SU2_MPI::Allreduce(MySurface_CMy_Mnt, Surface_CMy_Mnt, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); SU2_MPI::Allreduce(MySurface_CMz_Mnt, Surface_CMz_Mnt, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); } - + delete [] MySurface_CL_Mnt; delete [] MySurface_CD_Mnt; delete [] MySurface_CSF_Mnt; delete [] MySurface_CEff_Mnt; delete [] MySurface_CFx_Mnt; delete [] MySurface_CFy_Mnt; delete [] MySurface_CFz_Mnt; delete [] MySurface_CMx_Mnt; delete [] MySurface_CMy_Mnt; delete [] MySurface_CMz_Mnt; - + #endif - + /*--- Update the total coefficients (note that all the nodes have the same value) ---*/ - + Total_CD += AllBound_CD_Mnt; Total_CL += AllBound_CL_Mnt; Total_CSF += AllBound_CSF_Mnt; @@ -4926,9 +4923,9 @@ void CEulerSolver::Momentum_Forces(CGeometry *geometry, CConfig *config) { Total_CT += AllBound_CT_Mnt; Total_CQ += AllBound_CQ_Mnt; Total_CMerit = Total_CT / (Total_CQ + EPS); - + /*--- Update the total coefficients per surface (note that all the nodes have the same value)---*/ - + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { Surface_CL[iMarker_Monitoring] += Surface_CL_Mnt[iMarker_Monitoring]; Surface_CD[iMarker_Monitoring] += Surface_CD_Mnt[iMarker_Monitoring]; @@ -4949,25 +4946,25 @@ void CEulerSolver::ExplicitRK_Iteration(CGeometry *geometry, CSolver **solver_co su2double *Residual, *Res_TruncError, Vol, Delta, Res; unsigned short iVar; unsigned long iPoint; - + su2double RK_AlphaCoeff = config->Get_Alpha_RKStep(iRKStep); bool adjoint = config->GetContinuous_Adjoint(); - + for (iVar = 0; iVar < nVar; iVar++) { SetRes_RMS(iVar, 0.0); SetRes_Max(iVar, 0.0, 0); } - + /*--- Update the solution ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { Vol = (geometry->node[iPoint]->GetVolume() + geometry->node[iPoint]->GetPeriodicVolume()); Delta = nodes->GetDelta_Time(iPoint) / Vol; - + Res_TruncError = nodes->GetResTruncError(iPoint); Residual = LinSysRes.GetBlock(iPoint); - + if (!adjoint) { for (iVar = 0; iVar < nVar; iVar++) { Res = Residual[iVar] + Res_TruncError[iVar]; @@ -4976,22 +4973,22 @@ void CEulerSolver::ExplicitRK_Iteration(CGeometry *geometry, CSolver **solver_co AddRes_Max(iVar, fabs(Res), geometry->node[iPoint]->GetGlobalIndex(), geometry->node[iPoint]->GetCoord()); } } - + } - + /*--- MPI solution ---*/ - + InitiateComms(geometry, config, SOLUTION); CompleteComms(geometry, config, SOLUTION); - + /*--- Compute the root mean square residual ---*/ - + SetResidual_RMS(geometry, config); - + /*--- For verification cases, compute the global error metrics. ---*/ - + ComputeVerificationError(geometry, config); - + } void CEulerSolver::ClassicalRK4_Iteration(CGeometry *geometry, CSolver **solver_container, @@ -5049,36 +5046,36 @@ void CEulerSolver::ClassicalRK4_Iteration(CGeometry *geometry, CSolver **solver_ InitiateComms(geometry, config, SOLUTION); CompleteComms(geometry, config, SOLUTION); - + /*--- Compute the root mean square residual ---*/ SetResidual_RMS(geometry, config); /*--- For verification cases, compute the global error metrics. ---*/ - + ComputeVerificationError(geometry, config); - + } void CEulerSolver::ExplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { su2double *local_Residual, *local_Res_TruncError, Vol, Delta, Res; unsigned short iVar; unsigned long iPoint; - + bool adjoint = config->GetContinuous_Adjoint(); - + for (iVar = 0; iVar < nVar; iVar++) { SetRes_RMS(iVar, 0.0); SetRes_Max(iVar, 0.0, 0); } - + /*--- Update the solution ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { Vol = (geometry->node[iPoint]->GetVolume() + geometry->node[iPoint]->GetPeriodicVolume()); Delta = nodes->GetDelta_Time(iPoint) / Vol; - + local_Res_TruncError = nodes->GetResTruncError(iPoint); local_Residual = LinSysRes.GetBlock(iPoint); if (!adjoint) { @@ -5089,57 +5086,57 @@ void CEulerSolver::ExplicitEuler_Iteration(CGeometry *geometry, CSolver **solver AddRes_Max(iVar, fabs(Res), geometry->node[iPoint]->GetGlobalIndex(), geometry->node[iPoint]->GetCoord()); } } - + } - + /*--- MPI solution ---*/ - + InitiateComms(geometry, config, SOLUTION); CompleteComms(geometry, config, SOLUTION); - + /*--- Compute the root mean square residual ---*/ - + SetResidual_RMS(geometry, config); - + /*--- For verification cases, compute the global error metrics. ---*/ - + ComputeVerificationError(geometry, config); - + } void CEulerSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { - + unsigned short iVar, jVar; unsigned long iPoint, total_index, IterLinSol = 0; su2double Delta, *local_Res_TruncError, Vol; - + bool adjoint = config->GetContinuous_Adjoint(); bool roe_turkel = config->GetKind_Upwind_Flow() == TURKEL; bool low_mach_prec = config->Low_Mach_Preconditioning(); - + /*--- Set maximum residual to zero ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { SetRes_RMS(iVar, 0.0); SetRes_Max(iVar, 0.0, 0); } - + /*--- Build implicit system ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /*--- Read the residual ---*/ - + local_Res_TruncError = nodes->GetResTruncError(iPoint); - + /*--- Read the volume ---*/ - + Vol = (geometry->node[iPoint]->GetVolume() + geometry->node[iPoint]->GetPeriodicVolume()); - + /*--- Modify matrix diagonal to assure diagonal dominance ---*/ - - + + if (nodes->GetDelta_Time(iPoint) != 0.0) { Delta = Vol / nodes->GetDelta_Time(iPoint); if (roe_turkel || low_mach_prec) { @@ -5161,9 +5158,9 @@ void CEulerSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver local_Res_TruncError[iVar] = 0.0; } } - + /*--- Right hand side of the system (-Residual) and initial guess (x = 0) ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { total_index = iPoint*nVar + iVar; LinSysRes[total_index] = - (LinSysRes[total_index] + local_Res_TruncError[iVar]); @@ -5172,9 +5169,9 @@ void CEulerSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver AddRes_Max(iVar, fabs(LinSysRes[total_index]), geometry->node[iPoint]->GetGlobalIndex(), geometry->node[iPoint]->GetCoord()); } } - + /*--- Initialize residual and solution at the ghost points ---*/ - + for (iPoint = nPointDomain; iPoint < nPoint; iPoint++) { for (iVar = 0; iVar < nVar; iVar++) { total_index = iPoint*nVar + iVar; @@ -5182,23 +5179,23 @@ void CEulerSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver LinSysSol[total_index] = 0.0; } } - + /*--- Solve or smooth the linear system ---*/ - + IterLinSol = System.Solve(Jacobian, LinSysRes, LinSysSol, geometry, config); - + /*--- Store the value of the residual. ---*/ - + SetResLinSolver(System.GetResidual()); - + /*--- The the number of iterations of the linear solver ---*/ - + SetIterLinSolver(IterLinSol); - + ComputeUnderRelaxationFactor(solver_container, config); - + /*--- Update solution (system written in terms of increments) ---*/ - + if (!adjoint) { for (iPoint = 0; iPoint < nPointDomain; iPoint++) { for (iVar = 0; iVar < nVar; iVar++) { @@ -5206,42 +5203,42 @@ void CEulerSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver } } } - + for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_IMPLICIT); CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_IMPLICIT); } - + /*--- MPI solution ---*/ - + InitiateComms(geometry, config, SOLUTION); CompleteComms(geometry, config, SOLUTION); - + /*--- Compute the root mean square residual ---*/ - + SetResidual_RMS(geometry, config); - + /*--- For verification cases, compute the global error metrics. ---*/ - + ComputeVerificationError(geometry, config); - + } void CEulerSolver::ComputeUnderRelaxationFactor(CSolver **solver_container, CConfig *config) { - + /* Loop over the solution update given by relaxing the linear system for this nonlinear iteration. */ - + su2double localUnderRelaxation = 1.0; const su2double allowableRatio = 0.2; for (unsigned long iPoint = 0; iPoint < nPointDomain; iPoint++) { - + localUnderRelaxation = 1.0; for (unsigned short iVar = 0; iVar < nVar; iVar++) { - + /* We impose a limit on the maximum percentage that the density and energy can change over a nonlinear iteration. */ - + if ((iVar == 0) || (iVar == nVar-1)) { const unsigned long index = iPoint*nVar + iVar; su2double ratio = fabs(LinSysSol[index])/(nodes->GetSolution(iPoint, iVar)+EPS); @@ -5250,25 +5247,25 @@ void CEulerSolver::ComputeUnderRelaxationFactor(CSolver **solver_container, CCon } } } - + /* In case of turbulence, take the min of the under-relaxation factor between the mean flow and the turb model. */ - + if (config->GetKind_Turb_Model() != NONE) localUnderRelaxation = min(localUnderRelaxation, solver_container[TURB_SOL]->GetNodes()->GetUnderRelaxation(iPoint)); - + /* Threshold the relaxation factor in the event that there is a very small value. This helps avoid catastrophic crashes due to non-realizable states by canceling the update. */ - + if (localUnderRelaxation < 1e-10) localUnderRelaxation = 0.0; - + /* Store the under-relaxation factor for this point. */ - + nodes->SetUnderRelaxation(iPoint, localUnderRelaxation); } - + } void CEulerSolver::SetPrimitive_Gradient_GG(CGeometry *geometry, CConfig *config, bool reconstruction) { @@ -5318,7 +5315,7 @@ void CEulerSolver::SetPreconditioner(CConfig *config, unsigned long iPoint) { su2double *U_i = NULL; su2double Beta_max = config->GetmaxTurkelBeta(); su2double Mach_infty2, Mach_lim2, aux, parameter; - + /*--- Variables to calculate the preconditioner parameter Beta ---*/ local_Mach = sqrt(nodes->GetVelocity2(iPoint))/nodes->GetSoundSpeed(iPoint); @@ -5327,20 +5324,20 @@ void CEulerSolver::SetPreconditioner(CConfig *config, unsigned long iPoint) { Mach_lim2 = pow(0.00001,2.0); aux = max(pow(local_Mach,2.0),Mach_lim2); parameter = min(1.0, max(aux,Beta_max*Mach_infty2)); - + U_i = nodes->GetSolution(iPoint); - + rho = U_i[0]; enthalpy = nodes->GetEnthalpy(iPoint); soundspeed = nodes->GetSoundSpeed(iPoint); sq_vel = nodes->GetVelocity2(iPoint); - + /*---Calculating the inverse of the preconditioning matrix that multiplies the time derivative */ LowMach_Precontioner[0][0] = 0.5*sq_vel; LowMach_Precontioner[0][nVar-1] = 1.0; for (iDim = 0; iDim < nDim; iDim ++) LowMach_Precontioner[0][1+iDim] = -1.0*U_i[iDim+1]/rho; - + for (iDim = 0; iDim < nDim; iDim ++) { LowMach_Precontioner[iDim+1][0] = 0.5*sq_vel*U_i[iDim+1]/rho; LowMach_Precontioner[iDim+1][nVar-1] = U_i[iDim+1]/rho; @@ -5348,13 +5345,13 @@ void CEulerSolver::SetPreconditioner(CConfig *config, unsigned long iPoint) { LowMach_Precontioner[iDim+1][1+jDim] = -1.0*U_i[jDim+1]/rho*U_i[iDim+1]/rho; } } - + LowMach_Precontioner[nVar-1][0] = 0.5*sq_vel*enthalpy; LowMach_Precontioner[nVar-1][nVar-1] = enthalpy; for (iDim = 0; iDim < nDim; iDim ++) LowMach_Precontioner[nVar-1][1+iDim] = -1.0*U_i[iDim+1]/rho*enthalpy; - - + + for (iVar = 0; iVar < nVar; iVar ++ ) { for (jVar = 0; jVar < nVar; jVar ++ ) { LowMach_Precontioner[iVar][jVar] = (parameter - 1.0) * ((Gamma-1.0)/(soundspeed*soundspeed))*LowMach_Precontioner[iVar][jVar]; @@ -5362,11 +5359,11 @@ void CEulerSolver::SetPreconditioner(CConfig *config, unsigned long iPoint) { LowMach_Precontioner[iVar][iVar] += 1.0; } } - + } void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, unsigned short iMesh, bool Output) { - + unsigned short iDim, iMarker, jMarker; unsigned long iVertex, iPoint; su2double *V_inlet = NULL, *V_outlet = NULL, Pressure, Temperature, Velocity[3], Vn, @@ -5378,7 +5375,7 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns su2double DeltaPress = 0.0, DeltaTemp = 0.0, TotalPressRatio = 0.0, TotalTempRatio = 0.0, StaticPressRatio = 0.0, StaticTempRatio = 0.0, NetThrust = 0.0, GrossThrust = 0.0, Power = 0.0, MassFlow = 0.0, Mach = 0.0, Force = 0.0; bool ReverseFlow, Engine = false, Pair = true; - + su2double Gas_Constant = config->GetGas_ConstantND(); su2double Cp = Gas_Constant*Gamma / (Gamma-1.0); su2double Alpha = config->GetAoA()*PI_NUMBER/180.0; @@ -5387,21 +5384,21 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns || (config->GetInnerIter() == 1)); bool Evaluate_BC = ((((config->GetInnerIter() % (config->GetWrt_Con_Freq()*40)) == 0)) || (config->GetInnerIter() == 1) || (config->GetDiscrete_Adjoint())); - + if ((config->GetnMarker_EngineInflow() != 0) || (config->GetnMarker_EngineExhaust() != 0)) Engine = true; if ((config->GetnMarker_ActDiskInlet() != 0) || (config->GetnMarker_ActDiskOutlet() != 0)) Engine = false; if ((config->GetnMarker_EngineInflow()) != (config->GetnMarker_EngineExhaust())) Pair = false; - - + + if (Engine) { nMarker_Inlet = config->GetnMarker_EngineInflow(); nMarker_Outlet = config->GetnMarker_EngineExhaust(); } else { nMarker_Inlet = config->GetnMarker_ActDiskInlet(); nMarker_Outlet = config->GetnMarker_ActDiskOutlet(); } - + /*--- Evaluate the MPI for the actuator disk IO ---*/ - + if (Evaluate_BC) { - + /*--- Allocate memory ---*/ - + su2double *Inlet_MassFlow = new su2double [config->GetnMarker_All()]; su2double *Inlet_ReverseMassFlow = new su2double [config->GetnMarker_All()]; su2double *Inlet_Pressure = new su2double [config->GetnMarker_All()]; @@ -5418,7 +5415,7 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns su2double *Inlet_XCG = new su2double [config->GetnMarker_All()]; su2double *Inlet_YCG = new su2double [config->GetnMarker_All()]; su2double *Inlet_ZCG = new su2double [config->GetnMarker_All()]; - + su2double *Outlet_MassFlow = new su2double [config->GetnMarker_All()]; su2double *Outlet_Pressure = new su2double [config->GetnMarker_All()]; su2double *Outlet_TotalPressure = new su2double [config->GetnMarker_All()]; @@ -5428,11 +5425,11 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns su2double *Outlet_GrossThrust = new su2double [config->GetnMarker_All()]; su2double *Outlet_Force = new su2double [config->GetnMarker_All()]; su2double *Outlet_Power = new su2double [config->GetnMarker_All()]; - + /*--- Comute MassFlow, average temp, press, etc. ---*/ - + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { - + Inlet_MassFlow[iMarker] = 0.0; Inlet_ReverseMassFlow[iMarker] = 0.0; Inlet_MinPressure[iMarker] = 0.0; Inlet_Pressure[iMarker] = 0.0; Inlet_Mach[iMarker] = 0.0; Inlet_Temperature[iMarker] = 0.0; Inlet_MinPressure[iMarker] = +1E10; Inlet_MaxPressure[iMarker] = -1E10; Inlet_Power[iMarker] = 0.0; @@ -5440,34 +5437,34 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns Inlet_Area[iMarker] = 0.0; Inlet_RamDrag[iMarker] = 0.0; Inlet_Force[iMarker] = 0.0; Inlet_XCG[iMarker] = 0.0; Inlet_YCG[iMarker] = 0.0; Inlet_ZCG[iMarker] = 0.0; - + Outlet_MassFlow[iMarker] = 0.0; Outlet_Pressure[iMarker] = 0.0; Outlet_Temperature[iMarker] = 0.0; Outlet_TotalPressure[iMarker] = 0.0; Outlet_TotalTemperature[iMarker] = 0.0; Outlet_Area[iMarker] = 0.0; Outlet_GrossThrust[iMarker] = 0.0; Outlet_Force[iMarker] = 0.0; Outlet_Power[iMarker] = 0.0; - + MinPressure = +1E10; MaxPressure = -1E10; - + if ((config->GetMarker_All_KindBC(iMarker) == ACTDISK_INLET) || (config->GetMarker_All_KindBC(iMarker) == ENGINE_INFLOW)) { - + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - + if (geometry->node[iPoint]->GetDomain()) { - + V_inlet = nodes->GetPrimitive(iPoint); - + geometry->vertex[iMarker][iVertex]->GetNormal(Vector); - + Temperature = V_inlet[0]; Pressure = V_inlet[nDim+1]; - + Density = V_inlet[nDim+2]; SoundSpeed = sqrt(Gamma*Pressure/Density); - + Velocity2 = 0.0; Area = 0.0; MassFlow = 0.0; Vel_Infty2 =0.0; for (iDim = 0; iDim < nDim; iDim++) { Area += Vector[iDim]*Vector[iDim]; @@ -5476,11 +5473,11 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns Vel_Infty2 += GetVelocity_Inf(iDim)*GetVelocity_Inf(iDim); MassFlow -= Vector[iDim]*Velocity[iDim]*Density; } - + Vn = 0.0; ReverseFlow = false; for (iDim = 0; iDim < nDim; iDim++) { Vn -= Velocity[iDim]*Vector[iDim]/Area; } if (Vn < 0.0) { ReverseFlow = true; } - + Vel_Infty = sqrt (Vel_Infty2); Area = sqrt (Area); Mach = sqrt(Velocity2)/SoundSpeed; @@ -5488,9 +5485,9 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns TotalTemperature = Temperature * (1.0 + Mach * Mach * 0.5 * (Gamma - 1.0)); MinPressure = min(MinPressure, TotalPressure); MaxPressure = max(MaxPressure, TotalPressure); - + RamDrag = MassFlow * Vel_Infty; - + Inlet_MassFlow[iMarker] += MassFlow; Inlet_Pressure[iMarker] += Pressure*MassFlow; Inlet_Mach[iMarker] += Mach*MassFlow; @@ -5503,41 +5500,41 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns Inlet_RamDrag[iMarker] += RamDrag; Inlet_Power[iMarker] += MassFlow*Cp*TotalTemperature; if (ReverseFlow) Inlet_ReverseMassFlow[iMarker] += MassFlow; - + su2double Inlet_ForceX = -(Pressure - Pressure_Inf)*Vector[0] + MassFlow*Velocity[0]; su2double Inlet_ForceY = -(Pressure - Pressure_Inf)*Vector[1] + MassFlow*Velocity[1]; su2double Inlet_ForceZ = 0.0; if (nDim == 3) Inlet_ForceZ = -(Pressure - Pressure_Inf)*Vector[2] + MassFlow*Velocity[2]; Inlet_Force[iMarker] += Inlet_ForceX*cos(Alpha)*cos(Beta) + Inlet_ForceY*sin(Beta) +Inlet_ForceZ*sin(Alpha)*cos(Beta); - + Inlet_XCG[iMarker] += geometry->node[iPoint]->GetCoord(0)*Area; Inlet_YCG[iMarker] += geometry->node[iPoint]->GetCoord(1)*Area; if (nDim == 3) Inlet_ZCG[iMarker] += geometry->node[iPoint]->GetCoord(2)*Area; - + } } - + } - + if ((config->GetMarker_All_KindBC(iMarker) == ACTDISK_OUTLET) || (config->GetMarker_All_KindBC(iMarker) == ENGINE_EXHAUST)) { - + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - + if (geometry->node[iPoint]->GetDomain()) { - + V_outlet = nodes->GetPrimitive(iPoint); - + geometry->vertex[iMarker][iVertex]->GetNormal(Vector); - + Temperature = V_outlet[0]; Pressure = V_outlet[nDim+1]; - + Density = V_outlet[nDim+2]; SoundSpeed = sqrt(Gamma*Pressure/Density); - + Velocity2 = 0.0; Area = 0.0; MassFlow = 0.0; Vel_Infty2 = 0.0; for (iDim = 0; iDim < nDim; iDim++) { Area += Vector[iDim]*Vector[iDim]; @@ -5546,7 +5543,7 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns Vel_Infty2 += GetVelocity_Inf(iDim)*GetVelocity_Inf(iDim); MassFlow += Vector[iDim]*Velocity[iDim]*Density; } - + Vel_Infty = sqrt (Vel_Infty2); Area = sqrt (Area); Mach = sqrt(Velocity2)/SoundSpeed; @@ -5564,24 +5561,24 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns Outlet_Area[iMarker] += Area; Outlet_GrossThrust[iMarker] += GrossThrust; Outlet_Power[iMarker] += MassFlow*Cp*TotalTemperature; - + su2double Outlet_ForceX = -(Pressure - Pressure_Inf)*Vector[0] -MassFlow*Velocity[0]; su2double Outlet_ForceY = -(Pressure - Pressure_Inf)*Vector[1] -MassFlow*Velocity[1]; su2double Outlet_ForceZ = 0.0; if (nDim == 3) Outlet_ForceZ = -(Pressure - Pressure_Inf)*Vector[2] -MassFlow*Velocity[2]; - + if (nDim == 2) Outlet_Force[iMarker] += Outlet_ForceX*cos(Alpha) + Outlet_ForceY*sin(Alpha); if (nDim == 3) Outlet_Force[iMarker] += Outlet_ForceX*cos(Alpha)*cos(Beta) + Outlet_ForceY*sin(Beta) + Outlet_ForceZ*sin(Alpha)*cos(Beta); - + } } - + } - + } - + /*--- Copy to the appropriate structure ---*/ - + su2double *Inlet_MassFlow_Local = new su2double [nMarker_Inlet]; su2double *Inlet_ReverseMassFlow_Local = new su2double [nMarker_Inlet]; su2double *Inlet_Temperature_Local = new su2double [nMarker_Inlet]; @@ -5598,7 +5595,7 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns su2double *Inlet_XCG_Local = new su2double [nMarker_Inlet]; su2double *Inlet_YCG_Local = new su2double [nMarker_Inlet]; su2double *Inlet_ZCG_Local = new su2double [nMarker_Inlet]; - + su2double *Inlet_MassFlow_Total = new su2double [nMarker_Inlet]; su2double *Inlet_ReverseMassFlow_Total = new su2double [nMarker_Inlet]; su2double *Inlet_Pressure_Total = new su2double [nMarker_Inlet]; @@ -5615,7 +5612,7 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns su2double *Inlet_XCG_Total = new su2double [nMarker_Inlet]; su2double *Inlet_YCG_Total = new su2double [nMarker_Inlet]; su2double *Inlet_ZCG_Total = new su2double [nMarker_Inlet]; - + for (iMarker_Inlet = 0; iMarker_Inlet < nMarker_Inlet; iMarker_Inlet++) { Inlet_MassFlow_Local[iMarker_Inlet] = 0.0; Inlet_ReverseMassFlow_Local[iMarker_Inlet] = 0.0; @@ -5633,7 +5630,7 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns Inlet_XCG_Local[iMarker_Inlet] = 0.0; Inlet_YCG_Local[iMarker_Inlet] = 0.0; Inlet_ZCG_Local[iMarker_Inlet] = 0.0; - + Inlet_MassFlow_Total[iMarker_Inlet] = 0.0; Inlet_ReverseMassFlow_Total[iMarker_Inlet] = 0.0; Inlet_Pressure_Total[iMarker_Inlet] = 0.0; @@ -5651,7 +5648,7 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns Inlet_YCG_Total[iMarker_Inlet] = 0.0; Inlet_ZCG_Total[iMarker_Inlet] = 0.0; } - + su2double *Outlet_MassFlow_Local = new su2double [nMarker_Outlet]; su2double *Outlet_Pressure_Local = new su2double [nMarker_Outlet]; su2double *Outlet_TotalPressure_Local = new su2double [nMarker_Outlet]; @@ -5661,7 +5658,7 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns su2double *Outlet_Force_Local = new su2double [nMarker_Outlet]; su2double *Outlet_Power_Local = new su2double [nMarker_Outlet]; su2double *Outlet_Area_Local = new su2double [nMarker_Outlet]; - + su2double *Outlet_MassFlow_Total = new su2double [nMarker_Outlet]; su2double *Outlet_Pressure_Total = new su2double [nMarker_Outlet]; su2double *Outlet_TotalPressure_Total = new su2double [nMarker_Outlet]; @@ -5671,7 +5668,7 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns su2double *Outlet_Force_Total = new su2double [nMarker_Outlet]; su2double *Outlet_Power_Total = new su2double [nMarker_Outlet]; su2double *Outlet_Area_Total = new su2double [nMarker_Outlet]; - + for (iMarker_Outlet = 0; iMarker_Outlet < nMarker_Outlet; iMarker_Outlet++) { Outlet_MassFlow_Local[iMarker_Outlet] = 0.0; Outlet_Pressure_Local[iMarker_Outlet] = 0.0; @@ -5682,7 +5679,7 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns Outlet_Force_Local[iMarker_Outlet] = 0.0; Outlet_Power_Local[iMarker_Outlet] = 0.0; Outlet_Area_Local[iMarker_Outlet] = 0.0; - + Outlet_MassFlow_Total[iMarker_Outlet] = 0.0; Outlet_Pressure_Total[iMarker_Outlet] = 0.0; Outlet_TotalPressure_Total[iMarker_Outlet] = 0.0; @@ -5693,17 +5690,17 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns Outlet_Power_Total[iMarker_Outlet] = 0.0; Outlet_Area_Total[iMarker_Outlet] = 0.0; } - + /*--- Copy the values to the local array for MPI ---*/ - + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { - + if ((config->GetMarker_All_KindBC(iMarker) == ACTDISK_INLET) || (config->GetMarker_All_KindBC(iMarker) == ENGINE_INFLOW)) { for (iMarker_Inlet = 0; iMarker_Inlet < nMarker_Inlet; iMarker_Inlet++) { - + if (config->GetMarker_All_KindBC(iMarker) == ACTDISK_INLET) Inlet_TagBound = config->GetMarker_ActDiskInlet_TagBound(iMarker_Inlet); if (config->GetMarker_All_KindBC(iMarker) == ENGINE_INFLOW) Inlet_TagBound = config->GetMarker_EngineInflow_TagBound(iMarker_Inlet); - + if (config->GetMarker_All_TagBound(iMarker) == Inlet_TagBound) { Inlet_MassFlow_Local[iMarker_Inlet] += Inlet_MassFlow[iMarker]; Inlet_ReverseMassFlow_Local[iMarker_Inlet] += Inlet_ReverseMassFlow[iMarker]; @@ -5722,16 +5719,16 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns Inlet_YCG_Local[iMarker_Inlet] += Inlet_YCG[iMarker]; if (nDim == 3) Inlet_ZCG_Local[iMarker_Inlet] += Inlet_ZCG[iMarker]; } - + } } - + if ((config->GetMarker_All_KindBC(iMarker) == ACTDISK_OUTLET) || (config->GetMarker_All_KindBC(iMarker) == ENGINE_EXHAUST)) { for (iMarker_Outlet= 0; iMarker_Outlet < nMarker_Outlet; iMarker_Outlet++) { - + if (config->GetMarker_All_KindBC(iMarker) == ACTDISK_OUTLET) Outlet_TagBound = config->GetMarker_ActDiskOutlet_TagBound(iMarker_Outlet); if (config->GetMarker_All_KindBC(iMarker) == ENGINE_EXHAUST) Outlet_TagBound = config->GetMarker_EngineExhaust_TagBound(iMarker_Outlet); - + if (config->GetMarker_All_TagBound(iMarker) == Outlet_TagBound) { Outlet_MassFlow_Local[iMarker_Outlet] += Outlet_MassFlow[iMarker]; Outlet_Pressure_Local[iMarker_Outlet] += Outlet_Pressure[iMarker]; @@ -5743,31 +5740,31 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns Outlet_Power_Local[iMarker_Outlet] += Outlet_Power[iMarker]; Outlet_Area_Local[iMarker_Outlet] += Outlet_Area[iMarker]; } - + } } - + } - + /*--- Correct the min max values for the MPI ---*/ - + bool ActDisk = false; for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) == ACTDISK_INLET) || (config->GetMarker_All_KindBC(iMarker) == ENGINE_INFLOW)) { ActDisk = true; break; } } - + if (!ActDisk) { for (iMarker_Inlet = 0; iMarker_Inlet < nMarker_Inlet; iMarker_Inlet++) { Inlet_MinPressure_Local[iMarker_Inlet] = 1E10; Inlet_MaxPressure_Local[iMarker_Inlet] = -1E10; } } - + /*--- All the ranks to compute the total value ---*/ - + #ifdef HAVE_MPI - + SU2_MPI::Allreduce(Inlet_MassFlow_Local, Inlet_MassFlow_Total, nMarker_Inlet, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); SU2_MPI::Allreduce(Inlet_ReverseMassFlow_Local, Inlet_ReverseMassFlow_Total, nMarker_Inlet, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); SU2_MPI::Allreduce(Inlet_Pressure_Local, Inlet_Pressure_Total, nMarker_Inlet, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); @@ -5784,7 +5781,7 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns SU2_MPI::Allreduce(Inlet_XCG_Local, Inlet_XCG_Total, nMarker_Inlet, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); SU2_MPI::Allreduce(Inlet_YCG_Local, Inlet_YCG_Total, nMarker_Inlet, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); if (nDim == 3) SU2_MPI::Allreduce(Inlet_ZCG_Local, Inlet_ZCG_Total, nMarker_Inlet, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - + SU2_MPI::Allreduce(Outlet_MassFlow_Local, Outlet_MassFlow_Total, nMarker_Outlet, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); SU2_MPI::Allreduce(Outlet_Pressure_Local, Outlet_Pressure_Total, nMarker_Outlet, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); SU2_MPI::Allreduce(Outlet_TotalPressure_Local, Outlet_TotalPressure_Total, nMarker_Outlet, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); @@ -5794,9 +5791,9 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns SU2_MPI::Allreduce(Outlet_Force_Local, Outlet_Force_Total, nMarker_Outlet, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); SU2_MPI::Allreduce(Outlet_Power_Local, Outlet_Power_Total, nMarker_Outlet, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); SU2_MPI::Allreduce(Outlet_Area_Local, Outlet_Area_Total, nMarker_Outlet, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - + #else - + for (iMarker_Inlet = 0; iMarker_Inlet < nMarker_Inlet; iMarker_Inlet++) { Inlet_MassFlow_Total[iMarker_Inlet] = Inlet_MassFlow_Local[iMarker_Inlet]; Inlet_ReverseMassFlow_Total[iMarker_Inlet] = Inlet_ReverseMassFlow_Local[iMarker_Inlet]; @@ -5815,7 +5812,7 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns Inlet_YCG_Total[iMarker_Inlet] = Inlet_YCG_Local[iMarker_Inlet]; if (nDim == 3) Inlet_ZCG_Total[iMarker_Inlet] = Inlet_ZCG_Local[iMarker_Inlet]; } - + for (iMarker_Outlet = 0; iMarker_Outlet < nMarker_Outlet; iMarker_Outlet++) { Outlet_MassFlow_Total[iMarker_Outlet] = Outlet_MassFlow_Local[iMarker_Outlet]; Outlet_Pressure_Total[iMarker_Outlet] = Outlet_Pressure_Local[iMarker_Outlet]; @@ -5827,12 +5824,12 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns Outlet_Power_Total[iMarker_Outlet] = Outlet_Power_Local[iMarker_Outlet]; Outlet_Area_Total[iMarker_Outlet] = Outlet_Area_Local[iMarker_Outlet]; } - + #endif - + /*--- Compute the value of the average surface temperature and pressure and set the value in the config structure for future use ---*/ - + for (iMarker_Inlet = 0; iMarker_Inlet < nMarker_Inlet; iMarker_Inlet++) { if (Inlet_Area_Total[iMarker_Inlet] != 0.0) { Inlet_Pressure_Total[iMarker_Inlet] /= Inlet_MassFlow_Total[iMarker_Inlet]; @@ -5854,9 +5851,9 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns Inlet_YCG_Total[iMarker_Inlet] = 0.0; if (nDim == 3) Inlet_ZCG_Total[iMarker_Inlet] = 0.0; } - + if (iMesh == MESH_0) { - + if (Engine) { config->SetInflow_MassFlow(iMarker_Inlet, Inlet_MassFlow_Total[iMarker_Inlet]); config->SetInflow_ReverseMassFlow(iMarker_Inlet, Inlet_ReverseMassFlow_Total[iMarker_Inlet]); @@ -5879,11 +5876,11 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns config->SetActDiskInlet_Force(iMarker_Inlet, Inlet_Force_Total[iMarker_Inlet]); config->SetActDiskInlet_Power(iMarker_Inlet, Inlet_Power_Total[iMarker_Inlet]); } - + } - + } - + for (iMarker_Outlet = 0; iMarker_Outlet < nMarker_Outlet; iMarker_Outlet++) { if (Outlet_Area_Total[iMarker_Outlet] != 0.0) { Outlet_Pressure_Total[iMarker_Outlet] /= Outlet_MassFlow_Total[iMarker_Outlet]; @@ -5897,9 +5894,9 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns Outlet_Temperature_Total[iMarker_Outlet] = 0.0; Outlet_TotalTemperature_Total[iMarker_Outlet] = 0.0; } - + if (iMesh == MESH_0) { - + if (Engine) { config->SetExhaust_MassFlow(iMarker_Outlet, Outlet_MassFlow_Total[iMarker_Outlet]); config->SetExhaust_Pressure(iMarker_Outlet, Outlet_Pressure_Total[iMarker_Outlet]); @@ -5920,18 +5917,18 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns config->SetActDiskOutlet_Force(iMarker_Outlet, Outlet_Force_Total[iMarker_Outlet]); config->SetActDiskOutlet_Power(iMarker_Outlet, Outlet_Power_Total[iMarker_Outlet]); } - + } - + } - - + + if (Pair) { - + /*--- Store delta pressure, temperature, thrust, and area ---*/ - + for (iMarker_Inlet = 0; iMarker_Inlet < nMarker_Inlet; iMarker_Inlet++) { - + if (Engine) { Inlet_TagBound = config->GetMarker_EngineInflow_TagBound(iMarker_Inlet); jMarker = config->GetMarker_CfgFile_EngineExhaust(Inlet_TagBound); @@ -5942,10 +5939,10 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns jMarker = config->GetMarker_CfgFile_ActDiskOutlet(Inlet_TagBound); Outlet_TagBound = config->GetMarker_CfgFile_TagBound(jMarker); } - - + + su2double DeltaPress = 0.0, DeltaTemp = 0.0, NetThrust = 0.0, GrossThrust = 0.0, TotalPressRatio = 0.0, TotalTempRatio = 0.0, StaticPressRatio = 0.0, StaticTempRatio = 0.0; - + if (Engine) { DeltaPress = config->GetExhaust_Pressure(Outlet_TagBound) - config->GetInflow_Pressure(Inlet_TagBound); DeltaTemp = config->GetExhaust_Temperature(Outlet_TagBound) - config->GetInflow_Temperature(Inlet_TagBound); @@ -5971,10 +5968,10 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns Power = config->GetActDiskOutlet_Power(Outlet_TagBound) - config->GetActDiskInlet_Power(Inlet_TagBound); MassFlow = config->GetActDiskInlet_MassFlow(Inlet_TagBound); } - + Mach = Inlet_Mach_Total[iMarker_Inlet]; Area = Inlet_Area_Total[iMarker_Inlet]; - + if (Engine) { config->SetEngine_Mach(iMarker_Inlet, Mach); config->SetEngine_Force(iMarker_Inlet, Force); @@ -5998,23 +5995,23 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns config->SetActDisk_GrossThrust(iMarker_Inlet, GrossThrust); config->SetActDisk_Area(iMarker_Inlet, Area); } - + } - + /*--- Screen output using the values already stored in the config container ---*/ - + if ((rank == MASTER_NODE) && (iMesh == MESH_0) ) { - + cout.precision(5); cout.setf(ios::fixed, ios::floatfield); - + if (write_heads && Output && !config->GetDiscrete_Adjoint()) { if (Engine) cout << endl << "---------------------------- Engine properties --------------------------" << endl; else cout << endl << "------------------------ Actuator Disk properties -----------------------" << endl; } - + for (iMarker_Inlet = 0; iMarker_Inlet < nMarker_Inlet; iMarker_Inlet++) { - + if (Engine) { Inlet_TagBound = config->GetMarker_EngineInflow_TagBound(iMarker_Inlet); jMarker = config->GetMarker_CfgFile_EngineExhaust(Inlet_TagBound); @@ -6025,8 +6022,8 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns jMarker = config->GetMarker_CfgFile_ActDiskOutlet(Inlet_TagBound); Outlet_TagBound = config->GetMarker_CfgFile_TagBound(jMarker); } - - + + if (Engine) { NetThrust = config->GetEngine_NetThrust(iMarker_Inlet); GrossThrust = config->GetEngine_GrossThrust(iMarker_Inlet); @@ -6047,24 +6044,24 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns Mach = config->GetActDisk_Mach(iMarker_Inlet); Force = config->GetActDisk_Force(iMarker_Inlet); } - + su2double Mach_Inf = config->GetMach(); su2double Pressure_Inf = config->GetPressure_FreeStreamND(); - + su2double TotalPressure_Inf = Pressure_Inf * pow( 1.0 + Mach_Inf * Mach_Inf * 0.5 * (Gamma - 1.0), Gamma / (Gamma - 1.0)); - + su2double MinPressure = Inlet_MinPressure_Total[iMarker_Inlet]/TotalPressure_Inf; su2double MaxPressure = Inlet_MaxPressure_Total[iMarker_Inlet]/TotalPressure_Inf; su2double AvePressure = Inlet_TotalPressure_Total[iMarker_Inlet]/TotalPressure_Inf; - + su2double RefDensity = Density_Inf; su2double RefArea = config->GetRefArea(); su2double RefVel2 = 0.0; for (iDim = 0; iDim < nDim; iDim++) RefVel2 += Velocity_Inf[iDim]*Velocity_Inf[iDim]; - + su2double Factor = (0.5*RefDensity*RefArea*RefVel2); su2double Ref = config->GetDensity_Ref() * config->GetVelocity_Ref() * config->GetVelocity_Ref() * 1.0 * 1.0; su2double DmT = GetTotal_CD() * Factor; - + // su2double ModDmT = 0.0; // if (nDim == 2) ModDmT = sqrt(GetTotal_CFx()*GetTotal_CFx() + // GetTotal_CFy()*GetTotal_CFy()); @@ -6076,7 +6073,7 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns // DmTVector[0] = GetTotal_CFx()/ModDmT; // DmTVector[1] = GetTotal_CFy()/ModDmT; // if (nDim == 3) DmTVector[2] = GetTotal_CFz()/ModDmT; - + /*--- Set the aero drag ---*/ su2double Aero_Drag = DmT - Force; @@ -6085,41 +6082,41 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns SetTotal_AeroCD(Aero_CD); /*--- Set the solid surface drag ---*/ - + su2double Solid_Drag = DmT - Force; su2double Solid_CD = Solid_Drag / Factor; SetTotal_SolidCD(Solid_CD); - + /*--- Set the net thrust value---*/ - + su2double CT = NetThrust / Factor; SetTotal_NetThrust(CT); - + /*--- Set the total power ---*/ - + su2double PowerHP = Power * Ref * config->GetVelocity_Ref() / 550.0; - + SetTotal_Power(PowerHP); - + /*--- Set the total ReverseFlow ---*/ - + su2double ReverseFlow; if (Engine) ReverseFlow = fabs(config->GetInflow_ReverseMassFlow(iMarker_Inlet) / config->GetInflow_MassFlow(Inlet_TagBound)); else ReverseFlow = fabs(config->GetActDisk_ReverseMassFlow(iMarker_Inlet) / config->GetActDiskInlet_MassFlow(Inlet_TagBound)); - + SetTotal_ReverseFlow(ReverseFlow); - + /*--- Set the total mass flow ratio ---*/ - + InfVel2 = 0.0; for (iDim = 0; iDim < nDim; iDim++) InfVel2 += Velocity_Inf[iDim]*Velocity_Inf[iDim]; if (Engine) MFR =fabs(config->GetInflow_MassFlow(Inlet_TagBound)) / (Density_Inf * sqrt(InfVel2) * config->GetHighlite_Area()); else MFR = fabs(config->GetActDiskInlet_MassFlow(Inlet_TagBound)) / (Density_Inf * sqrt(InfVel2) * config->GetHighlite_Area()); SetTotal_MFR(MFR); - + /*--- Evaluate shaft power and adiabatic efficiency (average) ---*/ - + su2double Pstatic1, P1, P2, T1, T2; if (Engine) { Pstatic1 = config->GetInflow_Pressure(Inlet_TagBound); @@ -6135,38 +6132,38 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns T1 = config->GetActDiskInlet_TotalTemperature(Inlet_TagBound); T2 = config->GetActDiskOutlet_TotalTemperature(Outlet_TagBound); } - + /*-- Set the propulsive efficiency ---*/ - + su2double mu_prop = fabs(DmT)*sqrt(RefVel2)/Power; SetTotal_Prop_Eff(mu_prop); - + /*-- Set the bypass propulsive efficiency ---*/ - + su2double mu_bypass_prop = NetThrust*sqrt(RefVel2)/Power; SetTotal_ByPassProp_Eff(mu_bypass_prop); - + /*-- Set the fan adiabatic efficiency ---*/ - + su2double mu_isentropic = 0.0; if ((P2/P1) > 0.0) mu_isentropic = (T1/(T2-T1))*(pow((P2/P1),(Gamma-1.0)/Gamma)-1.0); SetTotal_Adiab_Eff(mu_isentropic); - + /*-- Set the polytropic efficiency ---*/ - + su2double poly_coeff = 1.0/(1.0-log(T2/T1)/log(P2/P1)); su2double mu_polytropic = ((Gamma-1.0)/Gamma)/((poly_coeff-1.0)/poly_coeff); SetTotal_Poly_Eff(mu_polytropic); - + if (write_heads && Output && !config->GetDiscrete_Adjoint()) { - + if (iMarker_Inlet > 0) cout << endl; - + /*--- Geometry defintion ---*/ - + if (Engine) cout <<"Engine surfaces: " << Inlet_TagBound << ", " << Outlet_TagBound << "." << endl; else cout <<"Actuator disk surfaces: " << Inlet_TagBound << ", " << Outlet_TagBound << "." << endl; - + if (nDim == 2) { if (config->GetSystemMeasurements() == SI) cout <<"CG (m): (" << Inlet_XCG_Total[iMarker_Inlet] <<", " << Inlet_YCG_Total[iMarker_Inlet] << "). Length (m): " << Inlet_Area_Total[iMarker_Inlet] << "." << endl; @@ -6174,7 +6171,7 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns cout <<"CG (in): (" << Inlet_XCG_Total[iMarker_Inlet]*12.0 <<", " << Inlet_YCG_Total[iMarker_Inlet]*12.0 << "). Length (in): " << Inlet_Area_Total[iMarker_Inlet]*12.0 << "." << endl; cout << endl; } - + if (nDim ==3) { if (config->GetSystemMeasurements() == SI) cout <<"CG (m): (" << Inlet_XCG_Total[iMarker_Inlet] <<", " << Inlet_YCG_Total[iMarker_Inlet] <<", " << Inlet_ZCG_Total[iMarker_Inlet] << "). Area (m^2): " << Inlet_Area_Total[iMarker_Inlet] << ". Radius (m): " << sqrt(Inlet_Area_Total[iMarker_Inlet]/PI_NUMBER) << "." << endl; @@ -6182,10 +6179,10 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns cout <<"CG (in): (" << Inlet_XCG_Total[iMarker_Inlet]*12.0 <<", " << Inlet_YCG_Total[iMarker_Inlet]*12.0 <<", " << Inlet_ZCG_Total[iMarker_Inlet]*12.0 << "). Area (in^2): " << Inlet_Area_Total[iMarker_Inlet]*12.0*12.0 << "." << endl; cout << endl; } - - + + /*--- Flow field descritption ---*/ - + if (config->GetSystemMeasurements() == SI) { cout << setprecision(2) << "Inlet Ave. P (Pa): " << Pstatic1*config->GetPressure_Ref() << setprecision(3) << ". Inlet Ave. Mach: " << Mach << "." << endl; cout << setprecision(2) << "Outlet Ave. PT (Pa): " << P2*config->GetPressure_Ref() << ". Outlet Ave. TT (K): " << T2*config->GetTemperature_Ref() << "." << endl; @@ -6194,33 +6191,33 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns cout << setprecision(2) << "Inlet Ave. P (psf): " << Pstatic1*config->GetPressure_Ref() << setprecision(3) << ". Inlet Ave. Mach: " << Mach << "." << endl; cout << setprecision(2) << "Outlet Ave. PT (psf): " << P2*config->GetPressure_Ref() << ". Outlet Ave. TT (R): " << T2*config->GetTemperature_Ref() << "." << endl; } - + cout << "Inlet min. PT/PTinf: " << MinPressure << ". Inlet max. PT/PTinf: " << MaxPressure << ". Inlet Ave. PT/PTinf: " << AvePressure << endl; - + su2double InfVel2, Inlet_MassFlow, Outlet_MassFlow; - + if (Engine) Inlet_MassFlow = fabs(config->GetInflow_MassFlow(Inlet_TagBound)) * config->GetDensity_Ref() * config->GetVelocity_Ref(); else Inlet_MassFlow = fabs(config->GetActDiskInlet_MassFlow(Inlet_TagBound)) * config->GetDensity_Ref() * config->GetVelocity_Ref(); - + if (config->GetSystemMeasurements() == SI) { cout << "Inlet mass flow (kg/s): "; cout << setprecision(2) << Inlet_MassFlow; } else if (config->GetSystemMeasurements() == US) { cout << "Inlet mass flow (lbs/s): "; cout << setprecision(2) << Inlet_MassFlow * 32.174; } - + if (Engine) Outlet_MassFlow = fabs(config->GetExhaust_MassFlow(Outlet_TagBound)) * config->GetDensity_Ref() * config->GetVelocity_Ref(); else Outlet_MassFlow = fabs(config->GetActDiskOutlet_MassFlow(Outlet_TagBound)) * config->GetDensity_Ref() * config->GetVelocity_Ref(); - + // if (config->GetSystemMeasurements() == SI) { cout << ". Outlet mass flow (kg/s): "; cout << setprecision(2) << Outlet_MassFlow; } // else if (config->GetSystemMeasurements() == US) { cout << ". Outlet mass flow (lbs/s): "; cout << setprecision(2) << Outlet_MassFlow * 32.174; } - + if (Inlet_MassFlow > Outlet_MassFlow) cout << ". I/O diff.: " << setprecision(2) << 100.0*fabs(1.0-(Outlet_MassFlow/Inlet_MassFlow)) << "%"; else cout << ". I/O diff.: " << setprecision(2) << -100.0*fabs(1.0-(Inlet_MassFlow/Outlet_MassFlow)) << "%"; - + InfVel2 = 0.0; for (iDim = 0; iDim < nDim; iDim++) InfVel2 += Velocity_Inf[iDim]*Velocity_Inf[iDim]; cout << setprecision(2) << ". MFR: " << MFR << "." << endl; - + if (!Engine) { - + cout << setprecision(3) << "PT in/out ratio: " << TotalPressRatio << ". TT in/out ratio: " << TotalTempRatio << "." << endl; - + if (config->GetActDisk_Jump() == VARIABLES_JUMP) { if (config->GetSystemMeasurements() == SI) cout << setprecision(3) << "P in/out jump (Pa): "; else if (config->GetSystemMeasurements() == US) cout << setprecision(3) << "P in/out jump (psf): "; @@ -6236,27 +6233,27 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns cout << setprecision(3) << StaticTempRatio <<"."<< endl; } } - + cout << setprecision(1) << "\nProp. eff. (D-T.V/Shaft P): " << 100*mu_prop << "%. By-pass prop. eff. (NetT.V/Shaft P): " << 100*mu_bypass_prop << "%." << endl; cout << setprecision(1) << "Fan adiabatic eff.: " << 100*mu_isentropic << "%. Fan poly. eff.: " << 100*mu_polytropic << "%. Poly coeff. (n): " << setprecision(4) << poly_coeff << "." << endl; - + cout << endl; - - + + /*--- Forces descritption ---*/ - + if (config->GetSystemMeasurements() == SI) cout << setprecision(1) << "Ram Drag (N): "; else if (config->GetSystemMeasurements() == US) cout << setprecision(1) << "Ram Drag (lbf): "; cout << (GrossThrust-NetThrust) * Ref; - + if (config->GetSystemMeasurements() == SI) cout << setprecision(1) << ". Gross Thrust (N): "; else if (config->GetSystemMeasurements() == US) cout << setprecision(1) << ". Gross Thrust (lbf): "; cout << -GrossThrust * Ref << "." << endl; - + if (config->GetSystemMeasurements() == SI) cout << setprecision(1) << "Open surfaces Thurst (N): "; else if (config->GetSystemMeasurements() == US) cout << setprecision(1) << "Open surfaces Thrust (lbf): "; cout<< setprecision(1) << Force * Ref << ". Open surfaces CT: " << setprecision(5) << -Force / Factor << "." << endl; - + if (config->GetSystemMeasurements() == SI) cout << "Solid surfaces Drag (N): "; else if (config->GetSystemMeasurements() == US) cout << "Solid surfaces Drag (lbf): "; cout << setprecision(1) << Solid_Drag * Ref << ". Solid surfaces CD: " << setprecision(5) << Solid_CD << "." << endl; @@ -6264,7 +6261,7 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns if (config->GetSystemMeasurements() == SI) cout << setprecision(1) <<"Net Thrust (N): "; else if (config->GetSystemMeasurements() == US) cout << setprecision(1) << "Net Thrust (lbf): "; cout << setprecision(5) << -NetThrust * Ref << ". Net CT: " << CT; - + if (config->GetSystemMeasurements() == SI) { cout << ". Power (W): "; cout << setprecision(1) << Power * Ref * config->GetVelocity_Ref() << "." << endl; @@ -6273,18 +6270,18 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns cout << ". Power (HP): "; cout << setprecision(1) << Power * Ref * config->GetVelocity_Ref() / 550.0 << "." << endl; } - + } - + } - + if (write_heads && Output && !config->GetDiscrete_Adjoint()) cout << "-------------------------------------------------------------------------" << endl << endl; - + } - + } - - + + delete [] Outlet_MassFlow_Local; delete [] Outlet_Temperature_Local; delete [] Outlet_TotalTemperature_Local; @@ -6294,7 +6291,7 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns delete [] Outlet_GrossThrust_Local; delete [] Outlet_Force_Local; delete [] Outlet_Power_Local; - + delete [] Outlet_MassFlow_Total; delete [] Outlet_Temperature_Total; delete [] Outlet_TotalTemperature_Total; @@ -6304,7 +6301,7 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns delete [] Outlet_GrossThrust_Total; delete [] Outlet_Force_Total; delete [] Outlet_Power_Total; - + delete [] Inlet_MassFlow_Local; delete [] Inlet_ReverseMassFlow_Local; delete [] Inlet_Temperature_Local; @@ -6321,7 +6318,7 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns delete [] Inlet_XCG_Local; delete [] Inlet_YCG_Local; delete [] Inlet_ZCG_Local; - + delete [] Inlet_MassFlow_Total; delete [] Inlet_ReverseMassFlow_Total; delete [] Inlet_Temperature_Total; @@ -6338,7 +6335,7 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns delete [] Inlet_XCG_Total; delete [] Inlet_YCG_Total; delete [] Inlet_ZCG_Total; - + delete [] Inlet_MassFlow; delete [] Inlet_Mach; delete [] Inlet_MinPressure; @@ -6355,7 +6352,7 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns delete [] Inlet_XCG; delete [] Inlet_YCG; delete [] Inlet_ZCG; - + delete [] Outlet_MassFlow; delete [] Outlet_Pressure; delete [] Outlet_TotalPressure; @@ -6365,14 +6362,14 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns delete [] Outlet_GrossThrust; delete [] Outlet_Force; delete [] Outlet_Power; - + } - + } void CEulerSolver::SetActDisk_BCThrust(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, bool Output) { - + su2double Massflow = 0.0 , Target_Massflow = 0.0, DragMinusThrust = 0.0 , Target_DragMinusThrust = 0.0, Target_NetThrust = 0.0, BCThrust = 0.0, BCThrust_inc = 0.0; unsigned short iDim, iMarker; unsigned long iVertex, iPoint; @@ -6386,7 +6383,7 @@ void CEulerSolver::SetActDisk_BCThrust(CGeometry *geometry, CSolver **solver_con su2double Target_Force, Force, Target_Power, Power, NetThrust, BCThrust_old, Initial_BCThrust; bool ActDisk_Info; su2double MyBCThrust, BCThrust_Init; - + su2double dNetThrust_dBCThrust = config->GetdNetThrust_dBCThrust(); unsigned short Kind_ActDisk = config->GetKind_ActDisk(); bool ratio = (config->GetActDisk_Jump() == RATIO); @@ -6397,24 +6394,24 @@ void CEulerSolver::SetActDisk_BCThrust(CGeometry *geometry, CSolver **solver_con bool restart = (config->GetRestart() || config->GetRestart_Flow()); su2double Fan_Poly_Eff = config->GetFan_Poly_Eff(); su2double PolyCoeff = 1.0/(1.0-((Gamma-1.0)/Gamma)/Fan_Poly_Eff); - + RefDensity = Density_Inf; RefArea = config->GetRefArea(); RefVel2 = 0.0; for (iDim = 0; iDim < nDim; iDim++) RefVel2 += Velocity_Inf[iDim]*Velocity_Inf[iDim]; - + Factor = (0.5*RefDensity*RefArea*RefVel2); Ref = config->GetDensity_Ref() * config->GetVelocity_Ref() * config->GetVelocity_Ref() * 1.0 * 1.0; - + /*--- Delta P and delta T are inputs ---*/ - + if (Kind_ActDisk == VARIABLES_JUMP) { for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { - + if ((config->GetMarker_All_KindBC(iMarker) == ACTDISK_INLET) || (config->GetMarker_All_KindBC(iMarker) == ACTDISK_OUTLET)) { - + Marker_Tag = config->GetMarker_All_TagBound(iMarker); - + if (ratio) { if (config->GetMach() < 0.5) { DeltaP = config->GetActDisk_PressJump(Marker_Tag, 0); @@ -6435,35 +6432,35 @@ void CEulerSolver::SetActDisk_BCThrust(CGeometry *geometry, CSolver **solver_con DeltaT = max(0.0, config->GetActDisk_TempJump(Marker_Tag, 1) / config->GetTemperature_Ref()); } } - + /*--- Set the Delta P, Delta T values at each discrete point (uniform distribution) ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); SetActDisk_DeltaP(iMarker, iVertex, DeltaP); SetActDisk_DeltaT(iMarker, iVertex, DeltaT); } - + } } } - + /*--- Iteration using BCThrust ---*/ - + else { - + if (InnerIter == 0) BCThrust_Counter = 0; - + /*--- Only the fine mesh level should check the convergence criteria ---*/ - + if ((iMesh == MESH_0) && Output) { - + /*--- Initialize the update flag to false ---*/ - + Update_BCThrust_Bool = false; - + /*--- Reevaluate BCThrust at a fix number of iterations ---*/ - + if ((InnerIter % Iter_Fixed_NetThrust == 0) && (InnerIter != 0)) { BCThrust_Counter++; if ((BCThrust_Counter != 0) && @@ -6473,27 +6470,27 @@ void CEulerSolver::SetActDisk_BCThrust(CGeometry *geometry, CSolver **solver_con (BCThrust_Counter != Update_BCThrust + 4) ) Update_BCThrust_Bool = true; else Update_BCThrust_Bool = false; } - + /*--- Store the update boolean for use on other mesh levels in the MG ---*/ - + config->SetUpdate_BCThrust_Bool(Update_BCThrust_Bool); - + } - + else { Update_BCThrust_Bool = config->GetUpdate_BCThrust_Bool(); } - - + + /*--- If it is the first iteration, set the BCThrust to a meaning full target value, * this can be done at an initialization level, for the time being it is OK here ---*/ - + if (InnerIter == 0) { for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) == ACTDISK_INLET) || (config->GetMarker_All_KindBC(iMarker) == ACTDISK_OUTLET)) { Marker_Tag = config->GetMarker_All_TagBound(iMarker); - + if (Kind_ActDisk == NET_THRUST) { if (restart) Initial_BCThrust = config->GetInitial_BCThrust() / Ref; @@ -6504,7 +6501,7 @@ void CEulerSolver::SetActDisk_BCThrust(CGeometry *geometry, CSolver **solver_con config->SetActDisk_BCThrust(Marker_Tag, Initial_BCThrust); config->SetActDisk_BCThrust_Old(Marker_Tag, Initial_BCThrust); } - + if (Kind_ActDisk == BC_THRUST) { if (restart) Initial_BCThrust = config->GetInitial_BCThrust() / Ref; @@ -6515,42 +6512,42 @@ void CEulerSolver::SetActDisk_BCThrust(CGeometry *geometry, CSolver **solver_con config->SetActDisk_BCThrust(Marker_Tag, Initial_BCThrust); config->SetActDisk_BCThrust_Old(Marker_Tag, Initial_BCThrust); } - + if (Kind_ActDisk == POWER) { Initial_BCThrust = config->GetInitial_BCThrust() / Ref; config->SetActDisk_BCThrust(Marker_Tag, Initial_BCThrust); config->SetActDisk_BCThrust_Old(Marker_Tag, Initial_BCThrust); } - + if (Kind_ActDisk == DRAG_MINUS_THRUST) { Initial_BCThrust = config->GetInitial_BCThrust() / Ref; config->SetActDisk_BCThrust(Marker_Tag, Initial_BCThrust); config->SetActDisk_BCThrust_Old(Marker_Tag, Initial_BCThrust); } - + if (Kind_ActDisk == MASSFLOW) { Initial_BCThrust = config->GetInitial_BCThrust() / Ref; config->SetActDisk_BCThrust(Marker_Tag, Initial_BCThrust); config->SetActDisk_BCThrust_Old(Marker_Tag, Initial_BCThrust); } - + } } } - + /*--- Typical iteration to set the value of BC Thrust at each actuator disk ---*/ - + if (Update_BCThrust_Bool && Output) { - + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { - + if ((config->GetMarker_All_KindBC(iMarker) == ACTDISK_INLET) || (config->GetMarker_All_KindBC(iMarker) == ACTDISK_OUTLET)) { - + Marker_Tag = config->GetMarker_All_TagBound(iMarker); - + if (Kind_ActDisk == NET_THRUST) { - + if (config->GetMach() < 0.5) Target_NetThrust = fabs( config->GetActDisk_PressJump(Marker_Tag, 0) / Ref); else Target_NetThrust = fabs( config->GetActDisk_PressJump(Marker_Tag, 1) / Ref); NetThrust = config->GetActDisk_NetThrust(Marker_Tag); @@ -6559,74 +6556,74 @@ void CEulerSolver::SetActDisk_BCThrust(CGeometry *geometry, CSolver **solver_con if (iMesh == MESH_0) BCThrust = max(0.0,(BCThrust_old + BCThrust_inc)); else BCThrust = config->GetActDisk_BCThrust(Marker_Tag); - + if (iMesh == MESH_0) { config->SetActDisk_BCThrust(Marker_Tag, BCThrust); BCThrust_Init = BCThrust*Ref; config->SetInitial_BCThrust(BCThrust_Init); } - + } - + if (Kind_ActDisk == BC_THRUST) { - + if (config->GetMach() < 0.5) Target_Force = fabs( config->GetActDisk_PressJump(Marker_Tag, 0) / Ref); else Target_Force = fabs( config->GetActDisk_PressJump(Marker_Tag, 1) / Ref); Force = -config->GetActDisk_Force(Marker_Tag); BCThrust_old = config->GetActDisk_BCThrust_Old(Marker_Tag); BCThrust_inc = (1.0/dNetThrust_dBCThrust)*(Target_Force - Force); - + if (iMesh == MESH_0) BCThrust = max(0.0,(BCThrust_old + BCThrust_inc)); else BCThrust = config->GetActDisk_BCThrust(Marker_Tag); - + if (iMesh == MESH_0) { config->SetActDisk_BCThrust(Marker_Tag, BCThrust); BCThrust_Init = BCThrust*Ref; config->SetInitial_BCThrust(BCThrust_Init); } - + } - + if (Kind_ActDisk == POWER) { - + if (config->GetMach() < 0.5) Target_Power = fabs( config->GetActDisk_PressJump(Marker_Tag, 0) / (Ref * config->GetVelocity_Ref() / 550.0)); else Target_Power = fabs( config->GetActDisk_PressJump(Marker_Tag, 1) / (Ref * config->GetVelocity_Ref() / 550.0)); Power = config->GetActDisk_Power(Marker_Tag); BCThrust_old = config->GetActDisk_BCThrust_Old(Marker_Tag); BCThrust_inc = (1.0/dNetThrust_dBCThrust)*(Target_Power - Power); - + if (iMesh == MESH_0) BCThrust = max(0.0,(BCThrust_old + BCThrust_inc)); else BCThrust = config->GetActDisk_BCThrust(Marker_Tag); - + if (iMesh == MESH_0) { config->SetActDisk_BCThrust(Marker_Tag, BCThrust); BCThrust_Init = BCThrust*Ref; config->SetInitial_BCThrust(BCThrust_Init); } - + } - + if (Kind_ActDisk == DRAG_MINUS_THRUST) { - + if (config->GetMach() < 0.5) Target_DragMinusThrust = -fabs(config->GetActDisk_PressJump(Marker_Tag, 0)) * Factor; else Target_DragMinusThrust = -fabs(config->GetActDisk_PressJump(Marker_Tag, 1)) * Factor; DragMinusThrust = GetTotal_CD() * Factor; BCThrust_old = config->GetActDisk_BCThrust_Old(Marker_Tag); BCThrust_inc = -(1.0/dNetThrust_dBCThrust)*(Target_DragMinusThrust - DragMinusThrust); - + if (iMesh == MESH_0) BCThrust = max(0.0,(BCThrust_old + BCThrust_inc)); else BCThrust = config->GetActDisk_BCThrust(Marker_Tag); - + if (iMesh == MESH_0) { config->SetActDisk_BCThrust(Marker_Tag, BCThrust); BCThrust_Init = BCThrust*Ref; config->SetInitial_BCThrust(BCThrust_Init); } - + } - + if (Kind_ActDisk == MASSFLOW) { - + if (config->GetMach() < 0.5) { Target_Massflow = fabs(config->GetActDisk_PressJump(Marker_Tag, 0) / (config->GetDensity_Ref() * config->GetVelocity_Ref())); if (config->GetSystemMeasurements() == US) Target_Massflow /= 32.174; @@ -6635,7 +6632,7 @@ void CEulerSolver::SetActDisk_BCThrust(CGeometry *geometry, CSolver **solver_con Target_Massflow = fabs(config->GetActDisk_PressJump(Marker_Tag, 1) / (config->GetDensity_Ref() * config->GetVelocity_Ref())); if (config->GetSystemMeasurements() == US) Target_Massflow /= 32.174; } - + Massflow = config->GetActDisk_MassFlow(Marker_Tag); BCThrust_old = config->GetActDisk_BCThrust_Old(Marker_Tag); BCThrust_inc = (1.0/dNetThrust_dBCThrust)*(Target_Massflow - Massflow); @@ -6646,16 +6643,16 @@ void CEulerSolver::SetActDisk_BCThrust(CGeometry *geometry, CSolver **solver_con BCThrust_Init = BCThrust*Ref; config->SetInitial_BCThrust(BCThrust_Init); } - + } - + } - + } - + /*--- After a complete update of BC_Thrust update the value of BC Thrust (old) for future iterations ---*/ - + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) == ACTDISK_INLET) || (config->GetMarker_All_KindBC(iMarker) == ACTDISK_OUTLET)) { @@ -6668,134 +6665,134 @@ void CEulerSolver::SetActDisk_BCThrust(CGeometry *geometry, CSolver **solver_con } } } - + } - + /*--- Evaluate the pressure jump at each node using the total thrust ---*/ - + if ((Update_BCThrust_Bool && Output) || (InnerIter == 0)) { - + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { - + if ((config->GetMarker_All_KindBC(iMarker) == ACTDISK_INLET) || (config->GetMarker_All_KindBC(iMarker) == ACTDISK_OUTLET)) { - + Marker_Tag = config->GetMarker_All_TagBound(iMarker); RefDensity = Density_Inf; RefArea = config->GetRefArea(); RefVel2 = 0.0; for (iDim = 0; iDim < nDim; iDim++) RefVel2 += Velocity_Inf[iDim]*Velocity_Inf[iDim]; - + Factor = (0.5*RefDensity*RefArea*RefVel2); Ref = config->GetDensity_Ref() * config->GetVelocity_Ref() * config->GetVelocity_Ref() * 1.0 * 1.0; BCThrust = config->GetActDisk_BCThrust(Marker_Tag); - + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - + if (geometry->node[iPoint]->GetDomain()) { - + geometry->vertex[iMarker][iVertex]->GetNormal(Vector); - + if (config->GetMarker_All_KindBC(iMarker) == ACTDISK_INLET) { for (iDim = 0; iDim < nDim; iDim++) { Vector[iDim] = -Vector[iDim]; } } - + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) { Area += Vector[iDim]*Vector[iDim]; } Area = sqrt (Area); - + /*--- Use the inlet state to compute the Pressure and Temperature jumps ---*/ - + if (config->GetMarker_All_KindBC(iMarker) == ACTDISK_INLET) V_inlet = nodes->GetPrimitive(iPoint); if (config->GetMarker_All_KindBC(iMarker) == ACTDISK_OUTLET) V_inlet = GetDonorPrimVar(iMarker, iVertex); - + Density = V_inlet[nDim+2]; Pressure = V_inlet[nDim+1]; SoundSpeed2 = Pressure*Gamma/Density; TotalArea = config->GetActDisk_Area(Marker_Tag); Force_Normal = Area*(BCThrust/TotalArea); - - + + Velocity_Normal = 0.0; for (iDim = 0; iDim < nDim; iDim++) { Velocity_Normal += V_inlet[iDim+1]*Vector[iDim]/Area; } - - + + if (Velocity_Normal > EPS) { - + /*--- Ratio of the total temperature to the temperature at the inflow ---*/ - + T0_Ti = 1.0 + ((Gamma-1.0)/SoundSpeed2)*(0.5*Velocity_Normal*Velocity_Normal + Force_Normal/(Density*Area)); - - + + ATerm = 2.0*T0_Ti/(Gamma+1.0); BTerm = 0.5*(Gamma+1.0)/(Gamma-1.0); LHS = fabs(Velocity_Normal)/(sqrt(SoundSpeed2)*pow(ATerm,BTerm)); - + CTerm_ = (PolyCoeff-1.0)/(PolyCoeff+1.0); DTerm_ = 1.0/(PolyCoeff-1.0); - + La = EPS; La_old = EPS; - + for (iter = 0; iter < 100; iter++) { - + ETerm = ((1.0-CTerm_*La*La)/(1.0-CTerm_+EPS)); - + RHS = La*pow(ETerm, DTerm_); - + ETerm = ((1.0-CTerm_*(La+1E-6)*(La+1E-6))/(1.0-CTerm_+EPS)); RHS_PDelta = (La+1E-6)*pow(ETerm, DTerm_); - + ETerm = ((1.0-CTerm_*(La-1E-6)*(La-1E-6))/(1.0-CTerm_+EPS)); RHS_MDelta = (La-1E-6)*pow(ETerm, DTerm_); - + /*--- Objective function and finitte differences derivative ---*/ - + F = RHS - LHS; DF_DLa = (RHS_PDelta - RHS_MDelta)/2E-6; - + /*--- Newton's step ---*/ - + La_old = La; La = La_old - 0.75*(F/DF_DLa); - + if (fabs(F) < 1E-10) break; - + } - + if (iter == 99) cout << "The laval number evaluation is not converging." << endl; - + /*--- Laval is bounded ---*/ - + La = min(La, sqrt(6.0)); La = max(La, 0.0); - + To_Ti = max(1.0, T0_Ti*(1.0-CTerm_*La*La)); SetActDisk_DeltaT(iMarker, iVertex, To_Ti); - + Po_Pi = max(1.0, pow(To_Ti, PolyCoeff*DTerm_)); SetActDisk_DeltaP(iMarker, iVertex, Po_Pi); - + } else { SetActDisk_DeltaT(iMarker, iVertex, 1.0); SetActDisk_DeltaP(iMarker, iVertex, 1.0); } - + } - + } } - + } } } - + /*--- Broadcast some information to the master node ---*/ - + ActDisk_Info = false; for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) == ACTDISK_INLET) || @@ -6804,7 +6801,7 @@ void CEulerSolver::SetActDisk_BCThrust(CGeometry *geometry, CSolver **solver_con } } if (!ActDisk_Info) config->SetInitial_BCThrust(0.0); - + MyBCThrust = config->GetInitial_BCThrust(); #ifdef HAVE_MPI SU2_MPI::Allreduce(&MyBCThrust, &BCThrust, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); @@ -6812,19 +6809,19 @@ void CEulerSolver::SetActDisk_BCThrust(CGeometry *geometry, CSolver **solver_con BCThrust = MyBCThrust; #endif config->SetInitial_BCThrust(BCThrust); - + } void CEulerSolver::SetFarfield_AoA(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, bool Output) { - + su2double AoA = 0.0, Vel_Infty[3], Vel_Infty_Mag; unsigned short iDim; unsigned long InnerIter = config->GetInnerIter(); su2double Beta = config->GetAoS(); /* --- Initialize values at first iteration --- */ - + if (InnerIter == 0) { Total_CD_Prev = 0.0; Total_CL_Prev = 0.0; @@ -6835,19 +6832,19 @@ void CEulerSolver::SetFarfield_AoA(CGeometry *geometry, CSolver **solver_contain dCL_dAlpha = config->GetdCL_dAlpha(); AoA_inc = 0.0; } - + /*--- Retrieve the AoA (degrees) ---*/ - + AoA = config->GetAoA(); /* --- Set new AoA if needed --- */ if (fabs(AoA_inc) > 0.0 && Output) { - + /* --- Update *_Prev values with current coefficients --- */ SetCoefficient_Gradients(config); - + Total_CD_Prev = Total_CD; Total_CL_Prev = Total_CL; Total_CMx_Prev = Total_CMx; @@ -6856,30 +6853,30 @@ void CEulerSolver::SetFarfield_AoA(CGeometry *geometry, CSolver **solver_contain AoA_Prev = AoA; /*--- Compute a new value for AoA on the fine mesh only (degrees)---*/ - + if (iMesh == MESH_0) AoA = AoA + AoA_inc; else { AoA = config->GetAoA(); } /*--- Only the fine mesh stores the updated values for AoA in config ---*/ - + if (iMesh == MESH_0) { config->SetAoA(AoA); } - + /*--- Update the freestream velocity vector at the farfield ---*/ - + for (iDim = 0; iDim < nDim; iDim++) Vel_Infty[iDim] = GetVelocity_Inf(iDim); - + /*--- Compute the magnitude of the free stream velocity ---*/ - + Vel_Infty_Mag = 0; for (iDim = 0; iDim < nDim; iDim++) Vel_Infty_Mag += Vel_Infty[iDim]*Vel_Infty[iDim]; Vel_Infty_Mag = sqrt(Vel_Infty_Mag); - + /*--- Compute the new freestream velocity with the updated AoA ---*/ - + if (nDim == 2) { Vel_Infty[0] = cos(AoA*PI_NUMBER/180.0)*Vel_Infty_Mag; Vel_Infty[1] = sin(AoA*PI_NUMBER/180.0)*Vel_Infty_Mag; @@ -6889,15 +6886,15 @@ void CEulerSolver::SetFarfield_AoA(CGeometry *geometry, CSolver **solver_contain Vel_Infty[1] = sin(Beta)*Vel_Infty_Mag; Vel_Infty[2] = sin(AoA*PI_NUMBER/180.0)*cos(Beta*PI_NUMBER/180.0)*Vel_Infty_Mag; } - + /*--- Store the new freestream velocity vector for the next iteration ---*/ - + for (iDim = 0; iDim < nDim; iDim++) { Velocity_Inf[iDim] = Vel_Infty[iDim]; } - + /*--- Only the fine mesh stores the updated values for velocity in config ---*/ - + if (iMesh == MESH_0) { for (iDim = 0; iDim < nDim; iDim++) config->SetVelocity_FreeStreamND(Vel_Infty[iDim], iDim); @@ -6931,14 +6928,14 @@ bool CEulerSolver::FixedCL_Convergence(CConfig* config, bool convergence) { } /* --- Else, set up finite differencing routine ---*/ - + Iter_Update_AoA = curr_iter; Start_AoA_FD = true; fixed_cl_conv = false; AoA_inc = 0.001; } - /* --- C_L is not converged to target value and some iterations + /* --- C_L is not converged to target value and some iterations have passed since last update, so update AoA --- */ else if ((curr_iter - Iter_Update_AoA) > config->GetStartConv_Iter()){ @@ -6979,24 +6976,24 @@ bool CEulerSolver::FixedCL_Convergence(CConfig* config, bool convergence) { //fixed_cl_conv = true; return true; } - + /* --- If starting Finite Difference Mode --- */ if (Start_AoA_FD){ - + /* --- Disable history writing --- */ config->SetHistory_Wrt_Freq(2, 0); - + /* --- End Finite Difference Mode if iteration limit is reached, so simualtion is converged --- */ - End_AoA_FD = ((curr_iter - Iter_Update_AoA - 2) == Iter_dCL_dAlpha || + End_AoA_FD = ((curr_iter - Iter_Update_AoA - 2) == Iter_dCL_dAlpha || curr_iter == config->GetnInner_Iter()- 2 ); if (convergence && (curr_iter - Iter_Update_AoA) > config->GetStartConv_Iter()) End_AoA_FD = true; - + /* --- If Finite Difference mode is ending, reset AoA and calculate Coefficient Gradients --- */ if (End_AoA_FD){ @@ -7006,13 +7003,13 @@ bool CEulerSolver::FixedCL_Convergence(CConfig* config, bool convergence) { } return fixed_cl_conv; - + } void CEulerSolver::SetCoefficient_Gradients(CConfig *config){ su2double dCL_dAlpha_, dCD_dCL_, dCMx_dCL_, dCMy_dCL_, dCMz_dCL_; su2double AoA = config->GetAoA(); - + if (AoA != AoA_Prev) { /* --- Calculate gradients of coefficients w.r.t. CL --- */ @@ -7084,87 +7081,87 @@ su2double CEulerSolver::GetInletAtVertex(su2double *val_inlet, unsigned short val_kind_marker, string val_marker, CGeometry *geometry, - CConfig *config) { - + CConfig *config) const { + /*--- Local variables ---*/ - + unsigned short iMarker, iDim; unsigned long iPoint, iVertex; su2double Area = 0.0; su2double Normal[3] = {0.0,0.0,0.0}; - + /*--- Alias positions within inlet file for readability ---*/ - + unsigned short T_position = nDim; unsigned short P_position = nDim+1; unsigned short FlowDir_position = nDim+2; - + if (val_kind_marker == INLET_FLOW) { - + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) == INLET_FLOW) && (config->GetMarker_All_TagBound(iMarker) == val_marker)) { - + for (iVertex = 0; iVertex < nVertex[iMarker]; iVertex++){ - + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - + if (iPoint == val_inlet_point) { - + /*-- Compute boundary face area for this vertex. ---*/ - + geometry->vertex[iMarker][iVertex]->GetNormal(Normal); Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); - + /*--- Access and store the inlet variables for this vertex. ---*/ - + val_inlet[T_position] = Inlet_Ttotal[iMarker][iVertex]; val_inlet[P_position] = Inlet_Ptotal[iMarker][iVertex]; for (iDim = 0; iDim < nDim; iDim++) { val_inlet[FlowDir_position + iDim] = Inlet_FlowDir[iMarker][iVertex][iDim]; } - + /*--- Exit once we find the point. ---*/ - + return Area; - + } } } } } - + /*--- If we don't find a match, then the child point is not on the current inlet boundary marker. Return zero area so this point does not contribute to the restriction operator and continue. ---*/ - + return Area; - + } void CEulerSolver::SetUniformInlet(CConfig* config, unsigned short iMarker) { - + if (config->GetMarker_All_KindBC(iMarker) == INLET_FLOW) { - + string Marker_Tag = config->GetMarker_All_TagBound(iMarker); su2double p_total = config->GetInlet_Ptotal(Marker_Tag); su2double t_total = config->GetInlet_Ttotal(Marker_Tag); su2double* flow_dir = config->GetInlet_FlowDir(Marker_Tag); - + for (unsigned long iVertex=0; iVertex < nVertex[iMarker]; iVertex++){ Inlet_Ttotal[iMarker][iVertex] = t_total; Inlet_Ptotal[iMarker][iVertex] = p_total; for (unsigned short iDim = 0; iDim < nDim; iDim++) Inlet_FlowDir[iMarker][iVertex][iDim] = flow_dir[iDim]; } - + } else { - + /*--- For now, non-inlets just get set to zero. In the future, we can do more customization for other boundary types here. ---*/ - + for (unsigned long iVertex=0; iVertex < nVertex[iMarker]; iVertex++){ Inlet_Ttotal[iMarker][iVertex] = 0.0; Inlet_Ptotal[iMarker][iVertex] = 0.0; @@ -7172,7 +7169,7 @@ void CEulerSolver::SetUniformInlet(CConfig* config, unsigned short iMarker) { Inlet_FlowDir[iMarker][iVertex][iDim] = 0.0; } } - + } void CEulerSolver::UpdateCustomBoundaryConditions(CGeometry **geometry_container, CConfig *config){ @@ -7192,10 +7189,10 @@ void CEulerSolver::UpdateCustomBoundaryConditions(CGeometry **geometry_container } void CEulerSolver::Evaluate_ObjFunc(CConfig *config) { - + unsigned short iMarker_Monitoring, Kind_ObjFunc; su2double Weight_ObjFunc; - + Total_ComboObj = 0.0; /*--- Loop over all monitored markers, add to the 'combo' objective ---*/ @@ -7251,15 +7248,15 @@ void CEulerSolver::Evaluate_ObjFunc(CConfig *config) { break; } } - + /*--- The following are not per-surface, and so to avoid that they are double-counted when multiple surfaces are specified, they have been placed outside of the loop above. In addition, multi-objective mode is also disabled for these objective functions (error thrown at start). ---*/ - + Weight_ObjFunc = config->GetWeight_ObjFunc(0); Kind_ObjFunc = config->GetKind_ObjFunc(0); - + switch(Kind_ObjFunc) { case EQUIVALENT_AREA: Total_ComboObj+=Weight_ObjFunc*Total_CEquivArea; @@ -7315,7 +7312,7 @@ void CEulerSolver::Evaluate_ObjFunc(CConfig *config) { default: break; } - + } @@ -7347,7 +7344,7 @@ void CEulerSolver::BC_Sym_Plane(CGeometry *geometry, /*--- Allocation of variables necessary for convective fluxes. ---*/ su2double Area, ProjVelocity_i, - *V_reflected, + *V_reflected, *V_domain, *Normal = new su2double[nDim], *UnitNormal = new su2double[nDim]; @@ -7383,11 +7380,11 @@ void CEulerSolver::BC_Sym_Plane(CGeometry *geometry, /*----------------------------------------------------------------------------------------------*/ /*--- Normal vector for a random vertex (zero) on this marker (negate for outward convention). ---*/ - geometry->vertex[val_marker][iVertex]->GetNormal(Normal); + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; - /*--- Compute unit normal, to be used for unit tangential, projected velocity and velocity + /*--- Compute unit normal, to be used for unit tangential, projected velocity and velocity component gradients. ---*/ Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) @@ -7397,7 +7394,7 @@ void CEulerSolver::BC_Sym_Plane(CGeometry *geometry, for (iDim = 0; iDim < nDim; iDim++) UnitNormal[iDim] = -Normal[iDim]/Area; - /*--- Preprocessing: Compute unit tangential, the direction is arbitrary as long as + /*--- Preprocessing: Compute unit tangential, the direction is arbitrary as long as t*n=0 && |t|_2 = 1 ---*/ if (viscous) { switch( nDim ) { @@ -7459,8 +7456,8 @@ void CEulerSolver::BC_Sym_Plane(CGeometry *geometry, /*--- Get current solution at this boundary node ---*/ V_domain = nodes->GetPrimitive(iPoint); - /*--- Set the reflected state based on the boundary node. Scalars are copied and - the velocity is mirrored along the symmetry boundary, i.e. the velocity in + /*--- Set the reflected state based on the boundary node. Scalars are copied and + the velocity is mirrored along the symmetry boundary, i.e. the velocity in normal direction is substracted twice. ---*/ for(iVar = 0; iVar < nPrimVar; iVar++) V_reflected[iVar] = nodes->GetPrimitive(iPoint,iVar); @@ -7580,7 +7577,7 @@ void CEulerSolver::BC_Sym_Plane(CGeometry *geometry, visc_numerics->SetTurbKineticEnergy(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0), solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0)); - /*--- Compute and update residual. Note that the viscous shear stress tensor is computed in the + /*--- Compute and update residual. Note that the viscous shear stress tensor is computed in the following routine based upon the velocity-component gradients. ---*/ visc_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); @@ -7608,10 +7605,10 @@ void CEulerSolver::BC_Sym_Plane(CGeometry *geometry, void CEulerSolver::BC_Far_Field(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + unsigned short iDim; unsigned long iVertex, iPoint, Point_Normal; - + su2double *GridVel; su2double Area, UnitNormal[3] = {0.0,0.0,0.0}; su2double Density, Pressure, Energy, Velocity[3] = {0.0,0.0,0.0}; @@ -7622,37 +7619,37 @@ void CEulerSolver::BC_Far_Field(CGeometry *geometry, CSolver **solver_container, su2double SoundSpeed_Infty, Entropy_Infty, Vel2_Infty, Vn_Infty, Qn_Infty; su2double RiemannPlus, RiemannMinus; su2double *V_infty, *V_domain; - + su2double Gas_Constant = config->GetGas_ConstantND(); - + bool implicit = config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT; bool viscous = config->GetViscous(); bool tkeNeeded = (config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST); - + su2double *Normal = new su2double[nDim]; - + /*--- Loop over all the vertices on this boundary marker ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Allocate the value at the infinity ---*/ V_infty = GetCharacPrimVar(val_marker, iVertex); - + /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ - + if (geometry->node[iPoint]->GetDomain()) { - + /*--- Index of the closest interior node ---*/ - + Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); - + /*--- Normal vector for this vertex (negate for outward convention) ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); - + /*--- Retrieve solution at the farfield boundary node ---*/ V_domain = nodes->GetPrimitive(iPoint); @@ -7791,20 +7788,20 @@ void CEulerSolver::BC_Far_Field(CGeometry *geometry, CSolver **solver_container, V_infty[nDim+3] = Energy + Pressure/Density; - + /*--- Set various quantities in the numerics class ---*/ - + conv_numerics->SetPrimitive(V_domain, V_infty); - + if (dynamic_grid) { conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); } - + /*--- Compute the convective residual using an upwind scheme ---*/ conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - + /*--- Update residual value ---*/ LinSysRes.AddBlock(iPoint, Residual); @@ -7815,38 +7812,38 @@ void CEulerSolver::BC_Far_Field(CGeometry *geometry, CSolver **solver_container, Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); /*--- Viscous residual contribution ---*/ - + if (viscous) { - + /*--- Set laminar and eddy viscosity at the infinity ---*/ - + V_infty[nDim+5] = nodes->GetLaminarViscosity(iPoint); V_infty[nDim+6] = nodes->GetEddyViscosity(iPoint); - + /*--- Set the normal vector and the coordinates ---*/ - + visc_numerics->SetNormal(Normal); visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[Point_Normal]->GetCoord()); - + /*--- Primitive variables, and gradient ---*/ - + visc_numerics->SetPrimitive(V_domain, V_infty); visc_numerics->SetPrimVarGradient(nodes->GetGradient_Primitive(iPoint), nodes->GetGradient_Primitive(iPoint)); - + /*--- Turbulent kinetic energy ---*/ - + if ((config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST)) visc_numerics->SetTurbKineticEnergy(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0), solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0)); - + /*--- Set the wall shear stress values (wall functions) to -1 (no evaluation using wall functions) ---*/ - + visc_numerics->SetTauWall(-1.0, -1.0); /*--- Compute and update viscous residual ---*/ - + visc_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); LinSysRes.SubtractBlock(iPoint, Residual); @@ -7854,15 +7851,15 @@ void CEulerSolver::BC_Far_Field(CGeometry *geometry, CSolver **solver_container, if (implicit) Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - + } - + } } - + /*--- Free locally allocated memory ---*/ delete [] Normal; - + } void CEulerSolver::BC_Riemann(CGeometry *geometry, CSolver **solver_container, @@ -7877,13 +7874,13 @@ void CEulerSolver::BC_Riemann(CGeometry *geometry, CSolver **solver_container, su2double **P_Tensor, **invP_Tensor, *Lambda_i, **Jacobian_b, **DubDu, *dw, *u_e, *u_i, *u_b; su2double *gridVel; su2double *V_boundary, *V_domain, *S_boundary, *S_domain; - + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); string Marker_Tag = config->GetMarker_All_TagBound(val_marker); bool viscous = config->GetViscous(); bool gravity = (config->GetGravityForce()); bool tkeNeeded = (config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST); - + su2double *Normal, *FlowDirMix, TangVelocity, NormalVelocity; Normal = new su2double[nDim]; @@ -7896,9 +7893,9 @@ void CEulerSolver::BC_Riemann(CGeometry *geometry, CSolver **solver_container, u_e = new su2double[nVar]; u_b = new su2double[nVar]; dw = new su2double[nVar]; - + S_boundary = new su2double[8]; - + P_Tensor = new su2double*[nVar]; invP_Tensor = new su2double*[nVar]; for (iVar = 0; iVar < nVar; iVar++) @@ -7906,35 +7903,35 @@ void CEulerSolver::BC_Riemann(CGeometry *geometry, CSolver **solver_container, P_Tensor[iVar] = new su2double[nVar]; invP_Tensor[iVar] = new su2double[nVar]; } - + /*--- Loop over all the vertices on this boundary marker ---*/ for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + V_boundary= GetCharacPrimVar(val_marker, iVertex); - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check if the node belongs to the domain (i.e., not a halo node) ---*/ if (geometry->node[iPoint]->GetDomain()) { - + /*--- Index of the closest interior node ---*/ Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); - + /*--- Normal vector for this vertex (negate for outward convention) ---*/ geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); - + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt (Area); - + for (iDim = 0; iDim < nDim; iDim++) UnitNormal[iDim] = Normal[iDim]/Area; - + /*--- Retrieve solution at this boundary node ---*/ V_domain = nodes->GetPrimitive(iPoint); - + /*--- Compute the internal state u_i ---*/ Velocity2_i = 0; for (iDim=0; iDim < nDim; iDim++) @@ -7942,29 +7939,29 @@ void CEulerSolver::BC_Riemann(CGeometry *geometry, CSolver **solver_container, Velocity_i[iDim] = nodes->GetVelocity(iPoint,iDim); Velocity2_i += Velocity_i[iDim]*Velocity_i[iDim]; } - - + + Density_i = nodes->GetDensity(iPoint); - + Energy_i = nodes->GetEnergy(iPoint); StaticEnergy_i = Energy_i - 0.5*Velocity2_i; - + FluidModel->SetTDState_rhoe(Density_i, StaticEnergy_i); - + Pressure_i = FluidModel->GetPressure(); Enthalpy_i = Energy_i + Pressure_i/Density_i; - + SoundSpeed_i = FluidModel->GetSoundSpeed(); - + Kappa_i = FluidModel->GetdPde_rho() / Density_i; Chi_i = FluidModel->GetdPdrho_e() - Kappa_i * StaticEnergy_i; - + ProjVelocity_i = 0.0; for (iDim = 0; iDim < nDim; iDim++) ProjVelocity_i += Velocity_i[iDim]*UnitNormal[iDim]; - + /*--- Build the external state u_e from boundary data and internal node ---*/ - + switch(config->GetKind_Data_Riemann(Marker_Tag)) { case TOTAL_CONDITIONS_PT: @@ -8095,66 +8092,66 @@ void CEulerSolver::BC_Riemann(CGeometry *geometry, CSolver **solver_container, SU2_MPI::Error("Invalid Riemann input!", CURRENT_FUNCTION); break; } - + /*--- Compute P (matrix of right eigenvectors) ---*/ conv_numerics->GetPMatrix(&Density_i, Velocity_i, &SoundSpeed_i, &Enthalpy_i, &Chi_i, &Kappa_i, UnitNormal, P_Tensor); - + /*--- Compute inverse P (matrix of left eigenvectors)---*/ conv_numerics->GetPMatrix_inv(invP_Tensor, &Density_i, Velocity_i, &SoundSpeed_i, &Chi_i, &Kappa_i, UnitNormal); - + /*--- eigenvalues contribution due to grid motion ---*/ if (dynamic_grid) { gridVel = geometry->node[iPoint]->GetGridVel(); - + su2double ProjGridVel = 0.0; for (iDim = 0; iDim < nDim; iDim++) ProjGridVel += gridVel[iDim]*UnitNormal[iDim]; ProjVelocity_i -= ProjGridVel; } - + /*--- Flow eigenvalues ---*/ for (iDim = 0; iDim < nDim; iDim++) Lambda_i[iDim] = ProjVelocity_i; Lambda_i[nVar-2] = ProjVelocity_i + SoundSpeed_i; Lambda_i[nVar-1] = ProjVelocity_i - SoundSpeed_i; - + /*--- Compute the boundary state u_e ---*/ u_e[0] = Density_e; for (iDim = 0; iDim < nDim; iDim++) u_e[iDim+1] = Velocity_e[iDim]*Density_e; u_e[nVar-1] = Energy_e*Density_e; - + /*--- Compute the boundary state u_i ---*/ u_i[0] = Density_i; for (iDim = 0; iDim < nDim; iDim++) u_i[iDim+1] = Velocity_i[iDim]*Density_i; u_i[nVar-1] = Energy_i*Density_i; - + /*--- Compute the characteristic jumps ---*/ for (iVar = 0; iVar < nVar; iVar++) { dw[iVar] = 0; for (jVar = 0; jVar < nVar; jVar++) dw[iVar] += invP_Tensor[iVar][jVar] * (u_e[jVar] - u_i[jVar]); - + } - + /*--- Compute the boundary state u_b using characteristics ---*/ for (iVar = 0; iVar < nVar; iVar++) { u_b[iVar] = u_i[iVar]; - + for (jVar = 0; jVar < nVar; jVar++) { if (Lambda_i[jVar] < 0) { u_b[iVar] += P_Tensor[iVar][jVar]*dw[jVar]; - + } } } - - + + /*--- Compute the thermodynamic state in u_b ---*/ Density_b = u_b[0]; Velocity2_b = 0; @@ -8171,23 +8168,23 @@ void CEulerSolver::BC_Riemann(CGeometry *geometry, CSolver **solver_container, Enthalpy_b = Energy_b + Pressure_b/Density_b; Kappa_b = FluidModel->GetdPde_rho() / Density_b; Chi_b = FluidModel->GetdPdrho_e() - Kappa_b * StaticEnergy_b; - + /*--- Compute the residuals ---*/ conv_numerics->GetInviscidProjFlux(&Density_b, Velocity_b, &Pressure_b, &Enthalpy_b, Normal, Residual); - + /*--- Residual contribution due to grid motion ---*/ if (dynamic_grid) { gridVel = geometry->node[iPoint]->GetGridVel(); su2double projVelocity = 0.0; - + for (iDim = 0; iDim < nDim; iDim++) projVelocity += gridVel[iDim]*Normal[iDim]; for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] -= projVelocity *(u_b[iVar]); } - + if (implicit) { - + Jacobian_b = new su2double*[nVar]; DubDu = new su2double*[nVar]; for (iVar = 0; iVar < nVar; iVar++) @@ -8195,17 +8192,17 @@ void CEulerSolver::BC_Riemann(CGeometry *geometry, CSolver **solver_container, Jacobian_b[iVar] = new su2double[nVar]; DubDu[iVar] = new su2double[nVar]; } - + /*--- Initialize DubDu to unit matrix---*/ - + for (iVar = 0; iVar < nVar; iVar++) { for (jVar = 0; jVar < nVar; jVar++) DubDu[iVar][jVar]= 0; - + DubDu[iVar][iVar]= 1; } - + /*--- Compute DubDu -= RNL---*/ for (iVar=0; iVarGetInviscidProjJac(Velocity_b, &Enthalpy_b, &Chi_b, &Kappa_b, Normal, 1.0, Jacobian_b); - + /*--- Jacobian contribution due to grid motion ---*/ if (dynamic_grid) { @@ -8233,14 +8230,14 @@ void CEulerSolver::BC_Riemann(CGeometry *geometry, CSolver **solver_container, Residual[iVar] -= projVelocity *(u_b[iVar]); Jacobian_b[iVar][iVar] -= projVelocity; } - + } - + /*--- initiate Jacobian_i to zero matrix ---*/ for (iVar=0; iVarGetLaminarViscosity(); V_boundary[nDim+6] = nodes->GetEddyViscosity(iPoint); V_boundary[nDim+7] = FluidModel->GetThermalConductivity(); V_boundary[nDim+8] = FluidModel->GetCp(); - + /*--- Set the normal vector and the coordinates ---*/ - + visc_numerics->SetNormal(Normal); visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[Point_Normal]->GetCoord()); - + /*--- Primitive variables, and gradient ---*/ - + visc_numerics->SetPrimitive(V_domain, V_boundary); visc_numerics->SetPrimVarGradient(nodes->GetGradient_Primitive(iPoint), nodes->GetGradient_Primitive(iPoint)); - + /*--- Secondary variables ---*/ - + S_domain = nodes->GetSecondary(iPoint); - + /*--- Compute secondary thermodynamic properties (partial derivatives...) ---*/ - + S_boundary[0]= FluidModel->GetdPdrho_e(); S_boundary[1]= FluidModel->GetdPde_rho(); - + S_boundary[2]= FluidModel->GetdTdrho_e(); S_boundary[3]= FluidModel->GetdTde_rho(); - + /*--- Compute secondary thermo-physical properties (partial derivatives...) ---*/ - + S_boundary[4]= FluidModel->Getdmudrho_T(); S_boundary[5]= FluidModel->GetdmudT_rho(); - + S_boundary[6]= FluidModel->Getdktdrho_T(); S_boundary[7]= FluidModel->GetdktdT_rho(); - + visc_numerics->SetSecondary(S_domain, S_boundary); - + /*--- Turbulent kinetic energy ---*/ if ((config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST)) visc_numerics->SetTurbKineticEnergy(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0), solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0)); - + /*--- Set the wall shear stress values (wall functions) to -1 (no evaluation using wall functions) ---*/ - + visc_numerics->SetTauWall(-1.0, -1.0); /*--- Compute and update residual ---*/ - + visc_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); LinSysRes.SubtractBlock(iPoint, Residual); - + /*--- Jacobian contribution for implicit integration ---*/ - + if (implicit) Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - + } - + } } - + /*--- Free locally allocated memory ---*/ delete [] Normal; delete [] Velocity_e; delete [] Velocity_b; delete [] Velocity_i; delete [] FlowDirMix; - + delete [] S_boundary; delete [] Lambda_i; delete [] u_i; delete [] u_e; delete [] u_b; delete [] dw; - - + + for (iVar = 0; iVar < nVar; iVar++) { delete [] P_Tensor[iVar]; @@ -8363,7 +8360,7 @@ void CEulerSolver::BC_Riemann(CGeometry *geometry, CSolver **solver_container, } delete [] P_Tensor; delete [] invP_Tensor; - + } @@ -8390,8 +8387,8 @@ void CEulerSolver::BC_TurboRiemann(CGeometry *geometry, CSolver **solver_contain su2double *Normal, *turboNormal, *UnitNormal, *FlowDirMix, FlowDirMixMag, *turboVelocity; Normal = new su2double[nDim]; - turboNormal = new su2double[nDim]; - UnitNormal = new su2double[nDim]; + turboNormal = new su2double[nDim]; + UnitNormal = new su2double[nDim]; Velocity_i = new su2double[nDim]; Velocity_b = new su2double[nDim]; @@ -8426,7 +8423,7 @@ void CEulerSolver::BC_TurboRiemann(CGeometry *geometry, CSolver **solver_contain Point_Normal = geometry->vertex[val_marker][oldVertex]->GetNormal_Neighbor(); /*--- Normal vector for this vertex (negate for outward convention), - * this normal is scaled with the area of the face of the element ---*/ + * this normal is scaled with the area of the face of the element ---*/ geometry->vertex[val_marker][oldVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); @@ -8538,7 +8535,7 @@ void CEulerSolver::BC_TurboRiemann(CGeometry *geometry, CSolver **solver_contain Density_e = FluidModel->GetDensity(); StaticEnergy_e = FluidModel->GetStaticEnergy(); Energy_e = StaticEnergy_e + 0.5 * Velocity2_e; - // if (tkeNeeded) Energy_e += GetTke_Inf(); + // if (tkeNeeded) Energy_e += GetTke_Inf(); break; @@ -8767,11 +8764,11 @@ void CEulerSolver::BC_TurboRiemann(CGeometry *geometry, CSolver **solver_contain Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); /*--- Viscous contribution ---*/ - + if (viscous) { /*--- Primitive variables, using the derived quantities ---*/ - + V_boundary[0] = Temperature_b; for (iDim = 0; iDim < nDim; iDim++) V_boundary[iDim+1] = Velocity_b[iDim]; @@ -8780,24 +8777,24 @@ void CEulerSolver::BC_TurboRiemann(CGeometry *geometry, CSolver **solver_contain V_boundary[nDim+3] = Enthalpy_b; /*--- Set laminar and eddy viscosity at the infinity ---*/ - + V_boundary[nDim+5] = FluidModel->GetLaminarViscosity(); V_boundary[nDim+6] = nodes->GetEddyViscosity(iPoint); V_boundary[nDim+7] = FluidModel->GetThermalConductivity(); V_boundary[nDim+8] = FluidModel->GetCp(); /*--- Set the normal vector and the coordinates ---*/ - + visc_numerics->SetNormal(Normal); visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[Point_Normal]->GetCoord()); /*--- Primitive variables, and gradient ---*/ - + visc_numerics->SetPrimitive(V_domain, V_boundary); visc_numerics->SetPrimVarGradient(nodes->GetGradient_Primitive(iPoint), nodes->GetGradient_Primitive(iPoint)); /*--- Secondary variables ---*/ - + S_domain = nodes->GetSecondary(iPoint); /*--- Compute secondary thermodynamic properties (partial derivatives...) ---*/ @@ -8819,21 +8816,21 @@ void CEulerSolver::BC_TurboRiemann(CGeometry *geometry, CSolver **solver_contain visc_numerics->SetSecondary(S_domain, S_boundary); /*--- Turbulent kinetic energy ---*/ - + if ((config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST)) visc_numerics->SetTurbKineticEnergy(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0), solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0)); /*--- Set the wall shear stress values (wall functions) to -1 (no evaluation using wall functions) ---*/ - + visc_numerics->SetTauWall(-1.0, -1.0); /*--- Compute and update residual ---*/ - + visc_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); LinSysRes.SubtractBlock(iPoint, Residual); /*--- Jacobian contribution for implicit integration ---*/ - + if (implicit) Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); @@ -8879,11 +8876,11 @@ void CEulerSolver::PreprocessBC_Giles(CGeometry *geometry, CConfig *config, CNum long freq; unsigned short iZone = config->GetiZone(); unsigned short nSpanWiseSections = geometry->GetnSpanWiseSections(marker_flag); - turboNormal = new su2double[nDim]; + turboNormal = new su2double[nDim]; turboVelocity = new su2double[nDim]; - Velocity_i = new su2double[nDim]; + Velocity_i = new su2double[nDim]; deltaprim = new su2double[nVar]; - cj = new su2double[nVar]; + cj = new su2double[nVar]; complex I, cktemp_inf,cktemp_out1, cktemp_out2, expArg; I = complex(0.0,1.0); @@ -9049,7 +9046,7 @@ void CEulerSolver::BC_Giles(CGeometry *geometry, CSolver **solver_container, unsigned short Turbo_Flag; Normal = new su2double[nDim]; - turboNormal = new su2double[nDim]; + turboNormal = new su2double[nDim]; UnitNormal = new su2double[nDim]; turboVelocity = new su2double[nDim]; Velocity_i = new su2double[nDim]; @@ -9345,7 +9342,7 @@ void CEulerSolver::BC_Giles(CGeometry *geometry, CSolver **solver_container, Point_Normal = geometry->vertex[val_marker][oldVertex]->GetNormal_Neighbor(); /*--- Normal vector for this vertex (negate for outward convention), - * this normal is scaled with the area of the face of the element ---*/ + * this normal is scaled with the area of the face of the element ---*/ geometry->vertex[val_marker][oldVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); @@ -9371,15 +9368,15 @@ void CEulerSolver::BC_Giles(CGeometry *geometry, CSolver **solver_container, Velocity_i[iDim] = nodes->GetVelocity(iPoint,iDim); Velocity2_i += Velocity_i[iDim]*Velocity_i[iDim]; } - - + + Density_i = nodes->GetDensity(iPoint); - + Energy_i = nodes->GetEnergy(iPoint); StaticEnergy_i = Energy_i - 0.5*Velocity2_i; - + FluidModel->SetTDState_rhoe(Density_i, StaticEnergy_i); - + Pressure_i = FluidModel->GetPressure(); ComputeTurboVelocity(Velocity_i, turboNormal, turboVelocity, config->GetMarker_All_TurbomachineryFlag(val_marker),config->GetKind_TurboMachinery(iZone)); @@ -9529,7 +9526,7 @@ void CEulerSolver::BC_Giles(CGeometry *geometry, CSolver **solver_container, /* --- subsonic Giles implementation ---*/ Beta_inf= I*complex(sqrt(1.0 - AvgMach)); - cOutjs = complex(0.0,0.0); + cOutjs = complex(0.0,0.0); for(k=0; k < 2*kend_max+1; k++){ freq = k - kend_max; if(freq >= (long)(-kend) && freq <= (long)(kend) && AverageTurboMach[0] > config->GetAverageMachLimit()){ @@ -9589,7 +9586,7 @@ void CEulerSolver::BC_Giles(CGeometry *geometry, CSolver **solver_container, SU2_MPI::Error("Invalid Giles input!", CURRENT_FUNCTION); break; } - + /*--- Compute primitive jump from characteristic variables ---*/ for (iVar = 0; iVar < nVar; iVar++) { @@ -9662,85 +9659,85 @@ void CEulerSolver::BC_Giles(CGeometry *geometry, CSolver **solver_container, /*--- Update residual value ---*/ LinSysRes.AddBlock(iPoint, Residual); - + /*--- Jacobian contribution for implicit integration ---*/ if (implicit) Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); /*--- Viscous contribution ---*/ - + if (viscous) { /*--- Set laminar and eddy viscosity at the infinity ---*/ - + V_boundary[nDim+5] = FluidModel->GetLaminarViscosity(); V_boundary[nDim+6] = nodes->GetEddyViscosity(iPoint); V_boundary[nDim+7] = FluidModel->GetThermalConductivity(); V_boundary[nDim+8] = FluidModel->GetCp(); - + /*--- Set the normal vector and the coordinates ---*/ - + visc_numerics->SetNormal(Normal); visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[Point_Normal]->GetCoord()); - + /*--- Primitive variables, and gradient ---*/ - + visc_numerics->SetPrimitive(V_domain, V_boundary); visc_numerics->SetPrimVarGradient(nodes->GetGradient_Primitive(iPoint), nodes->GetGradient_Primitive(iPoint)); /*--- Compute secondary thermodynamic properties (partial derivatives...) ---*/ - + S_boundary[0]= FluidModel->GetdPdrho_e(); S_boundary[1]= FluidModel->GetdPde_rho(); - + S_boundary[2]= FluidModel->GetdTdrho_e(); S_boundary[3]= FluidModel->GetdTde_rho(); - + /*--- Compute secondary thermo-physical properties (partial derivatives...) ---*/ - + S_boundary[4]= FluidModel->Getdmudrho_T(); S_boundary[5]= FluidModel->GetdmudT_rho(); - + S_boundary[6]= FluidModel->Getdktdrho_T(); S_boundary[7]= FluidModel->GetdktdT_rho(); - + visc_numerics->SetSecondary(S_domain, S_boundary); - + /*--- Turbulent kinetic energy ---*/ - + if ((config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST)) visc_numerics->SetTurbKineticEnergy(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0), solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0)); - + /*--- Set the wall shear stress values (wall functions) to -1 (no evaluation using wall functions) ---*/ - + visc_numerics->SetTauWall(-1.0, -1.0); /*--- Compute and update residual ---*/ - + visc_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); LinSysRes.SubtractBlock(iPoint, Residual); - + /*--- Jacobian contribution for implicit integration ---*/ - + if (implicit) Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - + } - + } } - + /*--- Free locally allocated memory ---*/ delete [] Normal; - + delete [] Velocity_b; delete [] Velocity_i; - + delete [] S_boundary; - delete [] delta_c; - delete [] deltaprim; - delete [] cj; + delete [] delta_c; + delete [] deltaprim; + delete [] cj; for (iVar = 0; iVar < nVar; iVar++) { delete [] R_Matrix[iVar]; @@ -9771,7 +9768,7 @@ void CEulerSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, Pressure, Density, Energy, *Flow_Dir, Mach2, SoundSpeed2, SoundSpeed_Total2, Vel_Mag, alpha, aa, bb, cc, dd, Area, UnitNormal[3]; su2double *V_inlet, *V_domain; - + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); su2double Two_Gamma_M1 = 2.0/Gamma_Minus_One; su2double Gas_Constant = config->GetGas_ConstantND(); @@ -9779,40 +9776,40 @@ void CEulerSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, string Marker_Tag = config->GetMarker_All_TagBound(val_marker); bool tkeNeeded = (config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST); su2double *Normal = new su2double[nDim]; - + /*--- Loop over all the vertices on this boundary marker ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + /*--- Allocate the value at the inlet ---*/ - + V_inlet = GetCharacPrimVar(val_marker, iVertex); - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check if the node belongs to the domain (i.e., not a halo node) ---*/ - + if (geometry->node[iPoint]->GetDomain()) { - + /*--- Normal vector for this vertex (negate for outward convention) ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); - + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt (Area); - + for (iDim = 0; iDim < nDim; iDim++) UnitNormal[iDim] = Normal[iDim]/Area; - + /*--- Retrieve solution at this boundary node ---*/ - + V_domain = nodes->GetPrimitive(iPoint); - + /*--- Build the fictitious intlet state based on characteristics ---*/ - + /*--- Subsonic inflow: there is one outgoing characteristic (u-c), therefore we can specify all but one state variable at the inlet. @@ -9832,7 +9829,7 @@ void CEulerSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, P_Total = Inlet_Ptotal[val_marker][iVertex]; T_Total = Inlet_Ttotal[val_marker][iVertex]; Flow_Dir = Inlet_FlowDir[val_marker][iVertex]; - + /*--- Non-dim. the inputs if necessary. ---*/ P_Total /= config->GetPressure_Ref(); @@ -9988,24 +9985,24 @@ void CEulerSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, break; } - + /*--- Set various quantities in the solver class ---*/ - + conv_numerics->SetPrimitive(V_domain, V_inlet); - + if (dynamic_grid) conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); - + /*--- Compute the residual using an upwind scheme ---*/ - + conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - + /*--- Update residual value ---*/ - + LinSysRes.AddBlock(iPoint, Residual); - + /*--- Jacobian contribution for implicit integration ---*/ - + if (implicit) Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); @@ -10048,14 +10045,14 @@ void CEulerSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, // Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); // // } - + } } - + /*--- Free locally allocated memory ---*/ - + delete [] Normal; - + } void CEulerSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, @@ -10066,40 +10063,40 @@ void CEulerSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, Velocity2, Entropy, Density, Energy, Riemann, Vn, SoundSpeed, Mach_Exit, Vn_Exit, Area, UnitNormal[3]; su2double *V_outlet, *V_domain; - + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); su2double Gas_Constant = config->GetGas_ConstantND(); string Marker_Tag = config->GetMarker_All_TagBound(val_marker); bool gravity = (config->GetGravityForce()); bool tkeNeeded = (config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST); su2double *Normal = new su2double[nDim]; - + /*--- Loop over all the vertices on this boundary marker ---*/ for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + /*--- Allocate the value at the outlet ---*/ V_outlet = GetCharacPrimVar(val_marker, iVertex); - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check if the node belongs to the domain (i.e., not a halo node) ---*/ if (geometry->node[iPoint]->GetDomain()) { - + /*--- Normal vector for this vertex (negate for outward convention) ---*/ geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); - + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt (Area); - + for (iDim = 0; iDim < nDim; iDim++) UnitNormal[iDim] = Normal[iDim]/Area; - + /*--- Current solution at this boundary node ---*/ V_domain = nodes->GetPrimitive(iPoint); - + /*--- Build the fictitious intlet state based on characteristics ---*/ /*--- Retrieve the specified back pressure for this outlet. ---*/ @@ -10165,19 +10162,19 @@ void CEulerSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, V_outlet[nDim+3] = Energy + Pressure/Density; } - + /*--- Set various quantities in the solver class ---*/ conv_numerics->SetPrimitive(V_domain, V_outlet); - + if (dynamic_grid) conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); - + /*--- Compute the residual using an upwind scheme ---*/ conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - + /*--- Update residual value ---*/ LinSysRes.AddBlock(iPoint, Residual); - + /*--- Jacobian contribution for implicit integration ---*/ if (implicit) { Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); @@ -10221,13 +10218,13 @@ void CEulerSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, // Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); // // } - + } } - + /*--- Free locally allocated memory ---*/ delete [] Normal; - + } void CEulerSolver::BC_Supersonic_Inlet(CGeometry *geometry, CSolver **solver_container, @@ -10235,35 +10232,35 @@ void CEulerSolver::BC_Supersonic_Inlet(CGeometry *geometry, CSolver **solver_con unsigned short iDim; unsigned long iVertex, iPoint; su2double *V_inlet, *V_domain; - + su2double Density, Pressure, Temperature, Energy, *Vel, Velocity2; su2double Gas_Constant = config->GetGas_ConstantND(); - + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); string Marker_Tag = config->GetMarker_All_TagBound(val_marker); bool tkeNeeded = (config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST); su2double *Normal = new su2double[nDim]; su2double *Velocity = new su2double[nDim]; - + /*--- Supersonic inlet flow: there are no outgoing characteristics, so all flow variables can be imposed at the inlet. First, retrieve the specified values for the primitive variables. ---*/ - + Temperature = config->GetInlet_Temperature(Marker_Tag); Pressure = config->GetInlet_Pressure(Marker_Tag); Vel = config->GetInlet_Velocity(Marker_Tag); - + /*--- Non-dim. the inputs if necessary. ---*/ - + Temperature /= config->GetTemperature_Ref(); Pressure /= config->GetPressure_Ref(); for (iDim = 0; iDim < nDim; iDim++) Velocity[iDim] = Vel[iDim] / config->GetVelocity_Ref(); - + /*--- Density at the inlet from the gas law ---*/ - + Density = Pressure/(Gas_Constant*Temperature); - + /*--- Compute the energy from the specified state ---*/ Velocity2 = 0.0; @@ -10271,58 +10268,58 @@ void CEulerSolver::BC_Supersonic_Inlet(CGeometry *geometry, CSolver **solver_con Velocity2 += Velocity[iDim]*Velocity[iDim]; Energy = Pressure/(Density*Gamma_Minus_One)+0.5*Velocity2; if (tkeNeeded) Energy += GetTke_Inf(); - + /*--- Loop over all the vertices on this boundary marker ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + /*--- Allocate the value at the outlet ---*/ - + V_inlet = GetCharacPrimVar(val_marker, iVertex); - + /*--- Primitive variables, using the derived quantities ---*/ - + V_inlet[0] = Temperature; for (iDim = 0; iDim < nDim; iDim++) V_inlet[iDim+1] = Velocity[iDim]; V_inlet[nDim+1] = Pressure; V_inlet[nDim+2] = Density; V_inlet[nDim+3] = Energy + Pressure/Density; - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ - + if (geometry->node[iPoint]->GetDomain()) { - + /*--- Current solution at this boundary node ---*/ - + V_domain = nodes->GetPrimitive(iPoint); - + /*--- Normal vector for this vertex (negate for outward convention) ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; - + /*--- Set various quantities in the solver class ---*/ - + conv_numerics->SetNormal(Normal); conv_numerics->SetPrimitive(V_domain, V_inlet); - + if (dynamic_grid) conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); /*--- Compute the residual using an upwind scheme ---*/ - + conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); LinSysRes.AddBlock(iPoint, Residual); - + /*--- Jacobian contribution for implicit integration ---*/ - + if (implicit) Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - + // /*--- Viscous contribution, commented out because serious convergence problems ---*/ // // if (viscous) { @@ -10361,12 +10358,12 @@ void CEulerSolver::BC_Supersonic_Inlet(CGeometry *geometry, CSolver **solver_con // if (implicit) // Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); // } - + } } - + /*--- Free locally allocated memory ---*/ - + delete [] Normal; delete [] Velocity; @@ -10377,70 +10374,70 @@ void CEulerSolver::BC_Supersonic_Outlet(CGeometry *geometry, CSolver **solver_co unsigned short iDim; unsigned long iVertex, iPoint; su2double *V_outlet, *V_domain; - + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - + su2double *Normal = new su2double[nDim]; - + /*--- Supersonic outlet flow: there are no ingoing characteristics, so all flow variables can should be interpolated from the domain. ---*/ - + /*--- Loop over all the vertices on this boundary marker ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ - + if (geometry->node[iPoint]->GetDomain()) { - + /*--- Current solution at this boundary node ---*/ - + V_domain = nodes->GetPrimitive(iPoint); - + /*--- Allocate the value at the outlet ---*/ - + V_outlet = GetCharacPrimVar(val_marker, iVertex); - + /*--- Primitive variables, using the derived quantities ---*/ - + V_outlet[0] = V_domain[0]; for (iDim = 0; iDim < nDim; iDim++) V_outlet[iDim+1] = V_domain[iDim+1]; V_outlet[nDim+1] = V_domain[nDim+1]; V_outlet[nDim+2] = V_domain[nDim+2]; V_outlet[nDim+3] = V_domain[nDim+3]; - + /*--- Current solution at this boundary node ---*/ - + V_domain = nodes->GetPrimitive(iPoint); - + /*--- Normal vector for this vertex (negate for outward convention) ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; - + /*--- Set various quantities in the solver class ---*/ - + conv_numerics->SetNormal(Normal); conv_numerics->SetPrimitive(V_domain, V_outlet); - + if (dynamic_grid) conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); - + /*--- Compute the residual using an upwind scheme ---*/ - + conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); LinSysRes.AddBlock(iPoint, Residual); - + /*--- Jacobian contribution for implicit integration ---*/ - + if (implicit) Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - + // /*--- Viscous contribution, commented out because serious convergence problems ---*/ // // if (viscous) { @@ -10479,24 +10476,24 @@ void CEulerSolver::BC_Supersonic_Outlet(CGeometry *geometry, CSolver **solver_co // if (implicit) // Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); // } - + } } - + /*--- Free locally allocated memory ---*/ - + delete [] Normal; - + } void CEulerSolver::BC_Engine_Inflow(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + unsigned short iDim; unsigned long iVertex, iPoint; su2double Pressure, Inflow_Pressure = 0.0, Velocity[3], Velocity2, Entropy, Target_Inflow_MassFlow = 0.0, Target_Inflow_Mach = 0.0, Density, Energy, Riemann, Area, UnitNormal[3], Vn, SoundSpeed, Vn_Exit, Inflow_Pressure_inc, Inflow_Pressure_old, Inflow_Mach_old, Inflow_MassFlow_old; su2double *V_inflow, *V_domain; - + su2double DampingFactor = config->GetDamp_Engine_Inflow(); bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); unsigned short Kind_Engine_Inflow = config->GetKind_Engine_Inflow(); @@ -10507,104 +10504,104 @@ void CEulerSolver::BC_Engine_Inflow(CGeometry *geometry, CSolver **solver_contai bool Engine_HalfModel = config->GetEngine_HalfModel(); su2double *Normal = new su2double[nDim]; - - + + if (Kind_Engine_Inflow == FAN_FACE_MACH) { - + /*--- Retrieve the specified target fan face mach at the nacelle. ---*/ - + Target_Inflow_Mach = config->GetEngineInflow_Target(Marker_Tag); - + /*--- Retrieve the old fan face pressure and mach number in the nacelle (this has been computed in a preprocessing). ---*/ - + Inflow_Pressure_old = config->GetInflow_Pressure(Marker_Tag); // Note that has been computed by the code (non-dimensional). Inflow_Mach_old = config->GetInflow_Mach(Marker_Tag); - + /*--- Compute the pressure increment (note that increasing pressure decreases flow speed) ---*/ - + Inflow_Pressure_inc = - (1.0 - (Inflow_Mach_old/Target_Inflow_Mach)) * Baseline_Press; - + /*--- Estimate the new fan face pressure ---*/ - + Inflow_Pressure = (1.0 - DampingFactor)*Inflow_Pressure_old + DampingFactor * (Inflow_Pressure_old + Inflow_Pressure_inc); - + } - + if (Kind_Engine_Inflow == FAN_FACE_MDOT) { - + /*--- Retrieve the specified target mass flow (non-dimensional) at the nacelle. ---*/ - + Target_Inflow_MassFlow = config->GetEngineInflow_Target(Marker_Tag) / (config->GetDensity_Ref() * config->GetVelocity_Ref()); - + if (config->GetSystemMeasurements() == US) Target_Inflow_MassFlow /= 32.174; - + if (Engine_HalfModel) Target_Inflow_MassFlow /= 2.0; /*--- Retrieve the old fan face pressure and mach number in the nacelle (this has been computed in a preprocessing). ---*/ - + Inflow_Pressure_old = config->GetInflow_Pressure(Marker_Tag); // Note that has been computed by the code (non-dimensional). Inflow_MassFlow_old = config->GetInflow_MassFlow(Marker_Tag); // same here... it is a non dimensional value - + /*--- Compute the pressure increment (note that increasing pressure decreases flow speed) ---*/ - + Inflow_Pressure_inc = - (1.0 - (Inflow_MassFlow_old/Target_Inflow_MassFlow)) * Baseline_Press; - + /*--- Estimate the new fan face pressure ---*/ - + Inflow_Pressure = (1.0 - DampingFactor)*Inflow_Pressure_old + DampingFactor * (Inflow_Pressure_old + Inflow_Pressure_inc); - + } - + /*--- No iterative scheme if we provide the static pressure ---*/ - + if (Kind_Engine_Inflow == FAN_FACE_PRESSURE) { - + /*--- Retrieve the specified pressure (non-dimensional) at the nacelle. ---*/ - + Inflow_Pressure = config->GetEngineInflow_Target(Marker_Tag) / config->GetPressure_Ref(); - + } - - + + /*--- Loop over all the vertices on this boundary marker ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + /*--- Allocate the value at the outlet ---*/ - + V_inflow = GetCharacPrimVar(val_marker, iVertex); - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ - + if (geometry->node[iPoint]->GetDomain()) { - + /*--- Normal vector for this vertex (negate for outward convention) ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; - + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt (Area); - + for (iDim = 0; iDim < nDim; iDim++) UnitNormal[iDim] = Normal[iDim]/Area; - + /*--- Current solution at this boundary node ---*/ - + V_domain = nodes->GetPrimitive(iPoint); - + /*--- Subsonic nacelle inflow: there is one incoming characteristic, therefore one variable can be specified (back pressure) and is used to update the conservative variables. - + Compute the entropy and the acoustic variable. These riemann invariants, as well as the tangential velocity components, are extrapolated. ---*/ - + Density = V_domain[nDim+2]; Velocity2 = 0.0; Vn = 0.0; for (iDim = 0; iDim < nDim; iDim++) { @@ -10616,9 +10613,9 @@ void CEulerSolver::BC_Engine_Inflow(CGeometry *geometry, CSolver **solver_contai SoundSpeed = sqrt(Gamma*Pressure/Density); Entropy = Pressure*pow(1.0/Density, Gamma); Riemann = Vn + 2.0*SoundSpeed/Gamma_Minus_One; - + /*--- Compute the new fictious state at the outlet ---*/ - + Density = pow(Inflow_Pressure/Entropy,1.0/Gamma); Pressure = Inflow_Pressure; SoundSpeed = sqrt(Gamma*Inflow_Pressure/Density); @@ -10628,12 +10625,12 @@ void CEulerSolver::BC_Engine_Inflow(CGeometry *geometry, CSolver **solver_contai Velocity[iDim] = Velocity[iDim] + (Vn_Exit-Vn)*UnitNormal[iDim]; Velocity2 += Velocity[iDim]*Velocity[iDim]; } - + Energy = Inflow_Pressure/(Density*Gamma_Minus_One) + 0.5*Velocity2; if (tkeNeeded) Energy += GetTke_Inf(); - + /*--- Conservative variables, using the derived quantities ---*/ - + V_inflow[0] = Pressure / ( Gas_Constant * Density); for (iDim = 0; iDim < nDim; iDim++) V_inflow[iDim+1] = Velocity[iDim]; @@ -10641,27 +10638,27 @@ void CEulerSolver::BC_Engine_Inflow(CGeometry *geometry, CSolver **solver_contai V_inflow[nDim+2] = Density; V_inflow[nDim+3] = Energy + Pressure/Density; V_inflow[nDim+4] = SoundSpeed; - + /*--- Set various quantities in the solver class ---*/ - + conv_numerics->SetNormal(Normal); conv_numerics->SetPrimitive(V_domain, V_inflow); - + /*--- Set grid movement ---*/ - + if (dynamic_grid) conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); /*--- Compute the residual using an upwind scheme ---*/ - + conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); LinSysRes.AddBlock(iPoint, Residual); - + /*--- Jacobian contribution for implicit integration ---*/ - + if (implicit) Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - + // /*--- Viscous contribution, commented out because serious convergence problems ---*/ // // if (viscous) { @@ -10701,94 +10698,94 @@ void CEulerSolver::BC_Engine_Inflow(CGeometry *geometry, CSolver **solver_contai // Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); // // } - + } } - + delete [] Normal; - + } void CEulerSolver::BC_Engine_Exhaust(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + unsigned short iDim; unsigned long iVertex, iPoint; su2double Exhaust_Pressure, Exhaust_Temperature, Velocity[3], Velocity2, H_Exhaust, Temperature, Riemann, Area, UnitNormal[3], Pressure, Density, Energy, Mach2, SoundSpeed2, SoundSpeed_Exhaust2, Vel_Mag, alpha, aa, bb, cc, dd, Flow_Dir[3]; su2double *V_exhaust, *V_domain, Target_Exhaust_Pressure, Exhaust_Pressure_old, Exhaust_Pressure_inc; - + su2double Gas_Constant = config->GetGas_ConstantND(); bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); string Marker_Tag = config->GetMarker_All_TagBound(val_marker); bool tkeNeeded = (config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST); su2double DampingFactor = config->GetDamp_Engine_Exhaust(); su2double Baseline_Press = 0.75 * config->GetPressure_FreeStreamND(); - + su2double *Normal = new su2double[nDim]; - + /*--- Retrieve the specified exhaust pressure in the engine (non-dimensional). ---*/ - + Target_Exhaust_Pressure = config->GetExhaust_Pressure_Target(Marker_Tag) / config->GetPressure_Ref(); - + /*--- Retrieve the old exhaust pressure in the engine exhaust (this has been computed in a preprocessing). ---*/ - + Exhaust_Pressure_old = config->GetExhaust_Pressure(Marker_Tag); - + /*--- Compute the Pressure increment ---*/ - + Exhaust_Pressure_inc = (1.0 - (Exhaust_Pressure_old/Target_Exhaust_Pressure)) * Baseline_Press; - + /*--- Estimate the new exhaust pressure ---*/ - + Exhaust_Pressure = (1.0 - DampingFactor) * Exhaust_Pressure_old + DampingFactor * (Exhaust_Pressure_old + Exhaust_Pressure_inc); - + /*--- The temperature is given (no iteration is required) ---*/ - + Exhaust_Temperature = config->GetExhaust_Temperature_Target(Marker_Tag); Exhaust_Temperature /= config->GetTemperature_Ref(); - + /*--- The pressure is given (no iteration is required) ---*/ - + Exhaust_Pressure = config->GetExhaust_Pressure_Target(Marker_Tag); Exhaust_Pressure /= config->GetPressure_Ref(); - + /*--- Loop over all the vertices on this boundary marker ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + /*--- Allocate the value at the exhaust ---*/ - + V_exhaust = GetCharacPrimVar(val_marker, iVertex); - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ - + if (geometry->node[iPoint]->GetDomain()) { - + /*--- Normal vector for this vertex (negate for outward convention) ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; - + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt (Area); - + for (iDim = 0; iDim < nDim; iDim++) UnitNormal[iDim] = Normal[iDim]/Area; - + /*--- Current solution at this boundary node ---*/ - + V_domain = nodes->GetPrimitive(iPoint); - + /*--- Subsonic inflow: there is one outgoing characteristic (u-c), therefore we can specify all but one state variable at the inlet. The outgoing Riemann invariant provides the final piece of info. ---*/ - + /*--- Store primitives and set some variables for clarity. ---*/ - + Density = V_domain[nDim+2]; Velocity2 = 0.0; for (iDim = 0; iDim < nDim; iDim++) { @@ -10799,79 +10796,79 @@ void CEulerSolver::BC_Engine_Exhaust(CGeometry *geometry, CSolver **solver_conta Pressure = V_domain[nDim+1]; H_Exhaust = (Gamma*Gas_Constant/Gamma_Minus_One)*Exhaust_Temperature; SoundSpeed2 = Gamma*Pressure/Density; - + /*--- Compute the acoustic Riemann invariant that is extrapolated from the domain interior. ---*/ - + Riemann = 2.0*sqrt(SoundSpeed2)/Gamma_Minus_One; for (iDim = 0; iDim < nDim; iDim++) Riemann += Velocity[iDim]*UnitNormal[iDim]; - + /*--- Total speed of sound ---*/ - + SoundSpeed_Exhaust2 = Gamma_Minus_One*(H_Exhaust - (Energy + Pressure/Density)+0.5*Velocity2) + SoundSpeed2; - + /*--- The flow direction is defined by the surface normal ---*/ - + for (iDim = 0; iDim < nDim; iDim++) Flow_Dir[iDim] = -UnitNormal[iDim]; - + /*--- Dot product of normal and flow direction. This should be negative due to outward facing boundary normal convention. ---*/ - + alpha = 0.0; for (iDim = 0; iDim < nDim; iDim++) alpha += UnitNormal[iDim]*Flow_Dir[iDim]; - + /*--- Coefficients in the quadratic equation for the velocity ---*/ - + aa = 1.0 + 0.5*Gamma_Minus_One*alpha*alpha; bb = -1.0*Gamma_Minus_One*alpha*Riemann; cc = 0.5*Gamma_Minus_One*Riemann*Riemann - 2.0*SoundSpeed_Exhaust2/Gamma_Minus_One; - + /*--- Solve quadratic equation for velocity magnitude. Value must be positive, so the choice of root is clear. ---*/ - + dd = bb*bb - 4.0*aa*cc; dd = sqrt(max(0.0, dd)); Vel_Mag = (-bb + dd)/(2.0*aa); - + if (Vel_Mag >= 0.0) { - + Velocity2 = Vel_Mag*Vel_Mag; - + /*--- Compute speed of sound from total speed of sound eqn. ---*/ - + SoundSpeed2 = SoundSpeed_Exhaust2 - 0.5*Gamma_Minus_One*Velocity2; Mach2 = Velocity2/SoundSpeed2; Velocity2 = Mach2*SoundSpeed2; Vel_Mag = sqrt(Velocity2); SoundSpeed2 = SoundSpeed_Exhaust2 - 0.5*Gamma_Minus_One*Velocity2; - + /*--- Compute new velocity vector at the inlet ---*/ - + for (iDim = 0; iDim < nDim; iDim++) Velocity[iDim] = Vel_Mag*Flow_Dir[iDim]; - + /*--- Static temperature from the speed of sound relation ---*/ - + Temperature = SoundSpeed2/(Gamma*Gas_Constant); - + /*--- Static pressure using isentropic relation at a point ---*/ - + Pressure = Exhaust_Pressure*pow((Temperature/Exhaust_Temperature), Gamma/Gamma_Minus_One); - + /*--- Density at the exhaust from the gas law ---*/ - + Density = Pressure/(Gas_Constant*Temperature); - + /*--- Using pressure, density, & velocity, compute the energy ---*/ - + Energy = Pressure/(Density*Gamma_Minus_One) + 0.5*Velocity2; if (tkeNeeded) Energy += GetTke_Inf(); - + /*--- Primitive variables, using the derived quantities ---*/ - + V_exhaust[0] = Temperature; for (iDim = 0; iDim < nDim; iDim++) V_exhaust[iDim+1] = Velocity[iDim]; @@ -10879,12 +10876,12 @@ void CEulerSolver::BC_Engine_Exhaust(CGeometry *geometry, CSolver **solver_conta V_exhaust[nDim+2] = Density; V_exhaust[nDim+3] = Energy + Pressure/Density; V_exhaust[nDim+4] = sqrt(SoundSpeed2); - - } + + } /*--- The flow goes in the wrong direction ---*/ - + else { - + V_exhaust[0] = V_domain[0]; for (iDim = 0; iDim < nDim; iDim++) V_exhaust[iDim+1] = V_domain[iDim+1]; @@ -10892,29 +10889,29 @@ void CEulerSolver::BC_Engine_Exhaust(CGeometry *geometry, CSolver **solver_conta V_exhaust[nDim+2] = V_domain[nDim+2]; V_exhaust[nDim+3] = V_domain[nDim+3]; V_exhaust[nDim+4] = V_domain[nDim+4]; - + } - + /*--- Set various quantities in the solver class ---*/ - + conv_numerics->SetNormal(Normal); conv_numerics->SetPrimitive(V_domain, V_exhaust); - + /*--- Set grid movement ---*/ if (dynamic_grid) conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); /*--- Compute the residual using an upwind scheme ---*/ - + conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); LinSysRes.AddBlock(iPoint, Residual); - + /*--- Jacobian contribution for implicit integration ---*/ - + if (implicit) Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - + // /*--- Viscous contribution, commented out because serious convergence problems ---*/ // // if (viscous) { @@ -10954,31 +10951,31 @@ void CEulerSolver::BC_Engine_Exhaust(CGeometry *geometry, CSolver **solver_conta // Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); // // } - + } } - + delete [] Normal; - + } void CEulerSolver::BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config) { - + unsigned long iVertex, jVertex, iPoint, Point_Normal = 0; unsigned short iDim, iVar, iMarker, nDonorVertex; - + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); bool viscous = config->GetViscous(); - + su2double *Normal = new su2double[nDim]; su2double *PrimVar_i = new su2double[nPrimVar]; su2double *PrimVar_j = new su2double[nPrimVar]; su2double *tmp_residual = new su2double[nVar]; - + su2double weight; su2double P_static, rho_static; - + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { if (config->GetMarker_All_KindBC(iMarker) == FLUID_INTERFACE) { @@ -10989,7 +10986,7 @@ void CEulerSolver::BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_cont if (geometry->node[iPoint]->GetDomain()) { nDonorVertex = GetnSlidingStates(iMarker, iVertex); - + /*--- Initialize Residual, this will serve to accumulate the average ---*/ for (iVar = 0; iVar < nVar; iVar++) @@ -11005,7 +11002,7 @@ void CEulerSolver::BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_cont PrimVar_i[iVar] = nodes->GetPrimitive(iPoint,iVar); PrimVar_j[iVar] = GetSlidingState(iMarker, iVertex, iVar, jVertex); } - + /*--- Get the weight computed in the interpolator class for the j-th donor vertex ---*/ weight = GetSlidingState(iMarker, iVertex, nPrimVar, jVertex); @@ -11013,65 +11010,65 @@ void CEulerSolver::BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_cont /*--- Set primitive variables ---*/ conv_numerics->SetPrimitive( PrimVar_i, PrimVar_j ); - + if( !( config->GetKind_FluidModel() == STANDARD_AIR || config->GetKind_FluidModel() == IDEAL_GAS ) ) { Secondary_i = nodes->GetSecondary(iPoint); P_static = PrimVar_j[nDim+1]; - rho_static = PrimVar_j[nDim+2]; + rho_static = PrimVar_j[nDim+2]; FluidModel->SetTDState_Prho(P_static, rho_static); Secondary_j[0] = FluidModel->GetdPdrho_e(); - Secondary_j[1] = FluidModel->GetdPde_rho(); + Secondary_j[1] = FluidModel->GetdPde_rho(); conv_numerics->SetSecondary(Secondary_i, Secondary_j); } /*--- Set the normal vector ---*/ - + geometry->vertex[iMarker][iVertex]->GetNormal(Normal); - for (iDim = 0; iDim < nDim; iDim++) + for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); if (dynamic_grid) conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); - + /*--- Compute the convective residual using an upwind scheme ---*/ conv_numerics->ComputeResidual(tmp_residual, Jacobian_i, Jacobian_j, config); /*--- Accumulate the residuals to compute the average ---*/ - + for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] += weight*tmp_residual[iVar]; } /*--- Add Residuals and Jacobians ---*/ - + LinSysRes.AddBlock(iPoint, Residual); - if (implicit) + if (implicit) Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); if (viscous) { - + /*--- Initialize Residual, this will serve to accumulate the average ---*/ - + for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = 0.0; - + /*--- Loop over the nDonorVertexes and compute the averaged flux ---*/ - + for (jVertex = 0; jVertex < nDonorVertex; jVertex++){ - PrimVar_j[nDim+5] = GetSlidingState(iMarker, iVertex, nDim+5, jVertex); - PrimVar_j[nDim+6] = GetSlidingState(iMarker, iVertex, nDim+6, jVertex); + PrimVar_j[nDim+5] = GetSlidingState(iMarker, iVertex, nDim+5, jVertex); + PrimVar_j[nDim+6] = GetSlidingState(iMarker, iVertex, nDim+6, jVertex); /*--- Get the weight computed in the interpolator class for the j-th donor vertex ---*/ - + weight = GetSlidingState(iMarker, iVertex, nPrimVar, jVertex); - + /*--- Set the normal vector and the coordinates ---*/ visc_numerics->SetNormal(Normal); @@ -11088,26 +11085,26 @@ void CEulerSolver::BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_cont visc_numerics->SetTurbKineticEnergy(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0), solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0)); /*--- Set the wall shear stress values (wall functions) to -1 (no evaluation using wall functions) ---*/ - + visc_numerics->SetTauWall(-1.0, -1.0); /*--- Compute and update residual ---*/ visc_numerics->ComputeResidual(tmp_residual, Jacobian_i, Jacobian_j, config); - + /*--- Accumulate the residuals to compute the average ---*/ - + for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] += weight*tmp_residual[iVar]; } - + LinSysRes.SubtractBlock(iPoint, Residual); - + /*--- Jacobian contribution for implicit integration ---*/ if (implicit) Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - + } } } @@ -11124,143 +11121,143 @@ void CEulerSolver::BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_cont void CEulerSolver::BC_Interface_Boundary(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short val_marker) { - + unsigned long iVertex, iPoint, GlobalIndex_iPoint, GlobalIndex_jPoint; unsigned short iDim, iVar; - + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); - + su2double *Normal = new su2double[nDim]; su2double *PrimVar_i = new su2double[nPrimVar]; su2double *PrimVar_j = new su2double[nPrimVar]; - + /*--- Do the send process, by the moment we are sending each node individually, this must be changed ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); GlobalIndex_iPoint = geometry->node[iPoint]->GetGlobalIndex(); GlobalIndex_jPoint = GetDonorGlobalIndex(val_marker, iVertex); - + if ((geometry->node[iPoint]->GetDomain()) && (GlobalIndex_iPoint != GlobalIndex_jPoint)) { - + /*--- Store the solution for both points ---*/ - + for (iVar = 0; iVar < nPrimVar; iVar++) { PrimVar_i[iVar] = nodes->GetPrimitive(iPoint,iVar); PrimVar_j[iVar] = GetDonorPrimVar(val_marker, iVertex, iVar); } - + /*--- Set Conservative Variables ---*/ - + numerics->SetPrimitive(PrimVar_i, PrimVar_j); - + /*--- Set Normal ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; numerics->SetNormal(Normal); - + /*--- Compute the convective residual using an upwind scheme ---*/ - + numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - + /*--- Add Residuals and Jacobians ---*/ - + LinSysRes.AddBlock(iPoint, Residual); if (implicit) Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - + } - + } - + /*--- Free locally allocated memory ---*/ - + delete [] Normal; delete [] PrimVar_i; delete [] PrimVar_j; - + } void CEulerSolver::BC_NearField_Boundary(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short val_marker) { - + unsigned long iVertex, iPoint, GlobalIndex_iPoint, GlobalIndex_jPoint; unsigned short iDim, iVar; - + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); - + su2double *Normal = new su2double[nDim]; su2double *PrimVar_i = new su2double[nPrimVar]; su2double *PrimVar_j = new su2double[nPrimVar]; - + /*--- Do the send process, by the moment we are sending each node individually, this must be changed ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); GlobalIndex_iPoint = geometry->node[iPoint]->GetGlobalIndex(); GlobalIndex_jPoint = GetDonorGlobalIndex(val_marker, iVertex); - + if ((geometry->node[iPoint]->GetDomain()) && (GlobalIndex_iPoint != GlobalIndex_jPoint)) { - + /*--- Store the solution for both points ---*/ - + for (iVar = 0; iVar < nPrimVar; iVar++) { PrimVar_i[iVar] = nodes->GetPrimitive(iPoint,iVar); PrimVar_j[iVar] = GetDonorPrimVar(val_marker, iVertex, iVar); } - + /*--- Set Conservative Variables ---*/ - + numerics->SetPrimitive(PrimVar_i, PrimVar_j); - + /*--- Set Normal ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; numerics->SetNormal(Normal); - + /*--- Compute the convective residual using an upwind scheme ---*/ - + numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - + /*--- Add Residuals and Jacobians ---*/ - + LinSysRes.AddBlock(iPoint, Residual); if (implicit) Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - + } - + } - + /*--- Free locally allocated memory ---*/ - + delete [] Normal; delete [] PrimVar_i; delete [] PrimVar_j; - + } void CEulerSolver::BC_ActDisk_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + BC_ActDisk(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker, true); - + } void CEulerSolver::BC_ActDisk_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + BC_ActDisk(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker, false); - + } void CEulerSolver::BC_ActDisk(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker, bool val_inlet_surface) { - + unsigned short iDim; unsigned long iVertex, iPoint, GlobalIndex_donor, GlobalIndex; su2double Pressure, Velocity[3], Target_Press_Jump, Target_Temp_Jump, @@ -11272,83 +11269,83 @@ void CEulerSolver::BC_ActDisk(CGeometry *geometry, CSolver **solver_container, C su2double Vel_normal_outlet[3], Vel_tangent_outlet[3], Vel_outlet[3]; su2double Vel_normal_inlet_, Vel_tangent_inlet_, Vel_inlet_; su2double Vel_normal_outlet_, Vel_outlet_; - + su2double Pressure_out, Density_out, SoundSpeed_out, Velocity2_out, Mach_out, Pressure_in, Density_in, SoundSpeed_in, Velocity2_in, Mach_in, PressureAdj, TemperatureAdj; - + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); su2double Gas_Constant = config->GetGas_ConstantND(); bool tkeNeeded = (config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST); bool ratio = (config->GetActDisk_Jump() == RATIO); su2double SecondaryFlow = config->GetSecondaryFlow_ActDisk(); - + su2double *Normal = new su2double[nDim]; su2double *Flow_Dir = new su2double[nDim]; - + /*--- Loop over all the vertices on this boundary marker ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); GlobalIndex = geometry->node[iPoint]->GetGlobalIndex(); GlobalIndex_donor = GetDonorGlobalIndex(val_marker, iVertex); - + /*--- Check if the node belongs to the domain (i.e., not a halo node) ---*/ - + if ((geometry->node[iPoint]->GetDomain()) && (GlobalIndex != GlobalIndex_donor)) { - + /*--- Normal vector for this vertex (negative for outward convention) ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); - + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt (Area); - + for (iDim = 0; iDim < nDim; iDim++) UnitNormal[iDim] = Normal[iDim]/Area; - + /*--- Current solution at this boundary node and jumps values ---*/ - + V_domain = nodes->GetPrimitive(iPoint); Target_Press_Jump = GetActDisk_DeltaP(val_marker, iVertex); Target_Temp_Jump = GetActDisk_DeltaT(val_marker, iVertex); - + if (val_inlet_surface) { V_inlet = nodes->GetPrimitive(iPoint); V_outlet = GetDonorPrimVar(val_marker, iVertex); - + Pressure_out = V_outlet[nDim+1]; Density_out = V_outlet[nDim+2]; SoundSpeed_out = sqrt(Gamma*Pressure_out/Density_out); - + Pressure_in = V_inlet[nDim+1]; Density_in = V_inlet[nDim+2]; SoundSpeed_in = sqrt(Gamma*Pressure_in/Density_in); - + Velocity2_out = 0.0; Velocity2_in = 0.0; for (iDim = 0; iDim < nDim; iDim++) { Velocity2_out += V_outlet[iDim+1]*V_outlet[iDim+1]; Velocity2_in += V_inlet[iDim+1]*V_inlet[iDim+1]; } - + PressureAdj = 1.0; TemperatureAdj = 1.0; if ((Velocity2_out > 0.0) && (Velocity2_in > 0.0)) { - + Mach_out = sqrt(Velocity2_out)/SoundSpeed_out; Mach_in = sqrt(Velocity2_in)/SoundSpeed_in; - + PressureAdj = pow( 1.0 + Mach_out * Mach_out * 0.5 * (Gamma - 1.0), Gamma / (Gamma - 1.0)) / pow( 1.0 + Mach_in * Mach_in * 0.5 * (Gamma - 1.0), Gamma / (Gamma - 1.0)); TemperatureAdj = (1.0 + Mach_out * Mach_out * 0.5 * (Gamma - 1.0)) / (1.0 + Mach_in * Mach_in * 0.5 * (Gamma - 1.0)); - + } - + if (ratio) { P_static = V_outlet[nDim+1] / (Target_Press_Jump/PressureAdj); T_static = V_outlet[0] / (Target_Temp_Jump/TemperatureAdj); @@ -11358,47 +11355,47 @@ void CEulerSolver::BC_ActDisk(CGeometry *geometry, CSolver **solver_container, C else { V_outlet = nodes->GetPrimitive(iPoint); V_inlet = GetDonorPrimVar(val_marker, iVertex); - + Pressure_out = V_outlet[nDim+1]; Density_out = V_outlet[nDim+2]; SoundSpeed_out = sqrt(Gamma*Pressure_out/Density_out); - + Pressure_in = V_inlet[nDim+1]; Density_in = V_inlet[nDim+2]; SoundSpeed_in = sqrt(Gamma*Pressure_in/Density_in); - + Velocity2_out = 0.0; Velocity2_in = 0.0; for (iDim = 0; iDim < nDim; iDim++) { Velocity2_out += V_outlet[iDim+1]*V_outlet[iDim+1]; Velocity2_in += V_inlet[iDim+1]*V_inlet[iDim+1]; } - + PressureAdj = 1.0; TemperatureAdj = 1.0; if ((Velocity2_out > 0.0) && (Velocity2_in > 0.0)) { - + Mach_out = sqrt(Velocity2_out)/SoundSpeed_out; Mach_in = sqrt(Velocity2_in)/SoundSpeed_in; - + PressureAdj = pow( 1.0 + Mach_out * Mach_out * 0.5 * (Gamma - 1.0), Gamma / (Gamma - 1.0)) / pow( 1.0 + Mach_in * Mach_in * 0.5 * (Gamma - 1.0), Gamma / (Gamma - 1.0)); TemperatureAdj = (1.0 + Mach_out * Mach_out * 0.5 * (Gamma - 1.0)) / (1.0 + Mach_in * Mach_in * 0.5 * (Gamma - 1.0)); } - + if (ratio) { P_static = V_inlet[nDim+1] * (Target_Press_Jump/PressureAdj); T_static = V_inlet[0] * (Target_Temp_Jump/TemperatureAdj); } else { P_static = V_inlet[nDim+1] + Target_Press_Jump; T_static = V_inlet[0] + Target_Temp_Jump; } } - + /*--- Subsonic inlet ---*/ - + if (val_inlet_surface) { - + /*--- Build the fictitious intlet state based on characteristics. Retrieve the specified back pressure for this inlet ---*/ - + Density = V_domain[nDim+2]; Velocity2 = 0.0; Vn = 0.0; for (iDim = 0; iDim < nDim; iDim++) { @@ -11408,17 +11405,17 @@ void CEulerSolver::BC_ActDisk(CGeometry *geometry, CSolver **solver_container, C } Pressure = V_domain[nDim+1]; SoundSpeed = sqrt(Gamma*Pressure/Density); - + Entropy = Pressure*pow(1.0/Density, Gamma); Riemann = Vn + 2.0*SoundSpeed/Gamma_Minus_One; - + /*--- Compute the new fictious state at the outlet ---*/ - + Pressure = P_static; Density = pow(Pressure/Entropy,1.0/Gamma); SoundSpeed = sqrt(Gamma*Pressure/Density); Vn_Inlet = Riemann - 2.0*SoundSpeed/Gamma_Minus_One; - + Velocity2 = 0.0; for (iDim = 0; iDim < nDim; iDim++) { Velocity[iDim] = Velocity[iDim] + (Vn_Inlet-Vn)*UnitNormal[iDim]; @@ -11426,9 +11423,9 @@ void CEulerSolver::BC_ActDisk(CGeometry *geometry, CSolver **solver_container, C } Energy = Pressure/(Density*Gamma_Minus_One) + 0.5*Velocity2; if (tkeNeeded) Energy += GetTke_Inf(); - + /*--- Conservative variables, using the derived quantities ---*/ - + V_inlet[0] = Pressure / ( Gas_Constant * Density); for (iDim = 0; iDim < nDim; iDim++) V_inlet[iDim+1] = Velocity[iDim]; @@ -11437,24 +11434,24 @@ void CEulerSolver::BC_ActDisk(CGeometry *geometry, CSolver **solver_container, C V_inlet[nDim+3] = Energy + Pressure/Density; V_inlet[nDim+4] = SoundSpeed; conv_numerics->SetPrimitive(V_domain, V_inlet); - + } - + /*--- Subsonic outlet ---*/ - + else { - + FluidModel->SetTDState_PT(P_static, T_static); SoS_outlet = FluidModel->GetSoundSpeed(); Rho_outlet = FluidModel->GetDensity(); - + /*--- We use the velocity and the density from the flow inlet to evaluate flow direction and mass flow ---*/ - + Rho_inlet = V_inlet[nDim+2]; for (iDim = 0; iDim < nDim; iDim++) Vel_inlet[iDim] = V_inlet[iDim+1]; - + Vel_normal_inlet_ = 0.0; Vel_inlet_ = 0.0; for (iDim = 0; iDim < nDim; iDim++) { Vel_normal_inlet[iDim] = -Vel_inlet[iDim]*UnitNormal[iDim]; @@ -11463,19 +11460,19 @@ void CEulerSolver::BC_ActDisk(CGeometry *geometry, CSolver **solver_container, C } Vel_inlet_ = sqrt(Vel_inlet_); Vel_normal_inlet_ = sqrt(Vel_normal_inlet_); - + Vel_tangent_inlet_ = 0.0; for (iDim = 0; iDim < nDim; iDim++) { Vel_tangent_inlet[iDim] = Vel_inlet[iDim] - Vel_normal_inlet[iDim]; Vel_tangent_inlet_ += Vel_tangent_inlet[iDim]*Vel_tangent_inlet[iDim]; } Vel_tangent_inlet_ = sqrt(Vel_tangent_inlet_); - + /*--- Mass flow conservation (normal direction) and no jump in the tangential velocity ---*/ - + Vel_normal_outlet_ = (1.0-SecondaryFlow/100.0)*(Rho_inlet*Vel_normal_inlet_)/Rho_outlet; - + Vel_outlet_ = 0.0; for (iDim = 0; iDim < nDim; iDim++) { Vel_normal_outlet[iDim] = -Vel_normal_outlet_*UnitNormal[iDim]; @@ -11484,27 +11481,27 @@ void CEulerSolver::BC_ActDisk(CGeometry *geometry, CSolver **solver_container, C Vel_outlet_ += Vel_outlet[iDim]*Vel_outlet[iDim]; } Vel_outlet_ = sqrt(Vel_outlet_); - + Mach_Outlet = min(Vel_outlet_/SoS_outlet, 1.0); - + /*--- Reevaluate the Total Pressure and Total Temperature using the Fan Face Mach number and the static values from the jum condition ---*/ - + Factor = 1.0 + 0.5*Mach_Outlet*Mach_Outlet*Gamma_Minus_One; P_Total = P_static * pow(Factor, Gamma/Gamma_Minus_One); T_Total = T_static * Factor; - + /*--- Flow direction using the velocity direction at the outlet ---*/ - + if (Vel_outlet_ != 0.0) { for (iDim = 0; iDim < nDim; iDim++) Flow_Dir[iDim] = Vel_outlet[iDim]/Vel_outlet_; } else { for (iDim = 0; iDim < nDim; iDim++) Flow_Dir[iDim] = 0.0; } - + /*--- Store primitives and set some variables for clarity. ---*/ - + Density = V_domain[nDim+2]; Velocity2 = 0.0; for (iDim = 0; iDim < nDim; iDim++) { @@ -11515,75 +11512,75 @@ void CEulerSolver::BC_ActDisk(CGeometry *geometry, CSolver **solver_container, C Pressure = V_domain[nDim+1]; H_Total = (Gamma*Gas_Constant/Gamma_Minus_One)*T_Total; SoundSpeed2 = Gamma*Pressure/Density; - + /*--- Compute the acoustic Riemann invariant that is extrapolated from the domain interior. ---*/ - + Riemann = 2.0*sqrt(SoundSpeed2)/Gamma_Minus_One; for (iDim = 0; iDim < nDim; iDim++) Riemann += Velocity[iDim]*UnitNormal[iDim]; - + /*--- Total speed of sound ---*/ - + SoundSpeed_Total2 = Gamma_Minus_One*(H_Total - (Energy + Pressure/Density)+0.5*Velocity2) + SoundSpeed2; - + /*--- Dot product of normal and flow direction. This should be negative due to outward facing boundary normal convention. ---*/ - + alpha = 0.0; for (iDim = 0; iDim < nDim; iDim++) alpha += UnitNormal[iDim]*Flow_Dir[iDim]; - + /*--- Coefficients in the quadratic equation for the velocity ---*/ - + aa = 1.0 + 0.5*Gamma_Minus_One*alpha*alpha; bb = -1.0*Gamma_Minus_One*alpha*Riemann; cc = 0.5*Gamma_Minus_One*Riemann*Riemann - 2.0*SoundSpeed_Total2/Gamma_Minus_One; - + /*--- Solve quadratic equation for velocity magnitude. Value must be positive, so the choice of root is clear. ---*/ - + dd = bb*bb - 4.0*aa*cc; dd = sqrt(max(0.0, dd)); Vel_Mag = (-bb + dd)/(2.0*aa); Vel_Mag = max(0.0, Vel_Mag); Velocity2 = Vel_Mag*Vel_Mag; - + /*--- Compute speed of sound from total speed of sound eqn. ---*/ - + SoundSpeed2 = SoundSpeed_Total2 - 0.5*Gamma_Minus_One*Velocity2; - + /*--- Mach squared (cut between 0-1), use to adapt velocity ---*/ - + Mach2 = min(1.0, Velocity2/SoundSpeed2); Velocity2 = Mach2*SoundSpeed2; Vel_Mag = sqrt(Velocity2); SoundSpeed2 = SoundSpeed_Total2 - 0.5*Gamma_Minus_One*Velocity2; - + /*--- Compute new velocity vector at the exit ---*/ - + for (iDim = 0; iDim < nDim; iDim++) Velocity[iDim] = Vel_Mag*Flow_Dir[iDim]; - + /*--- Static temperature from the speed of sound relation ---*/ - + Temperature = SoundSpeed2/(Gamma*Gas_Constant); - + /*--- Static pressure using isentropic relation at a point ---*/ - + Pressure = P_Total*pow((Temperature/T_Total), Gamma/Gamma_Minus_One); - + /*--- Density at the inlet from the gas law ---*/ - + Density = Pressure/(Gas_Constant*Temperature); - + /*--- Using pressure, density, & velocity, compute the energy ---*/ - + Energy = Pressure/(Density*Gamma_Minus_One) + 0.5*Velocity2; if (tkeNeeded) Energy += GetTke_Inf(); - + /*--- Primitive variables, using the derived quantities ---*/ - + V_outlet[0] = Temperature; for (iDim = 0; iDim < nDim; iDim++) V_outlet[iDim+1] = Velocity[iDim]; @@ -11592,26 +11589,26 @@ void CEulerSolver::BC_ActDisk(CGeometry *geometry, CSolver **solver_container, C V_outlet[nDim+3] = Energy + Pressure/Density; V_outlet[nDim+4] = sqrt(SoundSpeed2); conv_numerics->SetPrimitive(V_domain, V_outlet); - + } - + /*--- Grid Movement ---*/ - + if (dynamic_grid) conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); - + /*--- Compute the residual using an upwind scheme ---*/ - + conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - + /*--- Update residual value ---*/ - + LinSysRes.AddBlock(iPoint, Residual); - + /*--- Jacobian contribution for implicit integration ---*/ - + if (implicit) Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - + // /*--- Viscous contribution, commented out because serious convergence problems ---*/ // // if (viscous) { @@ -11658,36 +11655,33 @@ void CEulerSolver::BC_ActDisk(CGeometry *geometry, CSolver **solver_container, C // if (implicit) Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); // // } - + } - + } - + /*--- Free locally allocated memory ---*/ - + delete [] Normal; delete [] Flow_Dir; - + } void CEulerSolver::BC_Periodic(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config) { - + /*--- Complete residuals for periodic boundary conditions. We loop over the periodic BCs in matching pairs so that, in the event that there are adjacent periodic markers, the repeated points will have their residuals accumulated correctly during the communications. For implicit calculations, the Jacobians and linear system are also correctly adjusted here. ---*/ - + for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_RESIDUAL); CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_RESIDUAL); } - -} -void CEulerSolver::BC_Dirichlet(CGeometry *geometry, CSolver **solver_container, - CConfig *config, unsigned short val_marker) { } +} void CEulerSolver::BC_Custom(CGeometry *geometry, CSolver **solver_container, @@ -11695,113 +11689,113 @@ void CEulerSolver::BC_Custom(CGeometry *geometry, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + /* Check for a verification solution. */ - + if (VerificationSolution) { - + unsigned short iVar; unsigned long iVertex, iPoint, total_index; - + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); - + /*--- Get the physical time. ---*/ - + su2double time = 0.0; if (config->GetTime_Marching()) time = config->GetPhysicalTime(); - + /*--- Loop over all the vertices on this boundary marker ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + /*--- Get the point index for the current node. ---*/ - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ - + if (geometry->node[iPoint]->GetDomain()) { - + /*--- Get the coordinates for the current node. ---*/ - + const su2double *coor = geometry->node[iPoint]->GetCoord(); - + /*--- Get the conservative state from the verification solution. ---*/ - + VerificationSolution->GetBCState(coor, time, Solution); - + /*--- For verification cases, we will apply a strong Dirichlet condition by setting the solution values at the boundary nodes directly and setting the residual to zero at those nodes. ---*/ - + nodes->SetSolution_Old(iPoint,Solution); nodes->SetSolution(iPoint,Solution); nodes->SetRes_TruncErrorZero(iPoint); LinSysRes.SetBlock_Zero(iPoint); - + /*--- Adjust rows of the Jacobian (includes 1 in the diagonal) ---*/ - + if (implicit){ for (iVar = 0; iVar < nVar; iVar++) { total_index = iPoint*nVar+iVar; Jacobian.DeleteValsRowi(total_index); } } - + } } - + } else { - + /* The user must specify the custom BC's here. */ SU2_MPI::Error("Implement customized boundary conditions here.", CURRENT_FUNCTION); - + } - + } void CEulerSolver::SetResidual_DualTime(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iRKStep, unsigned short iMesh, unsigned short RunTime_EqSystem) { - + /*--- Local variables ---*/ - + unsigned short iVar, jVar, iMarker, iDim; unsigned long iPoint, jPoint, iEdge, iVertex; - + su2double *U_time_nM1, *U_time_n, *U_time_nP1; su2double Volume_nM1, Volume_nP1, TimeStep; su2double *Normal = NULL, *GridVel_i = NULL, *GridVel_j = NULL, Residual_GCL; - + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); - + /*--- Store the physical time step ---*/ - + TimeStep = config->GetDelta_UnstTimeND(); - + /*--- Compute the dual time-stepping source term for static meshes ---*/ - + if (!dynamic_grid) { - + /*--- Loop over all nodes (excluding halos) ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /*--- Retrieve the solution at time levels n-1, n, and n+1. Note that we are currently iterating on U^n+1 and that U^n & U^n-1 are fixed, previous solutions that are stored in memory. ---*/ - + U_time_nM1 = nodes->GetSolution_time_n1(iPoint); U_time_n = nodes->GetSolution_time_n(iPoint); U_time_nP1 = nodes->GetSolution(iPoint); - + /*--- CV volume at time n+1. As we are on a static mesh, the volume of the CV will remained fixed for all time steps. ---*/ - + Volume_nP1 = geometry->node[iPoint]->GetVolume(); - + /*--- Compute the dual time-stepping source term based on the chosen time discretization scheme (1st- or 2nd-order).---*/ - + for (iVar = 0; iVar < nVar; iVar++) { if (config->GetTime_Marching() == DT_STEPPING_1ST) Residual[iVar] = (U_time_nP1[iVar] - U_time_n[iVar])*Volume_nP1 / TimeStep; @@ -11809,10 +11803,10 @@ void CEulerSolver::SetResidual_DualTime(CGeometry *geometry, CSolver **solver_co Residual[iVar] = ( 3.0*U_time_nP1[iVar] - 4.0*U_time_n[iVar] +1.0*U_time_nM1[iVar])*Volume_nP1 / (2.0*TimeStep); } - + /*--- Store the residual and compute the Jacobian contribution due to the dual time source term. ---*/ - + LinSysRes.AddBlock(iPoint, Residual); if (implicit) { for (iVar = 0; iVar < nVar; iVar++) { @@ -11825,11 +11819,11 @@ void CEulerSolver::SetResidual_DualTime(CGeometry *geometry, CSolver **solver_co Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); } } - + } - + else { - + /*--- For unsteady flows on dynamic meshes (rigidly transforming or dynamically deforming), the Geometric Conservation Law (GCL) should be satisfied in conjunction with the ALE formulation of the governing @@ -11837,101 +11831,101 @@ void CEulerSolver::SetResidual_DualTime(CGeometry *geometry, CSolver **solver_co a uniform free-stream should be preserved through a moving grid. First, we will loop over the edges and boundaries to compute the GCL component of the dual time source term that depends on grid velocities. ---*/ - + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - + /*--- Get indices for nodes i & j plus the face normal ---*/ - + iPoint = geometry->edge[iEdge]->GetNode(0); jPoint = geometry->edge[iEdge]->GetNode(1); Normal = geometry->edge[iEdge]->GetNormal(); - + /*--- Grid velocities stored at nodes i & j ---*/ - + GridVel_i = geometry->node[iPoint]->GetGridVel(); GridVel_j = geometry->node[jPoint]->GetGridVel(); - + /*--- Compute the GCL term by averaging the grid velocities at the edge mid-point and dotting with the face normal. ---*/ - + Residual_GCL = 0.0; for (iDim = 0; iDim < nDim; iDim++) Residual_GCL += 0.5*(GridVel_i[iDim]+GridVel_j[iDim])*Normal[iDim]; - + /*--- Compute the GCL component of the source term for node i ---*/ - + U_time_n = nodes->GetSolution_time_n(iPoint); for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = U_time_n[iVar]*Residual_GCL; LinSysRes.AddBlock(iPoint, Residual); - + /*--- Compute the GCL component of the source term for node j ---*/ - + U_time_n = nodes->GetSolution_time_n(jPoint); for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = U_time_n[iVar]*Residual_GCL; LinSysRes.SubtractBlock(jPoint, Residual); - + } - + /*--- Loop over the boundary edges ---*/ - + for (iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) != INTERNAL_BOUNDARY) && (config->GetMarker_All_KindBC(iMarker) != PERIODIC_BOUNDARY)) { for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { - + /*--- Get the index for node i plus the boundary face normal ---*/ - + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - + /*--- Grid velocities stored at boundary node i ---*/ - + GridVel_i = geometry->node[iPoint]->GetGridVel(); - + /*--- Compute the GCL term by dotting the grid velocity with the face normal. The normal is negated to match the boundary convention. ---*/ - + Residual_GCL = 0.0; for (iDim = 0; iDim < nDim; iDim++) Residual_GCL -= 0.5*(GridVel_i[iDim]+GridVel_i[iDim])*Normal[iDim]; - + /*--- Compute the GCL component of the source term for node i ---*/ - + U_time_n = nodes->GetSolution_time_n(iPoint); for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = U_time_n[iVar]*Residual_GCL; LinSysRes.AddBlock(iPoint, Residual); - + } } } - + /*--- Loop over all nodes (excluding halos) to compute the remainder of the dual time-stepping source term. ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /*--- Retrieve the solution at time levels n-1, n, and n+1. Note that we are currently iterating on U^n+1 and that U^n & U^n-1 are fixed, previous solutions that are stored in memory. ---*/ - + U_time_nM1 = nodes->GetSolution_time_n1(iPoint); U_time_n = nodes->GetSolution_time_n(iPoint); U_time_nP1 = nodes->GetSolution(iPoint); - + /*--- CV volume at time n-1 and n+1. In the case of dynamically deforming grids, the volumes will change. On rigidly transforming grids, the volumes will remain constant. ---*/ - + Volume_nM1 = geometry->node[iPoint]->GetVolume_nM1(); Volume_nP1 = geometry->node[iPoint]->GetVolume(); - + /*--- Compute the dual time-stepping source residual. Due to the introduction of the GCL term above, the remainder of the source residual due to the time discretization has a new form.---*/ - + for (iVar = 0; iVar < nVar; iVar++) { if (config->GetTime_Marching() == DT_STEPPING_1ST) Residual[iVar] = (U_time_nP1[iVar] - U_time_n[iVar])*(Volume_nP1/TimeStep); @@ -11941,7 +11935,7 @@ void CEulerSolver::SetResidual_DualTime(CGeometry *geometry, CSolver **solver_co } /*--- Store the residual and compute the Jacobian contribution due to the dual time source term. ---*/ - + LinSysRes.AddBlock(iPoint, Residual); if (implicit) { for (iVar = 0; iVar < nVar; iVar++) { @@ -11955,7 +11949,7 @@ void CEulerSolver::SetResidual_DualTime(CGeometry *geometry, CSolver **solver_co } } } - + } void CEulerSolver::ComputeVerificationError(CGeometry *geometry, @@ -11969,11 +11963,11 @@ void CEulerSolver::ComputeVerificationError(CGeometry *geometry, and the known solution at each DOF. This is then collected into RMS (L2) and maximum (Linf) global error norms. From these global measures, one can compute the order of accuracy. ---*/ - + bool write_heads = ((((config->GetInnerIter() % (config->GetWrt_Con_Freq()*40)) == 0) && (config->GetInnerIter()!= 0)) || (config->GetInnerIter() == 1)); - if( !write_heads ) return; + if( !write_heads ) return; /*--- Check if there actually is an exact solution for this verification case, if computed at all. ---*/ @@ -11983,24 +11977,24 @@ void CEulerSolver::ComputeVerificationError(CGeometry *geometry, /*--- Get the physical time if necessary. ---*/ su2double time = 0.0; if (config->GetTime_Marching()) time = config->GetPhysicalTime(); - + /*--- Reset the global error measures to zero. ---*/ for (unsigned short iVar = 0; iVar < nVar; iVar++) { VerificationSolution->SetError_RMS(iVar, 0.0); VerificationSolution->SetError_Max(iVar, 0.0, 0); } - + /*--- Loop over all owned points. ---*/ for (unsigned long iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /* Set the pointers to the coordinates and solution of this DOF. */ const su2double *coor = geometry->node[iPoint]->GetCoord(); su2double *solDOF = nodes->GetSolution(iPoint); - + /* Get local error from the verification solution class. */ vector error(nVar,0.0); VerificationSolution->GetLocalError(coor, time, solDOF, error.data()); - + /* Increment the global error measures */ for (unsigned short iVar = 0; iVar < nVar; iVar++) { VerificationSolution->AddError_RMS(iVar, error[iVar]*error[iVar]); @@ -12009,52 +12003,52 @@ void CEulerSolver::ComputeVerificationError(CGeometry *geometry, geometry->node[iPoint]->GetCoord()); } } - + /* Finalize the calculation of the global error measures. */ VerificationSolution->SetVerificationError(geometry->GetGlobal_nPointDomain(), config); - + /*--- Screen output of the error metrics. This can be improved once the new output classes are in place. ---*/ - + if ((rank == MASTER_NODE) && (geometry->GetMGLevel() == MESH_0)) { cout.precision(5); cout.setf(ios::scientific, ios::floatfield); - + if (!config->GetDiscrete_Adjoint()) { - + cout << endl << "------------------------ Global Error Analysis --------------------------" << endl; - + cout << setw(20) << "RMS Error [Rho]: " << setw(12) << VerificationSolution->GetError_RMS(0) << " | "; cout << setw(20) << "Max Error [Rho]: " << setw(12) << VerificationSolution->GetError_Max(0); cout << endl; - + cout << setw(20) << "RMS Error [RhoU]: " << setw(12) << VerificationSolution->GetError_RMS(1) << " | "; cout << setw(20) << "Max Error [RhoU]: " << setw(12) << VerificationSolution->GetError_Max(1); cout << endl; - + cout << setw(20) << "RMS Error [RhoV]: " << setw(12) << VerificationSolution->GetError_RMS(2) << " | "; cout << setw(20) << "Max Error [RhoV]: " << setw(12) << VerificationSolution->GetError_Max(2); cout << endl; - + if (nDim == 3) { cout << setw(20) << "RMS Error [RhoW]: " << setw(12) << VerificationSolution->GetError_RMS(3) << " | "; cout << setw(20) << "Max Error [RhoW]: " << setw(12) << VerificationSolution->GetError_Max(3); cout << endl; } - + cout << setw(20) << "RMS Error [RhoE]: " << setw(12) << VerificationSolution->GetError_RMS(nDim+1) << " | "; cout << setw(20) << "Max Error [RhoE]: " << setw(12) << VerificationSolution->GetError_Max(nDim+1); cout << endl; - + cout << "-------------------------------------------------------------------------" << endl << endl; cout.unsetf(ios_base::floatfield); - + } } } } - + } void CEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo) { @@ -12083,7 +12077,7 @@ void CEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig unsigned short rbuf_NotMatching = 0, sbuf_NotMatching = 0; /*--- Skip coordinates ---*/ - + unsigned short skipVars = geometry[MESH_0]->GetnDim(); /*--- Store the number of variables for the turbulence model @@ -12148,7 +12142,7 @@ void CEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig geometry[MESH_0]->node[iPoint_Local]->SetGridVel(iDim, GridVel[iDim]); } } - + if (static_fsi && val_update_geo) { /*--- Rewind the index to retrieve the Coords. ---*/ index = counter*Restart_Vars[1]; @@ -12186,7 +12180,7 @@ void CEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig solver[MESH_0][FLOW_SOL]->InitiateComms(geometry[MESH_0], config, SOLUTION); solver[MESH_0][FLOW_SOL]->CompleteComms(geometry[MESH_0], config, SOLUTION); - + solver[MESH_0][FLOW_SOL]->Preprocessing(geometry[MESH_0], solver[MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); /*--- Interpolate the solution down to the coarse multigrid levels ---*/ @@ -12205,10 +12199,10 @@ void CEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig } solver[iMesh][FLOW_SOL]->GetNodes()->SetSolution(iPoint,Solution); } - + solver[iMesh][FLOW_SOL]->InitiateComms(geometry[iMesh], config, SOLUTION); solver[iMesh][FLOW_SOL]->CompleteComms(geometry[iMesh], config, SOLUTION); - + solver[iMesh][FLOW_SOL]->Preprocessing(geometry[iMesh], solver[iMesh], config, iMesh, NO_RK_ITER, RUNTIME_FLOW_SYS, false); } @@ -12220,10 +12214,10 @@ void CEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig geometry[MESH_0]->InitiateComms(geometry[MESH_0], config, COORDINATES); geometry[MESH_0]->CompleteComms(geometry[MESH_0], config, COORDINATES); - + geometry[MESH_0]->InitiateComms(geometry[MESH_0], config, GRID_VELOCITY); geometry[MESH_0]->CompleteComms(geometry[MESH_0], config, GRID_VELOCITY); - + /*--- Recompute the edges and dual mesh control volumes in the domain and on the boundaries. ---*/ @@ -12253,7 +12247,7 @@ void CEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig geometry[MESH_0]->InitiateComms(geometry[MESH_0], config, COORDINATES); geometry[MESH_0]->CompleteComms(geometry[MESH_0], config, COORDINATES); - + /*--- Recompute the edges and dual mesh control volumes in the domain and on the boundaries. ---*/ @@ -12273,7 +12267,7 @@ void CEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig geometry[iMesh]->SetMaxLength(config); } } - + /*--- Update the old geometry (coordinates n and n-1) in dual time-stepping strategy. ---*/ if (dual_time && config->GetGrid_Movement() && (config->GetKind_GridMovement() != RIGID_MOTION)) @@ -12463,7 +12457,7 @@ void CEulerSolver::PreprocessAverage(CSolver **solver, CGeometry *geometry, CCon if (config->GetMarker_All_TurbomachineryFlag(iMarker) == marker_flag){ TotalArea = geometry->GetSpanArea(iMarker,iSpan); - AverageTurboNormal = geometry->GetAverageTurboNormal(iMarker,iSpan); + AverageTurboNormal = geometry->GetAverageTurboNormal(iMarker,iSpan); /*--- Compute the averaged value for the boundary of interest for the span of interest ---*/ @@ -12493,7 +12487,7 @@ void CEulerSolver::PreprocessAverage(CSolver **solver, CGeometry *geometry, CCon if (config->GetMarker_All_Turbomachinery(iMarker) == iMarkerTP){ if (config->GetMarker_All_TurbomachineryFlag(iMarker) == marker_flag){ - AverageTurboNormal = geometry->GetAverageTurboNormal(iMarker,nSpanWiseSections); + AverageTurboNormal = geometry->GetAverageTurboNormal(iMarker,nSpanWiseSections); /*--- Compute the averaged value for the boundary of interest for the span of interest ---*/ @@ -12845,7 +12839,7 @@ void CEulerSolver::TurboAverageProcess(CSolver **solver, CGeometry *geometry, CC if (config->GetMarker_All_TurbomachineryFlag(iMarker) == marker_flag){ TotalArea = geometry->GetSpanArea(iMarker,iSpan); - AverageTurboNormal = geometry->GetAverageTurboNormal(iMarker,iSpan); + AverageTurboNormal = geometry->GetAverageTurboNormal(iMarker,iSpan); nVert = geometry->GetnTotVertexSpan(iMarker,iSpan); @@ -13221,7 +13215,7 @@ void CEulerSolver::GatherInOutAverageValues(CConfig *config, CGeometry *geometry //TODO (turbo) implement interpolation so that Inflow and Outflow spanwise section can be different for (iSpan= 0; iSpan < nSpanWiseSections + 1 ; iSpan++) { - + #ifdef HAVE_MPI unsigned short i, n1, n2, n1t,n2t; su2double *TurbPerfIn= NULL,*TurbPerfOut= NULL; @@ -13414,3120 +13408,3 @@ void CEulerSolver::GatherInOutAverageValues(CConfig *config, CGeometry *geometry } } } - -CNSSolver::CNSSolver(void) : CEulerSolver() { - - /*--- Basic array initialization ---*/ - - CD_Visc = NULL; CL_Visc = NULL; CSF_Visc = NULL; CEff_Visc = NULL; - CFx_Visc = NULL; CFy_Visc = NULL; CFz_Visc = NULL; - CMx_Visc = NULL; CMy_Visc = NULL; CMz_Visc = NULL; - CoPx_Visc = NULL; CoPy_Visc = NULL; CoPz_Visc = NULL; - - ForceViscous = NULL; MomentViscous = NULL; CSkinFriction = NULL; - - Buffet_Sensor = NULL; Buffet_Metric = NULL; - - /*--- Surface based array initialization ---*/ - - Surface_CL_Visc = NULL; Surface_CD_Visc = NULL; Surface_CSF_Visc = NULL; Surface_CEff_Visc = NULL; - Surface_CFx_Visc = NULL; Surface_CFy_Visc = NULL; Surface_CFz_Visc = NULL; - Surface_CMx_Visc = NULL; Surface_CMy_Visc = NULL; Surface_CMz_Visc = NULL; - Surface_HF_Visc = NULL; Surface_MaxHF_Visc = NULL; Surface_Buffet_Metric = NULL; - - /*--- Rotorcraft simulation array initialization ---*/ - - CMerit_Visc = NULL; CT_Visc = NULL; CQ_Visc = NULL; - HF_Visc = NULL; MaxHF_Visc = NULL; - - /*--- Inlet Variables ---*/ - Inlet_Ttotal = NULL; - Inlet_Ptotal = NULL; - Inlet_FlowDir = NULL; - - SlidingState = NULL; - SlidingStateNodes = NULL; - - DonorPrimVar = NULL; DonorGlobalIndex = NULL; - - HeatConjugateVar = NULL; - -} - -CNSSolver::CNSSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh) : CEulerSolver() { - - unsigned long iPoint, counter_local = 0, counter_global = 0, iVertex; - unsigned short iVar, iDim, iMarker, nLineLets; - su2double Density, Velocity2, Pressure, Temperature, StaticEnergy; - ifstream restart_file; - unsigned short nZone = geometry->GetnZone(); - bool restart = (config->GetRestart() || config->GetRestart_Flow()); - int Unst_RestartIter = 0; - bool dual_time = ((config->GetTime_Marching() == DT_STEPPING_1ST) || - (config->GetTime_Marching() == DT_STEPPING_2ND)); - bool time_stepping = config->GetTime_Marching() == TIME_STEPPING; - - /* A grid is defined as dynamic if there's rigid grid movement or grid deformation AND the problem is time domain */ - dynamic_grid = config->GetDynamic_Grid(); - - bool roe_turkel = (config->GetKind_Upwind_Flow() == TURKEL); - bool low_mach_prec = config->Low_Mach_Preconditioning(); - - bool adjoint = (config->GetContinuous_Adjoint()) || (config->GetDiscrete_Adjoint()); - string filename_ = "flow"; - - unsigned short direct_diff = config->GetDirectDiff(); - bool rans = (config->GetKind_Turb_Model() != NONE); - - /*--- Store the multigrid level. ---*/ - MGLevel = iMesh; - - /*--- Check for a restart file to evaluate if there is a change in the angle of attack - before computing all the non-dimesional quantities. ---*/ - - if (!(!restart || (iMesh != MESH_0) || nZone > 1) && - (config->GetFixed_CL_Mode() || config->GetFixed_CM_Mode())) { - - /*--- Modify file name for a dual-time unsteady restart ---*/ - - if (dual_time) { - if (adjoint) Unst_RestartIter = SU2_TYPE::Int(config->GetUnst_AdjointIter())-1; - else if (config->GetTime_Marching() == DT_STEPPING_1ST) - Unst_RestartIter = SU2_TYPE::Int(config->GetRestart_Iter())-1; - else Unst_RestartIter = SU2_TYPE::Int(config->GetRestart_Iter())-2; - } - - /*--- Modify file name for a time stepping unsteady restart ---*/ - - if (time_stepping) { - if (adjoint) Unst_RestartIter = SU2_TYPE::Int(config->GetUnst_AdjointIter())-1; - else Unst_RestartIter = SU2_TYPE::Int(config->GetRestart_Iter())-1; - } - - filename_ = config->GetFilename(filename_, ".meta", Unst_RestartIter); - - /*--- Read and store the restart metadata. ---*/ - - Read_SU2_Restart_Metadata(geometry, config, adjoint, filename_); - - } - - /*--- Array initialization ---*/ - - CD_Visc = NULL; CL_Visc = NULL; CSF_Visc = NULL; CEff_Visc = NULL; - CFx_Visc = NULL; CFy_Visc = NULL; CFz_Visc = NULL; - CMx_Visc = NULL; CMy_Visc = NULL; CMz_Visc = NULL; - CoPx_Visc = NULL; CoPy_Visc = NULL; CoPz_Visc = NULL; - - Buffet_Sensor = NULL; Buffet_Metric = NULL; - - Surface_CL_Visc = NULL; Surface_CD_Visc = NULL; Surface_CSF_Visc = NULL; Surface_CEff_Visc = NULL; - Surface_CFx_Visc = NULL; Surface_CFy_Visc = NULL; Surface_CFz_Visc = NULL; - Surface_CMx_Visc = NULL; Surface_CMy_Visc = NULL; Surface_CMz_Visc = NULL; - Surface_HF_Visc = NULL; Surface_MaxHF_Visc = NULL; - - Surface_Buffet_Metric = NULL; - - CMerit_Visc = NULL; CT_Visc = NULL; CQ_Visc = NULL; - MaxHF_Visc = NULL; ForceViscous = NULL; MomentViscous = NULL; - CSkinFriction = NULL; HF_Visc = NULL; - HeatConjugateVar = NULL; - - /*--- Initialize quantities for the average process for internal flow ---*/ - - AverageVelocity = NULL; - AverageTurboVelocity = NULL; - OldAverageTurboVelocity = NULL; - ExtAverageTurboVelocity = NULL; - AverageFlux = NULL; - SpanTotalFlux = NULL; - AveragePressure = NULL; - OldAveragePressure = NULL; - RadialEquilibriumPressure = NULL; - ExtAveragePressure = NULL; - AverageDensity = NULL; - OldAverageDensity = NULL; - ExtAverageDensity = NULL; - AverageNu = NULL; - AverageKine = NULL; - AverageOmega = NULL; - ExtAverageNu = NULL; - ExtAverageKine = NULL; - ExtAverageOmega = NULL; - - - /*--- Initialize primitive quantities for turboperformace ---*/ - - DensityIn = NULL; - PressureIn = NULL; - TurboVelocityIn = NULL; - DensityOut = NULL; - PressureOut = NULL; - TurboVelocityOut = NULL; - - - /*--- Initialize quantities for Giles BC ---*/ - - CkInflow = NULL; - CkOutflow1 = NULL; - CkOutflow2 = NULL; - - - - /*--- Set the gamma value ---*/ - - Gamma = config->GetGamma(); - Gamma_Minus_One = Gamma - 1.0; - - /*--- Define geometry constants in the solver structure - Compressible flow, primitive variables (T, vx, vy, vz, P, rho, h, c, lamMu, EddyMu, ThCond, Cp). - ---*/ - - nDim = geometry->GetnDim(); - - nVar = nDim+2; - nPrimVar = nDim+9; nPrimVarGrad = nDim+4; - nSecondaryVar = 8; nSecondaryVarGrad = 2; - - - /*--- Initialize nVarGrad for deallocation ---*/ - - nVarGrad = nPrimVarGrad; - - nMarker = config->GetnMarker_All(); - nPoint = geometry->GetnPoint(); - nPointDomain = geometry->GetnPointDomain(); - - /*--- Store the number of vertices on each marker for deallocation later ---*/ - - nVertex = new unsigned long[nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) - nVertex[iMarker] = geometry->nVertex[iMarker]; - - /*--- Perform the non-dimensionalization for the flow equations using the - specified reference values. ---*/ - - SetNondimensionalization(config, iMesh); - - /*--- Check if we are executing a verification case. If so, the - VerificationSolution object will be instantiated for a particular - option from the available library of verification solutions. Note - that this is done after SetNondim(), as problem-specific initial - parameters are needed by the solution constructors. ---*/ - - SetVerificationSolution(nDim, nVar, config); - - /*--- Define some auxiliar vector related with the residual ---*/ - - Residual = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = 0.0; - Residual_RMS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_RMS[iVar] = 0.0; - Residual_Max = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_Max[iVar] = 0.0; - Residual_i = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_i[iVar] = 0.0; - Residual_j = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_j[iVar] = 0.0; - Res_Conv = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Conv[iVar] = 0.0; - Res_Visc = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Visc[iVar] = 0.0; - Res_Sour = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Sour[iVar] = 0.0; - - /*--- Define some structures for locating max residuals ---*/ - - Point_Max = new unsigned long[nVar]; for (iVar = 0; iVar < nVar; iVar++) Point_Max[iVar] = 0; - Point_Max_Coord = new su2double*[nVar]; - for (iVar = 0; iVar < nVar; iVar++) { - Point_Max_Coord[iVar] = new su2double[nDim]; - for (iDim = 0; iDim < nDim; iDim++) Point_Max_Coord[iVar][iDim] = 0.0; - } - - /*--- Define some auxiliary vectors related to the solution ---*/ - - Solution = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution[iVar] = 0.0; - Solution_i = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution_i[iVar] = 0.0; - Solution_j = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution_j[iVar] = 0.0; - - /*--- Define some auxiliary vectors related to the geometry ---*/ - - Vector = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = 0.0; - Vector_i = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector_i[iDim] = 0.0; - Vector_j = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector_j[iDim] = 0.0; - - /*--- Define some auxiliary vectors related to the primitive solution ---*/ - - Primitive = new su2double[nPrimVar]; for (iVar = 0; iVar < nPrimVar; iVar++) Primitive[iVar] = 0.0; - Primitive_i = new su2double[nPrimVar]; for (iVar = 0; iVar < nPrimVar; iVar++) Primitive_i[iVar] = 0.0; - Primitive_j = new su2double[nPrimVar]; for (iVar = 0; iVar < nPrimVar; iVar++) Primitive_j[iVar] = 0.0; - - /*--- Define some auxiliary vectors related to the Secondary solution ---*/ - - Secondary = new su2double[nSecondaryVar]; for (iVar = 0; iVar < nSecondaryVar; iVar++) Secondary[iVar] = 0.0; - Secondary_i = new su2double[nSecondaryVar]; for (iVar = 0; iVar < nSecondaryVar; iVar++) Secondary_i[iVar] = 0.0; - Secondary_j = new su2double[nSecondaryVar]; for (iVar = 0; iVar < nSecondaryVar; iVar++) Secondary_j[iVar] = 0.0; - - /*--- Define some auxiliar vector related with the undivided lapalacian computation ---*/ - - if (config->GetKind_ConvNumScheme_Flow() == SPACE_CENTERED) { - iPoint_UndLapl = new su2double [nPoint]; - jPoint_UndLapl = new su2double [nPoint]; - } - - /*--- Define some auxiliary vectors related to low-speed preconditioning ---*/ - - if (roe_turkel || low_mach_prec) { - LowMach_Precontioner = new su2double* [nVar]; - for (iVar = 0; iVar < nVar; iVar ++) - LowMach_Precontioner[iVar] = new su2double[nVar]; - } - - /*--- Initialize the solution and right hand side vectors for storing - the residuals and updating the solution (always needed even for - explicit schemes). ---*/ - - LinSysSol.Initialize(nPoint, nPointDomain, nVar, 0.0); - LinSysRes.Initialize(nPoint, nPointDomain, nVar, 0.0); - - /*--- Jacobians and vector structures for implicit computations ---*/ - - if (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT) { - - Jacobian_i = new su2double* [nVar]; - Jacobian_j = new su2double* [nVar]; - for (iVar = 0; iVar < nVar; iVar++) { - Jacobian_i[iVar] = new su2double [nVar]; - Jacobian_j[iVar] = new su2double [nVar]; - } - - if (rank == MASTER_NODE) cout << "Initialize Jacobian structure (Navier-Stokes). MG level: " << iMesh <<"." << endl; - Jacobian.Initialize(nPoint, nPointDomain, nVar, nVar, true, geometry, config); - - if (config->GetKind_Linear_Solver_Prec() == LINELET) { - nLineLets = Jacobian.BuildLineletPreconditioner(geometry, config); - if (rank == MASTER_NODE) cout << "Compute linelet structure. " << nLineLets << " elements in each line (average)." << endl; - } - - } - - else { - if (rank == MASTER_NODE) - cout << "Explicit scheme. No Jacobian structure (Navier-Stokes). MG level: " << iMesh <<"." << endl; - } - - /*--- Define some auxiliary vectors for computing flow variable - gradients by least squares, S matrix := inv(R)*traspose(inv(R)), - c vector := transpose(WA)*(Wb) ---*/ - - if (config->GetLeastSquaresRequired()) { - Smatrix = new su2double* [nDim]; - for (iDim = 0; iDim < nDim; iDim++) - Smatrix[iDim] = new su2double [nDim]; - - Cvector = new su2double* [nPrimVarGrad]; - for (iVar = 0; iVar < nPrimVarGrad; iVar++) - Cvector[iVar] = new su2double [nDim]; - } - - /*--- Store the value of the characteristic primitive variables at the boundaries ---*/ - - CharacPrimVar = new su2double** [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - CharacPrimVar[iMarker] = new su2double* [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - CharacPrimVar[iMarker][iVertex] = new su2double [nPrimVar]; - for (iVar = 0; iVar < nPrimVar; iVar++) { - CharacPrimVar[iMarker][iVertex][iVar] = 0.0; - } - } - } - - /*--- Store the value of the primitive variables + 2 turb variables at the boundaries, - used for IO with a donor cell ---*/ - - DonorPrimVar = new su2double** [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - DonorPrimVar[iMarker] = new su2double* [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - if (rans) { - DonorPrimVar[iMarker][iVertex] = new su2double [nPrimVar+2]; - for (iVar = 0; iVar < nPrimVar + 2 ; iVar++) { - DonorPrimVar[iMarker][iVertex][iVar] = 0.0; - } - } - else { - DonorPrimVar[iMarker][iVertex] = new su2double [nPrimVar]; - for (iVar = 0; iVar < nPrimVar ; iVar++) { - DonorPrimVar[iMarker][iVertex][iVar] = 0.0; - } - } - } - } - - /*--- Store the value of the characteristic primitive variables index at the boundaries ---*/ - - DonorGlobalIndex = new unsigned long* [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - DonorGlobalIndex[iMarker] = new unsigned long [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - DonorGlobalIndex[iMarker][iVertex] = 0; - } - } - - /*--- Store the values of the temperature and the heat flux density at the boundaries, - used for coupling with a solid donor cell ---*/ - unsigned short nHeatConjugateVar = 4; - - HeatConjugateVar = new su2double** [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - HeatConjugateVar[iMarker] = new su2double* [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - - HeatConjugateVar[iMarker][iVertex] = new su2double [nHeatConjugateVar]; - for (iVar = 1; iVar < nHeatConjugateVar ; iVar++) { - HeatConjugateVar[iMarker][iVertex][iVar] = 0.0; - } - HeatConjugateVar[iMarker][iVertex][0] = config->GetTemperature_FreeStreamND(); - } - } - - /*--- Store the value of the Delta P at the Actuator Disk ---*/ - - ActDisk_DeltaP = new su2double* [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - ActDisk_DeltaP[iMarker] = new su2double [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - ActDisk_DeltaP[iMarker][iVertex] = 0; - } - } - - /*--- Store the value of the Delta T at the Actuator Disk ---*/ - - ActDisk_DeltaT = new su2double* [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - ActDisk_DeltaT[iMarker] = new su2double [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - ActDisk_DeltaT[iMarker][iVertex] = 0; - } - } - - /*--- Store the value of the Total Pressure at the inlet BC ---*/ - - Inlet_Ttotal = new su2double* [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - Inlet_Ttotal[iMarker] = new su2double [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - Inlet_Ttotal[iMarker][iVertex] = 0; - } - } - - /*--- Store the value of the Total Temperature at the inlet BC ---*/ - - Inlet_Ptotal = new su2double* [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - Inlet_Ptotal[iMarker] = new su2double [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - Inlet_Ptotal[iMarker][iVertex] = 0; - } - } - - /*--- Store the value of the Flow direction at the inlet BC ---*/ - - Inlet_FlowDir = new su2double** [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - Inlet_FlowDir[iMarker] = new su2double* [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - Inlet_FlowDir[iMarker][iVertex] = new su2double [nDim]; - for (iDim = 0; iDim < nDim; iDim++) { - Inlet_FlowDir[iMarker][iVertex][iDim] = 0; - } - } - } - - /*--- Inviscid force definition and coefficient in all the markers ---*/ - - CPressure = new su2double* [nMarker]; - CPressureTarget = new su2double* [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - CPressure[iMarker] = new su2double [geometry->nVertex[iMarker]]; - CPressureTarget[iMarker] = new su2double [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - CPressure[iMarker][iVertex] = 0.0; - CPressureTarget[iMarker][iVertex] = 0.0; - } - } - - /*--- Heat flux in all the markers ---*/ - - HeatFlux = new su2double* [nMarker]; - HeatFluxTarget = new su2double* [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - HeatFlux[iMarker] = new su2double [geometry->nVertex[iMarker]]; - HeatFluxTarget[iMarker] = new su2double [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - HeatFlux[iMarker][iVertex] = 0.0; - HeatFluxTarget[iMarker][iVertex] = 0.0; - } - } - - /*--- Y plus in all the markers ---*/ - - YPlus = new su2double* [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - YPlus[iMarker] = new su2double [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - YPlus[iMarker][iVertex] = 0.0; - } - } - - /*--- Skin friction in all the markers ---*/ - - CSkinFriction = new su2double** [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - CSkinFriction[iMarker] = new su2double*[nDim]; - for (iDim = 0; iDim < nDim; iDim++) { - CSkinFriction[iMarker][iDim] = new su2double[geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - CSkinFriction[iMarker][iDim][iVertex] = 0.0; - } - } - } - - /*--- Buffet sensor in all the markers ---*/ - - if(config->GetBuffet_Monitoring() || config->GetKind_ObjFunc() == BUFFET_SENSOR){ - - Buffet_Sensor = new su2double*[nMarker]; - for(iMarker = 0; iMarker < nMarker; iMarker++) { - Buffet_Sensor[iMarker] = new su2double[geometry->nVertex[iMarker]]; - } - - } - - /*--- Non dimensional coefficients ---*/ - - ForceInviscid = new su2double[3]; - MomentInviscid = new su2double[3]; - CD_Inv = new su2double[nMarker]; - CL_Inv = new su2double[nMarker]; - CSF_Inv = new su2double[nMarker]; - CEff_Inv = new su2double[nMarker]; - CFx_Inv = new su2double[nMarker]; - CFy_Inv = new su2double[nMarker]; - CFz_Inv = new su2double[nMarker]; - CMx_Inv = new su2double[nMarker]; - CMy_Inv = new su2double[nMarker]; - CMz_Inv = new su2double[nMarker]; - CoPx_Inv = new su2double[nMarker]; - CoPy_Inv = new su2double[nMarker]; - CoPz_Inv = new su2double[nMarker]; - - ForceMomentum = new su2double[3]; - MomentMomentum = new su2double[3]; - CD_Mnt = new su2double[nMarker]; - CL_Mnt = new su2double[nMarker]; - CSF_Mnt = new su2double[nMarker]; - CEff_Mnt = new su2double[nMarker]; - CFx_Mnt = new su2double[nMarker]; - CFy_Mnt = new su2double[nMarker]; - CFz_Mnt = new su2double[nMarker]; - CMx_Mnt = new su2double[nMarker]; - CMy_Mnt = new su2double[nMarker]; - CMz_Mnt = new su2double[nMarker]; - CoPx_Mnt = new su2double[nMarker]; - CoPy_Mnt = new su2double[nMarker]; - CoPz_Mnt = new su2double[nMarker]; - - ForceViscous = new su2double[3]; - MomentViscous = new su2double[3]; - CD_Visc = new su2double[nMarker]; - CL_Visc = new su2double[nMarker]; - CSF_Visc = new su2double[nMarker]; - CEff_Visc = new su2double[nMarker]; - CFx_Visc = new su2double[nMarker]; - CFy_Visc = new su2double[nMarker]; - CFz_Visc = new su2double[nMarker]; - CMx_Visc = new su2double[nMarker]; - CMy_Visc = new su2double[nMarker]; - CMz_Visc = new su2double[nMarker]; - CoPx_Visc = new su2double[nMarker]; - CoPy_Visc = new su2double[nMarker]; - CoPz_Visc = new su2double[nMarker]; - - Surface_CL_Inv = new su2double[config->GetnMarker_Monitoring()]; - Surface_CD_Inv = new su2double[config->GetnMarker_Monitoring()]; - Surface_CSF_Inv = new su2double[config->GetnMarker_Monitoring()]; - Surface_CEff_Inv = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFx_Inv = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFy_Inv = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFz_Inv = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMx_Inv = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMy_Inv = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMz_Inv = new su2double[config->GetnMarker_Monitoring()]; - - Surface_CL_Mnt = new su2double[config->GetnMarker_Monitoring()]; - Surface_CD_Mnt = new su2double[config->GetnMarker_Monitoring()]; - Surface_CSF_Mnt = new su2double[config->GetnMarker_Monitoring()]; - Surface_CEff_Mnt = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFx_Mnt = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFy_Mnt = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFz_Mnt = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMx_Mnt = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMy_Mnt = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMz_Mnt = new su2double[config->GetnMarker_Monitoring()]; - - Surface_CL = new su2double[config->GetnMarker_Monitoring()]; - Surface_CD = new su2double[config->GetnMarker_Monitoring()]; - Surface_CSF = new su2double[config->GetnMarker_Monitoring()]; - Surface_CEff = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFx = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFy = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFz = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMx = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMy = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMz = new su2double[config->GetnMarker_Monitoring()]; - - Surface_CL_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CD_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CSF_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CEff_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFx_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFy_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFz_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMx_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMy_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMz_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_HF_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_MaxHF_Visc = new su2double[config->GetnMarker_Monitoring()]; - - if(config->GetBuffet_Monitoring() || config->GetKind_ObjFunc() == BUFFET_SENSOR){ - - Buffet_Metric = new su2double[nMarker]; - Surface_Buffet_Metric = new su2double[config->GetnMarker_Monitoring()]; - - } - - - /*--- Rotational coefficients ---*/ - - CMerit_Inv = new su2double[nMarker]; - CT_Inv = new su2double[nMarker]; - CQ_Inv = new su2double[nMarker]; - - CMerit_Mnt = new su2double[nMarker]; - CT_Mnt = new su2double[nMarker]; - CQ_Mnt = new su2double[nMarker]; - - CMerit_Visc = new su2double[nMarker]; - CT_Visc = new su2double[nMarker]; - CQ_Visc = new su2double[nMarker]; - - /*--- Heat based coefficients ---*/ - - HF_Visc = new su2double[nMarker]; - MaxHF_Visc = new su2double[nMarker]; - - /*--- Supersonic coefficients ---*/ - - CEquivArea_Inv = new su2double[nMarker]; - CNearFieldOF_Inv = new su2double[nMarker]; - - /*--- Engine simulation ---*/ - - Inflow_MassFlow = new su2double[nMarker]; - Inflow_Pressure = new su2double[nMarker]; - Inflow_Mach = new su2double[nMarker]; - Inflow_Area = new su2double[nMarker]; - - Exhaust_MassFlow = new su2double[nMarker]; - Exhaust_Pressure = new su2double[nMarker]; - Exhaust_Temperature = new su2double[nMarker]; - Exhaust_Area = new su2double[nMarker]; - - /*--- Init total coefficients ---*/ - - Total_CD = 0.0; Total_CL = 0.0; Total_CSF = 0.0; - Total_CMx = 0.0; Total_CMy = 0.0; Total_CMz = 0.0; - Total_CoPx = 0.0; Total_CoPy = 0.0; Total_CoPz = 0.0; - Total_CEff = 0.0; Total_CEquivArea = 0.0; Total_CNearFieldOF = 0.0; - Total_CFx = 0.0; Total_CFy = 0.0; Total_CFz = 0.0; - Total_CT = 0.0; Total_CQ = 0.0; Total_CMerit = 0.0; - Total_MaxHeat = 0.0; Total_Heat = 0.0; Total_ComboObj = 0.0; - Total_CpDiff = 0.0; Total_HeatFluxDiff = 0.0; - Total_NetThrust = 0.0; Total_Power = 0.0; - Total_CL_Prev = 0.0; Total_CD_Prev = 0.0; Total_CMx_Prev = 0.0; - Total_CMy_Prev = 0.0; Total_CMz_Prev = 0.0; - Total_AeroCD = 0.0; Total_SolidCD = 0.0; Total_IDR = 0.0; - Total_IDC = 0.0; - Total_Custom_ObjFunc = 0.0; - - /*--- Read farfield conditions from config ---*/ - - Density_Inf = config->GetDensity_FreeStreamND(); - Pressure_Inf = config->GetPressure_FreeStreamND(); - Velocity_Inf = config->GetVelocity_FreeStreamND(); - Energy_Inf = config->GetEnergy_FreeStreamND(); - Temperature_Inf = config->GetTemperature_FreeStreamND(); - Viscosity_Inf = config->GetViscosity_FreeStreamND(); - Mach_Inf = config->GetMach(); - Prandtl_Lam = config->GetPrandtl_Lam(); - Prandtl_Turb = config->GetPrandtl_Turb(); - Tke_Inf = config->GetTke_FreeStreamND(); - - /*--- Initialize the secondary values for direct derivative approxiations ---*/ - - switch(direct_diff) { - case NO_DERIVATIVE: - break; - case D_DENSITY: - SU2_TYPE::SetDerivative(Density_Inf, 1.0); - break; - case D_PRESSURE: - SU2_TYPE::SetDerivative(Pressure_Inf, 1.0); - break; - case D_TEMPERATURE: - SU2_TYPE::SetDerivative(Temperature_Inf, 1.0); - break; - case D_VISCOSITY: - SU2_TYPE::SetDerivative(Viscosity_Inf, 1.0); - break; - case D_MACH: case D_AOA: - case D_SIDESLIP: case D_REYNOLDS: - case D_TURB2LAM: case D_DESIGN: - /*--- Already done in postprocessing of config ---*/ - break; - default: - break; - } - - /*--- Initialize fan face pressure, fan face mach number, and mass flow rate ---*/ - - for (iMarker = 0; iMarker < nMarker; iMarker++) { - Inflow_MassFlow[iMarker] = 0.0; - Inflow_Mach[iMarker] = Mach_Inf; - Inflow_Pressure[iMarker] = Pressure_Inf; - Inflow_Area[iMarker] = 0.0; - - Exhaust_MassFlow[iMarker] = 0.0; - Exhaust_Temperature[iMarker] = Temperature_Inf; - Exhaust_Pressure[iMarker] = Pressure_Inf; - Exhaust_Area[iMarker] = 0.0; - - } - /*--- Initializate quantities for SlidingMesh Interface ---*/ - - SlidingState = new su2double*** [nMarker]; - SlidingStateNodes = new int* [nMarker]; - - for (iMarker = 0; iMarker < nMarker; iMarker++){ - - SlidingState[iMarker] = NULL; - SlidingStateNodes[iMarker] = NULL; - - if (config->GetMarker_All_KindBC(iMarker) == FLUID_INTERFACE){ - - SlidingState[iMarker] = new su2double**[geometry->GetnVertex(iMarker)]; - SlidingStateNodes[iMarker] = new int [geometry->GetnVertex(iMarker)]; - - for (iPoint = 0; iPoint < geometry->GetnVertex(iMarker); iPoint++){ - SlidingState[iMarker][iPoint] = new su2double*[nPrimVar+1]; - - SlidingStateNodes[iMarker][iPoint] = 0; - for (iVar = 0; iVar < nPrimVar+1; iVar++) - SlidingState[iMarker][iPoint][iVar] = NULL; - } - - } - } - - /*--- Only initialize when there is a Marker_Fluid_Load - *--- (this avoids overhead in all other cases while a more permanent structure is being developed) ---*/ - if((config->GetnMarker_Fluid_Load() > 0) && (MGLevel == MESH_0)){ - - InitVertexTractionContainer(geometry, config); - - if (config->GetDiscrete_Adjoint()) - InitVertexTractionAdjointContainer(geometry, config); - - } - - /*--- Initialize the solution to the far-field state everywhere. ---*/ - - nodes = new CNSVariable(Density_Inf, Velocity_Inf, Energy_Inf, nPoint, nDim, nVar, config); - SetBaseClassPointerToNodes(); - - /*--- Check that the initial solution is physical, report any non-physical nodes ---*/ - - counter_local = 0; - - for (iPoint = 0; iPoint < nPoint; iPoint++) { - - Density = nodes->GetDensity(iPoint); - - Velocity2 = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - Velocity2 += pow(nodes->GetSolution(iPoint,iDim+1)/Density,2); - - StaticEnergy= nodes->GetEnergy(iPoint) - 0.5*Velocity2; - - FluidModel->SetTDState_rhoe(Density, StaticEnergy); - Pressure= FluidModel->GetPressure(); - Temperature= FluidModel->GetTemperature(); - - /*--- Use the values at the infinity ---*/ - - if ((Pressure < 0.0) || (Density < 0.0) || (Temperature < 0.0)) { - Solution[0] = Density_Inf; - for (iDim = 0; iDim < nDim; iDim++) - Solution[iDim+1] = Velocity_Inf[iDim]*Density_Inf; - Solution[nDim+1] = Energy_Inf*Density_Inf; - nodes->SetSolution(iPoint,Solution); - nodes->SetSolution_Old(iPoint,Solution); - counter_local++; - } - - } - - /*--- Warning message about non-physical points ---*/ - - if (config->GetComm_Level() == COMM_FULL) { -#ifdef HAVE_MPI - SU2_MPI::Reduce(&counter_local, &counter_global, 1, MPI_UNSIGNED_LONG, MPI_SUM, MASTER_NODE, MPI_COMM_WORLD); -#else - counter_global = counter_local; -#endif - if ((rank == MASTER_NODE) && (counter_global != 0)) - cout << "Warning. The original solution contains "<< counter_global << " points that are not physical." << endl; - } - - /*--- Initialize the BGS residuals in FSI problems. ---*/ - if (config->GetMultizone_Residual()){ - Residual_BGS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_BGS[iVar] = 1.0; - Residual_Max_BGS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_Max_BGS[iVar] = 1.0; - - /*--- Define some structures for locating max residuals ---*/ - - Point_Max_BGS = new unsigned long[nVar]; for (iVar = 0; iVar < nVar; iVar++) Point_Max_BGS[iVar] = 0; - Point_Max_Coord_BGS = new su2double*[nVar]; - for (iVar = 0; iVar < nVar; iVar++) { - Point_Max_Coord_BGS[iVar] = new su2double[nDim]; - for (iDim = 0; iDim < nDim; iDim++) Point_Max_Coord_BGS[iVar][iDim] = 0.0; - } - } - - /*--- Define solver parameters needed for execution of destructor ---*/ - - if (config->GetKind_ConvNumScheme_Flow() == SPACE_CENTERED) space_centered = true; - else space_centered = false; - - if (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT) euler_implicit = true; - else euler_implicit = false; - - if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) least_squares = true; - else least_squares = false; - - /*--- Communicate and store volume and the number of neighbors for - any dual CVs that lie on on periodic markers. ---*/ - - for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { - InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_VOLUME); - CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_VOLUME); - InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_NEIGHBORS); - CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_NEIGHBORS); - } - SetImplicitPeriodic(euler_implicit); - if (iMesh == MESH_0) SetRotatePeriodic(true); - - /*--- Perform the MPI communication of the solution ---*/ - - InitiateComms(geometry, config, SOLUTION); - CompleteComms(geometry, config, SOLUTION); - - /* Store the initial CFL number for all grid points. */ - - const su2double CFL = config->GetCFL(MGLevel); - for (iPoint = 0; iPoint < nPoint; iPoint++) { - nodes->SetLocalCFL(iPoint, CFL); - } - Min_CFL_Local = CFL; - Max_CFL_Local = CFL; - Avg_CFL_Local = CFL; - - /*--- Add the solver name (max 8 characters) ---*/ - SolverName = "C.FLOW"; - -} - -CNSSolver::~CNSSolver(void) { - - unsigned short iMarker, iDim; - - unsigned long iVertex; - - if (CD_Visc != NULL) delete [] CD_Visc; - if (CL_Visc != NULL) delete [] CL_Visc; - if (CSF_Visc != NULL) delete [] CSF_Visc; - if (CFx_Visc != NULL) delete [] CFx_Visc; - if (CFy_Visc != NULL) delete [] CFy_Visc; - if (CFz_Visc != NULL) delete [] CFz_Visc; - if (CMx_Visc != NULL) delete [] CMx_Visc; - if (CMy_Visc != NULL) delete [] CMy_Visc; - if (CMz_Visc != NULL) delete [] CMz_Visc; - if (CoPx_Visc != NULL) delete [] CoPx_Visc; - if (CoPy_Visc != NULL) delete [] CoPy_Visc; - if (CoPz_Visc != NULL) delete [] CoPz_Visc; - if (CEff_Visc != NULL) delete [] CEff_Visc; - if (CMerit_Visc != NULL) delete [] CMerit_Visc; - if (Buffet_Metric != NULL) delete [] Buffet_Metric; - if (CT_Visc != NULL) delete [] CT_Visc; - if (CQ_Visc != NULL) delete [] CQ_Visc; - if (HF_Visc != NULL) delete [] HF_Visc; - if (MaxHF_Visc != NULL) delete [] MaxHF_Visc; - if (ForceViscous != NULL) delete [] ForceViscous; - if (MomentViscous != NULL) delete [] MomentViscous; - - if (Surface_CL_Visc != NULL) delete [] Surface_CL_Visc; - if (Surface_CD_Visc != NULL) delete [] Surface_CD_Visc; - if (Surface_CSF_Visc != NULL) delete [] Surface_CSF_Visc; - if (Surface_CEff_Visc != NULL) delete [] Surface_CEff_Visc; - if (Surface_CFx_Visc != NULL) delete [] Surface_CFx_Visc; - if (Surface_CFy_Visc != NULL) delete [] Surface_CFy_Visc; - if (Surface_CFz_Visc != NULL) delete [] Surface_CFz_Visc; - if (Surface_CMx_Visc != NULL) delete [] Surface_CMx_Visc; - if (Surface_CMy_Visc != NULL) delete [] Surface_CMy_Visc; - if (Surface_CMz_Visc != NULL) delete [] Surface_CMz_Visc; - if (Surface_HF_Visc != NULL) delete [] Surface_HF_Visc; - if (Surface_MaxHF_Visc != NULL) delete [] Surface_MaxHF_Visc; - if (Surface_Buffet_Metric != NULL) delete [] Surface_Buffet_Metric; - - if (CSkinFriction != NULL) { - for (iMarker = 0; iMarker < nMarker; iMarker++) { - for (iDim = 0; iDim < nDim; iDim++) { - delete [] CSkinFriction[iMarker][iDim]; - } - delete [] CSkinFriction[iMarker]; - } - delete [] CSkinFriction; - } - - if (HeatConjugateVar != NULL) { - for (iMarker = 0; iMarker < nMarker; iMarker++) { - for (iVertex = 0; iVertex < nVertex[iMarker]; iVertex++) { - delete [] HeatConjugateVar[iMarker][iVertex]; - } - delete [] HeatConjugateVar[iMarker]; - } - delete [] HeatConjugateVar; - } - - if (Buffet_Sensor != NULL) { - for (iMarker = 0; iMarker < nMarker; iMarker++){ - delete [] Buffet_Sensor[iMarker]; - } - delete [] Buffet_Sensor; - } - -} - -void CNSSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output) { - - unsigned long iPoint, ErrorCounter = 0; - su2double StrainMag = 0.0, Omega = 0.0, *Vorticity; - - unsigned long InnerIter = config->GetInnerIter(); - bool cont_adjoint = config->GetContinuous_Adjoint(); - bool disc_adjoint = config->GetDiscrete_Adjoint(); - bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); - bool center = (config->GetKind_ConvNumScheme_Flow() == SPACE_CENTERED) || (cont_adjoint && config->GetKind_ConvNumScheme_AdjFlow() == SPACE_CENTERED); - bool center_jst = center && config->GetKind_Centered_Flow() == JST; - bool limiter_flow = (config->GetKind_SlopeLimit_Flow() != NO_LIMITER) && (InnerIter <= config->GetLimiterIter()); - bool limiter_turb = (config->GetKind_SlopeLimit_Turb() != NO_LIMITER) && (InnerIter <= config->GetLimiterIter()); - bool limiter_adjflow = (cont_adjoint && (config->GetKind_SlopeLimit_AdjFlow() != NO_LIMITER) && (InnerIter <= config->GetLimiterIter())); - bool fixed_cl = config->GetFixed_CL_Mode(); - bool engine = ((config->GetnMarker_EngineInflow() != 0) || (config->GetnMarker_EngineExhaust() != 0)); - bool actuator_disk = ((config->GetnMarker_ActDiskInlet() != 0) || (config->GetnMarker_ActDiskOutlet() != 0)); - bool nearfield = (config->GetnMarker_NearFieldBound() != 0); - bool van_albada = config->GetKind_SlopeLimit_Flow() == VAN_ALBADA_EDGE; - unsigned short kind_row_dissipation = config->GetKind_RoeLowDiss(); - bool roe_low_dissipation = (kind_row_dissipation != NO_ROELOWDISS) && - (config->GetKind_Upwind_Flow() == ROE || - config->GetKind_Upwind_Flow() == SLAU || - config->GetKind_Upwind_Flow() == SLAU2); - bool wall_functions = config->GetWall_Functions(); - - /*--- Update the angle of attack at the far-field for fixed CL calculations (only direct problem). ---*/ - - if ((fixed_cl) && (!disc_adjoint) && (!cont_adjoint)) { SetFarfield_AoA(geometry, solver_container, config, iMesh, Output); } - - /*--- Set the primitive variables ---*/ - - ErrorCounter = SetPrimitive_Variables(solver_container, config, Output); - - /*--- Compute the engine properties ---*/ - - if (engine) { GetPower_Properties(geometry, config, iMesh, Output); } - - /*--- Compute the actuator disk properties and distortion levels ---*/ - - if (actuator_disk) { - Set_MPI_ActDisk(solver_container, geometry, config); - SetActDisk_BCThrust(geometry, solver_container, config, iMesh, Output); - } - - /*--- Compute NearField MPI ---*/ - - if (nearfield) { Set_MPI_Nearfield(geometry, config); } - - /*--- Artificial dissipation ---*/ - - if (center && !Output) { - SetMax_Eigenvalue(geometry, config); - if ((center_jst) && (iMesh == MESH_0)) { - SetCentered_Dissipation_Sensor(geometry, config); - SetUndivided_Laplacian(geometry, config); - } - } - - /*--- Roe Low Dissipation Sensor ---*/ - - if (roe_low_dissipation){ - SetRoe_Dissipation(geometry, config); - if (kind_row_dissipation == FD_DUCROS || kind_row_dissipation == NTS_DUCROS){ - SetUpwind_Ducros_Sensor(geometry, config); - } - } - - /*--- Compute gradient for MUSCL reconstruction. ---*/ - - if (config->GetReconstructionGradientRequired() && (iMesh == MESH_0)) { - if (config->GetKind_Gradient_Method_Recon() == GREEN_GAUSS) - SetPrimitive_Gradient_GG(geometry, config, true); - if (config->GetKind_Gradient_Method_Recon() == LEAST_SQUARES) - SetPrimitive_Gradient_LS(geometry, config, true); - if (config->GetKind_Gradient_Method_Recon() == WEIGHTED_LEAST_SQUARES) - SetPrimitive_Gradient_LS(geometry, config, true); - } - - /*--- Compute gradient of the primitive variables ---*/ - - if (config->GetKind_Gradient_Method() == GREEN_GAUSS) { - SetPrimitive_Gradient_GG(geometry, config); - } - if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) { - SetPrimitive_Gradient_LS(geometry, config); - } - - /*--- Compute the limiter in case we need it in the turbulence model - or to limit the viscous terms (check this logic with JST and 2nd order turbulence model) ---*/ - - if ((iMesh == MESH_0) && (limiter_flow || limiter_turb || limiter_adjflow) - && !Output && !van_albada) { SetPrimitive_Limiter(geometry, config); } - - /*--- Evaluate the vorticity and strain rate magnitude ---*/ - - solver_container[FLOW_SOL]->GetNodes()->SetVorticity_StrainMag(); - - StrainMag_Max = 0.0; Omega_Max = 0.0; - for (iPoint = 0; iPoint < nPoint; iPoint++) { - - StrainMag = solver_container[FLOW_SOL]->GetNodes()->GetStrainMag(iPoint); - Vorticity = solver_container[FLOW_SOL]->GetNodes()->GetVorticity(iPoint); - Omega = sqrt(Vorticity[0]*Vorticity[0]+ Vorticity[1]*Vorticity[1]+ Vorticity[2]*Vorticity[2]); - - StrainMag_Max = max(StrainMag_Max, StrainMag); - Omega_Max = max(Omega_Max, Omega); - - } - - /*--- Compute the TauWall from the wall functions ---*/ - - if (wall_functions) - SetTauWall_WF(geometry, solver_container, config); - - /*--- Initialize the Jacobian matrices ---*/ - - if (implicit && !config->GetDiscrete_Adjoint()) Jacobian.SetValZero(); - - /*--- Error message ---*/ - - if (config->GetComm_Level() == COMM_FULL) { - -#ifdef HAVE_MPI - unsigned long MyErrorCounter = ErrorCounter; ErrorCounter = 0; - su2double MyOmega_Max = Omega_Max; Omega_Max = 0.0; - su2double MyStrainMag_Max = StrainMag_Max; StrainMag_Max = 0.0; - - SU2_MPI::Allreduce(&MyErrorCounter, &ErrorCounter, 1, MPI_UNSIGNED_LONG, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyStrainMag_Max, &StrainMag_Max, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyOmega_Max, &Omega_Max, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); -#endif - - if (iMesh == MESH_0) { - config->SetNonphysical_Points(ErrorCounter); - solver_container[FLOW_SOL]->SetStrainMag_Max(StrainMag_Max); - solver_container[FLOW_SOL]->SetOmega_Max(Omega_Max); - } - - } - -} - -unsigned long CNSSolver::SetPrimitive_Variables(CSolver **solver_container, CConfig *config, bool Output) { - - unsigned long iPoint, nonPhysicalPoints = 0; - su2double eddy_visc = 0.0, turb_ke = 0.0, DES_LengthScale = 0.0; - unsigned short turb_model = config->GetKind_Turb_Model(); - bool physical = true; - - bool tkeNeeded = ((turb_model == SST) || (turb_model == SST_SUST)) ; - - for (iPoint = 0; iPoint < nPoint; iPoint ++) { - - /*--- Retrieve the value of the kinetic energy (if need it) ---*/ - - if (turb_model != NONE) { - eddy_visc = solver_container[TURB_SOL]->GetNodes()->GetmuT(iPoint); - if (tkeNeeded) turb_ke = solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0); - - if (config->GetKind_HybridRANSLES() != NO_HYBRIDRANSLES){ - DES_LengthScale = solver_container[TURB_SOL]->GetNodes()->GetDES_LengthScale(iPoint); - } - } - - /*--- Compressible flow, primitive variables nDim+5, (T, vx, vy, vz, P, rho, h, c, lamMu, eddyMu, ThCond, Cp) ---*/ - - physical = static_cast(nodes)->SetPrimVar(iPoint,eddy_visc, turb_ke, FluidModel); - nodes->SetSecondaryVar(iPoint,FluidModel); - - /* Check for non-realizable states for reporting. */ - - if (!physical) nonPhysicalPoints++; - - /*--- Set the DES length scale ---*/ - - nodes->SetDES_LengthScale(iPoint,DES_LengthScale); - - /*--- Initialize the convective, source and viscous residual vector ---*/ - - if (!Output) LinSysRes.SetBlock_Zero(iPoint); - - } - - return nonPhysicalPoints; -} - -void CNSSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned long Iteration) { - - su2double *Normal, Area, Vol, Mean_SoundSpeed = 0.0, Mean_ProjVel = 0.0, Lambda, Local_Delta_Time, Local_Delta_Time_Visc, - Global_Delta_Time = 1E6, Mean_LaminarVisc = 0.0, Mean_EddyVisc = 0.0, Mean_Density = 0.0, Lambda_1, Lambda_2, K_v = 0.25, Global_Delta_UnstTimeND; - unsigned long iEdge, iVertex, iPoint = 0, jPoint = 0; - unsigned short iDim, iMarker; - su2double ProjVel, ProjVel_i, ProjVel_j; - - bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); - bool dual_time = ((config->GetTime_Marching() == DT_STEPPING_1ST) || - (config->GetTime_Marching() == DT_STEPPING_2ND)); - - Min_Delta_Time = 1.E30; Max_Delta_Time = 0.0; - - /*--- Set maximum inviscid eigenvalue to zero, and compute sound speed and viscosity ---*/ - - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - nodes->SetMax_Lambda_Inv(iPoint,0.0); - nodes->SetMax_Lambda_Visc(iPoint,0.0); - } - - /*--- Loop interior edges ---*/ - - for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - - /*--- Point identification, Normal vector and area ---*/ - - iPoint = geometry->edge[iEdge]->GetNode(0); - jPoint = geometry->edge[iEdge]->GetNode(1); - - Normal = geometry->edge[iEdge]->GetNormal(); - Area = 0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); - - /*--- Mean Values ---*/ - - Mean_ProjVel = 0.5 * (nodes->GetProjVel(iPoint,Normal) + nodes->GetProjVel(jPoint,Normal)); - Mean_SoundSpeed = 0.5 * (nodes->GetSoundSpeed(iPoint) + nodes->GetSoundSpeed(jPoint)) * Area; - - /*--- Adjustment for grid movement ---*/ - - if (dynamic_grid) { - su2double *GridVel_i = geometry->node[iPoint]->GetGridVel(); - su2double *GridVel_j = geometry->node[jPoint]->GetGridVel(); - ProjVel_i = 0.0; ProjVel_j =0.0; - for (iDim = 0; iDim < nDim; iDim++) { - ProjVel_i += GridVel_i[iDim]*Normal[iDim]; - ProjVel_j += GridVel_j[iDim]*Normal[iDim]; - } - Mean_ProjVel -= 0.5 * (ProjVel_i + ProjVel_j) ; - } - - /*--- Inviscid contribution ---*/ - - Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed ; - if (geometry->node[iPoint]->GetDomain()) nodes->AddMax_Lambda_Inv(iPoint,Lambda); - if (geometry->node[jPoint]->GetDomain()) nodes->AddMax_Lambda_Inv(jPoint,Lambda); - - /*--- Viscous contribution ---*/ - - Mean_LaminarVisc = 0.5*(nodes->GetLaminarViscosity(iPoint) + nodes->GetLaminarViscosity(jPoint)); - Mean_EddyVisc = 0.5*(nodes->GetEddyViscosity(iPoint) + nodes->GetEddyViscosity(jPoint)); - Mean_Density = 0.5*(nodes->GetDensity(iPoint) + nodes->GetDensity(jPoint)); - - Lambda_1 = (4.0/3.0)*(Mean_LaminarVisc + Mean_EddyVisc); - //TODO (REAL_GAS) removing Gamma it cannot work with FLUIDPROP - Lambda_2 = (1.0 + (Prandtl_Lam/Prandtl_Turb)*(Mean_EddyVisc/Mean_LaminarVisc))*(Gamma*Mean_LaminarVisc/Prandtl_Lam); - Lambda = (Lambda_1 + Lambda_2)*Area*Area/Mean_Density; - - if (geometry->node[iPoint]->GetDomain()) nodes->AddMax_Lambda_Visc(iPoint, Lambda); - if (geometry->node[jPoint]->GetDomain()) nodes->AddMax_Lambda_Visc(jPoint, Lambda); - - } - - /*--- Loop boundary edges ---*/ - - for (iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { - if ((config->GetMarker_All_KindBC(iMarker) != INTERNAL_BOUNDARY) && - (config->GetMarker_All_KindBC(iMarker) != PERIODIC_BOUNDARY)) { - for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { - - /*--- Point identification, Normal vector and area ---*/ - - iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); - - /*--- Mean Values ---*/ - - Mean_ProjVel = nodes->GetProjVel(iPoint,Normal); - Mean_SoundSpeed = nodes->GetSoundSpeed(iPoint) * Area; - - /*--- Adjustment for grid movement ---*/ - - if (dynamic_grid) { - su2double *GridVel = geometry->node[iPoint]->GetGridVel(); - ProjVel = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - ProjVel += GridVel[iDim]*Normal[iDim]; - Mean_ProjVel -= ProjVel; - } - - /*--- Inviscid contribution ---*/ - - Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; - if (geometry->node[iPoint]->GetDomain()) { - nodes->AddMax_Lambda_Inv(iPoint,Lambda); - } - - /*--- Viscous contribution ---*/ - - Mean_LaminarVisc = nodes->GetLaminarViscosity(iPoint); - Mean_EddyVisc = nodes->GetEddyViscosity(iPoint); - Mean_Density = nodes->GetDensity(iPoint); - - Lambda_1 = (4.0/3.0)*(Mean_LaminarVisc + Mean_EddyVisc); - Lambda_2 = (1.0 + (Prandtl_Lam/Prandtl_Turb)*(Mean_EddyVisc/Mean_LaminarVisc))*(Gamma*Mean_LaminarVisc/Prandtl_Lam); - Lambda = (Lambda_1 + Lambda_2)*Area*Area/Mean_Density; - - if (geometry->node[iPoint]->GetDomain()) nodes->AddMax_Lambda_Visc(iPoint, Lambda); - - } - } - } - - /*--- Each element uses their own speed, steady state simulation ---*/ - - - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - - Vol = geometry->node[iPoint]->GetVolume(); - - if (Vol != 0.0) { - Local_Delta_Time = nodes->GetLocalCFL(iPoint)*Vol / nodes->GetMax_Lambda_Inv(iPoint); - Local_Delta_Time_Visc = nodes->GetLocalCFL(iPoint)*K_v*Vol*Vol/ nodes->GetMax_Lambda_Visc(iPoint); - Local_Delta_Time = min(Local_Delta_Time, Local_Delta_Time_Visc); - Global_Delta_Time = min(Global_Delta_Time, Local_Delta_Time); - Min_Delta_Time = min(Min_Delta_Time, Local_Delta_Time); - Max_Delta_Time = max(Max_Delta_Time, Local_Delta_Time); - if (Local_Delta_Time > config->GetMax_DeltaTime()) - Local_Delta_Time = config->GetMax_DeltaTime(); - nodes->SetDelta_Time(iPoint,Local_Delta_Time); - } - else { - nodes->SetDelta_Time(iPoint,0.0); - } - - } - - - /*--- Compute the max and the min dt (in parallel) ---*/ - if (config->GetComm_Level() == COMM_FULL) { -#ifdef HAVE_MPI - su2double rbuf_time, sbuf_time; - sbuf_time = Min_Delta_Time; - SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, MPI_COMM_WORLD); - SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); - Min_Delta_Time = rbuf_time; - - sbuf_time = Max_Delta_Time; - SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MAX, MASTER_NODE, MPI_COMM_WORLD); - SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); - Max_Delta_Time = rbuf_time; -#endif - } - - /*--- For exact time solution use the minimum delta time of the whole mesh ---*/ - if (config->GetTime_Marching() == TIME_STEPPING) { -#ifdef HAVE_MPI - su2double rbuf_time, sbuf_time; - sbuf_time = Global_Delta_Time; - SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, MPI_COMM_WORLD); - SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); - Global_Delta_Time = rbuf_time; -#endif - /*--- If the unsteady CFL is set to zero, it uses the defined - unsteady time step, otherwise it computes the time step based - on the unsteady CFL ---*/ - - if (config->GetUnst_CFL() == 0.0) { - Global_Delta_Time = config->GetDelta_UnstTime(); - } - config->SetDelta_UnstTimeND(Global_Delta_Time); - for (iPoint = 0; iPoint < nPointDomain; iPoint++){ - - /*--- Sets the regular CFL equal to the unsteady CFL ---*/ - - nodes->SetLocalCFL(iPoint, config->GetUnst_CFL()); - nodes->SetDelta_Time(iPoint, Global_Delta_Time); - Min_Delta_Time = Global_Delta_Time; - Max_Delta_Time = Global_Delta_Time; - - } - } - - /*--- Recompute the unsteady time step for the dual time strategy - if the unsteady CFL is diferent from 0 ---*/ - if ((dual_time) && (Iteration == 0) && (config->GetUnst_CFL() != 0.0) && (iMesh == MESH_0)) { - - Global_Delta_UnstTimeND = 1e30; - for (iPoint = 0; iPoint < nPointDomain; iPoint++){ - Global_Delta_UnstTimeND = min(Global_Delta_UnstTimeND,config->GetUnst_CFL()*Global_Delta_Time/nodes->GetLocalCFL(iPoint)); - } - -#ifdef HAVE_MPI - su2double rbuf_time, sbuf_time; - sbuf_time = Global_Delta_UnstTimeND; - SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, MPI_COMM_WORLD); - SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); - Global_Delta_UnstTimeND = rbuf_time; -#endif - config->SetDelta_UnstTimeND(Global_Delta_UnstTimeND); - } - - /*--- The pseudo local time (explicit integration) cannot be greater than the physical time ---*/ - if (dual_time) - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - if (!implicit) { - Local_Delta_Time = min((2.0/3.0)*config->GetDelta_UnstTimeND(), nodes->GetDelta_Time(iPoint)); - nodes->SetDelta_Time(iPoint,Local_Delta_Time); - } - } - -} - -void CNSSolver::Viscous_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh, unsigned short iRKStep) { - - unsigned long iPoint, jPoint, iEdge; - - bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); - - for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - - /*--- Points, coordinates and normal vector in edge ---*/ - - iPoint = geometry->edge[iEdge]->GetNode(0); - jPoint = geometry->edge[iEdge]->GetNode(1); - numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[jPoint]->GetCoord()); - numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); - - /*--- Primitive and secondary variables ---*/ - - numerics->SetPrimitive(nodes->GetPrimitive(iPoint), nodes->GetPrimitive(jPoint)); - numerics->SetSecondary(nodes->GetSecondary(iPoint), nodes->GetSecondary(jPoint)); - - /*--- Gradient and limiters ---*/ - - numerics->SetPrimVarGradient(nodes->GetGradient_Primitive(iPoint), nodes->GetGradient_Primitive(jPoint)); - - /*--- Turbulent kinetic energy ---*/ - - if ((config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST)) - numerics->SetTurbKineticEnergy(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0), - solver_container[TURB_SOL]->GetNodes()->GetSolution(jPoint,0)); - - /*--- Wall shear stress values (wall functions) ---*/ - - numerics->SetTauWall(nodes->GetTauWall(iPoint), nodes->GetTauWall(iPoint)); - - /*--- Compute and update residual ---*/ - - numerics->ComputeResidual(Res_Visc, Jacobian_i, Jacobian_j, config); - - LinSysRes.SubtractBlock(iPoint, Res_Visc); - LinSysRes.AddBlock(jPoint, Res_Visc); - - /*--- Implicit part ---*/ - - if (implicit) { - Jacobian.UpdateBlocks(iEdge, iPoint, jPoint, Jacobian_i, Jacobian_j); - } - - } - -} - -void CNSSolver::Friction_Forces(CGeometry *geometry, CConfig *config) { - - unsigned long iVertex, iPoint, iPointNormal; - unsigned short Boundary, Monitoring, iMarker, iMarker_Monitoring, iDim, jDim; - su2double Viscosity = 0.0, div_vel, *Normal, MomentDist[3] = {0.0, 0.0, 0.0}, WallDist[3] = {0.0, 0.0, 0.0}, - *Coord, *Coord_Normal, Area, WallShearStress, TauNormal, factor, RefTemp, RefVel2, - RefDensity, GradTemperature, Density = 0.0, WallDistMod, FrictionVel, - Mach2Vel, Mach_Motion, UnitNormal[3] = {0.0, 0.0, 0.0}, TauElem[3] = {0.0, 0.0, 0.0}, TauTangent[3] = {0.0, 0.0, 0.0}, - Tau[3][3] = {{0.0, 0.0, 0.0},{0.0, 0.0, 0.0},{0.0, 0.0, 0.0}}, Force[3] = {0.0, 0.0, 0.0}, Cp, thermal_conductivity, MaxNorm = 8.0, - Grad_Vel[3][3] = {{0.0, 0.0, 0.0},{0.0, 0.0, 0.0},{0.0, 0.0, 0.0}}, Grad_Temp[3] = {0.0, 0.0, 0.0}, - delta[3][3] = {{1.0, 0.0, 0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}}; - su2double MomentX_Force[3] = {0.0,0.0,0.0}, MomentY_Force[3] = {0.0,0.0,0.0}, MomentZ_Force[3] = {0.0,0.0,0.0}; - su2double AxiFactor; - -#ifdef HAVE_MPI - su2double MyAllBound_CD_Visc, MyAllBound_CL_Visc, MyAllBound_CSF_Visc, MyAllBound_CMx_Visc, MyAllBound_CMy_Visc, MyAllBound_CMz_Visc, MyAllBound_CoPx_Visc, MyAllBound_CoPy_Visc, MyAllBound_CoPz_Visc, MyAllBound_CFx_Visc, MyAllBound_CFy_Visc, MyAllBound_CFz_Visc, MyAllBound_CT_Visc, MyAllBound_CQ_Visc, MyAllBound_HF_Visc, MyAllBound_MaxHF_Visc, *MySurface_CL_Visc = NULL, *MySurface_CD_Visc = NULL, *MySurface_CSF_Visc = NULL, *MySurface_CEff_Visc = NULL, *MySurface_CFx_Visc = NULL, *MySurface_CFy_Visc = NULL, *MySurface_CFz_Visc = NULL, *MySurface_CMx_Visc = NULL, *MySurface_CMy_Visc = NULL, *MySurface_CMz_Visc = NULL, *MySurface_HF_Visc = NULL, *MySurface_MaxHF_Visc; -#endif - - string Marker_Tag, Monitoring_Tag; - - su2double Alpha = config->GetAoA()*PI_NUMBER/180.0; - su2double Beta = config->GetAoS()*PI_NUMBER/180.0; - su2double RefArea = config->GetRefArea(); - su2double RefLength = config->GetRefLength(); - su2double RefHeatFlux = config->GetHeat_Flux_Ref(); - su2double Gas_Constant = config->GetGas_ConstantND(); - su2double *Origin = NULL; - - if (config->GetnMarker_Monitoring() != 0) { Origin = config->GetRefOriginMoment(0); } - - su2double Prandtl_Lam = config->GetPrandtl_Lam(); - bool QCR = config->GetQCR(); - bool axisymmetric = config->GetAxisymmetric(); - - /*--- Evaluate reference values for non-dimensionalization. - For dynamic meshes, use the motion Mach number as a reference value - for computing the force coefficients. Otherwise, use the freestream values, - which is the standard convention. ---*/ - - RefTemp = Temperature_Inf; - RefDensity = Density_Inf; - if (dynamic_grid) { - Mach2Vel = sqrt(Gamma*Gas_Constant*RefTemp); - Mach_Motion = config->GetMach_Motion(); - RefVel2 = (Mach_Motion*Mach2Vel)*(Mach_Motion*Mach2Vel); - } else { - RefVel2 = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - RefVel2 += Velocity_Inf[iDim]*Velocity_Inf[iDim]; - } - - factor = 1.0 / (0.5*RefDensity*RefArea*RefVel2); - - /*--- Variables initialization ---*/ - - AllBound_CD_Visc = 0.0; AllBound_CL_Visc = 0.0; AllBound_CSF_Visc = 0.0; - AllBound_CFx_Visc = 0.0; AllBound_CFy_Visc = 0.0; AllBound_CFz_Visc = 0.0; - AllBound_CMx_Visc = 0.0; AllBound_CMy_Visc = 0.0; AllBound_CMz_Visc = 0.0; - AllBound_CoPx_Visc = 0.0; AllBound_CoPy_Visc = 0.0; AllBound_CoPz_Visc = 0.0; - AllBound_CT_Visc = 0.0; AllBound_CQ_Visc = 0.0; AllBound_CMerit_Visc = 0.0; - AllBound_HF_Visc = 0.0; AllBound_MaxHF_Visc = 0.0; AllBound_CEff_Visc = 0.0; - - for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { - Surface_CL_Visc[iMarker_Monitoring] = 0.0; Surface_CD_Visc[iMarker_Monitoring] = 0.0; - Surface_CSF_Visc[iMarker_Monitoring] = 0.0; Surface_CEff_Visc[iMarker_Monitoring] = 0.0; - Surface_CFx_Visc[iMarker_Monitoring] = 0.0; Surface_CFy_Visc[iMarker_Monitoring] = 0.0; - Surface_CFz_Visc[iMarker_Monitoring] = 0.0; Surface_CMx_Visc[iMarker_Monitoring] = 0.0; - Surface_CMy_Visc[iMarker_Monitoring] = 0.0; Surface_CMz_Visc[iMarker_Monitoring] = 0.0; - Surface_HF_Visc[iMarker_Monitoring] = 0.0; Surface_MaxHF_Visc[iMarker_Monitoring] = 0.0; - } - - /*--- Loop over the Navier-Stokes markers ---*/ - - for (iMarker = 0; iMarker < nMarker; iMarker++) { - - Boundary = config->GetMarker_All_KindBC(iMarker); - Monitoring = config->GetMarker_All_Monitoring(iMarker); - - /*--- Obtain the origin for the moment computation for a particular marker ---*/ - - if (Monitoring == YES) { - for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { - Monitoring_Tag = config->GetMarker_Monitoring_TagBound(iMarker_Monitoring); - Marker_Tag = config->GetMarker_All_TagBound(iMarker); - if (Marker_Tag == Monitoring_Tag) - Origin = config->GetRefOriginMoment(iMarker_Monitoring); - } - } - - if ((Boundary == HEAT_FLUX) || (Boundary == ISOTHERMAL) || (Boundary == HEAT_FLUX) || (Boundary == CHT_WALL_INTERFACE)) { - - /*--- Forces initialization at each Marker ---*/ - - CD_Visc[iMarker] = 0.0; CL_Visc[iMarker] = 0.0; CSF_Visc[iMarker] = 0.0; - CFx_Visc[iMarker] = 0.0; CFy_Visc[iMarker] = 0.0; CFz_Visc[iMarker] = 0.0; - CMx_Visc[iMarker] = 0.0; CMy_Visc[iMarker] = 0.0; CMz_Visc[iMarker] = 0.0; - CoPx_Visc[iMarker] = 0.0; CoPy_Visc[iMarker] = 0.0; CoPz_Visc[iMarker] = 0.0; - CT_Visc[iMarker] = 0.0; CQ_Visc[iMarker] = 0.0; CMerit_Visc[iMarker] = 0.0; - HF_Visc[iMarker] = 0.0; MaxHF_Visc[iMarker] = 0.0; CEff_Visc[iMarker] = 0.0; - - for (iDim = 0; iDim < nDim; iDim++) ForceViscous[iDim] = 0.0; - MomentViscous[0] = 0.0; MomentViscous[1] = 0.0; MomentViscous[2] = 0.0; - MomentX_Force[0] = 0.0; MomentX_Force[1] = 0.0; MomentX_Force[2] = 0.0; - MomentY_Force[0] = 0.0; MomentY_Force[1] = 0.0; MomentY_Force[2] = 0.0; - MomentZ_Force[0] = 0.0; MomentZ_Force[1] = 0.0; MomentZ_Force[2] = 0.0; - - /*--- Loop over the vertices to compute the forces ---*/ - - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - - iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - iPointNormal = geometry->vertex[iMarker][iVertex]->GetNormal_Neighbor(); - - Coord = geometry->node[iPoint]->GetCoord(); - Coord_Normal = geometry->node[iPointNormal]->GetCoord(); - - Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - - for (iDim = 0; iDim < nDim; iDim++) { - for (jDim = 0 ; jDim < nDim; jDim++) { - Grad_Vel[iDim][jDim] = nodes->GetGradient_Primitive(iPoint,iDim+1, jDim); - } - Grad_Temp[iDim] = nodes->GetGradient_Primitive(iPoint,0, iDim); - } - - Viscosity = nodes->GetLaminarViscosity(iPoint); - Density = nodes->GetDensity(iPoint); - - Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); - - - for (iDim = 0; iDim < nDim; iDim++) { - UnitNormal[iDim] = Normal[iDim]/Area; - } - - /*--- Evaluate Tau ---*/ - - div_vel = 0.0; for (iDim = 0; iDim < nDim; iDim++) div_vel += Grad_Vel[iDim][iDim]; - - for (iDim = 0; iDim < nDim; iDim++) { - for (jDim = 0 ; jDim < nDim; jDim++) { - Tau[iDim][jDim] = Viscosity*(Grad_Vel[jDim][iDim] + Grad_Vel[iDim][jDim]) - TWO3*Viscosity*div_vel*delta[iDim][jDim]; - } - } - - /*--- If necessary evaluate the QCR contribution to Tau ---*/ - - if (QCR){ - su2double den_aux, c_cr1=0.3, O_ik, O_jk; - unsigned short kDim; - - /*--- Denominator Antisymmetric normalized rotation tensor ---*/ - - den_aux = 0.0; - for (iDim = 0 ; iDim < nDim; iDim++) - for (jDim = 0 ; jDim < nDim; jDim++) - den_aux += Grad_Vel[iDim][jDim] * Grad_Vel[iDim][jDim]; - den_aux = sqrt(max(den_aux,1E-10)); - - /*--- Adding the QCR contribution ---*/ - - for (iDim = 0 ; iDim < nDim; iDim++){ - for (jDim = 0 ; jDim < nDim; jDim++){ - for (kDim = 0 ; kDim < nDim; kDim++){ - O_ik = (Grad_Vel[iDim][kDim] - Grad_Vel[kDim][iDim])/ den_aux; - O_jk = (Grad_Vel[jDim][kDim] - Grad_Vel[kDim][jDim])/ den_aux; - Tau[iDim][jDim] -= c_cr1 * (O_ik * Tau[jDim][kDim] + O_jk * Tau[iDim][kDim]); - } - } - } - - } - - /*--- Project Tau in each surface element ---*/ - - for (iDim = 0; iDim < nDim; iDim++) { - TauElem[iDim] = 0.0; - for (jDim = 0; jDim < nDim; jDim++) { - TauElem[iDim] += Tau[iDim][jDim]*UnitNormal[jDim]; - } - } - - /*--- Compute wall shear stress (using the stress tensor). Compute wall skin friction coefficient, and heat flux on the wall ---*/ - - TauNormal = 0.0; for (iDim = 0; iDim < nDim; iDim++) TauNormal += TauElem[iDim] * UnitNormal[iDim]; - - WallShearStress = 0.0; - for (iDim = 0; iDim < nDim; iDim++) { - TauTangent[iDim] = TauElem[iDim] - TauNormal * UnitNormal[iDim]; - CSkinFriction[iMarker][iDim][iVertex] = TauTangent[iDim] / (0.5*RefDensity*RefVel2); - WallShearStress += TauTangent[iDim] * TauTangent[iDim]; - } - WallShearStress = sqrt(WallShearStress); - - for (iDim = 0; iDim < nDim; iDim++) WallDist[iDim] = (Coord[iDim] - Coord_Normal[iDim]); - WallDistMod = 0.0; for (iDim = 0; iDim < nDim; iDim++) WallDistMod += WallDist[iDim]*WallDist[iDim]; WallDistMod = sqrt(WallDistMod); - - /*--- Compute y+ and non-dimensional velocity ---*/ - - FrictionVel = sqrt(fabs(WallShearStress)/Density); - YPlus[iMarker][iVertex] = WallDistMod*FrictionVel/(Viscosity/Density); - - /*--- Compute total and maximum heat flux on the wall ---*/ - - GradTemperature = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - GradTemperature -= Grad_Temp[iDim]*UnitNormal[iDim]; - - Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; - thermal_conductivity = Cp * Viscosity/Prandtl_Lam; - HeatFlux[iMarker][iVertex] = -thermal_conductivity*GradTemperature*RefHeatFlux; - - /*--- Note that y+, and heat are computed at the - halo cells (for visualization purposes), but not the forces ---*/ - - if ((geometry->node[iPoint]->GetDomain()) && (Monitoring == YES)) { - - /*--- Axisymmetric simulations ---*/ - - if (axisymmetric) AxiFactor = 2.0*PI_NUMBER*geometry->node[iPoint]->GetCoord(1); - else AxiFactor = 1.0; - - /*--- Force computation ---*/ - - for (iDim = 0; iDim < nDim; iDim++) { - Force[iDim] = TauElem[iDim] * Area * factor * AxiFactor; - ForceViscous[iDim] += Force[iDim]; - MomentDist[iDim] = Coord[iDim] - Origin[iDim]; - } - - /*--- Moment with respect to the reference axis ---*/ - - if (iDim == 3) { - MomentViscous[0] += (Force[2]*MomentDist[1] - Force[1]*MomentDist[2])/RefLength; - MomentX_Force[1] += (-Force[1]*Coord[2]); - MomentX_Force[2] += (Force[2]*Coord[1]); - - MomentViscous[1] += (Force[0]*MomentDist[2] - Force[2]*MomentDist[0])/RefLength; - MomentY_Force[2] += (-Force[2]*Coord[0]); - MomentY_Force[0] += (Force[0]*Coord[2]); - } - MomentViscous[2] += (Force[1]*MomentDist[0] - Force[0]*MomentDist[1])/RefLength; - MomentZ_Force[0] += (-Force[0]*Coord[1]); - MomentZ_Force[1] += (Force[1]*Coord[0]); - - } - - HF_Visc[iMarker] += HeatFlux[iMarker][iVertex]*Area; - MaxHF_Visc[iMarker] += pow(HeatFlux[iMarker][iVertex], MaxNorm); - - } - - /*--- Project forces and store the non-dimensional coefficients ---*/ - - if (Monitoring == YES) { - if (nDim == 2) { - CD_Visc[iMarker] = ForceViscous[0]*cos(Alpha) + ForceViscous[1]*sin(Alpha); - CL_Visc[iMarker] = -ForceViscous[0]*sin(Alpha) + ForceViscous[1]*cos(Alpha); - CEff_Visc[iMarker] = CL_Visc[iMarker] / (CD_Visc[iMarker]+EPS); - CFx_Visc[iMarker] = ForceViscous[0]; - CFy_Visc[iMarker] = ForceViscous[1]; - CMz_Visc[iMarker] = MomentViscous[2]; - CoPx_Visc[iMarker] = MomentZ_Force[1]; - CoPy_Visc[iMarker] = -MomentZ_Force[0]; - CT_Visc[iMarker] = -CFx_Visc[iMarker]; - CQ_Visc[iMarker] = -CMz_Visc[iMarker]; - CMerit_Visc[iMarker] = CT_Visc[iMarker] / (CQ_Visc[iMarker]+EPS); - MaxHF_Visc[iMarker] = pow(MaxHF_Visc[iMarker], 1.0/MaxNorm); - } - if (nDim == 3) { - CD_Visc[iMarker] = ForceViscous[0]*cos(Alpha)*cos(Beta) + ForceViscous[1]*sin(Beta) + ForceViscous[2]*sin(Alpha)*cos(Beta); - CL_Visc[iMarker] = -ForceViscous[0]*sin(Alpha) + ForceViscous[2]*cos(Alpha); - CSF_Visc[iMarker] = -ForceViscous[0]*sin(Beta)*cos(Alpha) + ForceViscous[1]*cos(Beta) - ForceViscous[2]*sin(Beta)*sin(Alpha); - CEff_Visc[iMarker] = CL_Visc[iMarker]/(CD_Visc[iMarker] + EPS); - CFx_Visc[iMarker] = ForceViscous[0]; - CFy_Visc[iMarker] = ForceViscous[1]; - CFz_Visc[iMarker] = ForceViscous[2]; - CMx_Visc[iMarker] = MomentViscous[0]; - CMy_Visc[iMarker] = MomentViscous[1]; - CMz_Visc[iMarker] = MomentViscous[2]; - CoPx_Visc[iMarker] = -MomentY_Force[0]; - CoPz_Visc[iMarker] = MomentY_Force[2]; - CT_Visc[iMarker] = -CFz_Visc[iMarker]; - CQ_Visc[iMarker] = -CMz_Visc[iMarker]; - CMerit_Visc[iMarker] = CT_Visc[iMarker] / (CQ_Visc[iMarker] + EPS); - MaxHF_Visc[iMarker] = pow(MaxHF_Visc[iMarker], 1.0/MaxNorm); - } - - AllBound_CD_Visc += CD_Visc[iMarker]; - AllBound_CL_Visc += CL_Visc[iMarker]; - AllBound_CSF_Visc += CSF_Visc[iMarker]; - AllBound_CFx_Visc += CFx_Visc[iMarker]; - AllBound_CFy_Visc += CFy_Visc[iMarker]; - AllBound_CFz_Visc += CFz_Visc[iMarker]; - AllBound_CMx_Visc += CMx_Visc[iMarker]; - AllBound_CMy_Visc += CMy_Visc[iMarker]; - AllBound_CMz_Visc += CMz_Visc[iMarker]; - AllBound_CoPx_Visc += CoPx_Visc[iMarker]; - AllBound_CoPy_Visc += CoPy_Visc[iMarker]; - AllBound_CoPz_Visc += CoPz_Visc[iMarker]; - AllBound_CT_Visc += CT_Visc[iMarker]; - AllBound_CQ_Visc += CQ_Visc[iMarker]; - AllBound_HF_Visc += HF_Visc[iMarker]; - AllBound_MaxHF_Visc += pow(MaxHF_Visc[iMarker], MaxNorm); - - /*--- Compute the coefficients per surface ---*/ - - for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { - Monitoring_Tag = config->GetMarker_Monitoring_TagBound(iMarker_Monitoring); - Marker_Tag = config->GetMarker_All_TagBound(iMarker); - if (Marker_Tag == Monitoring_Tag) { - Surface_CL_Visc[iMarker_Monitoring] += CL_Visc[iMarker]; - Surface_CD_Visc[iMarker_Monitoring] += CD_Visc[iMarker]; - Surface_CSF_Visc[iMarker_Monitoring] += CSF_Visc[iMarker]; - Surface_CEff_Visc[iMarker_Monitoring] += CEff_Visc[iMarker]; - Surface_CFx_Visc[iMarker_Monitoring] += CFx_Visc[iMarker]; - Surface_CFy_Visc[iMarker_Monitoring] += CFy_Visc[iMarker]; - Surface_CFz_Visc[iMarker_Monitoring] += CFz_Visc[iMarker]; - Surface_CMx_Visc[iMarker_Monitoring] += CMx_Visc[iMarker]; - Surface_CMy_Visc[iMarker_Monitoring] += CMy_Visc[iMarker]; - Surface_CMz_Visc[iMarker_Monitoring] += CMz_Visc[iMarker]; - Surface_HF_Visc[iMarker_Monitoring] += HF_Visc[iMarker]; - Surface_MaxHF_Visc[iMarker_Monitoring] += pow(MaxHF_Visc[iMarker],MaxNorm); - } - } - - } - - } - } - - /*--- Update some global coeffients ---*/ - - AllBound_CEff_Visc = AllBound_CL_Visc / (AllBound_CD_Visc + EPS); - AllBound_CMerit_Visc = AllBound_CT_Visc / (AllBound_CQ_Visc + EPS); - AllBound_MaxHF_Visc = pow(AllBound_MaxHF_Visc, 1.0/MaxNorm); - - -#ifdef HAVE_MPI - - /*--- Add AllBound information using all the nodes ---*/ - - MyAllBound_CD_Visc = AllBound_CD_Visc; AllBound_CD_Visc = 0.0; - MyAllBound_CL_Visc = AllBound_CL_Visc; AllBound_CL_Visc = 0.0; - MyAllBound_CSF_Visc = AllBound_CSF_Visc; AllBound_CSF_Visc = 0.0; - AllBound_CEff_Visc = 0.0; - MyAllBound_CMx_Visc = AllBound_CMx_Visc; AllBound_CMx_Visc = 0.0; - MyAllBound_CMy_Visc = AllBound_CMy_Visc; AllBound_CMy_Visc = 0.0; - MyAllBound_CMz_Visc = AllBound_CMz_Visc; AllBound_CMz_Visc = 0.0; - MyAllBound_CoPx_Visc = AllBound_CoPx_Visc; AllBound_CoPx_Visc = 0.0; - MyAllBound_CoPy_Visc = AllBound_CoPy_Visc; AllBound_CoPy_Visc = 0.0; - MyAllBound_CoPz_Visc = AllBound_CoPz_Visc; AllBound_CoPz_Visc = 0.0; - MyAllBound_CFx_Visc = AllBound_CFx_Visc; AllBound_CFx_Visc = 0.0; - MyAllBound_CFy_Visc = AllBound_CFy_Visc; AllBound_CFy_Visc = 0.0; - MyAllBound_CFz_Visc = AllBound_CFz_Visc; AllBound_CFz_Visc = 0.0; - MyAllBound_CT_Visc = AllBound_CT_Visc; AllBound_CT_Visc = 0.0; - MyAllBound_CQ_Visc = AllBound_CQ_Visc; AllBound_CQ_Visc = 0.0; - AllBound_CMerit_Visc = 0.0; - MyAllBound_HF_Visc = AllBound_HF_Visc; AllBound_HF_Visc = 0.0; - MyAllBound_MaxHF_Visc = pow(AllBound_MaxHF_Visc, MaxNorm); AllBound_MaxHF_Visc = 0.0; - - if (config->GetComm_Level() == COMM_FULL) { - SU2_MPI::Allreduce(&MyAllBound_CD_Visc, &AllBound_CD_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CL_Visc, &AllBound_CL_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CSF_Visc, &AllBound_CSF_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - AllBound_CEff_Visc = AllBound_CL_Visc / (AllBound_CD_Visc + EPS); - SU2_MPI::Allreduce(&MyAllBound_CMx_Visc, &AllBound_CMx_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CMy_Visc, &AllBound_CMy_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CMz_Visc, &AllBound_CMz_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CFx_Visc, &AllBound_CFx_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CFy_Visc, &AllBound_CFy_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CFz_Visc, &AllBound_CFz_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CoPx_Visc, &AllBound_CoPx_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CoPy_Visc, &AllBound_CoPy_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CoPz_Visc, &AllBound_CoPz_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CT_Visc, &AllBound_CT_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CQ_Visc, &AllBound_CQ_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - AllBound_CMerit_Visc = AllBound_CT_Visc / (AllBound_CQ_Visc + EPS); - SU2_MPI::Allreduce(&MyAllBound_HF_Visc, &AllBound_HF_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_MaxHF_Visc, &AllBound_MaxHF_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - AllBound_MaxHF_Visc = pow(AllBound_MaxHF_Visc, 1.0/MaxNorm); - } - - /*--- Add the forces on the surfaces using all the nodes ---*/ - - MySurface_CL_Visc = new su2double[config->GetnMarker_Monitoring()]; - MySurface_CD_Visc = new su2double[config->GetnMarker_Monitoring()]; - MySurface_CSF_Visc = new su2double[config->GetnMarker_Monitoring()]; - MySurface_CEff_Visc = new su2double[config->GetnMarker_Monitoring()]; - MySurface_CFx_Visc = new su2double[config->GetnMarker_Monitoring()]; - MySurface_CFy_Visc = new su2double[config->GetnMarker_Monitoring()]; - MySurface_CFz_Visc = new su2double[config->GetnMarker_Monitoring()]; - MySurface_CMx_Visc = new su2double[config->GetnMarker_Monitoring()]; - MySurface_CMy_Visc = new su2double[config->GetnMarker_Monitoring()]; - MySurface_CMz_Visc = new su2double[config->GetnMarker_Monitoring()]; - MySurface_HF_Visc = new su2double[config->GetnMarker_Monitoring()]; - MySurface_MaxHF_Visc = new su2double[config->GetnMarker_Monitoring()]; - - for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { - - MySurface_CL_Visc[iMarker_Monitoring] = Surface_CL_Visc[iMarker_Monitoring]; - MySurface_CD_Visc[iMarker_Monitoring] = Surface_CD_Visc[iMarker_Monitoring]; - MySurface_CSF_Visc[iMarker_Monitoring] = Surface_CSF_Visc[iMarker_Monitoring]; - MySurface_CEff_Visc[iMarker_Monitoring] = Surface_CEff_Visc[iMarker_Monitoring]; - MySurface_CFx_Visc[iMarker_Monitoring] = Surface_CFx_Visc[iMarker_Monitoring]; - MySurface_CFy_Visc[iMarker_Monitoring] = Surface_CFy_Visc[iMarker_Monitoring]; - MySurface_CFz_Visc[iMarker_Monitoring] = Surface_CFz_Visc[iMarker_Monitoring]; - MySurface_CMx_Visc[iMarker_Monitoring] = Surface_CMx_Visc[iMarker_Monitoring]; - MySurface_CMy_Visc[iMarker_Monitoring] = Surface_CMy_Visc[iMarker_Monitoring]; - MySurface_CMz_Visc[iMarker_Monitoring] = Surface_CMz_Visc[iMarker_Monitoring]; - MySurface_HF_Visc[iMarker_Monitoring] = Surface_HF_Visc[iMarker_Monitoring]; - MySurface_MaxHF_Visc[iMarker_Monitoring] = Surface_MaxHF_Visc[iMarker_Monitoring]; - - Surface_CL_Visc[iMarker_Monitoring] = 0.0; - Surface_CD_Visc[iMarker_Monitoring] = 0.0; - Surface_CSF_Visc[iMarker_Monitoring] = 0.0; - Surface_CEff_Visc[iMarker_Monitoring] = 0.0; - Surface_CFx_Visc[iMarker_Monitoring] = 0.0; - Surface_CFy_Visc[iMarker_Monitoring] = 0.0; - Surface_CFz_Visc[iMarker_Monitoring] = 0.0; - Surface_CMx_Visc[iMarker_Monitoring] = 0.0; - Surface_CMy_Visc[iMarker_Monitoring] = 0.0; - Surface_CMz_Visc[iMarker_Monitoring] = 0.0; - Surface_HF_Visc[iMarker_Monitoring] = 0.0; - Surface_MaxHF_Visc[iMarker_Monitoring] = 0.0; - } - - if (config->GetComm_Level() == COMM_FULL) { - SU2_MPI::Allreduce(MySurface_CL_Visc, Surface_CL_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(MySurface_CD_Visc, Surface_CD_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(MySurface_CSF_Visc, Surface_CSF_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) - Surface_CEff_Visc[iMarker_Monitoring] = Surface_CL_Visc[iMarker_Monitoring] / (Surface_CD_Visc[iMarker_Monitoring] + EPS); - SU2_MPI::Allreduce(MySurface_CFx_Visc, Surface_CFx_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(MySurface_CFy_Visc, Surface_CFy_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(MySurface_CFz_Visc, Surface_CFz_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(MySurface_CMx_Visc, Surface_CMx_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(MySurface_CMy_Visc, Surface_CMy_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(MySurface_CMz_Visc, Surface_CMz_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(MySurface_HF_Visc, Surface_HF_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(MySurface_MaxHF_Visc, Surface_MaxHF_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - } - - delete [] MySurface_CL_Visc; delete [] MySurface_CD_Visc; delete [] MySurface_CSF_Visc; - delete [] MySurface_CEff_Visc; delete [] MySurface_CFx_Visc; delete [] MySurface_CFy_Visc; - delete [] MySurface_CFz_Visc; delete [] MySurface_CMx_Visc; delete [] MySurface_CMy_Visc; - delete [] MySurface_CMz_Visc; delete [] MySurface_HF_Visc; delete [] MySurface_MaxHF_Visc; - -#endif - - /*--- Update the total coefficients (note that all the nodes have the same value)---*/ - - Total_CD += AllBound_CD_Visc; - Total_CL += AllBound_CL_Visc; - Total_CSF += AllBound_CSF_Visc; - Total_CEff = Total_CL / (Total_CD + EPS); - Total_CFx += AllBound_CFx_Visc; - Total_CFy += AllBound_CFy_Visc; - Total_CFz += AllBound_CFz_Visc; - Total_CMx += AllBound_CMx_Visc; - Total_CMy += AllBound_CMy_Visc; - Total_CMz += AllBound_CMz_Visc; - Total_CoPx += AllBound_CoPx_Visc; - Total_CoPy += AllBound_CoPy_Visc; - Total_CoPz += AllBound_CoPz_Visc; - Total_CT += AllBound_CT_Visc; - Total_CQ += AllBound_CQ_Visc; - Total_CMerit = AllBound_CT_Visc / (AllBound_CQ_Visc + EPS); - Total_Heat = AllBound_HF_Visc; - Total_MaxHeat = AllBound_MaxHF_Visc; - - /*--- Update the total coefficients per surface (note that all the nodes have the same value)---*/ - - for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { - Surface_CL[iMarker_Monitoring] += Surface_CL_Visc[iMarker_Monitoring]; - Surface_CD[iMarker_Monitoring] += Surface_CD_Visc[iMarker_Monitoring]; - Surface_CSF[iMarker_Monitoring] += Surface_CSF_Visc[iMarker_Monitoring]; - Surface_CEff[iMarker_Monitoring] = Surface_CL[iMarker_Monitoring] / (Surface_CD[iMarker_Monitoring] + EPS); - Surface_CFx[iMarker_Monitoring] += Surface_CFx_Visc[iMarker_Monitoring]; - Surface_CFy[iMarker_Monitoring] += Surface_CFy_Visc[iMarker_Monitoring]; - Surface_CFz[iMarker_Monitoring] += Surface_CFz_Visc[iMarker_Monitoring]; - Surface_CMx[iMarker_Monitoring] += Surface_CMx_Visc[iMarker_Monitoring]; - Surface_CMy[iMarker_Monitoring] += Surface_CMy_Visc[iMarker_Monitoring]; - Surface_CMz[iMarker_Monitoring] += Surface_CMz_Visc[iMarker_Monitoring]; - } - -} - -void CNSSolver::Buffet_Monitoring(CGeometry *geometry, CConfig *config) { - - unsigned long iVertex; - unsigned short Boundary, Monitoring, iMarker, iMarker_Monitoring, iDim; - su2double *Vel_FS = config->GetVelocity_FreeStream(); - su2double VelMag_FS = 0.0, SkinFrictionMag = 0.0, SkinFrictionDot = 0.0, *Normal, Area, Sref = config->GetRefArea(); - su2double k = config->GetBuffet_k(), - lam = config->GetBuffet_lambda(); - string Marker_Tag, Monitoring_Tag; - - for (iDim = 0; iDim < nDim; iDim++){ - VelMag_FS += Vel_FS[iDim]*Vel_FS[iDim]; - } - VelMag_FS = sqrt(VelMag_FS); - - /*-- Variables initialization ---*/ - - Total_Buffet_Metric = 0.0; - - for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { - Surface_Buffet_Metric[iMarker_Monitoring] = 0.0; - } - - /*--- Loop over the Euler and Navier-Stokes markers ---*/ - - for (iMarker = 0; iMarker < nMarker; iMarker++) { - - Buffet_Metric[iMarker] = 0.0; - - Boundary = config->GetMarker_All_KindBC(iMarker); - Monitoring = config->GetMarker_All_Monitoring(iMarker); - - if ((Boundary == HEAT_FLUX) || (Boundary == ISOTHERMAL) || (Boundary == HEAT_FLUX) || (Boundary == CHT_WALL_INTERFACE)) { - - /*--- Loop over the vertices to compute the buffet sensor ---*/ - - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - - /*--- Perform dot product of skin friction with freestream velocity ---*/ - - SkinFrictionMag = 0.0; - SkinFrictionDot = 0.0; - for(iDim = 0; iDim < nDim; iDim++){ - SkinFrictionMag += CSkinFriction[iMarker][iDim][iVertex]*CSkinFriction[iMarker][iDim][iVertex]; - SkinFrictionDot += CSkinFriction[iMarker][iDim][iVertex]*Vel_FS[iDim]; - } - SkinFrictionMag = sqrt(SkinFrictionMag); - - /*--- Normalize the dot product ---*/ - - SkinFrictionDot /= SkinFrictionMag*VelMag_FS; - - /*--- Compute Heaviside function ---*/ - - Buffet_Sensor[iMarker][iVertex] = 1./(1. + exp(2.*k*(SkinFrictionDot + lam))); - - /*--- Integrate buffet sensor ---*/ - - if(Monitoring == YES){ - - Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - Area = 0.0; - for(iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; - Area = sqrt(Area); - - Buffet_Metric[iMarker] += Buffet_Sensor[iMarker][iVertex]*Area/Sref; - - } - - } - - if(Monitoring == YES){ - - Total_Buffet_Metric += Buffet_Metric[iMarker]; - - /*--- Per surface buffet metric ---*/ - - for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { - Monitoring_Tag = config->GetMarker_Monitoring_TagBound(iMarker_Monitoring); - Marker_Tag = config->GetMarker_All_TagBound(iMarker); - if (Marker_Tag == Monitoring_Tag) Surface_Buffet_Metric[iMarker_Monitoring] = Buffet_Metric[iMarker]; - } - - } - - } - - } - -#ifdef HAVE_MPI - - /*--- Add buffet metric information using all the nodes ---*/ - - su2double MyTotal_Buffet_Metric = Total_Buffet_Metric; - Total_Buffet_Metric = 0.0; - - SU2_MPI::Allreduce(&MyTotal_Buffet_Metric, &Total_Buffet_Metric, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - - /*--- Add the buffet metric on the surfaces using all the nodes ---*/ - - su2double *MySurface_Buffet_Metric = new su2double[config->GetnMarker_Monitoring()]; - - for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { - - MySurface_Buffet_Metric[iMarker_Monitoring] = Surface_Buffet_Metric[iMarker_Monitoring]; - Surface_Buffet_Metric[iMarker_Monitoring] = 0.0; - - } - - SU2_MPI::Allreduce(MySurface_Buffet_Metric, Surface_Buffet_Metric, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - - delete [] MySurface_Buffet_Metric; - -#endif - -} - -void CNSSolver::Evaluate_ObjFunc(CConfig *config) { - - unsigned short iMarker_Monitoring, Kind_ObjFunc; - su2double Weight_ObjFunc; - - /*--- Evaluate objective functions common to Euler and NS solvers ---*/ - - CEulerSolver::Evaluate_ObjFunc(config); - - /*--- Evaluate objective functions specific to NS solver ---*/ - - for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { - - Weight_ObjFunc = config->GetWeight_ObjFunc(iMarker_Monitoring); - Kind_ObjFunc = config->GetKind_ObjFunc(iMarker_Monitoring); - - switch(Kind_ObjFunc) { - case BUFFET_SENSOR: - Total_ComboObj +=Weight_ObjFunc*Surface_Buffet_Metric[iMarker_Monitoring]; - break; - default: - break; - } - } - -} - - -void CNSSolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - - unsigned short iDim, jDim, iVar, jVar; - unsigned long iVertex, iPoint, Point_Normal, total_index; - - su2double Wall_HeatFlux, dist_ij, *Coord_i, *Coord_j, theta2; - su2double thetax, thetay, thetaz, etax, etay, etaz, pix, piy, piz, factor; - su2double ProjGridVel, *GridVel, GridVel2, *Normal, Area, Pressure = 0.0; - su2double total_viscosity, div_vel, Density, tau_vel[3] = {0.0, 0.0, 0.0}, UnitNormal[3] = {0.0, 0.0, 0.0}; - su2double laminar_viscosity = 0.0, eddy_viscosity = 0.0, Grad_Vel[3][3] = {{0.0,0.0,0.0},{0.0,0.0,0.0},{0.0,0.0,0.0}}, - tau[3][3] = {{0.0,0.0,0.0},{0.0,0.0,0.0},{0.0,0.0,0.0}}; - su2double delta[3][3] = {{1.0, 0.0, 0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}}; - - bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); - - /*--- Identify the boundary by string name ---*/ - - string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - - /*--- Get the specified wall heat flux from config as well as the - wall function treatment.---*/ - - Wall_HeatFlux = config->GetWall_HeatFlux(Marker_Tag)/config->GetHeat_Flux_Ref(); - -// Wall_Function = config->GetWallFunction_Treatment(Marker_Tag); -// if (Wall_Function != NO_WALL_FUNCTION) { -// SU2_MPI::Error("Wall function treament not implemented yet", CURRENT_FUNCTION); -// } - - /*--- Loop over all of the vertices on this boundary marker ---*/ - - for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - - /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ - - if (geometry->node[iPoint]->GetDomain()) { - - /*--- If it is a customizable patch, retrieve the specified wall heat flux. ---*/ - - if (config->GetMarker_All_PyCustom(val_marker)) Wall_HeatFlux = geometry->GetCustomBoundaryHeatFlux(val_marker, iVertex); - - /*--- Compute dual-grid area and boundary normal ---*/ - - Normal = geometry->vertex[val_marker][iVertex]->GetNormal(); - - Area = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - Area += Normal[iDim]*Normal[iDim]; - Area = sqrt (Area); - - for (iDim = 0; iDim < nDim; iDim++) - UnitNormal[iDim] = -Normal[iDim]/Area; - - /*--- Initialize the convective & viscous residuals to zero ---*/ - - for (iVar = 0; iVar < nVar; iVar++) { - Res_Conv[iVar] = 0.0; - Res_Visc[iVar] = 0.0; - } - - /*--- Store the corrected velocity at the wall which will - be zero (v = 0), unless there are moving walls (v = u_wall)---*/ - - if (dynamic_grid) { - GridVel = geometry->node[iPoint]->GetGridVel(); - for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = GridVel[iDim]; - } else { - for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = 0.0; - } - - /*--- Impose the value of the velocity as a strong boundary - condition (Dirichlet). Fix the velocity and remove any - contribution to the residual at this node. ---*/ - - nodes->SetVelocity_Old(iPoint,Vector); - - for (iDim = 0; iDim < nDim; iDim++) - LinSysRes.SetBlock_Zero(iPoint, iDim+1); - nodes->SetVel_ResTruncError_Zero(iPoint); - - /*--- Apply a weak boundary condition for the energy equation. - Compute the residual due to the prescribed heat flux. ---*/ - - Res_Visc[nDim+1] = Wall_HeatFlux * Area; - - /*--- If the wall is moving, there are additional residual contributions - due to pressure (p v_wall.n) and shear stress (tau.v_wall.n). ---*/ - - if (dynamic_grid) { - - /*--- Get the grid velocity at the current boundary node ---*/ - - GridVel = geometry->node[iPoint]->GetGridVel(); - ProjGridVel = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - ProjGridVel += GridVel[iDim]*UnitNormal[iDim]*Area; - - /*--- Retrieve other primitive quantities and viscosities ---*/ - - Density = nodes->GetDensity(iPoint); - Pressure = nodes->GetPressure(iPoint); - laminar_viscosity = nodes->GetLaminarViscosity(iPoint); - eddy_viscosity = nodes->GetEddyViscosity(iPoint); - total_viscosity = laminar_viscosity + eddy_viscosity; - - for (iDim = 0; iDim < nDim; iDim++) { - for (jDim = 0 ; jDim < nDim; jDim++) { - Grad_Vel[iDim][jDim] = nodes->GetGradient_Primitive(iPoint,iDim+1, jDim); - } - } - - /*--- Divergence of the velocity ---*/ - - div_vel = 0.0; for (iDim = 0 ; iDim < nDim; iDim++) div_vel += Grad_Vel[iDim][iDim]; - - /*--- Compute the viscous stress tensor ---*/ - - for (iDim = 0; iDim < nDim; iDim++) { - for (jDim = 0; jDim < nDim; jDim++) { - tau[iDim][jDim] = total_viscosity*( Grad_Vel[jDim][iDim]+Grad_Vel[iDim][jDim] ) - TWO3*total_viscosity*div_vel*delta[iDim][jDim]; - } - } - - /*--- Dot product of the stress tensor with the grid velocity ---*/ - - for (iDim = 0 ; iDim < nDim; iDim++) { - tau_vel[iDim] = 0.0; - for (jDim = 0 ; jDim < nDim; jDim++) - tau_vel[iDim] += tau[iDim][jDim]*GridVel[jDim]; - } - - /*--- Compute the convective and viscous residuals (energy eqn.) ---*/ - - Res_Conv[nDim+1] = Pressure*ProjGridVel; - for (iDim = 0 ; iDim < nDim; iDim++) - Res_Visc[nDim+1] += tau_vel[iDim]*UnitNormal[iDim]*Area; - - /*--- Implicit Jacobian contributions due to moving walls ---*/ - - if (implicit) { - - /*--- Jacobian contribution related to the pressure term ---*/ - - GridVel2 = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - GridVel2 += GridVel[iDim]*GridVel[iDim]; - for (iVar = 0; iVar < nVar; iVar++) - for (jVar = 0; jVar < nVar; jVar++) - Jacobian_i[iVar][jVar] = 0.0; - Jacobian_i[nDim+1][0] = 0.5*(Gamma-1.0)*GridVel2*ProjGridVel; - for (jDim = 0; jDim < nDim; jDim++) - Jacobian_i[nDim+1][jDim+1] = -(Gamma-1.0)*GridVel[jDim]*ProjGridVel; - Jacobian_i[nDim+1][nDim+1] = (Gamma-1.0)*ProjGridVel; - - /*--- Add the block to the Global Jacobian structure ---*/ - - Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - - /*--- Now the Jacobian contribution related to the shear stress ---*/ - - for (iVar = 0; iVar < nVar; iVar++) - for (jVar = 0; jVar < nVar; jVar++) - Jacobian_i[iVar][jVar] = 0.0; - - /*--- Compute closest normal neighbor ---*/ - - Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); - - /*--- Get coordinates of i & nearest normal and compute distance ---*/ - - Coord_i = geometry->node[iPoint]->GetCoord(); - Coord_j = geometry->node[Point_Normal]->GetCoord(); - - dist_ij = 0; - for (iDim = 0; iDim < nDim; iDim++) - dist_ij += (Coord_j[iDim]-Coord_i[iDim])*(Coord_j[iDim]-Coord_i[iDim]); - dist_ij = sqrt(dist_ij); - - theta2 = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - theta2 += UnitNormal[iDim]*UnitNormal[iDim]; - - factor = total_viscosity*Area/(Density*dist_ij); - - if (nDim == 2) { - thetax = theta2 + UnitNormal[0]*UnitNormal[0]/3.0; - thetay = theta2 + UnitNormal[1]*UnitNormal[1]/3.0; - - etaz = UnitNormal[0]*UnitNormal[1]/3.0; - - pix = GridVel[0]*thetax + GridVel[1]*etaz; - piy = GridVel[0]*etaz + GridVel[1]*thetay; - - Jacobian_i[nDim+1][0] -= factor*(-pix*GridVel[0]+piy*GridVel[1]); - Jacobian_i[nDim+1][1] -= factor*pix; - Jacobian_i[nDim+1][2] -= factor*piy; - } else { - thetax = theta2 + UnitNormal[0]*UnitNormal[0]/3.0; - thetay = theta2 + UnitNormal[1]*UnitNormal[1]/3.0; - thetaz = theta2 + UnitNormal[2]*UnitNormal[2]/3.0; - - etaz = UnitNormal[0]*UnitNormal[1]/3.0; - etax = UnitNormal[1]*UnitNormal[2]/3.0; - etay = UnitNormal[0]*UnitNormal[2]/3.0; - - pix = GridVel[0]*thetax + GridVel[1]*etaz + GridVel[2]*etay; - piy = GridVel[0]*etaz + GridVel[1]*thetay + GridVel[2]*etax; - piz = GridVel[0]*etay + GridVel[1]*etax + GridVel[2]*thetaz; - - Jacobian_i[nDim+1][0] -= factor*(-pix*GridVel[0]+piy*GridVel[1]+piz*GridVel[2]); - Jacobian_i[nDim+1][1] -= factor*pix; - Jacobian_i[nDim+1][2] -= factor*piy; - Jacobian_i[nDim+1][3] -= factor*piz; - } - - /*--- Subtract the block from the Global Jacobian structure ---*/ - - Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - - } - } - - /*--- Convective contribution to the residual at the wall ---*/ - - LinSysRes.AddBlock(iPoint, Res_Conv); - - /*--- Viscous contribution to the residual at the wall ---*/ - - LinSysRes.SubtractBlock(iPoint, Res_Visc); - - /*--- Enforce the no-slip boundary condition in a strong way by - modifying the velocity-rows of the Jacobian (1 on the diagonal). ---*/ - - if (implicit) { - for (iVar = 1; iVar <= nDim; iVar++) { - total_index = iPoint*nVar+iVar; - Jacobian.DeleteValsRowi(total_index); - } - } - - } - } -} - -void CNSSolver::BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - - unsigned short iVar, jVar, iDim, jDim; - unsigned long iVertex, iPoint, Point_Normal, total_index; - - su2double *Normal, *Coord_i, *Coord_j, Area, dist_ij, theta2; - su2double Twall, dTdn, dTdrho, thermal_conductivity; - su2double thetax, thetay, thetaz, etax, etay, etaz, pix, piy, piz, factor; - su2double ProjGridVel, *GridVel, GridVel2, Pressure = 0.0, Density, Vel2; - su2double total_viscosity, div_vel, tau_vel[3] = {0.0,0.0,0.0}, UnitNormal[3] = {0.0,0.0,0.0}; - su2double laminar_viscosity, eddy_viscosity, Grad_Vel[3][3] = {{1.0, 0.0, 0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}}, - tau[3][3] = {{0.0, 0.0, 0.0},{0.0,0.0,0.0},{0.0,0.0,0.0}}, delta[3][3] = {{1.0, 0.0, 0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}}; - - su2double Prandtl_Lam = config->GetPrandtl_Lam(); - su2double Prandtl_Turb = config->GetPrandtl_Turb(); - su2double Gas_Constant = config->GetGas_ConstantND(); - su2double Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; - - bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); - - /*--- Identify the boundary ---*/ - - string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - - /*--- Retrieve the specified wall temperature from config - as well as the wall function treatment.---*/ - - Twall = config->GetIsothermal_Temperature(Marker_Tag)/config->GetTemperature_Ref(); - -// Wall_Function = config->GetWallFunction_Treatment(Marker_Tag); -// if (Wall_Function != NO_WALL_FUNCTION) { -// SU2_MPI::Error("Wall function treament not implemented yet", CURRENT_FUNCTION); -// } - - /*--- Loop over boundary points ---*/ - - for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - - iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - - if (geometry->node[iPoint]->GetDomain()) { - - /*--- If it is a customizable patch, retrieve the specified wall temperature. ---*/ - - if (config->GetMarker_All_PyCustom(val_marker)) Twall = geometry->GetCustomBoundaryTemperature(val_marker, iVertex); - - /*--- Compute dual-grid area and boundary normal ---*/ - - Normal = geometry->vertex[val_marker][iVertex]->GetNormal(); - - Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt (Area); - - for (iDim = 0; iDim < nDim; iDim++) - UnitNormal[iDim] = -Normal[iDim]/Area; - - /*--- Calculate useful quantities ---*/ - - theta2 = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - theta2 += UnitNormal[iDim]*UnitNormal[iDim]; - - /*--- Compute closest normal neighbor ---*/ - - Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); - - /*--- Get coordinates of i & nearest normal and compute distance ---*/ - - Coord_i = geometry->node[iPoint]->GetCoord(); - Coord_j = geometry->node[Point_Normal]->GetCoord(); - dist_ij = 0; - for (iDim = 0; iDim < nDim; iDim++) - dist_ij += (Coord_j[iDim]-Coord_i[iDim])*(Coord_j[iDim]-Coord_i[iDim]); - dist_ij = sqrt(dist_ij); - - /*--- Store the corrected velocity at the wall which will - be zero (v = 0), unless there is grid motion (v = u_wall)---*/ - - if (dynamic_grid) { - GridVel = geometry->node[iPoint]->GetGridVel(); - for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = GridVel[iDim]; - } - else { - for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = 0.0; - } - - /*--- Initialize the convective & viscous residuals to zero ---*/ - - for (iVar = 0; iVar < nVar; iVar++) { - Res_Conv[iVar] = 0.0; - Res_Visc[iVar] = 0.0; - } - - /*--- Set the residual, truncation error and velocity value on the boundary ---*/ - - nodes->SetVelocity_Old(iPoint,Vector); - - for (iDim = 0; iDim < nDim; iDim++) - LinSysRes.SetBlock_Zero(iPoint, iDim+1); - nodes->SetVel_ResTruncError_Zero(iPoint); - - /*--- Compute the normal gradient in temperature using Twall ---*/ - - dTdn = -(nodes->GetTemperature(Point_Normal) - Twall)/dist_ij; - - /*--- Get transport coefficients ---*/ - - laminar_viscosity = nodes->GetLaminarViscosity(iPoint); - eddy_viscosity = nodes->GetEddyViscosity(iPoint); - thermal_conductivity = Cp * ( laminar_viscosity/Prandtl_Lam + eddy_viscosity/Prandtl_Turb); - - // work in progress on real-gases... - //thermal_conductivity = nodes->GetThermalConductivity(iPoint); - //Cp = nodes->GetSpecificHeatCp(iPoint); - //thermal_conductivity += Cp*eddy_viscosity/Prandtl_Turb; - - /*--- Apply a weak boundary condition for the energy equation. - Compute the residual due to the prescribed heat flux. ---*/ - - Res_Visc[nDim+1] = thermal_conductivity * dTdn * Area; - - /*--- Calculate Jacobian for implicit time stepping ---*/ - - if (implicit) { - - for (iVar = 0; iVar < nVar; iVar ++) - for (jVar = 0; jVar < nVar; jVar ++) - Jacobian_i[iVar][jVar] = 0.0; - - /*--- Calculate useful quantities ---*/ - - Density = nodes->GetDensity(iPoint); - Vel2 = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - Vel2 += pow(nodes->GetVelocity(iPoint,iDim),2); - dTdrho = 1.0/Density * ( -Twall + (Gamma-1.0)/Gas_Constant*(Vel2/2.0) ); - - /*--- Enforce the no-slip boundary condition in a strong way ---*/ - - for (iVar = 1; iVar <= nDim; iVar++) { - total_index = iPoint*nVar+iVar; - Jacobian.DeleteValsRowi(total_index); - } - - /*--- Add contributions to the Jacobian from the weak enforcement of the energy equations ---*/ - - Jacobian_i[nDim+1][0] = -thermal_conductivity*theta2/dist_ij * dTdrho * Area; - Jacobian_i[nDim+1][nDim+1] = -thermal_conductivity*theta2/dist_ij * (Gamma-1.0)/(Gas_Constant*Density) * Area; - - /*--- Subtract the block from the Global Jacobian structure ---*/ - - Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - - } - - /*--- If the wall is moving, there are additional residual contributions - due to pressure (p v_wall.n) and shear stress (tau.v_wall.n). ---*/ - - if (dynamic_grid) { - - /*--- Get the grid velocity at the current boundary node ---*/ - - GridVel = geometry->node[iPoint]->GetGridVel(); - ProjGridVel = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - ProjGridVel += GridVel[iDim]*UnitNormal[iDim]*Area; - - /*--- Retrieve other primitive quantities and viscosities ---*/ - - Density = nodes->GetDensity(iPoint); - Pressure = nodes->GetPressure(iPoint); - laminar_viscosity = nodes->GetLaminarViscosity(iPoint); - eddy_viscosity = nodes->GetEddyViscosity(iPoint); - - total_viscosity = laminar_viscosity + eddy_viscosity; - - for (iDim = 0; iDim < nDim; iDim++) { - for (jDim = 0 ; jDim < nDim; jDim++) { - Grad_Vel[iDim][jDim] = nodes->GetGradient_Primitive(iPoint,iDim+1, jDim); - } - } - - /*--- Divergence of the velocity ---*/ - - div_vel = 0.0; for (iDim = 0 ; iDim < nDim; iDim++) div_vel += Grad_Vel[iDim][iDim]; - - /*--- Compute the viscous stress tensor ---*/ - - for (iDim = 0; iDim < nDim; iDim++) - for (jDim = 0; jDim < nDim; jDim++) { - tau[iDim][jDim] = total_viscosity*( Grad_Vel[jDim][iDim] + Grad_Vel[iDim][jDim] ) - TWO3*total_viscosity*div_vel*delta[iDim][jDim]; - } - - /*--- Dot product of the stress tensor with the grid velocity ---*/ - - for (iDim = 0 ; iDim < nDim; iDim++) { - tau_vel[iDim] = 0.0; - for (jDim = 0 ; jDim < nDim; jDim++) - tau_vel[iDim] += tau[iDim][jDim]*GridVel[jDim]; - } - - /*--- Compute the convective and viscous residuals (energy eqn.) ---*/ - - Res_Conv[nDim+1] = Pressure*ProjGridVel; - for (iDim = 0 ; iDim < nDim; iDim++) - Res_Visc[nDim+1] += tau_vel[iDim]*UnitNormal[iDim]*Area; - - /*--- Implicit Jacobian contributions due to moving walls ---*/ - - if (implicit) { - - /*--- Jacobian contribution related to the pressure term ---*/ - - GridVel2 = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - GridVel2 += GridVel[iDim]*GridVel[iDim]; - for (iVar = 0; iVar < nVar; iVar++) - for (jVar = 0; jVar < nVar; jVar++) - Jacobian_i[iVar][jVar] = 0.0; - - Jacobian_i[nDim+1][0] = 0.5*(Gamma-1.0)*GridVel2*ProjGridVel; - for (jDim = 0; jDim < nDim; jDim++) - Jacobian_i[nDim+1][jDim+1] = -(Gamma-1.0)*GridVel[jDim]*ProjGridVel; - Jacobian_i[nDim+1][nDim+1] = (Gamma-1.0)*ProjGridVel; - - /*--- Add the block to the Global Jacobian structure ---*/ - - Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - - /*--- Now the Jacobian contribution related to the shear stress ---*/ - - for (iVar = 0; iVar < nVar; iVar++) - for (jVar = 0; jVar < nVar; jVar++) - Jacobian_i[iVar][jVar] = 0.0; - - factor = total_viscosity*Area/(Density*dist_ij); - - if (nDim == 2) { - thetax = theta2 + UnitNormal[0]*UnitNormal[0]/3.0; - thetay = theta2 + UnitNormal[1]*UnitNormal[1]/3.0; - - etaz = UnitNormal[0]*UnitNormal[1]/3.0; - - pix = GridVel[0]*thetax + GridVel[1]*etaz; - piy = GridVel[0]*etaz + GridVel[1]*thetay; - - Jacobian_i[nDim+1][0] -= factor*(-pix*GridVel[0]+piy*GridVel[1]); - Jacobian_i[nDim+1][1] -= factor*pix; - Jacobian_i[nDim+1][2] -= factor*piy; - } - else { - thetax = theta2 + UnitNormal[0]*UnitNormal[0]/3.0; - thetay = theta2 + UnitNormal[1]*UnitNormal[1]/3.0; - thetaz = theta2 + UnitNormal[2]*UnitNormal[2]/3.0; - - etaz = UnitNormal[0]*UnitNormal[1]/3.0; - etax = UnitNormal[1]*UnitNormal[2]/3.0; - etay = UnitNormal[0]*UnitNormal[2]/3.0; - - pix = GridVel[0]*thetax + GridVel[1]*etaz + GridVel[2]*etay; - piy = GridVel[0]*etaz + GridVel[1]*thetay + GridVel[2]*etax; - piz = GridVel[0]*etay + GridVel[1]*etax + GridVel[2]*thetaz; - - Jacobian_i[nDim+1][0] -= factor*(-pix*GridVel[0]+piy*GridVel[1]+piz*GridVel[2]); - Jacobian_i[nDim+1][1] -= factor*pix; - Jacobian_i[nDim+1][2] -= factor*piy; - Jacobian_i[nDim+1][3] -= factor*piz; - } - - /*--- Subtract the block from the Global Jacobian structure ---*/ - - Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - } - - } - - /*--- Convective contribution to the residual at the wall ---*/ - - LinSysRes.AddBlock(iPoint, Res_Conv); - - /*--- Viscous contribution to the residual at the wall ---*/ - - LinSysRes.SubtractBlock(iPoint, Res_Visc); - - /*--- Enforce the no-slip boundary condition in a strong way by - modifying the velocity-rows of the Jacobian (1 on the diagonal). ---*/ - - if (implicit) { - for (iVar = 1; iVar <= nDim; iVar++) { - total_index = iPoint*nVar+iVar; - Jacobian.DeleteValsRowi(total_index); - } - } - - } - } -} - -void CNSSolver::SetRoe_Dissipation(CGeometry *geometry, CConfig *config){ - - unsigned long iPoint; - su2double wall_distance; - - unsigned short kind_roe_dissipation = config->GetKind_RoeLowDiss(); - - for (iPoint = 0; iPoint < nPoint; iPoint++){ - - if (kind_roe_dissipation == FD || kind_roe_dissipation == FD_DUCROS){ - - wall_distance = geometry->node[iPoint]->GetWall_Distance(); - - nodes->SetRoe_Dissipation_FD(iPoint,wall_distance); - - } else if (kind_roe_dissipation == NTS || kind_roe_dissipation == NTS_DUCROS) { - - const su2double delta = geometry->node[iPoint]->GetMaxLength(); - assert(delta > 0); // Delta must be initialized and non-negative - nodes->SetRoe_Dissipation_NTS(iPoint,delta, config->GetConst_DES()); - } - } -} - -void CNSSolver::BC_ConjugateHeat_Interface(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CConfig *config, unsigned short val_marker) { - - unsigned short iVar, jVar, iDim, jDim; - unsigned long iVertex, iPoint, Point_Normal, total_index; - - su2double *Normal, *Coord_i, *Coord_j, Area, dist_ij, theta2; - su2double Twall, There, dTdn, dTdrho, thermal_conductivity, Tconjugate, HF_FactorHere, HF_FactorConjugate; - su2double thetax, thetay, thetaz, etax, etay, etaz, pix, piy, piz, factor; - su2double ProjGridVel, *GridVel, GridVel2, Pressure = 0.0, Density, Vel2; - su2double total_viscosity, div_vel, tau_vel[3] = {0.0,0.0,0.0}, UnitNormal[3] = {0.0,0.0,0.0}; - su2double laminar_viscosity, eddy_viscosity, Grad_Vel[3][3] = {{1.0, 0.0, 0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}}, - tau[3][3] = {{0.0, 0.0, 0.0},{0.0,0.0,0.0},{0.0,0.0,0.0}}, delta[3][3] = {{1.0, 0.0, 0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}}; - - su2double Prandtl_Lam = config->GetPrandtl_Lam(); - su2double Prandtl_Turb = config->GetPrandtl_Turb(); - su2double Gas_Constant = config->GetGas_ConstantND(); - su2double Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; - - su2double Temperature_Ref = config->GetTemperature_Ref(); - - bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); - - /*--- Identify the boundary ---*/ - - string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - -// /*--- Retrieve the specified wall function treatment.---*/ -// -// Wall_Function = config->GetWallFunction_Treatment(Marker_Tag); -// if (Wall_Function != NO_WALL_FUNCTION) { -// SU2_MPI::Error("Wall function treament not implemented yet", CURRENT_FUNCTION); -// } - - /*--- Loop over boundary points ---*/ - - for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - - iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - - if (geometry->node[iPoint]->GetDomain()) { - - /*--- Compute dual-grid area and boundary normal ---*/ - - Normal = geometry->vertex[val_marker][iVertex]->GetNormal(); - - Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt (Area); - - for (iDim = 0; iDim < nDim; iDim++) - UnitNormal[iDim] = -Normal[iDim]/Area; - - /*--- Calculate useful quantities ---*/ - - theta2 = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - theta2 += UnitNormal[iDim]*UnitNormal[iDim]; - - /*--- Compute closest normal neighbor ---*/ - - Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); - - /*--- Get coordinates of i & nearest normal and compute distance ---*/ - - Coord_i = geometry->node[iPoint]->GetCoord(); - Coord_j = geometry->node[Point_Normal]->GetCoord(); - dist_ij = 0; - for (iDim = 0; iDim < nDim; iDim++) - dist_ij += (Coord_j[iDim]-Coord_i[iDim])*(Coord_j[iDim]-Coord_i[iDim]); - dist_ij = sqrt(dist_ij); - - /*--- Store the corrected velocity at the wall which will - be zero (v = 0), unless there is grid motion (v = u_wall)---*/ - - if (dynamic_grid) { - GridVel = geometry->node[iPoint]->GetGridVel(); - for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = GridVel[iDim]; - } - else { - for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = 0.0; - } - - /*--- Initialize the convective & viscous residuals to zero ---*/ - - for (iVar = 0; iVar < nVar; iVar++) { - Res_Conv[iVar] = 0.0; - Res_Visc[iVar] = 0.0; - } - - /*--- Set the residual, truncation error and velocity value on the boundary ---*/ - - nodes->SetVelocity_Old(iPoint,Vector); - - for (iDim = 0; iDim < nDim; iDim++) - LinSysRes.SetBlock_Zero(iPoint, iDim+1); - nodes->SetVel_ResTruncError_Zero(iPoint); - - /*--- Get transport coefficients ---*/ - - laminar_viscosity = nodes->GetLaminarViscosity(iPoint); - eddy_viscosity = nodes->GetEddyViscosity(iPoint); - thermal_conductivity = Cp * ( laminar_viscosity/Prandtl_Lam + eddy_viscosity/Prandtl_Turb); - - // work in progress on real-gases... - //thermal_conductivity = nodes->GetThermalConductivity(iPoint); - //Cp = nodes->GetSpecificHeatCp(iPoint); - //thermal_conductivity += Cp*eddy_viscosity/Prandtl_Turb; - - /*--- Compute the normal gradient in temperature using Twall ---*/ - - There = nodes->GetTemperature(Point_Normal); - Tconjugate = GetConjugateHeatVariable(val_marker, iVertex, 0)/Temperature_Ref; - - if ((config->GetKind_CHT_Coupling() == AVERAGED_TEMPERATURE_NEUMANN_HEATFLUX) || - (config->GetKind_CHT_Coupling() == AVERAGED_TEMPERATURE_ROBIN_HEATFLUX)) { - - /*--- Compute wall temperature from both temperatures ---*/ - - HF_FactorHere = thermal_conductivity*config->GetViscosity_Ref()/dist_ij; - HF_FactorConjugate = GetConjugateHeatVariable(val_marker, iVertex, 2); - - Twall = (There*HF_FactorHere + Tconjugate*HF_FactorConjugate)/(HF_FactorHere + HF_FactorConjugate); - dTdn = -(There - Twall)/dist_ij; - } - else if ((config->GetKind_CHT_Coupling() == DIRECT_TEMPERATURE_NEUMANN_HEATFLUX) || - (config->GetKind_CHT_Coupling() == DIRECT_TEMPERATURE_ROBIN_HEATFLUX)) { - - /*--- (Directly) Set wall temperature to conjugate temperature. ---*/ - - Twall = Tconjugate; - dTdn = -(There - Twall)/dist_ij; - } - else { - - SU2_MPI::Error(string("Unknown CHT coupling method."), CURRENT_FUNCTION); - } - - /*--- Apply a weak boundary condition for the energy equation. - Compute the residual due to the prescribed heat flux. ---*/ - - Res_Visc[nDim+1] = thermal_conductivity * dTdn * Area; - - /*--- Calculate Jacobian for implicit time stepping ---*/ - - if (implicit) { - - for (iVar = 0; iVar < nVar; iVar ++) - for (jVar = 0; jVar < nVar; jVar ++) - Jacobian_i[iVar][jVar] = 0.0; - - /*--- Calculate useful quantities ---*/ - - Density = nodes->GetDensity(iPoint); - Vel2 = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - Vel2 += pow(nodes->GetVelocity(iPoint,iDim),2); - dTdrho = 1.0/Density * ( -Twall + (Gamma-1.0)/Gas_Constant*(Vel2/2.0) ); - - /*--- Enforce the no-slip boundary condition in a strong way ---*/ - - for (iVar = 1; iVar <= nDim; iVar++) { - total_index = iPoint*nVar+iVar; - Jacobian.DeleteValsRowi(total_index); - } - - /*--- Add contributions to the Jacobian from the weak enforcement of the energy equations ---*/ - - Jacobian_i[nDim+1][0] = -thermal_conductivity*theta2/dist_ij * dTdrho * Area; - Jacobian_i[nDim+1][nDim+1] = -thermal_conductivity*theta2/dist_ij * (Gamma-1.0)/(Gas_Constant*Density) * Area; - - /*--- Subtract the block from the Global Jacobian structure ---*/ - - Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - - } - - /*--- If the wall is moving, there are additional residual contributions - due to pressure (p v_wall.n) and shear stress (tau.v_wall.n). ---*/ - - if (dynamic_grid) { - - /*--- Get the grid velocity at the current boundary node ---*/ - - GridVel = geometry->node[iPoint]->GetGridVel(); - ProjGridVel = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - ProjGridVel += GridVel[iDim]*UnitNormal[iDim]*Area; - - /*--- Retrieve other primitive quantities and viscosities ---*/ - - Density = nodes->GetDensity(iPoint); - Pressure = nodes->GetPressure(iPoint); - laminar_viscosity = nodes->GetLaminarViscosity(iPoint); - eddy_viscosity = nodes->GetEddyViscosity(iPoint); - - total_viscosity = laminar_viscosity + eddy_viscosity; - - for (iDim = 0; iDim < nDim; iDim++) { - for (jDim = 0 ; jDim < nDim; jDim++) { - Grad_Vel[iDim][jDim] = nodes->GetGradient_Primitive(iPoint,iDim+1, jDim); - } - } - - /*--- Divergence of the velocity ---*/ - - div_vel = 0.0; for (iDim = 0 ; iDim < nDim; iDim++) div_vel += Grad_Vel[iDim][iDim]; - - /*--- Compute the viscous stress tensor ---*/ - - for (iDim = 0; iDim < nDim; iDim++) - for (jDim = 0; jDim < nDim; jDim++) { - tau[iDim][jDim] = total_viscosity*( Grad_Vel[jDim][iDim] + Grad_Vel[iDim][jDim] ) - TWO3*total_viscosity*div_vel*delta[iDim][jDim]; - } - - /*--- Dot product of the stress tensor with the grid velocity ---*/ - - for (iDim = 0 ; iDim < nDim; iDim++) { - tau_vel[iDim] = 0.0; - for (jDim = 0 ; jDim < nDim; jDim++) - tau_vel[iDim] += tau[iDim][jDim]*GridVel[jDim]; - } - - /*--- Compute the convective and viscous residuals (energy eqn.) ---*/ - - Res_Conv[nDim+1] = Pressure*ProjGridVel; - for (iDim = 0 ; iDim < nDim; iDim++) - Res_Visc[nDim+1] += tau_vel[iDim]*UnitNormal[iDim]*Area; - - /*--- Implicit Jacobian contributions due to moving walls ---*/ - - if (implicit) { - - /*--- Jacobian contribution related to the pressure term ---*/ - - GridVel2 = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - GridVel2 += GridVel[iDim]*GridVel[iDim]; - for (iVar = 0; iVar < nVar; iVar++) - for (jVar = 0; jVar < nVar; jVar++) - Jacobian_i[iVar][jVar] = 0.0; - - Jacobian_i[nDim+1][0] = 0.5*(Gamma-1.0)*GridVel2*ProjGridVel; - for (jDim = 0; jDim < nDim; jDim++) - Jacobian_i[nDim+1][jDim+1] = -(Gamma-1.0)*GridVel[jDim]*ProjGridVel; - Jacobian_i[nDim+1][nDim+1] = (Gamma-1.0)*ProjGridVel; - - /*--- Add the block to the Global Jacobian structure ---*/ - - Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - - /*--- Now the Jacobian contribution related to the shear stress ---*/ - - for (iVar = 0; iVar < nVar; iVar++) - for (jVar = 0; jVar < nVar; jVar++) - Jacobian_i[iVar][jVar] = 0.0; - - factor = total_viscosity*Area/(Density*dist_ij); - - if (nDim == 2) { - thetax = theta2 + UnitNormal[0]*UnitNormal[0]/3.0; - thetay = theta2 + UnitNormal[1]*UnitNormal[1]/3.0; - - etaz = UnitNormal[0]*UnitNormal[1]/3.0; - - pix = GridVel[0]*thetax + GridVel[1]*etaz; - piy = GridVel[0]*etaz + GridVel[1]*thetay; - - Jacobian_i[nDim+1][0] -= factor*(-pix*GridVel[0]+piy*GridVel[1]); - Jacobian_i[nDim+1][1] -= factor*pix; - Jacobian_i[nDim+1][2] -= factor*piy; - } - else { - thetax = theta2 + UnitNormal[0]*UnitNormal[0]/3.0; - thetay = theta2 + UnitNormal[1]*UnitNormal[1]/3.0; - thetaz = theta2 + UnitNormal[2]*UnitNormal[2]/3.0; - - etaz = UnitNormal[0]*UnitNormal[1]/3.0; - etax = UnitNormal[1]*UnitNormal[2]/3.0; - etay = UnitNormal[0]*UnitNormal[2]/3.0; - - pix = GridVel[0]*thetax + GridVel[1]*etaz + GridVel[2]*etay; - piy = GridVel[0]*etaz + GridVel[1]*thetay + GridVel[2]*etax; - piz = GridVel[0]*etay + GridVel[1]*etax + GridVel[2]*thetaz; - - Jacobian_i[nDim+1][0] -= factor*(-pix*GridVel[0]+piy*GridVel[1]+piz*GridVel[2]); - Jacobian_i[nDim+1][1] -= factor*pix; - Jacobian_i[nDim+1][2] -= factor*piy; - Jacobian_i[nDim+1][3] -= factor*piz; - } - - /*--- Subtract the block from the Global Jacobian structure ---*/ - - Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - } - - } - - /*--- Convective contribution to the residual at the wall ---*/ - - LinSysRes.AddBlock(iPoint, Res_Conv); - - /*--- Viscous contribution to the residual at the wall ---*/ - - LinSysRes.SubtractBlock(iPoint, Res_Visc); - - /*--- Enforce the no-slip boundary condition in a strong way by - modifying the velocity-rows of the Jacobian (1 on the diagonal). ---*/ - - if (implicit) { - for (iVar = 1; iVar <= nDim; iVar++) { - total_index = iPoint*nVar+iVar; - Jacobian.DeleteValsRowi(total_index); - } - } - } - } -} - -void CNSSolver::SetTauWall_WF(CGeometry *geometry, CSolver **solver_container, CConfig *config) { - - unsigned short iDim, jDim, iMarker; - unsigned long iVertex, iPoint, Point_Normal, counter; - - su2double Area, div_vel, UnitNormal[3], *Normal; - su2double **grad_primvar, tau[3][3]; - - su2double Vel[3] = {0.0, 0.0, 0.0}, VelNormal, VelTang[3], VelTangMod, VelInfMod, WallDist[3], WallDistMod; - su2double T_Normal, P_Normal; - su2double Density_Wall, T_Wall, P_Wall, Lam_Visc_Wall, Tau_Wall = 0.0, Tau_Wall_Old = 0.0; - su2double *Coord, *Coord_Normal; - su2double diff, Delta; - su2double U_Tau, U_Plus, Gam, Beta, Phi, Q, Y_Plus_White, Y_Plus; - su2double TauElem[3], TauNormal, TauTangent[3], WallShearStress; - su2double Gas_Constant = config->GetGas_ConstantND(); - su2double Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; - - unsigned short max_iter = 10; - su2double tol = 1e-6; - - /*--- Get the freestream velocity magnitude for non-dim. purposes ---*/ - - su2double *VelInf = config->GetVelocity_FreeStreamND(); - VelInfMod = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - VelInfMod += VelInf[iDim]; - VelInfMod = sqrt(VelInfMod); - - /*--- Compute the recovery factor ---*/ - // Double-check: laminar or turbulent Pr for this? - su2double Recovery = pow(config->GetPrandtl_Lam(), (1.0/3.0)); - - /*--- Typical constants from boundary layer theory ---*/ - - su2double kappa = 0.4; - su2double B = 5.5; - - for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { - - if ((config->GetMarker_All_KindBC(iMarker) == HEAT_FLUX) || - (config->GetMarker_All_KindBC(iMarker) == ISOTHERMAL) ) { - - /*--- Identify the boundary by string name ---*/ - - string Marker_Tag = config->GetMarker_All_TagBound(iMarker); - - /*--- Get the specified wall heat flux from config ---*/ - - // Wall_HeatFlux = config->GetWall_HeatFlux(Marker_Tag); - - /*--- Loop over all of the vertices on this boundary marker ---*/ - - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - - iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - Point_Normal = geometry->vertex[iMarker][iVertex]->GetNormal_Neighbor(); - - /*--- Check if the node belongs to the domain (i.e, not a halo node) - and the neighbor is not part of the physical boundary ---*/ - - if (geometry->node[iPoint]->GetDomain()) { - - /*--- Get coordinates of the current vertex and nearest normal point ---*/ - - Coord = geometry->node[iPoint]->GetCoord(); - Coord_Normal = geometry->node[Point_Normal]->GetCoord(); - - /*--- Compute dual-grid area and boundary normal ---*/ - - Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - - Area = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - Area += Normal[iDim]*Normal[iDim]; - Area = sqrt (Area); - - for (iDim = 0; iDim < nDim; iDim++) - UnitNormal[iDim] = -Normal[iDim]/Area; - - /*--- Get the velocity, pressure, and temperature at the nearest - (normal) interior point. ---*/ - - for (iDim = 0; iDim < nDim; iDim++) - Vel[iDim] = nodes->GetVelocity(Point_Normal,iDim); - P_Normal = nodes->GetPressure(Point_Normal); - T_Normal = nodes->GetTemperature(Point_Normal); - - /*--- Compute the wall-parallel velocity at first point off the wall ---*/ - - VelNormal = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - VelNormal += Vel[iDim] * UnitNormal[iDim]; - for (iDim = 0; iDim < nDim; iDim++) - VelTang[iDim] = Vel[iDim] - VelNormal*UnitNormal[iDim]; - - VelTangMod = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - VelTangMod += VelTang[iDim]*VelTang[iDim]; - VelTangMod = sqrt(VelTangMod); - - /*--- Compute normal distance of the interior point from the wall ---*/ - - for (iDim = 0; iDim < nDim; iDim++) - WallDist[iDim] = (Coord[iDim] - Coord_Normal[iDim]); - - WallDistMod = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - WallDistMod += WallDist[iDim]*WallDist[iDim]; - WallDistMod = sqrt(WallDistMod); - - /*--- Compute mach number ---*/ - - // M_Normal = VelTangMod / sqrt(Gamma * Gas_Constant * T_Normal); - - /*--- Compute the wall temperature using the Crocco-Buseman equation ---*/ - - //T_Wall = T_Normal * (1.0 + 0.5*Gamma_Minus_One*Recovery*M_Normal*M_Normal); - T_Wall = T_Normal + Recovery*pow(VelTangMod,2.0)/(2.0*Cp); - - /*--- Extrapolate the pressure from the interior & compute the - wall density using the equation of state ---*/ - - P_Wall = P_Normal; - Density_Wall = P_Wall/(Gas_Constant*T_Wall); - - /*--- Compute the shear stress at the wall in the regular fashion - by using the stress tensor on the surface ---*/ - - Lam_Visc_Wall = nodes->GetLaminarViscosity(iPoint); - grad_primvar = nodes->GetGradient_Primitive(iPoint); - - div_vel = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - div_vel += grad_primvar[iDim+1][iDim]; - - for (iDim = 0; iDim < nDim; iDim++) { - for (jDim = 0 ; jDim < nDim; jDim++) { - Delta = 0.0; if (iDim == jDim) Delta = 1.0; - tau[iDim][jDim] = Lam_Visc_Wall*( grad_primvar[jDim+1][iDim] - + grad_primvar[iDim+1][jDim]) - - TWO3*Lam_Visc_Wall*div_vel*Delta; - } - TauElem[iDim] = 0.0; - for (jDim = 0; jDim < nDim; jDim++) - TauElem[iDim] += tau[iDim][jDim]*UnitNormal[jDim]; - } - - /*--- Compute wall shear stress as the magnitude of the wall-tangential - component of the shear stress tensor---*/ - - TauNormal = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - TauNormal += TauElem[iDim] * UnitNormal[iDim]; - - for (iDim = 0; iDim < nDim; iDim++) - TauTangent[iDim] = TauElem[iDim] - TauNormal * UnitNormal[iDim]; - - WallShearStress = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - WallShearStress += TauTangent[iDim]*TauTangent[iDim]; - WallShearStress = sqrt(WallShearStress); - - /*--- Calculate the quantities from boundary layer theory and - iteratively solve for a new wall shear stress. Use the current wall - shear stress as a starting guess for the wall function. ---*/ - - Tau_Wall_Old = WallShearStress; - counter = 0; diff = 1.0; - - while (diff > tol) { - - /*--- Friction velocity and u+ ---*/ - - U_Tau = sqrt(Tau_Wall_Old/Density_Wall); - U_Plus = VelTangMod/U_Tau; - - /*--- Gamma, Beta, Q, and Phi, defined by Nichols & Nelson (2004) ---*/ - - Gam = Recovery*U_Tau*U_Tau/(2.0*Cp*T_Wall); - Beta = 0.0; // For adiabatic flows only - Q = sqrt(Beta*Beta + 4.0*Gam); - Phi = asin(-1.0*Beta/Q); - - /*--- Y+ defined by White & Christoph (compressibility and heat transfer) negative value for (2.0*Gam*U_Plus - Beta)/Q ---*/ - - Y_Plus_White = exp((kappa/sqrt(Gam))*(asin((2.0*Gam*U_Plus - Beta)/Q) - Phi))*exp(-1.0*kappa*B); - - /*--- Spalding's universal form for the BL velocity with the - outer velocity form of White & Christoph above. ---*/ - - Y_Plus = U_Plus + Y_Plus_White - (exp(-1.0*kappa*B)* - (1.0 + kappa*U_Plus + kappa*kappa*U_Plus*U_Plus/2.0 + - kappa*kappa*kappa*U_Plus*U_Plus*U_Plus/6.0)); - - /*--- Calculate an updated value for the wall shear stress - using the y+ value, the definition of y+, and the definition of - the friction velocity. ---*/ - - Tau_Wall = (1.0/Density_Wall)*pow(Y_Plus*Lam_Visc_Wall/WallDistMod,2.0); - - /*--- Difference between the old and new Tau. Update old value. ---*/ - - diff = fabs(Tau_Wall-Tau_Wall_Old); - Tau_Wall_Old += 0.25*(Tau_Wall-Tau_Wall_Old); - - counter++; - if (counter > max_iter) { - cout << "WARNING: Tau_Wall evaluation has not converged in solver_direct_mean.cpp" << endl; - cout << Tau_Wall_Old << " " << Tau_Wall << " " << diff << endl; - break; - } - - } - - - /*--- Store this value for the wall shear stress at the node. ---*/ - - nodes->SetTauWall(iPoint,Tau_Wall); - - - } - - } - - } - } - -} - diff --git a/SU2_CFD/src/solvers/CFEASolver.cpp b/SU2_CFD/src/solvers/CFEASolver.cpp index 239f00744ca0..3c64d8ba244c 100644 --- a/SU2_CFD/src/solvers/CFEASolver.cpp +++ b/SU2_CFD/src/solvers/CFEASolver.cpp @@ -93,10 +93,8 @@ CFEASolver::CFEASolver(bool mesh_deform_mode) : CSolver(mesh_deform_mode) { WAitken_Dyn_tn1 = 0.0; loadIncrement = 1.0; - element_container = nullptr; - unsigned short iTerm; element_container = new CElement** [MAX_TERMS](); - for (iTerm = 0; iTerm < MAX_TERMS; iTerm++) + for (unsigned short iTerm = 0; iTerm < MAX_TERMS; iTerm++) element_container[iTerm] = new CElement* [MAX_FE_KINDS*omp_get_max_threads()](); nodes = nullptr; @@ -112,9 +110,7 @@ CFEASolver::CFEASolver(bool mesh_deform_mode) : CSolver(mesh_deform_mode) { CFEASolver::CFEASolver(CGeometry *geometry, CConfig *config) : CSolver() { - unsigned long iPoint; unsigned short iVar; - unsigned short iTerm; bool dynamic = (config->GetTime_Domain()); @@ -137,7 +133,7 @@ CFEASolver::CFEASolver(CGeometry *geometry, CConfig *config) : CSolver() { /*--- First level: different possible terms of the equations ---*/ element_container = new CElement** [MAX_TERMS](); - for (iTerm = 0; iTerm < MAX_TERMS; iTerm++) + for (unsigned short iTerm = 0; iTerm < MAX_TERMS; iTerm++) element_container[iTerm] = new CElement* [MAX_FE_KINDS*omp_get_max_threads()](); SU2_OMP_PARALLEL @@ -212,7 +208,7 @@ CFEASolver::CFEASolver(CGeometry *geometry, CConfig *config) : CSolver() { /*--- Set which points are vertices and allocate boundary data. ---*/ - for (iPoint = 0; iPoint < nPoint; iPoint++) + for (unsigned long iPoint = 0; iPoint < nPoint; iPoint++) for (unsigned short iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { long iVertex = geometry->node[iPoint]->GetVertex(iMarker); if (iVertex >= 0) { diff --git a/SU2_CFD/src/solver_direct_mean_fem.cpp b/SU2_CFD/src/solvers/CFEM_DG_EulerSolver.cpp similarity index 56% rename from SU2_CFD/src/solver_direct_mean_fem.cpp rename to SU2_CFD/src/solvers/CFEM_DG_EulerSolver.cpp index 1bf781df82bb..e07b9f038749 100644 --- a/SU2_CFD/src/solver_direct_mean_fem.cpp +++ b/SU2_CFD/src/solvers/CFEM_DG_EulerSolver.cpp @@ -1,12 +1,12 @@ /*! - * \file solution_direct_mean_fem.cpp - * \brief Main subroutines for solving finite element flow problems (Euler, Navier-Stokes, etc.). + * \file CFEM_DG_EulerSolver.cpp + * \brief Main subroutines for solving finite element Euler flow problems * \author J. Alonso, E. van der Weide, T. Economon * \version 7.0.0 "Blackbird" * * SU2 Project Website: https://su2code.github.io * - * The SU2 Project is maintained by the SU2 Foundation + * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) @@ -26,8 +26,8 @@ */ -#include "../include/solver_structure.hpp" -#include "../../Common/include/toolboxes/printing_toolbox.hpp" +#include "../../include/solvers/CFEM_DG_EulerSolver.hpp" +#include "../../../Common/include/toolboxes/printing_toolbox.hpp" #define SIZE_ARR_NORM 8 @@ -62,7 +62,7 @@ CFEM_DG_EulerSolver::CFEM_DG_EulerSolver(void) : CSolver() { /*--- Initialize the pointer for performing the BLAS functionalities. ---*/ blasFunctions = NULL; - + } CFEM_DG_EulerSolver::CFEM_DG_EulerSolver(CConfig *config, unsigned short val_nDim, unsigned short iMesh) : CSolver() { @@ -108,7 +108,7 @@ CFEM_DG_EulerSolver::CFEM_DG_EulerSolver(CConfig *config, unsigned short val_nDi /*--- Initialize the pointer for performing the BLAS functionalities. ---*/ blasFunctions = NULL; - + } CFEM_DG_EulerSolver::CFEM_DG_EulerSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh) : CSolver() { @@ -257,7 +257,7 @@ CFEM_DG_EulerSolver::CFEM_DG_EulerSolver(CGeometry *geometry, CConfig *config, u sizeWorkArray = max(sizeWorkArray, sizePredictorADER); } - + /*--- Perform the non-dimensionalization for the flow equations using the specified reference values. ---*/ SetNondimensionalization(config, iMesh, true); @@ -267,9 +267,9 @@ CFEM_DG_EulerSolver::CFEM_DG_EulerSolver(CGeometry *geometry, CConfig *config, u option from the available library of verification solutions. Note that this is done after SetNondim(), as problem-specific initial parameters are needed by the solution constructors. ---*/ - + SetVerificationSolution(nDim, nVar, config); - + /*--- Define some auxiliary vectors related to the residual ---*/ Residual_RMS = new su2double[nVar]; for(unsigned short iVar=0; iVarGetKind_ViscosityModel()){ case CONSTANT_VISCOSITY: ModelTable << "CONSTANT_VISCOSITY"; @@ -1150,9 +1150,9 @@ void CFEM_DG_EulerSolver::SetNondimensionalization(CConfig *config, Unit.str(""); NonDimTable.PrintFooter(); break; - + case SUTHERLAND: - ModelTable << "SUTHERLAND"; + ModelTable << "SUTHERLAND"; if (config->GetSystemMeasurements() == SI) Unit << "N.s/m^2"; else if (config->GetSystemMeasurements() == US) Unit << "lbf.s/ft^2"; NonDimTable << "Ref. Viscosity" << config->GetMu_Ref() << config->GetViscosity_Ref() << Unit.str() << config->GetMu_RefND(); @@ -1167,26 +1167,26 @@ void CFEM_DG_EulerSolver::SetNondimensionalization(CConfig *config, Unit.str(""); NonDimTable.PrintFooter(); break; - + } switch(config->GetKind_ConductivityModel()){ case CONSTANT_PRANDTL: ModelTable << "CONSTANT_PRANDTL"; - NonDimTable << "Prandtl (Lam.)" << "-" << "-" << "-" << config->GetPrandtl_Lam(); + NonDimTable << "Prandtl (Lam.)" << "-" << "-" << "-" << config->GetPrandtl_Lam(); Unit.str(""); - NonDimTable << "Prandtl (Turb.)" << "-" << "-" << "-" << config->GetPrandtl_Turb(); + NonDimTable << "Prandtl (Turb.)" << "-" << "-" << "-" << config->GetPrandtl_Turb(); Unit.str(""); NonDimTable.PrintFooter(); break; - + case CONSTANT_CONDUCTIVITY: ModelTable << "CONSTANT_CONDUCTIVITY"; Unit << "W/m^2.K"; - NonDimTable << "Molecular Cond." << config->GetKt_Constant() << config->GetKt_Constant()/config->GetKt_ConstantND() << Unit.str() << config->GetKt_ConstantND(); + NonDimTable << "Molecular Cond." << config->GetKt_Constant() << config->GetKt_Constant()/config->GetKt_ConstantND() << Unit.str() << config->GetKt_ConstantND(); Unit.str(""); NonDimTable.PrintFooter(); break; - + } } else { ModelTable << "-" << "-"; @@ -1200,7 +1200,7 @@ void CFEM_DG_EulerSolver::SetNondimensionalization(CConfig *config, else if (config->GetSystemMeasurements() == US) Unit << "lbf.ft/slug.R"; NonDimTable << "Spec. Heat Ratio" << "-" << "-" << "-" << Gamma; Unit.str(""); - + switch(config->GetKind_FluidModel()){ case STANDARD_AIR: ModelTable << "STANDARD_AIR"; @@ -1215,7 +1215,7 @@ void CFEM_DG_EulerSolver::SetNondimensionalization(CConfig *config, ModelTable << "PR_GAS"; break; } - + if (config->GetKind_FluidModel() == VW_GAS || config->GetKind_FluidModel() == PR_GAS){ NonDimTable << "Critical Pressure" << config->GetPressure_Critical() << config->GetPressure_Ref() << Unit.str() << config->GetPressure_Critical() /config->GetPressure_Ref(); Unit.str(""); @@ -1224,11 +1224,11 @@ void CFEM_DG_EulerSolver::SetNondimensionalization(CConfig *config, Unit.str(""); } NonDimTable.PrintFooter(); - + NonDimTableOut <<"-- Initial and free-stream conditions:"<< endl; - + NonDimTable.PrintHeader(); - + if (config->GetSystemMeasurements() == SI) Unit << "Pa"; else if (config->GetSystemMeasurements() == US) Unit << "psf"; NonDimTable << "Static Pressure" << config->GetPressure_FreeStream() << config->GetPressure_Ref() << Unit.str() << config->GetPressure_FreeStreamND(); @@ -1254,7 +1254,7 @@ void CFEM_DG_EulerSolver::SetNondimensionalization(CConfig *config, } NonDimTable << "Velocity Magnitude" << config->GetModVel_FreeStream() << config->GetVelocity_Ref() << Unit.str() << config->GetModVel_FreeStreamND(); Unit.str(""); - + if (viscous) { NonDimTable.PrintFooter(); if (config->GetSystemMeasurements() == SI) Unit << "N.s/m^2"; @@ -1276,17 +1276,17 @@ void CFEM_DG_EulerSolver::SetNondimensionalization(CConfig *config, Unit.str(""); } } - + NonDimTable.PrintFooter(); NonDimTable << "Mach Number" << "-" << "-" << "-" << config->GetMach(); if (viscous) { - NonDimTable << "Reynolds Number" << "-" << "-" << "-" << config->GetReynolds(); + NonDimTable << "Reynolds Number" << "-" << "-" << "-" << config->GetReynolds(); } NonDimTable.PrintFooter(); ModelTable.PrintFooter(); - + if (unsteady){ - NonDimTableOut << "-- Unsteady conditions" << endl; + NonDimTableOut << "-- Unsteady conditions" << endl; NonDimTable.PrintHeader(); NonDimTable << "Total Time" << config->GetMax_Time() << config->GetTime_Ref() << "s" << config->GetMax_Time()/config->GetTime_Ref(); Unit.str(""); @@ -1294,10 +1294,10 @@ void CFEM_DG_EulerSolver::SetNondimensionalization(CConfig *config, Unit.str(""); NonDimTable.PrintFooter(); } - + cout << ModelTableOut.str(); cout << NonDimTableOut.str(); - + } } @@ -1870,7 +1870,7 @@ void CFEM_DG_EulerSolver::SetUpTaskList(CConfig *config) { interpolOwnedElem[level] = true; if(nMatchingInternalFacesLocalElem[level+1] > nMatchingInternalFacesLocalElem[level]) interpolOwnedElem[level] = true; - if(nMatchingInternalFacesWithHaloElem[level+1] > nMatchingInternalFacesWithHaloElem[level]) + if(nMatchingInternalFacesWithHaloElem[level+1] > nMatchingInternalFacesWithHaloElem[level]) interpolOwnedElem[level] = true; if( BCPresent[level] ) interpolOwnedElem[level] = true; @@ -3115,10 +3115,10 @@ void CFEM_DG_EulerSolver::SetInitialCondition(CGeometry **geometry, CSolver ***s /* Loop over the owned elements. */ for(unsigned long i=0; iGetTime_Marching() == TIME_STEPPING; @@ -3734,7 +3734,7 @@ void CFEM_DG_EulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_con if (time_stepping) { for(unsigned long l=0; lSetDelta_UnstTimeND(Min_Delta_Time); } } @@ -4576,9 +4576,9 @@ void CFEM_DG_EulerSolver::ADER_DG_PredictorStep(CConfig *config, dSol[indDSol+2] += coefADER*resInt[indResInt+2]; dSol[indDSol+3] += coefADER*resInt[indResInt+3]; dSol[indDSol+4] += coefADER*resInt[indResInt+4]; - } - } - } + } + } + } break; } @@ -4912,7 +4912,7 @@ void CFEM_DG_EulerSolver::ADER_DG_AliasedPredictorResidual_2D(CConfig divFluxInt[1] -= weightJac*sourceMan[1]; divFluxInt[2] -= weightJac*sourceMan[2]; divFluxInt[3] -= weightJac*sourceMan[3]; - } + } } } } @@ -5193,7 +5193,7 @@ void CFEM_DG_EulerSolver::ADER_DG_AliasedPredictorResidual_3D(CConfig divFluxInt[2] -= weightJac*sourceMan[2]; divFluxInt[3] -= weightJac*sourceMan[3]; divFluxInt[4] -= weightJac*sourceMan[4]; - } + } } } } @@ -5402,7 +5402,7 @@ void CFEM_DG_EulerSolver::ADER_DG_NonAliasedPredictorResidual_2D(CConfig divFluxInt[1] -= weightJac*sourceMan[1]; divFluxInt[2] -= weightJac*sourceMan[2]; divFluxInt[3] -= weightJac*sourceMan[3]; - } + } } } } @@ -5638,7 +5638,7 @@ void CFEM_DG_EulerSolver::ADER_DG_NonAliasedPredictorResidual_3D(CConfig divFluxInt[2] -= weightJac*sourceMan[2]; divFluxInt[3] -= weightJac*sourceMan[3]; divFluxInt[4] -= weightJac*sourceMan[4]; - } + } } } } @@ -5764,7 +5764,7 @@ void CFEM_DG_EulerSolver::Volume_Residual(CConfig *config, /*--- Get the physical time for MMS if necessary. ---*/ su2double time = 0.0; if (config->GetTime_Marching()) time = config->GetPhysicalTime(); - + /* Determine the number of elements that are treated simultaneously in the matrix products to obtain good gemm performance. */ const unsigned short nPadInput = config->GetSizeMatMulPadding(); @@ -6064,21 +6064,21 @@ void CFEM_DG_EulerSolver::Volume_Residual(CConfig *config, const unsigned long lInd = l + ll; for(unsigned short i=0; iGetMMSSourceTerm(coor, time, sourceMan); - + /*--- Subtract the source term of the manufactured solution, multiplied by the appropriate weight, from the possibly earlier computed source term. It is subtracted in order to be consistent with @@ -6090,7 +6090,7 @@ void CFEM_DG_EulerSolver::Volume_Residual(CConfig *config, } } } - + /*------------------------------------------------------------------------*/ /*--- Step 3: Compute the contribution to the residuals from the ---*/ /*--- integration over the volume element. ---*/ @@ -7326,7 +7326,7 @@ void CFEM_DG_EulerSolver::ComputeVerificationError(CGeometry *geometry, && (config->GetTimeIter()!= 0)) || (config->GetTimeIter() == 1)); if( !write_heads ) return; - + /*--- Check if there actually is an exact solution for this verification case, if computed at all. ---*/ if (VerificationSolution) { @@ -7346,7 +7346,7 @@ void CFEM_DG_EulerSolver::ComputeVerificationError(CGeometry *geometry, DOFs, because the coordinates of the DOFs are only known in the volume element class. ---*/ for(unsigned long l=0; lGetTime_Marching()) time = config->GetPhysicalTime(); - + /*--- Loop over the requested range of surface faces. Multiple faces are treated simultaneously to improve the performance of the matrix multiplications. As a consequence, the update of the counter l @@ -8712,13 +8712,13 @@ void CFEM_DG_EulerSolver::BC_Custom(CConfig *config, GetBCState to determine the actual boundary state. */ const su2double *coor = surfElem[ll+l].coorIntegrationPoints.data() + i*nDim; su2double *UR = solIntR + NPad*i + ll*nVar; - + VerificationSolution->GetBCState(coor, time, UR); } } } else { - + /* The user must specify the custom BC's here. */ SU2_MPI::Error("Implement customized boundary conditions here.", CURRENT_FUNCTION); } @@ -9410,7 +9410,7 @@ void CFEM_DG_EulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, C /*--- Skip coordinates ---*/ unsigned short skipVars = geometry[MESH_0]->GetnDim(); - + restart_filename = config->GetFilename(restart_filename, "", val_iter); /*--- Read the restart data from either an ASCII or binary SU2 file. ---*/ @@ -9513,6549 +9513,3 @@ void CFEM_DG_EulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, C Restart_Vars = NULL; Restart_Data = NULL; } - -CFEM_DG_NSSolver::CFEM_DG_NSSolver(void) : CFEM_DG_EulerSolver() { - - /*--- Basic array initialization ---*/ - CD_Visc = NULL; CL_Visc = NULL; CSF_Visc = NULL; CEff_Visc = NULL; - CMx_Visc = NULL; CMy_Visc = NULL; CMz_Visc = NULL; - CFx_Visc = NULL; CFy_Visc = NULL; CFz_Visc = NULL; - - /*--- Surface-based array initialization ---*/ - Surface_CL_Visc = NULL; Surface_CD_Visc = NULL; Surface_CSF_Visc = NULL; Surface_CEff_Visc = NULL; - Surface_CFx_Visc = NULL; Surface_CFy_Visc = NULL; Surface_CFz_Visc = NULL; - Surface_CMx_Visc = NULL; Surface_CMy_Visc = NULL; Surface_CMz_Visc = NULL; - MaxHeatFlux_Visc = NULL; Heat_Visc = NULL; - - /*--- Set the SGS model to NULL and indicate that no SGS model is used. ---*/ - SGSModel = NULL; - SGSModelUsed = false; -} - -CFEM_DG_NSSolver::CFEM_DG_NSSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh) - : CFEM_DG_EulerSolver(geometry, config, iMesh) { - - /*--- Array initialization ---*/ - CD_Visc = NULL; CL_Visc = NULL; CSF_Visc = NULL; CEff_Visc = NULL; - CMx_Visc = NULL; CMy_Visc = NULL; CMz_Visc = NULL; - CFx_Visc = NULL; CFy_Visc = NULL; CFz_Visc = NULL; - - Surface_CL_Visc = NULL; Surface_CD_Visc = NULL; Surface_CSF_Visc = NULL; Surface_CEff_Visc = NULL; - Surface_CFx_Visc = NULL; Surface_CFy_Visc = NULL; Surface_CFz_Visc = NULL; - Surface_CMx_Visc = NULL; Surface_CMy_Visc = NULL; Surface_CMz_Visc = NULL; - MaxHeatFlux_Visc = NULL; Heat_Visc = NULL; - - /*--- Initialize the solution and right hand side vectors for storing - the residuals and updating the solution (always needed even for - explicit schemes). ---*/ - - //LinSysSol.Initialize(nPoint, nPointDomain, nVar, 0.0); - //LinSysRes.Initialize(nPoint, nPointDomain, nVar, 0.0); - - /*--- Non dimensional coefficients ---*/ - CD_Visc = new su2double[nMarker]; - CL_Visc = new su2double[nMarker]; - CSF_Visc = new su2double[nMarker]; - CMx_Visc = new su2double[nMarker]; - CMy_Visc = new su2double[nMarker]; - CMz_Visc = new su2double[nMarker]; - CEff_Visc = new su2double[nMarker]; - CFx_Visc = new su2double[nMarker]; - CFy_Visc = new su2double[nMarker]; - CFz_Visc = new su2double[nMarker]; - - Surface_CL_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CD_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CSF_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CEff_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFx_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFy_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFz_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMx_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMy_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMz_Visc = new su2double[config->GetnMarker_Monitoring()]; - - Heat_Visc = new su2double[nMarker]; - MaxHeatFlux_Visc = new su2double[nMarker]; - - /*--- Init total coefficients ---*/ - - Total_CD = 0.0; Total_CL = 0.0; Total_CSF = 0.0; - Total_CMx = 0.0; Total_CMy = 0.0; Total_CMz = 0.0; - Total_CEff = 0.0; - Total_CFx = 0.0; Total_CFy = 0.0; Total_CFz = 0.0; - - /*--- Read farfield conditions from config ---*/ - - Viscosity_Inf = config->GetViscosity_FreeStreamND(); - Prandtl_Lam = config->GetPrandtl_Lam(); - Prandtl_Turb = config->GetPrandtl_Turb(); - Tke_Inf = config->GetTke_FreeStreamND(); - - /*--- Set the SGS model in case an LES simulation is carried out ---*/ - - if(config->GetKind_Solver() == FEM_LES) { - - /* Make a distinction between the SGS models used and set SGSModel and - SGSModelUsed accordingly. */ - switch( config->GetKind_SGS_Model() ) { - - case IMPLICIT_LES: - SGSModel = NULL; - SGSModelUsed = false; - break; - - case SMAGORINSKY: - SGSModel = new CSmagorinskyModel; - SGSModelUsed = true; - break; - - case WALE: - SGSModel = new CWALEModel; - SGSModelUsed = true; - break; - - case VREMAN: - SGSModel = new CVremanModel; - SGSModelUsed = true; - break; - - default: - SU2_MPI::Error("Unknown SGS model encountered", CURRENT_FUNCTION); - } - } - else { - - /* No LES, so no SGS model needed. - Set the pointer to NULL and the boolean to false. */ - SGSModel = NULL; - SGSModelUsed = false; - } -} - -CFEM_DG_NSSolver::~CFEM_DG_NSSolver(void) { - - if (CD_Visc != NULL) delete [] CD_Visc; - if (CL_Visc != NULL) delete [] CL_Visc; - if (CSF_Visc != NULL) delete [] CSF_Visc; - if (CMx_Visc != NULL) delete [] CMx_Visc; - if (CMy_Visc != NULL) delete [] CMy_Visc; - if (CMz_Visc != NULL) delete [] CMz_Visc; - if (CFx_Visc != NULL) delete [] CFx_Visc; - if (CFy_Visc != NULL) delete [] CFy_Visc; - if (CFz_Visc != NULL) delete [] CFz_Visc; - if (CEff_Visc != NULL) delete [] CEff_Visc; - - if (Surface_CL_Visc != NULL) delete [] Surface_CL_Visc; - if (Surface_CD_Visc != NULL) delete [] Surface_CD_Visc; - if (Surface_CSF_Visc != NULL) delete [] Surface_CSF_Visc; - if (Surface_CEff_Visc != NULL) delete [] Surface_CEff_Visc; - if (Surface_CFx_Visc != NULL) delete [] Surface_CFx_Visc; - if (Surface_CFy_Visc != NULL) delete [] Surface_CFy_Visc; - if (Surface_CFz_Visc != NULL) delete [] Surface_CFz_Visc; - if (Surface_CMx_Visc != NULL) delete [] Surface_CMx_Visc; - if (Surface_CMy_Visc != NULL) delete [] Surface_CMy_Visc; - if (Surface_CMz_Visc != NULL) delete [] Surface_CMz_Visc; - - if (Heat_Visc != NULL) delete [] Heat_Visc; - if (MaxHeatFlux_Visc != NULL) delete [] MaxHeatFlux_Visc; - - if( SGSModel ) delete SGSModel; -} - -void CFEM_DG_NSSolver::Friction_Forces(CGeometry *geometry, CConfig *config) { - - /* Allocate the memory for the work array and initialize it to zero to avoid - warnings in debug mode about uninitialized memory when padding is applied. */ - vector workArrayVec(sizeWorkArray, 0.0); - su2double *workArray = workArrayVec.data(); - - /*--------------------------------------------------------------------------*/ - /*--- The skin friction is computed using the laminar viscosity and ---*/ - /*--- velocity gradients. This is correct when integration to the wall ---*/ - /*--- is performed, but not when wall functions are used. Hence, this ---*/ - /*--- function must be modified when wall functions are implemented. ---*/ - /*--------------------------------------------------------------------------*/ - - /* The number of bytes to copied in the memcpy calls. */ - const unsigned long nBytes = nVar*sizeof(su2double); - - /* Determine the number of faces that are treated simultaneously - in the matrix products to obtain good gemm performance. */ - const unsigned short nPadInput = config->GetSizeMatMulPadding(); - const unsigned short nFaceSimul = nPadInput/nVar; - - /* Determine the minimum padded size in the matrix multiplications, which - corresponds to 64 byte alignment. */ - const unsigned short nPadMin = 64/sizeof(passivedouble); - - /* Constant factor present in the heat flux vector. */ - const su2double factHeatFlux_Lam = Gamma/Prandtl_Lam; - - /*--- Get the information of the angle of attack, reference area, etc. ---*/ - const su2double Alpha = config->GetAoA()*PI_NUMBER/180.0; - const su2double Beta = config->GetAoS()*PI_NUMBER/180.0; - const su2double RefArea = config->GetRefArea(); - const su2double RefLength = config->GetRefLength(); - const su2double Gas_Constant = config->GetGas_ConstantND(); - const su2double *Origin = config->GetRefOriginMoment(0); - const bool grid_movement = config->GetGrid_Movement(); - -/*--- Evaluate reference values for non-dimensionalization. - For dynamic meshes, use the motion Mach number as a reference value - for computing the force coefficients. Otherwise, use the freestream - values, which is the standard convention. ---*/ - const su2double RefTemp = Temperature_Inf; - const su2double RefDensity = Density_Inf; - const su2double RefHeatFlux = config->GetHeat_Flux_Ref(); - - su2double RefVel2; - if (grid_movement) { - const su2double Mach2Vel = sqrt(Gamma*Gas_Constant*RefTemp); - const su2double Mach_Motion = config->GetMach_Motion(); - RefVel2 = (Mach_Motion*Mach2Vel)*(Mach_Motion*Mach2Vel); - } - else { - RefVel2 = 0.0; - for(unsigned short iDim=0; iDimGetnMarker_Monitoring(); ++iMarker_Monitoring) { - Surface_CL_Visc[iMarker_Monitoring] = 0.0; Surface_CD_Visc[iMarker_Monitoring] = 0.0; - Surface_CSF_Visc[iMarker_Monitoring] = 0.0; Surface_CEff_Visc[iMarker_Monitoring] = 0.0; - Surface_CFx_Visc[iMarker_Monitoring] = 0.0; Surface_CFy_Visc[iMarker_Monitoring] = 0.0; - Surface_CFz_Visc[iMarker_Monitoring] = 0.0; Surface_CMx_Visc[iMarker_Monitoring] = 0.0; - Surface_CMy_Visc[iMarker_Monitoring] = 0.0; Surface_CMz_Visc[iMarker_Monitoring] = 0.0; - } - - /*--- Loop over the Navier-Stokes markers ---*/ - for(unsigned short iMarker=0; iMarkerGetMarker_All_Monitoring(iMarker); - if(Monitoring == YES) { - - /* Easier storage of the boundary condition. */ - const unsigned short Boundary = config->GetMarker_All_KindBC(iMarker); - - /*--- Obtain the origin for the moment computation for a particular marker ---*/ - for(unsigned short iMarker_Monitoring=0; iMarker_MonitoringGetnMarker_Monitoring(); - ++iMarker_Monitoring) { - string Monitoring_Tag = config->GetMarker_Monitoring_TagBound(iMarker_Monitoring); - string Marker_Tag = config->GetMarker_All_TagBound(iMarker); - if (Marker_Tag == Monitoring_Tag) - Origin = config->GetRefOriginMoment(iMarker_Monitoring); - } - - /* Check for a boundary for which the viscous forces must be computed. */ - if((Boundary == HEAT_FLUX) || (Boundary == ISOTHERMAL)) { - - /*--- Determine the prescribed heat flux or prescribed temperature. ---*/ - bool HeatFlux_Prescribed = false, Temperature_Prescribed = false; - su2double Wall_HeatFlux = 0.0, Wall_Temperature = 0.0; - - const string Marker_Tag = config->GetMarker_All_TagBound(iMarker); - if(Boundary == HEAT_FLUX) { - HeatFlux_Prescribed = true; - Wall_HeatFlux = config->GetWall_HeatFlux(Marker_Tag); - } - else { - Temperature_Prescribed = true; - Wall_Temperature = config->GetIsothermal_Temperature(Marker_Tag) - / config->GetTemperature_Ref(); - } - - /*--- Forces initialization at each Marker ---*/ - CD_Visc[iMarker] = 0.0; CL_Visc[iMarker] = 0.0; CSF_Visc[iMarker] = 0.0; - CMx_Visc[iMarker] = 0.0; CMy_Visc[iMarker] = 0.0; CMz_Visc[iMarker] = 0.0; - CFx_Visc[iMarker] = 0.0; CFy_Visc[iMarker] = 0.0; CFz_Visc[iMarker] = 0.0; - - Heat_Visc[iMarker] = 0.0; MaxHeatFlux_Visc[iMarker] = 0.0; CEff_Visc[iMarker] = 0.0; - - su2double ForceViscous[] = {0.0, 0.0, 0.0}; - su2double MomentViscous[] = {0.0, 0.0, 0.0}; - - /* Easier storage of the boundary faces for this boundary marker. */ - const unsigned long nSurfElem = boundaries[iMarker].surfElem.size(); - const CSurfaceElementFEM *surfElem = boundaries[iMarker].surfElem.data(); - - /* Check if a wall treatment is used. */ - if( boundaries[iMarker].wallModel ) { - - /*--- Wall treatment is used, so the wall shear stress and heat flux - are computed using the wall model. As the interpolation of data - of the exchange point is different for each element, it is not - possible to treat multiple faces simultaneously. So here just - a loop over the number of faces is carried out. ---*/ - for(unsigned long l=0; lgemm(nIntThisDonor, nVar, nDOFsElem, surfElem[l].matWallFunctionDonor[j].data(), - solDOFsElem, workArray, config); - - /* Loop over the integration points for this donor element. */ - for(unsigned short i=surfElem[l].nIntPerWallFunctionDonor[j]; - iSetTDState_rhoe(solInt[0], eInt); - const su2double Pressure = FluidModel->GetPressure(); - const su2double Temperature = FluidModel->GetTemperature(); - const su2double LaminarViscosity= FluidModel->GetLaminarViscosity(); - - /* Subtract the prescribed wall velocity, i.e. grid velocity - from the velocity in the exchange point. */ - for(unsigned short k=0; kWallShearStressAndHeatFlux(Temperature, velTan, - LaminarViscosity, Pressure, - Wall_HeatFlux, HeatFlux_Prescribed, - Wall_Temperature, Temperature_Prescribed, - FluidModel, tauWall, qWall, - ViscosityWall, kOverCvWall); - - /* Update the viscous forces and moments. Note that the force direction - is the direction of the tangential velocity. */ - const su2double dForceMag = tauWall*weights[ii]*normals[nDim]*factor; - su2double dForces[] = {0.0, 0.0, 0.0}, dCoor[] = {0.0, 0.0, 0.0}; - for(unsigned short k=0; kgemm(nInt, NPad, nDOFsFace, basisFace, solCopy, solInt, config); - - /*--- Store the solution of the DOFs of the adjacent elements in contiguous - memory such that the function blasFunctions->gemm can be used to compute - the gradients solution variables in the integration points of the face. ---*/ - for(unsigned short ll=0; llgemm(nInt*nDim, NPad, nDOFsElem, derBasisElem, solCopy, gradSolInt, config); - - /* Determine the offset between r- and -s-derivatives, which is also the - offset between s- and t-derivatives. */ - const unsigned short offDeriv = NPad*nInt; - - /* Make a distinction between two and three space dimensions - in order to have the most efficient code. */ - switch( nDim ) { - - case 2: { - - /* Two dimensional simulation. Loop over the number of faces treated - simultaneously. */ - for(unsigned short ll=0; llSetTDState_rhoe(sol[0], StaticEnergy); - const su2double ViscosityLam = FluidModel->GetLaminarViscosity(); - - /* Set the value of the second viscosity and compute the - divergence term in the viscous normal stresses. */ - const su2double lambda = -TWO3*ViscosityLam; - const su2double lamDivTerm = lambda*divVel; - - /* Compute the viscous stress tensor and the normal flux. - Note that there is a plus sign for the heat flux, because - the normal points into the geometry. */ - const su2double tauxx = 2.0*ViscosityLam*dudx + lamDivTerm; - const su2double tauyy = 2.0*ViscosityLam*dvdy + lamDivTerm; - const su2double tauxy = ViscosityLam*(dudy + dvdx); - - const su2double qHeatNorm = ViscosityLam*factHeatFlux_Lam - * (dStaticEnergydx*normals[0] - + dStaticEnergydy*normals[1]); - - /* Update the viscous force and moment. Note that the normal - points into the geometry, hence the minus sign for the stress. */ - const su2double scaleFac = weights[i]*normals[nDim]*factor; - const su2double Fx = -scaleFac*(tauxx*normals[0] + tauxy*normals[1]); - const su2double Fy = -scaleFac*(tauxy*normals[0] + tauyy*normals[1]); - - ForceViscous[0] += Fx; - ForceViscous[1] += Fy; - - const su2double dx = Coord[0] - Origin[0]; - const su2double dy = Coord[1] - Origin[1]; - - MomentViscous[2] += (Fy*dx - Fx*dy)/RefLength; - - /* Update the heat flux and maximum heat flux for this marker. */ - Heat_Visc[iMarker] += qHeatNorm*weights[i]*normals[nDim]*RefHeatFlux; - MaxHeatFlux_Visc[iMarker] = max(MaxHeatFlux_Visc[iMarker], fabs(qHeatNorm)); - } - } - - break; - } - - /*------------------------------------------------------------------*/ - - case 3: { - - /* Three dimensional simulation. Loop over the number of faces treated - simultaneously. */ - for(unsigned short ll=0; llSetTDState_rhoe(sol[0], StaticEnergy); - const su2double ViscosityLam = FluidModel->GetLaminarViscosity(); - - /* Set the value of the second viscosity and compute the - divergence term in the viscous normal stresses. */ - const su2double lambda = -TWO3*ViscosityLam; - const su2double lamDivTerm = lambda*divVel; - - /* Compute the viscous stress tensor and the normal flux. - Note that there is a plus sign for the heat flux, because - the normal points into the geometry. */ - const su2double tauxx = 2.0*ViscosityLam*dudx + lamDivTerm; - const su2double tauyy = 2.0*ViscosityLam*dvdy + lamDivTerm; - const su2double tauzz = 2.0*ViscosityLam*dwdz + lamDivTerm; - - const su2double tauxy = ViscosityLam*(dudy + dvdx); - const su2double tauxz = ViscosityLam*(dudz + dwdx); - const su2double tauyz = ViscosityLam*(dvdz + dwdy); - - const su2double qHeatNorm = ViscosityLam*factHeatFlux_Lam - * (dStaticEnergydx*normals[0] - + dStaticEnergydy*normals[1] - + dStaticEnergydz*normals[2]); - - /* Update the viscous force and moment. Note that the normal - points into the geometry, hence the minus sign for the stress. */ - const su2double scaleFac = weights[i]*normals[nDim]*factor; - - const su2double Fx = -scaleFac*(tauxx*normals[0] + tauxy*normals[1] - + tauxz*normals[2]); - const su2double Fy = -scaleFac*(tauxy*normals[0] + tauyy*normals[1] - + tauyz*normals[2]); - const su2double Fz = -scaleFac*(tauxz*normals[0] + tauyz*normals[1] - + tauzz*normals[2]); - - ForceViscous[0] += Fx; - ForceViscous[1] += Fy; - ForceViscous[2] += Fz; - - const su2double dx = Coord[0] - Origin[0]; - const su2double dy = Coord[1] - Origin[1]; - const su2double dz = Coord[2] - Origin[2]; - - MomentViscous[0] += (Fz*dy - Fy*dz)/RefLength; - MomentViscous[1] += (Fx*dz - Fz*dx)/RefLength; - MomentViscous[2] += (Fy*dx - Fx*dy)/RefLength; - - /* Update the heat flux and maximum heat flux for this marker. */ - Heat_Visc[iMarker] += qHeatNorm*weights[i]*normals[nDim]*RefHeatFlux; - MaxHeatFlux_Visc[iMarker] = max(MaxHeatFlux_Visc[iMarker], fabs(qHeatNorm)); - } - } - - break; - } - } - - /* Update the value of the counter l to the end index of the - current chunk. */ - l = lEnd; - } - } - - /*--- Project forces and store the non-dimensional coefficients ---*/ - if (nDim == 2) { - CD_Visc[iMarker] = ForceViscous[0]*cos(Alpha) + ForceViscous[1]*sin(Alpha); - CL_Visc[iMarker] = -ForceViscous[0]*sin(Alpha) + ForceViscous[1]*cos(Alpha); - CEff_Visc[iMarker] = CL_Visc[iMarker] / (CD_Visc[iMarker]+EPS); - CMz_Visc[iMarker] = MomentViscous[2]; - CFx_Visc[iMarker] = ForceViscous[0]; - CFy_Visc[iMarker] = ForceViscous[1]; - } - if (nDim == 3) { - CD_Visc[iMarker] = ForceViscous[0]*cos(Alpha)*cos(Beta) - + ForceViscous[1]*sin(Beta) - + ForceViscous[2]*sin(Alpha)*cos(Beta); - CL_Visc[iMarker] = -ForceViscous[0]*sin(Alpha) + ForceViscous[2]*cos(Alpha); - CSF_Visc[iMarker] = -ForceViscous[0]*sin(Beta)*cos(Alpha) - + ForceViscous[1]*cos(Beta) - - ForceViscous[2]*sin(Beta)*sin(Alpha); - CEff_Visc[iMarker] = CL_Visc[iMarker]/(CD_Visc[iMarker] + EPS); - CMx_Visc[iMarker] = MomentViscous[0]; - CMy_Visc[iMarker] = MomentViscous[1]; - CMz_Visc[iMarker] = MomentViscous[2]; - CFx_Visc[iMarker] = ForceViscous[0]; - CFy_Visc[iMarker] = ForceViscous[1]; - CFz_Visc[iMarker] = ForceViscous[2]; - } - - AllBound_CD_Visc += CD_Visc[iMarker]; - AllBound_CL_Visc += CL_Visc[iMarker]; - AllBound_CSF_Visc += CSF_Visc[iMarker]; - AllBound_CMx_Visc += CMx_Visc[iMarker]; - AllBound_CMy_Visc += CMy_Visc[iMarker]; - AllBound_CMz_Visc += CMz_Visc[iMarker]; - AllBound_CFx_Visc += CFx_Visc[iMarker]; - AllBound_CFy_Visc += CFy_Visc[iMarker]; - AllBound_CFz_Visc += CFz_Visc[iMarker]; - - AllBound_HeatFlux_Visc += Heat_Visc[iMarker]; - AllBound_MaxHeatFlux_Visc = max(AllBound_MaxHeatFlux_Visc, - MaxHeatFlux_Visc[iMarker]); - - /*--- Compute the coefficients per surface ---*/ - for(unsigned short iMarker_Monitoring=0; iMarker_MonitoringGetnMarker_Monitoring(); - ++iMarker_Monitoring) { - string Monitoring_Tag = config->GetMarker_Monitoring_TagBound(iMarker_Monitoring); - string Marker_Tag = config->GetMarker_All_TagBound(iMarker); - if (Marker_Tag == Monitoring_Tag) { - Surface_CL_Visc[iMarker_Monitoring] += CL_Visc[iMarker]; - Surface_CD_Visc[iMarker_Monitoring] += CD_Visc[iMarker]; - Surface_CSF_Visc[iMarker_Monitoring] += CSF_Visc[iMarker]; - Surface_CEff_Visc[iMarker_Monitoring] += CEff_Visc[iMarker]; - Surface_CFx_Visc[iMarker_Monitoring] += CFx_Visc[iMarker]; - Surface_CFy_Visc[iMarker_Monitoring] += CFy_Visc[iMarker]; - Surface_CFz_Visc[iMarker_Monitoring] += CFz_Visc[iMarker]; - Surface_CMx_Visc[iMarker_Monitoring] += CMx_Visc[iMarker]; - Surface_CMy_Visc[iMarker_Monitoring] += CMy_Visc[iMarker]; - Surface_CMz_Visc[iMarker_Monitoring] += CMz_Visc[iMarker]; - } - } - } - } - } - -#ifdef HAVE_MPI - - /*--- Parallel mode. The data from all ranks must be gathered. - Determine the size of the communication buffer. ---*/ - const unsigned long nCommSize = 9*config->GetnMarker_Monitoring() + 10; - - /*--- Define the communication buffers and store to local data in - the local buffer. ---*/ - vector locBuf(nCommSize), globBuf(nCommSize); - - unsigned long ii = 0; - locBuf[ii++] = AllBound_CD_Visc; locBuf[ii++] = AllBound_CL_Visc; - locBuf[ii++] = AllBound_CSF_Visc; locBuf[ii++] = AllBound_CMx_Visc; - locBuf[ii++] = AllBound_CMy_Visc; locBuf[ii++] = AllBound_CMz_Visc; - locBuf[ii++] = AllBound_CFx_Visc; locBuf[ii++] = AllBound_CFy_Visc; - locBuf[ii++] = AllBound_CFz_Visc; locBuf[ii++] = AllBound_HeatFlux_Visc; - - for(unsigned short i=0; iGetnMarker_Monitoring(); ++i) { - locBuf[ii++] = Surface_CL_Visc[i]; locBuf[ii++] = Surface_CD_Visc[i]; - locBuf[ii++] = Surface_CSF_Visc[i]; locBuf[ii++] = Surface_CFx_Visc[i]; - locBuf[ii++] = Surface_CFy_Visc[i]; locBuf[ii++] = Surface_CFz_Visc[i]; - locBuf[ii++] = Surface_CMx_Visc[i]; locBuf[ii++] = Surface_CMy_Visc[i]; - locBuf[ii++] = Surface_CMz_Visc[i]; - } - - /* Sum up all the data from all ranks. The result will be available on all ranks. */ - if (config->GetComm_Level() == COMM_FULL) { - SU2_MPI::Allreduce(locBuf.data(), globBuf.data(), nCommSize, MPI_DOUBLE, - MPI_SUM, MPI_COMM_WORLD); - } - - /*--- Copy the data back from globBuf into the required variables. ---*/ - ii = 0; - AllBound_CD_Visc = globBuf[ii++]; AllBound_CL_Visc = globBuf[ii++]; - AllBound_CSF_Visc = globBuf[ii++]; AllBound_CMx_Visc = globBuf[ii++]; - AllBound_CMy_Visc = globBuf[ii++]; AllBound_CMz_Visc = globBuf[ii++]; - AllBound_CFx_Visc = globBuf[ii++]; AllBound_CFy_Visc = globBuf[ii++]; - AllBound_CFz_Visc = globBuf[ii++]; AllBound_HeatFlux_Visc = globBuf[ii++]; - - AllBound_CEff_Visc = AllBound_CL_Visc/(AllBound_CD_Visc + EPS); - - for(unsigned short i=0; iGetnMarker_Monitoring(); ++i) { - Surface_CL_Visc[i] = globBuf[ii++]; Surface_CD_Visc[i] = globBuf[ii++]; - Surface_CSF_Visc[i] = globBuf[ii++]; Surface_CFx_Visc[i] = globBuf[ii++]; - Surface_CFy_Visc[i] = globBuf[ii++]; Surface_CFz_Visc[i] = globBuf[ii++]; - Surface_CMx_Visc[i] = globBuf[ii++]; Surface_CMy_Visc[i] = globBuf[ii++]; - Surface_CMz_Visc[i] = globBuf[ii++]; - - Surface_CEff_Visc[i] = Surface_CL_Visc[i]/(Surface_CD_Visc[i] + EPS); - } - - /* Determine the maximum heat flux over all ranks. */ - su2double localMax = AllBound_MaxHeatFlux_Visc; - if (config->GetComm_Level() == COMM_FULL) { - SU2_MPI::Allreduce(&localMax, &AllBound_MaxHeatFlux_Visc, 1, MPI_DOUBLE, - MPI_MAX, MPI_COMM_WORLD); - } -#endif - - /*--- Update the total coefficients (note that all the nodes have the same value)---*/ - Total_CD += AllBound_CD_Visc; - Total_CL += AllBound_CL_Visc; - Total_CSF += AllBound_CSF_Visc; - Total_CEff = Total_CL / (Total_CD + EPS); - Total_CMx += AllBound_CMx_Visc; - Total_CMy += AllBound_CMy_Visc; - Total_CMz += AllBound_CMz_Visc; - Total_CFx += AllBound_CFx_Visc; - Total_CFy += AllBound_CFy_Visc; - Total_CFz += AllBound_CFz_Visc; - - /*--- Update the total coefficients per surface (note that all the nodes have the same value)---*/ - for (unsigned short iMarker_Monitoring=0; iMarker_MonitoringGetnMarker_Monitoring(); - ++iMarker_Monitoring) { - Surface_CL[iMarker_Monitoring] += Surface_CL_Visc[iMarker_Monitoring]; - Surface_CD[iMarker_Monitoring] += Surface_CD_Visc[iMarker_Monitoring]; - Surface_CSF[iMarker_Monitoring] += Surface_CSF_Visc[iMarker_Monitoring]; - Surface_CEff[iMarker_Monitoring] = Surface_CL[iMarker_Monitoring] / (Surface_CD[iMarker_Monitoring] + EPS); - Surface_CFx[iMarker_Monitoring] += Surface_CFx_Visc[iMarker_Monitoring]; - Surface_CFy[iMarker_Monitoring] += Surface_CFy_Visc[iMarker_Monitoring]; - Surface_CFz[iMarker_Monitoring] += Surface_CFz_Visc[iMarker_Monitoring]; - Surface_CMx[iMarker_Monitoring] += Surface_CMx_Visc[iMarker_Monitoring]; - Surface_CMy[iMarker_Monitoring] += Surface_CMy_Visc[iMarker_Monitoring]; - Surface_CMz[iMarker_Monitoring] += Surface_CMz_Visc[iMarker_Monitoring]; - } -} - -void CFEM_DG_NSSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh, unsigned long Iteration) { - - /* Check whether or not a time stepping scheme is used. */ - const bool time_stepping = config->GetTime_Marching() == TIME_STEPPING; - - /* Allocate the memory for the work array and initialize it to zero to avoid - warnings in debug mode about uninitialized memory when padding is applied. */ - vector workArrayVec(sizeWorkArray, 0.0); - su2double *workArray = workArrayVec.data(); - - /* Constant factor present in the heat flux vector, namely the ratio of - thermal conductivity and viscosity. */ - const su2double factHeatFlux_Lam = Gamma/Prandtl_Lam; - const su2double factHeatFlux_Turb = Gamma/Prandtl_Turb; - - /* Constant ratio of the second viscosity and the viscosity itself. */ - const su2double lambdaOverMu = -TWO3; - - /* The eigenvalues of the viscous Jacobian, scaled by the kinematic viscosity, - are 1.0, 2.0 + lambdaOverMu and kOverCv/Mu. The last is variable due to the - possible presence of an eddy viscosity, but the first two are constant and - the maximum can be determined. */ - const su2double radOverNuTerm = max(1.0, 2.0+lambdaOverMu); - - /* Store the number of metric points per DOF, which depends - on the number of dimensions. */ - const unsigned short nMetricPerPoint = nDim*nDim + 1; - - /* Determine the number of elements that are treated simultaneously - in the matrix products to obtain good gemm performance. */ - const unsigned short nPadInput = config->GetSizeMatMulPadding(); - const unsigned short nElemSimul = nPadInput/nVar; - - /* Determine the minimum padded size in the matrix multiplications, which - corresponds to 64 byte alignment. */ - const unsigned short nPadMin = 64/sizeof(passivedouble); - - /* Set the number of bytes that must be copied in the memcpy calls. */ - const unsigned long nBytes = nVar*sizeof(su2double); - - /* Initialize the minimum and maximum time step. */ - Min_Delta_Time = 1.e25; Max_Delta_Time = 0.0; - - /* Easier storage of the CFL number. Note that if we are using explicit - time stepping, the regular CFL condition has been overwritten with the - unsteady CFL condition in the config post-processing (if non-zero). */ - - const su2double CFL = config->GetCFL(iMesh); - - /*--- Explicit time stepping with imposed time step (eventually will - allow for local time stepping with this value imposed as the time - for syncing the cells). If the unsteady CFL is set to zero (default), - it uses the defined unsteady time step, otherwise it computes the time - step based on the provided unsteady CFL. Note that the regular CFL - option in the config is always ignored with time stepping. ---*/ - if (time_stepping && (config->GetUnst_CFL() == 0.0)) { - - /*--- Loop over the owned volume elements and set the fixed dt. ---*/ - for(unsigned long l=0; lGetDelta_UnstTimeND(); - - } else { - - /*--- Check for a compressible solver. ---*/ - if(config->GetKind_Regime() == COMPRESSIBLE) { - - /*--- Loop over the owned volume elements. Multiple elements are treated - simultaneously to improve the performance of the matrix - multiplications. As a consequence, the update of the counter l - happens at the end of this loop section. ---*/ - for(unsigned long l=0; lgemm(nDOFs*nDim, NPad, nDOFs, matDerBasisSolDOFs, solDOFs, gradSolDOFs, config); - } - - /*--- Make a distinction between 2D and 3D for optimal performance. ---*/ - switch( nDim ) { - - case 2: { - - /*--- 2D simulation. Loop over the chunk of elements. ---*/ - for(unsigned short ll=0; llSetTDState_rhoe(solDOF[0], StaticEnergy); - const su2double SoundSpeed2 = FluidModel->GetSoundSpeed2(); - const su2double SoundSpeed = sqrt(fabs(SoundSpeed2)); - - const su2double radx = fabs(u-gridVel[0]) + SoundSpeed; - const su2double rady = fabs(v-gridVel[1]) + SoundSpeed; - const su2double charVel2 = radx*radx + rady*rady; - - charVel2Max = max(charVel2Max, charVel2); - - /* Compute the laminar kinematic viscosity and check if an eddy - viscosity must be determined. */ - const su2double muLam = FluidModel->GetLaminarViscosity(); - su2double muTurb = 0.0; - - if( SGSModelUsed ) { - - /* Set the pointers to the locations where the gradients - of this DOF start. */ - const su2double *solDOFDr = gradSolDOFs + i*NPad + llNVar; - const su2double *solDOFDs = solDOFDr + offDerivSol; - - /* Compute the true value of the metric terms in this DOF. Note that in - metricTerms the metric terms scaled by the Jacobian are stored. */ - const su2double *metricTerms = volElem[lInd].metricTermsSolDOFs.data() - + i*nMetricPerPoint; - const su2double JacInv = 1.0/metricTerms[0]; - - const su2double drdx = JacInv*metricTerms[1]; - const su2double drdy = JacInv*metricTerms[2]; - - const su2double dsdx = JacInv*metricTerms[3]; - const su2double dsdy = JacInv*metricTerms[4]; - - /*--- Compute the Cartesian gradients of the independent solution - variables from the gradients in parametric coordinates and the metric - terms in this DOF. ---*/ - const su2double drhodx = solDOFDr[0]*drdx + solDOFDs[0]*dsdx; - const su2double drudx = solDOFDr[1]*drdx + solDOFDs[1]*dsdx; - const su2double drvdx = solDOFDr[2]*drdx + solDOFDs[2]*dsdx; - - const su2double drhody = solDOFDr[0]*drdy + solDOFDs[0]*dsdy; - const su2double drudy = solDOFDr[1]*drdy + solDOFDs[1]*dsdy; - const su2double drvdy = solDOFDr[2]*drdy + solDOFDs[2]*dsdy; - - /*--- Compute the Cartesian gradients of the velocities. ---*/ - const su2double dudx = DensityInv*(drudx - u*drhodx); - const su2double dvdx = DensityInv*(drvdx - v*drhodx); - const su2double dudy = DensityInv*(drudy - u*drhody); - const su2double dvdy = DensityInv*(drvdy - v*drhody); - - /* Compute the eddy viscosity. */ - const su2double dist = volElem[lInd].wallDistanceSolDOFs[i]; - muTurb = SGSModel->ComputeEddyViscosity_2D(solDOF[0], dudx, dudy, - dvdx, dvdy, lenScale, - dist); - } - - /*--- Determine the viscous spectral radius. ---*/ - const su2double mu = muLam + muTurb; - const su2double kOverCv = muLam*factHeatFlux_Lam - + muTurb*factHeatFlux_Turb; - const su2double factHeatFlux = kOverCv/mu; - - const su2double radVisc = DensityInv*mu*max(radOverNuTerm, factHeatFlux); - - /* Update the maximum value of the viscous spectral radius. */ - radViscMax = max(radViscMax, radVisc); - } - - /*--- Compute the time step for the element and update the minimum and - maximum value. Take the factor for time accurate local time - stepping into account for the minimum and maximum. ---*/ - const su2double dtInv = lenScaleInv*(sqrt(charVel2Max) + radViscMax*lenScaleInv); - - VecDeltaTime[lInd] = CFL/dtInv; - - const su2double dtEff = volElem[lInd].factTimeLevel*VecDeltaTime[lInd]; - Min_Delta_Time = min(Min_Delta_Time, dtEff); - Max_Delta_Time = max(Max_Delta_Time, dtEff); - } - - break; - } - - /*------------------------------------------------------------------*/ - - case 3: { - - /*--- 3D simulation. Loop over the chunk of elements. ---*/ - for(unsigned short ll=0; llSetTDState_rhoe(solDOF[0], StaticEnergy); - const su2double SoundSpeed2 = FluidModel->GetSoundSpeed2(); - const su2double SoundSpeed = sqrt(fabs(SoundSpeed2)); - - const su2double radx = fabs(u-gridVel[0]) + SoundSpeed; - const su2double rady = fabs(v-gridVel[1]) + SoundSpeed; - const su2double radz = fabs(w-gridVel[2]) + SoundSpeed; - const su2double charVel2 = radx*radx + rady*rady + radz*radz; - - charVel2Max = max(charVel2Max, charVel2); - - /* Compute the laminar kinematic viscosity and check if an eddy - viscosity must be determined. */ - const su2double muLam = FluidModel->GetLaminarViscosity(); - su2double muTurb = 0.0; - - if( SGSModelUsed ) { - - /* Set the pointers to the locations where the gradients - of this DOF start. */ - const su2double *solDOFDr = gradSolDOFs + i*NPad + llNVar; - const su2double *solDOFDs = solDOFDr + offDerivSol; - const su2double *solDOFDt = solDOFDs + offDerivSol; - - /* Compute the true value of the metric terms in this DOF. Note that in - metricTerms the metric terms scaled by the Jacobian are stored. */ - const su2double *metricTerms = volElem[lInd].metricTermsSolDOFs.data() - + i*nMetricPerPoint; - const su2double JacInv = 1.0/metricTerms[0]; - - const su2double drdx = JacInv*metricTerms[1]; - const su2double drdy = JacInv*metricTerms[2]; - const su2double drdz = JacInv*metricTerms[3]; - - const su2double dsdx = JacInv*metricTerms[4]; - const su2double dsdy = JacInv*metricTerms[5]; - const su2double dsdz = JacInv*metricTerms[6]; - - const su2double dtdx = JacInv*metricTerms[7]; - const su2double dtdy = JacInv*metricTerms[8]; - const su2double dtdz = JacInv*metricTerms[9]; - - /*--- Compute the Cartesian gradients of the independent solution - variables from the gradients in parametric coordinates and the metric - terms in this DOF. ---*/ - const su2double drhodx = solDOFDr[0]*drdx + solDOFDs[0]*dsdx + solDOFDt[0]*dtdx; - const su2double drux = solDOFDr[1]*drdx + solDOFDs[1]*dsdx + solDOFDt[1]*dtdx; - const su2double drvx = solDOFDr[2]*drdx + solDOFDs[2]*dsdx + solDOFDt[2]*dtdx; - const su2double drwx = solDOFDr[3]*drdx + solDOFDs[3]*dsdx + solDOFDt[3]*dtdx; - - const su2double drhody = solDOFDr[0]*drdy + solDOFDs[0]*dsdy + solDOFDt[0]*dtdy; - const su2double druy = solDOFDr[1]*drdy + solDOFDs[1]*dsdy + solDOFDt[1]*dtdy; - const su2double drvy = solDOFDr[2]*drdy + solDOFDs[2]*dsdy + solDOFDt[2]*dtdy; - const su2double drwy = solDOFDr[3]*drdy + solDOFDs[3]*dsdy + solDOFDt[3]*dtdy; - - const su2double drhodz = solDOFDr[0]*drdz + solDOFDs[0]*dsdz + solDOFDt[0]*dtdz; - const su2double druz = solDOFDr[1]*drdz + solDOFDs[1]*dsdz + solDOFDt[1]*dtdz; - const su2double drvz = solDOFDr[2]*drdz + solDOFDs[2]*dsdz + solDOFDt[2]*dtdz; - const su2double drwz = solDOFDr[3]*drdz + solDOFDs[3]*dsdz + solDOFDt[3]*dtdz; - - /*--- Compute the Cartesian gradients of the velocities. ---*/ - const su2double dudx = DensityInv*(drux - u*drhodx); - const su2double dudy = DensityInv*(druy - u*drhody); - const su2double dudz = DensityInv*(druz - u*drhodz); - - const su2double dvdx = DensityInv*(drvx - v*drhodx); - const su2double dvdy = DensityInv*(drvy - v*drhody); - const su2double dvdz = DensityInv*(drvz - v*drhodz); - - const su2double dwdx = DensityInv*(drwx - w*drhodx); - const su2double dwdy = DensityInv*(drwy - w*drhody); - const su2double dwdz = DensityInv*(drwz - w*drhodz); - - /* Compute the eddy viscosity. */ - const su2double dist = volElem[lInd].wallDistanceSolDOFs[i]; - muTurb = SGSModel->ComputeEddyViscosity_3D(solDOF[0], dudx, dudy, dudz, - dvdx, dvdy, dvdz, dwdx, dwdy, - dwdz, lenScale, dist); - } - - /*--- Determine the viscous spectral radius. ---*/ - const su2double mu = muLam + muTurb; - const su2double kOverCv = muLam*factHeatFlux_Lam - + muTurb*factHeatFlux_Turb; - const su2double factHeatFlux = kOverCv/mu; - - const su2double radVisc = DensityInv*mu*max(radOverNuTerm, factHeatFlux); - - /* Update the maximum value of the viscous spectral radius. */ - radViscMax = max(radViscMax, radVisc); - } - - /*--- Compute the time step for the element and update the minimum and - maximum value. Take the factor for time accurate local time - stepping into account for the minimum and maximum. ---*/ - const su2double dtInv = lenScaleInv*(sqrt(charVel2Max) + radViscMax*lenScaleInv); - - VecDeltaTime[lInd] = CFL/dtInv; - - const su2double dtEff = volElem[lInd].factTimeLevel*VecDeltaTime[lInd]; - Min_Delta_Time = min(Min_Delta_Time, dtEff); - Max_Delta_Time = max(Max_Delta_Time, dtEff); - } - - break; - } - } - - /* Update the value of the counter l to the end index of the - current chunk. */ - l = lEnd; - } - } - else { - - /*--- Incompressible solver. ---*/ - - SU2_MPI::Error("Incompressible solver not implemented yet", CURRENT_FUNCTION); - } - - /*--- Compute the max and the min dt (in parallel). Note that we only - do this for steady calculations if the high verbosity is set, but we - always perform the reduction for unsteady calculations where the CFL - limit is used to set the global time step. ---*/ - if ((config->GetComm_Level() == COMM_FULL) || time_stepping) { -#ifdef HAVE_MPI - su2double rbuf_time = Min_Delta_Time; - SU2_MPI::Allreduce(&rbuf_time, &Min_Delta_Time, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); - - rbuf_time = Max_Delta_Time; - SU2_MPI::Allreduce(&rbuf_time, &Max_Delta_Time, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); -#endif - } - - /*--- For explicit time stepping with an unsteady CFL imposed, use the - minimum delta time of the entire mesh. As Min_Delta_Time is scaled to - the time step of the largest time level, a correction must be used - for the time level when time accurate local time stepping is used. ---*/ - if (time_stepping) { - for(unsigned long l=0; lSetDelta_UnstTimeND(Min_Delta_Time); - } - } -} - -void CFEM_DG_NSSolver::ADER_DG_AliasedPredictorResidual_2D(CConfig *config, - CVolumeElementFEM *elem, - const su2double *sol, - const unsigned short nSimul, - const unsigned short NPad, - su2double *res, - su2double *work) { - /* Constant factor present in the heat flux vector. */ - const su2double factHeatFlux_Lam = Gamma/Prandtl_Lam; - const su2double factHeatFlux_Turb = Gamma/Prandtl_Turb; - - /* Get the necessary information from the standard element. */ - const unsigned short ind = elem->indStandardElement; - const unsigned short nInt = standardElementsSol[ind].GetNIntegration(); - const unsigned short nDOFs = elem->nDOFsSol; - const su2double *matBasisInt = standardElementsSol[ind].GetMatBasisFunctionsIntegration(); - const su2double *matDerBasisInt = matBasisInt + nDOFs*nInt; - const su2double *matDerBasisSolDOFs = standardElementsSol[ind].GetMatDerBasisFunctionsSolDOFs(); - const su2double *basisFunctionsIntTrans = standardElementsSol[ind].GetBasisFunctionsIntegrationTrans(); - const su2double *weights = standardElementsSol[ind].GetWeightsIntegration(); - - unsigned short nPoly = standardElementsSol[ind].GetNPoly(); - if(nPoly == 0) nPoly = 1; - - /* Compute the length scale of the current element for the LES. */ - const su2double lenScale = elem->lenScale/nPoly; - - /* Set the pointers for fluxes in the DOFs, the gradient of the fluxes in - the integration points, the gradient of the solution in the DOFs and the - divergence of the fluxes in the integration points. Note that some pointers - point to the same physical location. This is because this memory can be - used for different purposes. */ - su2double *fluxXDOF = work; - su2double *fluxYDOF = fluxXDOF + NPad*nDOFs; - su2double *gradFluxXInt = fluxYDOF + NPad*nDOFs; - su2double *gradFluxYInt = gradFluxXInt + nDim*NPad*nInt; - su2double *gradSolDOFs = gradFluxXInt; - su2double *divFlux = work; - - /* Determine the offset between the r-derivatives and s-derivatives of the - fluxes in the integration points and the offset between the r-derivatives - and s-derivatives of the solution in the DOFs. */ - const unsigned short offDerivSol = NPad*nDOFs; - const unsigned short offDerivFluxes = NPad*nInt; - - /* Store the number of metric points per integration point for readability. */ - const unsigned short nMetricPerPoint = 5; /* nDim*nDim + 1. */ - - /*--------------------------------------------------------------------------*/ - /*--- Construct the Cartesian fluxes in the DOFs. ---*/ - /*--------------------------------------------------------------------------*/ - - /* Compute the derivatives of the solution variables w.r.t. the parametric - coordinates in the DOFs. */ - blasFunctions->gemm(nDOFs*nDim, NPad, nDOFs, matDerBasisSolDOFs, sol, gradSolDOFs, config); - - /*--- Loop over the number of entities that are treated simultaneously. */ - for(unsigned short simul=0; simulgridVelocitiesSolDOFs.data() + 2*i; /* nDim*i. */ - - /* Compute the true value of the metric terms in this DOF. Note that in - metricTerms the metric terms scaled by the Jacobian are stored. THIS - IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, THE - DATA FOR THIS DOF FOR THE CURRENT TIME INTEGRATION POINT MUST BE TAKEN. */ - const su2double *metricTerms = elem->metricTermsSolDOFs.data() - + i*nMetricPerPoint; - const su2double JacInv = 1.0/metricTerms[0]; - - const su2double drdx = JacInv*metricTerms[1]; - const su2double drdy = JacInv*metricTerms[2]; - - const su2double dsdx = JacInv*metricTerms[3]; - const su2double dsdy = JacInv*metricTerms[4]; - - /* Compute the Cartesian gradients of the independent solution variables - from the gradients in parametric coordinates and the metric terms. */ - const su2double drhodx = solDOFDr[0]*drdx + solDOFDs[0]*dsdx; - const su2double drudx = solDOFDr[1]*drdx + solDOFDs[1]*dsdx; - const su2double drvdx = solDOFDr[2]*drdx + solDOFDs[2]*dsdx; - const su2double drEdx = solDOFDr[3]*drdx + solDOFDs[3]*dsdx; - - const su2double drhody = solDOFDr[0]*drdy + solDOFDs[0]*dsdy; - const su2double drudy = solDOFDr[1]*drdy + solDOFDs[1]*dsdy; - const su2double drvdy = solDOFDr[2]*drdy + solDOFDs[2]*dsdy; - const su2double drEdy = solDOFDr[3]*drdy + solDOFDs[3]*dsdy; - - /* Compute the velocities, pressure and laminar viscosity in this DOF. */ - const su2double DensityInv = 1.0/solDOF[0]; - const su2double u = DensityInv*solDOF[1]; - const su2double v = DensityInv*solDOF[2]; - const su2double TotalEnergy = DensityInv*solDOF[3]; - const su2double StaticEnergy = TotalEnergy - 0.5*(u*u + v*v); - - FluidModel->SetTDState_rhoe(solDOF[0], StaticEnergy); - const su2double Pressure = FluidModel->GetPressure(); - const su2double ViscosityLam = FluidModel->GetLaminarViscosity(); - - /* Compute the Cartesian gradients of the velocities and static energy. */ - const su2double dudx = DensityInv*(drudx - u*drhodx); - const su2double dvdx = DensityInv*(drvdx - v*drhodx); - const su2double dudy = DensityInv*(drudy - u*drhody); - const su2double dvdy = DensityInv*(drvdy - v*drhody); - - const su2double dedx = DensityInv*(drEdx - TotalEnergy*drhodx) - u*dudx - v*dvdx; - const su2double dedy = DensityInv*(drEdy - TotalEnergy*drhody) - u*dudy - v*dvdy; - - /* Compute the eddy viscosity, if needed, and the total viscosity. */ - su2double ViscosityTurb = 0.0; - if( SGSModelUsed ) - ViscosityTurb = SGSModel->ComputeEddyViscosity_2D(solDOF[0], dudx, dudy, - dvdx, dvdy, lenScale, - elem->wallDistanceSolDOFs[i]); - const su2double Viscosity = ViscosityLam + ViscosityTurb; - - /* Compute the total thermal conductivity divided by Cv. */ - const su2double kOverCv = ViscosityLam *factHeatFlux_Lam - + ViscosityTurb*factHeatFlux_Turb; - - /* Set the value of the second viscosity and compute the divergence - term in the viscous normal stresses. */ - const su2double lambda = -TWO3*Viscosity; - const su2double lamDivTerm = lambda*(dudx + dvdy); - - /* Compute the viscous stress tensor. */ - const su2double tauxx = 2.0*Viscosity*dudx + lamDivTerm; - const su2double tauyy = 2.0*Viscosity*dvdy + lamDivTerm; - const su2double tauxy = Viscosity*(dudy + dvdx); - - /* The Cartesian fluxes in the x-direction. */ - const su2double uRel = u - gridVel[0]; - fluxX[0] = solDOF[0]*uRel; - fluxX[1] = solDOF[1]*uRel + Pressure - tauxx; - fluxX[2] = solDOF[2]*uRel - tauxy; - fluxX[3] = solDOF[3]*uRel + Pressure*u - kOverCv*dedx - u*tauxx - v*tauxy;; - - /* The Cartesian fluxes in the y-direction. */ - const su2double vRel = v - gridVel[1]; - fluxY[0] = solDOF[0]*vRel; - fluxY[1] = solDOF[1]*vRel - tauxy; - fluxY[2] = solDOF[2]*vRel + Pressure - tauyy; - fluxY[3] = solDOF[3]*vRel + Pressure*v - kOverCv*dedy - u*tauxy - v*tauyy; - } - } - - /*--------------------------------------------------------------------------*/ - /*--- Compute the derivatives of the Cartesian fluxes w.r.t. the ---*/ - /*--- parametric coordinates in the integration points. ---*/ - /*--------------------------------------------------------------------------*/ - - blasFunctions->gemm(nInt*nDim, NPad, nDOFs, matDerBasisInt, fluxXDOF, gradFluxXInt, config); - blasFunctions->gemm(nInt*nDim, NPad, nDOFs, matDerBasisInt, fluxYDOF, gradFluxYInt, config); - - /*--------------------------------------------------------------------------*/ - /*--- Compute the divergence of the fluxes in the integration points, ---*/ - /*--- multiplied by the integration weight. ---*/ - /*--------------------------------------------------------------------------*/ - - /*--- Loop over the number of entities that are treated simultaneously. */ - for(unsigned short simul=0; simulmetricTerms.data() + i*nMetricPerPoint; - - /* Compute the metric terms multiplied by the integration weight. Note that the - first term in the metric terms is the Jacobian. */ - const su2double wDrdx = weights[i]*metricTerms[1]; - const su2double wDrdy = weights[i]*metricTerms[2]; - - const su2double wDsdx = weights[i]*metricTerms[3]; - const su2double wDsdy = weights[i]*metricTerms[4]; - - /* Compute the divergence of the fluxes, multiplied by the - integration weight. */ - divFluxInt[0] = gradFluxXDr[0]*wDrdx + gradFluxXDs[0]*wDsdx - + gradFluxYDr[0]*wDrdy + gradFluxYDs[0]*wDsdy; - divFluxInt[1] = gradFluxXDr[1]*wDrdx + gradFluxXDs[1]*wDsdx - + gradFluxYDr[1]*wDrdy + gradFluxYDs[1]*wDsdy; - divFluxInt[2] = gradFluxXDr[2]*wDrdx + gradFluxXDs[2]*wDsdx - + gradFluxYDr[2]*wDrdy + gradFluxYDs[2]*wDsdy; - divFluxInt[3] = gradFluxXDr[3]*wDrdx + gradFluxXDs[3]*wDsdx - + gradFluxYDr[3]*wDrdy + gradFluxYDs[3]*wDsdy; - } - } - - /*--------------------------------------------------------------------------*/ - /*--- Add the body force to the divergence of the fluxes, if such a ---*/ - /*--- force is present. ---*/ - /*--------------------------------------------------------------------------*/ - - if( config->GetBody_Force() ) { - - /* Easier storage of the body force. */ - const su2double *body_force_vector = config->GetBody_Force_Vector(); - - /* Compute the solution in the integration points of the element. - Use gradFluxYInt to store this solution. */ - su2double *solInt = gradFluxYInt; - - blasFunctions->gemm(nInt, NPad, nDOFs, matBasisInt, sol, solInt, config); - - /*--- Loop over the number of entities that are treated simultaneously. */ - for(unsigned short simul=0; simulmetricTerms.data() + i*nMetricPerPoint; - - /* Compute the velocities. */ - const su2double rhoInv = 1.0/solThisInt[0]; - const su2double u = solThisInt[1]*rhoInv; - const su2double v = solThisInt[2]*rhoInv; - - /* Add the body force to the flux divergence for the momentum and energy - equation. Note that the source terms are multiplied with minus the - integration weight in order to be consistent with the formulation of - the residual. Also note that for the energy source term the absolute - velocity must be taken and not the relative. */ - const su2double weightJac = weights[i]*metricTerms[0]; - - divFluxInt[1] -= weightJac*body_force_vector[0]; - divFluxInt[2] -= weightJac*body_force_vector[1]; - divFluxInt[3] -= weightJac*(u*body_force_vector[0] + v*body_force_vector[1]); - } - } - } - - /*--------------------------------------------------------------------------*/ - /*--- Add the source terms of the manufactured solution to the divergence---*/ - /*--- of the fluxes, if a manufactured solution is used. ---*/ - /*--------------------------------------------------------------------------*/ - - if( VerificationSolution ) { - if( VerificationSolution->IsManufacturedSolution() ) { - - /*--- Loop over the number of entities that are treated simultaneously. */ - for(unsigned short simul=0; simulcoorIntegrationPoints.data() + i*nDim; - - /* Easier storage of the metric terms in this integration point. - THIS IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, - THE DATA FOR THIS DOF FOR THE CURRENT TIME INTEGRATION POINT MUST - BE TAKEN. */ - const su2double *metricTerms = elem->metricTerms.data() + i*nMetricPerPoint; - const su2double weightJac = weights[i]*metricTerms[0]; - - /* Compute the source terms of the manufactured solution. - THIS IS A TEMPORARY IMPLEMENTATION. FOR AN ACTUAL TIME ACCURATE - SIMULATION THE CORRECT TIME MUST BE GIVEN TO THIS FUNCTION. */ - su2double sourceMan[4]; - VerificationSolution->GetMMSSourceTerm(coor, 0.0, sourceMan); - - /* Add the source terms to the flux divergence. Note that the source - terms are multiplied with minus the integration weight in order - to be consistent with the formulation of the residual. */ - divFluxInt[0] -= weightJac*sourceMan[0]; - divFluxInt[1] -= weightJac*sourceMan[1]; - divFluxInt[2] -= weightJac*sourceMan[2]; - divFluxInt[3] -= weightJac*sourceMan[3]; - } - } - } - } - - /*--------------------------------------------------------------------------*/ - /*--- Compute the residual in the DOFs, which is the matrix product of ---*/ - /*--- basisFunctionsIntTrans and divFlux. ---*/ - /*--------------------------------------------------------------------------*/ - - blasFunctions->gemm(nDOFs, NPad, nInt, basisFunctionsIntTrans, divFlux, res, config); -} - -void CFEM_DG_NSSolver::ADER_DG_AliasedPredictorResidual_3D(CConfig *config, - CVolumeElementFEM *elem, - const su2double *sol, - const unsigned short nSimul, - const unsigned short NPad, - su2double *res, - su2double *work) { - /* Constant factor present in the heat flux vector. */ - const su2double factHeatFlux_Lam = Gamma/Prandtl_Lam; - const su2double factHeatFlux_Turb = Gamma/Prandtl_Turb; - - /*--- Get the necessary information from the standard element. ---*/ - const unsigned short ind = elem->indStandardElement; - const unsigned short nInt = standardElementsSol[ind].GetNIntegration(); - const unsigned short nDOFs = elem->nDOFsSol; - const su2double *matBasisInt = standardElementsSol[ind].GetMatBasisFunctionsIntegration(); - const su2double *matDerBasisInt = matBasisInt + nDOFs*nInt; - const su2double *matDerBasisSolDOFs = standardElementsSol[ind].GetMatDerBasisFunctionsSolDOFs(); - const su2double *basisFunctionsIntTrans = standardElementsSol[ind].GetBasisFunctionsIntegrationTrans(); - const su2double *weights = standardElementsSol[ind].GetWeightsIntegration(); - - unsigned short nPoly = standardElementsSol[ind].GetNPoly(); - if(nPoly == 0) nPoly = 1; - - /* Compute the length scale of the current element for the LES. */ - const su2double lenScale = elem->lenScale/nPoly; - - /* Set the pointers for fluxes in the DOFs, the gradient of the fluxes in - the integration points, the gradient of the solution in the DOFs and the - divergence of the fluxes in the integration points. Note that some pointers - point to the same physical location. This is because this memory can be - used for different purposes. */ - su2double *fluxXDOF = work; - su2double *fluxYDOF = fluxXDOF + NPad*nDOFs; - su2double *fluxZDOF = fluxYDOF + NPad*nDOFs; - su2double *gradFluxXInt = fluxZDOF + NPad*nDOFs; - su2double *gradFluxYInt = gradFluxXInt + nDim*NPad*nInt; - su2double *gradFluxZInt = gradFluxYInt + nDim*NPad*nInt; - su2double *gradSolDOFs = gradFluxXInt; - su2double *divFlux = work; - - /* Determine the offset between the r-derivatives and s-derivatives of the - fluxes in the integration points and the offset between the r-derivatives - and s-derivatives of the solution in the DOFs. */ - const unsigned short offDerivSol = NPad*nDOFs; - const unsigned short offDerivFluxes = NPad*nInt; - - /* Store the number of metric points per integration point/DOF for readability. */ - const unsigned short nMetricPerPoint = 10; /* nDim*nDim + 1. */ - - /*--------------------------------------------------------------------------*/ - /*--- Construct the Cartesian fluxes in the DOFs. ---*/ - /*--------------------------------------------------------------------------*/ - - /* Compute the derivatives of the solution variables w.r.t. the parametric - coordinates in the DOFs. */ - blasFunctions->gemm(nDOFs*nDim, NPad, nDOFs, matDerBasisSolDOFs, sol, gradSolDOFs, config); - - /*--- Loop over the number of entities that are treated simultaneously. */ - for(unsigned short simul=0; simulgridVelocitiesSolDOFs.data() + 3*i; /* nDim*i. */ - - /* Compute the true value of the metric terms in this DOF. Note that in - metricTerms the metric terms scaled by the Jacobian are stored. THIS - IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, THE - DATA FOR THIS DOF FOR THE CURRENT TIME INTEGRATION POINT MUST BE TAKEN. */ - const su2double *metricTerms = elem->metricTermsSolDOFs.data() - + i*nMetricPerPoint; - const su2double JacInv = 1.0/metricTerms[0]; - - const su2double drdx = JacInv*metricTerms[1]; - const su2double drdy = JacInv*metricTerms[2]; - const su2double drdz = JacInv*metricTerms[3]; - - const su2double dsdx = JacInv*metricTerms[4]; - const su2double dsdy = JacInv*metricTerms[5]; - const su2double dsdz = JacInv*metricTerms[6]; - - const su2double dtdx = JacInv*metricTerms[7]; - const su2double dtdy = JacInv*metricTerms[8]; - const su2double dtdz = JacInv*metricTerms[9]; - - /* Compute the Cartesian gradients of the independent solution variables - from the gradients in parametric coordinates and the metric terms. */ - const su2double drhodx = solDOFDr[0]*drdx + solDOFDs[0]*dsdx + solDOFDt[0]*dtdx; - const su2double drudx = solDOFDr[1]*drdx + solDOFDs[1]*dsdx + solDOFDt[1]*dtdx; - const su2double drvdx = solDOFDr[2]*drdx + solDOFDs[2]*dsdx + solDOFDt[2]*dtdx; - const su2double drwdx = solDOFDr[3]*drdx + solDOFDs[3]*dsdx + solDOFDt[3]*dtdx; - const su2double drEdx = solDOFDr[4]*drdx + solDOFDs[4]*dsdx + solDOFDt[4]*dtdx; - - const su2double drhody = solDOFDr[0]*drdy + solDOFDs[0]*dsdy + solDOFDt[0]*dtdy; - const su2double drudy = solDOFDr[1]*drdy + solDOFDs[1]*dsdy + solDOFDt[1]*dtdy; - const su2double drvdy = solDOFDr[2]*drdy + solDOFDs[2]*dsdy + solDOFDt[2]*dtdy; - const su2double drwdy = solDOFDr[3]*drdy + solDOFDs[3]*dsdy + solDOFDt[3]*dtdy; - const su2double drEdy = solDOFDr[4]*drdy + solDOFDs[4]*dsdy + solDOFDt[4]*dtdy; - - const su2double drhodz = solDOFDr[0]*drdz + solDOFDs[0]*dsdz + solDOFDt[0]*dtdz; - const su2double drudz = solDOFDr[1]*drdz + solDOFDs[1]*dsdz + solDOFDt[1]*dtdz; - const su2double drvdz = solDOFDr[2]*drdz + solDOFDs[2]*dsdz + solDOFDt[2]*dtdz; - const su2double drwdz = solDOFDr[3]*drdz + solDOFDs[3]*dsdz + solDOFDt[3]*dtdz; - const su2double drEdz = solDOFDr[4]*drdz + solDOFDs[4]*dsdz + solDOFDt[4]*dtdz; - - /* Compute the velocities, pressure and laminar viscosity in this DOF. */ - const su2double DensityInv = 1.0/solDOF[0]; - const su2double u = DensityInv*solDOF[1]; - const su2double v = DensityInv*solDOF[2]; - const su2double w = DensityInv*solDOF[3]; - const su2double TotalEnergy = DensityInv*solDOF[4]; - const su2double StaticEnergy = TotalEnergy - 0.5*(u*u + v*v + w*w); - - FluidModel->SetTDState_rhoe(solDOF[0], StaticEnergy); - const su2double Pressure = FluidModel->GetPressure(); - const su2double ViscosityLam = FluidModel->GetLaminarViscosity(); - - /* Compute the Cartesian gradients of the velocities and static energy. */ - const su2double dudx = DensityInv*(drudx - u*drhodx); - const su2double dudy = DensityInv*(drudy - u*drhody); - const su2double dudz = DensityInv*(drudz - u*drhodz); - - const su2double dvdx = DensityInv*(drvdx - v*drhodx); - const su2double dvdy = DensityInv*(drvdy - v*drhody); - const su2double dvdz = DensityInv*(drvdz - v*drhodz); - - const su2double dwdx = DensityInv*(drwdx - w*drhodx); - const su2double dwdy = DensityInv*(drwdy - w*drhody); - const su2double dwdz = DensityInv*(drwdz - w*drhodz); - - const su2double dedx = DensityInv*(drEdx - TotalEnergy*drhodx) - u*dudx - v*dvdx - w*dwdx; - const su2double dedy = DensityInv*(drEdy - TotalEnergy*drhody) - u*dudy - v*dvdy - w*dwdy; - const su2double dedz = DensityInv*(drEdz - TotalEnergy*drhodz) - u*dudz - v*dvdz - w*dwdz; - - /* Compute the eddy viscosity, if needed, and the total viscosity. */ - su2double ViscosityTurb = 0.0; - if( SGSModelUsed ) - ViscosityTurb = SGSModel->ComputeEddyViscosity_3D(solDOF[0], dudx, dudy, dudz, - dvdx, dvdy, dvdz, dwdx, - dwdy, dwdz, lenScale, - elem->wallDistanceSolDOFs[i]); - const su2double Viscosity = ViscosityLam + ViscosityTurb; - - /* Compute the total thermal conductivity divided by Cv. */ - const su2double kOverCv = ViscosityLam *factHeatFlux_Lam - + ViscosityTurb*factHeatFlux_Turb; - - /* Set the value of the second viscosity and compute the divergence - term in the viscous normal stresses. */ - const su2double lambda = -TWO3*Viscosity; - const su2double lamDivTerm = lambda*(dudx + dvdy + dwdz); - - /* Compute the viscous stress tensor. */ - const su2double tauxx = 2.0*Viscosity*dudx + lamDivTerm; - const su2double tauyy = 2.0*Viscosity*dvdy + lamDivTerm; - const su2double tauzz = 2.0*Viscosity*dwdz + lamDivTerm; - - const su2double tauxy = Viscosity*(dudy + dvdx); - const su2double tauxz = Viscosity*(dudz + dwdx); - const su2double tauyz = Viscosity*(dvdz + dwdy); - - /* The Cartesian fluxes in the x-direction. */ - const su2double uRel = u - gridVel[0]; - fluxX[0] = solDOF[0]*uRel; - fluxX[1] = solDOF[1]*uRel + Pressure - tauxx; - fluxX[2] = solDOF[2]*uRel - tauxy; - fluxX[3] = solDOF[3]*uRel - tauxz; - fluxX[4] = solDOF[4]*uRel + Pressure*u - kOverCv*dedx - u*tauxx - v*tauxy - w*tauxz; - - /* The Cartesian fluxes in the y-direction. */ - const su2double vRel = v - gridVel[1]; - fluxY[0] = solDOF[0]*vRel; - fluxY[1] = solDOF[1]*vRel - tauxy; - fluxY[2] = solDOF[2]*vRel + Pressure - tauyy; - fluxY[3] = solDOF[3]*vRel - tauyz; - fluxY[4] = solDOF[4]*vRel + Pressure*v - kOverCv*dedy - u*tauxy - v*tauyy - w*tauyz; - - /* The Cartesian fluxes in the z-direction. */ - const su2double wRel = w - gridVel[2]; - fluxZ[0] = solDOF[0]*wRel; - fluxZ[1] = solDOF[1]*wRel - tauxz; - fluxZ[2] = solDOF[2]*wRel - tauyz; - fluxZ[3] = solDOF[3]*wRel + Pressure - tauzz; - fluxZ[4] = solDOF[4]*wRel + Pressure*w - kOverCv*dedz - u*tauxz - v*tauyz - w*tauzz; - } - } - - /*--------------------------------------------------------------------------*/ - /*--- Compute the derivatives of the Cartesian fluxes w.r.t. the ---*/ - /*--- parametric coordinates in the integration points. ---*/ - /*--------------------------------------------------------------------------*/ - - blasFunctions->gemm(nInt*nDim, NPad, nDOFs, matDerBasisInt, fluxXDOF, gradFluxXInt, config); - blasFunctions->gemm(nInt*nDim, NPad, nDOFs, matDerBasisInt, fluxYDOF, gradFluxYInt, config); - blasFunctions->gemm(nInt*nDim, NPad, nDOFs, matDerBasisInt, fluxZDOF, gradFluxZInt, config); - - /*--------------------------------------------------------------------------*/ - /*--- Compute the divergence of the fluxes in the integration points, ---*/ - /*--- multiplied by the integration weight. ---*/ - /*--------------------------------------------------------------------------*/ - - /*--- Loop over the number of entities that are treated simultaneously. */ - for(unsigned short simul=0; simulmetricTerms.data() + i*nMetricPerPoint; - - /* Compute the metric terms multiplied by the integration weight. Note that the - first term in the metric terms is the Jacobian. */ - const su2double wDrdx = weights[i]*metricTerms[1]; - const su2double wDrdy = weights[i]*metricTerms[2]; - const su2double wDrdz = weights[i]*metricTerms[3]; - - const su2double wDsdx = weights[i]*metricTerms[4]; - const su2double wDsdy = weights[i]*metricTerms[5]; - const su2double wDsdz = weights[i]*metricTerms[6]; - - const su2double wDtdx = weights[i]*metricTerms[7]; - const su2double wDtdy = weights[i]*metricTerms[8]; - const su2double wDtdz = weights[i]*metricTerms[9]; - - /* Compute the divergence of the fluxes, multiplied by the integration weight. */ - divFluxInt[0] = gradFluxXDr[0]*wDrdx + gradFluxXDs[0]*wDsdx + gradFluxXDt[0]*wDtdx - + gradFluxYDr[0]*wDrdy + gradFluxYDs[0]*wDsdy + gradFluxYDt[0]*wDtdy - + gradFluxZDr[0]*wDrdz + gradFluxZDs[0]*wDsdz + gradFluxZDt[0]*wDtdz; - divFluxInt[1] = gradFluxXDr[1]*wDrdx + gradFluxXDs[1]*wDsdx + gradFluxXDt[1]*wDtdx - + gradFluxYDr[1]*wDrdy + gradFluxYDs[1]*wDsdy + gradFluxYDt[1]*wDtdy - + gradFluxZDr[1]*wDrdz + gradFluxZDs[1]*wDsdz + gradFluxZDt[1]*wDtdz; - divFluxInt[2] = gradFluxXDr[2]*wDrdx + gradFluxXDs[2]*wDsdx + gradFluxXDt[2]*wDtdx - + gradFluxYDr[2]*wDrdy + gradFluxYDs[2]*wDsdy + gradFluxYDt[2]*wDtdy - + gradFluxZDr[2]*wDrdz + gradFluxZDs[2]*wDsdz + gradFluxZDt[2]*wDtdz; - divFluxInt[3] = gradFluxXDr[3]*wDrdx + gradFluxXDs[3]*wDsdx + gradFluxXDt[3]*wDtdx - + gradFluxYDr[3]*wDrdy + gradFluxYDs[3]*wDsdy + gradFluxYDt[3]*wDtdy - + gradFluxZDr[3]*wDrdz + gradFluxZDs[3]*wDsdz + gradFluxZDt[3]*wDtdz; - divFluxInt[4] = gradFluxXDr[4]*wDrdx + gradFluxXDs[4]*wDsdx + gradFluxXDt[4]*wDtdx - + gradFluxYDr[4]*wDrdy + gradFluxYDs[4]*wDsdy + gradFluxYDt[4]*wDtdy - + gradFluxZDr[4]*wDrdz + gradFluxZDs[4]*wDsdz + gradFluxZDt[4]*wDtdz; - } - } - - /*--------------------------------------------------------------------------*/ - /*--- Add the body force to the divergence of the fluxes, if such a ---*/ - /*--- force is present. ---*/ - /*--------------------------------------------------------------------------*/ - - if( config->GetBody_Force() ) { - - /* Easier storage of the body force. */ - const su2double *body_force_vector = config->GetBody_Force_Vector(); - - /* Compute the solution in the integration points of the element. - Use gradFluxYInt to store this solution. */ - su2double *solInt = gradFluxYInt; - - blasFunctions->gemm(nInt, NPad, nDOFs, matBasisInt, sol, solInt, config); - - /*--- Loop over the number of entities that are treated simultaneously. */ - for(unsigned short simul=0; simulmetricTerms.data() + i*nMetricPerPoint; - - /* Compute the velocities. */ - const su2double rhoInv = 1.0/solThisInt[0]; - const su2double u = solThisInt[1]*rhoInv; - const su2double v = solThisInt[2]*rhoInv; - const su2double w = solThisInt[3]*rhoInv; - - /* Add the body force to the flux divergence for the momentum and energy - equation. Note that the source terms are multiplied with minus the - integration weight in order to be consistent with the formulation of - the residual. Also note that for the energy source term the absolute - velocity must be taken and not the relative. */ - const su2double weightJac = weights[i]*metricTerms[0]; - - divFluxInt[1] -= weightJac*body_force_vector[0]; - divFluxInt[2] -= weightJac*body_force_vector[1]; - divFluxInt[3] -= weightJac*body_force_vector[2]; - divFluxInt[4] -= weightJac*(u*body_force_vector[0] + v*body_force_vector[1] - + w*body_force_vector[2]); - } - } - } - - /*--------------------------------------------------------------------------*/ - /*--- Add the source terms of the manufactured solution to the divergence---*/ - /*--- of the fluxes, if a manufactured solution is used. ---*/ - /*--------------------------------------------------------------------------*/ - - if( VerificationSolution ) { - if( VerificationSolution->IsManufacturedSolution() ) { - - /*--- Loop over the number of entities that are treated simultaneously. */ - for(unsigned short simul=0; simulcoorIntegrationPoints.data() + i*nDim; - - /* Easier storage of the metric terms in this integration point. - THIS IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, - THE DATA FOR THIS DOF FOR THE CURRENT TIME INTEGRATION POINT MUST - BE TAKEN. */ - const su2double *metricTerms = elem->metricTerms.data() + i*nMetricPerPoint; - const su2double weightJac = weights[i]*metricTerms[0]; - - /* Compute the source terms of the manufactured solution. - THIS IS A TEMPORARY IMPLEMENTATION. FOR AN ACTUAL TIME ACCURATE - SIMULATION THE CORRECT TIME MUST BE GIVEN TO THIS FUNCTION. */ - su2double sourceMan[5]; - VerificationSolution->GetMMSSourceTerm(coor, 0.0, sourceMan); - - /* Add the source terms to the flux divergence. Note that the source - terms are multiplied with minus the integration weight in order - to be consistent with the formulation of the residual. */ - divFluxInt[0] -= weightJac*sourceMan[0]; - divFluxInt[1] -= weightJac*sourceMan[1]; - divFluxInt[2] -= weightJac*sourceMan[2]; - divFluxInt[3] -= weightJac*sourceMan[3]; - divFluxInt[4] -= weightJac*sourceMan[4]; - } - } - } - } - - /*--------------------------------------------------------------------------*/ - /*--- Compute the residual in the DOFs, which is the matrix product of ---*/ - /*--- basisFunctionsIntTrans and divFlux. ---*/ - /*--------------------------------------------------------------------------*/ - - blasFunctions->gemm(nDOFs, NPad, nInt, basisFunctionsIntTrans, divFlux, res, config); -} - -void CFEM_DG_NSSolver::ADER_DG_NonAliasedPredictorResidual_2D(CConfig *config, - CVolumeElementFEM *elem, - const su2double *sol, - const unsigned short nSimul, - const unsigned short NPad, - su2double *res, - su2double *work) { - - /* Constant factor present in the heat flux vector, the inverse of - the specific heat at constant volume and ratio lambdaOverMu. */ - const su2double factHeatFlux_Lam = Gamma/Prandtl_Lam; - const su2double factHeatFlux_Turb = Gamma/Prandtl_Turb; - const su2double Gas_Constant = config->GetGas_ConstantND(); - const su2double CvInv = Gamma_Minus_One/Gas_Constant; - const su2double lambdaOverMu = -TWO3; - - /*--- Get the necessary information from the standard element. ---*/ - const unsigned short ind = elem->indStandardElement; - const unsigned short nInt = standardElementsSol[ind].GetNIntegration(); - const unsigned short nDOFs = elem->nDOFsSol; - const su2double *matBasisInt = standardElementsSol[ind].GetMatBasisFunctionsIntegration(); - const su2double *mat2ndDerBasisInt = standardElementsSol[ind].GetMat2ndDerBasisFunctionsInt(); - const su2double *basisFunctionsIntTrans = standardElementsSol[ind].GetBasisFunctionsIntegrationTrans(); - const su2double *weights = standardElementsSol[ind].GetWeightsIntegration(); - - unsigned short nPoly = standardElementsSol[ind].GetNPoly(); - if(nPoly == 0) nPoly = 1; - - /* Check if a body force is present and set it accordingly. */ - su2double bodyForceX = 0.0, bodyForceY = 0.0; - if( config->GetBody_Force() ) { - const su2double *body_force_vector = config->GetBody_Force_Vector(); - bodyForceX = body_force_vector[0]; - bodyForceY = body_force_vector[1]; - } - - /* Compute the length scale of the current element for the LES. */ - const su2double lenScale = elem->lenScale/nPoly; - - /* Set the pointers for solAndGradInt and divFlux to work. The same array - can be used for both help arrays. */ - su2double *solAndGradInt = work; - su2double *divFlux = work; - - /* Determine the offset between the solution variables and the r-derivatives, - which is also the offset between the r- and s-derivatives in the - integration points. */ - const unsigned short offDerivInt = NPad*nInt; - - /* Set the pointer for the second derivatives such that they are stored - after the first derivatives. */ - su2double *secDerSol = solAndGradInt + 3*NPad*nInt; /*(nDim+1)*NPad*nInt. */ - - /* Store the number of metric points per integration point for readability. */ - const unsigned short nMetricPerPoint = 5; /* nDim*nDim + 1. */ - - /* Store the number of additional metric points per integration point, which - are needed to compute the second derivatives. These terms take the - non-constant metric into account. */ - const unsigned short nMetric2ndDerPerPoint = 6; /*nDim*(nDim + nDim*(nDim-1)/2). */ - - /*--------------------------------------------------------------------------*/ - /*--- Interpolate the solution variables to the integration points and ---*/ - /*--- also determine the first and second derivatives of these variables ---*/ - /*--- in the integration points. All derivatives are w.r.t. the ---*/ - /*--- parametric coordinates. ---*/ - /*--------------------------------------------------------------------------*/ - - /* Compute the solution and the derivatives w.r.t. the parametric coordinates - in the integration points. The first argument is nInt*(nDim+1). */ - blasFunctions->gemm(nInt*3, NPad, nDOFs, matBasisInt, sol, solAndGradInt, config); - - /* Compute the second derivatives w.r.t. the parametric coordinates - in the integration points. */ - blasFunctions->gemm(nInt*3, NPad, nDOFs, mat2ndDerBasisInt, sol, secDerSol, config); - - /*--------------------------------------------------------------------------*/ - /*--- Compute the divergence of viscous fluxes, multiplied by the ---*/ - /*--- integration weight in the integration points of the element. ---*/ - /*--------------------------------------------------------------------------*/ - - /*--- Loop over the number of entities that are treated simultaneously. */ - for(unsigned short simul=0; simulSetTDState_rhoe(rho, StaticEnergy); - const su2double Pressure = FluidModel->GetPressure(); - const su2double Htot = rhoInv*(rE + Pressure); - - /* Compute the laminar viscosity and its derivative w.r.t. temperature. */ - const su2double ViscosityLam = FluidModel->GetLaminarViscosity(); - const su2double dViscLamdT = FluidModel->GetdmudT_rho(); - - /* Set the pointer to the grid velocities in this integration point. - THIS IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, - THE DATA FOR THIS SPATIAL INTEGRATION POINT FOR THE CURRENT TIME - INTEGRATION POINT MUST BE TAKEN. */ - const su2double *gridVel = elem->gridVelocities.data() + 2*i; /* nDim*i. */ - - /* Easier storage of the metric terms in this integration point. - THIS IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, - THE DATA FOR THIS SPATIAL INTEGRATION POINT FOR THE CURRENT TIME - INTEGRATION POINT MUST BE TAKEN. */ - const su2double *metricTerms = elem->metricTerms.data() + i*nMetricPerPoint; - - /* Compute the true metric terms. Note in metricTerms the actual metric - terms multiplied by the Jacobian are stored. */ - const su2double Jac = metricTerms[0]; - const su2double JacInv = 1.0/Jac; - - const su2double drdx = JacInv*metricTerms[1]; - const su2double drdy = JacInv*metricTerms[2]; - const su2double dsdx = JacInv*metricTerms[3]; - const su2double dsdy = JacInv*metricTerms[4]; - - /* Compute the Cartesian gradients of the independent solution - variables from the gradients in parametric coordinates and the - metric terms in this integration point. */ - const su2double drhodx = solDr[0]*drdx + solDs[0]*dsdx; - const su2double drudx = solDr[1]*drdx + solDs[1]*dsdx; - const su2double drvdx = solDr[2]*drdx + solDs[2]*dsdx; - const su2double drEdx = solDr[3]*drdx + solDs[3]*dsdx; - - const su2double drhody = solDr[0]*drdy + solDs[0]*dsdy; - const su2double drudy = solDr[1]*drdy + solDs[1]*dsdy; - const su2double drvdy = solDr[2]*drdy + solDs[2]*dsdy; - const su2double drEdy = solDr[3]*drdy + solDs[3]*dsdy; - - /* Pointer to the necessary additional metric terms needed to compute - the Cartesian second derivatives for this integration point. - HIS IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, - THE DATA FOR THIS SPATIAL INTEGRATION POINT FOR THE CURRENT TIME - INTEGRATION POINT MUST BE TAKEN. */ - const su2double *metricTerms2ndDer = elem->metricTerms2ndDer.data() - + i*nMetric2ndDerPerPoint; - - /* Compute the Cartesian second derivatives of the independent solution - variables from the gradients and second derivatives in parametric - coordinates and the metric terms and its derivatives w.r.t. the - parametric coordinates. */ - const su2double d2rhodxdx = solDrDr[0]*drdx*drdx + solDsDs[0]*dsdx*dsdx - + 2.0*solDrDs[0]*drdx*dsdx - + solDr[0]*metricTerms2ndDer[0] + solDs[0]*metricTerms2ndDer[1]; - const su2double d2rudxdx = solDrDr[1]*drdx*drdx + solDsDs[1]*dsdx*dsdx - + 2.0*solDrDs[1]*drdx*dsdx - + solDr[1]*metricTerms2ndDer[0] + solDs[1]*metricTerms2ndDer[1]; - const su2double d2rvdxdx = solDrDr[2]*drdx*drdx + solDsDs[2]*dsdx*dsdx - + 2.0*solDrDs[2]*drdx*dsdx - + solDr[2]*metricTerms2ndDer[0] + solDs[2]*metricTerms2ndDer[1]; - const su2double d2rEdxdx = solDrDr[3]*drdx*drdx + solDsDs[3]*dsdx*dsdx - + 2.0*solDrDs[3]*drdx*dsdx - + solDr[3]*metricTerms2ndDer[0] + solDs[3]*metricTerms2ndDer[1]; - - const su2double d2rhodydy = solDrDr[0]*drdy*drdy + solDsDs[0]*dsdy*dsdy - + 2.0*solDrDs[0]*drdy*dsdy - + solDr[0]*metricTerms2ndDer[4] + solDs[0]*metricTerms2ndDer[5]; - const su2double d2rudydy = solDrDr[1]*drdy*drdy + solDsDs[1]*dsdy*dsdy - + 2.0*solDrDs[1]*drdy*dsdy - + solDr[1]*metricTerms2ndDer[4] + solDs[1]*metricTerms2ndDer[5]; - const su2double d2rvdydy = solDrDr[2]*drdy*drdy + solDsDs[2]*dsdy*dsdy - + 2.0*solDrDs[2]*drdy*dsdy - + solDr[2]*metricTerms2ndDer[4] + solDs[2]*metricTerms2ndDer[5]; - const su2double d2rEdydy = solDrDr[3]*drdy*drdy + solDsDs[3]*dsdy*dsdy - + 2.0*solDrDs[3]*drdy*dsdy - + solDr[3]*metricTerms2ndDer[4] + solDs[3]*metricTerms2ndDer[5]; - - const su2double d2rhodxdy = solDrDr[0]*drdx*drdy + solDsDs[0]*dsdx*dsdy - + solDrDs[0]*(drdx*dsdy + dsdx*drdy) - + solDr[0]*metricTerms2ndDer[2] + solDs[0]*metricTerms2ndDer[3]; - const su2double d2rudxdy = solDrDr[1]*drdx*drdy + solDsDs[1]*dsdx*dsdy - + solDrDs[1]*(drdx*dsdy + dsdx*drdy) - + solDr[1]*metricTerms2ndDer[2] + solDs[1]*metricTerms2ndDer[3]; - const su2double d2rvdxdy = solDrDr[2]*drdx*drdy + solDsDs[2]*dsdx*dsdy - + solDrDs[2]*(drdx*dsdy + dsdx*drdy) - + solDr[2]*metricTerms2ndDer[2] + solDs[2]*metricTerms2ndDer[3]; - - /* Compute the Cartesian gradients of the pressure, velocity components, - static energy and dynamic viscosity. */ - const su2double dpdx = Gamma_Minus_One*(drEdx + kinEnergy*drhodx - - u*drudx - v*drvdx); - const su2double dpdy = Gamma_Minus_One*(drEdy + kinEnergy*drhody - - u*drudy - v*drvdy); - - const su2double dudx = rhoInv*(drudx - u*drhodx); - const su2double dudy = rhoInv*(drudy - u*drhody); - const su2double dvdx = rhoInv*(drvdx - v*drhodx); - const su2double dvdy = rhoInv*(drvdy - v*drhody); - - const su2double dedx = rhoInv*(drEdx - TotalEnergy*drhodx) - u*dudx - v*dvdx; - const su2double dedy = rhoInv*(drEdy - TotalEnergy*drhody) - u*dudy - v*dvdy; - - const su2double dViscLamdx = CvInv*dedx*dViscLamdT; - const su2double dViscLamdy = CvInv*dedy*dViscLamdT; - - /* Compute the second derivatives of the velocity components. */ - const su2double d2udxdx = rhoInv*(d2rudxdx - u*d2rhodxdx - + 2.0*rhoInv*drhodx*(u*drhodx - drudx)); - const su2double d2udydy = rhoInv*(d2rudydy - u*d2rhodydy - + 2.0*rhoInv*drhody*(u*drhody - drudy)); - const su2double d2udxdy = rhoInv*(d2rudxdy - u*d2rhodxdy - + rhoInv*(drhodx*(u*drhody - drudy) - + drhody*(u*drhodx - drudx))); - - const su2double d2vdxdx = rhoInv*(d2rvdxdx - v*d2rhodxdx - + 2.0*rhoInv*drhodx*(v*drhodx - drvdx)); - const su2double d2vdydy = rhoInv*(d2rvdydy - v*d2rhodydy - + 2.0*rhoInv*drhody*(v*drhody - drvdy)); - const su2double d2vdxdy = rhoInv*(d2rvdxdy - v*d2rhodxdy - + rhoInv*(drhodx*(v*drhody - drvdy) - + drhody*(v*drhodx - drvdx))); - - /* Compute the second derivatives of the static energy. Note that this - term appears in the heat flux and therefore only the pure second - derivatives are needed. Hence, the cross-derivatives are omitted. */ - const su2double d2edxdx = rhoInv*(d2rEdxdx - TotalEnergy*d2rhodxdx - + 2.0*rhoInv*drhodx*(TotalEnergy*drhodx - drEdx)) - - u*d2udxdx - dudx*dudx - v*d2vdxdx - dvdx*dvdx; - const su2double d2edydy = rhoInv*(d2rEdydy - TotalEnergy*d2rhodydy - + 2.0*rhoInv*drhody*(TotalEnergy*drhody - drEdy)) - - u*d2udydy - dudy*dudy - v*d2vdydy - dvdy*dvdy; - - /* If an SGS model is used the eddy viscosity and its spatial - derivatives must be computed. */ - su2double ViscosityTurb = 0.0; - su2double dViscTurbdx = 0.0, dViscTurbdy = 0.0; - - if( SGSModelUsed ) { - const su2double dist = elem->wallDistance[i]; - ViscosityTurb = SGSModel->ComputeEddyViscosity_2D(rho, dudx, dudy, dvdx, - dvdy, lenScale, dist); - - SGSModel->ComputeGradEddyViscosity_2D(rho, drhodx, drhody, dudx, dudy, - dvdx, dvdy, d2udxdx, d2udydy, d2udxdy, - d2vdxdx, d2vdydy, d2vdxdy, lenScale, - dist, dViscTurbdx, dViscTurbdy); - } - - /* Compute the total viscosity, the total heat conductivity and their - gradients. Note that the heat conductivity is divided by the Cv, - because gradients of internal energy are computed and not temperature. */ - const su2double Viscosity = ViscosityLam + ViscosityTurb; - const su2double kOverCv = ViscosityLam *factHeatFlux_Lam - + ViscosityTurb*factHeatFlux_Turb; - - const su2double dViscDx = dViscLamdx + dViscTurbdx; - const su2double dViscDy = dViscLamdy + dViscTurbdy; - - const su2double dkOverCvdx = dViscLamdx *factHeatFlux_Lam - + dViscTurbdx*factHeatFlux_Turb; - const su2double dkOverCvdy = dViscLamdy *factHeatFlux_Lam - + dViscTurbdy*factHeatFlux_Turb; - - /* Abbreviations, which make it easier to compute the divergence term. */ - const su2double abv1 = drudx + drvdy; - const su2double abv2 = u*drhodx + v*drhody; - const su2double abv3 = u*(drEdx + dpdx) + v*(drEdy + dpdy); - const su2double abv4 = dudx + dvdy; - - /* Compute the divergence of the grid velocity. - SET TO ZERO FOR NOW. THIS IS NOT CORRECT!!!!. */ - const su2double divGridVel = 0.0; - - /* Set the pointer to store the divergence terms for this integration - point and compute these terms, multiplied by the integration weight - and Jacobian. */ - const su2double weightJac = weights[i]*Jac; - su2double *divFluxInt = divFlux + offInt; - - divFluxInt[0] = weightJac*(abv1 - rho*divGridVel - - gridVel[0]*drhodx - gridVel[1]*drhody); - divFluxInt[1] = weightJac*(dpdx + u*(abv1-abv2) - lambdaOverMu*abv4*dViscDx - + u*drudx + v*drudy - - lambdaOverMu*Viscosity*(d2udxdx + d2vdxdy) - - Viscosity*(2.0*d2udxdx + d2udydy + d2vdxdy) - - 2.0*dViscDx*dudx - dViscDy*(dudy+dvdx) - - ru*divGridVel - - gridVel[0]*drudx - gridVel[1]*drudy); - divFluxInt[2] = weightJac*(dpdy + v*(abv1-abv2) - lambdaOverMu*abv4*dViscDy - + u*drvdx + v*drvdy - - lambdaOverMu*Viscosity*(d2udxdy + d2vdydy) - - Viscosity*(2.0*d2vdydy + d2vdxdx + d2udxdy) - - dViscDx*(dudy + dvdx) - 2.0*dViscDy*dvdy - - rv*divGridVel - - gridVel[0]*drvdx - gridVel[1]*drvdy); - divFluxInt[3] = weightJac*(abv3 + Htot*(abv1 - abv2) - - abv4*lambdaOverMu*(Viscosity*abv4 + u*dViscDx + v*dViscDy) - - dkOverCvdx*dedx - dkOverCvdy*dedy - kOverCv*(d2edxdx + d2edydy) - - (Viscosity*dudx + u*dViscDx)*2.0*dudx - - (Viscosity*dvdy + v*dViscDy)*2.0*dvdy - - (Viscosity*dudy + u*dViscDy + Viscosity*dvdx + v*dViscDx)*(dudy + dvdx) - - Viscosity*u*(d2udxdx+d2udydy + (1.0+lambdaOverMu)*(d2udxdx+d2vdxdy)) - - Viscosity*v*(d2vdxdx+d2vdydy + (1.0+lambdaOverMu)*(d2udxdy+d2vdydy)) - - rE*divGridVel - - gridVel[0]*drEdx - gridVel[1]*drEdy); - - /* Add the body force to the flux divergence for the momentum and energy - equation. Note that the source terms are multiplied with minus the - integration weight in order to be consistent with the formulation of - the residual. Also note that for the energy source term the absolute - velocity must be taken and not the relative. */ - divFluxInt[1] -= weightJac*bodyForceX; - divFluxInt[2] -= weightJac*bodyForceY; - divFluxInt[3] -= weightJac*(u*bodyForceX + v*bodyForceY); - } - } - - /*--------------------------------------------------------------------------*/ - /*--- Add the source terms of the manufactured solution to the divergence---*/ - /*--- of the fluxes, if a manufactured solution is used. ---*/ - /*--------------------------------------------------------------------------*/ - - if( VerificationSolution ) { - if( VerificationSolution->IsManufacturedSolution() ) { - - /*--- Loop over the number of entities that are treated simultaneously. */ - for(unsigned short simul=0; simulcoorIntegrationPoints.data() + i*nDim; - - /* Easier storage of the metric terms in this integration point. - THIS IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, - THE DATA FOR THIS DOF FOR THE CURRENT TIME INTEGRATION POINT MUST - BE TAKEN. */ - const su2double *metricTerms = elem->metricTerms.data() + i*nMetricPerPoint; - const su2double weightJac = weights[i]*metricTerms[0]; - - /* Compute the source terms of the manufactured solution. - THIS IS A TEMPORARY IMPLEMENTATION. FOR AN ACTUAL TIME ACCURATE - SIMULATION THE CORRECT TIME MUST BE GIVEN TO THIS FUNCTION. */ - su2double sourceMan[4]; - VerificationSolution->GetMMSSourceTerm(coor, 0.0, sourceMan); - - /* Add the source terms to the flux divergence. Note that the source - terms are multiplied with minus the integration weight in order - to be consistent with the formulation of the residual. */ - divFluxInt[0] -= weightJac*sourceMan[0]; - divFluxInt[1] -= weightJac*sourceMan[1]; - divFluxInt[2] -= weightJac*sourceMan[2]; - divFluxInt[3] -= weightJac*sourceMan[3]; - } - } - } - } - - /*--------------------------------------------------------------------------*/ - /*--- Compute the residual in the DOFs, which is the matrix product of ---*/ - /*--- basisFunctionsIntTrans and divFlux. ---*/ - /*--------------------------------------------------------------------------*/ - - blasFunctions->gemm(nDOFs, NPad, nInt, basisFunctionsIntTrans, divFlux, res, config); -} - -void CFEM_DG_NSSolver::ADER_DG_NonAliasedPredictorResidual_3D(CConfig *config, - CVolumeElementFEM *elem, - const su2double *sol, - const unsigned short nSimul, - const unsigned short NPad, - su2double *res, - su2double *work) { - - /* Constant factor present in the heat flux vector, the inverse of - the specific heat at constant volume and ratio lambdaOverMu. */ - const su2double factHeatFlux_Lam = Gamma/Prandtl_Lam; - const su2double factHeatFlux_Turb = Gamma/Prandtl_Turb; - const su2double Gas_Constant = config->GetGas_ConstantND(); - const su2double CvInv = Gamma_Minus_One/Gas_Constant; - const su2double lambdaOverMu = -TWO3; - - /*--- Get the necessary information from the standard element. ---*/ - const unsigned short ind = elem->indStandardElement; - const unsigned short nInt = standardElementsSol[ind].GetNIntegration(); - const unsigned short nDOFs = elem->nDOFsSol; - const su2double *matBasisInt = standardElementsSol[ind].GetMatBasisFunctionsIntegration(); - const su2double *mat2ndDerBasisInt = standardElementsSol[ind].GetMat2ndDerBasisFunctionsInt(); - const su2double *basisFunctionsIntTrans = standardElementsSol[ind].GetBasisFunctionsIntegrationTrans(); - const su2double *weights = standardElementsSol[ind].GetWeightsIntegration(); - - unsigned short nPoly = standardElementsSol[ind].GetNPoly(); - if(nPoly == 0) nPoly = 1; - - /* Check if a body force is present and set it accordingly. */ - su2double bodyForceX = 0.0, bodyForceY = 0.0, bodyForceZ = 0.0; - if( config->GetBody_Force() ) { - const su2double *body_force_vector = config->GetBody_Force_Vector(); - bodyForceX = body_force_vector[0]; - bodyForceY = body_force_vector[1]; - bodyForceZ = body_force_vector[2]; - } - - /* Compute the length scale of the current element for the LES. */ - const su2double lenScale = elem->lenScale/nPoly; - - /* Set the pointers for solAndGradInt and divFlux to work. The same array - can be used for both help arrays. */ - su2double *solAndGradInt = work; - su2double *divFlux = work; - - /* Determine the offset between the solution variables and the r-derivatives, - which is also the offset between the r- and s-derivatives in the - integration points. */ - const unsigned short offDerivInt = NPad*nInt; - - /* Set the pointer for the second derivatives such that they are stored - after the first derivatives. */ - su2double *secDerSol = solAndGradInt + 4*NPad*nInt; /*(nDim+1)*NPad*nInt. */ - - /* Store the number of metric points per integration point for readability. */ - const unsigned short nMetricPerPoint = 10; /* nDim*nDim + 1. */ - - /* Store the number of additional metric points per integration point, which - are needed to compute the second derivatives. These terms take the - non-constant metric into account. */ - const unsigned short nMetric2ndDerPerPoint = 18; /*nDim*(nDim + nDim*(nDim-1)/2). */ - - /*--------------------------------------------------------------------------*/ - /*--- Interpolate the solution variables to the integration points and ---*/ - /*--- also determine the first and second derivatives of these variables ---*/ - /*--- in the integration points. All derivatives are w.r.t. the ---*/ - /*--- parametric coordinates. ---*/ - /*--------------------------------------------------------------------------*/ - - /* Compute the solution and the derivatives w.r.t. the parametric coordinates - in the integration points. The first argument is nInt*(nDim+1). */ - blasFunctions->gemm(nInt*4, NPad, nDOFs, matBasisInt, sol, solAndGradInt, config); - - /* Compute the second derivatives w.r.t. the parametric coordinates - in the integration points. */ - blasFunctions->gemm(nInt*6, NPad, nDOFs, mat2ndDerBasisInt, sol, secDerSol, config); - - /*--------------------------------------------------------------------------*/ - /*--- Compute the divergence of viscous fluxes, multiplied by the ---*/ - /*--- integration weight in the integration points of the element. ---*/ - /*--------------------------------------------------------------------------*/ - - /*--- Loop over the number of entities that are treated simultaneously. */ - for(unsigned short simul=0; simulSetTDState_rhoe(rho, StaticEnergy); - const su2double Pressure = FluidModel->GetPressure(); - const su2double Htot = rhoInv*(rE + Pressure); - - /* Compute the laminar viscosity and its derivative w.r.t. temperature. */ - const su2double ViscosityLam = FluidModel->GetLaminarViscosity(); - const su2double dViscLamdT = FluidModel->GetdmudT_rho(); - - /* Set the pointer to the grid velocities in this integration point. - THIS IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, - THE DATA FOR THIS SPATIAL INTEGRATION POINT FOR THE CURRENT TIME - INTEGRATION POINT MUST BE TAKEN. */ - const su2double *gridVel = elem->gridVelocities.data() + 3*i; /* nDim*i. */ - - /* Easier storage of the metric terms in this integration point. - THIS IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, - THE DATA FOR THIS SPATIAL INTEGRATION POINT FOR THE CURRENT TIME - INTEGRATION POINT MUST BE TAKEN. */ - const su2double *metricTerms = elem->metricTerms.data() + i*nMetricPerPoint; - - /* Compute the true metric terms. Note in metricTerms the actual metric - terms multiplied by the Jacobian are stored. */ - const su2double Jac = metricTerms[0]; - const su2double JacInv = 1.0/Jac; - - const su2double drdx = JacInv*metricTerms[1]; - const su2double drdy = JacInv*metricTerms[2]; - const su2double drdz = JacInv*metricTerms[3]; - - const su2double dsdx = JacInv*metricTerms[4]; - const su2double dsdy = JacInv*metricTerms[5]; - const su2double dsdz = JacInv*metricTerms[6]; - - const su2double dtdx = JacInv*metricTerms[7]; - const su2double dtdy = JacInv*metricTerms[8]; - const su2double dtdz = JacInv*metricTerms[9]; - - /* Compute the Cartesian gradients of the independent solution - variables from the gradients in parametric coordinates and the - metric terms in this integration point. */ - const su2double drhodx = solDr[0]*drdx + solDs[0]*dsdx + solDt[0]*dtdx; - const su2double drudx = solDr[1]*drdx + solDs[1]*dsdx + solDt[1]*dtdx; - const su2double drvdx = solDr[2]*drdx + solDs[2]*dsdx + solDt[2]*dtdx; - const su2double drwdx = solDr[3]*drdx + solDs[3]*dsdx + solDt[3]*dtdx; - const su2double drEdx = solDr[4]*drdx + solDs[4]*dsdx + solDt[4]*dtdx; - - const su2double drhody = solDr[0]*drdy + solDs[0]*dsdy + solDt[0]*dtdy; - const su2double drudy = solDr[1]*drdy + solDs[1]*dsdy + solDt[1]*dtdy; - const su2double drvdy = solDr[2]*drdy + solDs[2]*dsdy + solDt[2]*dtdy; - const su2double drwdy = solDr[3]*drdy + solDs[3]*dsdy + solDt[3]*dtdy; - const su2double drEdy = solDr[4]*drdy + solDs[4]*dsdy + solDt[4]*dtdy; - - const su2double drhodz = solDr[0]*drdz + solDs[0]*dsdz + solDt[0]*dtdz; - const su2double drudz = solDr[1]*drdz + solDs[1]*dsdz + solDt[1]*dtdz; - const su2double drvdz = solDr[2]*drdz + solDs[2]*dsdz + solDt[2]*dtdz; - const su2double drwdz = solDr[3]*drdz + solDs[3]*dsdz + solDt[3]*dtdz; - const su2double drEdz = solDr[4]*drdz + solDs[4]*dsdz + solDt[4]*dtdz; - - /* Pointer to the necessary additional metric terms needed to compute - the Cartesian second derivatives for this integration point. - HIS IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, - THE DATA FOR THIS SPATIAL INTEGRATION POINT FOR THE CURRENT TIME - INTEGRATION POINT MUST BE TAKEN. */ - const su2double *metricTerms2ndDer = elem->metricTerms2ndDer.data() - + i*nMetric2ndDerPerPoint; - - /* Compute the Cartesian second derivatives of the independent solution - variables from the gradients and second derivatives in parametric - coordinates and the metric terms and its derivatives w.r.t. the - parametric coordinates. */ - const su2double d2rhodxdx = solDrDr[0]*drdx*drdx + solDsDs[0]*dsdx*dsdx + solDtDt[0]*dtdx*dtdx - + 2.0*(solDrDs[0]*drdx*dsdx + solDrDt[0]*drdx*dtdx + solDsDt[0]*dsdx*dtdx) - + solDr[0]*metricTerms2ndDer[0] + solDs[0]*metricTerms2ndDer[1] - + solDt[0]*metricTerms2ndDer[2]; - const su2double d2rudxdx = solDrDr[1]*drdx*drdx + solDsDs[1]*dsdx*dsdx + solDtDt[1]*dtdx*dtdx - + 2.0*(solDrDs[1]*drdx*dsdx + solDrDt[1]*drdx*dtdx + solDsDt[1]*dsdx*dtdx) - + solDr[1]*metricTerms2ndDer[0] + solDs[1]*metricTerms2ndDer[1] - + solDt[1]*metricTerms2ndDer[2]; - const su2double d2rvdxdx = solDrDr[2]*drdx*drdx + solDsDs[2]*dsdx*dsdx + solDtDt[2]*dtdx*dtdx - + 2.0*(solDrDs[2]*drdx*dsdx + solDrDt[2]*drdx*dtdx + solDsDt[2]*dsdx*dtdx) - + solDr[2]*metricTerms2ndDer[0] + solDs[2]*metricTerms2ndDer[1] - + solDt[2]*metricTerms2ndDer[2]; - const su2double d2rwdxdx = solDrDr[3]*drdx*drdx + solDsDs[3]*dsdx*dsdx + solDtDt[3]*dtdx*dtdx - + 2.0*(solDrDs[3]*drdx*dsdx + solDrDt[3]*drdx*dtdx + solDsDt[3]*dsdx*dtdx) - + solDr[3]*metricTerms2ndDer[0] + solDs[3]*metricTerms2ndDer[1] - + solDt[3]*metricTerms2ndDer[2]; - const su2double d2rEdxdx = solDrDr[4]*drdx*drdx + solDsDs[4]*dsdx*dsdx + solDtDt[4]*dtdx*dtdx - + 2.0*(solDrDs[4]*drdx*dsdx + solDrDt[4]*drdx*dtdx + solDsDt[4]*dsdx*dtdx) - + solDr[4]*metricTerms2ndDer[0] + solDs[4]*metricTerms2ndDer[1] - + solDt[4]*metricTerms2ndDer[2]; - - const su2double d2rhodydy = solDrDr[0]*drdy*drdy + solDsDs[0]*dsdy*dsdy + solDtDt[0]*dtdy*dtdy - + 2.0*(solDrDs[0]*drdy*dsdy + solDrDt[0]*drdy*dtdy + solDsDt[0]*dsdy*dtdy) - + solDr[0]*metricTerms2ndDer[6] + solDs[0]*metricTerms2ndDer[7] - + solDt[0]*metricTerms2ndDer[8]; - const su2double d2rudydy = solDrDr[1]*drdy*drdy + solDsDs[1]*dsdy*dsdy + solDtDt[1]*dtdy*dtdy - + 2.0*(solDrDs[1]*drdy*dsdy + solDrDt[1]*drdy*dtdy + solDsDt[1]*dsdy*dtdy) - + solDr[1]*metricTerms2ndDer[6] + solDs[1]*metricTerms2ndDer[7] - + solDt[1]*metricTerms2ndDer[8]; - const su2double d2rvdydy = solDrDr[2]*drdy*drdy + solDsDs[2]*dsdy*dsdy + solDtDt[2]*dtdy*dtdy - + 2.0*(solDrDs[2]*drdy*dsdy + solDrDt[2]*drdy*dtdy + solDsDt[2]*dsdy*dtdy) - + solDr[2]*metricTerms2ndDer[6] + solDs[2]*metricTerms2ndDer[7] - + solDt[2]*metricTerms2ndDer[8]; - const su2double d2rwdydy = solDrDr[3]*drdy*drdy + solDsDs[3]*dsdy*dsdy + solDtDt[3]*dtdy*dtdy - + 2.0*(solDrDs[3]*drdy*dsdy + solDrDt[3]*drdy*dtdy + solDsDt[3]*dsdy*dtdy) - + solDr[3]*metricTerms2ndDer[6] + solDs[3]*metricTerms2ndDer[7] - + solDt[3]*metricTerms2ndDer[8]; - const su2double d2rEdydy = solDrDr[4]*drdy*drdy + solDsDs[4]*dsdy*dsdy + solDtDt[4]*dtdy*dtdy - + 2.0*(solDrDs[4]*drdy*dsdy + solDrDt[4]*drdy*dtdy + solDsDt[4]*dsdy*dtdy) - + solDr[4]*metricTerms2ndDer[6] + solDs[4]*metricTerms2ndDer[7] - + solDt[4]*metricTerms2ndDer[8]; - - const su2double d2rhodzdz = solDrDr[0]*drdz*drdz + solDsDs[0]*dsdz*dsdz + solDtDt[0]*dtdz*dtdz - + 2.0*(solDrDs[0]*drdz*dsdz + solDrDt[0]*drdz*dtdz + solDsDt[0]*dsdz*dtdz) - + solDr[0]*metricTerms2ndDer[15] + solDs[0]*metricTerms2ndDer[16] - + solDt[0]*metricTerms2ndDer[17]; - const su2double d2rudzdz = solDrDr[1]*drdz*drdz + solDsDs[1]*dsdz*dsdz + solDtDt[1]*dtdz*dtdz - + 2.0*(solDrDs[1]*drdz*dsdz + solDrDt[1]*drdz*dtdz + solDsDt[1]*dsdz*dtdz) - + solDr[1]*metricTerms2ndDer[15] + solDs[1]*metricTerms2ndDer[16] - + solDt[1]*metricTerms2ndDer[17]; - const su2double d2rvdzdz = solDrDr[2]*drdz*drdz + solDsDs[2]*dsdz*dsdz + solDtDt[2]*dtdz*dtdz - + 2.0*(solDrDs[2]*drdz*dsdz + solDrDt[2]*drdz*dtdz + solDsDt[2]*dsdz*dtdz) - + solDr[2]*metricTerms2ndDer[15] + solDs[2]*metricTerms2ndDer[16] - + solDt[2]*metricTerms2ndDer[17]; - const su2double d2rwdzdz = solDrDr[3]*drdz*drdz + solDsDs[3]*dsdz*dsdz + solDtDt[3]*dtdz*dtdz - + 2.0*(solDrDs[3]*drdz*dsdz + solDrDt[3]*drdz*dtdz + solDsDt[3]*dsdz*dtdz) - + solDr[3]*metricTerms2ndDer[15] + solDs[3]*metricTerms2ndDer[16] - + solDt[3]*metricTerms2ndDer[17]; - const su2double d2rEdzdz = solDrDr[4]*drdz*drdz + solDsDs[4]*dsdz*dsdz + solDtDt[4]*dtdz*dtdz - + 2.0*(solDrDs[4]*drdz*dsdz + solDrDt[4]*drdz*dtdz + solDsDt[4]*dsdz*dtdz) - + solDr[4]*metricTerms2ndDer[15] + solDs[4]*metricTerms2ndDer[16] - + solDt[4]*metricTerms2ndDer[17]; - - const su2double d2rhodxdy = solDrDr[0]*drdx*drdy + solDsDs[0]*dsdx*dsdy + solDtDt[0]*dtdx*dtdy - + solDrDs[0]*(drdx*dsdy + dsdx*drdy) + solDrDt[0]*(drdx*dtdy + dtdx*drdy) - + solDsDt[0]*(dsdx*dtdy + dtdx*dsdy) + solDr[0]*metricTerms2ndDer[3] - + solDs[0]*metricTerms2ndDer[4] + solDt[0]*metricTerms2ndDer[5]; - const su2double d2rudxdy = solDrDr[1]*drdx*drdy + solDsDs[1]*dsdx*dsdy + solDtDt[1]*dtdx*dtdy - + solDrDs[1]*(drdx*dsdy + dsdx*drdy) + solDrDt[1]*(drdx*dtdy + dtdx*drdy) - + solDsDt[1]*(dsdx*dtdy + dtdx*dsdy) + solDr[1]*metricTerms2ndDer[3] - + solDs[1]*metricTerms2ndDer[4] + solDt[1]*metricTerms2ndDer[5]; - const su2double d2rvdxdy = solDrDr[2]*drdx*drdy + solDsDs[2]*dsdx*dsdy + solDtDt[2]*dtdx*dtdy - + solDrDs[2]*(drdx*dsdy + dsdx*drdy) + solDrDt[2]*(drdx*dtdy + dtdx*drdy) - + solDsDt[2]*(dsdx*dtdy + dtdx*dsdy) + solDr[2]*metricTerms2ndDer[3] - + solDs[2]*metricTerms2ndDer[4] + solDt[2]*metricTerms2ndDer[5]; - const su2double d2rwdxdy = solDrDr[3]*drdx*drdy + solDsDs[3]*dsdx*dsdy + solDtDt[3]*dtdx*dtdy - + solDrDs[3]*(drdx*dsdy + dsdx*drdy) + solDrDt[3]*(drdx*dtdy + dtdx*drdy) - + solDsDt[3]*(dsdx*dtdy + dtdx*dsdy) + solDr[3]*metricTerms2ndDer[3] - + solDs[3]*metricTerms2ndDer[4] + solDt[3]*metricTerms2ndDer[5]; - - const su2double d2rhodxdz = solDrDr[0]*drdx*drdz + solDsDs[0]*dsdx*dsdz + solDtDt[0]*dtdx*dtdz - + solDrDs[0]*(drdx*dsdz + dsdx*drdz) + solDrDt[0]*(drdx*dtdz + dtdx*drdz) - + solDsDt[0]*(dsdx*dtdz + dtdx*dsdz) + solDr[0]*metricTerms2ndDer[9] - + solDs[0]*metricTerms2ndDer[10] + solDt[0]*metricTerms2ndDer[11]; - const su2double d2rudxdz = solDrDr[1]*drdx*drdz + solDsDs[1]*dsdx*dsdz + solDtDt[1]*dtdx*dtdz - + solDrDs[1]*(drdx*dsdz + dsdx*drdz) + solDrDt[1]*(drdx*dtdz + dtdx*drdz) - + solDsDt[1]*(dsdx*dtdz + dtdx*dsdz) + solDr[1]*metricTerms2ndDer[9] - + solDs[1]*metricTerms2ndDer[10] + solDt[1]*metricTerms2ndDer[11]; - const su2double d2rvdxdz = solDrDr[2]*drdx*drdz + solDsDs[2]*dsdx*dsdz + solDtDt[2]*dtdx*dtdz - + solDrDs[2]*(drdx*dsdz + dsdx*drdz) + solDrDt[2]*(drdx*dtdz + dtdx*drdz) - + solDsDt[2]*(dsdx*dtdz + dtdx*dsdz) + solDr[2]*metricTerms2ndDer[9] - + solDs[2]*metricTerms2ndDer[10] + solDt[2]*metricTerms2ndDer[11]; - const su2double d2rwdxdz = solDrDr[3]*drdx*drdz + solDsDs[3]*dsdx*dsdz + solDtDt[3]*dtdx*dtdz - + solDrDs[3]*(drdx*dsdz + dsdx*drdz) + solDrDt[3]*(drdx*dtdz + dtdx*drdz) - + solDsDt[3]*(dsdx*dtdz + dtdx*dsdz) + solDr[3]*metricTerms2ndDer[9] - + solDs[3]*metricTerms2ndDer[10] + solDt[3]*metricTerms2ndDer[11]; - - const su2double d2rhodydz = solDrDr[0]*drdy*drdz + solDsDs[0]*dsdy*dsdz + solDtDt[0]*dtdy*dtdz - + solDrDs[0]*(drdy*dsdz + dsdy*drdz) + solDrDt[0]*(drdy*dtdz + dtdy*drdz) - + solDsDt[0]*(dsdy*dtdz + dtdy*dsdz) + solDr[0]*metricTerms2ndDer[12] - + solDs[0]*metricTerms2ndDer[13] + solDt[0]*metricTerms2ndDer[14]; - const su2double d2rudydz = solDrDr[1]*drdy*drdz + solDsDs[1]*dsdy*dsdz + solDtDt[1]*dtdy*dtdz - + solDrDs[1]*(drdy*dsdz + dsdy*drdz) + solDrDt[1]*(drdy*dtdz + dtdy*drdz) - + solDsDt[1]*(dsdy*dtdz + dtdy*dsdz) + solDr[1]*metricTerms2ndDer[12] - + solDs[1]*metricTerms2ndDer[13] + solDt[1]*metricTerms2ndDer[14]; - const su2double d2rvdydz = solDrDr[2]*drdy*drdz + solDsDs[2]*dsdy*dsdz + solDtDt[2]*dtdy*dtdz - + solDrDs[2]*(drdy*dsdz + dsdy*drdz) + solDrDt[2]*(drdy*dtdz + dtdy*drdz) - + solDsDt[2]*(dsdy*dtdz + dtdy*dsdz) + solDr[2]*metricTerms2ndDer[12] - + solDs[2]*metricTerms2ndDer[13] + solDt[2]*metricTerms2ndDer[14]; - const su2double d2rwdydz = solDrDr[3]*drdy*drdz + solDsDs[3]*dsdy*dsdz + solDtDt[3]*dtdy*dtdz - + solDrDs[3]*(drdy*dsdz + dsdy*drdz) + solDrDt[3]*(drdy*dtdz + dtdy*drdz) - + solDsDt[3]*(dsdy*dtdz + dtdy*dsdz) + solDr[3]*metricTerms2ndDer[12] - + solDs[3]*metricTerms2ndDer[13] + solDt[3]*metricTerms2ndDer[14]; - - /* Compute the Cartesian gradients of the pressure, velocity components, - static energy and dynamic viscosity. */ - const su2double dpdx = Gamma_Minus_One*(drEdx + kinEnergy*drhodx - - u*drudx - v*drvdx - w*drwdx); - const su2double dpdy = Gamma_Minus_One*(drEdy + kinEnergy*drhody - - u*drudy - v*drvdy - w*drwdy); - const su2double dpdz = Gamma_Minus_One*(drEdz + kinEnergy*drhodz - - u*drudz - v*drvdz - w*drwdz); - - const su2double dudx = rhoInv*(drudx - u*drhodx); - const su2double dudy = rhoInv*(drudy - u*drhody); - const su2double dudz = rhoInv*(drudz - u*drhodz); - - const su2double dvdx = rhoInv*(drvdx - v*drhodx); - const su2double dvdy = rhoInv*(drvdy - v*drhody); - const su2double dvdz = rhoInv*(drvdz - v*drhodz); - - const su2double dwdx = rhoInv*(drwdx - w*drhodx); - const su2double dwdy = rhoInv*(drwdy - w*drhody); - const su2double dwdz = rhoInv*(drwdz - w*drhodz); - - const su2double dedx = rhoInv*(drEdx - TotalEnergy*drhodx) - u*dudx - v*dvdx - w*dwdx; - const su2double dedy = rhoInv*(drEdy - TotalEnergy*drhody) - u*dudy - v*dvdy - w*dwdy; - const su2double dedz = rhoInv*(drEdz - TotalEnergy*drhodz) - u*dudz - v*dvdz - w*dwdz; - - const su2double dViscLamdx = CvInv*dedx*dViscLamdT; - const su2double dViscLamdy = CvInv*dedy*dViscLamdT; - const su2double dViscLamdz = CvInv*dedz*dViscLamdT; - - /*--- Compute the second derivatives of the velocity components. ---*/ - const su2double d2udxdx = rhoInv*(d2rudxdx - u*d2rhodxdx - + 2.0*rhoInv*drhodx*(u*drhodx - drudx)); - const su2double d2udydy = rhoInv*(d2rudydy - u*d2rhodydy - + 2.0*rhoInv*drhody*(u*drhody - drudy)); - const su2double d2udzdz = rhoInv*(d2rudzdz - u*d2rhodzdz - + 2.0*rhoInv*drhodz*(u*drhodz - drudz)); - const su2double d2udxdy = rhoInv*(d2rudxdy - u*d2rhodxdy - + rhoInv*(drhodx*(u*drhody - drudy) - + drhody*(u*drhodx - drudx))); - const su2double d2udxdz = rhoInv*(d2rudxdz - u*d2rhodxdz - + rhoInv*(drhodx*(u*drhodz - drudz) - + drhodz*(u*drhodx - drudx))); - const su2double d2udydz = rhoInv*(d2rudydz - u*d2rhodydz - + rhoInv*(drhody*(u*drhodz - drudz) - + drhodz*(u*drhody - drudy))); - - const su2double d2vdxdx = rhoInv*(d2rvdxdx - v*d2rhodxdx - + 2.0*rhoInv*drhodx*(v*drhodx - drvdx)); - const su2double d2vdydy = rhoInv*(d2rvdydy - v*d2rhodydy - + 2.0*rhoInv*drhody*(v*drhody - drvdy)); - const su2double d2vdzdz = rhoInv*(d2rvdzdz - v*d2rhodzdz - + 2.0*rhoInv*drhodz*(v*drhodz - drvdz)); - const su2double d2vdxdy = rhoInv*(d2rvdxdy - v*d2rhodxdy - + rhoInv*(drhodx*(v*drhody - drvdy) - + drhody*(v*drhodx - drvdx))); - const su2double d2vdxdz = rhoInv*(d2rvdxdz - v*d2rhodxdz - + rhoInv*(drhodx*(v*drhodz - drvdz) - + drhodz*(v*drhodx - drvdx))); - const su2double d2vdydz = rhoInv*(d2rvdydz - v*d2rhodydz - + rhoInv*(drhody*(v*drhodz - drvdz) - + drhodz*(v*drhody - drvdy))); - - const su2double d2wdxdx = rhoInv*(d2rwdxdx - w*d2rhodxdx - + 2.0*rhoInv*drhodx*(w*drhodx - drwdx)); - const su2double d2wdydy = rhoInv*(d2rwdydy - w*d2rhodydy - + 2.0*rhoInv*drhody*(w*drhody - drwdy)); - const su2double d2wdzdz = rhoInv*(d2rwdzdz - w*d2rhodzdz - + 2.0*rhoInv*drhodz*(w*drhodz - drwdz)); - const su2double d2wdxdy = rhoInv*(d2rwdxdy - w*d2rhodxdy - + rhoInv*(drhodx*(w*drhody - drwdy) - + drhody*(w*drhodx - drwdx))); - const su2double d2wdxdz = rhoInv*(d2rwdxdz - w*d2rhodxdz - + rhoInv*(drhodx*(w*drhodz - drwdz) - + drhodz*(w*drhodx - drwdx))); - const su2double d2wdydz = rhoInv*(d2rwdydz - w*d2rhodydz - + rhoInv*(drhody*(w*drhodz - drwdz) - + drhodz*(w*drhody - drwdy))); - - /* Compute the second derivatives of the static energy. Note that this - term appears in the heat flux and therefore only the pure second - derivatives are needed. Hence, the cross-derivatives are omitted. */ - const su2double d2edxdx = rhoInv*(d2rEdxdx - TotalEnergy*d2rhodxdx - + 2.0*rhoInv*drhodx*(TotalEnergy*drhodx - drEdx)) - - u*d2udxdx - dudx*dudx - v*d2vdxdx - dvdx*dvdx - - w*d2wdxdx - dwdx*dwdx; - const su2double d2edydy = rhoInv*(d2rEdydy - TotalEnergy*d2rhodydy - + 2.0*rhoInv*drhody*(TotalEnergy*drhody - drEdy)) - - u*d2udydy - dudy*dudy - v*d2vdydy - dvdy*dvdy - - w*d2wdydy - dwdy*dwdy; - const su2double d2edzdz = rhoInv*(d2rEdzdz - TotalEnergy*d2rhodzdz - + 2.0*rhoInv*drhodz*(TotalEnergy*drhodz - drEdz)) - - u*d2udzdz - dudz*dudz - v*d2vdzdz - dvdz*dvdz - - w*d2wdzdz - dwdz*dwdz; - - /*--- If an SGS model is used the eddy viscosity and its spatial - derivatives must be computed. ---*/ - su2double ViscosityTurb = 0.0; - su2double dViscTurbdx = 0.0, dViscTurbdy = 0.0, dViscTurbdz = 0.0; - - if( SGSModelUsed ) { - const su2double dist = elem->wallDistance[i]; - ViscosityTurb = SGSModel->ComputeEddyViscosity_3D(rho, dudx, dudy, dudz, - dvdx, dvdy, dvdz, dwdx, - dwdy, dwdz, lenScale, dist); - - SGSModel->ComputeGradEddyViscosity_3D(rho, drhodx, drhody, drhodz, dudx, dudy, - dudz, dvdx, dvdy, dvdz, dwdx, dwdy, dwdz, - d2udxdx, d2udydy, d2udzdz, d2udxdy, - d2udxdz, d2udydz, d2vdxdx, d2vdydy, - d2vdzdz, d2vdxdy, d2vdxdz, d2vdydz, - d2wdxdx, d2wdydy, d2wdzdz, d2wdxdy, - d2wdxdz, d2wdydz, lenScale, dist, - dViscTurbdx, dViscTurbdy, dViscTurbdz); - } - - /*--- Compute the total viscosity, the total heat conductivity and their - gradients. Note that the heat conductivity is divided by the Cv, - because gradients of internal energy are computed and not temperature. ---*/ - const su2double Viscosity = ViscosityLam + ViscosityTurb; - const su2double kOverCv = ViscosityLam *factHeatFlux_Lam - + ViscosityTurb*factHeatFlux_Turb; - - const su2double dViscDx = dViscLamdx + dViscTurbdx; - const su2double dViscDy = dViscLamdy + dViscTurbdy; - const su2double dViscDz = dViscLamdz + dViscTurbdz; - - const su2double dkOverCvdx = dViscLamdx *factHeatFlux_Lam - + dViscTurbdx*factHeatFlux_Turb; - const su2double dkOverCvdy = dViscLamdy *factHeatFlux_Lam - + dViscTurbdy*factHeatFlux_Turb; - const su2double dkOverCvdz = dViscLamdz *factHeatFlux_Lam - + dViscTurbdz*factHeatFlux_Turb; - - /* Abbreviations, which make it easier to compute the divergence term. */ - const su2double abv1 = drudx + drvdy + drwdz; - const su2double abv2 = u*drhodx + v*drhody + w*drhodz; - const su2double abv3 = u*(drEdx + dpdx) + v*(drEdy + dpdy) + w*(drEdz + dpdz); - const su2double abv4 = dudx + dvdy + dwdz; - - /*--- Compute the divergence of the grid velocity. - SET TO ZERO FOR NOW. THIS IS NOT CORRECT!!!!. ---*/ - const su2double divGridVel = 0.0; - - /* Set the pointer to store the divergence terms for this integration - point and compute these terms, multiplied by the integration weight - and Jacobian. */ - const su2double weightJac = weights[i]*Jac; - su2double *divFluxInt = divFlux + offInt; - - divFluxInt[0] = weightJac*(abv1 - rho*divGridVel - gridVel[0]*drhodx - - gridVel[1]*drhody - gridVel[2]*drhodz); - divFluxInt[1] = weightJac*(dpdx + u*(abv1-abv2) - lambdaOverMu*abv4*dViscDx - + u*drudx + v*drudy + w*drudz - - lambdaOverMu*Viscosity*(d2udxdx + d2vdxdy + d2wdxdz) - - Viscosity*(2.0*d2udxdx + d2udydy + d2vdxdy + d2udzdz + d2wdxdz) - - 2.0*dViscDx*dudx - dViscDy*(dudy+dvdx) - dViscDz*(dudz+dwdx) - - ru*divGridVel - - gridVel[0]*drudx - gridVel[1]*drudy - gridVel[2]*drudz); - divFluxInt[2] = weightJac*(dpdy + v*(abv1-abv2) - lambdaOverMu*abv4*dViscDy - + u*drvdx + v*drvdy + w*drvdz - - lambdaOverMu*Viscosity*(d2udxdy + d2vdydy + d2wdydz) - - Viscosity*(d2udxdy + d2vdxdx + 2.0*d2vdydy + d2vdzdz + d2wdydz) - - dViscDx*(dudy + dvdx) - 2.0*dViscDy*dvdy - dViscDz*(dvdz+dwdy) - - rv*divGridVel - - gridVel[0]*drvdx - gridVel[1]*drvdy - gridVel[2]*drvdz); - divFluxInt[3] = weightJac*(dpdz + w*(abv1-abv2) - lambdaOverMu*abv4*dViscDz - + u*drwdx + v*drwdy + w*drwdz - - lambdaOverMu*Viscosity*(d2udxdz + d2vdydz + d2wdzdz) - - Viscosity*(d2udxdz + d2wdxdx + d2vdydz + d2wdydy + 2.0*d2wdzdz) - - dViscDx*(dudz+dwdx) - dViscDy*(dvdz+dwdy) - 2.0*dViscDz*dwdz - - rw*divGridVel - - gridVel[0]*drwdx - gridVel[1]*drwdy - gridVel[2]*drwdz); - divFluxInt[4] = weightJac*(abv3 + Htot*(abv1 - abv2) - - abv4*lambdaOverMu*(Viscosity*abv4 + u*dViscDx + v*dViscDy + w*dViscDz) - - dkOverCvdx*dedx - dkOverCvdy*dedy - dkOverCvdz*dedz - - kOverCv*(d2edxdx + d2edydy + d2edzdz) - - (Viscosity*dudx + u*dViscDx)*2.0*dudx - - (Viscosity*dvdy + v*dViscDy)*2.0*dvdy - - (Viscosity*dwdz + w*dViscDz)*2.0*dwdz - - (Viscosity*dudy + u*dViscDy + Viscosity*dvdx + v*dViscDx)*(dudy + dvdx) - - (Viscosity*dudz + u*dViscDz + Viscosity*dwdx + w*dViscDx)*(dudz + dwdx) - - (Viscosity*dvdz + v*dViscDz + Viscosity*dwdy + w*dViscDy)*(dvdz + dwdy) - - Viscosity*u*(d2udxdx+d2udydy+d2udzdz + (1.0+lambdaOverMu)*(d2udxdx+d2vdxdy+d2wdxdz)) - - Viscosity*v*(d2vdxdx+d2vdydy+d2vdzdz + (1.0+lambdaOverMu)*(d2udxdy+d2vdydy+d2wdydz)) - - Viscosity*w*(d2wdxdx+d2wdydy+d2wdzdz + (1.0+lambdaOverMu)*(d2udxdz+d2vdydz+d2wdzdz)) - - rE*divGridVel - - gridVel[0]*drEdx - gridVel[1]*drEdy - gridVel[2]*drEdz); - - /* Add the body force to the flux divergence for the momentum and energy - equation. Note that the source terms are multiplied with minus the - integration weight in order to be consistent with the formulation of - the residual. Also note that for the energy source term the absolute - velocity must be taken and not the relative. */ - divFluxInt[1] -= weightJac*bodyForceX; - divFluxInt[2] -= weightJac*bodyForceY; - divFluxInt[3] -= weightJac*bodyForceZ; - divFluxInt[4] -= weightJac*(u*bodyForceX + v*bodyForceY + w*bodyForceZ); - } - } - - /*--------------------------------------------------------------------------*/ - /*--- Add the source terms of the manufactured solution to the divergence---*/ - /*--- of the fluxes, if a manufactured solution is used. ---*/ - /*--------------------------------------------------------------------------*/ - - if( VerificationSolution ) { - if( VerificationSolution->IsManufacturedSolution() ) { - - /*--- Loop over the number of entities that are treated simultaneously. */ - for(unsigned short simul=0; simulcoorIntegrationPoints.data() + i*nDim; - - /* Easier storage of the metric terms in this integration point. - THIS IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, - THE DATA FOR THIS DOF FOR THE CURRENT TIME INTEGRATION POINT MUST - BE TAKEN. */ - const su2double *metricTerms = elem->metricTerms.data() + i*nMetricPerPoint; - const su2double weightJac = weights[i]*metricTerms[0]; - - /* Compute the source terms of the manufactured solution. - THIS IS A TEMPORARY IMPLEMENTATION. FOR AN ACTUAL TIME ACCURATE - SIMULATION THE CORRECT TIME MUST BE GIVEN TO THIS FUNCTION. */ - su2double sourceMan[5]; - VerificationSolution->GetMMSSourceTerm(coor, 0.0, sourceMan); - - /* Add the source terms to the flux divergence. Note that the source - terms are multiplied with minus the integration weight in order - to be consistent with the formulation of the residual. */ - divFluxInt[0] -= weightJac*sourceMan[0]; - divFluxInt[1] -= weightJac*sourceMan[1]; - divFluxInt[2] -= weightJac*sourceMan[2]; - divFluxInt[3] -= weightJac*sourceMan[3]; - divFluxInt[4] -= weightJac*sourceMan[4]; - } - } - } - } - - /*--------------------------------------------------------------------------*/ - /*--- Compute the residual in the DOFs, which is the matrix product of ---*/ - /*--- basisFunctionsIntTrans and divFlux. ---*/ - /*--------------------------------------------------------------------------*/ - - blasFunctions->gemm(nDOFs, NPad, nInt, basisFunctionsIntTrans, divFlux, res, config); -} - -void CFEM_DG_NSSolver::Shock_Capturing_DG(CConfig *config, - const unsigned long elemBeg, - const unsigned long elemEnd, - su2double *workArray) { - - /*--- Run shock capturing algorithm ---*/ - switch( config->GetKind_FEM_DG_Shock() ) { - case NONE: - break; - case PERSSON: - Shock_Capturing_DG_Persson(elemBeg, elemEnd, workArray); - break; - } - -} -void CFEM_DG_NSSolver::Shock_Capturing_DG_Persson(const unsigned long elemBeg, - const unsigned long elemEnd, - su2double *workArray) { - - /*--- Dummy variable for storing shock sensor value temporarily ---*/ - su2double sensorVal, sensorLowerBound, machNorm, machMax; - su2double DensityInv, Velocity2, StaticEnergy, SoundSpeed2, Velocity2Rel; - - bool shockExist; - unsigned short nDOFsPm1; // Number of DOFs up to polynomial degree p-1 - - /*--- Loop over the given range of elements to sense the shock. If shock exists, - add artificial viscosity for DG FEM formulation to the residual. ---*/ - for(unsigned long l=elemBeg; lSetTDState_rhoe(sol[0], StaticEnergy); - SoundSpeed2 = FluidModel->GetSoundSpeed2(); - machSolDOFs[iInd] = sqrt( Velocity2Rel/SoundSpeed2 ); - machMax = max(machSolDOFs[iInd],machMax); - } - - /* Change the solution coefficients to modal form from nodal form */ - for(unsigned short i=0; i 1.0) { - // !!!!!Threshold value for sensorVal should be further investigated - if(sensorVal > 1.e-15) { - machNorm = 0.0; - - /*--- Get L2 norm square of vecTemp ---*/ - for (unsigned short i=0; i sensorLowerBound ) { - // Following value is initial guess. - volElem[l].shockArtificialViscosity = 1.e-10; - } - else { - volElem[l].shockArtificialViscosity = 0.0; - } - } - else { - volElem[l].shockArtificialViscosity = 0.0; - } - } -} - -void CFEM_DG_NSSolver::Volume_Residual(CConfig *config, - const unsigned long elemBeg, - const unsigned long elemEnd, - su2double *workArray) { - - /*--- Determine whether a body force term is present. ---*/ - bool body_force = config->GetBody_Force(); - const su2double *body_force_vector = body_force ? config->GetBody_Force_Vector() : NULL; - - /*--- Get the physical time if necessary. ---*/ - su2double time = 0.0; - if (config->GetTime_Marching()) time = config->GetPhysicalTime(); - - /* Constant factor present in the heat flux vector. */ - const su2double factHeatFlux_Lam = Gamma/Prandtl_Lam; - const su2double factHeatFlux_Turb = Gamma/Prandtl_Turb; - - /* Determine the number of elements that are treated simultaneously - in the matrix products to obtain good gemm performance. */ - const unsigned short nPadInput = config->GetSizeMatMulPadding(); - const unsigned short nElemSimul = nPadInput/nVar; - - /* Determine the minimum padded size in the matrix multiplications, which - corresponds to 64 byte alignment. */ - const unsigned short nPadMin = 64/sizeof(passivedouble); - - /* Set the number of bytes that must be copied in the memcpy calls. */ - const unsigned long nBytes = nVar*sizeof(su2double); - - /* Store the number of metric points per integration point, which depends - on the number of dimensions. */ - const unsigned short nMetricPerPoint = nDim*nDim + 1; - - /*--- Loop over the given element range to compute the contribution of the - volume integral in the DG FEM formulation to the residual. Multiple - elements are treated simultaneously to improve the performance - of the matrix multiplications. As a consequence, the update of the - counter l happens at the end of this loop section. ---*/ - for(unsigned long l=elemBeg; lgemm(nInt*(nDim+1), NPad, nDOFs, matBasisInt, solDOFs, solAndGradInt, config); - - /*------------------------------------------------------------------------*/ - /*--- Step 2: Compute the total fluxes (inviscid fluxes minus the ---*/ - /*--- viscous fluxes), multiplied by minus the integration ---*/ - /*--- weight, in the integration points. ---*/ - /*------------------------------------------------------------------------*/ - - /* Determine the offset between the solution variables and the r-derivatives, - which is also the offset between the r- and s-derivatives and the offset - between s- and t-derivatives. */ - const unsigned short offDeriv = NPad*nInt; - - /* Make a distinction between two and three space dimensions - in order to have the most efficient code. */ - switch( nDim ) { - - case 2: { - - /* 2D simulation. Loop over the chunk of elements and loop over the - integration points of the elements to compute the fluxes. */ - for(unsigned short ll=0; llSetTDState_rhoe(sol[0], StaticEnergy); - const su2double Pressure = FluidModel->GetPressure(); - const su2double ViscosityLam = FluidModel->GetLaminarViscosity(); - - /*--- If an SGS model is used the eddy viscosity must be computed. ---*/ - su2double ViscosityTurb = 0.0; - if( SGSModelUsed ) { - const su2double lenScale = volElem[lInd].lenScale/nPoly; - ViscosityTurb = SGSModel->ComputeEddyViscosity_2D(sol[0], dudx, dudy, - dvdx, dvdy, lenScale, - volElem[lInd].wallDistance[i]); - } - - /* Compute the total viscosity and heat conductivity. Note that the heat - conductivity is divided by the Cv, because gradients of internal energy - are computed and not temperature. */ - const su2double Viscosity = ViscosityLam + ViscosityTurb; - const su2double kOverCv = ViscosityLam *factHeatFlux_Lam - + ViscosityTurb*factHeatFlux_Turb; - - /*--- Set the value of the second viscosity and compute the divergence - term in the viscous normal stresses. ---*/ - const su2double lambda = -TWO3*Viscosity; - const su2double lamDivTerm = lambda*divVel; - - /*--- Compute the viscous stress tensor and minus the heatflux vector. ---*/ - const su2double tauxx = 2.0*Viscosity*dudx + lamDivTerm; - const su2double tauyy = 2.0*Viscosity*dvdy + lamDivTerm; - const su2double tauxy = Viscosity*(dudy + dvdx); - - const su2double qx = kOverCv*dStaticEnergyDx; - const su2double qy = kOverCv*dStaticEnergyDy; - - /* Compute the relative velocities w.r.t. the grid. */ - const su2double uRel = u - gridVel[0]; - const su2double vRel = v - gridVel[1]; - - /* Compute the viscous normal stress minus the pressure. */ - const su2double tauxxMP = tauxx - Pressure; - const su2double tauyyMP = tauyy - Pressure; - - /* Set the pointer for the fluxes in this integration point. */ - su2double *flux = fluxes + nDim*iNPad + llNVar; - - /*--- Fluxes in r-direction. */ - const su2double Ur = uRel*wDrdx + vRel*wDrdy; - - flux[0] = sol[0]*Ur; - flux[1] = sol[1]*Ur - tauxxMP*wDrdx - tauxy*wDrdy; - flux[2] = sol[2]*Ur - tauxy*wDrdx - tauyyMP*wDrdy; - flux[3] = sol[3]*Ur - (u*tauxxMP + v*tauxy + qx)*wDrdx - - (u*tauxy + v*tauyyMP + qy)*wDrdy; - - /*--- Fluxes in s-direction. */ - flux = flux + NPad; - const su2double Us = uRel*wDsdx + vRel*wDsdy; - - flux[0] = sol[0]*Us; - flux[1] = sol[1]*Us - tauxxMP*wDsdx - tauxy*wDsdy; - flux[2] = sol[2]*Us - tauxy*wDsdx - tauyyMP*wDsdy; - flux[3] = sol[3]*Us - (u*tauxxMP + v*tauxy + qx)*wDsdx - - (u*tauxy + v*tauyyMP + qy)*wDsdy; - - /*--- If needed, compute the body forces in this integration point. - Note that the source terms are multiplied with minus the - integration weight in order to be consistent with the - formulation of the residual. Note that for the energy source - term the absolute velocity must be taken and not the - relative. ---*/ - if( body_force ) { - su2double *source = sources + iNPad + llNVar; - const su2double weightJac = weights[i]*Jac; - - source[0] = 0.0; - source[1] = -weightJac*body_force_vector[0]; - source[2] = -weightJac*body_force_vector[1]; - source[3] = -weightJac*(u*body_force_vector[0] + v*body_force_vector[1]); - } - } - } - - break; - } - - /*----------------------------------------------------------------------*/ - - case 3: { - - /* 3D simulation. Loop over the chunk of elements and loop over the - integration points of the elements to compute the fluxes. */ - for(unsigned short ll=0; llSetTDState_rhoe(sol[0], StaticEnergy); - const su2double Pressure = FluidModel->GetPressure(); - const su2double ViscosityLam = FluidModel->GetLaminarViscosity(); - - /*--- If an SGS model is used the eddy viscosity must be computed. ---*/ - su2double ViscosityTurb = 0.0; - if( SGSModelUsed ) { - const su2double lenScale = volElem[lInd].lenScale/nPoly; - ViscosityTurb = SGSModel->ComputeEddyViscosity_3D(sol[0], dudx, dudy, dudz, - dvdx, dvdy, dvdz, dwdx, - dwdy, dwdz, lenScale, - volElem[lInd].wallDistance[i]); - } - - /* Compute the total viscosity and heat conductivity. Note that the heat - conductivity is divided by the Cv, because gradients of internal energy - are computed and not temperature. */ - const su2double Viscosity = ViscosityLam + ViscosityTurb; - const su2double kOverCv = ViscosityLam *factHeatFlux_Lam - + ViscosityTurb*factHeatFlux_Turb; - - /*--- Set the value of the second viscosity and compute the divergence - term in the viscous normal stresses. ---*/ - const su2double lambda = -TWO3*Viscosity; - const su2double lamDivTerm = lambda*divVel; - - /*--- Compute the viscous stress tensor and minus the heatflux vector. ---*/ - const su2double tauxx = 2.0*Viscosity*dudx + lamDivTerm; - const su2double tauyy = 2.0*Viscosity*dvdy + lamDivTerm; - const su2double tauzz = 2.0*Viscosity*dwdz + lamDivTerm; - - const su2double tauxy = Viscosity*(dudy + dvdx); - const su2double tauxz = Viscosity*(dudz + dwdx); - const su2double tauyz = Viscosity*(dvdz + dwdy); - - const su2double qx = kOverCv*dStaticEnergyDx; - const su2double qy = kOverCv*dStaticEnergyDy; - const su2double qz = kOverCv*dStaticEnergyDz; - - /* Compute the relative velocities w.r.t. the grid. */ - const su2double uRel = u - gridVel[0]; - const su2double vRel = v - gridVel[1]; - const su2double wRel = w - gridVel[2]; - - /* Compute the viscous normal stress minus the pressure. */ - const su2double tauxxMP = tauxx - Pressure; - const su2double tauyyMP = tauyy - Pressure; - const su2double tauzzMP = tauzz - Pressure; - - /* Set the pointer for the fluxes in this integration point. */ - su2double *flux = fluxes + nDim*iNPad + llNVar; - - /*--- Fluxes in r-direction. */ - const su2double Ur = uRel*wDrdx + vRel*wDrdy + wRel*wDrdz; - - flux[0] = sol[0]*Ur; - flux[1] = sol[1]*Ur - tauxxMP*wDrdx - tauxy*wDrdy - tauxz*wDrdz; - flux[2] = sol[2]*Ur - tauxy*wDrdx - tauyyMP*wDrdy - tauyz*wDrdz; - flux[3] = sol[3]*Ur - tauxz*wDrdx - tauyz*wDrdy - tauzzMP*wDrdz; - flux[4] = sol[4]*Ur - (u*tauxxMP + v*tauxy + w*tauxz + qx)*wDrdx - - (u*tauxy + v*tauyyMP + w*tauyz + qy)*wDrdy - - (u*tauxz + v*tauyz + w*tauzzMP + qz)*wDrdz; - - /*--- Fluxes in s-direction. */ - flux = flux + NPad; - const su2double Us = uRel*wDsdx + vRel*wDsdy + wRel*wDsdz; - - flux[0] = sol[0]*Us; - flux[1] = sol[1]*Us - tauxxMP*wDsdx - tauxy*wDsdy - tauxz*wDsdz; - flux[2] = sol[2]*Us - tauxy*wDsdx - tauyyMP*wDsdy - tauyz*wDsdz; - flux[3] = sol[3]*Us - tauxz*wDsdx - tauyz*wDsdy - tauzzMP*wDsdz; - flux[4] = sol[4]*Us - (u*tauxxMP + v*tauxy + w*tauxz + qx)*wDsdx - - (u*tauxy + v*tauyyMP + w*tauyz + qy)*wDsdy - - (u*tauxz + v*tauyz + w*tauzzMP + qz)*wDsdz; - - /*--- Fluxes in t-direction. */ - flux = flux + NPad; - const su2double Ut = uRel*wDtdx + vRel*wDtdy + wRel*wDtdz; - - flux[0] = sol[0]*Ut; - flux[1] = sol[1]*Ut - tauxxMP*wDtdx - tauxy*wDtdy - tauxz*wDtdz; - flux[2] = sol[2]*Ut - tauxy*wDtdx - tauyyMP*wDtdy - tauyz*wDtdz; - flux[3] = sol[3]*Ut - tauxz*wDtdx - tauyz*wDtdy - tauzzMP*wDtdz; - flux[4] = sol[4]*Ut - (u*tauxxMP + v*tauxy + w*tauxz + qx)*wDtdx - - (u*tauxy + v*tauyyMP + w*tauyz + qy)*wDtdy - - (u*tauxz + v*tauyz + w*tauzzMP + qz)*wDtdz; - - /*--- If needed, compute the body forces in this integration point. - Note that the source terms are multiplied with minus the - integration weight in order to be consistent with the - formulation of the residual. Note that for the energy source - term the absolute velocity must be taken and not the - relative. ---*/ - if( body_force ) { - su2double *source = sources + iNPad + llNVar; - const su2double weightJac = weights[i]*Jac; - - source[0] = 0.0; - source[1] = -weightJac*body_force_vector[0]; - source[2] = -weightJac*body_force_vector[1]; - source[3] = -weightJac*body_force_vector[2]; - source[4] = -weightJac*(u*body_force_vector[0] + v*body_force_vector[1] - + w*body_force_vector[2]); - } - } - } - - break; - } - } - - /* Initialize addSourceTerms to body_force. The value of addSourceTerms - is set to true when a manufactured solution is computed. */ - bool addSourceTerms = body_force; - - /* Check whether or not a manufactured solution is used. */ - if( VerificationSolution ) { - if( VerificationSolution->IsManufacturedSolution() ) { - - /*--- For the manufactured solutions a source term must be added. If a - standard source term has not been specified, initialize the source - terms to zero and set addSourceTerms to true. ---*/ - addSourceTerms = true; - if( !body_force ) { - for(unsigned short i=0; i<(nInt*NPad); ++i) - sources[i] = 0.0; - } - - /*--- Loop over the chunk of elements and its integration points. ---*/ - for(unsigned short ll=0; llGetMMSSourceTerm(coor, time, sourceMan); - - /*--- Subtract the source term of the manufactured solution, multiplied - by the appropriate weight, from the possibly earlier computed - source term. It is subtracted in order to be consistent with - the definition of the residual used in this code. ---*/ - su2double *source = sources + iNPad + llNVar; - for(unsigned short k=0; kgemm(nDOFs, NPad, nInt*nDim, matDerBasisIntTrans, fluxes, solDOFs, config); - - /* Add the contribution from the source terms, if needed. Use solAndGradInt - as temporary storage for the matrix product. */ - if( addSourceTerms ) { - - /* Call the general function to carry out the matrix product. */ - blasFunctions->gemm(nDOFs, NPad, nInt, matBasisIntTrans, sources, solAndGradInt, config); - - /* Add the residuals due to source terms to the volume residuals */ - for(unsigned short i=0; i<(nDOFs*NPad); ++i) - solDOFs[i] += solAndGradInt[i]; - } - - /* Loop over the elements in this chunk to store the residuals - in the appropriate locations. */ - for(unsigned short ll=0; llGetSizeMatMulPadding(); - const unsigned short nFaceSimul = nPadInput/nVar; - - /* Determine the minimum padded size in the matrix multiplications, which - corresponds to 64 byte alignment. */ - const unsigned short nPadMin = 64/sizeof(passivedouble); - - /* Set the number of bytes that must be copied in the memcpy calls. */ - const unsigned long nBytes = nVar*sizeof(su2double); - - /*--- Loop over the requested range of matching faces. Multiple faces - are treated simultaneously to improve the performance of the matrix - multiplications. As a consequence, the update of the counter l - happens at the end of this loop section. ---*/ - for(unsigned long l=indFaceBeg; lgemm(nInt*nDim, NPad, nDOFsElem0, derBasisElem, solElem, gradSolInt, config); - - /*--- Loop over the faces in this chunk to compute the viscous flux - vector for side 0. */ - for(unsigned long ll=l; llgemm(nInt*nDim, NPad, nDOFsElem1, derBasisElem, solElem, gradSolInt, config); - - /*--- Loop over the faces in this chunk to compute the viscous flux - vector for side 1. */ - for(unsigned long ll=l; llgemm(nDOFsFace0, NPad, nInt, basisFaceTrans, fluxes, resSide0, config); - - /* Check if the number of DOFs on both sides of the face is different. - In that case also the matrix product with the basis functions on side 1 - must be carried out. Use viscFluxes as a temporary buffer to store - this product. */ - su2double *resSide1 = viscFluxes; - if(nDOFsFace1 != nDOFsFace0) { - basisFaceTrans = standardMatchingFacesSol[ind].GetBasisFaceIntegrationTransposeSide1(); - blasFunctions->gemm(nDOFsFace1, NPad, nInt, basisFaceTrans, fluxes, resSide1, config); - } - - /* Loop over the number of faces in this chunk. */ - for(unsigned short ll=0; llGetTheta_Interior_Penalty_DGFEM(); - - /* Loop over the faces in this chunk to compute the symmetrizing fluxes. */ - for(unsigned long ll=l; llgemm(nDOFsElem0, NPad, nInt*nDim, derBasisElemTrans, paramFluxes, solIntL, config); - - /* Loop over the faces in this chunk to compute the transformed - symmetrizing fluxes for side 1. */ - for(unsigned long ll=l; llgemm(nDOFsElem1, NPad, nInt*nDim, derBasisElemTrans, paramFluxes, solIntR, config); - - /* Loop over the number of faces in this chunk. */ - for(unsigned short ll=0; llindStandardElement; - unsigned short nPoly = standardElementsSol[iind].GetNPoly(); - if(nPoly == 0) nPoly = 1; - - const su2double lenScale_LES = adjVolElem->lenScale/nPoly; - - /* Determine the offset between r- and -s-derivatives, which is also the - offset between s- and t-derivatives. */ - const unsigned short offDeriv = NPad*nInt; - - /* Make a distinction between two and three space dimensions - in order to have the most efficient code. */ - switch( nDim ) { - - case 2: { - - /* 2D simulation. Loop over the integration points to - compute the viscous fluxes. */ - for(unsigned short i=0; iSetTDState_rhoe(sol[0], StaticEnergy); - const su2double ViscosityLam = FluidModel->GetLaminarViscosity(); - - /*--- Compute the eddy viscosity, if needed. ---*/ - su2double ViscosityTurb = 0.0; - if( SGSModelUsed ) - ViscosityTurb = SGSModel->ComputeEddyViscosity_2D(sol[0], dudx, dudy, dvdx, - dvdy, lenScale_LES, wallDist); - - /* Compute the total viscosity and heat conductivity. Note that the heat - conductivity is divided by the Cv, because gradients of internal energy - are computed and not temperature. */ - Viscosity = ViscosityLam + ViscosityTurb; - kOverCv = ViscosityLam*factHeatFlux_Lam + ViscosityTurb*factHeatFlux_Turb; - - /*--- Set the value of the second viscosity and compute the divergence - term in the viscous normal stresses. ---*/ - const su2double lambda = -TWO3*Viscosity; - const su2double lamDivTerm = lambda*divVel; - - /*--- Compute the viscous stress tensor and minus the heatflux vector. - The heat flux vector is multiplied by factHeatFlux, such that the - case of a prescribed heat flux is treated correctly. ---*/ - const su2double tauxx = 2.0*Viscosity*dudx + lamDivTerm; - const su2double tauyy = 2.0*Viscosity*dvdy + lamDivTerm; - const su2double tauxy = Viscosity*(dudy + dvdx); - - const su2double qx = factHeatFlux*kOverCv*dStaticEnergyDx; - const su2double qy = factHeatFlux*kOverCv*dStaticEnergyDy; - - /* Compute the unscaled normal vector. */ - const su2double nx = normal[0]*normal[2]; - const su2double ny = normal[1]*normal[2]; - - /*--- Compute the viscous normal flux. Note that the energy flux get a - contribution from both the prescribed and the computed heat flux. - At least one of these terms is zero. ---*/ - normalFlux[0] = 0.0; - normalFlux[1] = tauxx*nx + tauxy*ny; - normalFlux[2] = tauxy*nx + tauyy*ny; - normalFlux[3] = normal[2]*HeatFlux - + (u*tauxx + v*tauxy + qx)*nx + (u*tauxy + v*tauyy + qy)*ny; -} - -void CFEM_DG_NSSolver::ViscousNormalFluxIntegrationPoint_3D(const su2double *sol, - const su2double solGradCart[5][3], - const su2double *normal, - const su2double HeatFlux, - const su2double factHeatFlux, - const su2double wallDist, - const su2double lenScale_LES, - su2double &Viscosity, - su2double &kOverCv, - su2double *normalFlux) { - - /* Constant factor present in the heat flux vector, namely the ratio of - thermal conductivity and viscosity. */ - const su2double factHeatFlux_Lam = Gamma/Prandtl_Lam; - const su2double factHeatFlux_Turb = Gamma/Prandtl_Turb; - - /*--- Compute the velocities and static energy in this integration point. ---*/ - const su2double rhoInv = 1.0/sol[0]; - const su2double u = rhoInv*sol[1]; - const su2double v = rhoInv*sol[2]; - const su2double w = rhoInv*sol[3]; - - const su2double TotalEnergy = rhoInv*sol[4]; - const su2double StaticEnergy = TotalEnergy - 0.5*(u*u + v*v + w*w); - - /*--- Compute the Cartesian gradients of the velocities and static energy - in this integration point and also the divergence of the velocity. ---*/ - const su2double dudx = rhoInv*(solGradCart[1][0] - u*solGradCart[0][0]); - const su2double dudy = rhoInv*(solGradCart[1][1] - u*solGradCart[0][1]); - const su2double dudz = rhoInv*(solGradCart[1][2] - u*solGradCart[0][2]); - - const su2double dvdx = rhoInv*(solGradCart[2][0] - v*solGradCart[0][0]); - const su2double dvdy = rhoInv*(solGradCart[2][1] - v*solGradCart[0][1]); - const su2double dvdz = rhoInv*(solGradCart[2][2] - v*solGradCart[0][2]); - - const su2double dwdx = rhoInv*(solGradCart[3][0] - w*solGradCart[0][0]); - const su2double dwdy = rhoInv*(solGradCart[3][1] - w*solGradCart[0][1]); - const su2double dwdz = rhoInv*(solGradCart[3][2] - w*solGradCart[0][2]); - - const su2double dStaticEnergyDx = rhoInv*(solGradCart[4][0] - - TotalEnergy*solGradCart[0][0]) - - u*dudx - v*dvdx - w*dwdx; - const su2double dStaticEnergyDy = rhoInv*(solGradCart[4][1] - - TotalEnergy*solGradCart[0][1]) - - u*dudy - v*dvdy - w*dwdy; - const su2double dStaticEnergyDz = rhoInv*(solGradCart[4][2] - - TotalEnergy*solGradCart[0][2]) - - u*dudz - v*dvdz - w*dwdz; - - const su2double divVel = dudx + dvdy + dwdz; - - /*--- Compute the laminar viscosity. ---*/ - FluidModel->SetTDState_rhoe(sol[0], StaticEnergy); - const su2double ViscosityLam = FluidModel->GetLaminarViscosity(); - - /*--- Compute the eddy viscosity, if needed. ---*/ - su2double ViscosityTurb = 0.0; - if( SGSModelUsed ) - ViscosityTurb = SGSModel->ComputeEddyViscosity_3D(sol[0], dudx, dudy, dudz, - dvdx, dvdy, dvdz, dwdx, - dwdy, dwdz, lenScale_LES, - wallDist); - - /* Compute the total viscosity and heat conductivity. Note that the heat - conductivity is divided by the Cv, because gradients of internal energy - are computed and not temperature. */ - Viscosity = ViscosityLam + ViscosityTurb; - kOverCv = ViscosityLam*factHeatFlux_Lam + ViscosityTurb*factHeatFlux_Turb; - - /*--- Set the value of the second viscosity and compute the divergence - term in the viscous normal stresses. ---*/ - const su2double lambda = -TWO3*Viscosity; - const su2double lamDivTerm = lambda*divVel; - - /*--- Compute the viscous stress tensor and minus the heatflux vector. - The heat flux vector is multiplied by factHeatFlux, such that the - case of a prescribed heat flux is treated correctly. ---*/ - const su2double tauxx = 2.0*Viscosity*dudx + lamDivTerm; - const su2double tauyy = 2.0*Viscosity*dvdy + lamDivTerm; - const su2double tauzz = 2.0*Viscosity*dwdz + lamDivTerm; - - const su2double tauxy = Viscosity*(dudy + dvdx); - const su2double tauxz = Viscosity*(dudz + dwdx); - const su2double tauyz = Viscosity*(dvdz + dwdy); - - const su2double qx = factHeatFlux*kOverCv*dStaticEnergyDx; - const su2double qy = factHeatFlux*kOverCv*dStaticEnergyDy; - const su2double qz = factHeatFlux*kOverCv*dStaticEnergyDz; - - /* Compute the unscaled normal vector. */ - const su2double nx = normal[0]*normal[3]; - const su2double ny = normal[1]*normal[3]; - const su2double nz = normal[2]*normal[3]; - - /*--- Compute the viscous normal flux. Note that the energy flux get a - contribution from both the prescribed and the computed heat flux. - At least one of these terms is zero. ---*/ - normalFlux[0] = 0.0; - normalFlux[1] = tauxx*nx + tauxy*ny + tauxz*nz; - normalFlux[2] = tauxy*nx + tauyy*ny + tauyz*nz; - normalFlux[3] = tauxz*nx + tauyz*ny + tauzz*nz; - normalFlux[4] = normal[3]*HeatFlux - + (u*tauxx + v*tauxy + w*tauxz + qx)*nx - + (u*tauxy + v*tauyy + w*tauyz + qy)*ny - + (u*tauxz + v*tauyz + w*tauzz + qz)*nz; -} - -void CFEM_DG_NSSolver::PenaltyTermsFluxFace(const unsigned short indFaceChunk, - const unsigned short nInt, - const unsigned short NPad, - const su2double *solInt0, - const su2double *solInt1, - const su2double *viscosityInt0, - const su2double *viscosityInt1, - const su2double *kOverCvInt0, - const su2double *kOverCvInt1, - const su2double ConstPenFace, - const su2double lenScale0, - const su2double lenScale1, - const su2double *metricNormalsFace, - su2double *penaltyFluxes) { - - /* Constant ratio of the second viscosity and the viscosity itself. */ - const su2double lambdaOverMu = -TWO3; - - /* The eigenvalues of the viscous Jacobian, scaled by the kinematic viscosity, - are 1.0, 2.0 + lambdaOverMu and kOverCv/Mu. The last is variable due to the - possible presence of an eddy viscosity, but the first two are constant and - the maximum can be determined. */ - const su2double radOverNuTerm = max(1.0, 2.0+lambdaOverMu); - - /*--- Make a distinction between 2D and 3D for efficiency. ---*/ - switch ( nDim ) { - case 2: { - - /* 2D simulation. Loop over the integration points to compute - the penalty fluxes. */ - for(unsigned short i=0; iGetSizeMatMulPadding(); - const unsigned short nFaceSimul = nPadInput/nVar; - - /* Determine the minimum padded size in the matrix multiplications, which - corresponds to 64 byte alignment. */ - const unsigned short nPadMin = 64/sizeof(passivedouble); - - /*--- Loop over the requested range of surface faces. Multiple faces - are treated simultaneously to improve the performance of the matrix - multiplications. As a consequence, the update of the counter l - happens at the end of this loop section. ---*/ - for(unsigned long l=surfElemBeg; lGetSizeMatMulPadding(); - const unsigned short nFaceSimul = nPadInput/nVar; - - /* Determine the minimum padded size in the matrix multiplications, which - corresponds to 64 byte alignment. */ - const unsigned short nPadMin = 64/sizeof(passivedouble); - - /*--- Loop over the requested range of surface faces. Multiple faces - are treated simultaneously to improve the performance of the matrix - multiplications. As a consequence, the update of the counter l - happens at the end of this loop section. ---*/ - for(unsigned long l=surfElemBeg; lGetSizeMatMulPadding(); - const unsigned short nFaceSimul = nPadInput/nVar; - - /* Determine the minimum padded size in the matrix multiplications, which - corresponds to 64 byte alignment. */ - const unsigned short nPadMin = 64/sizeof(passivedouble); - - /*--- Loop over the requested range of surface faces. Multiple faces - are treated simultaneously to improve the performance of the matrix - multiplications. As a consequence, the update of the counter l - happens at the end of this loop section. ---*/ - for(unsigned long l=surfElemBeg; lgemm(nInt*nDim, NPad, nDOFsElem, derBasisElem, solElem, gradSolInt, config); - - /*-----------------------------------------------------------------------*/ - /*--- Step 3: Computation of the viscous fluxes in the integration ---*/ - /*--- points. ---*/ - /*-----------------------------------------------------------------------*/ - - /* Determine the offset between r- and -s-derivatives, which is also the - offset between s- and t-derivatives. */ - const unsigned short offDeriv = NPad*nInt; - - /* Loop over the faces of the chunk. */ - for(unsigned long ll=l; llGetSizeMatMulPadding(); - const unsigned short nFaceSimul = nPadInput/nVar; - - /* Determine the minimum padded size in the matrix multiplications, which - corresponds to 64 byte alignment. */ - const unsigned short nPadMin = 64/sizeof(passivedouble); - - /*--- Loop over the requested range of surface faces. Multiple faces - are treated simultaneously to improve the performance of the matrix - multiplications. As a consequence, the update of the counter l - happens at the end of this loop section. ---*/ - for(unsigned long l=surfElemBeg; lGetSizeMatMulPadding(); - const unsigned short nFaceSimul = nPadInput/nVar; - - /* Determine the minimum padded size in the matrix multiplications, which - corresponds to 64 byte alignment. */ - const unsigned short nPadMin = 64/sizeof(passivedouble); - - /*--- Loop over the requested range of surface faces. Multiple faces - are treated simultaneously to improve the performance of the matrix - multiplications. As a consequence, the update of the counter l - happens at the end of this loop section. ---*/ - for(unsigned long l=surfElemBeg; lGetSizeMatMulPadding(); - const unsigned short nFaceSimul = nPadInput/nVar; - - /* Determine the minimum padded size in the matrix multiplications, which - corresponds to 64 byte alignment. */ - const unsigned short nPadMin = 64/sizeof(passivedouble); - - /*--- Loop over the requested range of surface faces. Multiple faces - are treated simultaneously to improve the performance of the matrix - multiplications. As a consequence, the update of the counter l - happens at the end of this loop section. ---*/ - for(unsigned long l=surfElemBeg; lGetMarker_All_TagBound(val_marker); - const su2double Wall_HeatFlux = config->GetWall_HeatFlux(Marker_Tag); - - /* Initialization of the counter in resFaces. */ - unsigned long indResFaces = 0; - - /* Determine the number of faces that are treated simultaneously - in the matrix products to obtain good gemm performance. */ - const unsigned short nPadInput = config->GetSizeMatMulPadding(); - const unsigned short nFaceSimul = nPadInput/nVar; - - /* Determine the minimum padded size in the matrix multiplications, which - corresponds to 64 byte alignment. */ - const unsigned short nPadMin = 64/sizeof(passivedouble); - - /*--- Loop over the requested range of surface faces. Multiple faces - are treated simultaneously to improve the performance of the matrix - multiplications. As a consequence, the update of the counter l - happens at the end of this loop section. ---*/ - for(unsigned long l=surfElemBeg; lGetMarker_All_TagBound(val_marker); - const su2double TWall = config->GetIsothermal_Temperature(Marker_Tag)/config->GetTemperature_Ref(); - - /* Compute the prescribed value of the energy (per unit mass). */ - const su2double Gas_Constant = config->GetGas_ConstantND(); - const su2double Cv = Gas_Constant/Gamma_Minus_One; - const su2double StaticEnergy = Cv*TWall; - - /* Initialization of the counter in resFaces. */ - unsigned long indResFaces = 0; - - /* Determine the number of faces that are treated simultaneously - in the matrix products to obtain good gemm performance. */ - const unsigned short nPadInput = config->GetSizeMatMulPadding(); - const unsigned short nFaceSimul = nPadInput/nVar; - - /* Determine the minimum padded size in the matrix multiplications, which - corresponds to 64 byte alignment. */ - const unsigned short nPadMin = 64/sizeof(passivedouble); - - /*--- Loop over the requested range of surface faces. Multiple faces - are treated simultaneously to improve the performance of the matrix - multiplications. As a consequence, the update of the counter l - happens at the end of this loop section. ---*/ - for(unsigned long l=surfElemBeg; lGetSizeMatMulPadding(); - const unsigned short nFaceSimul = nPadInput/nVar; - - /* Determine the minimum padded size in the matrix multiplications, which - corresponds to 64 byte alignment. */ - const unsigned short nPadMin = 64/sizeof(passivedouble); - - /*--- Loop over the requested range of surface faces. Multiple faces - are treated simultaneously to improve the performance of the matrix - multiplications. As a consequence, the update of the counter l - happens at the end of this loop section. ---*/ - for(unsigned long l=surfElemBeg; lGetSizeMatMulPadding(); - const unsigned short nFaceSimul = nPadInput/nVar; - - /* Determine the minimum padded size in the matrix multiplications, which - corresponds to 64 byte alignment. */ - const unsigned short nPadMin = 64/sizeof(passivedouble); - - /*--- Get the physical time if necessary. ---*/ - su2double time = 0.0; - if (config->GetTime_Marching()) time = config->GetPhysicalTime(); - - /*--- Loop over the requested range of surface faces. Multiple faces - are treated simultaneously to improve the performance of the matrix - multiplications. As a consequence, the update of the counter l - happens at the end of this loop section. ---*/ - for(unsigned long l=surfElemBeg; lGetBCState(coor, time, UR); - } - } - } - else { - - /* The user must specify the custom BC's here. */ - SU2_MPI::Error("Implement customized boundary conditions here.", CURRENT_FUNCTION); - } - - - /* The remainder of the boundary treatment is the same for all - boundary conditions (except the symmetry plane). */ - ViscousBoundaryFacesBCTreatment(config, conv_numerics, llEnd, NPad, - 0.0, false, 0.0, false, &surfElem[l], - solIntL, solIntR, work, - resFaces, indResFaces, NULL); - - /* Update the value of the counter l to the end index of the - current chunk. */ - l = lEnd; - } -} - -void CFEM_DG_NSSolver::ViscousBoundaryFacesBCTreatment( - CConfig *config, - CNumerics *conv_numerics, - const unsigned short nFaceSimul, - const unsigned short NPad, - const su2double Wall_HeatFlux, - const bool HeatFlux_Prescribed, - const su2double Wall_Temperature, - const bool Temperature_Prescribed, - const CSurfaceElementFEM *surfElem, - const su2double *solIntL, - const su2double *solIntR, - su2double *workArray, - su2double *resFaces, - unsigned long &indResFaces, - CWallModel *wallModel) { - - /*--- Get the information from the standard element, which is the same - for all the faces in the chunks considered. ---*/ - const unsigned short ind = surfElem[0].indStandardElement; - const unsigned short nInt = standardBoundaryFacesSol[ind].GetNIntegration(); - const unsigned short nDOFsElem = standardBoundaryFacesSol[ind].GetNDOFsElem(); - const su2double *derBasisElem = standardBoundaryFacesSol[ind].GetMatDerBasisElemIntegration(); - - /*--- Set the pointers for the local arrays. ---*/ - su2double *viscosityInt = workArray; - su2double *kOverCvInt = viscosityInt + nFaceSimul*nInt; - su2double *gradSolInt = kOverCvInt + nFaceSimul*nInt; - su2double *fluxes = gradSolInt + NPad*nInt*nDim; - su2double *viscFluxes = fluxes + NPad*max(nInt*nDim, (int) nDOFsElem); - - /* Compute the viscous fluxes in the integration points of the faces that - are treated simulaneously. Make a distinction between a wall function - treatment and a standard computation of the viscous fluxes. */ - if( wallModel ) { - WallTreatmentViscousFluxes(config, nFaceSimul, NPad, nInt, Wall_HeatFlux, - HeatFlux_Prescribed, Wall_Temperature, - Temperature_Prescribed, surfElem, solIntL, - gradSolInt, viscFluxes, viscosityInt, - kOverCvInt, wallModel); - } - else { - ComputeViscousFluxesBoundaryFaces(config, nFaceSimul, NPad, nInt, nDOFsElem, - Wall_HeatFlux, HeatFlux_Prescribed, - derBasisElem, surfElem, solIntL, - fluxes, gradSolInt, viscFluxes, - viscosityInt, kOverCvInt); - } - - /* The remainder of the boundary condition treatment is the same for all - types of boundary conditions, including the symmetry plane and the - wall function treatment. The function ResidualViscousBoundaryFace will - carry out this task. */ - - ResidualViscousBoundaryFace(config, conv_numerics, nFaceSimul, NPad, surfElem, - solIntL, solIntR, gradSolInt, fluxes, viscFluxes, - viscosityInt, kOverCvInt, resFaces, indResFaces); -} - -void CFEM_DG_NSSolver::ComputeViscousFluxesBoundaryFaces( - CConfig *config, - const unsigned short nFaceSimul, - const unsigned short NPad, - const unsigned short nInt, - const unsigned short nDOFsElem, - const su2double Wall_HeatFlux, - const bool HeatFlux_Prescribed, - const su2double *derBasisElem, - const CSurfaceElementFEM *surfElem, - const su2double *solIntL, - su2double *solElem, - su2double *gradSolInt, - su2double *viscFluxes, - su2double *viscosityInt, - su2double *kOverCvInt) { - - /* Easier storage of the number of bytes to copy in the memcpy calls. */ - const unsigned long nBytes = nVar*sizeof(su2double); - - /*---------------------------------------------------------------------------*/ - /*--- Step 1: Compute the gradients of the conservative variables in the ---*/ - /*--- integration points of the faces. ---*/ - /*---------------------------------------------------------------------------*/ - - /* Loop over the simultaneously treated faces to set the solution of the elements. */ - for(unsigned short l=0; lgemm(nInt*nDim, NPad, nDOFsElem, derBasisElem, solElem, gradSolInt, config); - - /*---------------------------------------------------------------------------*/ - /*--- Step 2: Compute the viscous normal fluxes in the integration points ---*/ - /*--- of the faces. ---*/ - /*---------------------------------------------------------------------------*/ - - /* Loop over the simultaneously treated faces. */ - for(unsigned short l=0; lgemm(nIntThisDonor, nVar, nDOFsElem, surfElem[l].matWallFunctionDonor[j].data(), - solDOFsElem, workArray, config); - - /* Loop over the integration points for this donor element. */ - for(unsigned short i=surfElem[l].nIntPerWallFunctionDonor[j]; - iSetTDState_rhoe(solInt[0], eInt); - const su2double Pressure = FluidModel->GetPressure(); - const su2double Temperature = FluidModel->GetTemperature(); - const su2double LaminarViscosity= FluidModel->GetLaminarViscosity(); - - /* Subtract the prescribed wall velocity, i.e. grid velocity - from the velocity in the exchange point. */ - for(unsigned short k=0; kWallShearStressAndHeatFlux(Temperature, velTan, LaminarViscosity, Pressure, - Wall_HeatFlux, HeatFlux_Prescribed, - Wall_Temperature, Temperature_Prescribed, - FluidModel, tauWall, qWall, ViscosityWall, - kOverCvWall); - - /* Compute the wall velocity in tangential direction. */ - const su2double *solWallInt = solIntL + NPad*ii + llNVar; - su2double velWallTan = 0.0; - for(unsigned short k=0; k SIZE_ARR_NORM) - SU2_MPI::Error("SIZE_ARR_NORM is too small. Increase it or decrease ALIGNED_BYTES_MATMUL", - CURRENT_FUNCTION); - - for(unsigned short l=0; lgemm(nDOFs, NPad, nInt, basisFaceTrans, fluxes, viscFluxes, config); - - /* Loop over the number of faces in this chunk to store the residual in - the correct locations in resFaces. */ - for(unsigned short l=0; lGetTheta_Interior_Penalty_DGFEM(); - - /* Loop over the simultaneously treated faces. */ - for(unsigned short l=0; lgemm(nDOFsElem, NPad, nInt*nDim, derBasisElemTrans, paramFluxes, fluxes, config); - - /* Loop over the faces of this chunk to store the residual in - the correct locations in resFaces. */ - for(unsigned short l=0; l. + */ + + +#include "../../include/solvers/CFEM_DG_NSSolver.hpp" +#include "../../../Common/include/toolboxes/printing_toolbox.hpp" + +#define SIZE_ARR_NORM 8 + +CFEM_DG_NSSolver::CFEM_DG_NSSolver(void) : CFEM_DG_EulerSolver() { + + /*--- Basic array initialization ---*/ + CD_Visc = NULL; CL_Visc = NULL; CSF_Visc = NULL; CEff_Visc = NULL; + CMx_Visc = NULL; CMy_Visc = NULL; CMz_Visc = NULL; + CFx_Visc = NULL; CFy_Visc = NULL; CFz_Visc = NULL; + + /*--- Surface-based array initialization ---*/ + Surface_CL_Visc = NULL; Surface_CD_Visc = NULL; Surface_CSF_Visc = NULL; Surface_CEff_Visc = NULL; + Surface_CFx_Visc = NULL; Surface_CFy_Visc = NULL; Surface_CFz_Visc = NULL; + Surface_CMx_Visc = NULL; Surface_CMy_Visc = NULL; Surface_CMz_Visc = NULL; + MaxHeatFlux_Visc = NULL; Heat_Visc = NULL; + + /*--- Set the SGS model to NULL and indicate that no SGS model is used. ---*/ + SGSModel = NULL; + SGSModelUsed = false; +} + +CFEM_DG_NSSolver::CFEM_DG_NSSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh) + : CFEM_DG_EulerSolver(geometry, config, iMesh) { + + /*--- Array initialization ---*/ + CD_Visc = NULL; CL_Visc = NULL; CSF_Visc = NULL; CEff_Visc = NULL; + CMx_Visc = NULL; CMy_Visc = NULL; CMz_Visc = NULL; + CFx_Visc = NULL; CFy_Visc = NULL; CFz_Visc = NULL; + + Surface_CL_Visc = NULL; Surface_CD_Visc = NULL; Surface_CSF_Visc = NULL; Surface_CEff_Visc = NULL; + Surface_CFx_Visc = NULL; Surface_CFy_Visc = NULL; Surface_CFz_Visc = NULL; + Surface_CMx_Visc = NULL; Surface_CMy_Visc = NULL; Surface_CMz_Visc = NULL; + MaxHeatFlux_Visc = NULL; Heat_Visc = NULL; + + /*--- Initialize the solution and right hand side vectors for storing + the residuals and updating the solution (always needed even for + explicit schemes). ---*/ + + //LinSysSol.Initialize(nPoint, nPointDomain, nVar, 0.0); + //LinSysRes.Initialize(nPoint, nPointDomain, nVar, 0.0); + + /*--- Non dimensional coefficients ---*/ + CD_Visc = new su2double[nMarker]; + CL_Visc = new su2double[nMarker]; + CSF_Visc = new su2double[nMarker]; + CMx_Visc = new su2double[nMarker]; + CMy_Visc = new su2double[nMarker]; + CMz_Visc = new su2double[nMarker]; + CEff_Visc = new su2double[nMarker]; + CFx_Visc = new su2double[nMarker]; + CFy_Visc = new su2double[nMarker]; + CFz_Visc = new su2double[nMarker]; + + Surface_CL_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CD_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CSF_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CEff_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFx_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFy_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFz_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMx_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMy_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMz_Visc = new su2double[config->GetnMarker_Monitoring()]; + + Heat_Visc = new su2double[nMarker]; + MaxHeatFlux_Visc = new su2double[nMarker]; + + /*--- Init total coefficients ---*/ + + Total_CD = 0.0; Total_CL = 0.0; Total_CSF = 0.0; + Total_CMx = 0.0; Total_CMy = 0.0; Total_CMz = 0.0; + Total_CEff = 0.0; + Total_CFx = 0.0; Total_CFy = 0.0; Total_CFz = 0.0; + + /*--- Read farfield conditions from config ---*/ + + Viscosity_Inf = config->GetViscosity_FreeStreamND(); + Prandtl_Lam = config->GetPrandtl_Lam(); + Prandtl_Turb = config->GetPrandtl_Turb(); + Tke_Inf = config->GetTke_FreeStreamND(); + + /*--- Set the SGS model in case an LES simulation is carried out ---*/ + + if(config->GetKind_Solver() == FEM_LES) { + + /* Make a distinction between the SGS models used and set SGSModel and + SGSModelUsed accordingly. */ + switch( config->GetKind_SGS_Model() ) { + + case IMPLICIT_LES: + SGSModel = NULL; + SGSModelUsed = false; + break; + + case SMAGORINSKY: + SGSModel = new CSmagorinskyModel; + SGSModelUsed = true; + break; + + case WALE: + SGSModel = new CWALEModel; + SGSModelUsed = true; + break; + + case VREMAN: + SGSModel = new CVremanModel; + SGSModelUsed = true; + break; + + default: + SU2_MPI::Error("Unknown SGS model encountered", CURRENT_FUNCTION); + } + } + else { + + /* No LES, so no SGS model needed. + Set the pointer to NULL and the boolean to false. */ + SGSModel = NULL; + SGSModelUsed = false; + } +} + +CFEM_DG_NSSolver::~CFEM_DG_NSSolver(void) { + + if (CD_Visc != NULL) delete [] CD_Visc; + if (CL_Visc != NULL) delete [] CL_Visc; + if (CSF_Visc != NULL) delete [] CSF_Visc; + if (CMx_Visc != NULL) delete [] CMx_Visc; + if (CMy_Visc != NULL) delete [] CMy_Visc; + if (CMz_Visc != NULL) delete [] CMz_Visc; + if (CFx_Visc != NULL) delete [] CFx_Visc; + if (CFy_Visc != NULL) delete [] CFy_Visc; + if (CFz_Visc != NULL) delete [] CFz_Visc; + if (CEff_Visc != NULL) delete [] CEff_Visc; + + if (Surface_CL_Visc != NULL) delete [] Surface_CL_Visc; + if (Surface_CD_Visc != NULL) delete [] Surface_CD_Visc; + if (Surface_CSF_Visc != NULL) delete [] Surface_CSF_Visc; + if (Surface_CEff_Visc != NULL) delete [] Surface_CEff_Visc; + if (Surface_CFx_Visc != NULL) delete [] Surface_CFx_Visc; + if (Surface_CFy_Visc != NULL) delete [] Surface_CFy_Visc; + if (Surface_CFz_Visc != NULL) delete [] Surface_CFz_Visc; + if (Surface_CMx_Visc != NULL) delete [] Surface_CMx_Visc; + if (Surface_CMy_Visc != NULL) delete [] Surface_CMy_Visc; + if (Surface_CMz_Visc != NULL) delete [] Surface_CMz_Visc; + + if (Heat_Visc != NULL) delete [] Heat_Visc; + if (MaxHeatFlux_Visc != NULL) delete [] MaxHeatFlux_Visc; + + if( SGSModel ) delete SGSModel; +} + +void CFEM_DG_NSSolver::Friction_Forces(CGeometry *geometry, CConfig *config) { + + /* Allocate the memory for the work array and initialize it to zero to avoid + warnings in debug mode about uninitialized memory when padding is applied. */ + vector workArrayVec(sizeWorkArray, 0.0); + su2double *workArray = workArrayVec.data(); + + /*--------------------------------------------------------------------------*/ + /*--- The skin friction is computed using the laminar viscosity and ---*/ + /*--- velocity gradients. This is correct when integration to the wall ---*/ + /*--- is performed, but not when wall functions are used. Hence, this ---*/ + /*--- function must be modified when wall functions are implemented. ---*/ + /*--------------------------------------------------------------------------*/ + + /* The number of bytes to copied in the memcpy calls. */ + const unsigned long nBytes = nVar*sizeof(su2double); + + /* Determine the number of faces that are treated simultaneously + in the matrix products to obtain good gemm performance. */ + const unsigned short nPadInput = config->GetSizeMatMulPadding(); + const unsigned short nFaceSimul = nPadInput/nVar; + + /* Determine the minimum padded size in the matrix multiplications, which + corresponds to 64 byte alignment. */ + const unsigned short nPadMin = 64/sizeof(passivedouble); + + /* Constant factor present in the heat flux vector. */ + const su2double factHeatFlux_Lam = Gamma/Prandtl_Lam; + + /*--- Get the information of the angle of attack, reference area, etc. ---*/ + const su2double Alpha = config->GetAoA()*PI_NUMBER/180.0; + const su2double Beta = config->GetAoS()*PI_NUMBER/180.0; + const su2double RefArea = config->GetRefArea(); + const su2double RefLength = config->GetRefLength(); + const su2double Gas_Constant = config->GetGas_ConstantND(); + const su2double *Origin = config->GetRefOriginMoment(0); + const bool grid_movement = config->GetGrid_Movement(); + +/*--- Evaluate reference values for non-dimensionalization. + For dynamic meshes, use the motion Mach number as a reference value + for computing the force coefficients. Otherwise, use the freestream + values, which is the standard convention. ---*/ + const su2double RefTemp = Temperature_Inf; + const su2double RefDensity = Density_Inf; + const su2double RefHeatFlux = config->GetHeat_Flux_Ref(); + + su2double RefVel2; + if (grid_movement) { + const su2double Mach2Vel = sqrt(Gamma*Gas_Constant*RefTemp); + const su2double Mach_Motion = config->GetMach_Motion(); + RefVel2 = (Mach_Motion*Mach2Vel)*(Mach_Motion*Mach2Vel); + } + else { + RefVel2 = 0.0; + for(unsigned short iDim=0; iDimGetnMarker_Monitoring(); ++iMarker_Monitoring) { + Surface_CL_Visc[iMarker_Monitoring] = 0.0; Surface_CD_Visc[iMarker_Monitoring] = 0.0; + Surface_CSF_Visc[iMarker_Monitoring] = 0.0; Surface_CEff_Visc[iMarker_Monitoring] = 0.0; + Surface_CFx_Visc[iMarker_Monitoring] = 0.0; Surface_CFy_Visc[iMarker_Monitoring] = 0.0; + Surface_CFz_Visc[iMarker_Monitoring] = 0.0; Surface_CMx_Visc[iMarker_Monitoring] = 0.0; + Surface_CMy_Visc[iMarker_Monitoring] = 0.0; Surface_CMz_Visc[iMarker_Monitoring] = 0.0; + } + + /*--- Loop over the Navier-Stokes markers ---*/ + for(unsigned short iMarker=0; iMarkerGetMarker_All_Monitoring(iMarker); + if(Monitoring == YES) { + + /* Easier storage of the boundary condition. */ + const unsigned short Boundary = config->GetMarker_All_KindBC(iMarker); + + /*--- Obtain the origin for the moment computation for a particular marker ---*/ + for(unsigned short iMarker_Monitoring=0; iMarker_MonitoringGetnMarker_Monitoring(); + ++iMarker_Monitoring) { + string Monitoring_Tag = config->GetMarker_Monitoring_TagBound(iMarker_Monitoring); + string Marker_Tag = config->GetMarker_All_TagBound(iMarker); + if (Marker_Tag == Monitoring_Tag) + Origin = config->GetRefOriginMoment(iMarker_Monitoring); + } + + /* Check for a boundary for which the viscous forces must be computed. */ + if((Boundary == HEAT_FLUX) || (Boundary == ISOTHERMAL)) { + + /*--- Determine the prescribed heat flux or prescribed temperature. ---*/ + bool HeatFlux_Prescribed = false, Temperature_Prescribed = false; + su2double Wall_HeatFlux = 0.0, Wall_Temperature = 0.0; + + const string Marker_Tag = config->GetMarker_All_TagBound(iMarker); + if(Boundary == HEAT_FLUX) { + HeatFlux_Prescribed = true; + Wall_HeatFlux = config->GetWall_HeatFlux(Marker_Tag); + } + else { + Temperature_Prescribed = true; + Wall_Temperature = config->GetIsothermal_Temperature(Marker_Tag) + / config->GetTemperature_Ref(); + } + + /*--- Forces initialization at each Marker ---*/ + CD_Visc[iMarker] = 0.0; CL_Visc[iMarker] = 0.0; CSF_Visc[iMarker] = 0.0; + CMx_Visc[iMarker] = 0.0; CMy_Visc[iMarker] = 0.0; CMz_Visc[iMarker] = 0.0; + CFx_Visc[iMarker] = 0.0; CFy_Visc[iMarker] = 0.0; CFz_Visc[iMarker] = 0.0; + + Heat_Visc[iMarker] = 0.0; MaxHeatFlux_Visc[iMarker] = 0.0; CEff_Visc[iMarker] = 0.0; + + su2double ForceViscous[] = {0.0, 0.0, 0.0}; + su2double MomentViscous[] = {0.0, 0.0, 0.0}; + + /* Easier storage of the boundary faces for this boundary marker. */ + const unsigned long nSurfElem = boundaries[iMarker].surfElem.size(); + const CSurfaceElementFEM *surfElem = boundaries[iMarker].surfElem.data(); + + /* Check if a wall treatment is used. */ + if( boundaries[iMarker].wallModel ) { + + /*--- Wall treatment is used, so the wall shear stress and heat flux + are computed using the wall model. As the interpolation of data + of the exchange point is different for each element, it is not + possible to treat multiple faces simultaneously. So here just + a loop over the number of faces is carried out. ---*/ + for(unsigned long l=0; lgemm(nIntThisDonor, nVar, nDOFsElem, surfElem[l].matWallFunctionDonor[j].data(), + solDOFsElem, workArray, config); + + /* Loop over the integration points for this donor element. */ + for(unsigned short i=surfElem[l].nIntPerWallFunctionDonor[j]; + iSetTDState_rhoe(solInt[0], eInt); + const su2double Pressure = FluidModel->GetPressure(); + const su2double Temperature = FluidModel->GetTemperature(); + const su2double LaminarViscosity= FluidModel->GetLaminarViscosity(); + + /* Subtract the prescribed wall velocity, i.e. grid velocity + from the velocity in the exchange point. */ + for(unsigned short k=0; kWallShearStressAndHeatFlux(Temperature, velTan, + LaminarViscosity, Pressure, + Wall_HeatFlux, HeatFlux_Prescribed, + Wall_Temperature, Temperature_Prescribed, + FluidModel, tauWall, qWall, + ViscosityWall, kOverCvWall); + + /* Update the viscous forces and moments. Note that the force direction + is the direction of the tangential velocity. */ + const su2double dForceMag = tauWall*weights[ii]*normals[nDim]*factor; + su2double dForces[] = {0.0, 0.0, 0.0}, dCoor[] = {0.0, 0.0, 0.0}; + for(unsigned short k=0; kgemm(nInt, NPad, nDOFsFace, basisFace, solCopy, solInt, config); + + /*--- Store the solution of the DOFs of the adjacent elements in contiguous + memory such that the function blasFunctions->gemm can be used to compute + the gradients solution variables in the integration points of the face. ---*/ + for(unsigned short ll=0; llgemm(nInt*nDim, NPad, nDOFsElem, derBasisElem, solCopy, gradSolInt, config); + + /* Determine the offset between r- and -s-derivatives, which is also the + offset between s- and t-derivatives. */ + const unsigned short offDeriv = NPad*nInt; + + /* Make a distinction between two and three space dimensions + in order to have the most efficient code. */ + switch( nDim ) { + + case 2: { + + /* Two dimensional simulation. Loop over the number of faces treated + simultaneously. */ + for(unsigned short ll=0; llSetTDState_rhoe(sol[0], StaticEnergy); + const su2double ViscosityLam = FluidModel->GetLaminarViscosity(); + + /* Set the value of the second viscosity and compute the + divergence term in the viscous normal stresses. */ + const su2double lambda = -TWO3*ViscosityLam; + const su2double lamDivTerm = lambda*divVel; + + /* Compute the viscous stress tensor and the normal flux. + Note that there is a plus sign for the heat flux, because + the normal points into the geometry. */ + const su2double tauxx = 2.0*ViscosityLam*dudx + lamDivTerm; + const su2double tauyy = 2.0*ViscosityLam*dvdy + lamDivTerm; + const su2double tauxy = ViscosityLam*(dudy + dvdx); + + const su2double qHeatNorm = ViscosityLam*factHeatFlux_Lam + * (dStaticEnergydx*normals[0] + + dStaticEnergydy*normals[1]); + + /* Update the viscous force and moment. Note that the normal + points into the geometry, hence the minus sign for the stress. */ + const su2double scaleFac = weights[i]*normals[nDim]*factor; + const su2double Fx = -scaleFac*(tauxx*normals[0] + tauxy*normals[1]); + const su2double Fy = -scaleFac*(tauxy*normals[0] + tauyy*normals[1]); + + ForceViscous[0] += Fx; + ForceViscous[1] += Fy; + + const su2double dx = Coord[0] - Origin[0]; + const su2double dy = Coord[1] - Origin[1]; + + MomentViscous[2] += (Fy*dx - Fx*dy)/RefLength; + + /* Update the heat flux and maximum heat flux for this marker. */ + Heat_Visc[iMarker] += qHeatNorm*weights[i]*normals[nDim]*RefHeatFlux; + MaxHeatFlux_Visc[iMarker] = max(MaxHeatFlux_Visc[iMarker], fabs(qHeatNorm)); + } + } + + break; + } + + /*------------------------------------------------------------------*/ + + case 3: { + + /* Three dimensional simulation. Loop over the number of faces treated + simultaneously. */ + for(unsigned short ll=0; llSetTDState_rhoe(sol[0], StaticEnergy); + const su2double ViscosityLam = FluidModel->GetLaminarViscosity(); + + /* Set the value of the second viscosity and compute the + divergence term in the viscous normal stresses. */ + const su2double lambda = -TWO3*ViscosityLam; + const su2double lamDivTerm = lambda*divVel; + + /* Compute the viscous stress tensor and the normal flux. + Note that there is a plus sign for the heat flux, because + the normal points into the geometry. */ + const su2double tauxx = 2.0*ViscosityLam*dudx + lamDivTerm; + const su2double tauyy = 2.0*ViscosityLam*dvdy + lamDivTerm; + const su2double tauzz = 2.0*ViscosityLam*dwdz + lamDivTerm; + + const su2double tauxy = ViscosityLam*(dudy + dvdx); + const su2double tauxz = ViscosityLam*(dudz + dwdx); + const su2double tauyz = ViscosityLam*(dvdz + dwdy); + + const su2double qHeatNorm = ViscosityLam*factHeatFlux_Lam + * (dStaticEnergydx*normals[0] + + dStaticEnergydy*normals[1] + + dStaticEnergydz*normals[2]); + + /* Update the viscous force and moment. Note that the normal + points into the geometry, hence the minus sign for the stress. */ + const su2double scaleFac = weights[i]*normals[nDim]*factor; + + const su2double Fx = -scaleFac*(tauxx*normals[0] + tauxy*normals[1] + + tauxz*normals[2]); + const su2double Fy = -scaleFac*(tauxy*normals[0] + tauyy*normals[1] + + tauyz*normals[2]); + const su2double Fz = -scaleFac*(tauxz*normals[0] + tauyz*normals[1] + + tauzz*normals[2]); + + ForceViscous[0] += Fx; + ForceViscous[1] += Fy; + ForceViscous[2] += Fz; + + const su2double dx = Coord[0] - Origin[0]; + const su2double dy = Coord[1] - Origin[1]; + const su2double dz = Coord[2] - Origin[2]; + + MomentViscous[0] += (Fz*dy - Fy*dz)/RefLength; + MomentViscous[1] += (Fx*dz - Fz*dx)/RefLength; + MomentViscous[2] += (Fy*dx - Fx*dy)/RefLength; + + /* Update the heat flux and maximum heat flux for this marker. */ + Heat_Visc[iMarker] += qHeatNorm*weights[i]*normals[nDim]*RefHeatFlux; + MaxHeatFlux_Visc[iMarker] = max(MaxHeatFlux_Visc[iMarker], fabs(qHeatNorm)); + } + } + + break; + } + } + + /* Update the value of the counter l to the end index of the + current chunk. */ + l = lEnd; + } + } + + /*--- Project forces and store the non-dimensional coefficients ---*/ + if (nDim == 2) { + CD_Visc[iMarker] = ForceViscous[0]*cos(Alpha) + ForceViscous[1]*sin(Alpha); + CL_Visc[iMarker] = -ForceViscous[0]*sin(Alpha) + ForceViscous[1]*cos(Alpha); + CEff_Visc[iMarker] = CL_Visc[iMarker] / (CD_Visc[iMarker]+EPS); + CMz_Visc[iMarker] = MomentViscous[2]; + CFx_Visc[iMarker] = ForceViscous[0]; + CFy_Visc[iMarker] = ForceViscous[1]; + } + if (nDim == 3) { + CD_Visc[iMarker] = ForceViscous[0]*cos(Alpha)*cos(Beta) + + ForceViscous[1]*sin(Beta) + + ForceViscous[2]*sin(Alpha)*cos(Beta); + CL_Visc[iMarker] = -ForceViscous[0]*sin(Alpha) + ForceViscous[2]*cos(Alpha); + CSF_Visc[iMarker] = -ForceViscous[0]*sin(Beta)*cos(Alpha) + + ForceViscous[1]*cos(Beta) + - ForceViscous[2]*sin(Beta)*sin(Alpha); + CEff_Visc[iMarker] = CL_Visc[iMarker]/(CD_Visc[iMarker] + EPS); + CMx_Visc[iMarker] = MomentViscous[0]; + CMy_Visc[iMarker] = MomentViscous[1]; + CMz_Visc[iMarker] = MomentViscous[2]; + CFx_Visc[iMarker] = ForceViscous[0]; + CFy_Visc[iMarker] = ForceViscous[1]; + CFz_Visc[iMarker] = ForceViscous[2]; + } + + AllBound_CD_Visc += CD_Visc[iMarker]; + AllBound_CL_Visc += CL_Visc[iMarker]; + AllBound_CSF_Visc += CSF_Visc[iMarker]; + AllBound_CMx_Visc += CMx_Visc[iMarker]; + AllBound_CMy_Visc += CMy_Visc[iMarker]; + AllBound_CMz_Visc += CMz_Visc[iMarker]; + AllBound_CFx_Visc += CFx_Visc[iMarker]; + AllBound_CFy_Visc += CFy_Visc[iMarker]; + AllBound_CFz_Visc += CFz_Visc[iMarker]; + + AllBound_HeatFlux_Visc += Heat_Visc[iMarker]; + AllBound_MaxHeatFlux_Visc = max(AllBound_MaxHeatFlux_Visc, + MaxHeatFlux_Visc[iMarker]); + + /*--- Compute the coefficients per surface ---*/ + for(unsigned short iMarker_Monitoring=0; iMarker_MonitoringGetnMarker_Monitoring(); + ++iMarker_Monitoring) { + string Monitoring_Tag = config->GetMarker_Monitoring_TagBound(iMarker_Monitoring); + string Marker_Tag = config->GetMarker_All_TagBound(iMarker); + if (Marker_Tag == Monitoring_Tag) { + Surface_CL_Visc[iMarker_Monitoring] += CL_Visc[iMarker]; + Surface_CD_Visc[iMarker_Monitoring] += CD_Visc[iMarker]; + Surface_CSF_Visc[iMarker_Monitoring] += CSF_Visc[iMarker]; + Surface_CEff_Visc[iMarker_Monitoring] += CEff_Visc[iMarker]; + Surface_CFx_Visc[iMarker_Monitoring] += CFx_Visc[iMarker]; + Surface_CFy_Visc[iMarker_Monitoring] += CFy_Visc[iMarker]; + Surface_CFz_Visc[iMarker_Monitoring] += CFz_Visc[iMarker]; + Surface_CMx_Visc[iMarker_Monitoring] += CMx_Visc[iMarker]; + Surface_CMy_Visc[iMarker_Monitoring] += CMy_Visc[iMarker]; + Surface_CMz_Visc[iMarker_Monitoring] += CMz_Visc[iMarker]; + } + } + } + } + } + +#ifdef HAVE_MPI + + /*--- Parallel mode. The data from all ranks must be gathered. + Determine the size of the communication buffer. ---*/ + const unsigned long nCommSize = 9*config->GetnMarker_Monitoring() + 10; + + /*--- Define the communication buffers and store to local data in + the local buffer. ---*/ + vector locBuf(nCommSize), globBuf(nCommSize); + + unsigned long ii = 0; + locBuf[ii++] = AllBound_CD_Visc; locBuf[ii++] = AllBound_CL_Visc; + locBuf[ii++] = AllBound_CSF_Visc; locBuf[ii++] = AllBound_CMx_Visc; + locBuf[ii++] = AllBound_CMy_Visc; locBuf[ii++] = AllBound_CMz_Visc; + locBuf[ii++] = AllBound_CFx_Visc; locBuf[ii++] = AllBound_CFy_Visc; + locBuf[ii++] = AllBound_CFz_Visc; locBuf[ii++] = AllBound_HeatFlux_Visc; + + for(unsigned short i=0; iGetnMarker_Monitoring(); ++i) { + locBuf[ii++] = Surface_CL_Visc[i]; locBuf[ii++] = Surface_CD_Visc[i]; + locBuf[ii++] = Surface_CSF_Visc[i]; locBuf[ii++] = Surface_CFx_Visc[i]; + locBuf[ii++] = Surface_CFy_Visc[i]; locBuf[ii++] = Surface_CFz_Visc[i]; + locBuf[ii++] = Surface_CMx_Visc[i]; locBuf[ii++] = Surface_CMy_Visc[i]; + locBuf[ii++] = Surface_CMz_Visc[i]; + } + + /* Sum up all the data from all ranks. The result will be available on all ranks. */ + if (config->GetComm_Level() == COMM_FULL) { + SU2_MPI::Allreduce(locBuf.data(), globBuf.data(), nCommSize, MPI_DOUBLE, + MPI_SUM, MPI_COMM_WORLD); + } + + /*--- Copy the data back from globBuf into the required variables. ---*/ + ii = 0; + AllBound_CD_Visc = globBuf[ii++]; AllBound_CL_Visc = globBuf[ii++]; + AllBound_CSF_Visc = globBuf[ii++]; AllBound_CMx_Visc = globBuf[ii++]; + AllBound_CMy_Visc = globBuf[ii++]; AllBound_CMz_Visc = globBuf[ii++]; + AllBound_CFx_Visc = globBuf[ii++]; AllBound_CFy_Visc = globBuf[ii++]; + AllBound_CFz_Visc = globBuf[ii++]; AllBound_HeatFlux_Visc = globBuf[ii++]; + + AllBound_CEff_Visc = AllBound_CL_Visc/(AllBound_CD_Visc + EPS); + + for(unsigned short i=0; iGetnMarker_Monitoring(); ++i) { + Surface_CL_Visc[i] = globBuf[ii++]; Surface_CD_Visc[i] = globBuf[ii++]; + Surface_CSF_Visc[i] = globBuf[ii++]; Surface_CFx_Visc[i] = globBuf[ii++]; + Surface_CFy_Visc[i] = globBuf[ii++]; Surface_CFz_Visc[i] = globBuf[ii++]; + Surface_CMx_Visc[i] = globBuf[ii++]; Surface_CMy_Visc[i] = globBuf[ii++]; + Surface_CMz_Visc[i] = globBuf[ii++]; + + Surface_CEff_Visc[i] = Surface_CL_Visc[i]/(Surface_CD_Visc[i] + EPS); + } + + /* Determine the maximum heat flux over all ranks. */ + su2double localMax = AllBound_MaxHeatFlux_Visc; + if (config->GetComm_Level() == COMM_FULL) { + SU2_MPI::Allreduce(&localMax, &AllBound_MaxHeatFlux_Visc, 1, MPI_DOUBLE, + MPI_MAX, MPI_COMM_WORLD); + } +#endif + + /*--- Update the total coefficients (note that all the nodes have the same value)---*/ + Total_CD += AllBound_CD_Visc; + Total_CL += AllBound_CL_Visc; + Total_CSF += AllBound_CSF_Visc; + Total_CEff = Total_CL / (Total_CD + EPS); + Total_CMx += AllBound_CMx_Visc; + Total_CMy += AllBound_CMy_Visc; + Total_CMz += AllBound_CMz_Visc; + Total_CFx += AllBound_CFx_Visc; + Total_CFy += AllBound_CFy_Visc; + Total_CFz += AllBound_CFz_Visc; + + /*--- Update the total coefficients per surface (note that all the nodes have the same value)---*/ + for (unsigned short iMarker_Monitoring=0; iMarker_MonitoringGetnMarker_Monitoring(); + ++iMarker_Monitoring) { + Surface_CL[iMarker_Monitoring] += Surface_CL_Visc[iMarker_Monitoring]; + Surface_CD[iMarker_Monitoring] += Surface_CD_Visc[iMarker_Monitoring]; + Surface_CSF[iMarker_Monitoring] += Surface_CSF_Visc[iMarker_Monitoring]; + Surface_CEff[iMarker_Monitoring] = Surface_CL[iMarker_Monitoring] / (Surface_CD[iMarker_Monitoring] + EPS); + Surface_CFx[iMarker_Monitoring] += Surface_CFx_Visc[iMarker_Monitoring]; + Surface_CFy[iMarker_Monitoring] += Surface_CFy_Visc[iMarker_Monitoring]; + Surface_CFz[iMarker_Monitoring] += Surface_CFz_Visc[iMarker_Monitoring]; + Surface_CMx[iMarker_Monitoring] += Surface_CMx_Visc[iMarker_Monitoring]; + Surface_CMy[iMarker_Monitoring] += Surface_CMy_Visc[iMarker_Monitoring]; + Surface_CMz[iMarker_Monitoring] += Surface_CMz_Visc[iMarker_Monitoring]; + } +} + +void CFEM_DG_NSSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, + unsigned short iMesh, unsigned long Iteration) { + + /* Check whether or not a time stepping scheme is used. */ + const bool time_stepping = config->GetTime_Marching() == TIME_STEPPING; + + /* Allocate the memory for the work array and initialize it to zero to avoid + warnings in debug mode about uninitialized memory when padding is applied. */ + vector workArrayVec(sizeWorkArray, 0.0); + su2double *workArray = workArrayVec.data(); + + /* Constant factor present in the heat flux vector, namely the ratio of + thermal conductivity and viscosity. */ + const su2double factHeatFlux_Lam = Gamma/Prandtl_Lam; + const su2double factHeatFlux_Turb = Gamma/Prandtl_Turb; + + /* Constant ratio of the second viscosity and the viscosity itself. */ + const su2double lambdaOverMu = -TWO3; + + /* The eigenvalues of the viscous Jacobian, scaled by the kinematic viscosity, + are 1.0, 2.0 + lambdaOverMu and kOverCv/Mu. The last is variable due to the + possible presence of an eddy viscosity, but the first two are constant and + the maximum can be determined. */ + const su2double radOverNuTerm = max(1.0, 2.0+lambdaOverMu); + + /* Store the number of metric points per DOF, which depends + on the number of dimensions. */ + const unsigned short nMetricPerPoint = nDim*nDim + 1; + + /* Determine the number of elements that are treated simultaneously + in the matrix products to obtain good gemm performance. */ + const unsigned short nPadInput = config->GetSizeMatMulPadding(); + const unsigned short nElemSimul = nPadInput/nVar; + + /* Determine the minimum padded size in the matrix multiplications, which + corresponds to 64 byte alignment. */ + const unsigned short nPadMin = 64/sizeof(passivedouble); + + /* Set the number of bytes that must be copied in the memcpy calls. */ + const unsigned long nBytes = nVar*sizeof(su2double); + + /* Initialize the minimum and maximum time step. */ + Min_Delta_Time = 1.e25; Max_Delta_Time = 0.0; + + /* Easier storage of the CFL number. Note that if we are using explicit + time stepping, the regular CFL condition has been overwritten with the + unsteady CFL condition in the config post-processing (if non-zero). */ + + const su2double CFL = config->GetCFL(iMesh); + + /*--- Explicit time stepping with imposed time step (eventually will + allow for local time stepping with this value imposed as the time + for syncing the cells). If the unsteady CFL is set to zero (default), + it uses the defined unsteady time step, otherwise it computes the time + step based on the provided unsteady CFL. Note that the regular CFL + option in the config is always ignored with time stepping. ---*/ + if (time_stepping && (config->GetUnst_CFL() == 0.0)) { + + /*--- Loop over the owned volume elements and set the fixed dt. ---*/ + for(unsigned long l=0; lGetDelta_UnstTimeND(); + + } else { + + /*--- Check for a compressible solver. ---*/ + if(config->GetKind_Regime() == COMPRESSIBLE) { + + /*--- Loop over the owned volume elements. Multiple elements are treated + simultaneously to improve the performance of the matrix + multiplications. As a consequence, the update of the counter l + happens at the end of this loop section. ---*/ + for(unsigned long l=0; lgemm(nDOFs*nDim, NPad, nDOFs, matDerBasisSolDOFs, solDOFs, gradSolDOFs, config); + } + + /*--- Make a distinction between 2D and 3D for optimal performance. ---*/ + switch( nDim ) { + + case 2: { + + /*--- 2D simulation. Loop over the chunk of elements. ---*/ + for(unsigned short ll=0; llSetTDState_rhoe(solDOF[0], StaticEnergy); + const su2double SoundSpeed2 = FluidModel->GetSoundSpeed2(); + const su2double SoundSpeed = sqrt(fabs(SoundSpeed2)); + + const su2double radx = fabs(u-gridVel[0]) + SoundSpeed; + const su2double rady = fabs(v-gridVel[1]) + SoundSpeed; + const su2double charVel2 = radx*radx + rady*rady; + + charVel2Max = max(charVel2Max, charVel2); + + /* Compute the laminar kinematic viscosity and check if an eddy + viscosity must be determined. */ + const su2double muLam = FluidModel->GetLaminarViscosity(); + su2double muTurb = 0.0; + + if( SGSModelUsed ) { + + /* Set the pointers to the locations where the gradients + of this DOF start. */ + const su2double *solDOFDr = gradSolDOFs + i*NPad + llNVar; + const su2double *solDOFDs = solDOFDr + offDerivSol; + + /* Compute the true value of the metric terms in this DOF. Note that in + metricTerms the metric terms scaled by the Jacobian are stored. */ + const su2double *metricTerms = volElem[lInd].metricTermsSolDOFs.data() + + i*nMetricPerPoint; + const su2double JacInv = 1.0/metricTerms[0]; + + const su2double drdx = JacInv*metricTerms[1]; + const su2double drdy = JacInv*metricTerms[2]; + + const su2double dsdx = JacInv*metricTerms[3]; + const su2double dsdy = JacInv*metricTerms[4]; + + /*--- Compute the Cartesian gradients of the independent solution + variables from the gradients in parametric coordinates and the metric + terms in this DOF. ---*/ + const su2double drhodx = solDOFDr[0]*drdx + solDOFDs[0]*dsdx; + const su2double drudx = solDOFDr[1]*drdx + solDOFDs[1]*dsdx; + const su2double drvdx = solDOFDr[2]*drdx + solDOFDs[2]*dsdx; + + const su2double drhody = solDOFDr[0]*drdy + solDOFDs[0]*dsdy; + const su2double drudy = solDOFDr[1]*drdy + solDOFDs[1]*dsdy; + const su2double drvdy = solDOFDr[2]*drdy + solDOFDs[2]*dsdy; + + /*--- Compute the Cartesian gradients of the velocities. ---*/ + const su2double dudx = DensityInv*(drudx - u*drhodx); + const su2double dvdx = DensityInv*(drvdx - v*drhodx); + const su2double dudy = DensityInv*(drudy - u*drhody); + const su2double dvdy = DensityInv*(drvdy - v*drhody); + + /* Compute the eddy viscosity. */ + const su2double dist = volElem[lInd].wallDistanceSolDOFs[i]; + muTurb = SGSModel->ComputeEddyViscosity_2D(solDOF[0], dudx, dudy, + dvdx, dvdy, lenScale, + dist); + } + + /*--- Determine the viscous spectral radius. ---*/ + const su2double mu = muLam + muTurb; + const su2double kOverCv = muLam*factHeatFlux_Lam + + muTurb*factHeatFlux_Turb; + const su2double factHeatFlux = kOverCv/mu; + + const su2double radVisc = DensityInv*mu*max(radOverNuTerm, factHeatFlux); + + /* Update the maximum value of the viscous spectral radius. */ + radViscMax = max(radViscMax, radVisc); + } + + /*--- Compute the time step for the element and update the minimum and + maximum value. Take the factor for time accurate local time + stepping into account for the minimum and maximum. ---*/ + const su2double dtInv = lenScaleInv*(sqrt(charVel2Max) + radViscMax*lenScaleInv); + + VecDeltaTime[lInd] = CFL/dtInv; + + const su2double dtEff = volElem[lInd].factTimeLevel*VecDeltaTime[lInd]; + Min_Delta_Time = min(Min_Delta_Time, dtEff); + Max_Delta_Time = max(Max_Delta_Time, dtEff); + } + + break; + } + + /*------------------------------------------------------------------*/ + + case 3: { + + /*--- 3D simulation. Loop over the chunk of elements. ---*/ + for(unsigned short ll=0; llSetTDState_rhoe(solDOF[0], StaticEnergy); + const su2double SoundSpeed2 = FluidModel->GetSoundSpeed2(); + const su2double SoundSpeed = sqrt(fabs(SoundSpeed2)); + + const su2double radx = fabs(u-gridVel[0]) + SoundSpeed; + const su2double rady = fabs(v-gridVel[1]) + SoundSpeed; + const su2double radz = fabs(w-gridVel[2]) + SoundSpeed; + const su2double charVel2 = radx*radx + rady*rady + radz*radz; + + charVel2Max = max(charVel2Max, charVel2); + + /* Compute the laminar kinematic viscosity and check if an eddy + viscosity must be determined. */ + const su2double muLam = FluidModel->GetLaminarViscosity(); + su2double muTurb = 0.0; + + if( SGSModelUsed ) { + + /* Set the pointers to the locations where the gradients + of this DOF start. */ + const su2double *solDOFDr = gradSolDOFs + i*NPad + llNVar; + const su2double *solDOFDs = solDOFDr + offDerivSol; + const su2double *solDOFDt = solDOFDs + offDerivSol; + + /* Compute the true value of the metric terms in this DOF. Note that in + metricTerms the metric terms scaled by the Jacobian are stored. */ + const su2double *metricTerms = volElem[lInd].metricTermsSolDOFs.data() + + i*nMetricPerPoint; + const su2double JacInv = 1.0/metricTerms[0]; + + const su2double drdx = JacInv*metricTerms[1]; + const su2double drdy = JacInv*metricTerms[2]; + const su2double drdz = JacInv*metricTerms[3]; + + const su2double dsdx = JacInv*metricTerms[4]; + const su2double dsdy = JacInv*metricTerms[5]; + const su2double dsdz = JacInv*metricTerms[6]; + + const su2double dtdx = JacInv*metricTerms[7]; + const su2double dtdy = JacInv*metricTerms[8]; + const su2double dtdz = JacInv*metricTerms[9]; + + /*--- Compute the Cartesian gradients of the independent solution + variables from the gradients in parametric coordinates and the metric + terms in this DOF. ---*/ + const su2double drhodx = solDOFDr[0]*drdx + solDOFDs[0]*dsdx + solDOFDt[0]*dtdx; + const su2double drux = solDOFDr[1]*drdx + solDOFDs[1]*dsdx + solDOFDt[1]*dtdx; + const su2double drvx = solDOFDr[2]*drdx + solDOFDs[2]*dsdx + solDOFDt[2]*dtdx; + const su2double drwx = solDOFDr[3]*drdx + solDOFDs[3]*dsdx + solDOFDt[3]*dtdx; + + const su2double drhody = solDOFDr[0]*drdy + solDOFDs[0]*dsdy + solDOFDt[0]*dtdy; + const su2double druy = solDOFDr[1]*drdy + solDOFDs[1]*dsdy + solDOFDt[1]*dtdy; + const su2double drvy = solDOFDr[2]*drdy + solDOFDs[2]*dsdy + solDOFDt[2]*dtdy; + const su2double drwy = solDOFDr[3]*drdy + solDOFDs[3]*dsdy + solDOFDt[3]*dtdy; + + const su2double drhodz = solDOFDr[0]*drdz + solDOFDs[0]*dsdz + solDOFDt[0]*dtdz; + const su2double druz = solDOFDr[1]*drdz + solDOFDs[1]*dsdz + solDOFDt[1]*dtdz; + const su2double drvz = solDOFDr[2]*drdz + solDOFDs[2]*dsdz + solDOFDt[2]*dtdz; + const su2double drwz = solDOFDr[3]*drdz + solDOFDs[3]*dsdz + solDOFDt[3]*dtdz; + + /*--- Compute the Cartesian gradients of the velocities. ---*/ + const su2double dudx = DensityInv*(drux - u*drhodx); + const su2double dudy = DensityInv*(druy - u*drhody); + const su2double dudz = DensityInv*(druz - u*drhodz); + + const su2double dvdx = DensityInv*(drvx - v*drhodx); + const su2double dvdy = DensityInv*(drvy - v*drhody); + const su2double dvdz = DensityInv*(drvz - v*drhodz); + + const su2double dwdx = DensityInv*(drwx - w*drhodx); + const su2double dwdy = DensityInv*(drwy - w*drhody); + const su2double dwdz = DensityInv*(drwz - w*drhodz); + + /* Compute the eddy viscosity. */ + const su2double dist = volElem[lInd].wallDistanceSolDOFs[i]; + muTurb = SGSModel->ComputeEddyViscosity_3D(solDOF[0], dudx, dudy, dudz, + dvdx, dvdy, dvdz, dwdx, dwdy, + dwdz, lenScale, dist); + } + + /*--- Determine the viscous spectral radius. ---*/ + const su2double mu = muLam + muTurb; + const su2double kOverCv = muLam*factHeatFlux_Lam + + muTurb*factHeatFlux_Turb; + const su2double factHeatFlux = kOverCv/mu; + + const su2double radVisc = DensityInv*mu*max(radOverNuTerm, factHeatFlux); + + /* Update the maximum value of the viscous spectral radius. */ + radViscMax = max(radViscMax, radVisc); + } + + /*--- Compute the time step for the element and update the minimum and + maximum value. Take the factor for time accurate local time + stepping into account for the minimum and maximum. ---*/ + const su2double dtInv = lenScaleInv*(sqrt(charVel2Max) + radViscMax*lenScaleInv); + + VecDeltaTime[lInd] = CFL/dtInv; + + const su2double dtEff = volElem[lInd].factTimeLevel*VecDeltaTime[lInd]; + Min_Delta_Time = min(Min_Delta_Time, dtEff); + Max_Delta_Time = max(Max_Delta_Time, dtEff); + } + + break; + } + } + + /* Update the value of the counter l to the end index of the + current chunk. */ + l = lEnd; + } + } + else { + + /*--- Incompressible solver. ---*/ + + SU2_MPI::Error("Incompressible solver not implemented yet", CURRENT_FUNCTION); + } + + /*--- Compute the max and the min dt (in parallel). Note that we only + do this for steady calculations if the high verbosity is set, but we + always perform the reduction for unsteady calculations where the CFL + limit is used to set the global time step. ---*/ + if ((config->GetComm_Level() == COMM_FULL) || time_stepping) { +#ifdef HAVE_MPI + su2double rbuf_time = Min_Delta_Time; + SU2_MPI::Allreduce(&rbuf_time, &Min_Delta_Time, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); + + rbuf_time = Max_Delta_Time; + SU2_MPI::Allreduce(&rbuf_time, &Max_Delta_Time, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); +#endif + } + + /*--- For explicit time stepping with an unsteady CFL imposed, use the + minimum delta time of the entire mesh. As Min_Delta_Time is scaled to + the time step of the largest time level, a correction must be used + for the time level when time accurate local time stepping is used. ---*/ + if (time_stepping) { + for(unsigned long l=0; lSetDelta_UnstTimeND(Min_Delta_Time); + } + } +} + +void CFEM_DG_NSSolver::ADER_DG_AliasedPredictorResidual_2D(CConfig *config, + CVolumeElementFEM *elem, + const su2double *sol, + const unsigned short nSimul, + const unsigned short NPad, + su2double *res, + su2double *work) { + /* Constant factor present in the heat flux vector. */ + const su2double factHeatFlux_Lam = Gamma/Prandtl_Lam; + const su2double factHeatFlux_Turb = Gamma/Prandtl_Turb; + + /* Get the necessary information from the standard element. */ + const unsigned short ind = elem->indStandardElement; + const unsigned short nInt = standardElementsSol[ind].GetNIntegration(); + const unsigned short nDOFs = elem->nDOFsSol; + const su2double *matBasisInt = standardElementsSol[ind].GetMatBasisFunctionsIntegration(); + const su2double *matDerBasisInt = matBasisInt + nDOFs*nInt; + const su2double *matDerBasisSolDOFs = standardElementsSol[ind].GetMatDerBasisFunctionsSolDOFs(); + const su2double *basisFunctionsIntTrans = standardElementsSol[ind].GetBasisFunctionsIntegrationTrans(); + const su2double *weights = standardElementsSol[ind].GetWeightsIntegration(); + + unsigned short nPoly = standardElementsSol[ind].GetNPoly(); + if(nPoly == 0) nPoly = 1; + + /* Compute the length scale of the current element for the LES. */ + const su2double lenScale = elem->lenScale/nPoly; + + /* Set the pointers for fluxes in the DOFs, the gradient of the fluxes in + the integration points, the gradient of the solution in the DOFs and the + divergence of the fluxes in the integration points. Note that some pointers + point to the same physical location. This is because this memory can be + used for different purposes. */ + su2double *fluxXDOF = work; + su2double *fluxYDOF = fluxXDOF + NPad*nDOFs; + su2double *gradFluxXInt = fluxYDOF + NPad*nDOFs; + su2double *gradFluxYInt = gradFluxXInt + nDim*NPad*nInt; + su2double *gradSolDOFs = gradFluxXInt; + su2double *divFlux = work; + + /* Determine the offset between the r-derivatives and s-derivatives of the + fluxes in the integration points and the offset between the r-derivatives + and s-derivatives of the solution in the DOFs. */ + const unsigned short offDerivSol = NPad*nDOFs; + const unsigned short offDerivFluxes = NPad*nInt; + + /* Store the number of metric points per integration point for readability. */ + const unsigned short nMetricPerPoint = 5; /* nDim*nDim + 1. */ + + /*--------------------------------------------------------------------------*/ + /*--- Construct the Cartesian fluxes in the DOFs. ---*/ + /*--------------------------------------------------------------------------*/ + + /* Compute the derivatives of the solution variables w.r.t. the parametric + coordinates in the DOFs. */ + blasFunctions->gemm(nDOFs*nDim, NPad, nDOFs, matDerBasisSolDOFs, sol, gradSolDOFs, config); + + /*--- Loop over the number of entities that are treated simultaneously. */ + for(unsigned short simul=0; simulgridVelocitiesSolDOFs.data() + 2*i; /* nDim*i. */ + + /* Compute the true value of the metric terms in this DOF. Note that in + metricTerms the metric terms scaled by the Jacobian are stored. THIS + IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, THE + DATA FOR THIS DOF FOR THE CURRENT TIME INTEGRATION POINT MUST BE TAKEN. */ + const su2double *metricTerms = elem->metricTermsSolDOFs.data() + + i*nMetricPerPoint; + const su2double JacInv = 1.0/metricTerms[0]; + + const su2double drdx = JacInv*metricTerms[1]; + const su2double drdy = JacInv*metricTerms[2]; + + const su2double dsdx = JacInv*metricTerms[3]; + const su2double dsdy = JacInv*metricTerms[4]; + + /* Compute the Cartesian gradients of the independent solution variables + from the gradients in parametric coordinates and the metric terms. */ + const su2double drhodx = solDOFDr[0]*drdx + solDOFDs[0]*dsdx; + const su2double drudx = solDOFDr[1]*drdx + solDOFDs[1]*dsdx; + const su2double drvdx = solDOFDr[2]*drdx + solDOFDs[2]*dsdx; + const su2double drEdx = solDOFDr[3]*drdx + solDOFDs[3]*dsdx; + + const su2double drhody = solDOFDr[0]*drdy + solDOFDs[0]*dsdy; + const su2double drudy = solDOFDr[1]*drdy + solDOFDs[1]*dsdy; + const su2double drvdy = solDOFDr[2]*drdy + solDOFDs[2]*dsdy; + const su2double drEdy = solDOFDr[3]*drdy + solDOFDs[3]*dsdy; + + /* Compute the velocities, pressure and laminar viscosity in this DOF. */ + const su2double DensityInv = 1.0/solDOF[0]; + const su2double u = DensityInv*solDOF[1]; + const su2double v = DensityInv*solDOF[2]; + const su2double TotalEnergy = DensityInv*solDOF[3]; + const su2double StaticEnergy = TotalEnergy - 0.5*(u*u + v*v); + + FluidModel->SetTDState_rhoe(solDOF[0], StaticEnergy); + const su2double Pressure = FluidModel->GetPressure(); + const su2double ViscosityLam = FluidModel->GetLaminarViscosity(); + + /* Compute the Cartesian gradients of the velocities and static energy. */ + const su2double dudx = DensityInv*(drudx - u*drhodx); + const su2double dvdx = DensityInv*(drvdx - v*drhodx); + const su2double dudy = DensityInv*(drudy - u*drhody); + const su2double dvdy = DensityInv*(drvdy - v*drhody); + + const su2double dedx = DensityInv*(drEdx - TotalEnergy*drhodx) - u*dudx - v*dvdx; + const su2double dedy = DensityInv*(drEdy - TotalEnergy*drhody) - u*dudy - v*dvdy; + + /* Compute the eddy viscosity, if needed, and the total viscosity. */ + su2double ViscosityTurb = 0.0; + if( SGSModelUsed ) + ViscosityTurb = SGSModel->ComputeEddyViscosity_2D(solDOF[0], dudx, dudy, + dvdx, dvdy, lenScale, + elem->wallDistanceSolDOFs[i]); + const su2double Viscosity = ViscosityLam + ViscosityTurb; + + /* Compute the total thermal conductivity divided by Cv. */ + const su2double kOverCv = ViscosityLam *factHeatFlux_Lam + + ViscosityTurb*factHeatFlux_Turb; + + /* Set the value of the second viscosity and compute the divergence + term in the viscous normal stresses. */ + const su2double lambda = -TWO3*Viscosity; + const su2double lamDivTerm = lambda*(dudx + dvdy); + + /* Compute the viscous stress tensor. */ + const su2double tauxx = 2.0*Viscosity*dudx + lamDivTerm; + const su2double tauyy = 2.0*Viscosity*dvdy + lamDivTerm; + const su2double tauxy = Viscosity*(dudy + dvdx); + + /* The Cartesian fluxes in the x-direction. */ + const su2double uRel = u - gridVel[0]; + fluxX[0] = solDOF[0]*uRel; + fluxX[1] = solDOF[1]*uRel + Pressure - tauxx; + fluxX[2] = solDOF[2]*uRel - tauxy; + fluxX[3] = solDOF[3]*uRel + Pressure*u - kOverCv*dedx - u*tauxx - v*tauxy;; + + /* The Cartesian fluxes in the y-direction. */ + const su2double vRel = v - gridVel[1]; + fluxY[0] = solDOF[0]*vRel; + fluxY[1] = solDOF[1]*vRel - tauxy; + fluxY[2] = solDOF[2]*vRel + Pressure - tauyy; + fluxY[3] = solDOF[3]*vRel + Pressure*v - kOverCv*dedy - u*tauxy - v*tauyy; + } + } + + /*--------------------------------------------------------------------------*/ + /*--- Compute the derivatives of the Cartesian fluxes w.r.t. the ---*/ + /*--- parametric coordinates in the integration points. ---*/ + /*--------------------------------------------------------------------------*/ + + blasFunctions->gemm(nInt*nDim, NPad, nDOFs, matDerBasisInt, fluxXDOF, gradFluxXInt, config); + blasFunctions->gemm(nInt*nDim, NPad, nDOFs, matDerBasisInt, fluxYDOF, gradFluxYInt, config); + + /*--------------------------------------------------------------------------*/ + /*--- Compute the divergence of the fluxes in the integration points, ---*/ + /*--- multiplied by the integration weight. ---*/ + /*--------------------------------------------------------------------------*/ + + /*--- Loop over the number of entities that are treated simultaneously. */ + for(unsigned short simul=0; simulmetricTerms.data() + i*nMetricPerPoint; + + /* Compute the metric terms multiplied by the integration weight. Note that the + first term in the metric terms is the Jacobian. */ + const su2double wDrdx = weights[i]*metricTerms[1]; + const su2double wDrdy = weights[i]*metricTerms[2]; + + const su2double wDsdx = weights[i]*metricTerms[3]; + const su2double wDsdy = weights[i]*metricTerms[4]; + + /* Compute the divergence of the fluxes, multiplied by the + integration weight. */ + divFluxInt[0] = gradFluxXDr[0]*wDrdx + gradFluxXDs[0]*wDsdx + + gradFluxYDr[0]*wDrdy + gradFluxYDs[0]*wDsdy; + divFluxInt[1] = gradFluxXDr[1]*wDrdx + gradFluxXDs[1]*wDsdx + + gradFluxYDr[1]*wDrdy + gradFluxYDs[1]*wDsdy; + divFluxInt[2] = gradFluxXDr[2]*wDrdx + gradFluxXDs[2]*wDsdx + + gradFluxYDr[2]*wDrdy + gradFluxYDs[2]*wDsdy; + divFluxInt[3] = gradFluxXDr[3]*wDrdx + gradFluxXDs[3]*wDsdx + + gradFluxYDr[3]*wDrdy + gradFluxYDs[3]*wDsdy; + } + } + + /*--------------------------------------------------------------------------*/ + /*--- Add the body force to the divergence of the fluxes, if such a ---*/ + /*--- force is present. ---*/ + /*--------------------------------------------------------------------------*/ + + if( config->GetBody_Force() ) { + + /* Easier storage of the body force. */ + const su2double *body_force_vector = config->GetBody_Force_Vector(); + + /* Compute the solution in the integration points of the element. + Use gradFluxYInt to store this solution. */ + su2double *solInt = gradFluxYInt; + + blasFunctions->gemm(nInt, NPad, nDOFs, matBasisInt, sol, solInt, config); + + /*--- Loop over the number of entities that are treated simultaneously. */ + for(unsigned short simul=0; simulmetricTerms.data() + i*nMetricPerPoint; + + /* Compute the velocities. */ + const su2double rhoInv = 1.0/solThisInt[0]; + const su2double u = solThisInt[1]*rhoInv; + const su2double v = solThisInt[2]*rhoInv; + + /* Add the body force to the flux divergence for the momentum and energy + equation. Note that the source terms are multiplied with minus the + integration weight in order to be consistent with the formulation of + the residual. Also note that for the energy source term the absolute + velocity must be taken and not the relative. */ + const su2double weightJac = weights[i]*metricTerms[0]; + + divFluxInt[1] -= weightJac*body_force_vector[0]; + divFluxInt[2] -= weightJac*body_force_vector[1]; + divFluxInt[3] -= weightJac*(u*body_force_vector[0] + v*body_force_vector[1]); + } + } + } + + /*--------------------------------------------------------------------------*/ + /*--- Add the source terms of the manufactured solution to the divergence---*/ + /*--- of the fluxes, if a manufactured solution is used. ---*/ + /*--------------------------------------------------------------------------*/ + + if( VerificationSolution ) { + if( VerificationSolution->IsManufacturedSolution() ) { + + /*--- Loop over the number of entities that are treated simultaneously. */ + for(unsigned short simul=0; simulcoorIntegrationPoints.data() + i*nDim; + + /* Easier storage of the metric terms in this integration point. + THIS IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, + THE DATA FOR THIS DOF FOR THE CURRENT TIME INTEGRATION POINT MUST + BE TAKEN. */ + const su2double *metricTerms = elem->metricTerms.data() + i*nMetricPerPoint; + const su2double weightJac = weights[i]*metricTerms[0]; + + /* Compute the source terms of the manufactured solution. + THIS IS A TEMPORARY IMPLEMENTATION. FOR AN ACTUAL TIME ACCURATE + SIMULATION THE CORRECT TIME MUST BE GIVEN TO THIS FUNCTION. */ + su2double sourceMan[4]; + VerificationSolution->GetMMSSourceTerm(coor, 0.0, sourceMan); + + /* Add the source terms to the flux divergence. Note that the source + terms are multiplied with minus the integration weight in order + to be consistent with the formulation of the residual. */ + divFluxInt[0] -= weightJac*sourceMan[0]; + divFluxInt[1] -= weightJac*sourceMan[1]; + divFluxInt[2] -= weightJac*sourceMan[2]; + divFluxInt[3] -= weightJac*sourceMan[3]; + } + } + } + } + + /*--------------------------------------------------------------------------*/ + /*--- Compute the residual in the DOFs, which is the matrix product of ---*/ + /*--- basisFunctionsIntTrans and divFlux. ---*/ + /*--------------------------------------------------------------------------*/ + + blasFunctions->gemm(nDOFs, NPad, nInt, basisFunctionsIntTrans, divFlux, res, config); +} + +void CFEM_DG_NSSolver::ADER_DG_AliasedPredictorResidual_3D(CConfig *config, + CVolumeElementFEM *elem, + const su2double *sol, + const unsigned short nSimul, + const unsigned short NPad, + su2double *res, + su2double *work) { + /* Constant factor present in the heat flux vector. */ + const su2double factHeatFlux_Lam = Gamma/Prandtl_Lam; + const su2double factHeatFlux_Turb = Gamma/Prandtl_Turb; + + /*--- Get the necessary information from the standard element. ---*/ + const unsigned short ind = elem->indStandardElement; + const unsigned short nInt = standardElementsSol[ind].GetNIntegration(); + const unsigned short nDOFs = elem->nDOFsSol; + const su2double *matBasisInt = standardElementsSol[ind].GetMatBasisFunctionsIntegration(); + const su2double *matDerBasisInt = matBasisInt + nDOFs*nInt; + const su2double *matDerBasisSolDOFs = standardElementsSol[ind].GetMatDerBasisFunctionsSolDOFs(); + const su2double *basisFunctionsIntTrans = standardElementsSol[ind].GetBasisFunctionsIntegrationTrans(); + const su2double *weights = standardElementsSol[ind].GetWeightsIntegration(); + + unsigned short nPoly = standardElementsSol[ind].GetNPoly(); + if(nPoly == 0) nPoly = 1; + + /* Compute the length scale of the current element for the LES. */ + const su2double lenScale = elem->lenScale/nPoly; + + /* Set the pointers for fluxes in the DOFs, the gradient of the fluxes in + the integration points, the gradient of the solution in the DOFs and the + divergence of the fluxes in the integration points. Note that some pointers + point to the same physical location. This is because this memory can be + used for different purposes. */ + su2double *fluxXDOF = work; + su2double *fluxYDOF = fluxXDOF + NPad*nDOFs; + su2double *fluxZDOF = fluxYDOF + NPad*nDOFs; + su2double *gradFluxXInt = fluxZDOF + NPad*nDOFs; + su2double *gradFluxYInt = gradFluxXInt + nDim*NPad*nInt; + su2double *gradFluxZInt = gradFluxYInt + nDim*NPad*nInt; + su2double *gradSolDOFs = gradFluxXInt; + su2double *divFlux = work; + + /* Determine the offset between the r-derivatives and s-derivatives of the + fluxes in the integration points and the offset between the r-derivatives + and s-derivatives of the solution in the DOFs. */ + const unsigned short offDerivSol = NPad*nDOFs; + const unsigned short offDerivFluxes = NPad*nInt; + + /* Store the number of metric points per integration point/DOF for readability. */ + const unsigned short nMetricPerPoint = 10; /* nDim*nDim + 1. */ + + /*--------------------------------------------------------------------------*/ + /*--- Construct the Cartesian fluxes in the DOFs. ---*/ + /*--------------------------------------------------------------------------*/ + + /* Compute the derivatives of the solution variables w.r.t. the parametric + coordinates in the DOFs. */ + blasFunctions->gemm(nDOFs*nDim, NPad, nDOFs, matDerBasisSolDOFs, sol, gradSolDOFs, config); + + /*--- Loop over the number of entities that are treated simultaneously. */ + for(unsigned short simul=0; simulgridVelocitiesSolDOFs.data() + 3*i; /* nDim*i. */ + + /* Compute the true value of the metric terms in this DOF. Note that in + metricTerms the metric terms scaled by the Jacobian are stored. THIS + IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, THE + DATA FOR THIS DOF FOR THE CURRENT TIME INTEGRATION POINT MUST BE TAKEN. */ + const su2double *metricTerms = elem->metricTermsSolDOFs.data() + + i*nMetricPerPoint; + const su2double JacInv = 1.0/metricTerms[0]; + + const su2double drdx = JacInv*metricTerms[1]; + const su2double drdy = JacInv*metricTerms[2]; + const su2double drdz = JacInv*metricTerms[3]; + + const su2double dsdx = JacInv*metricTerms[4]; + const su2double dsdy = JacInv*metricTerms[5]; + const su2double dsdz = JacInv*metricTerms[6]; + + const su2double dtdx = JacInv*metricTerms[7]; + const su2double dtdy = JacInv*metricTerms[8]; + const su2double dtdz = JacInv*metricTerms[9]; + + /* Compute the Cartesian gradients of the independent solution variables + from the gradients in parametric coordinates and the metric terms. */ + const su2double drhodx = solDOFDr[0]*drdx + solDOFDs[0]*dsdx + solDOFDt[0]*dtdx; + const su2double drudx = solDOFDr[1]*drdx + solDOFDs[1]*dsdx + solDOFDt[1]*dtdx; + const su2double drvdx = solDOFDr[2]*drdx + solDOFDs[2]*dsdx + solDOFDt[2]*dtdx; + const su2double drwdx = solDOFDr[3]*drdx + solDOFDs[3]*dsdx + solDOFDt[3]*dtdx; + const su2double drEdx = solDOFDr[4]*drdx + solDOFDs[4]*dsdx + solDOFDt[4]*dtdx; + + const su2double drhody = solDOFDr[0]*drdy + solDOFDs[0]*dsdy + solDOFDt[0]*dtdy; + const su2double drudy = solDOFDr[1]*drdy + solDOFDs[1]*dsdy + solDOFDt[1]*dtdy; + const su2double drvdy = solDOFDr[2]*drdy + solDOFDs[2]*dsdy + solDOFDt[2]*dtdy; + const su2double drwdy = solDOFDr[3]*drdy + solDOFDs[3]*dsdy + solDOFDt[3]*dtdy; + const su2double drEdy = solDOFDr[4]*drdy + solDOFDs[4]*dsdy + solDOFDt[4]*dtdy; + + const su2double drhodz = solDOFDr[0]*drdz + solDOFDs[0]*dsdz + solDOFDt[0]*dtdz; + const su2double drudz = solDOFDr[1]*drdz + solDOFDs[1]*dsdz + solDOFDt[1]*dtdz; + const su2double drvdz = solDOFDr[2]*drdz + solDOFDs[2]*dsdz + solDOFDt[2]*dtdz; + const su2double drwdz = solDOFDr[3]*drdz + solDOFDs[3]*dsdz + solDOFDt[3]*dtdz; + const su2double drEdz = solDOFDr[4]*drdz + solDOFDs[4]*dsdz + solDOFDt[4]*dtdz; + + /* Compute the velocities, pressure and laminar viscosity in this DOF. */ + const su2double DensityInv = 1.0/solDOF[0]; + const su2double u = DensityInv*solDOF[1]; + const su2double v = DensityInv*solDOF[2]; + const su2double w = DensityInv*solDOF[3]; + const su2double TotalEnergy = DensityInv*solDOF[4]; + const su2double StaticEnergy = TotalEnergy - 0.5*(u*u + v*v + w*w); + + FluidModel->SetTDState_rhoe(solDOF[0], StaticEnergy); + const su2double Pressure = FluidModel->GetPressure(); + const su2double ViscosityLam = FluidModel->GetLaminarViscosity(); + + /* Compute the Cartesian gradients of the velocities and static energy. */ + const su2double dudx = DensityInv*(drudx - u*drhodx); + const su2double dudy = DensityInv*(drudy - u*drhody); + const su2double dudz = DensityInv*(drudz - u*drhodz); + + const su2double dvdx = DensityInv*(drvdx - v*drhodx); + const su2double dvdy = DensityInv*(drvdy - v*drhody); + const su2double dvdz = DensityInv*(drvdz - v*drhodz); + + const su2double dwdx = DensityInv*(drwdx - w*drhodx); + const su2double dwdy = DensityInv*(drwdy - w*drhody); + const su2double dwdz = DensityInv*(drwdz - w*drhodz); + + const su2double dedx = DensityInv*(drEdx - TotalEnergy*drhodx) - u*dudx - v*dvdx - w*dwdx; + const su2double dedy = DensityInv*(drEdy - TotalEnergy*drhody) - u*dudy - v*dvdy - w*dwdy; + const su2double dedz = DensityInv*(drEdz - TotalEnergy*drhodz) - u*dudz - v*dvdz - w*dwdz; + + /* Compute the eddy viscosity, if needed, and the total viscosity. */ + su2double ViscosityTurb = 0.0; + if( SGSModelUsed ) + ViscosityTurb = SGSModel->ComputeEddyViscosity_3D(solDOF[0], dudx, dudy, dudz, + dvdx, dvdy, dvdz, dwdx, + dwdy, dwdz, lenScale, + elem->wallDistanceSolDOFs[i]); + const su2double Viscosity = ViscosityLam + ViscosityTurb; + + /* Compute the total thermal conductivity divided by Cv. */ + const su2double kOverCv = ViscosityLam *factHeatFlux_Lam + + ViscosityTurb*factHeatFlux_Turb; + + /* Set the value of the second viscosity and compute the divergence + term in the viscous normal stresses. */ + const su2double lambda = -TWO3*Viscosity; + const su2double lamDivTerm = lambda*(dudx + dvdy + dwdz); + + /* Compute the viscous stress tensor. */ + const su2double tauxx = 2.0*Viscosity*dudx + lamDivTerm; + const su2double tauyy = 2.0*Viscosity*dvdy + lamDivTerm; + const su2double tauzz = 2.0*Viscosity*dwdz + lamDivTerm; + + const su2double tauxy = Viscosity*(dudy + dvdx); + const su2double tauxz = Viscosity*(dudz + dwdx); + const su2double tauyz = Viscosity*(dvdz + dwdy); + + /* The Cartesian fluxes in the x-direction. */ + const su2double uRel = u - gridVel[0]; + fluxX[0] = solDOF[0]*uRel; + fluxX[1] = solDOF[1]*uRel + Pressure - tauxx; + fluxX[2] = solDOF[2]*uRel - tauxy; + fluxX[3] = solDOF[3]*uRel - tauxz; + fluxX[4] = solDOF[4]*uRel + Pressure*u - kOverCv*dedx - u*tauxx - v*tauxy - w*tauxz; + + /* The Cartesian fluxes in the y-direction. */ + const su2double vRel = v - gridVel[1]; + fluxY[0] = solDOF[0]*vRel; + fluxY[1] = solDOF[1]*vRel - tauxy; + fluxY[2] = solDOF[2]*vRel + Pressure - tauyy; + fluxY[3] = solDOF[3]*vRel - tauyz; + fluxY[4] = solDOF[4]*vRel + Pressure*v - kOverCv*dedy - u*tauxy - v*tauyy - w*tauyz; + + /* The Cartesian fluxes in the z-direction. */ + const su2double wRel = w - gridVel[2]; + fluxZ[0] = solDOF[0]*wRel; + fluxZ[1] = solDOF[1]*wRel - tauxz; + fluxZ[2] = solDOF[2]*wRel - tauyz; + fluxZ[3] = solDOF[3]*wRel + Pressure - tauzz; + fluxZ[4] = solDOF[4]*wRel + Pressure*w - kOverCv*dedz - u*tauxz - v*tauyz - w*tauzz; + } + } + + /*--------------------------------------------------------------------------*/ + /*--- Compute the derivatives of the Cartesian fluxes w.r.t. the ---*/ + /*--- parametric coordinates in the integration points. ---*/ + /*--------------------------------------------------------------------------*/ + + blasFunctions->gemm(nInt*nDim, NPad, nDOFs, matDerBasisInt, fluxXDOF, gradFluxXInt, config); + blasFunctions->gemm(nInt*nDim, NPad, nDOFs, matDerBasisInt, fluxYDOF, gradFluxYInt, config); + blasFunctions->gemm(nInt*nDim, NPad, nDOFs, matDerBasisInt, fluxZDOF, gradFluxZInt, config); + + /*--------------------------------------------------------------------------*/ + /*--- Compute the divergence of the fluxes in the integration points, ---*/ + /*--- multiplied by the integration weight. ---*/ + /*--------------------------------------------------------------------------*/ + + /*--- Loop over the number of entities that are treated simultaneously. */ + for(unsigned short simul=0; simulmetricTerms.data() + i*nMetricPerPoint; + + /* Compute the metric terms multiplied by the integration weight. Note that the + first term in the metric terms is the Jacobian. */ + const su2double wDrdx = weights[i]*metricTerms[1]; + const su2double wDrdy = weights[i]*metricTerms[2]; + const su2double wDrdz = weights[i]*metricTerms[3]; + + const su2double wDsdx = weights[i]*metricTerms[4]; + const su2double wDsdy = weights[i]*metricTerms[5]; + const su2double wDsdz = weights[i]*metricTerms[6]; + + const su2double wDtdx = weights[i]*metricTerms[7]; + const su2double wDtdy = weights[i]*metricTerms[8]; + const su2double wDtdz = weights[i]*metricTerms[9]; + + /* Compute the divergence of the fluxes, multiplied by the integration weight. */ + divFluxInt[0] = gradFluxXDr[0]*wDrdx + gradFluxXDs[0]*wDsdx + gradFluxXDt[0]*wDtdx + + gradFluxYDr[0]*wDrdy + gradFluxYDs[0]*wDsdy + gradFluxYDt[0]*wDtdy + + gradFluxZDr[0]*wDrdz + gradFluxZDs[0]*wDsdz + gradFluxZDt[0]*wDtdz; + divFluxInt[1] = gradFluxXDr[1]*wDrdx + gradFluxXDs[1]*wDsdx + gradFluxXDt[1]*wDtdx + + gradFluxYDr[1]*wDrdy + gradFluxYDs[1]*wDsdy + gradFluxYDt[1]*wDtdy + + gradFluxZDr[1]*wDrdz + gradFluxZDs[1]*wDsdz + gradFluxZDt[1]*wDtdz; + divFluxInt[2] = gradFluxXDr[2]*wDrdx + gradFluxXDs[2]*wDsdx + gradFluxXDt[2]*wDtdx + + gradFluxYDr[2]*wDrdy + gradFluxYDs[2]*wDsdy + gradFluxYDt[2]*wDtdy + + gradFluxZDr[2]*wDrdz + gradFluxZDs[2]*wDsdz + gradFluxZDt[2]*wDtdz; + divFluxInt[3] = gradFluxXDr[3]*wDrdx + gradFluxXDs[3]*wDsdx + gradFluxXDt[3]*wDtdx + + gradFluxYDr[3]*wDrdy + gradFluxYDs[3]*wDsdy + gradFluxYDt[3]*wDtdy + + gradFluxZDr[3]*wDrdz + gradFluxZDs[3]*wDsdz + gradFluxZDt[3]*wDtdz; + divFluxInt[4] = gradFluxXDr[4]*wDrdx + gradFluxXDs[4]*wDsdx + gradFluxXDt[4]*wDtdx + + gradFluxYDr[4]*wDrdy + gradFluxYDs[4]*wDsdy + gradFluxYDt[4]*wDtdy + + gradFluxZDr[4]*wDrdz + gradFluxZDs[4]*wDsdz + gradFluxZDt[4]*wDtdz; + } + } + + /*--------------------------------------------------------------------------*/ + /*--- Add the body force to the divergence of the fluxes, if such a ---*/ + /*--- force is present. ---*/ + /*--------------------------------------------------------------------------*/ + + if( config->GetBody_Force() ) { + + /* Easier storage of the body force. */ + const su2double *body_force_vector = config->GetBody_Force_Vector(); + + /* Compute the solution in the integration points of the element. + Use gradFluxYInt to store this solution. */ + su2double *solInt = gradFluxYInt; + + blasFunctions->gemm(nInt, NPad, nDOFs, matBasisInt, sol, solInt, config); + + /*--- Loop over the number of entities that are treated simultaneously. */ + for(unsigned short simul=0; simulmetricTerms.data() + i*nMetricPerPoint; + + /* Compute the velocities. */ + const su2double rhoInv = 1.0/solThisInt[0]; + const su2double u = solThisInt[1]*rhoInv; + const su2double v = solThisInt[2]*rhoInv; + const su2double w = solThisInt[3]*rhoInv; + + /* Add the body force to the flux divergence for the momentum and energy + equation. Note that the source terms are multiplied with minus the + integration weight in order to be consistent with the formulation of + the residual. Also note that for the energy source term the absolute + velocity must be taken and not the relative. */ + const su2double weightJac = weights[i]*metricTerms[0]; + + divFluxInt[1] -= weightJac*body_force_vector[0]; + divFluxInt[2] -= weightJac*body_force_vector[1]; + divFluxInt[3] -= weightJac*body_force_vector[2]; + divFluxInt[4] -= weightJac*(u*body_force_vector[0] + v*body_force_vector[1] + + w*body_force_vector[2]); + } + } + } + + /*--------------------------------------------------------------------------*/ + /*--- Add the source terms of the manufactured solution to the divergence---*/ + /*--- of the fluxes, if a manufactured solution is used. ---*/ + /*--------------------------------------------------------------------------*/ + + if( VerificationSolution ) { + if( VerificationSolution->IsManufacturedSolution() ) { + + /*--- Loop over the number of entities that are treated simultaneously. */ + for(unsigned short simul=0; simulcoorIntegrationPoints.data() + i*nDim; + + /* Easier storage of the metric terms in this integration point. + THIS IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, + THE DATA FOR THIS DOF FOR THE CURRENT TIME INTEGRATION POINT MUST + BE TAKEN. */ + const su2double *metricTerms = elem->metricTerms.data() + i*nMetricPerPoint; + const su2double weightJac = weights[i]*metricTerms[0]; + + /* Compute the source terms of the manufactured solution. + THIS IS A TEMPORARY IMPLEMENTATION. FOR AN ACTUAL TIME ACCURATE + SIMULATION THE CORRECT TIME MUST BE GIVEN TO THIS FUNCTION. */ + su2double sourceMan[5]; + VerificationSolution->GetMMSSourceTerm(coor, 0.0, sourceMan); + + /* Add the source terms to the flux divergence. Note that the source + terms are multiplied with minus the integration weight in order + to be consistent with the formulation of the residual. */ + divFluxInt[0] -= weightJac*sourceMan[0]; + divFluxInt[1] -= weightJac*sourceMan[1]; + divFluxInt[2] -= weightJac*sourceMan[2]; + divFluxInt[3] -= weightJac*sourceMan[3]; + divFluxInt[4] -= weightJac*sourceMan[4]; + } + } + } + } + + /*--------------------------------------------------------------------------*/ + /*--- Compute the residual in the DOFs, which is the matrix product of ---*/ + /*--- basisFunctionsIntTrans and divFlux. ---*/ + /*--------------------------------------------------------------------------*/ + + blasFunctions->gemm(nDOFs, NPad, nInt, basisFunctionsIntTrans, divFlux, res, config); +} + +void CFEM_DG_NSSolver::ADER_DG_NonAliasedPredictorResidual_2D(CConfig *config, + CVolumeElementFEM *elem, + const su2double *sol, + const unsigned short nSimul, + const unsigned short NPad, + su2double *res, + su2double *work) { + + /* Constant factor present in the heat flux vector, the inverse of + the specific heat at constant volume and ratio lambdaOverMu. */ + const su2double factHeatFlux_Lam = Gamma/Prandtl_Lam; + const su2double factHeatFlux_Turb = Gamma/Prandtl_Turb; + const su2double Gas_Constant = config->GetGas_ConstantND(); + const su2double CvInv = Gamma_Minus_One/Gas_Constant; + const su2double lambdaOverMu = -TWO3; + + /*--- Get the necessary information from the standard element. ---*/ + const unsigned short ind = elem->indStandardElement; + const unsigned short nInt = standardElementsSol[ind].GetNIntegration(); + const unsigned short nDOFs = elem->nDOFsSol; + const su2double *matBasisInt = standardElementsSol[ind].GetMatBasisFunctionsIntegration(); + const su2double *mat2ndDerBasisInt = standardElementsSol[ind].GetMat2ndDerBasisFunctionsInt(); + const su2double *basisFunctionsIntTrans = standardElementsSol[ind].GetBasisFunctionsIntegrationTrans(); + const su2double *weights = standardElementsSol[ind].GetWeightsIntegration(); + + unsigned short nPoly = standardElementsSol[ind].GetNPoly(); + if(nPoly == 0) nPoly = 1; + + /* Check if a body force is present and set it accordingly. */ + su2double bodyForceX = 0.0, bodyForceY = 0.0; + if( config->GetBody_Force() ) { + const su2double *body_force_vector = config->GetBody_Force_Vector(); + bodyForceX = body_force_vector[0]; + bodyForceY = body_force_vector[1]; + } + + /* Compute the length scale of the current element for the LES. */ + const su2double lenScale = elem->lenScale/nPoly; + + /* Set the pointers for solAndGradInt and divFlux to work. The same array + can be used for both help arrays. */ + su2double *solAndGradInt = work; + su2double *divFlux = work; + + /* Determine the offset between the solution variables and the r-derivatives, + which is also the offset between the r- and s-derivatives in the + integration points. */ + const unsigned short offDerivInt = NPad*nInt; + + /* Set the pointer for the second derivatives such that they are stored + after the first derivatives. */ + su2double *secDerSol = solAndGradInt + 3*NPad*nInt; /*(nDim+1)*NPad*nInt. */ + + /* Store the number of metric points per integration point for readability. */ + const unsigned short nMetricPerPoint = 5; /* nDim*nDim + 1. */ + + /* Store the number of additional metric points per integration point, which + are needed to compute the second derivatives. These terms take the + non-constant metric into account. */ + const unsigned short nMetric2ndDerPerPoint = 6; /*nDim*(nDim + nDim*(nDim-1)/2). */ + + /*--------------------------------------------------------------------------*/ + /*--- Interpolate the solution variables to the integration points and ---*/ + /*--- also determine the first and second derivatives of these variables ---*/ + /*--- in the integration points. All derivatives are w.r.t. the ---*/ + /*--- parametric coordinates. ---*/ + /*--------------------------------------------------------------------------*/ + + /* Compute the solution and the derivatives w.r.t. the parametric coordinates + in the integration points. The first argument is nInt*(nDim+1). */ + blasFunctions->gemm(nInt*3, NPad, nDOFs, matBasisInt, sol, solAndGradInt, config); + + /* Compute the second derivatives w.r.t. the parametric coordinates + in the integration points. */ + blasFunctions->gemm(nInt*3, NPad, nDOFs, mat2ndDerBasisInt, sol, secDerSol, config); + + /*--------------------------------------------------------------------------*/ + /*--- Compute the divergence of viscous fluxes, multiplied by the ---*/ + /*--- integration weight in the integration points of the element. ---*/ + /*--------------------------------------------------------------------------*/ + + /*--- Loop over the number of entities that are treated simultaneously. */ + for(unsigned short simul=0; simulSetTDState_rhoe(rho, StaticEnergy); + const su2double Pressure = FluidModel->GetPressure(); + const su2double Htot = rhoInv*(rE + Pressure); + + /* Compute the laminar viscosity and its derivative w.r.t. temperature. */ + const su2double ViscosityLam = FluidModel->GetLaminarViscosity(); + const su2double dViscLamdT = FluidModel->GetdmudT_rho(); + + /* Set the pointer to the grid velocities in this integration point. + THIS IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, + THE DATA FOR THIS SPATIAL INTEGRATION POINT FOR THE CURRENT TIME + INTEGRATION POINT MUST BE TAKEN. */ + const su2double *gridVel = elem->gridVelocities.data() + 2*i; /* nDim*i. */ + + /* Easier storage of the metric terms in this integration point. + THIS IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, + THE DATA FOR THIS SPATIAL INTEGRATION POINT FOR THE CURRENT TIME + INTEGRATION POINT MUST BE TAKEN. */ + const su2double *metricTerms = elem->metricTerms.data() + i*nMetricPerPoint; + + /* Compute the true metric terms. Note in metricTerms the actual metric + terms multiplied by the Jacobian are stored. */ + const su2double Jac = metricTerms[0]; + const su2double JacInv = 1.0/Jac; + + const su2double drdx = JacInv*metricTerms[1]; + const su2double drdy = JacInv*metricTerms[2]; + const su2double dsdx = JacInv*metricTerms[3]; + const su2double dsdy = JacInv*metricTerms[4]; + + /* Compute the Cartesian gradients of the independent solution + variables from the gradients in parametric coordinates and the + metric terms in this integration point. */ + const su2double drhodx = solDr[0]*drdx + solDs[0]*dsdx; + const su2double drudx = solDr[1]*drdx + solDs[1]*dsdx; + const su2double drvdx = solDr[2]*drdx + solDs[2]*dsdx; + const su2double drEdx = solDr[3]*drdx + solDs[3]*dsdx; + + const su2double drhody = solDr[0]*drdy + solDs[0]*dsdy; + const su2double drudy = solDr[1]*drdy + solDs[1]*dsdy; + const su2double drvdy = solDr[2]*drdy + solDs[2]*dsdy; + const su2double drEdy = solDr[3]*drdy + solDs[3]*dsdy; + + /* Pointer to the necessary additional metric terms needed to compute + the Cartesian second derivatives for this integration point. + HIS IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, + THE DATA FOR THIS SPATIAL INTEGRATION POINT FOR THE CURRENT TIME + INTEGRATION POINT MUST BE TAKEN. */ + const su2double *metricTerms2ndDer = elem->metricTerms2ndDer.data() + + i*nMetric2ndDerPerPoint; + + /* Compute the Cartesian second derivatives of the independent solution + variables from the gradients and second derivatives in parametric + coordinates and the metric terms and its derivatives w.r.t. the + parametric coordinates. */ + const su2double d2rhodxdx = solDrDr[0]*drdx*drdx + solDsDs[0]*dsdx*dsdx + + 2.0*solDrDs[0]*drdx*dsdx + + solDr[0]*metricTerms2ndDer[0] + solDs[0]*metricTerms2ndDer[1]; + const su2double d2rudxdx = solDrDr[1]*drdx*drdx + solDsDs[1]*dsdx*dsdx + + 2.0*solDrDs[1]*drdx*dsdx + + solDr[1]*metricTerms2ndDer[0] + solDs[1]*metricTerms2ndDer[1]; + const su2double d2rvdxdx = solDrDr[2]*drdx*drdx + solDsDs[2]*dsdx*dsdx + + 2.0*solDrDs[2]*drdx*dsdx + + solDr[2]*metricTerms2ndDer[0] + solDs[2]*metricTerms2ndDer[1]; + const su2double d2rEdxdx = solDrDr[3]*drdx*drdx + solDsDs[3]*dsdx*dsdx + + 2.0*solDrDs[3]*drdx*dsdx + + solDr[3]*metricTerms2ndDer[0] + solDs[3]*metricTerms2ndDer[1]; + + const su2double d2rhodydy = solDrDr[0]*drdy*drdy + solDsDs[0]*dsdy*dsdy + + 2.0*solDrDs[0]*drdy*dsdy + + solDr[0]*metricTerms2ndDer[4] + solDs[0]*metricTerms2ndDer[5]; + const su2double d2rudydy = solDrDr[1]*drdy*drdy + solDsDs[1]*dsdy*dsdy + + 2.0*solDrDs[1]*drdy*dsdy + + solDr[1]*metricTerms2ndDer[4] + solDs[1]*metricTerms2ndDer[5]; + const su2double d2rvdydy = solDrDr[2]*drdy*drdy + solDsDs[2]*dsdy*dsdy + + 2.0*solDrDs[2]*drdy*dsdy + + solDr[2]*metricTerms2ndDer[4] + solDs[2]*metricTerms2ndDer[5]; + const su2double d2rEdydy = solDrDr[3]*drdy*drdy + solDsDs[3]*dsdy*dsdy + + 2.0*solDrDs[3]*drdy*dsdy + + solDr[3]*metricTerms2ndDer[4] + solDs[3]*metricTerms2ndDer[5]; + + const su2double d2rhodxdy = solDrDr[0]*drdx*drdy + solDsDs[0]*dsdx*dsdy + + solDrDs[0]*(drdx*dsdy + dsdx*drdy) + + solDr[0]*metricTerms2ndDer[2] + solDs[0]*metricTerms2ndDer[3]; + const su2double d2rudxdy = solDrDr[1]*drdx*drdy + solDsDs[1]*dsdx*dsdy + + solDrDs[1]*(drdx*dsdy + dsdx*drdy) + + solDr[1]*metricTerms2ndDer[2] + solDs[1]*metricTerms2ndDer[3]; + const su2double d2rvdxdy = solDrDr[2]*drdx*drdy + solDsDs[2]*dsdx*dsdy + + solDrDs[2]*(drdx*dsdy + dsdx*drdy) + + solDr[2]*metricTerms2ndDer[2] + solDs[2]*metricTerms2ndDer[3]; + + /* Compute the Cartesian gradients of the pressure, velocity components, + static energy and dynamic viscosity. */ + const su2double dpdx = Gamma_Minus_One*(drEdx + kinEnergy*drhodx + - u*drudx - v*drvdx); + const su2double dpdy = Gamma_Minus_One*(drEdy + kinEnergy*drhody + - u*drudy - v*drvdy); + + const su2double dudx = rhoInv*(drudx - u*drhodx); + const su2double dudy = rhoInv*(drudy - u*drhody); + const su2double dvdx = rhoInv*(drvdx - v*drhodx); + const su2double dvdy = rhoInv*(drvdy - v*drhody); + + const su2double dedx = rhoInv*(drEdx - TotalEnergy*drhodx) - u*dudx - v*dvdx; + const su2double dedy = rhoInv*(drEdy - TotalEnergy*drhody) - u*dudy - v*dvdy; + + const su2double dViscLamdx = CvInv*dedx*dViscLamdT; + const su2double dViscLamdy = CvInv*dedy*dViscLamdT; + + /* Compute the second derivatives of the velocity components. */ + const su2double d2udxdx = rhoInv*(d2rudxdx - u*d2rhodxdx + + 2.0*rhoInv*drhodx*(u*drhodx - drudx)); + const su2double d2udydy = rhoInv*(d2rudydy - u*d2rhodydy + + 2.0*rhoInv*drhody*(u*drhody - drudy)); + const su2double d2udxdy = rhoInv*(d2rudxdy - u*d2rhodxdy + + rhoInv*(drhodx*(u*drhody - drudy) + + drhody*(u*drhodx - drudx))); + + const su2double d2vdxdx = rhoInv*(d2rvdxdx - v*d2rhodxdx + + 2.0*rhoInv*drhodx*(v*drhodx - drvdx)); + const su2double d2vdydy = rhoInv*(d2rvdydy - v*d2rhodydy + + 2.0*rhoInv*drhody*(v*drhody - drvdy)); + const su2double d2vdxdy = rhoInv*(d2rvdxdy - v*d2rhodxdy + + rhoInv*(drhodx*(v*drhody - drvdy) + + drhody*(v*drhodx - drvdx))); + + /* Compute the second derivatives of the static energy. Note that this + term appears in the heat flux and therefore only the pure second + derivatives are needed. Hence, the cross-derivatives are omitted. */ + const su2double d2edxdx = rhoInv*(d2rEdxdx - TotalEnergy*d2rhodxdx + + 2.0*rhoInv*drhodx*(TotalEnergy*drhodx - drEdx)) + - u*d2udxdx - dudx*dudx - v*d2vdxdx - dvdx*dvdx; + const su2double d2edydy = rhoInv*(d2rEdydy - TotalEnergy*d2rhodydy + + 2.0*rhoInv*drhody*(TotalEnergy*drhody - drEdy)) + - u*d2udydy - dudy*dudy - v*d2vdydy - dvdy*dvdy; + + /* If an SGS model is used the eddy viscosity and its spatial + derivatives must be computed. */ + su2double ViscosityTurb = 0.0; + su2double dViscTurbdx = 0.0, dViscTurbdy = 0.0; + + if( SGSModelUsed ) { + const su2double dist = elem->wallDistance[i]; + ViscosityTurb = SGSModel->ComputeEddyViscosity_2D(rho, dudx, dudy, dvdx, + dvdy, lenScale, dist); + + SGSModel->ComputeGradEddyViscosity_2D(rho, drhodx, drhody, dudx, dudy, + dvdx, dvdy, d2udxdx, d2udydy, d2udxdy, + d2vdxdx, d2vdydy, d2vdxdy, lenScale, + dist, dViscTurbdx, dViscTurbdy); + } + + /* Compute the total viscosity, the total heat conductivity and their + gradients. Note that the heat conductivity is divided by the Cv, + because gradients of internal energy are computed and not temperature. */ + const su2double Viscosity = ViscosityLam + ViscosityTurb; + const su2double kOverCv = ViscosityLam *factHeatFlux_Lam + + ViscosityTurb*factHeatFlux_Turb; + + const su2double dViscDx = dViscLamdx + dViscTurbdx; + const su2double dViscDy = dViscLamdy + dViscTurbdy; + + const su2double dkOverCvdx = dViscLamdx *factHeatFlux_Lam + + dViscTurbdx*factHeatFlux_Turb; + const su2double dkOverCvdy = dViscLamdy *factHeatFlux_Lam + + dViscTurbdy*factHeatFlux_Turb; + + /* Abbreviations, which make it easier to compute the divergence term. */ + const su2double abv1 = drudx + drvdy; + const su2double abv2 = u*drhodx + v*drhody; + const su2double abv3 = u*(drEdx + dpdx) + v*(drEdy + dpdy); + const su2double abv4 = dudx + dvdy; + + /* Compute the divergence of the grid velocity. + SET TO ZERO FOR NOW. THIS IS NOT CORRECT!!!!. */ + const su2double divGridVel = 0.0; + + /* Set the pointer to store the divergence terms for this integration + point and compute these terms, multiplied by the integration weight + and Jacobian. */ + const su2double weightJac = weights[i]*Jac; + su2double *divFluxInt = divFlux + offInt; + + divFluxInt[0] = weightJac*(abv1 - rho*divGridVel + - gridVel[0]*drhodx - gridVel[1]*drhody); + divFluxInt[1] = weightJac*(dpdx + u*(abv1-abv2) - lambdaOverMu*abv4*dViscDx + + u*drudx + v*drudy + - lambdaOverMu*Viscosity*(d2udxdx + d2vdxdy) + - Viscosity*(2.0*d2udxdx + d2udydy + d2vdxdy) + - 2.0*dViscDx*dudx - dViscDy*(dudy+dvdx) + - ru*divGridVel + - gridVel[0]*drudx - gridVel[1]*drudy); + divFluxInt[2] = weightJac*(dpdy + v*(abv1-abv2) - lambdaOverMu*abv4*dViscDy + + u*drvdx + v*drvdy + - lambdaOverMu*Viscosity*(d2udxdy + d2vdydy) + - Viscosity*(2.0*d2vdydy + d2vdxdx + d2udxdy) + - dViscDx*(dudy + dvdx) - 2.0*dViscDy*dvdy + - rv*divGridVel + - gridVel[0]*drvdx - gridVel[1]*drvdy); + divFluxInt[3] = weightJac*(abv3 + Htot*(abv1 - abv2) + - abv4*lambdaOverMu*(Viscosity*abv4 + u*dViscDx + v*dViscDy) + - dkOverCvdx*dedx - dkOverCvdy*dedy - kOverCv*(d2edxdx + d2edydy) + - (Viscosity*dudx + u*dViscDx)*2.0*dudx + - (Viscosity*dvdy + v*dViscDy)*2.0*dvdy + - (Viscosity*dudy + u*dViscDy + Viscosity*dvdx + v*dViscDx)*(dudy + dvdx) + - Viscosity*u*(d2udxdx+d2udydy + (1.0+lambdaOverMu)*(d2udxdx+d2vdxdy)) + - Viscosity*v*(d2vdxdx+d2vdydy + (1.0+lambdaOverMu)*(d2udxdy+d2vdydy)) + - rE*divGridVel + - gridVel[0]*drEdx - gridVel[1]*drEdy); + + /* Add the body force to the flux divergence for the momentum and energy + equation. Note that the source terms are multiplied with minus the + integration weight in order to be consistent with the formulation of + the residual. Also note that for the energy source term the absolute + velocity must be taken and not the relative. */ + divFluxInt[1] -= weightJac*bodyForceX; + divFluxInt[2] -= weightJac*bodyForceY; + divFluxInt[3] -= weightJac*(u*bodyForceX + v*bodyForceY); + } + } + + /*--------------------------------------------------------------------------*/ + /*--- Add the source terms of the manufactured solution to the divergence---*/ + /*--- of the fluxes, if a manufactured solution is used. ---*/ + /*--------------------------------------------------------------------------*/ + + if( VerificationSolution ) { + if( VerificationSolution->IsManufacturedSolution() ) { + + /*--- Loop over the number of entities that are treated simultaneously. */ + for(unsigned short simul=0; simulcoorIntegrationPoints.data() + i*nDim; + + /* Easier storage of the metric terms in this integration point. + THIS IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, + THE DATA FOR THIS DOF FOR THE CURRENT TIME INTEGRATION POINT MUST + BE TAKEN. */ + const su2double *metricTerms = elem->metricTerms.data() + i*nMetricPerPoint; + const su2double weightJac = weights[i]*metricTerms[0]; + + /* Compute the source terms of the manufactured solution. + THIS IS A TEMPORARY IMPLEMENTATION. FOR AN ACTUAL TIME ACCURATE + SIMULATION THE CORRECT TIME MUST BE GIVEN TO THIS FUNCTION. */ + su2double sourceMan[4]; + VerificationSolution->GetMMSSourceTerm(coor, 0.0, sourceMan); + + /* Add the source terms to the flux divergence. Note that the source + terms are multiplied with minus the integration weight in order + to be consistent with the formulation of the residual. */ + divFluxInt[0] -= weightJac*sourceMan[0]; + divFluxInt[1] -= weightJac*sourceMan[1]; + divFluxInt[2] -= weightJac*sourceMan[2]; + divFluxInt[3] -= weightJac*sourceMan[3]; + } + } + } + } + + /*--------------------------------------------------------------------------*/ + /*--- Compute the residual in the DOFs, which is the matrix product of ---*/ + /*--- basisFunctionsIntTrans and divFlux. ---*/ + /*--------------------------------------------------------------------------*/ + + blasFunctions->gemm(nDOFs, NPad, nInt, basisFunctionsIntTrans, divFlux, res, config); +} + +void CFEM_DG_NSSolver::ADER_DG_NonAliasedPredictorResidual_3D(CConfig *config, + CVolumeElementFEM *elem, + const su2double *sol, + const unsigned short nSimul, + const unsigned short NPad, + su2double *res, + su2double *work) { + + /* Constant factor present in the heat flux vector, the inverse of + the specific heat at constant volume and ratio lambdaOverMu. */ + const su2double factHeatFlux_Lam = Gamma/Prandtl_Lam; + const su2double factHeatFlux_Turb = Gamma/Prandtl_Turb; + const su2double Gas_Constant = config->GetGas_ConstantND(); + const su2double CvInv = Gamma_Minus_One/Gas_Constant; + const su2double lambdaOverMu = -TWO3; + + /*--- Get the necessary information from the standard element. ---*/ + const unsigned short ind = elem->indStandardElement; + const unsigned short nInt = standardElementsSol[ind].GetNIntegration(); + const unsigned short nDOFs = elem->nDOFsSol; + const su2double *matBasisInt = standardElementsSol[ind].GetMatBasisFunctionsIntegration(); + const su2double *mat2ndDerBasisInt = standardElementsSol[ind].GetMat2ndDerBasisFunctionsInt(); + const su2double *basisFunctionsIntTrans = standardElementsSol[ind].GetBasisFunctionsIntegrationTrans(); + const su2double *weights = standardElementsSol[ind].GetWeightsIntegration(); + + unsigned short nPoly = standardElementsSol[ind].GetNPoly(); + if(nPoly == 0) nPoly = 1; + + /* Check if a body force is present and set it accordingly. */ + su2double bodyForceX = 0.0, bodyForceY = 0.0, bodyForceZ = 0.0; + if( config->GetBody_Force() ) { + const su2double *body_force_vector = config->GetBody_Force_Vector(); + bodyForceX = body_force_vector[0]; + bodyForceY = body_force_vector[1]; + bodyForceZ = body_force_vector[2]; + } + + /* Compute the length scale of the current element for the LES. */ + const su2double lenScale = elem->lenScale/nPoly; + + /* Set the pointers for solAndGradInt and divFlux to work. The same array + can be used for both help arrays. */ + su2double *solAndGradInt = work; + su2double *divFlux = work; + + /* Determine the offset between the solution variables and the r-derivatives, + which is also the offset between the r- and s-derivatives in the + integration points. */ + const unsigned short offDerivInt = NPad*nInt; + + /* Set the pointer for the second derivatives such that they are stored + after the first derivatives. */ + su2double *secDerSol = solAndGradInt + 4*NPad*nInt; /*(nDim+1)*NPad*nInt. */ + + /* Store the number of metric points per integration point for readability. */ + const unsigned short nMetricPerPoint = 10; /* nDim*nDim + 1. */ + + /* Store the number of additional metric points per integration point, which + are needed to compute the second derivatives. These terms take the + non-constant metric into account. */ + const unsigned short nMetric2ndDerPerPoint = 18; /*nDim*(nDim + nDim*(nDim-1)/2). */ + + /*--------------------------------------------------------------------------*/ + /*--- Interpolate the solution variables to the integration points and ---*/ + /*--- also determine the first and second derivatives of these variables ---*/ + /*--- in the integration points. All derivatives are w.r.t. the ---*/ + /*--- parametric coordinates. ---*/ + /*--------------------------------------------------------------------------*/ + + /* Compute the solution and the derivatives w.r.t. the parametric coordinates + in the integration points. The first argument is nInt*(nDim+1). */ + blasFunctions->gemm(nInt*4, NPad, nDOFs, matBasisInt, sol, solAndGradInt, config); + + /* Compute the second derivatives w.r.t. the parametric coordinates + in the integration points. */ + blasFunctions->gemm(nInt*6, NPad, nDOFs, mat2ndDerBasisInt, sol, secDerSol, config); + + /*--------------------------------------------------------------------------*/ + /*--- Compute the divergence of viscous fluxes, multiplied by the ---*/ + /*--- integration weight in the integration points of the element. ---*/ + /*--------------------------------------------------------------------------*/ + + /*--- Loop over the number of entities that are treated simultaneously. */ + for(unsigned short simul=0; simulSetTDState_rhoe(rho, StaticEnergy); + const su2double Pressure = FluidModel->GetPressure(); + const su2double Htot = rhoInv*(rE + Pressure); + + /* Compute the laminar viscosity and its derivative w.r.t. temperature. */ + const su2double ViscosityLam = FluidModel->GetLaminarViscosity(); + const su2double dViscLamdT = FluidModel->GetdmudT_rho(); + + /* Set the pointer to the grid velocities in this integration point. + THIS IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, + THE DATA FOR THIS SPATIAL INTEGRATION POINT FOR THE CURRENT TIME + INTEGRATION POINT MUST BE TAKEN. */ + const su2double *gridVel = elem->gridVelocities.data() + 3*i; /* nDim*i. */ + + /* Easier storage of the metric terms in this integration point. + THIS IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, + THE DATA FOR THIS SPATIAL INTEGRATION POINT FOR THE CURRENT TIME + INTEGRATION POINT MUST BE TAKEN. */ + const su2double *metricTerms = elem->metricTerms.data() + i*nMetricPerPoint; + + /* Compute the true metric terms. Note in metricTerms the actual metric + terms multiplied by the Jacobian are stored. */ + const su2double Jac = metricTerms[0]; + const su2double JacInv = 1.0/Jac; + + const su2double drdx = JacInv*metricTerms[1]; + const su2double drdy = JacInv*metricTerms[2]; + const su2double drdz = JacInv*metricTerms[3]; + + const su2double dsdx = JacInv*metricTerms[4]; + const su2double dsdy = JacInv*metricTerms[5]; + const su2double dsdz = JacInv*metricTerms[6]; + + const su2double dtdx = JacInv*metricTerms[7]; + const su2double dtdy = JacInv*metricTerms[8]; + const su2double dtdz = JacInv*metricTerms[9]; + + /* Compute the Cartesian gradients of the independent solution + variables from the gradients in parametric coordinates and the + metric terms in this integration point. */ + const su2double drhodx = solDr[0]*drdx + solDs[0]*dsdx + solDt[0]*dtdx; + const su2double drudx = solDr[1]*drdx + solDs[1]*dsdx + solDt[1]*dtdx; + const su2double drvdx = solDr[2]*drdx + solDs[2]*dsdx + solDt[2]*dtdx; + const su2double drwdx = solDr[3]*drdx + solDs[3]*dsdx + solDt[3]*dtdx; + const su2double drEdx = solDr[4]*drdx + solDs[4]*dsdx + solDt[4]*dtdx; + + const su2double drhody = solDr[0]*drdy + solDs[0]*dsdy + solDt[0]*dtdy; + const su2double drudy = solDr[1]*drdy + solDs[1]*dsdy + solDt[1]*dtdy; + const su2double drvdy = solDr[2]*drdy + solDs[2]*dsdy + solDt[2]*dtdy; + const su2double drwdy = solDr[3]*drdy + solDs[3]*dsdy + solDt[3]*dtdy; + const su2double drEdy = solDr[4]*drdy + solDs[4]*dsdy + solDt[4]*dtdy; + + const su2double drhodz = solDr[0]*drdz + solDs[0]*dsdz + solDt[0]*dtdz; + const su2double drudz = solDr[1]*drdz + solDs[1]*dsdz + solDt[1]*dtdz; + const su2double drvdz = solDr[2]*drdz + solDs[2]*dsdz + solDt[2]*dtdz; + const su2double drwdz = solDr[3]*drdz + solDs[3]*dsdz + solDt[3]*dtdz; + const su2double drEdz = solDr[4]*drdz + solDs[4]*dsdz + solDt[4]*dtdz; + + /* Pointer to the necessary additional metric terms needed to compute + the Cartesian second derivatives for this integration point. + HIS IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, + THE DATA FOR THIS SPATIAL INTEGRATION POINT FOR THE CURRENT TIME + INTEGRATION POINT MUST BE TAKEN. */ + const su2double *metricTerms2ndDer = elem->metricTerms2ndDer.data() + + i*nMetric2ndDerPerPoint; + + /* Compute the Cartesian second derivatives of the independent solution + variables from the gradients and second derivatives in parametric + coordinates and the metric terms and its derivatives w.r.t. the + parametric coordinates. */ + const su2double d2rhodxdx = solDrDr[0]*drdx*drdx + solDsDs[0]*dsdx*dsdx + solDtDt[0]*dtdx*dtdx + + 2.0*(solDrDs[0]*drdx*dsdx + solDrDt[0]*drdx*dtdx + solDsDt[0]*dsdx*dtdx) + + solDr[0]*metricTerms2ndDer[0] + solDs[0]*metricTerms2ndDer[1] + + solDt[0]*metricTerms2ndDer[2]; + const su2double d2rudxdx = solDrDr[1]*drdx*drdx + solDsDs[1]*dsdx*dsdx + solDtDt[1]*dtdx*dtdx + + 2.0*(solDrDs[1]*drdx*dsdx + solDrDt[1]*drdx*dtdx + solDsDt[1]*dsdx*dtdx) + + solDr[1]*metricTerms2ndDer[0] + solDs[1]*metricTerms2ndDer[1] + + solDt[1]*metricTerms2ndDer[2]; + const su2double d2rvdxdx = solDrDr[2]*drdx*drdx + solDsDs[2]*dsdx*dsdx + solDtDt[2]*dtdx*dtdx + + 2.0*(solDrDs[2]*drdx*dsdx + solDrDt[2]*drdx*dtdx + solDsDt[2]*dsdx*dtdx) + + solDr[2]*metricTerms2ndDer[0] + solDs[2]*metricTerms2ndDer[1] + + solDt[2]*metricTerms2ndDer[2]; + const su2double d2rwdxdx = solDrDr[3]*drdx*drdx + solDsDs[3]*dsdx*dsdx + solDtDt[3]*dtdx*dtdx + + 2.0*(solDrDs[3]*drdx*dsdx + solDrDt[3]*drdx*dtdx + solDsDt[3]*dsdx*dtdx) + + solDr[3]*metricTerms2ndDer[0] + solDs[3]*metricTerms2ndDer[1] + + solDt[3]*metricTerms2ndDer[2]; + const su2double d2rEdxdx = solDrDr[4]*drdx*drdx + solDsDs[4]*dsdx*dsdx + solDtDt[4]*dtdx*dtdx + + 2.0*(solDrDs[4]*drdx*dsdx + solDrDt[4]*drdx*dtdx + solDsDt[4]*dsdx*dtdx) + + solDr[4]*metricTerms2ndDer[0] + solDs[4]*metricTerms2ndDer[1] + + solDt[4]*metricTerms2ndDer[2]; + + const su2double d2rhodydy = solDrDr[0]*drdy*drdy + solDsDs[0]*dsdy*dsdy + solDtDt[0]*dtdy*dtdy + + 2.0*(solDrDs[0]*drdy*dsdy + solDrDt[0]*drdy*dtdy + solDsDt[0]*dsdy*dtdy) + + solDr[0]*metricTerms2ndDer[6] + solDs[0]*metricTerms2ndDer[7] + + solDt[0]*metricTerms2ndDer[8]; + const su2double d2rudydy = solDrDr[1]*drdy*drdy + solDsDs[1]*dsdy*dsdy + solDtDt[1]*dtdy*dtdy + + 2.0*(solDrDs[1]*drdy*dsdy + solDrDt[1]*drdy*dtdy + solDsDt[1]*dsdy*dtdy) + + solDr[1]*metricTerms2ndDer[6] + solDs[1]*metricTerms2ndDer[7] + + solDt[1]*metricTerms2ndDer[8]; + const su2double d2rvdydy = solDrDr[2]*drdy*drdy + solDsDs[2]*dsdy*dsdy + solDtDt[2]*dtdy*dtdy + + 2.0*(solDrDs[2]*drdy*dsdy + solDrDt[2]*drdy*dtdy + solDsDt[2]*dsdy*dtdy) + + solDr[2]*metricTerms2ndDer[6] + solDs[2]*metricTerms2ndDer[7] + + solDt[2]*metricTerms2ndDer[8]; + const su2double d2rwdydy = solDrDr[3]*drdy*drdy + solDsDs[3]*dsdy*dsdy + solDtDt[3]*dtdy*dtdy + + 2.0*(solDrDs[3]*drdy*dsdy + solDrDt[3]*drdy*dtdy + solDsDt[3]*dsdy*dtdy) + + solDr[3]*metricTerms2ndDer[6] + solDs[3]*metricTerms2ndDer[7] + + solDt[3]*metricTerms2ndDer[8]; + const su2double d2rEdydy = solDrDr[4]*drdy*drdy + solDsDs[4]*dsdy*dsdy + solDtDt[4]*dtdy*dtdy + + 2.0*(solDrDs[4]*drdy*dsdy + solDrDt[4]*drdy*dtdy + solDsDt[4]*dsdy*dtdy) + + solDr[4]*metricTerms2ndDer[6] + solDs[4]*metricTerms2ndDer[7] + + solDt[4]*metricTerms2ndDer[8]; + + const su2double d2rhodzdz = solDrDr[0]*drdz*drdz + solDsDs[0]*dsdz*dsdz + solDtDt[0]*dtdz*dtdz + + 2.0*(solDrDs[0]*drdz*dsdz + solDrDt[0]*drdz*dtdz + solDsDt[0]*dsdz*dtdz) + + solDr[0]*metricTerms2ndDer[15] + solDs[0]*metricTerms2ndDer[16] + + solDt[0]*metricTerms2ndDer[17]; + const su2double d2rudzdz = solDrDr[1]*drdz*drdz + solDsDs[1]*dsdz*dsdz + solDtDt[1]*dtdz*dtdz + + 2.0*(solDrDs[1]*drdz*dsdz + solDrDt[1]*drdz*dtdz + solDsDt[1]*dsdz*dtdz) + + solDr[1]*metricTerms2ndDer[15] + solDs[1]*metricTerms2ndDer[16] + + solDt[1]*metricTerms2ndDer[17]; + const su2double d2rvdzdz = solDrDr[2]*drdz*drdz + solDsDs[2]*dsdz*dsdz + solDtDt[2]*dtdz*dtdz + + 2.0*(solDrDs[2]*drdz*dsdz + solDrDt[2]*drdz*dtdz + solDsDt[2]*dsdz*dtdz) + + solDr[2]*metricTerms2ndDer[15] + solDs[2]*metricTerms2ndDer[16] + + solDt[2]*metricTerms2ndDer[17]; + const su2double d2rwdzdz = solDrDr[3]*drdz*drdz + solDsDs[3]*dsdz*dsdz + solDtDt[3]*dtdz*dtdz + + 2.0*(solDrDs[3]*drdz*dsdz + solDrDt[3]*drdz*dtdz + solDsDt[3]*dsdz*dtdz) + + solDr[3]*metricTerms2ndDer[15] + solDs[3]*metricTerms2ndDer[16] + + solDt[3]*metricTerms2ndDer[17]; + const su2double d2rEdzdz = solDrDr[4]*drdz*drdz + solDsDs[4]*dsdz*dsdz + solDtDt[4]*dtdz*dtdz + + 2.0*(solDrDs[4]*drdz*dsdz + solDrDt[4]*drdz*dtdz + solDsDt[4]*dsdz*dtdz) + + solDr[4]*metricTerms2ndDer[15] + solDs[4]*metricTerms2ndDer[16] + + solDt[4]*metricTerms2ndDer[17]; + + const su2double d2rhodxdy = solDrDr[0]*drdx*drdy + solDsDs[0]*dsdx*dsdy + solDtDt[0]*dtdx*dtdy + + solDrDs[0]*(drdx*dsdy + dsdx*drdy) + solDrDt[0]*(drdx*dtdy + dtdx*drdy) + + solDsDt[0]*(dsdx*dtdy + dtdx*dsdy) + solDr[0]*metricTerms2ndDer[3] + + solDs[0]*metricTerms2ndDer[4] + solDt[0]*metricTerms2ndDer[5]; + const su2double d2rudxdy = solDrDr[1]*drdx*drdy + solDsDs[1]*dsdx*dsdy + solDtDt[1]*dtdx*dtdy + + solDrDs[1]*(drdx*dsdy + dsdx*drdy) + solDrDt[1]*(drdx*dtdy + dtdx*drdy) + + solDsDt[1]*(dsdx*dtdy + dtdx*dsdy) + solDr[1]*metricTerms2ndDer[3] + + solDs[1]*metricTerms2ndDer[4] + solDt[1]*metricTerms2ndDer[5]; + const su2double d2rvdxdy = solDrDr[2]*drdx*drdy + solDsDs[2]*dsdx*dsdy + solDtDt[2]*dtdx*dtdy + + solDrDs[2]*(drdx*dsdy + dsdx*drdy) + solDrDt[2]*(drdx*dtdy + dtdx*drdy) + + solDsDt[2]*(dsdx*dtdy + dtdx*dsdy) + solDr[2]*metricTerms2ndDer[3] + + solDs[2]*metricTerms2ndDer[4] + solDt[2]*metricTerms2ndDer[5]; + const su2double d2rwdxdy = solDrDr[3]*drdx*drdy + solDsDs[3]*dsdx*dsdy + solDtDt[3]*dtdx*dtdy + + solDrDs[3]*(drdx*dsdy + dsdx*drdy) + solDrDt[3]*(drdx*dtdy + dtdx*drdy) + + solDsDt[3]*(dsdx*dtdy + dtdx*dsdy) + solDr[3]*metricTerms2ndDer[3] + + solDs[3]*metricTerms2ndDer[4] + solDt[3]*metricTerms2ndDer[5]; + + const su2double d2rhodxdz = solDrDr[0]*drdx*drdz + solDsDs[0]*dsdx*dsdz + solDtDt[0]*dtdx*dtdz + + solDrDs[0]*(drdx*dsdz + dsdx*drdz) + solDrDt[0]*(drdx*dtdz + dtdx*drdz) + + solDsDt[0]*(dsdx*dtdz + dtdx*dsdz) + solDr[0]*metricTerms2ndDer[9] + + solDs[0]*metricTerms2ndDer[10] + solDt[0]*metricTerms2ndDer[11]; + const su2double d2rudxdz = solDrDr[1]*drdx*drdz + solDsDs[1]*dsdx*dsdz + solDtDt[1]*dtdx*dtdz + + solDrDs[1]*(drdx*dsdz + dsdx*drdz) + solDrDt[1]*(drdx*dtdz + dtdx*drdz) + + solDsDt[1]*(dsdx*dtdz + dtdx*dsdz) + solDr[1]*metricTerms2ndDer[9] + + solDs[1]*metricTerms2ndDer[10] + solDt[1]*metricTerms2ndDer[11]; + const su2double d2rvdxdz = solDrDr[2]*drdx*drdz + solDsDs[2]*dsdx*dsdz + solDtDt[2]*dtdx*dtdz + + solDrDs[2]*(drdx*dsdz + dsdx*drdz) + solDrDt[2]*(drdx*dtdz + dtdx*drdz) + + solDsDt[2]*(dsdx*dtdz + dtdx*dsdz) + solDr[2]*metricTerms2ndDer[9] + + solDs[2]*metricTerms2ndDer[10] + solDt[2]*metricTerms2ndDer[11]; + const su2double d2rwdxdz = solDrDr[3]*drdx*drdz + solDsDs[3]*dsdx*dsdz + solDtDt[3]*dtdx*dtdz + + solDrDs[3]*(drdx*dsdz + dsdx*drdz) + solDrDt[3]*(drdx*dtdz + dtdx*drdz) + + solDsDt[3]*(dsdx*dtdz + dtdx*dsdz) + solDr[3]*metricTerms2ndDer[9] + + solDs[3]*metricTerms2ndDer[10] + solDt[3]*metricTerms2ndDer[11]; + + const su2double d2rhodydz = solDrDr[0]*drdy*drdz + solDsDs[0]*dsdy*dsdz + solDtDt[0]*dtdy*dtdz + + solDrDs[0]*(drdy*dsdz + dsdy*drdz) + solDrDt[0]*(drdy*dtdz + dtdy*drdz) + + solDsDt[0]*(dsdy*dtdz + dtdy*dsdz) + solDr[0]*metricTerms2ndDer[12] + + solDs[0]*metricTerms2ndDer[13] + solDt[0]*metricTerms2ndDer[14]; + const su2double d2rudydz = solDrDr[1]*drdy*drdz + solDsDs[1]*dsdy*dsdz + solDtDt[1]*dtdy*dtdz + + solDrDs[1]*(drdy*dsdz + dsdy*drdz) + solDrDt[1]*(drdy*dtdz + dtdy*drdz) + + solDsDt[1]*(dsdy*dtdz + dtdy*dsdz) + solDr[1]*metricTerms2ndDer[12] + + solDs[1]*metricTerms2ndDer[13] + solDt[1]*metricTerms2ndDer[14]; + const su2double d2rvdydz = solDrDr[2]*drdy*drdz + solDsDs[2]*dsdy*dsdz + solDtDt[2]*dtdy*dtdz + + solDrDs[2]*(drdy*dsdz + dsdy*drdz) + solDrDt[2]*(drdy*dtdz + dtdy*drdz) + + solDsDt[2]*(dsdy*dtdz + dtdy*dsdz) + solDr[2]*metricTerms2ndDer[12] + + solDs[2]*metricTerms2ndDer[13] + solDt[2]*metricTerms2ndDer[14]; + const su2double d2rwdydz = solDrDr[3]*drdy*drdz + solDsDs[3]*dsdy*dsdz + solDtDt[3]*dtdy*dtdz + + solDrDs[3]*(drdy*dsdz + dsdy*drdz) + solDrDt[3]*(drdy*dtdz + dtdy*drdz) + + solDsDt[3]*(dsdy*dtdz + dtdy*dsdz) + solDr[3]*metricTerms2ndDer[12] + + solDs[3]*metricTerms2ndDer[13] + solDt[3]*metricTerms2ndDer[14]; + + /* Compute the Cartesian gradients of the pressure, velocity components, + static energy and dynamic viscosity. */ + const su2double dpdx = Gamma_Minus_One*(drEdx + kinEnergy*drhodx + - u*drudx - v*drvdx - w*drwdx); + const su2double dpdy = Gamma_Minus_One*(drEdy + kinEnergy*drhody + - u*drudy - v*drvdy - w*drwdy); + const su2double dpdz = Gamma_Minus_One*(drEdz + kinEnergy*drhodz + - u*drudz - v*drvdz - w*drwdz); + + const su2double dudx = rhoInv*(drudx - u*drhodx); + const su2double dudy = rhoInv*(drudy - u*drhody); + const su2double dudz = rhoInv*(drudz - u*drhodz); + + const su2double dvdx = rhoInv*(drvdx - v*drhodx); + const su2double dvdy = rhoInv*(drvdy - v*drhody); + const su2double dvdz = rhoInv*(drvdz - v*drhodz); + + const su2double dwdx = rhoInv*(drwdx - w*drhodx); + const su2double dwdy = rhoInv*(drwdy - w*drhody); + const su2double dwdz = rhoInv*(drwdz - w*drhodz); + + const su2double dedx = rhoInv*(drEdx - TotalEnergy*drhodx) - u*dudx - v*dvdx - w*dwdx; + const su2double dedy = rhoInv*(drEdy - TotalEnergy*drhody) - u*dudy - v*dvdy - w*dwdy; + const su2double dedz = rhoInv*(drEdz - TotalEnergy*drhodz) - u*dudz - v*dvdz - w*dwdz; + + const su2double dViscLamdx = CvInv*dedx*dViscLamdT; + const su2double dViscLamdy = CvInv*dedy*dViscLamdT; + const su2double dViscLamdz = CvInv*dedz*dViscLamdT; + + /*--- Compute the second derivatives of the velocity components. ---*/ + const su2double d2udxdx = rhoInv*(d2rudxdx - u*d2rhodxdx + + 2.0*rhoInv*drhodx*(u*drhodx - drudx)); + const su2double d2udydy = rhoInv*(d2rudydy - u*d2rhodydy + + 2.0*rhoInv*drhody*(u*drhody - drudy)); + const su2double d2udzdz = rhoInv*(d2rudzdz - u*d2rhodzdz + + 2.0*rhoInv*drhodz*(u*drhodz - drudz)); + const su2double d2udxdy = rhoInv*(d2rudxdy - u*d2rhodxdy + + rhoInv*(drhodx*(u*drhody - drudy) + + drhody*(u*drhodx - drudx))); + const su2double d2udxdz = rhoInv*(d2rudxdz - u*d2rhodxdz + + rhoInv*(drhodx*(u*drhodz - drudz) + + drhodz*(u*drhodx - drudx))); + const su2double d2udydz = rhoInv*(d2rudydz - u*d2rhodydz + + rhoInv*(drhody*(u*drhodz - drudz) + + drhodz*(u*drhody - drudy))); + + const su2double d2vdxdx = rhoInv*(d2rvdxdx - v*d2rhodxdx + + 2.0*rhoInv*drhodx*(v*drhodx - drvdx)); + const su2double d2vdydy = rhoInv*(d2rvdydy - v*d2rhodydy + + 2.0*rhoInv*drhody*(v*drhody - drvdy)); + const su2double d2vdzdz = rhoInv*(d2rvdzdz - v*d2rhodzdz + + 2.0*rhoInv*drhodz*(v*drhodz - drvdz)); + const su2double d2vdxdy = rhoInv*(d2rvdxdy - v*d2rhodxdy + + rhoInv*(drhodx*(v*drhody - drvdy) + + drhody*(v*drhodx - drvdx))); + const su2double d2vdxdz = rhoInv*(d2rvdxdz - v*d2rhodxdz + + rhoInv*(drhodx*(v*drhodz - drvdz) + + drhodz*(v*drhodx - drvdx))); + const su2double d2vdydz = rhoInv*(d2rvdydz - v*d2rhodydz + + rhoInv*(drhody*(v*drhodz - drvdz) + + drhodz*(v*drhody - drvdy))); + + const su2double d2wdxdx = rhoInv*(d2rwdxdx - w*d2rhodxdx + + 2.0*rhoInv*drhodx*(w*drhodx - drwdx)); + const su2double d2wdydy = rhoInv*(d2rwdydy - w*d2rhodydy + + 2.0*rhoInv*drhody*(w*drhody - drwdy)); + const su2double d2wdzdz = rhoInv*(d2rwdzdz - w*d2rhodzdz + + 2.0*rhoInv*drhodz*(w*drhodz - drwdz)); + const su2double d2wdxdy = rhoInv*(d2rwdxdy - w*d2rhodxdy + + rhoInv*(drhodx*(w*drhody - drwdy) + + drhody*(w*drhodx - drwdx))); + const su2double d2wdxdz = rhoInv*(d2rwdxdz - w*d2rhodxdz + + rhoInv*(drhodx*(w*drhodz - drwdz) + + drhodz*(w*drhodx - drwdx))); + const su2double d2wdydz = rhoInv*(d2rwdydz - w*d2rhodydz + + rhoInv*(drhody*(w*drhodz - drwdz) + + drhodz*(w*drhody - drwdy))); + + /* Compute the second derivatives of the static energy. Note that this + term appears in the heat flux and therefore only the pure second + derivatives are needed. Hence, the cross-derivatives are omitted. */ + const su2double d2edxdx = rhoInv*(d2rEdxdx - TotalEnergy*d2rhodxdx + + 2.0*rhoInv*drhodx*(TotalEnergy*drhodx - drEdx)) + - u*d2udxdx - dudx*dudx - v*d2vdxdx - dvdx*dvdx + - w*d2wdxdx - dwdx*dwdx; + const su2double d2edydy = rhoInv*(d2rEdydy - TotalEnergy*d2rhodydy + + 2.0*rhoInv*drhody*(TotalEnergy*drhody - drEdy)) + - u*d2udydy - dudy*dudy - v*d2vdydy - dvdy*dvdy + - w*d2wdydy - dwdy*dwdy; + const su2double d2edzdz = rhoInv*(d2rEdzdz - TotalEnergy*d2rhodzdz + + 2.0*rhoInv*drhodz*(TotalEnergy*drhodz - drEdz)) + - u*d2udzdz - dudz*dudz - v*d2vdzdz - dvdz*dvdz + - w*d2wdzdz - dwdz*dwdz; + + /*--- If an SGS model is used the eddy viscosity and its spatial + derivatives must be computed. ---*/ + su2double ViscosityTurb = 0.0; + su2double dViscTurbdx = 0.0, dViscTurbdy = 0.0, dViscTurbdz = 0.0; + + if( SGSModelUsed ) { + const su2double dist = elem->wallDistance[i]; + ViscosityTurb = SGSModel->ComputeEddyViscosity_3D(rho, dudx, dudy, dudz, + dvdx, dvdy, dvdz, dwdx, + dwdy, dwdz, lenScale, dist); + + SGSModel->ComputeGradEddyViscosity_3D(rho, drhodx, drhody, drhodz, dudx, dudy, + dudz, dvdx, dvdy, dvdz, dwdx, dwdy, dwdz, + d2udxdx, d2udydy, d2udzdz, d2udxdy, + d2udxdz, d2udydz, d2vdxdx, d2vdydy, + d2vdzdz, d2vdxdy, d2vdxdz, d2vdydz, + d2wdxdx, d2wdydy, d2wdzdz, d2wdxdy, + d2wdxdz, d2wdydz, lenScale, dist, + dViscTurbdx, dViscTurbdy, dViscTurbdz); + } + + /*--- Compute the total viscosity, the total heat conductivity and their + gradients. Note that the heat conductivity is divided by the Cv, + because gradients of internal energy are computed and not temperature. ---*/ + const su2double Viscosity = ViscosityLam + ViscosityTurb; + const su2double kOverCv = ViscosityLam *factHeatFlux_Lam + + ViscosityTurb*factHeatFlux_Turb; + + const su2double dViscDx = dViscLamdx + dViscTurbdx; + const su2double dViscDy = dViscLamdy + dViscTurbdy; + const su2double dViscDz = dViscLamdz + dViscTurbdz; + + const su2double dkOverCvdx = dViscLamdx *factHeatFlux_Lam + + dViscTurbdx*factHeatFlux_Turb; + const su2double dkOverCvdy = dViscLamdy *factHeatFlux_Lam + + dViscTurbdy*factHeatFlux_Turb; + const su2double dkOverCvdz = dViscLamdz *factHeatFlux_Lam + + dViscTurbdz*factHeatFlux_Turb; + + /* Abbreviations, which make it easier to compute the divergence term. */ + const su2double abv1 = drudx + drvdy + drwdz; + const su2double abv2 = u*drhodx + v*drhody + w*drhodz; + const su2double abv3 = u*(drEdx + dpdx) + v*(drEdy + dpdy) + w*(drEdz + dpdz); + const su2double abv4 = dudx + dvdy + dwdz; + + /*--- Compute the divergence of the grid velocity. + SET TO ZERO FOR NOW. THIS IS NOT CORRECT!!!!. ---*/ + const su2double divGridVel = 0.0; + + /* Set the pointer to store the divergence terms for this integration + point and compute these terms, multiplied by the integration weight + and Jacobian. */ + const su2double weightJac = weights[i]*Jac; + su2double *divFluxInt = divFlux + offInt; + + divFluxInt[0] = weightJac*(abv1 - rho*divGridVel - gridVel[0]*drhodx + - gridVel[1]*drhody - gridVel[2]*drhodz); + divFluxInt[1] = weightJac*(dpdx + u*(abv1-abv2) - lambdaOverMu*abv4*dViscDx + + u*drudx + v*drudy + w*drudz + - lambdaOverMu*Viscosity*(d2udxdx + d2vdxdy + d2wdxdz) + - Viscosity*(2.0*d2udxdx + d2udydy + d2vdxdy + d2udzdz + d2wdxdz) + - 2.0*dViscDx*dudx - dViscDy*(dudy+dvdx) - dViscDz*(dudz+dwdx) + - ru*divGridVel + - gridVel[0]*drudx - gridVel[1]*drudy - gridVel[2]*drudz); + divFluxInt[2] = weightJac*(dpdy + v*(abv1-abv2) - lambdaOverMu*abv4*dViscDy + + u*drvdx + v*drvdy + w*drvdz + - lambdaOverMu*Viscosity*(d2udxdy + d2vdydy + d2wdydz) + - Viscosity*(d2udxdy + d2vdxdx + 2.0*d2vdydy + d2vdzdz + d2wdydz) + - dViscDx*(dudy + dvdx) - 2.0*dViscDy*dvdy - dViscDz*(dvdz+dwdy) + - rv*divGridVel + - gridVel[0]*drvdx - gridVel[1]*drvdy - gridVel[2]*drvdz); + divFluxInt[3] = weightJac*(dpdz + w*(abv1-abv2) - lambdaOverMu*abv4*dViscDz + + u*drwdx + v*drwdy + w*drwdz + - lambdaOverMu*Viscosity*(d2udxdz + d2vdydz + d2wdzdz) + - Viscosity*(d2udxdz + d2wdxdx + d2vdydz + d2wdydy + 2.0*d2wdzdz) + - dViscDx*(dudz+dwdx) - dViscDy*(dvdz+dwdy) - 2.0*dViscDz*dwdz + - rw*divGridVel + - gridVel[0]*drwdx - gridVel[1]*drwdy - gridVel[2]*drwdz); + divFluxInt[4] = weightJac*(abv3 + Htot*(abv1 - abv2) + - abv4*lambdaOverMu*(Viscosity*abv4 + u*dViscDx + v*dViscDy + w*dViscDz) + - dkOverCvdx*dedx - dkOverCvdy*dedy - dkOverCvdz*dedz + - kOverCv*(d2edxdx + d2edydy + d2edzdz) + - (Viscosity*dudx + u*dViscDx)*2.0*dudx + - (Viscosity*dvdy + v*dViscDy)*2.0*dvdy + - (Viscosity*dwdz + w*dViscDz)*2.0*dwdz + - (Viscosity*dudy + u*dViscDy + Viscosity*dvdx + v*dViscDx)*(dudy + dvdx) + - (Viscosity*dudz + u*dViscDz + Viscosity*dwdx + w*dViscDx)*(dudz + dwdx) + - (Viscosity*dvdz + v*dViscDz + Viscosity*dwdy + w*dViscDy)*(dvdz + dwdy) + - Viscosity*u*(d2udxdx+d2udydy+d2udzdz + (1.0+lambdaOverMu)*(d2udxdx+d2vdxdy+d2wdxdz)) + - Viscosity*v*(d2vdxdx+d2vdydy+d2vdzdz + (1.0+lambdaOverMu)*(d2udxdy+d2vdydy+d2wdydz)) + - Viscosity*w*(d2wdxdx+d2wdydy+d2wdzdz + (1.0+lambdaOverMu)*(d2udxdz+d2vdydz+d2wdzdz)) + - rE*divGridVel + - gridVel[0]*drEdx - gridVel[1]*drEdy - gridVel[2]*drEdz); + + /* Add the body force to the flux divergence for the momentum and energy + equation. Note that the source terms are multiplied with minus the + integration weight in order to be consistent with the formulation of + the residual. Also note that for the energy source term the absolute + velocity must be taken and not the relative. */ + divFluxInt[1] -= weightJac*bodyForceX; + divFluxInt[2] -= weightJac*bodyForceY; + divFluxInt[3] -= weightJac*bodyForceZ; + divFluxInt[4] -= weightJac*(u*bodyForceX + v*bodyForceY + w*bodyForceZ); + } + } + + /*--------------------------------------------------------------------------*/ + /*--- Add the source terms of the manufactured solution to the divergence---*/ + /*--- of the fluxes, if a manufactured solution is used. ---*/ + /*--------------------------------------------------------------------------*/ + + if( VerificationSolution ) { + if( VerificationSolution->IsManufacturedSolution() ) { + + /*--- Loop over the number of entities that are treated simultaneously. */ + for(unsigned short simul=0; simulcoorIntegrationPoints.data() + i*nDim; + + /* Easier storage of the metric terms in this integration point. + THIS IS A TEMPORARY IMPLEMENTATION. WHEN AN ACTUAL MOTION IS SPECIFIED, + THE DATA FOR THIS DOF FOR THE CURRENT TIME INTEGRATION POINT MUST + BE TAKEN. */ + const su2double *metricTerms = elem->metricTerms.data() + i*nMetricPerPoint; + const su2double weightJac = weights[i]*metricTerms[0]; + + /* Compute the source terms of the manufactured solution. + THIS IS A TEMPORARY IMPLEMENTATION. FOR AN ACTUAL TIME ACCURATE + SIMULATION THE CORRECT TIME MUST BE GIVEN TO THIS FUNCTION. */ + su2double sourceMan[5]; + VerificationSolution->GetMMSSourceTerm(coor, 0.0, sourceMan); + + /* Add the source terms to the flux divergence. Note that the source + terms are multiplied with minus the integration weight in order + to be consistent with the formulation of the residual. */ + divFluxInt[0] -= weightJac*sourceMan[0]; + divFluxInt[1] -= weightJac*sourceMan[1]; + divFluxInt[2] -= weightJac*sourceMan[2]; + divFluxInt[3] -= weightJac*sourceMan[3]; + divFluxInt[4] -= weightJac*sourceMan[4]; + } + } + } + } + + /*--------------------------------------------------------------------------*/ + /*--- Compute the residual in the DOFs, which is the matrix product of ---*/ + /*--- basisFunctionsIntTrans and divFlux. ---*/ + /*--------------------------------------------------------------------------*/ + + blasFunctions->gemm(nDOFs, NPad, nInt, basisFunctionsIntTrans, divFlux, res, config); +} + +void CFEM_DG_NSSolver::Shock_Capturing_DG(CConfig *config, + const unsigned long elemBeg, + const unsigned long elemEnd, + su2double *workArray) { + + /*--- Run shock capturing algorithm ---*/ + switch( config->GetKind_FEM_DG_Shock() ) { + case NONE: + break; + case PERSSON: + Shock_Capturing_DG_Persson(elemBeg, elemEnd, workArray); + break; + } + +} +void CFEM_DG_NSSolver::Shock_Capturing_DG_Persson(const unsigned long elemBeg, + const unsigned long elemEnd, + su2double *workArray) { + + /*--- Dummy variable for storing shock sensor value temporarily ---*/ + su2double sensorVal, sensorLowerBound, machNorm, machMax; + su2double DensityInv, Velocity2, StaticEnergy, SoundSpeed2, Velocity2Rel; + + bool shockExist; + unsigned short nDOFsPm1; // Number of DOFs up to polynomial degree p-1 + + /*--- Loop over the given range of elements to sense the shock. If shock exists, + add artificial viscosity for DG FEM formulation to the residual. ---*/ + for(unsigned long l=elemBeg; lSetTDState_rhoe(sol[0], StaticEnergy); + SoundSpeed2 = FluidModel->GetSoundSpeed2(); + machSolDOFs[iInd] = sqrt( Velocity2Rel/SoundSpeed2 ); + machMax = max(machSolDOFs[iInd],machMax); + } + + /* Change the solution coefficients to modal form from nodal form */ + for(unsigned short i=0; i 1.0) { + // !!!!!Threshold value for sensorVal should be further investigated + if(sensorVal > 1.e-15) { + machNorm = 0.0; + + /*--- Get L2 norm square of vecTemp ---*/ + for (unsigned short i=0; i sensorLowerBound ) { + // Following value is initial guess. + volElem[l].shockArtificialViscosity = 1.e-10; + } + else { + volElem[l].shockArtificialViscosity = 0.0; + } + } + else { + volElem[l].shockArtificialViscosity = 0.0; + } + } +} + +void CFEM_DG_NSSolver::Volume_Residual(CConfig *config, + const unsigned long elemBeg, + const unsigned long elemEnd, + su2double *workArray) { + + /*--- Determine whether a body force term is present. ---*/ + bool body_force = config->GetBody_Force(); + const su2double *body_force_vector = body_force ? config->GetBody_Force_Vector() : NULL; + + /*--- Get the physical time if necessary. ---*/ + su2double time = 0.0; + if (config->GetTime_Marching()) time = config->GetPhysicalTime(); + + /* Constant factor present in the heat flux vector. */ + const su2double factHeatFlux_Lam = Gamma/Prandtl_Lam; + const su2double factHeatFlux_Turb = Gamma/Prandtl_Turb; + + /* Determine the number of elements that are treated simultaneously + in the matrix products to obtain good gemm performance. */ + const unsigned short nPadInput = config->GetSizeMatMulPadding(); + const unsigned short nElemSimul = nPadInput/nVar; + + /* Determine the minimum padded size in the matrix multiplications, which + corresponds to 64 byte alignment. */ + const unsigned short nPadMin = 64/sizeof(passivedouble); + + /* Set the number of bytes that must be copied in the memcpy calls. */ + const unsigned long nBytes = nVar*sizeof(su2double); + + /* Store the number of metric points per integration point, which depends + on the number of dimensions. */ + const unsigned short nMetricPerPoint = nDim*nDim + 1; + + /*--- Loop over the given element range to compute the contribution of the + volume integral in the DG FEM formulation to the residual. Multiple + elements are treated simultaneously to improve the performance + of the matrix multiplications. As a consequence, the update of the + counter l happens at the end of this loop section. ---*/ + for(unsigned long l=elemBeg; lgemm(nInt*(nDim+1), NPad, nDOFs, matBasisInt, solDOFs, solAndGradInt, config); + + /*------------------------------------------------------------------------*/ + /*--- Step 2: Compute the total fluxes (inviscid fluxes minus the ---*/ + /*--- viscous fluxes), multiplied by minus the integration ---*/ + /*--- weight, in the integration points. ---*/ + /*------------------------------------------------------------------------*/ + + /* Determine the offset between the solution variables and the r-derivatives, + which is also the offset between the r- and s-derivatives and the offset + between s- and t-derivatives. */ + const unsigned short offDeriv = NPad*nInt; + + /* Make a distinction between two and three space dimensions + in order to have the most efficient code. */ + switch( nDim ) { + + case 2: { + + /* 2D simulation. Loop over the chunk of elements and loop over the + integration points of the elements to compute the fluxes. */ + for(unsigned short ll=0; llSetTDState_rhoe(sol[0], StaticEnergy); + const su2double Pressure = FluidModel->GetPressure(); + const su2double ViscosityLam = FluidModel->GetLaminarViscosity(); + + /*--- If an SGS model is used the eddy viscosity must be computed. ---*/ + su2double ViscosityTurb = 0.0; + if( SGSModelUsed ) { + const su2double lenScale = volElem[lInd].lenScale/nPoly; + ViscosityTurb = SGSModel->ComputeEddyViscosity_2D(sol[0], dudx, dudy, + dvdx, dvdy, lenScale, + volElem[lInd].wallDistance[i]); + } + + /* Compute the total viscosity and heat conductivity. Note that the heat + conductivity is divided by the Cv, because gradients of internal energy + are computed and not temperature. */ + const su2double Viscosity = ViscosityLam + ViscosityTurb; + const su2double kOverCv = ViscosityLam *factHeatFlux_Lam + + ViscosityTurb*factHeatFlux_Turb; + + /*--- Set the value of the second viscosity and compute the divergence + term in the viscous normal stresses. ---*/ + const su2double lambda = -TWO3*Viscosity; + const su2double lamDivTerm = lambda*divVel; + + /*--- Compute the viscous stress tensor and minus the heatflux vector. ---*/ + const su2double tauxx = 2.0*Viscosity*dudx + lamDivTerm; + const su2double tauyy = 2.0*Viscosity*dvdy + lamDivTerm; + const su2double tauxy = Viscosity*(dudy + dvdx); + + const su2double qx = kOverCv*dStaticEnergyDx; + const su2double qy = kOverCv*dStaticEnergyDy; + + /* Compute the relative velocities w.r.t. the grid. */ + const su2double uRel = u - gridVel[0]; + const su2double vRel = v - gridVel[1]; + + /* Compute the viscous normal stress minus the pressure. */ + const su2double tauxxMP = tauxx - Pressure; + const su2double tauyyMP = tauyy - Pressure; + + /* Set the pointer for the fluxes in this integration point. */ + su2double *flux = fluxes + nDim*iNPad + llNVar; + + /*--- Fluxes in r-direction. */ + const su2double Ur = uRel*wDrdx + vRel*wDrdy; + + flux[0] = sol[0]*Ur; + flux[1] = sol[1]*Ur - tauxxMP*wDrdx - tauxy*wDrdy; + flux[2] = sol[2]*Ur - tauxy*wDrdx - tauyyMP*wDrdy; + flux[3] = sol[3]*Ur - (u*tauxxMP + v*tauxy + qx)*wDrdx + - (u*tauxy + v*tauyyMP + qy)*wDrdy; + + /*--- Fluxes in s-direction. */ + flux = flux + NPad; + const su2double Us = uRel*wDsdx + vRel*wDsdy; + + flux[0] = sol[0]*Us; + flux[1] = sol[1]*Us - tauxxMP*wDsdx - tauxy*wDsdy; + flux[2] = sol[2]*Us - tauxy*wDsdx - tauyyMP*wDsdy; + flux[3] = sol[3]*Us - (u*tauxxMP + v*tauxy + qx)*wDsdx + - (u*tauxy + v*tauyyMP + qy)*wDsdy; + + /*--- If needed, compute the body forces in this integration point. + Note that the source terms are multiplied with minus the + integration weight in order to be consistent with the + formulation of the residual. Note that for the energy source + term the absolute velocity must be taken and not the + relative. ---*/ + if( body_force ) { + su2double *source = sources + iNPad + llNVar; + const su2double weightJac = weights[i]*Jac; + + source[0] = 0.0; + source[1] = -weightJac*body_force_vector[0]; + source[2] = -weightJac*body_force_vector[1]; + source[3] = -weightJac*(u*body_force_vector[0] + v*body_force_vector[1]); + } + } + } + + break; + } + + /*----------------------------------------------------------------------*/ + + case 3: { + + /* 3D simulation. Loop over the chunk of elements and loop over the + integration points of the elements to compute the fluxes. */ + for(unsigned short ll=0; llSetTDState_rhoe(sol[0], StaticEnergy); + const su2double Pressure = FluidModel->GetPressure(); + const su2double ViscosityLam = FluidModel->GetLaminarViscosity(); + + /*--- If an SGS model is used the eddy viscosity must be computed. ---*/ + su2double ViscosityTurb = 0.0; + if( SGSModelUsed ) { + const su2double lenScale = volElem[lInd].lenScale/nPoly; + ViscosityTurb = SGSModel->ComputeEddyViscosity_3D(sol[0], dudx, dudy, dudz, + dvdx, dvdy, dvdz, dwdx, + dwdy, dwdz, lenScale, + volElem[lInd].wallDistance[i]); + } + + /* Compute the total viscosity and heat conductivity. Note that the heat + conductivity is divided by the Cv, because gradients of internal energy + are computed and not temperature. */ + const su2double Viscosity = ViscosityLam + ViscosityTurb; + const su2double kOverCv = ViscosityLam *factHeatFlux_Lam + + ViscosityTurb*factHeatFlux_Turb; + + /*--- Set the value of the second viscosity and compute the divergence + term in the viscous normal stresses. ---*/ + const su2double lambda = -TWO3*Viscosity; + const su2double lamDivTerm = lambda*divVel; + + /*--- Compute the viscous stress tensor and minus the heatflux vector. ---*/ + const su2double tauxx = 2.0*Viscosity*dudx + lamDivTerm; + const su2double tauyy = 2.0*Viscosity*dvdy + lamDivTerm; + const su2double tauzz = 2.0*Viscosity*dwdz + lamDivTerm; + + const su2double tauxy = Viscosity*(dudy + dvdx); + const su2double tauxz = Viscosity*(dudz + dwdx); + const su2double tauyz = Viscosity*(dvdz + dwdy); + + const su2double qx = kOverCv*dStaticEnergyDx; + const su2double qy = kOverCv*dStaticEnergyDy; + const su2double qz = kOverCv*dStaticEnergyDz; + + /* Compute the relative velocities w.r.t. the grid. */ + const su2double uRel = u - gridVel[0]; + const su2double vRel = v - gridVel[1]; + const su2double wRel = w - gridVel[2]; + + /* Compute the viscous normal stress minus the pressure. */ + const su2double tauxxMP = tauxx - Pressure; + const su2double tauyyMP = tauyy - Pressure; + const su2double tauzzMP = tauzz - Pressure; + + /* Set the pointer for the fluxes in this integration point. */ + su2double *flux = fluxes + nDim*iNPad + llNVar; + + /*--- Fluxes in r-direction. */ + const su2double Ur = uRel*wDrdx + vRel*wDrdy + wRel*wDrdz; + + flux[0] = sol[0]*Ur; + flux[1] = sol[1]*Ur - tauxxMP*wDrdx - tauxy*wDrdy - tauxz*wDrdz; + flux[2] = sol[2]*Ur - tauxy*wDrdx - tauyyMP*wDrdy - tauyz*wDrdz; + flux[3] = sol[3]*Ur - tauxz*wDrdx - tauyz*wDrdy - tauzzMP*wDrdz; + flux[4] = sol[4]*Ur - (u*tauxxMP + v*tauxy + w*tauxz + qx)*wDrdx + - (u*tauxy + v*tauyyMP + w*tauyz + qy)*wDrdy + - (u*tauxz + v*tauyz + w*tauzzMP + qz)*wDrdz; + + /*--- Fluxes in s-direction. */ + flux = flux + NPad; + const su2double Us = uRel*wDsdx + vRel*wDsdy + wRel*wDsdz; + + flux[0] = sol[0]*Us; + flux[1] = sol[1]*Us - tauxxMP*wDsdx - tauxy*wDsdy - tauxz*wDsdz; + flux[2] = sol[2]*Us - tauxy*wDsdx - tauyyMP*wDsdy - tauyz*wDsdz; + flux[3] = sol[3]*Us - tauxz*wDsdx - tauyz*wDsdy - tauzzMP*wDsdz; + flux[4] = sol[4]*Us - (u*tauxxMP + v*tauxy + w*tauxz + qx)*wDsdx + - (u*tauxy + v*tauyyMP + w*tauyz + qy)*wDsdy + - (u*tauxz + v*tauyz + w*tauzzMP + qz)*wDsdz; + + /*--- Fluxes in t-direction. */ + flux = flux + NPad; + const su2double Ut = uRel*wDtdx + vRel*wDtdy + wRel*wDtdz; + + flux[0] = sol[0]*Ut; + flux[1] = sol[1]*Ut - tauxxMP*wDtdx - tauxy*wDtdy - tauxz*wDtdz; + flux[2] = sol[2]*Ut - tauxy*wDtdx - tauyyMP*wDtdy - tauyz*wDtdz; + flux[3] = sol[3]*Ut - tauxz*wDtdx - tauyz*wDtdy - tauzzMP*wDtdz; + flux[4] = sol[4]*Ut - (u*tauxxMP + v*tauxy + w*tauxz + qx)*wDtdx + - (u*tauxy + v*tauyyMP + w*tauyz + qy)*wDtdy + - (u*tauxz + v*tauyz + w*tauzzMP + qz)*wDtdz; + + /*--- If needed, compute the body forces in this integration point. + Note that the source terms are multiplied with minus the + integration weight in order to be consistent with the + formulation of the residual. Note that for the energy source + term the absolute velocity must be taken and not the + relative. ---*/ + if( body_force ) { + su2double *source = sources + iNPad + llNVar; + const su2double weightJac = weights[i]*Jac; + + source[0] = 0.0; + source[1] = -weightJac*body_force_vector[0]; + source[2] = -weightJac*body_force_vector[1]; + source[3] = -weightJac*body_force_vector[2]; + source[4] = -weightJac*(u*body_force_vector[0] + v*body_force_vector[1] + + w*body_force_vector[2]); + } + } + } + + break; + } + } + + /* Initialize addSourceTerms to body_force. The value of addSourceTerms + is set to true when a manufactured solution is computed. */ + bool addSourceTerms = body_force; + + /* Check whether or not a manufactured solution is used. */ + if( VerificationSolution ) { + if( VerificationSolution->IsManufacturedSolution() ) { + + /*--- For the manufactured solutions a source term must be added. If a + standard source term has not been specified, initialize the source + terms to zero and set addSourceTerms to true. ---*/ + addSourceTerms = true; + if( !body_force ) { + for(unsigned short i=0; i<(nInt*NPad); ++i) + sources[i] = 0.0; + } + + /*--- Loop over the chunk of elements and its integration points. ---*/ + for(unsigned short ll=0; llGetMMSSourceTerm(coor, time, sourceMan); + + /*--- Subtract the source term of the manufactured solution, multiplied + by the appropriate weight, from the possibly earlier computed + source term. It is subtracted in order to be consistent with + the definition of the residual used in this code. ---*/ + su2double *source = sources + iNPad + llNVar; + for(unsigned short k=0; kgemm(nDOFs, NPad, nInt*nDim, matDerBasisIntTrans, fluxes, solDOFs, config); + + /* Add the contribution from the source terms, if needed. Use solAndGradInt + as temporary storage for the matrix product. */ + if( addSourceTerms ) { + + /* Call the general function to carry out the matrix product. */ + blasFunctions->gemm(nDOFs, NPad, nInt, matBasisIntTrans, sources, solAndGradInt, config); + + /* Add the residuals due to source terms to the volume residuals */ + for(unsigned short i=0; i<(nDOFs*NPad); ++i) + solDOFs[i] += solAndGradInt[i]; + } + + /* Loop over the elements in this chunk to store the residuals + in the appropriate locations. */ + for(unsigned short ll=0; llGetSizeMatMulPadding(); + const unsigned short nFaceSimul = nPadInput/nVar; + + /* Determine the minimum padded size in the matrix multiplications, which + corresponds to 64 byte alignment. */ + const unsigned short nPadMin = 64/sizeof(passivedouble); + + /* Set the number of bytes that must be copied in the memcpy calls. */ + const unsigned long nBytes = nVar*sizeof(su2double); + + /*--- Loop over the requested range of matching faces. Multiple faces + are treated simultaneously to improve the performance of the matrix + multiplications. As a consequence, the update of the counter l + happens at the end of this loop section. ---*/ + for(unsigned long l=indFaceBeg; lgemm(nInt*nDim, NPad, nDOFsElem0, derBasisElem, solElem, gradSolInt, config); + + /*--- Loop over the faces in this chunk to compute the viscous flux + vector for side 0. */ + for(unsigned long ll=l; llgemm(nInt*nDim, NPad, nDOFsElem1, derBasisElem, solElem, gradSolInt, config); + + /*--- Loop over the faces in this chunk to compute the viscous flux + vector for side 1. */ + for(unsigned long ll=l; llgemm(nDOFsFace0, NPad, nInt, basisFaceTrans, fluxes, resSide0, config); + + /* Check if the number of DOFs on both sides of the face is different. + In that case also the matrix product with the basis functions on side 1 + must be carried out. Use viscFluxes as a temporary buffer to store + this product. */ + su2double *resSide1 = viscFluxes; + if(nDOFsFace1 != nDOFsFace0) { + basisFaceTrans = standardMatchingFacesSol[ind].GetBasisFaceIntegrationTransposeSide1(); + blasFunctions->gemm(nDOFsFace1, NPad, nInt, basisFaceTrans, fluxes, resSide1, config); + } + + /* Loop over the number of faces in this chunk. */ + for(unsigned short ll=0; llGetTheta_Interior_Penalty_DGFEM(); + + /* Loop over the faces in this chunk to compute the symmetrizing fluxes. */ + for(unsigned long ll=l; llgemm(nDOFsElem0, NPad, nInt*nDim, derBasisElemTrans, paramFluxes, solIntL, config); + + /* Loop over the faces in this chunk to compute the transformed + symmetrizing fluxes for side 1. */ + for(unsigned long ll=l; llgemm(nDOFsElem1, NPad, nInt*nDim, derBasisElemTrans, paramFluxes, solIntR, config); + + /* Loop over the number of faces in this chunk. */ + for(unsigned short ll=0; llindStandardElement; + unsigned short nPoly = standardElementsSol[iind].GetNPoly(); + if(nPoly == 0) nPoly = 1; + + const su2double lenScale_LES = adjVolElem->lenScale/nPoly; + + /* Determine the offset between r- and -s-derivatives, which is also the + offset between s- and t-derivatives. */ + const unsigned short offDeriv = NPad*nInt; + + /* Make a distinction between two and three space dimensions + in order to have the most efficient code. */ + switch( nDim ) { + + case 2: { + + /* 2D simulation. Loop over the integration points to + compute the viscous fluxes. */ + for(unsigned short i=0; iSetTDState_rhoe(sol[0], StaticEnergy); + const su2double ViscosityLam = FluidModel->GetLaminarViscosity(); + + /*--- Compute the eddy viscosity, if needed. ---*/ + su2double ViscosityTurb = 0.0; + if( SGSModelUsed ) + ViscosityTurb = SGSModel->ComputeEddyViscosity_2D(sol[0], dudx, dudy, dvdx, + dvdy, lenScale_LES, wallDist); + + /* Compute the total viscosity and heat conductivity. Note that the heat + conductivity is divided by the Cv, because gradients of internal energy + are computed and not temperature. */ + Viscosity = ViscosityLam + ViscosityTurb; + kOverCv = ViscosityLam*factHeatFlux_Lam + ViscosityTurb*factHeatFlux_Turb; + + /*--- Set the value of the second viscosity and compute the divergence + term in the viscous normal stresses. ---*/ + const su2double lambda = -TWO3*Viscosity; + const su2double lamDivTerm = lambda*divVel; + + /*--- Compute the viscous stress tensor and minus the heatflux vector. + The heat flux vector is multiplied by factHeatFlux, such that the + case of a prescribed heat flux is treated correctly. ---*/ + const su2double tauxx = 2.0*Viscosity*dudx + lamDivTerm; + const su2double tauyy = 2.0*Viscosity*dvdy + lamDivTerm; + const su2double tauxy = Viscosity*(dudy + dvdx); + + const su2double qx = factHeatFlux*kOverCv*dStaticEnergyDx; + const su2double qy = factHeatFlux*kOverCv*dStaticEnergyDy; + + /* Compute the unscaled normal vector. */ + const su2double nx = normal[0]*normal[2]; + const su2double ny = normal[1]*normal[2]; + + /*--- Compute the viscous normal flux. Note that the energy flux get a + contribution from both the prescribed and the computed heat flux. + At least one of these terms is zero. ---*/ + normalFlux[0] = 0.0; + normalFlux[1] = tauxx*nx + tauxy*ny; + normalFlux[2] = tauxy*nx + tauyy*ny; + normalFlux[3] = normal[2]*HeatFlux + + (u*tauxx + v*tauxy + qx)*nx + (u*tauxy + v*tauyy + qy)*ny; +} + +void CFEM_DG_NSSolver::ViscousNormalFluxIntegrationPoint_3D(const su2double *sol, + const su2double solGradCart[5][3], + const su2double *normal, + const su2double HeatFlux, + const su2double factHeatFlux, + const su2double wallDist, + const su2double lenScale_LES, + su2double &Viscosity, + su2double &kOverCv, + su2double *normalFlux) { + + /* Constant factor present in the heat flux vector, namely the ratio of + thermal conductivity and viscosity. */ + const su2double factHeatFlux_Lam = Gamma/Prandtl_Lam; + const su2double factHeatFlux_Turb = Gamma/Prandtl_Turb; + + /*--- Compute the velocities and static energy in this integration point. ---*/ + const su2double rhoInv = 1.0/sol[0]; + const su2double u = rhoInv*sol[1]; + const su2double v = rhoInv*sol[2]; + const su2double w = rhoInv*sol[3]; + + const su2double TotalEnergy = rhoInv*sol[4]; + const su2double StaticEnergy = TotalEnergy - 0.5*(u*u + v*v + w*w); + + /*--- Compute the Cartesian gradients of the velocities and static energy + in this integration point and also the divergence of the velocity. ---*/ + const su2double dudx = rhoInv*(solGradCart[1][0] - u*solGradCart[0][0]); + const su2double dudy = rhoInv*(solGradCart[1][1] - u*solGradCart[0][1]); + const su2double dudz = rhoInv*(solGradCart[1][2] - u*solGradCart[0][2]); + + const su2double dvdx = rhoInv*(solGradCart[2][0] - v*solGradCart[0][0]); + const su2double dvdy = rhoInv*(solGradCart[2][1] - v*solGradCart[0][1]); + const su2double dvdz = rhoInv*(solGradCart[2][2] - v*solGradCart[0][2]); + + const su2double dwdx = rhoInv*(solGradCart[3][0] - w*solGradCart[0][0]); + const su2double dwdy = rhoInv*(solGradCart[3][1] - w*solGradCart[0][1]); + const su2double dwdz = rhoInv*(solGradCart[3][2] - w*solGradCart[0][2]); + + const su2double dStaticEnergyDx = rhoInv*(solGradCart[4][0] + - TotalEnergy*solGradCart[0][0]) + - u*dudx - v*dvdx - w*dwdx; + const su2double dStaticEnergyDy = rhoInv*(solGradCart[4][1] + - TotalEnergy*solGradCart[0][1]) + - u*dudy - v*dvdy - w*dwdy; + const su2double dStaticEnergyDz = rhoInv*(solGradCart[4][2] + - TotalEnergy*solGradCart[0][2]) + - u*dudz - v*dvdz - w*dwdz; + + const su2double divVel = dudx + dvdy + dwdz; + + /*--- Compute the laminar viscosity. ---*/ + FluidModel->SetTDState_rhoe(sol[0], StaticEnergy); + const su2double ViscosityLam = FluidModel->GetLaminarViscosity(); + + /*--- Compute the eddy viscosity, if needed. ---*/ + su2double ViscosityTurb = 0.0; + if( SGSModelUsed ) + ViscosityTurb = SGSModel->ComputeEddyViscosity_3D(sol[0], dudx, dudy, dudz, + dvdx, dvdy, dvdz, dwdx, + dwdy, dwdz, lenScale_LES, + wallDist); + + /* Compute the total viscosity and heat conductivity. Note that the heat + conductivity is divided by the Cv, because gradients of internal energy + are computed and not temperature. */ + Viscosity = ViscosityLam + ViscosityTurb; + kOverCv = ViscosityLam*factHeatFlux_Lam + ViscosityTurb*factHeatFlux_Turb; + + /*--- Set the value of the second viscosity and compute the divergence + term in the viscous normal stresses. ---*/ + const su2double lambda = -TWO3*Viscosity; + const su2double lamDivTerm = lambda*divVel; + + /*--- Compute the viscous stress tensor and minus the heatflux vector. + The heat flux vector is multiplied by factHeatFlux, such that the + case of a prescribed heat flux is treated correctly. ---*/ + const su2double tauxx = 2.0*Viscosity*dudx + lamDivTerm; + const su2double tauyy = 2.0*Viscosity*dvdy + lamDivTerm; + const su2double tauzz = 2.0*Viscosity*dwdz + lamDivTerm; + + const su2double tauxy = Viscosity*(dudy + dvdx); + const su2double tauxz = Viscosity*(dudz + dwdx); + const su2double tauyz = Viscosity*(dvdz + dwdy); + + const su2double qx = factHeatFlux*kOverCv*dStaticEnergyDx; + const su2double qy = factHeatFlux*kOverCv*dStaticEnergyDy; + const su2double qz = factHeatFlux*kOverCv*dStaticEnergyDz; + + /* Compute the unscaled normal vector. */ + const su2double nx = normal[0]*normal[3]; + const su2double ny = normal[1]*normal[3]; + const su2double nz = normal[2]*normal[3]; + + /*--- Compute the viscous normal flux. Note that the energy flux get a + contribution from both the prescribed and the computed heat flux. + At least one of these terms is zero. ---*/ + normalFlux[0] = 0.0; + normalFlux[1] = tauxx*nx + tauxy*ny + tauxz*nz; + normalFlux[2] = tauxy*nx + tauyy*ny + tauyz*nz; + normalFlux[3] = tauxz*nx + tauyz*ny + tauzz*nz; + normalFlux[4] = normal[3]*HeatFlux + + (u*tauxx + v*tauxy + w*tauxz + qx)*nx + + (u*tauxy + v*tauyy + w*tauyz + qy)*ny + + (u*tauxz + v*tauyz + w*tauzz + qz)*nz; +} + +void CFEM_DG_NSSolver::PenaltyTermsFluxFace(const unsigned short indFaceChunk, + const unsigned short nInt, + const unsigned short NPad, + const su2double *solInt0, + const su2double *solInt1, + const su2double *viscosityInt0, + const su2double *viscosityInt1, + const su2double *kOverCvInt0, + const su2double *kOverCvInt1, + const su2double ConstPenFace, + const su2double lenScale0, + const su2double lenScale1, + const su2double *metricNormalsFace, + su2double *penaltyFluxes) { + + /* Constant ratio of the second viscosity and the viscosity itself. */ + const su2double lambdaOverMu = -TWO3; + + /* The eigenvalues of the viscous Jacobian, scaled by the kinematic viscosity, + are 1.0, 2.0 + lambdaOverMu and kOverCv/Mu. The last is variable due to the + possible presence of an eddy viscosity, but the first two are constant and + the maximum can be determined. */ + const su2double radOverNuTerm = max(1.0, 2.0+lambdaOverMu); + + /*--- Make a distinction between 2D and 3D for efficiency. ---*/ + switch ( nDim ) { + case 2: { + + /* 2D simulation. Loop over the integration points to compute + the penalty fluxes. */ + for(unsigned short i=0; iGetSizeMatMulPadding(); + const unsigned short nFaceSimul = nPadInput/nVar; + + /* Determine the minimum padded size in the matrix multiplications, which + corresponds to 64 byte alignment. */ + const unsigned short nPadMin = 64/sizeof(passivedouble); + + /*--- Loop over the requested range of surface faces. Multiple faces + are treated simultaneously to improve the performance of the matrix + multiplications. As a consequence, the update of the counter l + happens at the end of this loop section. ---*/ + for(unsigned long l=surfElemBeg; lGetSizeMatMulPadding(); + const unsigned short nFaceSimul = nPadInput/nVar; + + /* Determine the minimum padded size in the matrix multiplications, which + corresponds to 64 byte alignment. */ + const unsigned short nPadMin = 64/sizeof(passivedouble); + + /*--- Loop over the requested range of surface faces. Multiple faces + are treated simultaneously to improve the performance of the matrix + multiplications. As a consequence, the update of the counter l + happens at the end of this loop section. ---*/ + for(unsigned long l=surfElemBeg; lGetSizeMatMulPadding(); + const unsigned short nFaceSimul = nPadInput/nVar; + + /* Determine the minimum padded size in the matrix multiplications, which + corresponds to 64 byte alignment. */ + const unsigned short nPadMin = 64/sizeof(passivedouble); + + /*--- Loop over the requested range of surface faces. Multiple faces + are treated simultaneously to improve the performance of the matrix + multiplications. As a consequence, the update of the counter l + happens at the end of this loop section. ---*/ + for(unsigned long l=surfElemBeg; lgemm(nInt*nDim, NPad, nDOFsElem, derBasisElem, solElem, gradSolInt, config); + + /*-----------------------------------------------------------------------*/ + /*--- Step 3: Computation of the viscous fluxes in the integration ---*/ + /*--- points. ---*/ + /*-----------------------------------------------------------------------*/ + + /* Determine the offset between r- and -s-derivatives, which is also the + offset between s- and t-derivatives. */ + const unsigned short offDeriv = NPad*nInt; + + /* Loop over the faces of the chunk. */ + for(unsigned long ll=l; llGetSizeMatMulPadding(); + const unsigned short nFaceSimul = nPadInput/nVar; + + /* Determine the minimum padded size in the matrix multiplications, which + corresponds to 64 byte alignment. */ + const unsigned short nPadMin = 64/sizeof(passivedouble); + + /*--- Loop over the requested range of surface faces. Multiple faces + are treated simultaneously to improve the performance of the matrix + multiplications. As a consequence, the update of the counter l + happens at the end of this loop section. ---*/ + for(unsigned long l=surfElemBeg; lGetSizeMatMulPadding(); + const unsigned short nFaceSimul = nPadInput/nVar; + + /* Determine the minimum padded size in the matrix multiplications, which + corresponds to 64 byte alignment. */ + const unsigned short nPadMin = 64/sizeof(passivedouble); + + /*--- Loop over the requested range of surface faces. Multiple faces + are treated simultaneously to improve the performance of the matrix + multiplications. As a consequence, the update of the counter l + happens at the end of this loop section. ---*/ + for(unsigned long l=surfElemBeg; lGetSizeMatMulPadding(); + const unsigned short nFaceSimul = nPadInput/nVar; + + /* Determine the minimum padded size in the matrix multiplications, which + corresponds to 64 byte alignment. */ + const unsigned short nPadMin = 64/sizeof(passivedouble); + + /*--- Loop over the requested range of surface faces. Multiple faces + are treated simultaneously to improve the performance of the matrix + multiplications. As a consequence, the update of the counter l + happens at the end of this loop section. ---*/ + for(unsigned long l=surfElemBeg; lGetMarker_All_TagBound(val_marker); + const su2double Wall_HeatFlux = config->GetWall_HeatFlux(Marker_Tag); + + /* Initialization of the counter in resFaces. */ + unsigned long indResFaces = 0; + + /* Determine the number of faces that are treated simultaneously + in the matrix products to obtain good gemm performance. */ + const unsigned short nPadInput = config->GetSizeMatMulPadding(); + const unsigned short nFaceSimul = nPadInput/nVar; + + /* Determine the minimum padded size in the matrix multiplications, which + corresponds to 64 byte alignment. */ + const unsigned short nPadMin = 64/sizeof(passivedouble); + + /*--- Loop over the requested range of surface faces. Multiple faces + are treated simultaneously to improve the performance of the matrix + multiplications. As a consequence, the update of the counter l + happens at the end of this loop section. ---*/ + for(unsigned long l=surfElemBeg; lGetMarker_All_TagBound(val_marker); + const su2double TWall = config->GetIsothermal_Temperature(Marker_Tag)/config->GetTemperature_Ref(); + + /* Compute the prescribed value of the energy (per unit mass). */ + const su2double Gas_Constant = config->GetGas_ConstantND(); + const su2double Cv = Gas_Constant/Gamma_Minus_One; + const su2double StaticEnergy = Cv*TWall; + + /* Initialization of the counter in resFaces. */ + unsigned long indResFaces = 0; + + /* Determine the number of faces that are treated simultaneously + in the matrix products to obtain good gemm performance. */ + const unsigned short nPadInput = config->GetSizeMatMulPadding(); + const unsigned short nFaceSimul = nPadInput/nVar; + + /* Determine the minimum padded size in the matrix multiplications, which + corresponds to 64 byte alignment. */ + const unsigned short nPadMin = 64/sizeof(passivedouble); + + /*--- Loop over the requested range of surface faces. Multiple faces + are treated simultaneously to improve the performance of the matrix + multiplications. As a consequence, the update of the counter l + happens at the end of this loop section. ---*/ + for(unsigned long l=surfElemBeg; lGetSizeMatMulPadding(); + const unsigned short nFaceSimul = nPadInput/nVar; + + /* Determine the minimum padded size in the matrix multiplications, which + corresponds to 64 byte alignment. */ + const unsigned short nPadMin = 64/sizeof(passivedouble); + + /*--- Loop over the requested range of surface faces. Multiple faces + are treated simultaneously to improve the performance of the matrix + multiplications. As a consequence, the update of the counter l + happens at the end of this loop section. ---*/ + for(unsigned long l=surfElemBeg; lGetSizeMatMulPadding(); + const unsigned short nFaceSimul = nPadInput/nVar; + + /* Determine the minimum padded size in the matrix multiplications, which + corresponds to 64 byte alignment. */ + const unsigned short nPadMin = 64/sizeof(passivedouble); + + /*--- Get the physical time if necessary. ---*/ + su2double time = 0.0; + if (config->GetTime_Marching()) time = config->GetPhysicalTime(); + + /*--- Loop over the requested range of surface faces. Multiple faces + are treated simultaneously to improve the performance of the matrix + multiplications. As a consequence, the update of the counter l + happens at the end of this loop section. ---*/ + for(unsigned long l=surfElemBeg; lGetBCState(coor, time, UR); + } + } + } + else { + + /* The user must specify the custom BC's here. */ + SU2_MPI::Error("Implement customized boundary conditions here.", CURRENT_FUNCTION); + } + + + /* The remainder of the boundary treatment is the same for all + boundary conditions (except the symmetry plane). */ + ViscousBoundaryFacesBCTreatment(config, conv_numerics, llEnd, NPad, + 0.0, false, 0.0, false, &surfElem[l], + solIntL, solIntR, work, + resFaces, indResFaces, NULL); + + /* Update the value of the counter l to the end index of the + current chunk. */ + l = lEnd; + } +} + +void CFEM_DG_NSSolver::ViscousBoundaryFacesBCTreatment( + CConfig *config, + CNumerics *conv_numerics, + const unsigned short nFaceSimul, + const unsigned short NPad, + const su2double Wall_HeatFlux, + const bool HeatFlux_Prescribed, + const su2double Wall_Temperature, + const bool Temperature_Prescribed, + const CSurfaceElementFEM *surfElem, + const su2double *solIntL, + const su2double *solIntR, + su2double *workArray, + su2double *resFaces, + unsigned long &indResFaces, + CWallModel *wallModel) { + + /*--- Get the information from the standard element, which is the same + for all the faces in the chunks considered. ---*/ + const unsigned short ind = surfElem[0].indStandardElement; + const unsigned short nInt = standardBoundaryFacesSol[ind].GetNIntegration(); + const unsigned short nDOFsElem = standardBoundaryFacesSol[ind].GetNDOFsElem(); + const su2double *derBasisElem = standardBoundaryFacesSol[ind].GetMatDerBasisElemIntegration(); + + /*--- Set the pointers for the local arrays. ---*/ + su2double *viscosityInt = workArray; + su2double *kOverCvInt = viscosityInt + nFaceSimul*nInt; + su2double *gradSolInt = kOverCvInt + nFaceSimul*nInt; + su2double *fluxes = gradSolInt + NPad*nInt*nDim; + su2double *viscFluxes = fluxes + NPad*max(nInt*nDim, (int) nDOFsElem); + + /* Compute the viscous fluxes in the integration points of the faces that + are treated simulaneously. Make a distinction between a wall function + treatment and a standard computation of the viscous fluxes. */ + if( wallModel ) { + WallTreatmentViscousFluxes(config, nFaceSimul, NPad, nInt, Wall_HeatFlux, + HeatFlux_Prescribed, Wall_Temperature, + Temperature_Prescribed, surfElem, solIntL, + gradSolInt, viscFluxes, viscosityInt, + kOverCvInt, wallModel); + } + else { + ComputeViscousFluxesBoundaryFaces(config, nFaceSimul, NPad, nInt, nDOFsElem, + Wall_HeatFlux, HeatFlux_Prescribed, + derBasisElem, surfElem, solIntL, + fluxes, gradSolInt, viscFluxes, + viscosityInt, kOverCvInt); + } + + /* The remainder of the boundary condition treatment is the same for all + types of boundary conditions, including the symmetry plane and the + wall function treatment. The function ResidualViscousBoundaryFace will + carry out this task. */ + + ResidualViscousBoundaryFace(config, conv_numerics, nFaceSimul, NPad, surfElem, + solIntL, solIntR, gradSolInt, fluxes, viscFluxes, + viscosityInt, kOverCvInt, resFaces, indResFaces); +} + +void CFEM_DG_NSSolver::ComputeViscousFluxesBoundaryFaces( + CConfig *config, + const unsigned short nFaceSimul, + const unsigned short NPad, + const unsigned short nInt, + const unsigned short nDOFsElem, + const su2double Wall_HeatFlux, + const bool HeatFlux_Prescribed, + const su2double *derBasisElem, + const CSurfaceElementFEM *surfElem, + const su2double *solIntL, + su2double *solElem, + su2double *gradSolInt, + su2double *viscFluxes, + su2double *viscosityInt, + su2double *kOverCvInt) { + + /* Easier storage of the number of bytes to copy in the memcpy calls. */ + const unsigned long nBytes = nVar*sizeof(su2double); + + /*---------------------------------------------------------------------------*/ + /*--- Step 1: Compute the gradients of the conservative variables in the ---*/ + /*--- integration points of the faces. ---*/ + /*---------------------------------------------------------------------------*/ + + /* Loop over the simultaneously treated faces to set the solution of the elements. */ + for(unsigned short l=0; lgemm(nInt*nDim, NPad, nDOFsElem, derBasisElem, solElem, gradSolInt, config); + + /*---------------------------------------------------------------------------*/ + /*--- Step 2: Compute the viscous normal fluxes in the integration points ---*/ + /*--- of the faces. ---*/ + /*---------------------------------------------------------------------------*/ + + /* Loop over the simultaneously treated faces. */ + for(unsigned short l=0; lgemm(nIntThisDonor, nVar, nDOFsElem, surfElem[l].matWallFunctionDonor[j].data(), + solDOFsElem, workArray, config); + + /* Loop over the integration points for this donor element. */ + for(unsigned short i=surfElem[l].nIntPerWallFunctionDonor[j]; + iSetTDState_rhoe(solInt[0], eInt); + const su2double Pressure = FluidModel->GetPressure(); + const su2double Temperature = FluidModel->GetTemperature(); + const su2double LaminarViscosity= FluidModel->GetLaminarViscosity(); + + /* Subtract the prescribed wall velocity, i.e. grid velocity + from the velocity in the exchange point. */ + for(unsigned short k=0; kWallShearStressAndHeatFlux(Temperature, velTan, LaminarViscosity, Pressure, + Wall_HeatFlux, HeatFlux_Prescribed, + Wall_Temperature, Temperature_Prescribed, + FluidModel, tauWall, qWall, ViscosityWall, + kOverCvWall); + + /* Compute the wall velocity in tangential direction. */ + const su2double *solWallInt = solIntL + NPad*ii + llNVar; + su2double velWallTan = 0.0; + for(unsigned short k=0; k SIZE_ARR_NORM) + SU2_MPI::Error("SIZE_ARR_NORM is too small. Increase it or decrease ALIGNED_BYTES_MATMUL", + CURRENT_FUNCTION); + + for(unsigned short l=0; lgemm(nDOFs, NPad, nInt, basisFaceTrans, fluxes, viscFluxes, config); + + /* Loop over the number of faces in this chunk to store the residual in + the correct locations in resFaces. */ + for(unsigned short l=0; lGetTheta_Interior_Penalty_DGFEM(); + + /* Loop over the simultaneously treated faces. */ + for(unsigned short l=0; lgemm(nDOFsElem, NPad, nInt*nDim, derBasisElemTrans, paramFluxes, fluxes, config); + + /* Loop over the faces of this chunk to store the residual in + the correct locations in resFaces. */ + for(unsigned short l=0; lGetMultizone_Problem(); int rank = MASTER_NODE; - + bool heat_equation = ((config->GetKind_Solver() == HEAT_EQUATION_FVM) || (config->GetKind_Solver() == DISC_ADJ_HEAT)); @@ -216,7 +215,7 @@ CHeatSolverFVM::CHeatSolverFVM(CGeometry *geometry, CConfig *config, unsigned sh } /*--- Heat flux in all the markers ---*/ - + HeatFlux = new su2double* [nMarker]; for (iMarker = 0; iMarker < nMarker; iMarker++) { HeatFlux[iMarker] = new su2double [geometry->nVertex[iMarker]]; @@ -247,7 +246,7 @@ CHeatSolverFVM::CHeatSolverFVM(CGeometry *geometry, CConfig *config, unsigned sh SetBaseClassPointerToNodes(); /*--- MPI solution ---*/ - + InitiateComms(geometry, config, SOLUTION); CompleteComms(geometry, config, SOLUTION); @@ -257,16 +256,16 @@ CHeatSolverFVM::CHeatSolverFVM(CGeometry *geometry, CConfig *config, unsigned sh } CHeatSolverFVM::~CHeatSolverFVM(void) { - + unsigned short iMarker; - + if (HeatFlux != NULL) { for (iMarker = 0; iMarker < nMarker; iMarker++) { delete [] HeatFlux[iMarker]; } delete [] HeatFlux; } - + if (nodes != nullptr) delete nodes; } @@ -310,12 +309,12 @@ void CHeatSolverFVM::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfi unsigned short iDim, iVar, iMesh; unsigned long iPoint, index, iChildren, Point_Fine; - + bool flow = ((config->GetKind_Solver() == INC_NAVIER_STOKES) || (config->GetKind_Solver() == INC_RANS) || (config->GetKind_Solver() == DISC_ADJ_INC_NAVIER_STOKES) || (config->GetKind_Solver() == DISC_ADJ_INC_RANS)); - + bool heat_equation = ((config->GetKind_Solver() == HEAT_EQUATION_FVM) || (config->GetKind_Solver() == DISC_ADJ_HEAT)); @@ -416,10 +415,10 @@ void CHeatSolverFVM::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfi it down to the coarse levels. We alo call the preprocessing routine on the fine level in order to have all necessary quantities updated, especially if this is a turbulent simulation (eddy viscosity). ---*/ - + solver[MESH_0][HEAT_SOL]->InitiateComms(geometry[MESH_0], config, SOLUTION); solver[MESH_0][HEAT_SOL]->CompleteComms(geometry[MESH_0], config, SOLUTION); - + solver[MESH_0][HEAT_SOL]->Preprocessing(geometry[MESH_0], solver[MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_HEAT_SYS, false); /*--- Interpolate the solution down to the coarse multigrid levels ---*/ @@ -498,10 +497,10 @@ void CHeatSolverFVM::SetUndivided_Laplacian(CGeometry *geometry, CConfig *config } /*--- MPI parallelization ---*/ - + InitiateComms(geometry, config, UNDIVIDED_LAPLACIAN); CompleteComms(geometry, config, UNDIVIDED_LAPLACIAN); - + delete [] Diff; } @@ -911,7 +910,7 @@ void CHeatSolverFVM::BC_Inlet(CGeometry *geometry, CSolver **solver_container, unsigned long iVertex, iPoint, Point_Normal; su2double *Flow_Dir, Vel_Mag; su2double *V_inlet, *V_domain; - + bool flow = ((config->GetKind_Solver() == INC_NAVIER_STOKES) || (config->GetKind_Solver() == INC_RANS) || (config->GetKind_Solver() == DISC_ADJ_INC_NAVIER_STOKES) @@ -1095,7 +1094,7 @@ void CHeatSolverFVM::BC_Outlet(CGeometry *geometry, CSolver **solver_container, void CHeatSolverFVM::BC_ConjugateHeat_Interface(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short val_marker) { unsigned long iVertex, iPoint, total_index; - unsigned short iDim, iVar, iMarker; + unsigned short iDim, iVar; su2double thermal_diffusivity, rho_cp_solid, Temperature_Ref, T_Conjugate, Tinterface, Tnormal_Conjugate, HeatFluxDensity, HeatFlux, Area; @@ -1244,9 +1243,9 @@ void CHeatSolverFVM::Heat_Fluxes(CGeometry *geometry, CSolver **solver_container } HeatFlux[iMarker][iVertex] = thermal_diffusivity*dTdn*config->GetHeat_Flux_Ref(); - + HeatFlux_per_Marker[iMarker] += HeatFlux[iMarker][iVertex]*Area; - + } } } @@ -1284,7 +1283,7 @@ void CHeatSolverFVM::Heat_Fluxes(CGeometry *geometry, CSolver **solver_container } HeatFlux[iMarker][iVertex] = thermal_diffusivity*dTdn*config->GetHeat_Flux_Ref(); - + HeatFlux_per_Marker[iMarker] += HeatFlux[iMarker][iVertex]*Area; /*--- We do only aim to compute averaged temperatures on the (interesting) heat flux walls ---*/ @@ -1328,12 +1327,12 @@ void CHeatSolverFVM::SetTime_Step(CGeometry *geometry, CSolver **solver_containe unsigned long iEdge, iVertex, iPoint = 0, jPoint = 0; su2double *Normal, Area, Vol, laminar_viscosity, eddy_viscosity, thermal_diffusivity, Prandtl_Lam, Prandtl_Turb, Mean_ProjVel, Mean_BetaInc2, Mean_DensityInc, Mean_SoundSpeed, Lambda; su2double Global_Delta_Time = 0.0, Global_Delta_UnstTimeND = 0.0, Local_Delta_Time = 0.0, Local_Delta_Time_Inv, Local_Delta_Time_Visc, CFL_Reduction, K_v = 0.25; - + bool flow = ((config->GetKind_Solver() == INC_NAVIER_STOKES) || (config->GetKind_Solver() == INC_RANS) || (config->GetKind_Solver() == DISC_ADJ_INC_NAVIER_STOKES) || (config->GetKind_Solver() == DISC_ADJ_INC_RANS)); - + bool turb = ((config->GetKind_Solver() == INC_RANS) || (config->GetKind_Solver() == DISC_ADJ_INC_RANS)); bool dual_time = ((config->GetTime_Marching() == DT_STEPPING_1ST) || (config->GetTime_Marching() == DT_STEPPING_2ND)); @@ -1577,7 +1576,7 @@ void CHeatSolverFVM::ExplicitEuler_Iteration(CGeometry *geometry, CSolver **solv InitiateComms(geometry, config, SOLUTION); CompleteComms(geometry, config, SOLUTION); - + /*--- Compute the root mean square residual ---*/ SetResidual_RMS(geometry, config); @@ -1672,7 +1671,7 @@ void CHeatSolverFVM::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solv InitiateComms(geometry, config, SOLUTION); CompleteComms(geometry, config, SOLUTION); - + /*--- Compute the root mean square residual ---*/ SetResidual_RMS(geometry, config); @@ -1708,7 +1707,7 @@ void CHeatSolverFVM::SetInitialCondition(CGeometry **geometry, CSolver ***solver } } solver_container[iMesh][HEAT_SOL]->GetNodes()->SetSolution(iPoint,Solution); - } + } solver_container[iMesh][HEAT_SOL]->InitiateComms(geometry[iMesh], config, SOLUTION); solver_container[iMesh][HEAT_SOL]->CompleteComms(geometry[iMesh], config, SOLUTION); } diff --git a/SU2_CFD/src/solver_direct_mean_inc.cpp b/SU2_CFD/src/solvers/CIncEulerSolver.cpp similarity index 72% rename from SU2_CFD/src/solver_direct_mean_inc.cpp rename to SU2_CFD/src/solvers/CIncEulerSolver.cpp index 7bec4988809e..494418e8f574 100644 --- a/SU2_CFD/src/solver_direct_mean_inc.cpp +++ b/SU2_CFD/src/solvers/CIncEulerSolver.cpp @@ -6,7 +6,7 @@ * * SU2 Project Website: https://su2code.github.io * - * The SU2 Project is maintained by the SU2 Foundation + * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) @@ -26,13 +26,11 @@ */ -#include "../include/solver_structure.hpp" -#include "../../Common/include/toolboxes/printing_toolbox.hpp" -#include "../include/variables/CIncEulerVariable.hpp" -#include "../include/variables/CIncNSVariable.hpp" -#include "../include/gradients/computeGradientsGreenGauss.hpp" -#include "../include/gradients/computeGradientsLeastSquares.hpp" -#include "../include/limiters/computeLimiters.hpp" +#include "../../include/solvers/CIncEulerSolver.hpp" +#include "../../../Common/include/toolboxes/printing_toolbox.hpp" +#include "../../include/gradients/computeGradientsGreenGauss.hpp" +#include "../../include/gradients/computeGradientsLeastSquares.hpp" +#include "../../include/limiters/computeLimiters.hpp" CIncEulerSolver::CIncEulerSolver(void) : CSolver() { @@ -65,13 +63,13 @@ CIncEulerSolver::CIncEulerSolver(void) : CSolver() { Surface_CL = NULL; Surface_CD = NULL; Surface_CSF = NULL; Surface_CEff = NULL; Surface_CFx = NULL; Surface_CFy = NULL; Surface_CFz = NULL; Surface_CMx = NULL; Surface_CMy = NULL; Surface_CMz = NULL; - + /*--- Rotorcraft simulation array initialization ---*/ - + CMerit_Inv = NULL; CT_Inv = NULL; CQ_Inv = NULL; - + /*--- Numerical methods array initialization ---*/ - + iPoint_UndLapl = NULL; jPoint_UndLapl = NULL; Primitive = NULL; Primitive_i = NULL; Primitive_j = NULL; @@ -83,12 +81,12 @@ CIncEulerSolver::CIncEulerSolver(void) : CSolver() { SlidingState = NULL; SlidingStateNodes = NULL; - + nodes = nullptr; } CIncEulerSolver::CIncEulerSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh) : CSolver() { - + unsigned long iPoint, iVertex; unsigned short iVar, iDim, iMarker, nLineLets; ifstream restart_file; @@ -143,7 +141,7 @@ CIncEulerSolver::CIncEulerSolver(CGeometry *geometry, CConfig *config, unsigned /*--- Read and store the restart metadata. ---*/ // Read_SU2_Restart_Metadata(geometry, config, false, filename_); - + } /*--- Basic array initialization ---*/ @@ -180,7 +178,7 @@ CIncEulerSolver::CIncEulerSolver(CGeometry *geometry, CConfig *config, unsigned CMerit_Inv = NULL; CT_Inv = NULL; CQ_Inv = NULL; /*--- Numerical methods array initialization ---*/ - + iPoint_UndLapl = NULL; jPoint_UndLapl = NULL; Primitive = NULL; Primitive_i = NULL; Primitive_j = NULL; @@ -193,84 +191,84 @@ CIncEulerSolver::CIncEulerSolver(CGeometry *geometry, CConfig *config, unsigned FluidModel = NULL; /*--- Set the gamma value ---*/ - + Gamma = config->GetGamma(); Gamma_Minus_One = Gamma - 1.0; - + /*--- Define geometry constants in the solver structure. * Incompressible flow, primitive variables (P, vx, vy, vz, T, rho, beta, lamMu, EddyMu, Kt_eff, Cp, Cv) ---*/ - + nDim = geometry->GetnDim(); - + nVar = nDim+2; nPrimVar = nDim+9; nPrimVarGrad = nDim+4; /*--- Initialize nVarGrad for deallocation ---*/ - + nVarGrad = nPrimVarGrad; - + nMarker = config->GetnMarker_All(); nPoint = geometry->GetnPoint(); nPointDomain = geometry->GetnPointDomain(); - + /*--- Store the number of vertices on each marker for deallocation later ---*/ nVertex = new unsigned long[nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) + for (iMarker = 0; iMarker < nMarker; iMarker++) nVertex[iMarker] = geometry->nVertex[iMarker]; - + /*--- Perform the non-dimensionalization for the flow equations using the specified reference values. ---*/ - + SetNondimensionalization(config, iMesh); - + /*--- Check if we are executing a verification case. If so, the VerificationSolution object will be instantiated for a particular option from the available library of verification solutions. Note that this is done after SetNondim(), as problem-specific initial parameters are needed by the solution constructors. ---*/ - + SetVerificationSolution(nDim, nVar, config); - + /*--- Define some auxiliary vectors related to the residual ---*/ - + Residual = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = 0.0; Residual_RMS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_RMS[iVar] = 0.0; Residual_Max = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_Max[iVar] = 0.0; Res_Conv = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Conv[iVar] = 0.0; Res_Visc = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Visc[iVar] = 0.0; Res_Sour = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Sour[iVar] = 0.0; - + /*--- Define some structures for locating max residuals ---*/ - + Point_Max = new unsigned long[nVar]; for (iVar = 0; iVar < nVar; iVar++) Point_Max[iVar] = 0; - + Point_Max_Coord = new su2double*[nVar]; for (iVar = 0; iVar < nVar; iVar++) { Point_Max_Coord[iVar] = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Point_Max_Coord[iVar][iDim] = 0.0; } - + /*--- Define some auxiliary vectors related to the solution ---*/ - + Solution = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution[iVar] = 0.0; Solution_i = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution_i[iVar] = 0.0; Solution_j = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution_j[iVar] = 0.0; - + /*--- Define some auxiliary vectors related to the geometry ---*/ - + Vector = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = 0.0; Vector_i = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector_i[iDim] = 0.0; Vector_j = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector_j[iDim] = 0.0; - + /*--- Define some auxiliary vectors related to the primitive solution ---*/ - + Primitive = new su2double[nPrimVar]; for (iVar = 0; iVar < nPrimVar; iVar++) Primitive[iVar] = 0.0; Primitive_i = new su2double[nPrimVar]; for (iVar = 0; iVar < nPrimVar; iVar++) Primitive_i[iVar] = 0.0; Primitive_j = new su2double[nPrimVar]; for (iVar = 0; iVar < nPrimVar; iVar++) Primitive_j[iVar] = 0.0; - + /*--- Define some auxiliary vectors related to the undivided lapalacian ---*/ - + if (config->GetKind_ConvNumScheme_Flow() == SPACE_CENTERED) { iPoint_UndLapl = new su2double [nPoint]; jPoint_UndLapl = new su2double [nPoint]; @@ -283,49 +281,49 @@ CIncEulerSolver::CIncEulerSolver(CGeometry *geometry, CConfig *config, unsigned /*--- Initialize the solution and right-hand side vectors for storing the residuals and updating the solution (always needed even for explicit schemes). ---*/ - + LinSysSol.Initialize(nPoint, nPointDomain, nVar, 0.0); LinSysRes.Initialize(nPoint, nPointDomain, nVar, 0.0); - + /*--- Jacobians and vector structures for implicit computations ---*/ - + if (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT) { - + Jacobian_i = new su2double* [nVar]; Jacobian_j = new su2double* [nVar]; for (iVar = 0; iVar < nVar; iVar++) { Jacobian_i[iVar] = new su2double [nVar]; Jacobian_j[iVar] = new su2double [nVar]; } - + if (rank == MASTER_NODE) cout << "Initialize Jacobian structure (Euler). MG level: " << iMesh <<"." << endl; Jacobian.Initialize(nPoint, nPointDomain, nVar, nVar, true, geometry, config); - + if (config->GetKind_Linear_Solver_Prec() == LINELET) { nLineLets = Jacobian.BuildLineletPreconditioner(geometry, config); if (rank == MASTER_NODE) cout << "Compute linelet structure. " << nLineLets << " elements in each line (average)." << endl; } - + } - + else { if (rank == MASTER_NODE) cout << "Explicit scheme. No Jacobian structure (Euler). MG level: " << iMesh <<"." << endl; } - + /*--- Define some auxiliary vectors for computing flow variable gradients by least squares, S matrix := inv(R)*traspose(inv(R)), c vector := transpose(WA)*(Wb) ---*/ - + if (config->GetLeastSquaresRequired()) { - + Smatrix = new su2double* [nDim]; for (iDim = 0; iDim < nDim; iDim++) Smatrix[iDim] = new su2double [nDim]; - + Cvector = new su2double* [nPrimVarGrad]; for (iVar = 0; iVar < nPrimVarGrad; iVar++) Cvector[iVar] = new su2double [nDim]; - + } /*--- Store the value of the characteristic primitive variables at the boundaries ---*/ @@ -342,7 +340,7 @@ CIncEulerSolver::CIncEulerSolver(CGeometry *geometry, CConfig *config, unsigned } /*--- Force definition and coefficient arrays for all of the markers ---*/ - + CPressure = new su2double* [nMarker]; CPressureTarget = new su2double* [nMarker]; for (iMarker = 0; iMarker < nMarker; iMarker++) { @@ -353,9 +351,9 @@ CIncEulerSolver::CIncEulerSolver(CGeometry *geometry, CConfig *config, unsigned CPressureTarget[iMarker][iVertex] = 0.0; } } - + /*--- Store the value of the Total Pressure at the inlet BC ---*/ - + Inlet_Ttotal = new su2double* [nMarker]; for (iMarker = 0; iMarker < nMarker; iMarker++) { Inlet_Ttotal[iMarker] = new su2double [geometry->nVertex[iMarker]]; @@ -363,9 +361,9 @@ CIncEulerSolver::CIncEulerSolver(CGeometry *geometry, CConfig *config, unsigned Inlet_Ttotal[iMarker][iVertex] = 0; } } - + /*--- Store the value of the Total Temperature at the inlet BC ---*/ - + Inlet_Ptotal = new su2double* [nMarker]; for (iMarker = 0; iMarker < nMarker; iMarker++) { Inlet_Ptotal[iMarker] = new su2double [geometry->nVertex[iMarker]]; @@ -373,9 +371,9 @@ CIncEulerSolver::CIncEulerSolver(CGeometry *geometry, CConfig *config, unsigned Inlet_Ptotal[iMarker][iVertex] = 0; } } - + /*--- Store the value of the Flow direction at the inlet BC ---*/ - + Inlet_FlowDir = new su2double** [nMarker]; for (iMarker = 0; iMarker < nMarker; iMarker++) { Inlet_FlowDir[iMarker] = new su2double* [geometry->nVertex[iMarker]]; @@ -386,7 +384,7 @@ CIncEulerSolver::CIncEulerSolver(CGeometry *geometry, CConfig *config, unsigned } } } - + /*--- Non-dimensional coefficients ---*/ ForceInviscid = new su2double[nDim]; @@ -474,7 +472,7 @@ CIncEulerSolver::CIncEulerSolver(CGeometry *geometry, CConfig *config, unsigned Total_CT = 0.0; Total_CQ = 0.0; Total_CMerit = 0.0; Total_MaxHeat = 0.0; Total_Heat = 0.0; Total_ComboObj = 0.0; Total_CpDiff = 0.0; Total_HeatFluxDiff = 0.0; Total_Custom_ObjFunc = 0.0; - + /*--- Read farfield conditions ---*/ Density_Inf = config->GetDensity_FreeStreamND(); @@ -483,7 +481,7 @@ CIncEulerSolver::CIncEulerSolver(CGeometry *geometry, CConfig *config, unsigned Temperature_Inf = config->GetTemperature_FreeStreamND(); /*--- Initialize the secondary values for direct derivative approxiations ---*/ - + switch(direct_diff){ case NO_DERIVATIVE: /*--- Default ---*/ @@ -505,12 +503,12 @@ CIncEulerSolver::CIncEulerSolver(CGeometry *geometry, CConfig *config, unsigned default: break; } - + /*--- Initializate quantities for SlidingMesh Interface ---*/ - + SlidingState = new su2double*** [nMarker]; SlidingStateNodes = new int* [nMarker]; - + for (iMarker = 0; iMarker < nMarker; iMarker++){ SlidingState[iMarker] = NULL; SlidingStateNodes[iMarker] = NULL; @@ -575,7 +573,7 @@ CIncEulerSolver::CIncEulerSolver(CGeometry *geometry, CConfig *config, unsigned /*--- Communicate and store volume and the number of neighbors for any dual CVs that lie on on periodic markers. ---*/ - + for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_VOLUME); CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_VOLUME); @@ -584,14 +582,14 @@ CIncEulerSolver::CIncEulerSolver(CGeometry *geometry, CConfig *config, unsigned } SetImplicitPeriodic(euler_implicit); if (iMesh == MESH_0) SetRotatePeriodic(true); - + /*--- Perform the MPI communication of the solution ---*/ InitiateComms(geometry, config, SOLUTION); CompleteComms(geometry, config, SOLUTION); - + /* Store the initial CFL number for all grid points. */ - + const su2double CFL = config->GetCFL(MGLevel); for (iPoint = 0; iPoint < nPoint; iPoint++) { nodes->SetLocalCFL(iPoint, CFL); @@ -599,7 +597,7 @@ CIncEulerSolver::CIncEulerSolver(CGeometry *geometry, CConfig *config, unsigned Min_CFL_Local = CFL; Max_CFL_Local = CFL; Avg_CFL_Local = CFL; - + /*--- Add the solver name (max 8 characters) ---*/ SolverName = "INC.FLOW"; @@ -670,7 +668,7 @@ CIncEulerSolver::~CIncEulerSolver(void) { if (Surface_CMx != NULL) delete [] Surface_CMx; if (Surface_CMy != NULL) delete [] Surface_CMy; if (Surface_CMz != NULL) delete [] Surface_CMz; - + if (CEff_Inv != NULL) delete [] CEff_Inv; if (CMerit_Inv != NULL) delete [] CMerit_Inv; if (CT_Inv != NULL) delete [] CT_Inv; @@ -701,7 +699,7 @@ CIncEulerSolver::~CIncEulerSolver(void) { delete [] CPressure[iMarker]; delete [] CPressure; } - + if (CPressureTarget != NULL) { for (iMarker = 0; iMarker < nMarker; iMarker++) delete [] CPressureTarget[iMarker]; @@ -731,11 +729,11 @@ CIncEulerSolver::~CIncEulerSolver(void) { } delete [] SlidingState; } - + if ( SlidingStateNodes != NULL ){ for (iMarker = 0; iMarker < nMarker; iMarker++){ if (SlidingStateNodes[iMarker] != NULL) - delete [] SlidingStateNodes[iMarker]; + delete [] SlidingStateNodes[iMarker]; } delete [] SlidingStateNodes; } @@ -746,14 +744,14 @@ CIncEulerSolver::~CIncEulerSolver(void) { delete [] Inlet_Ttotal[iMarker]; delete [] Inlet_Ttotal; } - + if (Inlet_Ptotal != NULL) { for (iMarker = 0; iMarker < nMarker; iMarker++) if (Inlet_Ptotal[iMarker] != NULL) delete [] Inlet_Ptotal[iMarker]; delete [] Inlet_Ptotal; } - + if (Inlet_FlowDir != NULL) { for (iMarker = 0; iMarker < nMarker; iMarker++) { if (Inlet_FlowDir[iMarker] != NULL) { @@ -771,28 +769,28 @@ CIncEulerSolver::~CIncEulerSolver(void) { } delete [] HeatFlux; } - + if (HeatFluxTarget != NULL) { for (iMarker = 0; iMarker < nMarker; iMarker++) { delete [] HeatFluxTarget[iMarker]; } delete [] HeatFluxTarget; } - + if (YPlus != NULL) { for (iMarker = 0; iMarker < nMarker; iMarker++) { delete [] YPlus[iMarker]; } delete [] YPlus; } - + if (FluidModel != NULL) delete FluidModel; - + if (nodes != nullptr) delete nodes; } void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short iMesh) { - + su2double Temperature_FreeStream = 0.0, ModVel_FreeStream = 0.0,Energy_FreeStream = 0.0, ModVel_FreeStreamND = 0.0, Omega_FreeStream = 0.0, Omega_FreeStreamND = 0.0, Viscosity_FreeStream = 0.0, Density_FreeStream = 0.0, Pressure_FreeStream = 0.0, Pressure_Thermodynamic = 0.0, Tke_FreeStream = 0.0, @@ -802,14 +800,14 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i Velocity_FreeStreamND[3] = {0.0, 0.0, 0.0}, Viscosity_FreeStreamND = 0.0, Tke_FreeStreamND = 0.0, Energy_FreeStreamND = 0.0, Total_UnstTimeND = 0.0, Delta_UnstTimeND = 0.0; - + unsigned short iDim, iVar; - + /*--- Local variables ---*/ - + su2double Mach = config->GetMach(); su2double Reynolds = config->GetReynolds(); - + bool unsteady = (config->GetTime_Marching() != NO); bool viscous = config->GetViscous(); bool turbulent = ((config->GetKind_Solver() == INC_RANS) || @@ -850,9 +848,9 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i Pressure_Thermodynamic = FluidModel->GetPressure(); config->SetPressure_Thermodynamic(Pressure_Thermodynamic); break; - + case INC_IDEAL_GAS_POLY: - + config->SetGas_Constant(UNIVERSAL_GAS_CONSTANT/(config->GetMolecular_Weight()/1000.0)); Pressure_Thermodynamic = Density_FreeStream*Temperature_FreeStream*config->GetGas_Constant(); FluidModel = new CIncIdealGasPolynomial(config->GetGas_Constant(), Pressure_Thermodynamic); @@ -883,7 +881,7 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i config->SetMu_Temperature_RefND(config->GetMu_Temperature_Ref()); config->SetMu_SND(config->GetMu_S()); config->SetMu_ConstantND(config->GetMu_Constant()); - + for (iVar = 0; iVar < config->GetnPolyCoeffs(); iVar++) config->SetMu_PolyCoeffND(config->GetMu_PolyCoeff(iVar), iVar); @@ -922,7 +920,7 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i Velocity_Ref = ModVel_FreeStream; Temperature_Ref = Temperature_FreeStream; Pressure_Ref = Density_Ref*Velocity_Ref*Velocity_Ref; - } + } else if (config->GetRef_Inc_NonDim() == REFERENCE_VALUES) { Density_Ref = config->GetInc_Density_Ref(); Velocity_Ref = config->GetInc_Velocity_Ref(); @@ -935,7 +933,7 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i config->SetPressure_Ref(Pressure_Ref); /*--- More derived reference values ---*/ - + Length_Ref = 1.0; config->SetLength_Ref(Length_Ref); Time_Ref = Length_Ref/Velocity_Ref; config->SetTime_Ref(Time_Ref); Omega_Ref = Velocity_Ref/Length_Ref; config->SetOmega_Ref(Omega_Ref); @@ -961,11 +959,11 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i config->SetMach(Mach); /*--- Divide by reference values, to compute the non-dimensional free-stream values ---*/ - + Pressure_FreeStreamND = Pressure_FreeStream/config->GetPressure_Ref(); config->SetPressure_FreeStreamND(Pressure_FreeStreamND); Pressure_ThermodynamicND = Pressure_Thermodynamic/config->GetPressure_Ref(); config->SetPressure_ThermodynamicND(Pressure_ThermodynamicND); Density_FreeStreamND = Density_FreeStream/config->GetDensity_Ref(); config->SetDensity_FreeStreamND(Density_FreeStreamND); - + for (iDim = 0; iDim < nDim; iDim++) { Velocity_FreeStreamND[iDim] = config->GetVelocity_FreeStream()[iDim]/Velocity_Ref; config->SetVelocity_FreeStreamND(Velocity_FreeStreamND[iDim], iDim); } @@ -973,36 +971,36 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i Temperature_FreeStreamND = Temperature_FreeStream/config->GetTemperature_Ref(); config->SetTemperature_FreeStreamND(Temperature_FreeStreamND); Gas_ConstantND = config->GetGas_Constant()/Gas_Constant_Ref; config->SetGas_ConstantND(Gas_ConstantND); Specific_Heat_CpND = config->GetSpecific_Heat_Cp()/Gas_Constant_Ref; config->SetSpecific_Heat_CpND(Specific_Heat_CpND); - + /*--- We assume that Cp = Cv for our incompressible fluids. ---*/ Specific_Heat_CvND = config->GetSpecific_Heat_Cp()/Gas_Constant_Ref; config->SetSpecific_Heat_CvND(Specific_Heat_CvND); - + Thermal_Expansion_CoeffND = config->GetThermal_Expansion_Coeff()*config->GetTemperature_Ref(); config->SetThermal_Expansion_CoeffND(Thermal_Expansion_CoeffND); ModVel_FreeStreamND = 0.0; for (iDim = 0; iDim < nDim; iDim++) ModVel_FreeStreamND += Velocity_FreeStreamND[iDim]*Velocity_FreeStreamND[iDim]; ModVel_FreeStreamND = sqrt(ModVel_FreeStreamND); config->SetModVel_FreeStreamND(ModVel_FreeStreamND); - + Viscosity_FreeStreamND = Viscosity_FreeStream / Viscosity_Ref; config->SetViscosity_FreeStreamND(Viscosity_FreeStreamND); - + Tke_FreeStream = 3.0/2.0*(ModVel_FreeStream*ModVel_FreeStream*config->GetTurbulenceIntensity_FreeStream()*config->GetTurbulenceIntensity_FreeStream()); config->SetTke_FreeStream(Tke_FreeStream); - + Tke_FreeStreamND = 3.0/2.0*(ModVel_FreeStreamND*ModVel_FreeStreamND*config->GetTurbulenceIntensity_FreeStream()*config->GetTurbulenceIntensity_FreeStream()); config->SetTke_FreeStreamND(Tke_FreeStreamND); - + Omega_FreeStream = Density_FreeStream*Tke_FreeStream/(Viscosity_FreeStream*config->GetTurb2LamViscRatio_FreeStream()); config->SetOmega_FreeStream(Omega_FreeStream); - + Omega_FreeStreamND = Density_FreeStreamND*Tke_FreeStreamND/(Viscosity_FreeStreamND*config->GetTurb2LamViscRatio_FreeStream()); config->SetOmega_FreeStreamND(Omega_FreeStreamND); - + /*--- Delete the original (dimensional) FluidModel object. No fluid is used for inscompressible cases. ---*/ - + delete FluidModel; switch (config->GetKind_FluidModel()) { - + case CONSTANT_DENSITY: FluidModel = new CConstantDensity(Density_FreeStreamND, Specific_Heat_CpND); FluidModel->SetTDState_T(Temperature_FreeStreamND); @@ -1012,7 +1010,7 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i FluidModel = new CIncIdealGas(Specific_Heat_CpND, Gas_ConstantND, Pressure_ThermodynamicND); FluidModel->SetTDState_T(Temperature_FreeStreamND); break; - + case INC_IDEAL_GAS_POLY: FluidModel = new CIncIdealGasPolynomial(Gas_ConstantND, Pressure_ThermodynamicND); if (viscous) { @@ -1024,57 +1022,57 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i } FluidModel->SetTDState_T(Temperature_FreeStreamND); break; - + } - + Energy_FreeStreamND = FluidModel->GetStaticEnergy() + 0.5*ModVel_FreeStreamND*ModVel_FreeStreamND; - + if (viscous) { - + /*--- Constant viscosity model ---*/ config->SetMu_ConstantND(config->GetMu_Constant()/Viscosity_Ref); - + /*--- Sutherland's model ---*/ - + config->SetMu_RefND(config->GetMu_Ref()/Viscosity_Ref); config->SetMu_SND(config->GetMu_S()/config->GetTemperature_Ref()); config->SetMu_Temperature_RefND(config->GetMu_Temperature_Ref()/config->GetTemperature_Ref()); - + /*--- Viscosity model via polynomial. ---*/ config->SetMu_PolyCoeffND(config->GetMu_PolyCoeff(0)/Viscosity_Ref, 0); for (iVar = 1; iVar < config->GetnPolyCoeffs(); iVar++) config->SetMu_PolyCoeffND(config->GetMu_PolyCoeff(iVar)*pow(Temperature_Ref,iVar)/Viscosity_Ref, iVar); - + /*--- Constant thermal conductivity model ---*/ config->SetKt_ConstantND(config->GetKt_Constant()/Conductivity_Ref); - + /*--- Conductivity model via polynomial. ---*/ config->SetKt_PolyCoeffND(config->GetKt_PolyCoeff(0)/Conductivity_Ref, 0); for (iVar = 1; iVar < config->GetnPolyCoeffs(); iVar++) config->SetKt_PolyCoeffND(config->GetKt_PolyCoeff(iVar)*pow(Temperature_Ref,iVar)/Conductivity_Ref, iVar); - + /*--- Set up the transport property models. ---*/ FluidModel->SetLaminarViscosityModel(config); FluidModel->SetThermalConductivityModel(config); - + } if (tkeNeeded) { Energy_FreeStreamND += Tke_FreeStreamND; }; config->SetEnergy_FreeStreamND(Energy_FreeStreamND); - + Energy_Ref = Energy_FreeStream/Energy_FreeStreamND; config->SetEnergy_Ref(Energy_Ref); - + Total_UnstTimeND = config->GetTotal_UnstTime() / Time_Ref; config->SetTotal_UnstTimeND(Total_UnstTimeND); Delta_UnstTimeND = config->GetDelta_UnstTime() / Time_Ref; config->SetDelta_UnstTimeND(Delta_UnstTimeND); - + /*--- Write output to the console if this is the master node and first domain ---*/ - + if ((rank == MASTER_NODE) && (iMesh == MESH_0)) { - + cout.precision(6); if (config->GetRef_Inc_NonDim() == DIMENSIONAL) { @@ -1088,7 +1086,7 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i cout << "are based on the initial values, p_ref = rho_ref*vel_ref^2." << endl; if (dynamic_grid) cout << "Force coefficients computed using MACH_MOTION." << endl; else cout << "Force coefficients computed using initial values." << endl; - } + } else if (config->GetRef_Inc_NonDim() == REFERENCE_VALUES) { cout << "Incompressible flow: rho_ref, vel_ref, and temp_ref" << endl; cout << "are user-provided reference values, p_ref = rho_ref*vel_ref^2." << endl; @@ -1112,14 +1110,14 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i cout << "Angle of attack (deg): "<< config->GetAoA() << ", computed using the initial velocity." << endl; cout << "Side slip angle (deg): "<< config->GetAoS() << ", computed using the initial velocity." << endl; - if (viscous) { + if (viscous) { cout << "Reynolds number per meter: " << config->GetReynolds() << ", computed using initial values."<< endl; cout << "Reynolds number is a byproduct of inputs only (not used internally)." << endl; } cout << "SI units only. The grid should be dimensional (meters)." << endl; - + switch (config->GetKind_DensityModel()) { - + case CONSTANT: if (energy) cout << "Energy equation is active and decoupled." << endl; else cout << "No energy equation." << endl; @@ -1134,10 +1132,10 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i break; } - + stringstream NonDimTableOut, ModelTableOut; - stringstream Unit; - + stringstream Unit; + cout << endl; PrintingToolbox::CTablePrinter ModelTable(&ModelTableOut); ModelTableOut <<"-- Models:"<< endl; @@ -1147,21 +1145,21 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i ModelTable.AddColumn("Fluid Model", 25); ModelTable.SetAlign(PrintingToolbox::CTablePrinter::RIGHT); ModelTable.PrintHeader(); - - PrintingToolbox::CTablePrinter NonDimTable(&NonDimTableOut); + + PrintingToolbox::CTablePrinter NonDimTable(&NonDimTableOut); NonDimTable.AddColumn("Name", 22); NonDimTable.AddColumn("Dim. value", 14); NonDimTable.AddColumn("Ref. value", 14); NonDimTable.AddColumn("Unit", 10); NonDimTable.AddColumn("Non-dim. value", 14); NonDimTable.SetAlign(PrintingToolbox::CTablePrinter::RIGHT); - + NonDimTableOut <<"-- Fluid properties:"<< endl; - + NonDimTable.PrintHeader(); - + if (viscous){ - + switch(config->GetKind_ViscosityModel()){ case CONSTANT_VISCOSITY: ModelTable << "CONSTANT_VISCOSITY"; @@ -1173,7 +1171,7 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i break; case SUTHERLAND: - ModelTable << "SUTHERLAND"; + ModelTable << "SUTHERLAND"; if (config->GetSystemMeasurements() == SI) Unit << "N.s/m^2"; else if (config->GetSystemMeasurements() == US) Unit << "lbf.s/ft^2"; NonDimTable << "Ref. Viscosity" << config->GetMu_Ref() << config->GetViscosity_Ref() << Unit.str() << config->GetMu_RefND(); @@ -1188,7 +1186,7 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i Unit.str(""); NonDimTable.PrintFooter(); break; - + case POLYNOMIAL_VISCOSITY: ModelTable << "POLYNOMIAL_VISCOSITY"; for (iVar = 0; iVar < config->GetnPolyCoeffs(); iVar++) { @@ -1205,21 +1203,21 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i switch(config->GetKind_ConductivityModel()){ case CONSTANT_PRANDTL: ModelTable << "CONSTANT_PRANDTL"; - NonDimTable << "Prandtl (Lam.)" << "-" << "-" << "-" << config->GetPrandtl_Lam(); + NonDimTable << "Prandtl (Lam.)" << "-" << "-" << "-" << config->GetPrandtl_Lam(); Unit.str(""); - NonDimTable << "Prandtl (Turb.)" << "-" << "-" << "-" << config->GetPrandtl_Turb(); + NonDimTable << "Prandtl (Turb.)" << "-" << "-" << "-" << config->GetPrandtl_Turb(); Unit.str(""); NonDimTable.PrintFooter(); break; - + case CONSTANT_CONDUCTIVITY: ModelTable << "CONSTANT_CONDUCTIVITY"; Unit << "W/m^2.K"; - NonDimTable << "Molecular Cond." << config->GetKt_Constant() << config->GetKt_Constant()/config->GetKt_ConstantND() << Unit.str() << config->GetKt_ConstantND(); + NonDimTable << "Molecular Cond." << config->GetKt_Constant() << config->GetKt_Constant()/config->GetKt_ConstantND() << Unit.str() << config->GetKt_ConstantND(); Unit.str(""); NonDimTable.PrintFooter(); break; - + case POLYNOMIAL_CONDUCTIVITY: ModelTable << "POLYNOMIAL_CONDUCTIVITY"; for (iVar = 0; iVar < config->GetnPolyCoeffs(); iVar++) { @@ -1229,60 +1227,60 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i NonDimTable << "Kt(T) Poly. Coeff. " + ss.str() << config->GetKt_PolyCoeff(iVar) << config->GetKt_PolyCoeff(iVar)/config->GetKt_PolyCoeffND(iVar) << "-" << config->GetKt_PolyCoeffND(iVar); } Unit.str(""); - NonDimTable.PrintFooter(); + NonDimTable.PrintFooter(); break; } } else { ModelTable << "-" << "-"; } - + switch (config->GetKind_FluidModel()){ case CONSTANT_DENSITY: ModelTable << "CONSTANT_DENSITY"; if (energy){ Unit << "N.m/kg.K"; - NonDimTable << "Spec. Heat (Cp)" << config->GetSpecific_Heat_Cp() << config->GetSpecific_Heat_Cp()/config->GetSpecific_Heat_CpND() << Unit.str() << config->GetSpecific_Heat_CpND(); + NonDimTable << "Spec. Heat (Cp)" << config->GetSpecific_Heat_Cp() << config->GetSpecific_Heat_Cp()/config->GetSpecific_Heat_CpND() << Unit.str() << config->GetSpecific_Heat_CpND(); Unit.str(""); } if (boussinesq){ Unit << "K^-1"; - NonDimTable << "Thermal Exp." << config->GetThermal_Expansion_Coeff() << config->GetThermal_Expansion_Coeff()/config->GetThermal_Expansion_CoeffND() << Unit.str() << config->GetThermal_Expansion_CoeffND(); + NonDimTable << "Thermal Exp." << config->GetThermal_Expansion_Coeff() << config->GetThermal_Expansion_Coeff()/config->GetThermal_Expansion_CoeffND() << Unit.str() << config->GetThermal_Expansion_CoeffND(); Unit.str(""); } Unit << "Pa"; - NonDimTable << "Bulk Modulus" << config->GetBulk_Modulus() << 1.0 << Unit.str() << config->GetBulk_Modulus(); + NonDimTable << "Bulk Modulus" << config->GetBulk_Modulus() << 1.0 << Unit.str() << config->GetBulk_Modulus(); Unit.str(""); NonDimTable.PrintFooter(); break; - + case INC_IDEAL_GAS: - ModelTable << "INC_IDEAL_GAS"; + ModelTable << "INC_IDEAL_GAS"; Unit << "N.m/kg.K"; - NonDimTable << "Spec. Heat (Cp)" << config->GetSpecific_Heat_Cp() << config->GetSpecific_Heat_Cp()/config->GetSpecific_Heat_CpND() << Unit.str() << config->GetSpecific_Heat_CpND(); + NonDimTable << "Spec. Heat (Cp)" << config->GetSpecific_Heat_Cp() << config->GetSpecific_Heat_Cp()/config->GetSpecific_Heat_CpND() << Unit.str() << config->GetSpecific_Heat_CpND(); Unit.str(""); Unit << "g/mol"; - NonDimTable << "Molecular weight" << config->GetMolecular_Weight()<< 1.0 << Unit.str() << config->GetMolecular_Weight(); + NonDimTable << "Molecular weight" << config->GetMolecular_Weight()<< 1.0 << Unit.str() << config->GetMolecular_Weight(); Unit.str(""); Unit << "N.m/kg.K"; - NonDimTable << "Gas Constant" << config->GetGas_Constant() << config->GetGas_Constant_Ref() << Unit.str() << config->GetGas_ConstantND(); + NonDimTable << "Gas Constant" << config->GetGas_Constant() << config->GetGas_Constant_Ref() << Unit.str() << config->GetGas_ConstantND(); Unit.str(""); Unit << "Pa"; - NonDimTable << "Therm. Pressure" << config->GetPressure_Thermodynamic() << config->GetPressure_Ref() << Unit.str() << config->GetPressure_ThermodynamicND(); + NonDimTable << "Therm. Pressure" << config->GetPressure_Thermodynamic() << config->GetPressure_Ref() << Unit.str() << config->GetPressure_ThermodynamicND(); Unit.str(""); NonDimTable.PrintFooter(); break; - + case INC_IDEAL_GAS_POLY: - ModelTable << "INC_IDEAL_GAS_POLY"; + ModelTable << "INC_IDEAL_GAS_POLY"; Unit.str(""); Unit << "g/mol"; - NonDimTable << "Molecular weight" << config->GetMolecular_Weight()<< 1.0 << Unit.str() << config->GetMolecular_Weight(); + NonDimTable << "Molecular weight" << config->GetMolecular_Weight()<< 1.0 << Unit.str() << config->GetMolecular_Weight(); Unit.str(""); Unit << "N.m/kg.K"; - NonDimTable << "Gas Constant" << config->GetGas_Constant() << config->GetGas_Constant_Ref() << Unit.str() << config->GetGas_ConstantND(); + NonDimTable << "Gas Constant" << config->GetGas_Constant() << config->GetGas_Constant_Ref() << Unit.str() << config->GetGas_ConstantND(); Unit.str(""); Unit << "Pa"; - NonDimTable << "Therm. Pressure" << config->GetPressure_Thermodynamic() << config->GetPressure_Ref() << Unit.str() << config->GetPressure_ThermodynamicND(); + NonDimTable << "Therm. Pressure" << config->GetPressure_Thermodynamic() << config->GetPressure_Ref() << Unit.str() << config->GetPressure_ThermodynamicND(); Unit.str(""); for (iVar = 0; iVar < config->GetnPolyCoeffs(); iVar++) { stringstream ss; @@ -1293,10 +1291,10 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i Unit.str(""); NonDimTable.PrintFooter(); break; - + } - + NonDimTableOut <<"-- Initial and free-stream conditions:"<< endl; NonDimTable.PrintHeader(); @@ -1306,7 +1304,7 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i Unit.str(""); if (config->GetSystemMeasurements() == SI) Unit << "Pa"; else if (config->GetSystemMeasurements() == US) Unit << "psf"; - NonDimTable << "Total Pressure" << config->GetPressure_FreeStream() + 0.5*config->GetDensity_FreeStream()*config->GetModVel_FreeStream()*config->GetModVel_FreeStream() + NonDimTable << "Total Pressure" << config->GetPressure_FreeStream() + 0.5*config->GetDensity_FreeStream()*config->GetModVel_FreeStream()*config->GetModVel_FreeStream() << config->GetPressure_Ref() << Unit.str() << config->GetPressure_FreeStreamND() + 0.5*config->GetDensity_FreeStreamND()*config->GetModVel_FreeStreamND()*config->GetModVel_FreeStreamND(); Unit.str(""); if (config->GetSystemMeasurements() == SI) Unit << "kg/m^3"; @@ -1350,18 +1348,18 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i Unit.str(""); } } - + NonDimTable.PrintFooter(); NonDimTable << "Mach Number" << "-" << "-" << "-" << config->GetMach(); if (viscous){ - NonDimTable << "Reynolds Number" << "-" << "-" << "-" << config->GetReynolds(); + NonDimTable << "Reynolds Number" << "-" << "-" << "-" << config->GetReynolds(); } - + NonDimTable.PrintFooter(); ModelTable.PrintFooter(); if (unsteady){ - NonDimTableOut << "-- Unsteady conditions" << endl; + NonDimTableOut << "-- Unsteady conditions" << endl; NonDimTable.PrintHeader(); NonDimTable << "Total Time" << config->GetMax_Time() << config->GetTime_Ref() << "s" << config->GetMax_Time()/config->GetTime_Ref(); Unit.str(""); @@ -1369,41 +1367,41 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i Unit.str(""); NonDimTable.PrintFooter(); } - + cout << ModelTableOut.str(); cout << NonDimTableOut.str(); } - - - + + + } void CIncEulerSolver::SetInitialCondition(CGeometry **geometry, CSolver ***solver_container, CConfig *config, unsigned long TimeIter) { - + unsigned long iPoint, Point_Fine; unsigned short iMesh, iChildren, iVar; su2double Area_Children, Area_Parent, *Solution_Fine, *Solution; - + bool restart = (config->GetRestart() || config->GetRestart_Flow()); bool rans = ((config->GetKind_Solver() == INC_RANS) || (config->GetKind_Solver() == DISC_ADJ_INC_RANS)); bool dual_time = ((config->GetTime_Marching() == DT_STEPPING_1ST) || (config->GetTime_Marching() == DT_STEPPING_2ND)); - + /*--- Check if a verification solution is to be computed. ---*/ if ((VerificationSolution) && (TimeIter == 0) && !restart) { - + /*--- Loop over the multigrid levels. ---*/ for (iMesh = 0; iMesh <= config->GetnMGLevels(); iMesh++) { - + /*--- Loop over all grid points. ---*/ for (iPoint = 0; iPoint < geometry[iMesh]->GetnPoint(); iPoint++) { - + /* Set the pointers to the coordinates and solution of this DOF. */ const su2double *coor = geometry[iMesh]->node[iPoint]->GetCoord(); su2double *solDOF = solver_container[iMesh][FLOW_SOL]->GetNodes()->GetSolution(iPoint); - + /* Set the solution in this DOF to the initial condition provided by the verification solution class. This can be the exact solution, but this is not necessary. */ @@ -1411,12 +1409,12 @@ void CIncEulerSolver::SetInitialCondition(CGeometry **geometry, CSolver ***solve } } } - + /*--- If restart solution, then interpolate the flow solution to all the multigrid levels, this is important with the dual time strategy ---*/ - + if (restart && (TimeIter == 0)) { - + Solution = new su2double[nVar]; for (iMesh = 1; iMesh <= config->GetnMGLevels(); iMesh++) { for (iPoint = 0; iPoint < geometry[iMesh]->GetnPoint(); iPoint++) { @@ -1436,11 +1434,11 @@ void CIncEulerSolver::SetInitialCondition(CGeometry **geometry, CSolver ***solve solver_container[iMesh][FLOW_SOL]->CompleteComms(geometry[iMesh], config, SOLUTION); } delete [] Solution; - + /*--- Interpolate the turblence variable also, if needed ---*/ - + if (rans) { - + unsigned short nVar_Turb = solver_container[MESH_0][TURB_SOL]->GetnVar(); Solution = new su2double[nVar_Turb]; for (iMesh = 1; iMesh <= config->GetnMGLevels(); iMesh++) { @@ -1463,16 +1461,16 @@ void CIncEulerSolver::SetInitialCondition(CGeometry **geometry, CSolver ***solve } delete [] Solution; } - + } - + /*--- The value of the solution for the first iteration of the dual time ---*/ - + if (dual_time && (TimeIter == 0 || (restart && (long)TimeIter == (long)config->GetRestart_Iter()))) { - + /*--- Push back the initial condition to previous solution containers for a 1st-order restart or when simply intitializing to freestream. ---*/ - + for (iMesh = 0; iMesh <= config->GetnMGLevels(); iMesh++) { solver_container[iMesh][FLOW_SOL]->GetNodes()->Set_Solution_time_n(); solver_container[iMesh][FLOW_SOL]->GetNodes()->Set_Solution_time_n1(); @@ -1481,20 +1479,20 @@ void CIncEulerSolver::SetInitialCondition(CGeometry **geometry, CSolver ***solve solver_container[iMesh][TURB_SOL]->GetNodes()->Set_Solution_time_n1(); } } - + if ((restart && (long)TimeIter == (long)config->GetRestart_Iter()) && (config->GetTime_Marching() == DT_STEPPING_2ND)) { - + /*--- Load an additional restart file for a 2nd-order restart ---*/ - + solver_container[MESH_0][FLOW_SOL]->LoadRestart(geometry, solver_container, config, SU2_TYPE::Int(config->GetRestart_Iter()-1), true); - + /*--- Load an additional restart file for the turbulence model ---*/ if (rans) solver_container[MESH_0][TURB_SOL]->LoadRestart(geometry, solver_container, config, SU2_TYPE::Int(config->GetRestart_Iter()-1), false); - + /*--- Push back this new solution to time level N. ---*/ - + for (iMesh = 0; iMesh <= config->GetnMGLevels(); iMesh++) { solver_container[iMesh][FLOW_SOL]->GetNodes()->Set_Solution_time_n(); if (rans) { @@ -1506,7 +1504,7 @@ void CIncEulerSolver::SetInitialCondition(CGeometry **geometry, CSolver ***solve } void CIncEulerSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output) { - + unsigned long ErrorCounter = 0; unsigned long InnerIter = config->GetInnerIter(); @@ -1521,32 +1519,32 @@ void CIncEulerSolver::Preprocessing(CGeometry *geometry, CSolver **solver_contai bool outlet = ((config->GetnMarker_Outlet() != 0)); /*--- Set the primitive variables ---*/ - + ErrorCounter = SetPrimitive_Variables(solver_container, config, Output); - + /*--- Upwind second order reconstruction ---*/ - + if ((muscl && !center) && (iMesh == MESH_0) && !Output) { - + /*--- Gradient computation for MUSCL reconstruction. ---*/ - + if (config->GetKind_Gradient_Method_Recon() == GREEN_GAUSS) SetPrimitive_Gradient_GG(geometry, config, true); if (config->GetKind_Gradient_Method_Recon() == LEAST_SQUARES) SetPrimitive_Gradient_LS(geometry, config, true); if (config->GetKind_Gradient_Method_Recon() == WEIGHTED_LEAST_SQUARES) SetPrimitive_Gradient_LS(geometry, config, true); - + /*--- Limiter computation ---*/ - + if ((limiter) && (iMesh == MESH_0) && !Output && !van_albada) { SetPrimitive_Limiter(geometry, config); } - + } - + /*--- Artificial dissipation ---*/ - + if (center && !Output) { SetMax_Eigenvalue(geometry, config); if ((center_jst) && (iMesh == MESH_0)) { @@ -1554,21 +1552,21 @@ void CIncEulerSolver::Preprocessing(CGeometry *geometry, CSolver **solver_contai SetUndivided_Laplacian(geometry, config); } } - + /*--- Update the beta value based on the maximum velocity. ---*/ SetBeta_Parameter(geometry, solver_container, config, iMesh); - + /*--- Compute properties needed for mass flow BCs. ---*/ - + if (outlet) GetOutlet_Properties(geometry, config, iMesh, Output); /*--- Initialize the Jacobian matrices ---*/ - + if (implicit && !disc_adjoint) Jacobian.SetValZero(); /*--- Error message ---*/ - + if (config->GetComm_Level() == COMM_FULL) { #ifdef HAVE_MPI unsigned long MyErrorCounter = ErrorCounter; ErrorCounter = 0; @@ -1576,31 +1574,31 @@ void CIncEulerSolver::Preprocessing(CGeometry *geometry, CSolver **solver_contai #endif if (iMesh == MESH_0) config->SetNonphysical_Points(ErrorCounter); } - + } void CIncEulerSolver::Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh) { } unsigned long CIncEulerSolver::SetPrimitive_Variables(CSolver **solver_container, CConfig *config, bool Output) { - + unsigned long iPoint, nonPhysicalPoints = 0; bool physical = true; - + for (iPoint = 0; iPoint < nPoint; iPoint ++) { /*--- Incompressible flow, primitive variables ---*/ - + physical = nodes->SetPrimVar(iPoint,FluidModel); /* Check for non-realizable states for reporting. */ if (!physical) nonPhysicalPoints++; - + /*--- Initialize the convective, source and viscous residual vector ---*/ - + if (!Output) LinSysRes.SetBlock_Zero(iPoint); - + } return nonPhysicalPoints; @@ -1608,41 +1606,41 @@ unsigned long CIncEulerSolver::SetPrimitive_Variables(CSolver **solver_container void CIncEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned long Iteration) { - + su2double *Normal, Area, Vol, Mean_SoundSpeed = 0.0, Mean_ProjVel = 0.0, Mean_BetaInc2, Lambda, Local_Delta_Time, Global_Delta_Time = 1E6, Global_Delta_UnstTimeND, ProjVel, ProjVel_i, ProjVel_j; - + unsigned long iEdge, iVertex, iPoint, jPoint; unsigned short iDim, iMarker; - + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); bool time_stepping = config->GetTime_Marching() == TIME_STEPPING; bool dual_time = ((config->GetTime_Marching() == DT_STEPPING_1ST) || (config->GetTime_Marching() == DT_STEPPING_2ND)); - + Min_Delta_Time = 1.E30; Max_Delta_Time = 0.0; /*--- Set maximum inviscid eigenvalue to zero, and compute sound speed ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) nodes->SetMax_Lambda_Inv(iPoint,0.0); - + /*--- Loop interior edges ---*/ - + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - + /*--- Point identification, Normal vector and area ---*/ - + iPoint = geometry->edge[iEdge]->GetNode(0); jPoint = geometry->edge[iEdge]->GetNode(1); - + Normal = geometry->edge[iEdge]->GetNormal(); - + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); - + /*--- Mean Values ---*/ Mean_ProjVel = 0.5 * (nodes->GetProjVel(iPoint,Normal) + nodes->GetProjVel(jPoint,Normal)); @@ -1650,7 +1648,7 @@ void CIncEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contain Mean_SoundSpeed = sqrt(Mean_BetaInc2*Area*Area); /*--- Adjustment for grid movement ---*/ - + if (dynamic_grid) { su2double *GridVel_i = geometry->node[iPoint]->GetGridVel(); su2double *GridVel_j = geometry->node[jPoint]->GetGridVel(); @@ -1661,31 +1659,31 @@ void CIncEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contain } Mean_ProjVel -= 0.5 * (ProjVel_i + ProjVel_j); } - + /*--- Inviscid contribution ---*/ - + Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; if (geometry->node[iPoint]->GetDomain()) nodes->AddMax_Lambda_Inv(iPoint,Lambda); if (geometry->node[jPoint]->GetDomain()) nodes->AddMax_Lambda_Inv(jPoint,Lambda); - + } - + /*--- Loop boundary edges ---*/ - + for (iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) != INTERNAL_BOUNDARY) && (config->GetMarker_All_KindBC(iMarker) != PERIODIC_BOUNDARY)) { for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { - + /*--- Point identification, Normal vector and area ---*/ - + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); - + /*--- Mean Values ---*/ Mean_ProjVel = nodes->GetProjVel(iPoint,Normal); @@ -1693,7 +1691,7 @@ void CIncEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contain Mean_SoundSpeed = sqrt(Mean_BetaInc2*Area*Area); /*--- Adjustment for grid movement ---*/ - + if (dynamic_grid) { su2double *GridVel = geometry->node[iPoint]->GetGridVel(); ProjVel = 0.0; @@ -1701,25 +1699,25 @@ void CIncEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contain ProjVel += GridVel[iDim]*Normal[iDim]; Mean_ProjVel -= ProjVel; } - + /*--- Inviscid contribution ---*/ - + Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; if (geometry->node[iPoint]->GetDomain()) { nodes->AddMax_Lambda_Inv(iPoint,Lambda); } - + } } } - - /*--- Local time-stepping: each element uses their own speed for steady state + + /*--- Local time-stepping: each element uses their own speed for steady state simulations or for pseudo time steps in a dual time simulation. ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + Vol = geometry->node[iPoint]->GetVolume(); - + if (Vol != 0.0) { Local_Delta_Time = nodes->GetLocalCFL(iPoint)*Vol / nodes->GetMax_Lambda_Inv(iPoint); Global_Delta_Time = min(Global_Delta_Time, Local_Delta_Time); @@ -1732,11 +1730,11 @@ void CIncEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contain else { nodes->SetDelta_Time(iPoint,0.0); } - + } - + /*--- Compute the max and the min dt (in parallel) ---*/ - + if (config->GetComm_Level() == COMM_FULL) { #ifdef HAVE_MPI su2double rbuf_time, sbuf_time; @@ -1744,16 +1742,16 @@ void CIncEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contain SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, MPI_COMM_WORLD); SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); Min_Delta_Time = rbuf_time; - + sbuf_time = Max_Delta_Time; SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MAX, MASTER_NODE, MPI_COMM_WORLD); SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); Max_Delta_Time = rbuf_time; #endif } - + /*--- For time-accurate simulations use the minimum delta time of the whole mesh (global) ---*/ - + if (time_stepping) { #ifdef HAVE_MPI su2double rbuf_time, sbuf_time; @@ -1765,15 +1763,15 @@ void CIncEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contain /*--- If the unsteady CFL is set to zero, it uses the defined unsteady time step, otherwise it computes the time step based on the unsteady CFL ---*/ - + if (config->GetUnst_CFL() == 0.0) { Global_Delta_Time = config->GetDelta_UnstTime(); } config->SetDelta_UnstTimeND(Global_Delta_Time); for (iPoint = 0; iPoint < nPointDomain; iPoint++){ - + /*--- Sets the regular CFL equal to the unsteady CFL ---*/ - + nodes->SetLocalCFL(iPoint, config->GetUnst_CFL()); nodes->SetDelta_Time(iPoint, Global_Delta_Time); Min_Delta_Time = Global_Delta_Time; @@ -1781,17 +1779,17 @@ void CIncEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contain } } - + /*--- Recompute the unsteady time step for the dual time strategy if the unsteady CFL is diferent from 0 ---*/ - + if ((dual_time) && (Iteration == 0) && (config->GetUnst_CFL() != 0.0) && (iMesh == MESH_0)) { Global_Delta_UnstTimeND = 1e30; for (iPoint = 0; iPoint < nPointDomain; iPoint++){ Global_Delta_UnstTimeND = min(Global_Delta_UnstTimeND,config->GetUnst_CFL()*Global_Delta_Time/nodes->GetLocalCFL(iPoint)); } - + #ifdef HAVE_MPI su2double rbuf_time, sbuf_time; sbuf_time = Global_Delta_UnstTimeND; @@ -1801,9 +1799,9 @@ void CIncEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contain #endif config->SetDelta_UnstTimeND(Global_Delta_UnstTimeND); } - + /*--- The pseudo local time (explicit integration) cannot be greater than the physical time ---*/ - + if (dual_time) for (iPoint = 0; iPoint < nPointDomain; iPoint++) { if (!implicit) { @@ -1811,73 +1809,73 @@ void CIncEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_contain nodes->SetDelta_Time(iPoint,Local_Delta_Time); } } - + } void CIncEulerSolver::Centered_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short iMesh, unsigned short iRKStep) { - + unsigned long iEdge, iPoint, jPoint; - + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); bool jst_scheme = ((config->GetKind_Centered_Flow() == JST) && (iMesh == MESH_0)); - + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - + /*--- Points in edge, set normal vectors, and number of neighbors ---*/ - + iPoint = geometry->edge[iEdge]->GetNode(0); jPoint = geometry->edge[iEdge]->GetNode(1); numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); numerics->SetNeighbor(geometry->node[iPoint]->GetnNeighbor(), geometry->node[jPoint]->GetnNeighbor()); - + /*--- Set primitive variables w/o reconstruction ---*/ - + numerics->SetPrimitive(nodes->GetPrimitive(iPoint), nodes->GetPrimitive(jPoint)); - + /*--- Set the largest convective eigenvalue ---*/ - + numerics->SetLambda(nodes->GetLambda(iPoint), nodes->GetLambda(jPoint)); - + /*--- Set undivided laplacian and pressure-based sensor ---*/ - + if (jst_scheme) { numerics->SetUndivided_Laplacian(nodes->GetUndivided_Laplacian(iPoint), nodes->GetUndivided_Laplacian(jPoint)); numerics->SetSensor(nodes->GetSensor(iPoint), nodes->GetSensor(jPoint)); } - + /*--- Grid movement ---*/ - + if (dynamic_grid) { numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[jPoint]->GetGridVel()); } - + /*--- Compute residuals, and Jacobians ---*/ numerics->ComputeResidual(Res_Conv, Jacobian_i, Jacobian_j, config); - + /*--- Update convective and artificial dissipation residuals ---*/ LinSysRes.AddBlock(iPoint, Res_Conv); LinSysRes.SubtractBlock(jPoint, Res_Conv); - + /*--- Store implicit contributions from the residual calculation. ---*/ - + if (implicit) { Jacobian.UpdateBlocks(iEdge, iPoint, jPoint, Jacobian_i, Jacobian_j); } } - + } void CIncEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short iMesh) { - + su2double **Gradient_i, **Gradient_j, Project_Grad_i, Project_Grad_j, *V_i, *V_j, *S_i, *S_j, *Limiter_i = NULL, *Limiter_j = NULL; - + unsigned long iEdge, iPoint, jPoint, counter_local = 0, counter_global = 0; unsigned short iDim, iVar; - + unsigned long InnerIter = config->GetInnerIter(); bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); bool muscl = (config->GetMUSCL_Flow() && (iMesh == MESH_0)); @@ -1885,33 +1883,33 @@ void CIncEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_cont bool van_albada = config->GetKind_SlopeLimit_Flow() == VAN_ALBADA_EDGE; /*--- Loop over all the edges ---*/ - + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - + /*--- Points in edge and normal vectors ---*/ - + iPoint = geometry->edge[iEdge]->GetNode(0); jPoint = geometry->edge[iEdge]->GetNode(1); numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); - + /*--- Grid movement ---*/ - + if (dynamic_grid) numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[jPoint]->GetGridVel()); - + /*--- Get primitive variables ---*/ - + V_i = nodes->GetPrimitive(iPoint); V_j = nodes->GetPrimitive(jPoint); S_i = nodes->GetSecondary(iPoint); S_j = nodes->GetSecondary(jPoint); /*--- High order reconstruction using MUSCL strategy ---*/ - + if (muscl) { - + for (iDim = 0; iDim < nDim; iDim++) { Vector_i[iDim] = 0.5*(geometry->node[jPoint]->GetCoord(iDim) - geometry->node[iPoint]->GetCoord(iDim)); Vector_j[iDim] = 0.5*(geometry->node[iPoint]->GetCoord(iDim) - geometry->node[jPoint]->GetCoord(iDim)); } - + Gradient_i = nodes->GetGradient_Reconstruction(iPoint); Gradient_j = nodes->GetGradient_Reconstruction(jPoint); @@ -1919,7 +1917,7 @@ void CIncEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_cont Limiter_i = nodes->GetLimiter_Primitive(iPoint); Limiter_j = nodes->GetLimiter_Primitive(jPoint); } - + for (iVar = 0; iVar < nPrimVarGrad; iVar++) { Project_Grad_i = 0.0; Project_Grad_j = 0.0; for (iDim = 0; iDim < nDim; iDim++) { @@ -1951,29 +1949,29 @@ void CIncEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_cont during the start-up of a calculation or difficult transients. For incompressible flow, only the temperature and density need to be checked. Pressure is the dynamic pressure (can be negative). ---*/ - + if (config->GetEnergy_Equation()) { bool neg_temperature_i = (Primitive_i[nDim+1] < 0.0); bool neg_temperature_j = (Primitive_j[nDim+1] < 0.0); - + bool neg_density_i = (Primitive_i[nDim+2] < 0.0); bool neg_density_j = (Primitive_j[nDim+2] < 0.0); - + if (neg_density_i || neg_temperature_i) { nodes->SetNon_Physical(iPoint, true); } else { nodes->SetNon_Physical(iPoint, false); } - + if (neg_density_j || neg_temperature_j) { nodes->SetNon_Physical(jPoint, true); } else { nodes->SetNon_Physical(jPoint, false); } - + /* Lastly, check for existing first-order points still active from previous iterations. */ - + if (nodes->GetNon_Physical(iPoint)) { counter_local++; for (iVar = 0; iVar < nPrimVar; iVar++) @@ -1985,36 +1983,36 @@ void CIncEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_cont Primitive_j[iVar] = V_j[iVar]; } } - + numerics->SetPrimitive(Primitive_i, Primitive_j); - + } else { - + /*--- Set conservative variables without reconstruction ---*/ - + numerics->SetPrimitive(V_i, V_j); numerics->SetSecondary(S_i, S_j); - + } - + /*--- Compute the residual ---*/ - + numerics->ComputeResidual(Res_Conv, Jacobian_i, Jacobian_j, config); /*--- Update residual value ---*/ - + LinSysRes.AddBlock(iPoint, Res_Conv); LinSysRes.SubtractBlock(jPoint, Res_Conv); - + /*--- Set implicit Jacobians ---*/ - + if (implicit) { Jacobian.UpdateBlocks(iEdge, iPoint, jPoint, Jacobian_i, Jacobian_j); } } - + /*--- Warning message about non-physical reconstructions. ---*/ - + if (config->GetComm_Level() == COMM_FULL) { #ifdef HAVE_MPI SU2_MPI::Reduce(&counter_local, &counter_global, 1, MPI_UNSIGNED_LONG, MPI_SUM, MASTER_NODE, MPI_COMM_WORLD); @@ -2023,14 +2021,14 @@ void CIncEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_cont #endif if (iMesh == MESH_0) config->SetNonphysical_Reconstr(counter_global); } - + } void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CNumerics *second_numerics, CConfig *config, unsigned short iMesh) { - + unsigned short iVar; unsigned long iPoint; - + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); bool rotating_frame = config->GetRotating_Frame(); bool axisymmetric = config->GetAxisymmetric(); @@ -2055,7 +2053,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont nodes->GetSolution(iPoint)); /*--- Set incompressible density ---*/ - + numerics->SetDensity(nodes->GetDensity(iPoint), nodes->GetDensity(iPoint)); @@ -2068,9 +2066,9 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont numerics->ComputeResidual(Residual, config); /*--- Add the source residual to the total ---*/ - + LinSysRes.AddBlock(iPoint, Residual); - + } } @@ -2086,7 +2084,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont nodes->GetSolution(iPoint)); /*--- Set incompressible density ---*/ - + numerics->SetDensity(nodes->GetDensity(iPoint), nodes->GetDensity(iPoint)); @@ -2099,9 +2097,9 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont numerics->ComputeResidual(Residual, config); /*--- Add the source residual to the total ---*/ - + LinSysRes.AddBlock(iPoint, Residual); - + } } @@ -2110,11 +2108,11 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont /*--- Loop over all points ---*/ for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /*--- Load the conservative variables ---*/ - + numerics->SetConservative(nodes->GetSolution(iPoint), NULL); - + /*--- Set incompressible density ---*/ numerics->SetDensity(nodes->GetDensity(iPoint), 0.0); @@ -2139,7 +2137,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont } if (axisymmetric) { - + /*--- Zero out Jacobian structure ---*/ if (implicit) { @@ -2181,28 +2179,28 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) { SetAuxVar_Gradient_LS(geometry, config); } - + } - + /*--- loop over points ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /*--- Conservative variables w/o reconstruction ---*/ numerics->SetPrimitive(nodes->GetPrimitive(iPoint), NULL); /*--- Set incompressible density ---*/ - + numerics->SetDensity(nodes->GetDensity(iPoint), nodes->GetDensity(iPoint)); /*--- Set control volume ---*/ - + numerics->SetVolume(geometry->node[iPoint]->GetVolume()); - + /*--- Set y coordinate ---*/ - + numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[iPoint]->GetCoord()); @@ -2217,102 +2215,102 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont /*--- Load the aux variable gradient that we already computed. ---*/ numerics->SetAuxVarGrad(nodes->GetAuxVarGradient(iPoint), NULL); - + } /*--- Compute Source term Residual ---*/ - + numerics->ComputeResidual(Residual, Jacobian_i, config); - + /*--- Add Residual ---*/ - + LinSysRes.AddBlock(iPoint, Residual); - + /*--- Implicit part ---*/ - + if (implicit) Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - + } } - + /*--- Check if a verification solution is to be computed. ---*/ - + if (VerificationSolution) { if ( VerificationSolution->IsManufacturedSolution() ) { - + /*--- Get the physical time. ---*/ su2double time = 0.0; if (config->GetTime_Marching()) time = config->GetPhysicalTime(); - + /*--- Loop over points ---*/ for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /*--- Get control volume size. ---*/ su2double Volume = geometry->node[iPoint]->GetVolume(); - + /*--- Get the current point coordinates. ---*/ const su2double *coor = geometry->node[iPoint]->GetCoord(); - + /*--- Get the MMS source term. ---*/ vector sourceMan(nVar,0.0); VerificationSolution->GetMMSSourceTerm(coor, time, sourceMan.data()); - + /*--- Compute the residual for this control volume. ---*/ for (iVar = 0; iVar < nVar; iVar++) { Residual[iVar] = sourceMan[iVar]*Volume; } - + /*--- Subtract Residual ---*/ LinSysRes.SubtractBlock(iPoint, Residual); - + } } } - + } void CIncEulerSolver::Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short iMesh) { - + /* This method should be used to call any new source terms for a particular problem*/ /* This method calls the new child class in CNumerics, where the new source term should be implemented. */ - + /* Next we describe how to get access to some important quanties for this method */ /* Access to all points in the current geometric mesh by saying: nPointDomain */ /* Get the vector of conservative variables at some point iPoint = nodes->GetSolution(iPoint) */ /* Get the volume (or area in 2D) associated with iPoint = nodes->GetVolume(iPoint) */ /* Get the vector of geometric coordinates of point iPoint = nodes->GetCoord(iPoint) */ - + } void CIncEulerSolver::SetMax_Eigenvalue(CGeometry *geometry, CConfig *config) { - + su2double *Normal, Area, Mean_SoundSpeed = 0.0, Mean_ProjVel = 0.0, Mean_BetaInc2, Lambda, ProjVel, ProjVel_i, ProjVel_j, *GridVel, *GridVel_i, *GridVel_j; - + unsigned long iEdge, iVertex, iPoint, jPoint; unsigned short iDim, iMarker; /*--- Set maximum inviscid eigenvalue to zero, and compute sound speed ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { nodes->SetLambda(iPoint,0.0); } - + /*--- Loop interior edges ---*/ - + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - + /*--- Point identification, Normal vector and area ---*/ - + iPoint = geometry->edge[iEdge]->GetNode(0); jPoint = geometry->edge[iEdge]->GetNode(1); - + Normal = geometry->edge[iEdge]->GetNormal(); Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); - + /*--- Mean Values ---*/ Mean_ProjVel = 0.5 * (nodes->GetProjVel(iPoint,Normal) + nodes->GetProjVel(jPoint,Normal)); @@ -2320,7 +2318,7 @@ void CIncEulerSolver::SetMax_Eigenvalue(CGeometry *geometry, CConfig *config) { Mean_SoundSpeed = sqrt(Mean_BetaInc2*Area*Area); /*--- Adjustment for grid movement ---*/ - + if (dynamic_grid) { GridVel_i = geometry->node[iPoint]->GetGridVel(); GridVel_j = geometry->node[jPoint]->GetGridVel(); @@ -2331,38 +2329,38 @@ void CIncEulerSolver::SetMax_Eigenvalue(CGeometry *geometry, CConfig *config) { } Mean_ProjVel -= 0.5 * (ProjVel_i + ProjVel_j); } - + /*--- Inviscid contribution ---*/ - + Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; if (geometry->node[iPoint]->GetDomain()) nodes->AddLambda(iPoint,Lambda); if (geometry->node[jPoint]->GetDomain()) nodes->AddLambda(jPoint,Lambda); - + } - + /*--- Loop boundary edges ---*/ - + for (iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) != INTERNAL_BOUNDARY) && (config->GetMarker_All_KindBC(iMarker) != PERIODIC_BOUNDARY)) { for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { - + /*--- Point identification, Normal vector and area ---*/ - + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); - + /*--- Mean Values ---*/ - + Mean_ProjVel = nodes->GetProjVel(iPoint,Normal); Mean_BetaInc2 = nodes->GetBetaInc2(iPoint); Mean_SoundSpeed = sqrt(Mean_BetaInc2*Area*Area); - + /*--- Adjustment for grid movement ---*/ - + if (dynamic_grid) { GridVel = geometry->node[iPoint]->GetGridVel(); ProjVel = 0.0; @@ -2370,111 +2368,111 @@ void CIncEulerSolver::SetMax_Eigenvalue(CGeometry *geometry, CConfig *config) { ProjVel += GridVel[iDim]*Normal[iDim]; Mean_ProjVel -= ProjVel; } - + /*--- Inviscid contribution ---*/ - + Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; if (geometry->node[iPoint]->GetDomain()) { nodes->AddLambda(iPoint,Lambda); } - + } } } - + /*--- Correct the eigenvalue values across any periodic boundaries. ---*/ for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_MAX_EIG); CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_MAX_EIG); } - + /*--- MPI parallelization ---*/ - + InitiateComms(geometry, config, MAX_EIGENVALUE); CompleteComms(geometry, config, MAX_EIGENVALUE); - + } void CIncEulerSolver::SetUndivided_Laplacian(CGeometry *geometry, CConfig *config) { - + unsigned long iPoint, jPoint, iEdge; su2double *Diff; unsigned short iVar; bool boundary_i, boundary_j; - + Diff = new su2double[nVar]; - + nodes->SetUnd_LaplZero(); - + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - + iPoint = geometry->edge[iEdge]->GetNode(0); jPoint = geometry->edge[iEdge]->GetNode(1); - + /*--- Solution differences ---*/ - + for (iVar = 0; iVar < nVar; iVar++) Diff[iVar] = nodes->GetSolution(iPoint,iVar) - nodes->GetSolution(jPoint,iVar); - + boundary_i = geometry->node[iPoint]->GetPhysicalBoundary(); boundary_j = geometry->node[jPoint]->GetPhysicalBoundary(); - + /*--- Both points inside the domain, or both in the boundary ---*/ - + if ((!boundary_i && !boundary_j) || (boundary_i && boundary_j)) { if (geometry->node[iPoint]->GetDomain()) nodes->SubtractUnd_Lapl(iPoint,Diff); if (geometry->node[jPoint]->GetDomain()) nodes->AddUnd_Lapl(jPoint,Diff); } - + /*--- iPoint inside the domain, jPoint on the boundary ---*/ - + if (!boundary_i && boundary_j) if (geometry->node[iPoint]->GetDomain()) nodes->SubtractUnd_Lapl(iPoint,Diff); - + /*--- jPoint inside the domain, iPoint on the boundary ---*/ - + if (boundary_i && !boundary_j) if (geometry->node[jPoint]->GetDomain()) nodes->AddUnd_Lapl(jPoint,Diff); - + } - + /*--- Correct the Laplacian values across any periodic boundaries. ---*/ for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_LAPLACIAN); CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_LAPLACIAN); } - + /*--- MPI parallelization ---*/ - + InitiateComms(geometry, config, UNDIVIDED_LAPLACIAN); CompleteComms(geometry, config, UNDIVIDED_LAPLACIAN); - + delete [] Diff; - + } void CIncEulerSolver::SetCentered_Dissipation_Sensor(CGeometry *geometry, CConfig *config) { - + unsigned long iEdge, iPoint, jPoint; su2double Pressure_i = 0.0, Pressure_j = 0.0; bool boundary_i, boundary_j; - + /*--- Reset variables to store the undivided pressure ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { iPoint_UndLapl[iPoint] = 0.0; jPoint_UndLapl[iPoint] = 0.0; } - + /*--- Evaluate the pressure sensor ---*/ - + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - + iPoint = geometry->edge[iEdge]->GetNode(0); jPoint = geometry->edge[iEdge]->GetNode(1); - + /*--- Get the pressure, or density for incompressible solvers ---*/ Pressure_i = nodes->GetDensity(iPoint); @@ -2482,58 +2480,58 @@ void CIncEulerSolver::SetCentered_Dissipation_Sensor(CGeometry *geometry, CConfi boundary_i = geometry->node[iPoint]->GetPhysicalBoundary(); boundary_j = geometry->node[jPoint]->GetPhysicalBoundary(); - + /*--- Both points inside the domain, or both on the boundary ---*/ - + if ((!boundary_i && !boundary_j) || (boundary_i && boundary_j)) { - + if (geometry->node[iPoint]->GetDomain()) { iPoint_UndLapl[iPoint] += (Pressure_j - Pressure_i); jPoint_UndLapl[iPoint] += (Pressure_i + Pressure_j); } - + if (geometry->node[jPoint]->GetDomain()) { iPoint_UndLapl[jPoint] += (Pressure_i - Pressure_j); jPoint_UndLapl[jPoint] += (Pressure_i + Pressure_j); } - + } - + /*--- iPoint inside the domain, jPoint on the boundary ---*/ - + if (!boundary_i && boundary_j) if (geometry->node[iPoint]->GetDomain()) { iPoint_UndLapl[iPoint] += (Pressure_j - Pressure_i); jPoint_UndLapl[iPoint] += (Pressure_i + Pressure_j); } - + /*--- jPoint inside the domain, iPoint on the boundary ---*/ - + if (boundary_i && !boundary_j) if (geometry->node[jPoint]->GetDomain()) { iPoint_UndLapl[jPoint] += (Pressure_i - Pressure_j); jPoint_UndLapl[jPoint] += (Pressure_i + Pressure_j); } - + } - + /*--- Correct the sensor values across any periodic boundaries. ---*/ for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_SENSOR); CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_SENSOR); } - + /*--- Set pressure switch for each point ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) nodes->SetSensor(iPoint,fabs(iPoint_UndLapl[iPoint]) / jPoint_UndLapl[iPoint]); - + /*--- MPI parallelization ---*/ - + InitiateComms(geometry, config, SENSOR); CompleteComms(geometry, config, SENSOR); - + } void CIncEulerSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { @@ -2570,7 +2568,7 @@ void CIncEulerSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { on user-provided reference values, use the ref values to compute the forces. ---*/ - if ((config->GetRef_Inc_NonDim() == DIMENSIONAL) || + if ((config->GetRef_Inc_NonDim() == DIMENSIONAL) || (config->GetRef_Inc_NonDim() == INITIAL_VALUES)) { RefDensity = Density_Inf; RefVel2 = 0.0; @@ -2612,7 +2610,7 @@ void CIncEulerSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { Surface_CFx_Inv[iMarker_Monitoring] = 0.0; Surface_CFy_Inv[iMarker_Monitoring] = 0.0; Surface_CFz_Inv[iMarker_Monitoring] = 0.0; Surface_CMx_Inv[iMarker_Monitoring] = 0.0; Surface_CMy_Inv[iMarker_Monitoring] = 0.0; Surface_CMz_Inv[iMarker_Monitoring] = 0.0; - + Surface_CL[iMarker_Monitoring] = 0.0; Surface_CD[iMarker_Monitoring] = 0.0; Surface_CSF[iMarker_Monitoring] = 0.0; Surface_CEff[iMarker_Monitoring] = 0.0; Surface_CFx[iMarker_Monitoring] = 0.0; Surface_CFy[iMarker_Monitoring] = 0.0; @@ -2831,7 +2829,7 @@ void CIncEulerSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { SU2_MPI::Allreduce(&MyAllBound_CQ_Inv, &AllBound_CQ_Inv, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); AllBound_CMerit_Inv = AllBound_CT_Inv / (AllBound_CQ_Inv + EPS); } - + /*--- Add the forces on the surfaces using all the nodes ---*/ MySurface_CL_Inv = new su2double[config->GetnMarker_Monitoring()]; @@ -2882,7 +2880,7 @@ void CIncEulerSolver::Pressure_Forces(CGeometry *geometry, CConfig *config) { SU2_MPI::Allreduce(MySurface_CMy_Inv, Surface_CMy_Inv, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); SU2_MPI::Allreduce(MySurface_CMz_Inv, Surface_CMz_Inv, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); } - + delete [] MySurface_CL_Inv; delete [] MySurface_CD_Inv; delete [] MySurface_CSF_Inv; delete [] MySurface_CEff_Inv; delete [] MySurface_CFx_Inv; delete [] MySurface_CFy_Inv; delete [] MySurface_CFz_Inv; delete [] MySurface_CMx_Inv; delete [] MySurface_CMy_Inv; @@ -2965,7 +2963,7 @@ void CIncEulerSolver::Momentum_Forces(CGeometry *geometry, CConfig *config) { on user-provided reference values, use the ref values to compute the forces. ---*/ - if ((config->GetRef_Inc_NonDim() == DIMENSIONAL) || + if ((config->GetRef_Inc_NonDim() == DIMENSIONAL) || (config->GetRef_Inc_NonDim() == INITIAL_VALUES)) { RefDensity = Density_Inf; RefVel2 = 0.0; @@ -3210,7 +3208,7 @@ void CIncEulerSolver::Momentum_Forces(CGeometry *geometry, CConfig *config) { SU2_MPI::Allreduce(&MyAllBound_CQ_Mnt, &AllBound_CQ_Mnt, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); AllBound_CMerit_Mnt = AllBound_CT_Mnt / (AllBound_CQ_Mnt + EPS); } - + /*--- Add the forces on the surfaces using all the nodes ---*/ MySurface_CL_Mnt = new su2double[config->GetnMarker_Monitoring()]; @@ -3261,7 +3259,7 @@ void CIncEulerSolver::Momentum_Forces(CGeometry *geometry, CConfig *config) { SU2_MPI::Allreduce(MySurface_CMy_Mnt, Surface_CMy_Mnt, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); SU2_MPI::Allreduce(MySurface_CMz_Mnt, Surface_CMz_Mnt, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); } - + delete [] MySurface_CL_Mnt; delete [] MySurface_CD_Mnt; delete [] MySurface_CSF_Mnt; delete [] MySurface_CEff_Mnt; delete [] MySurface_CFx_Mnt; delete [] MySurface_CFy_Mnt; delete [] MySurface_CFz_Mnt; @@ -3307,21 +3305,21 @@ void CIncEulerSolver::Momentum_Forces(CGeometry *geometry, CConfig *config) { void CIncEulerSolver::ExplicitRK_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iRKStep) { - + su2double *Residual, *Res_TruncError, Vol, Delta, Res; unsigned short iVar, jVar; unsigned long iPoint; - + su2double RK_AlphaCoeff = config->Get_Alpha_RKStep(iRKStep); bool adjoint = config->GetContinuous_Adjoint(); - + for (iVar = 0; iVar < nVar; iVar++) { SetRes_RMS(iVar, 0.0); SetRes_Max(iVar, 0.0, 0); } - + /*--- Update the solution ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { Vol = (geometry->node[iPoint]->GetVolume() + geometry->node[iPoint]->GetPeriodicVolume()); @@ -3342,42 +3340,42 @@ void CIncEulerSolver::ExplicitRK_Iteration(CGeometry *geometry, CSolver **solver } } } - + /*--- MPI solution ---*/ - + InitiateComms(geometry, config, SOLUTION); CompleteComms(geometry, config, SOLUTION); - + /*--- Compute the root mean square residual ---*/ - + SetResidual_RMS(geometry, config); - + /*--- For verification cases, compute the global error metrics. ---*/ - + ComputeVerificationError(geometry, config); - + } void CIncEulerSolver::ExplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { - + su2double *local_Residual, *local_Res_TruncError, Vol, Delta, Res; unsigned short iVar, jVar; unsigned long iPoint; - + bool adjoint = config->GetContinuous_Adjoint(); - + for (iVar = 0; iVar < nVar; iVar++) { SetRes_RMS(iVar, 0.0); SetRes_Max(iVar, 0.0, 0); } - + /*--- Update the solution ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { Vol = (geometry->node[iPoint]->GetVolume() + geometry->node[iPoint]->GetPeriodicVolume()); Delta = nodes->GetDelta_Time(iPoint) / Vol; - + local_Res_TruncError = nodes->GetResTruncError(iPoint); local_Residual = LinSysRes.GetBlock(iPoint); @@ -3394,52 +3392,52 @@ void CIncEulerSolver::ExplicitEuler_Iteration(CGeometry *geometry, CSolver **sol } } } - + /*--- MPI solution ---*/ - + InitiateComms(geometry, config, SOLUTION); CompleteComms(geometry, config, SOLUTION); - + /*--- Compute the root mean square residual ---*/ - + SetResidual_RMS(geometry, config); - + /*--- For verification cases, compute the global error metrics. ---*/ - + ComputeVerificationError(geometry, config); - + } void CIncEulerSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { - + unsigned short iVar, jVar; unsigned long iPoint, total_index, IterLinSol = 0; su2double Delta, *local_Res_TruncError, Vol; - + bool adjoint = config->GetContinuous_Adjoint(); - + /*--- Set maximum residual to zero ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { SetRes_RMS(iVar, 0.0); SetRes_Max(iVar, 0.0, 0); } - + /*--- Build implicit system ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /*--- Read the residual ---*/ - + local_Res_TruncError = nodes->GetResTruncError(iPoint); - + /*--- Read the volume ---*/ - + Vol = (geometry->node[iPoint]->GetVolume() + geometry->node[iPoint]->GetPeriodicVolume()); - + /*--- Apply the preconditioner and add to the diagonal. ---*/ - + if (nodes->GetDelta_Time(iPoint) != 0.0) { Delta = Vol / nodes->GetDelta_Time(iPoint); SetPreconditioner(config, iPoint); @@ -3459,7 +3457,7 @@ void CIncEulerSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **sol } /*--- Right hand side of the system (-Residual) and initial guess (x = 0) ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { total_index = iPoint*nVar + iVar; LinSysRes[total_index] = - (LinSysRes[total_index] + local_Res_TruncError[iVar]); @@ -3467,11 +3465,11 @@ void CIncEulerSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **sol AddRes_RMS(iVar, LinSysRes[total_index]*LinSysRes[total_index]); AddRes_Max(iVar, fabs(LinSysRes[total_index]), geometry->node[iPoint]->GetGlobalIndex(), geometry->node[iPoint]->GetCoord()); } - + } - + /*--- Initialize residual and solution at the ghost points ---*/ - + for (iPoint = nPointDomain; iPoint < nPoint; iPoint++) { for (iVar = 0; iVar < nVar; iVar++) { total_index = iPoint*nVar + iVar; @@ -3479,21 +3477,21 @@ void CIncEulerSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **sol LinSysSol[total_index] = 0.0; } } - + /*--- Solve or smooth the linear system ---*/ - + IterLinSol = System.Solve(Jacobian, LinSysRes, LinSysSol, geometry, config); - + /*--- Store the value of the residual. ---*/ - + SetResLinSolver(System.GetResidual()); - + /*--- The the number of iterations of the linear solver ---*/ - + SetIterLinSolver(IterLinSol); - + /*--- Update solution (system written in terms of increments) ---*/ - + if (!adjoint) { for (iPoint = 0; iPoint < nPointDomain; iPoint++) { for (iVar = 0; iVar < nVar; iVar++) { @@ -3501,42 +3499,42 @@ void CIncEulerSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **sol } } } - + for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_IMPLICIT); CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_IMPLICIT); } - + /*--- MPI solution ---*/ - + InitiateComms(geometry, config, SOLUTION); CompleteComms(geometry, config, SOLUTION); - + /*--- Compute the root mean square residual ---*/ - + SetResidual_RMS(geometry, config); - + /*--- For verification cases, compute the global error metrics. ---*/ ComputeVerificationError(geometry, config); - + } void CIncEulerSolver::ComputeUnderRelaxationFactor(CSolver **solver_container, CConfig *config) { - + /* Loop over the solution update given by relaxing the linear system for this nonlinear iteration. */ - + su2double localUnderRelaxation = 1.0; const su2double allowableRatio = 0.2; for (unsigned long iPoint = 0; iPoint < nPointDomain; iPoint++) { - + localUnderRelaxation = 1.0; for (unsigned short iVar = 0; iVar < nVar; iVar++) { - + /* We impose a limit on the maximum percentage that the temperature can change over a nonlinear iteration. */ - + if ((config->GetEnergy_Equation() && (iVar == nVar-1))) { const unsigned long index = iPoint*nVar + iVar; su2double ratio = fabs(LinSysSol[index])/(nodes->GetSolution(iPoint, iVar)+EPS); @@ -3545,25 +3543,25 @@ void CIncEulerSolver::ComputeUnderRelaxationFactor(CSolver **solver_container, C } } } - + /* In case of turbulence, take the min of the under-relaxation factor between the mean flow and the turb model. */ - + if (config->GetKind_Turb_Model() != NONE) localUnderRelaxation = min(localUnderRelaxation, solver_container[TURB_SOL]->GetNodes()->GetUnderRelaxation(iPoint)); - + /* Threshold the relaxation factor in the event that there is a very small value. This helps avoid catastrophic crashes due to non-realizable states by canceling the update. */ - + if (localUnderRelaxation < 1e-10) localUnderRelaxation = 0.0; - + /* Store the under-relaxation factor for this point. */ - + nodes->SetUnderRelaxation(iPoint, localUnderRelaxation); - + } - + } void CIncEulerSolver::SetPrimitive_Gradient_GG(CGeometry *geometry, CConfig *config, bool reconstruction) { @@ -3610,25 +3608,25 @@ void CIncEulerSolver::SetPrimitive_Limiter(CGeometry *geometry, CConfig *config) void CIncEulerSolver::SetInletAtVertex(su2double *val_inlet, unsigned short iMarker, unsigned long iVertex) { - + /*--- Alias positions within inlet file for readability ---*/ - + unsigned short T_position = nDim; unsigned short P_position = nDim+1; unsigned short FlowDir_position = nDim+2; - + /*--- Check that the norm of the flow unit vector is actually 1 ---*/ - + su2double norm = 0.0; for (unsigned short iDim = 0; iDim < nDim; iDim++) { norm += pow(val_inlet[FlowDir_position + iDim], 2); } norm = sqrt(norm); - + /*--- The tolerance here needs to be loose. When adding a very * small number (1e-10 or smaller) to a number close to 1.0, floating * point roundoff errors can occur. ---*/ - + if (abs(norm - 1.0) > 1e-6) { ostringstream error_msg; error_msg << "ERROR: Found these values in columns "; @@ -3643,15 +3641,15 @@ void CIncEulerSolver::SetInletAtVertex(su2double *val_inlet, error_msg << " but their magnitude is: " << norm << endl; SU2_MPI::Error(error_msg.str(), CURRENT_FUNCTION); } - + /*--- Store the values in our inlet data structures. ---*/ - + Inlet_Ttotal[iMarker][iVertex] = val_inlet[T_position]; Inlet_Ptotal[iMarker][iVertex] = val_inlet[P_position]; for (unsigned short iDim = 0; iDim < nDim; iDim++) { Inlet_FlowDir[iMarker][iVertex][iDim] = val_inlet[FlowDir_position + iDim]; } - + } su2double CIncEulerSolver::GetInletAtVertex(su2double *val_inlet, @@ -3659,87 +3657,87 @@ su2double CIncEulerSolver::GetInletAtVertex(su2double *val_inlet, unsigned short val_kind_marker, string val_marker, CGeometry *geometry, - CConfig *config) { - + CConfig *config) const { + /*--- Local variables ---*/ - + unsigned short iMarker, iDim; unsigned long iPoint, iVertex; su2double Area = 0.0; su2double Normal[3] = {0.0,0.0,0.0}; - + /*--- Alias positions within inlet file for readability ---*/ - + unsigned short T_position = nDim; unsigned short P_position = nDim+1; unsigned short FlowDir_position = nDim+2; - + if (val_kind_marker == INLET_FLOW) { - + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) == INLET_FLOW) && (config->GetMarker_All_TagBound(iMarker) == val_marker)) { - + for (iVertex = 0; iVertex < nVertex[iMarker]; iVertex++){ - + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - + if (iPoint == val_inlet_point) { - + /*-- Compute boundary face area for this vertex. ---*/ - + geometry->vertex[iMarker][iVertex]->GetNormal(Normal); Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); - + /*--- Access and store the inlet variables for this vertex. ---*/ - + val_inlet[T_position] = Inlet_Ttotal[iMarker][iVertex]; val_inlet[P_position] = Inlet_Ptotal[iMarker][iVertex]; for (iDim = 0; iDim < nDim; iDim++) { val_inlet[FlowDir_position + iDim] = Inlet_FlowDir[iMarker][iVertex][iDim]; } - + /*--- Exit once we find the point. ---*/ - + return Area; - + } } } } } - + /*--- If we don't find a match, then the child point is not on the current inlet boundary marker. Return zero area so this point does not contribute to the restriction operator and continue. ---*/ - + return Area; - + } void CIncEulerSolver::SetUniformInlet(CConfig* config, unsigned short iMarker) { - + if (config->GetMarker_All_KindBC(iMarker) == INLET_FLOW) { - + string Marker_Tag = config->GetMarker_All_TagBound(iMarker); su2double p_total = config->GetInlet_Ptotal(Marker_Tag); su2double t_total = config->GetInlet_Ttotal(Marker_Tag); su2double* flow_dir = config->GetInlet_FlowDir(Marker_Tag); - + for(unsigned long iVertex=0; iVertex < nVertex[iMarker]; iVertex++){ Inlet_Ttotal[iMarker][iVertex] = t_total; Inlet_Ptotal[iMarker][iVertex] = p_total; for (unsigned short iDim = 0; iDim < nDim; iDim++) Inlet_FlowDir[iMarker][iVertex][iDim] = flow_dir[iDim]; } - + } else { - + /*--- For now, non-inlets just get set to zero. In the future, we can do more customization for other boundary types here. ---*/ - + for(unsigned long iVertex=0; iVertex < nVertex[iMarker]; iVertex++){ Inlet_Ttotal[iMarker][iVertex] = 0.0; Inlet_Ptotal[iMarker][iVertex] = 0.0; @@ -3747,7 +3745,7 @@ void CIncEulerSolver::SetUniformInlet(CConfig* config, unsigned short iMarker) { Inlet_FlowDir[iMarker][iVertex][iDim] = 0.0; } } - + } void CIncEulerSolver::Evaluate_ObjFunc(CConfig *config) { @@ -3756,14 +3754,14 @@ void CIncEulerSolver::Evaluate_ObjFunc(CConfig *config) { su2double Weight_ObjFunc; Total_ComboObj = 0.0; - + /*--- Loop over all monitored markers, add to the 'combo' objective ---*/ for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { Weight_ObjFunc = config->GetWeight_ObjFunc(iMarker_Monitoring); Kind_ObjFunc = config->GetKind_ObjFunc(iMarker_Monitoring); - + switch(Kind_ObjFunc) { case DRAG_COEFFICIENT: Total_ComboObj+=Weight_ObjFunc*(Surface_CD[iMarker_Monitoring]); @@ -3806,15 +3804,15 @@ void CIncEulerSolver::Evaluate_ObjFunc(CConfig *config) { } } - + /*--- The following are not per-surface, and so to avoid that they are double-counted when multiple surfaces are specified, they have been placed outside of the loop above. In addition, multi-objective mode is also disabled for these objective functions (error thrown at start). ---*/ - + Weight_ObjFunc = config->GetWeight_ObjFunc(0); Kind_ObjFunc = config->GetKind_ObjFunc(0); - + switch(Kind_ObjFunc) { case INVERSE_DESIGN_PRESSURE: Total_ComboObj+=Weight_ObjFunc*Total_CpDiff; @@ -3861,12 +3859,12 @@ void CIncEulerSolver::Evaluate_ObjFunc(CConfig *config) { default: break; } - + } void CIncEulerSolver::SetBeta_Parameter(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh) { - + su2double epsilon2 = config->GetBeta_Factor(); su2double epsilon2_default = 4.1; su2double maxVel2 = 0.0; @@ -3875,28 +3873,28 @@ void CIncEulerSolver::SetBeta_Parameter(CGeometry *geometry, CSolver **solver_co unsigned long iPoint; /*--- For now, only the finest mesh level stores the Beta for all levels. ---*/ - + if (iMesh == MESH_0) { - + for (iPoint = 0; iPoint < nPoint; iPoint++) { - + /*--- Store the local maximum of the squared velocity in the field. ---*/ - + if (nodes->GetVelocity2(iPoint) > maxVel2) maxVel2 = nodes->GetVelocity2(iPoint); - + } - + /*--- Communicate the max globally to give a conservative estimate. ---*/ - + #ifdef HAVE_MPI su2double myMaxVel2 = maxVel2; maxVel2 = 0.0; SU2_MPI::Allreduce(&myMaxVel2, &maxVel2, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); #endif - + Beta = max(1e-10,maxVel2); config->SetMax_Vel2(Beta); - + } /*--- Allow an override if user supplies a large epsilon^2. ---*/ @@ -4001,49 +3999,49 @@ void CIncEulerSolver::SetPreconditioner(CConfig *config, unsigned long iPoint) { if (energy) Preconditioner[nDim+1][nDim+1] = oneOverCp/Density; else Preconditioner[nDim+1][nDim+1] = 0.0; - + } - + } void CIncEulerSolver::BC_Far_Field(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + unsigned short iDim; unsigned long iVertex, iPoint, Point_Normal; - + su2double *V_infty, *V_domain; - + bool implicit = config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT; bool viscous = config->GetViscous(); - + su2double *Normal = new su2double[nDim]; /*--- Loop over all the vertices on this boundary marker ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); /*--- Allocate the value at the infinity ---*/ V_infty = GetCharacPrimVar(val_marker, iVertex); - + /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ - + if (geometry->node[iPoint]->GetDomain()) { - + /*--- Index of the closest interior node ---*/ - + Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); - + /*--- Normal vector for this vertex (negate for outward convention) ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); - + /*--- Retrieve solution at the farfield boundary node ---*/ - + V_domain = nodes->GetPrimitive(iPoint); /*--- Recompute and store the velocity in the primitive variable vector. ---*/ @@ -4072,30 +4070,30 @@ void CIncEulerSolver::BC_Far_Field(CGeometry *geometry, CSolver **solver_contain V_infty[nDim+7] = nodes->GetSpecificHeatCp(iPoint); /*--- Set various quantities in the numerics class ---*/ - + conv_numerics->SetPrimitive(V_domain, V_infty); - + if (dynamic_grid) conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); - + /*--- Compute the convective residual using an upwind scheme ---*/ - + conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - + /*--- Update residual value ---*/ LinSysRes.AddBlock(iPoint, Residual); - + /*--- Convective Jacobian contribution for implicit integration ---*/ - + if (implicit) Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - + /*--- Viscous residual contribution ---*/ - + if (viscous) { - + /*--- Set transport properties at infinity. ---*/ V_infty[nDim+4] = nodes->GetLaminarViscosity(iPoint); @@ -4103,42 +4101,42 @@ void CIncEulerSolver::BC_Far_Field(CGeometry *geometry, CSolver **solver_contain V_infty[nDim+6] = nodes->GetThermalConductivity(iPoint); /*--- Set the normal vector and the coordinates ---*/ - + visc_numerics->SetNormal(Normal); visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[Point_Normal]->GetCoord()); - + /*--- Primitive variables, and gradient ---*/ - + visc_numerics->SetPrimitive(V_domain, V_infty); visc_numerics->SetPrimVarGradient(nodes->GetGradient_Primitive(iPoint), nodes->GetGradient_Primitive(iPoint)); - + /*--- Turbulent kinetic energy ---*/ - + if ((config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST)) visc_numerics->SetTurbKineticEnergy(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0), solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0)); - + /*--- Compute and update viscous residual ---*/ visc_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); LinSysRes.SubtractBlock(iPoint, Residual); - + /*--- Viscous Jacobian contribution for implicit integration ---*/ - + if (implicit) Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - + } - + } } - + /*--- Free locally allocated memory ---*/ - + delete [] Normal; - + } void CIncEulerSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, @@ -4162,151 +4160,151 @@ void CIncEulerSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, su2double *Normal = new su2double[nDim]; /*--- Loop over all the vertices on this boundary marker ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + /*--- Allocate the value at the inlet ---*/ - + V_inlet = GetCharacPrimVar(val_marker, iVertex); - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check if the node belongs to the domain (i.e., not a halo node) ---*/ - + if (geometry->node[iPoint]->GetDomain()) { /*--- Index of the closest interior node ---*/ Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); - + /*--- Normal vector for this vertex (negate for outward convention) ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); - + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt (Area); - + /*--- Both types of inlets may use the prescribed flow direction. Ensure that the flow direction is a unit vector. ---*/ - + Flow_Dir = Inlet_FlowDir[val_marker][iVertex]; Flow_Dir_Mag = 0.0; for (iDim = 0; iDim < nDim; iDim++) Flow_Dir_Mag += Flow_Dir[iDim]*Flow_Dir[iDim]; Flow_Dir_Mag = sqrt(Flow_Dir_Mag); - + /*--- Store the unit flow direction vector. ---*/ - + for (iDim = 0; iDim < nDim; iDim++) UnitFlowDir[iDim] = Flow_Dir[iDim]/Flow_Dir_Mag; /*--- Retrieve solution at this boundary node. ---*/ - + V_domain = nodes->GetPrimitive(iPoint); /*--- Neumann condition for dynamic pressure ---*/ - + V_inlet[0] = nodes->GetPressure(iPoint); - + /*--- The velocity is either prescribed or computed from total pressure. ---*/ switch (Kind_Inlet) { - + /*--- Velocity and temperature (if required) been specified at the inlet. ---*/ - + case VELOCITY_INLET: - + /*--- Retrieve the specified velocity and temperature for the inlet. ---*/ - + Vel_Mag = Inlet_Ptotal[val_marker][iVertex]/config->GetVelocity_Ref(); - + /*--- Store the velocity in the primitive variable vector. ---*/ - + for (iDim = 0; iDim < nDim; iDim++) V_inlet[iDim+1] = Vel_Mag*UnitFlowDir[iDim]; - + /*--- Dirichlet condition for temperature (if energy is active) ---*/ - + V_inlet[nDim+1] = Inlet_Ttotal[val_marker][iVertex]/config->GetTemperature_Ref(); - + break; - + /*--- Stagnation pressure has been specified at the inlet. ---*/ - + case PRESSURE_INLET: - + /*--- Retrieve the specified total pressure for the inlet. ---*/ - + P_total = Inlet_Ptotal[val_marker][iVertex]/config->GetPressure_Ref(); - + /*--- Store the current static pressure for clarity. ---*/ - + P_domain = nodes->GetPressure(iPoint); - + /*--- Check for back flow through the inlet. ---*/ - + Vn = 0.0; for (iDim = 0; iDim < nDim; iDim++) { Vn += V_domain[iDim+1]*(-1.0*Normal[iDim]/Area); } - + /*--- If the local static pressure is larger than the specified total pressure or the velocity is directed upstream, we have a back flow situation. The specified total pressure should be used as a static pressure condition and the velocity from the domain is used for the BC. ---*/ - + if ((P_domain > P_total) || (Vn < 0.0)) { - + /*--- Back flow: use the prescribed P_total as static pressure. ---*/ - + V_inlet[0] = Inlet_Ptotal[val_marker][iVertex]/config->GetPressure_Ref(); - + /*--- Neumann condition for velocity. ---*/ - + for (iDim = 0; iDim < nDim; iDim++) V_inlet[iDim+1] = V_domain[iDim+1]; - + /*--- Neumann condition for the temperature. ---*/ - + V_inlet[nDim+1] = nodes->GetTemperature(iPoint); - + } else { - + /*--- Update the velocity magnitude using the total pressure. ---*/ - + Vel_Mag = sqrt((P_total - P_domain)/(0.5*nodes->GetDensity(iPoint))); - + /*--- If requested, use the local boundary normal (negative), instead of the prescribed flow direction in the config. ---*/ - + if (config->GetInc_Inlet_UseNormal()) { for (iDim = 0; iDim < nDim; iDim++) UnitFlowDir[iDim] = -Normal[iDim]/Area; } - + /*--- Compute the delta change in velocity in each direction. ---*/ - + for (iDim = 0; iDim < nDim; iDim++) dV[iDim] = Vel_Mag*UnitFlowDir[iDim] - V_domain[iDim+1]; - + /*--- Update the velocity in the primitive variable vector. Note we use damping here to improve stability/convergence. ---*/ - + for (iDim = 0; iDim < nDim; iDim++) V_inlet[iDim+1] = V_domain[iDim+1] + Damping*dV[iDim]; - + /*--- Dirichlet condition for temperature (if energy is active) ---*/ - + V_inlet[nDim+1] = Inlet_Ttotal[val_marker][iVertex]/config->GetTemperature_Ref(); - + } - + break; - + } /*--- Access density at the node. This is either constant by @@ -4324,74 +4322,74 @@ void CIncEulerSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, V_inlet[nDim+7] = nodes->GetSpecificHeatCp(iPoint); /*--- Set various quantities in the solver class ---*/ - + conv_numerics->SetPrimitive(V_domain, V_inlet); - + if (dynamic_grid) conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); - + /*--- Compute the residual using an upwind scheme ---*/ - + conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - + /*--- Update residual value ---*/ - + LinSysRes.AddBlock(iPoint, Residual); - + /*--- Jacobian contribution for implicit integration ---*/ - + if (implicit) Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); /*--- Viscous contribution, commented out because serious convergence problems ---*/ if (viscous) { - + /*--- Set transport properties at the inlet ---*/ - + V_inlet[nDim+4] = nodes->GetLaminarViscosity(iPoint); V_inlet[nDim+5] = nodes->GetEddyViscosity(iPoint); V_inlet[nDim+6] = nodes->GetThermalConductivity(iPoint); /*--- Set the normal vector and the coordinates ---*/ - + visc_numerics->SetNormal(Normal); visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[Point_Normal]->GetCoord()); - + /*--- Primitive variables, and gradient ---*/ - + visc_numerics->SetPrimitive(V_domain, V_inlet); visc_numerics->SetPrimVarGradient(nodes->GetGradient_Primitive(iPoint), nodes->GetGradient_Primitive(iPoint)); - + /*--- Turbulent kinetic energy ---*/ - + if ((config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST)) visc_numerics->SetTurbKineticEnergy(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0), solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0)); - + /*--- Compute and update residual ---*/ - + visc_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - + LinSysRes.SubtractBlock(iPoint, Residual); - + /*--- Jacobian contribution for implicit integration ---*/ - + if (implicit) Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - + } } } - + /*--- Free locally allocated memory ---*/ - + delete [] Normal; - + } void CIncEulerSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, @@ -4408,82 +4406,82 @@ void CIncEulerSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, string Marker_Tag = config->GetMarker_All_TagBound(val_marker); su2double *Normal = new su2double[nDim]; - + unsigned short Kind_Outlet = config->GetKind_Inc_Outlet(Marker_Tag); - + /*--- Loop over all the vertices on this boundary marker ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + /*--- Allocate the value at the outlet ---*/ - + V_outlet = GetCharacPrimVar(val_marker, iVertex); - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check if the node belongs to the domain (i.e., not a halo node) ---*/ - + if (geometry->node[iPoint]->GetDomain()) { - + /*--- Index of the closest interior node ---*/ - + Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); - + /*--- Normal vector for this vertex (negate for outward convention) ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); - + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt (Area); - + /*--- Current solution at this boundary node ---*/ - + V_domain = nodes->GetPrimitive(iPoint); - + /*--- Store the current static pressure for clarity. ---*/ - + P_domain = nodes->GetPressure(iPoint); - + /*--- Compute a boundary value for the pressure depending on whether we are prescribing a back pressure or a mass flow target. ---*/ - + switch (Kind_Outlet) { - + /*--- Velocity and temperature (if required) been specified at the inlet. ---*/ - + case PRESSURE_OUTLET: - + /*--- Retrieve the specified back pressure for this outlet. ---*/ - + P_Outlet = config->GetOutlet_Pressure(Marker_Tag)/config->GetPressure_Ref(); - + /*--- The pressure is prescribed at the outlet. ---*/ - + V_outlet[0] = P_Outlet; - + /*--- Neumann condition for the velocity. ---*/ - + for (iDim = 0; iDim < nDim; iDim++) { V_outlet[iDim+1] = nodes->GetVelocity(iPoint,iDim); } - + break; - + /*--- A mass flow target has been specified for the outlet. ---*/ - + case MASS_FLOW_OUTLET: - + /*--- Retrieve the specified target mass flow at the outlet. ---*/ - + mDot_Target = config->GetOutlet_Pressure(Marker_Tag)/(config->GetDensity_Ref() * config->GetVelocity_Ref()); /*--- Retrieve the old mass flow, density, and area of the outlet, which has been computed in a preprocessing step. These values were stored in non-dim. form in the config container. ---*/ - + mDot_Old = config->GetOutlet_MassFlow(Marker_Tag); Density_Avg = config->GetOutlet_Density(Marker_Tag); Area_Outlet = config->GetOutlet_Area(Marker_Tag); @@ -4491,28 +4489,28 @@ void CIncEulerSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, /*--- Compute the pressure increment based on the difference between the current and target mass flow. Note that increasing pressure decreases flow speed. ---*/ - + dP = 0.5*Density_Avg*(mDot_Old*mDot_Old - mDot_Target*mDot_Target)/((Density_Avg*Area_Outlet)*(Density_Avg*Area_Outlet)); - + /*--- Update the new outlet pressure. Note that we use damping here to improve stability/convergence. ---*/ - + P_Outlet = P_domain + Damping*dP; /*--- The pressure is prescribed at the outlet. ---*/ - + V_outlet[0] = P_Outlet; - + /*--- Neumann condition for the velocity ---*/ - + for (iDim = 0; iDim < nDim; iDim++) { V_outlet[iDim+1] = nodes->GetVelocity(iPoint,iDim); } - + break; - + } - + /*--- Neumann condition for the temperature. ---*/ V_outlet[nDim+1] = nodes->GetTemperature(iPoint); @@ -4520,11 +4518,11 @@ void CIncEulerSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, /*--- Access density at the interior node. This is either constant by construction, or will be set fixed implicitly by the temperature and equation of state. ---*/ - + V_outlet[nDim+2] = nodes->GetDensity(iPoint); /*--- Beta coefficient from the config file ---*/ - + V_outlet[nDim+3] = nodes->GetBetaInc2(iPoint); /*--- Cp is needed for Temperature equation. ---*/ @@ -4534,25 +4532,25 @@ void CIncEulerSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, /*--- Set various quantities in the solver class ---*/ conv_numerics->SetPrimitive(V_domain, V_outlet); - + if (dynamic_grid) conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); - + /*--- Compute the residual using an upwind scheme ---*/ - + conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - + /*--- Update residual value ---*/ - + LinSysRes.AddBlock(iPoint, Residual); - + /*--- Jacobian contribution for implicit integration ---*/ - + if (implicit) { Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); } - + /*--- Viscous contribution, commented out because serious convergence problems ---*/ if (viscous) { @@ -4564,41 +4562,41 @@ void CIncEulerSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, V_outlet[nDim+6] = nodes->GetThermalConductivity(iPoint); /*--- Set the normal vector and the coordinates ---*/ - + visc_numerics->SetNormal(Normal); visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[Point_Normal]->GetCoord()); - + /*--- Primitive variables, and gradient ---*/ - + visc_numerics->SetPrimitive(V_domain, V_outlet); visc_numerics->SetPrimVarGradient(nodes->GetGradient_Primitive(iPoint), nodes->GetGradient_Primitive(iPoint)); - + /*--- Turbulent kinetic energy ---*/ - + if ((config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST)) visc_numerics->SetTurbKineticEnergy(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0), solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0)); - + /*--- Compute and update residual ---*/ - + visc_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - + LinSysRes.SubtractBlock(iPoint, Residual); - + /*--- Jacobian contribution for implicit integration ---*/ if (implicit) Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - + } } } - + /*--- Free locally allocated memory ---*/ delete [] Normal; - + } @@ -4621,16 +4619,16 @@ void CIncEulerSolver::BC_Sym_Plane(CGeometry *geometry, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + unsigned short iDim, iVar; unsigned long iVertex, iPoint; - + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT), viscous = config->GetViscous(); - + /*--- Allocation of variables necessary for convective fluxes. ---*/ su2double Area, ProjVelocity_i, - *V_reflected, + *V_reflected, *V_domain, *Normal = new su2double[nDim], *UnitNormal = new su2double[nDim]; @@ -4648,8 +4646,8 @@ void CIncEulerSolver::BC_Sym_Plane(CGeometry *geometry, /*--- Loop over all the vertices on this boundary marker. ---*/ for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - - if (iVertex == 0 || + + if (iVertex == 0 || geometry->bound_is_straight[val_marker] != true) { /*----------------------------------------------------------------------------------------------*/ @@ -4666,11 +4664,11 @@ void CIncEulerSolver::BC_Sym_Plane(CGeometry *geometry, /*----------------------------------------------------------------------------------------------*/ /*--- Normal vector for a random vertex (zero) on this marker (negate for outward convention). ---*/ - geometry->vertex[val_marker][iVertex]->GetNormal(Normal); + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; - /*--- Compute unit normal, to be used for unit tangential, projected velocity and velocity + /*--- Compute unit normal, to be used for unit tangential, projected velocity and velocity component gradients. ---*/ Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) @@ -4680,7 +4678,7 @@ void CIncEulerSolver::BC_Sym_Plane(CGeometry *geometry, for (iDim = 0; iDim < nDim; iDim++) UnitNormal[iDim] = -Normal[iDim]/Area; - /*--- Preprocessing: Compute unit tangential, the direction is arbitrary as long as + /*--- Preprocessing: Compute unit tangential, the direction is arbitrary as long as t*n=0 && |t|_2 = 1 ---*/ if (viscous) { switch( nDim ) { @@ -4712,9 +4710,9 @@ void CIncEulerSolver::BC_Sym_Plane(CGeometry *geometry, }// switch }//if viscous }//if bound_is_straight - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check if the node belongs to the domain (i.e., not a halo node) ---*/ if (geometry->node[iPoint]->GetDomain()) { @@ -4731,18 +4729,18 @@ void CIncEulerSolver::BC_Sym_Plane(CGeometry *geometry, /*--- Grid movement ---*/ if (dynamic_grid) conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); - + /*--- Normal vector for this vertex (negate for outward convention). ---*/ geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); - + /*--- Get current solution at this boundary node ---*/ V_domain = nodes->GetPrimitive(iPoint); - - /*--- Set the reflected state based on the boundary node. Scalars are copied and - the velocity is mirrored along the symmetry boundary, i.e. the velocity in + + /*--- Set the reflected state based on the boundary node. Scalars are copied and + the velocity is mirrored along the symmetry boundary, i.e. the velocity in normal direction is substracted twice. ---*/ for(iVar = 0; iVar < nPrimVar; iVar++) V_reflected[iVar] = nodes->GetPrimitive(iPoint,iVar); @@ -4750,25 +4748,25 @@ void CIncEulerSolver::BC_Sym_Plane(CGeometry *geometry, /*--- Compute velocity in normal direction (ProjVelcity_i=(v*n)) und substract twice from velocity in normal direction: v_r = v - 2 (v*n)n ---*/ ProjVelocity_i = nodes->GetProjVel(iPoint,UnitNormal); - + for (iDim = 0; iDim < nDim; iDim++) V_reflected[iDim+1] = nodes->GetVelocity(iPoint,iDim) - 2.0 * ProjVelocity_i*UnitNormal[iDim]; - + /*--- Set Primitive and Secondary for numerics class. ---*/ conv_numerics->SetPrimitive(V_domain, V_reflected); conv_numerics->SetSecondary(nodes->GetSecondary(iPoint), nodes->GetSecondary(iPoint)); /*--- Compute the residual using an upwind scheme. ---*/ conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - + /*--- Update residual value ---*/ LinSysRes.AddBlock(iPoint, Residual); - + /*--- Jacobian contribution for implicit integration. ---*/ if (implicit) { Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); } - + if (viscous) { /*-------------------------------------------------------------------------------*/ @@ -4781,27 +4779,27 @@ void CIncEulerSolver::BC_Sym_Plane(CGeometry *geometry, /*-------------------------------------------------------------------------------*/ /*--- Set the normal vector and the coordinates. ---*/ - visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), + visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[iPoint]->GetCoord()); visc_numerics->SetNormal(Normal); - + /*--- Set the primitive and Secondary variables. ---*/ visc_numerics->SetPrimitive(V_domain, V_reflected); visc_numerics->SetSecondary(nodes->GetSecondary(iPoint), nodes->GetSecondary(iPoint)); - + /*--- For viscous Fluxes also the gradients of the primitives need to be determined. 1. The gradients of scalars are mirrored along the sym plane just as velocity for the primitives 2. The gradients of the velocity components need more attention, i.e. the gradient of the - normal velocity in tangential direction is mirrored and the gradient of the tangential velocity in + normal velocity in tangential direction is mirrored and the gradient of the tangential velocity in normal direction is mirrored. ---*/ /*--- Get gradients of primitives of boundary cell ---*/ for (iVar = 0; iVar < nPrimVarGrad; iVar++) for (iDim = 0; iDim < nDim; iDim++) Grad_Reflected[iVar][iDim] = nodes->GetGradient_Primitive(iPoint,iVar, iDim); - + /*--- Reflect the gradients for all scalars including the velocity components. - The gradients of the velocity components are set later with the + The gradients of the velocity components are set later with the correct values: grad(V)_r = grad(V) - 2 [grad(V)*n]n, V beeing any primitive ---*/ for (iVar = 0; iVar < nPrimVarGrad; iVar++) { if(iVar == 0 || iVar > nDim) { // Exclude velocity component gradients @@ -4810,12 +4808,12 @@ void CIncEulerSolver::BC_Sym_Plane(CGeometry *geometry, ProjGradient = 0.0; for (iDim = 0; iDim < nDim; iDim++) ProjGradient += Grad_Reflected[iVar][iDim]*UnitNormal[iDim]; - - for (iDim = 0; iDim < nDim; iDim++) + + for (iDim = 0; iDim < nDim; iDim++) Grad_Reflected[iVar][iDim] = Grad_Reflected[iVar][iDim] - 2.0 * ProjGradient*UnitNormal[iDim]; } } - + /*--- Compute gradients of normal and tangential velocity: grad(v*n) = grad(v_x) n_x + grad(v_y) n_y (+ grad(v_z) n_z) grad(v*t) = grad(v_x) t_x + grad(v_y) t_y (+ grad(v_z) t_z) ---*/ @@ -4838,12 +4836,12 @@ void CIncEulerSolver::BC_Sym_Plane(CGeometry *geometry, ProjNormVelGrad += GradNormVel[iDim]*Tangential[iDim]; //grad([v*n])*t ProjTangVelGrad += GradTangVel[iDim]*UnitNormal[iDim]; //grad([v*t])*n } - + for (iDim = 0; iDim < nDim; iDim++) { GradNormVel[iDim] = GradNormVel[iDim] - 2.0 * ProjNormVelGrad * Tangential[iDim]; GradTangVel[iDim] = GradTangVel[iDim] - 2.0 * ProjTangVelGrad * UnitNormal[iDim]; } - + /*--- Transfer reflected gradients back into the Cartesian Coordinate system: grad(v_x)_r = grad(v*n)_r n_x + grad(v*t)_r t_x grad(v_y)_r = grad(v*n)_r n_y + grad(v*t)_r t_y @@ -4851,28 +4849,28 @@ void CIncEulerSolver::BC_Sym_Plane(CGeometry *geometry, for (iVar = 0; iVar < nDim; iVar++) // loops over the velocity component gradients for (iDim = 0; iDim < nDim; iDim++) // loops over the entries of the above Grad_Reflected[iVar+1][iDim] = GradNormVel[iDim]*UnitNormal[iVar] + GradTangVel[iDim]*Tangential[iVar]; - + /*--- Set the primitive gradients of the boundary and reflected state. ---*/ visc_numerics->SetPrimVarGradient(nodes->GetGradient_Primitive(iPoint), Grad_Reflected); - + /*--- Turbulent kinetic energy. ---*/ if ((config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST)) visc_numerics->SetTurbKineticEnergy(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0), solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0)); - - /*--- Compute and update residual. Note that the viscous shear stress tensor is computed in the + + /*--- Compute and update residual. Note that the viscous shear stress tensor is computed in the following routine based upon the velocity-component gradients. ---*/ visc_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - + LinSysRes.SubtractBlock(iPoint, Residual); - + /*--- Jacobian contribution for implicit integration. ---*/ if (implicit) Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); }//if viscous }//if GetDomain }//for iVertex - + /*--- Free locally allocated memory ---*/ delete [] Normal; delete [] UnitNormal; @@ -4888,20 +4886,20 @@ void CIncEulerSolver::BC_Sym_Plane(CGeometry *geometry, void CIncEulerSolver::BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config) { - + unsigned long iVertex, jVertex, iPoint, Point_Normal = 0; unsigned short iDim, iVar, iMarker, nDonorVertex; - + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); bool viscous = config->GetViscous(); - + su2double *Normal = new su2double[nDim]; su2double *PrimVar_i = new su2double[nPrimVar]; su2double *PrimVar_j = new su2double[nPrimVar]; su2double *tmp_residual = new su2double[nVar]; - + su2double weight; - + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { if (config->GetMarker_All_KindBC(iMarker) == FLUID_INTERFACE) { @@ -4912,7 +4910,7 @@ void CIncEulerSolver::BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_c if (geometry->node[iPoint]->GetDomain()) { nDonorVertex = GetnSlidingStates(iMarker, iVertex); - + /*--- Initialize Residual, this will serve to accumulate the average ---*/ for (iVar = 0; iVar < nVar; iVar++) @@ -4928,7 +4926,7 @@ void CIncEulerSolver::BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_c PrimVar_i[iVar] = nodes->GetPrimitive(iPoint,iVar); PrimVar_j[iVar] = GetSlidingState(iMarker, iVertex, iVar, jVertex); } - + /*--- Get the weight computed in the interpolator class for the j-th donor vertex ---*/ weight = GetSlidingState(iMarker, iVertex, nPrimVar, jVertex); @@ -4936,52 +4934,52 @@ void CIncEulerSolver::BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_c /*--- Set primitive variables ---*/ conv_numerics->SetPrimitive( PrimVar_i, PrimVar_j ); - + /*--- Set the normal vector ---*/ - + geometry->vertex[iMarker][iVertex]->GetNormal(Normal); - for (iDim = 0; iDim < nDim; iDim++) + for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); if (dynamic_grid) conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); - + /*--- Compute the convective residual using an upwind scheme ---*/ conv_numerics->ComputeResidual(tmp_residual, Jacobian_i, Jacobian_j, config); /*--- Accumulate the residuals to compute the average ---*/ - + for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] += weight*tmp_residual[iVar]; } /*--- Add Residuals and Jacobians ---*/ - + LinSysRes.AddBlock(iPoint, Residual); - if (implicit) + if (implicit) Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); if (viscous) { - + /*--- Initialize Residual, this will serve to accumulate the average ---*/ - + for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = 0.0; - + /*--- Loop over the nDonorVertexes and compute the averaged flux ---*/ - + for (jVertex = 0; jVertex < nDonorVertex; jVertex++){ - PrimVar_j[nDim+5] = GetSlidingState(iMarker, iVertex, nDim+5, jVertex); - PrimVar_j[nDim+6] = GetSlidingState(iMarker, iVertex, nDim+6, jVertex); + PrimVar_j[nDim+5] = GetSlidingState(iMarker, iVertex, nDim+5, jVertex); + PrimVar_j[nDim+6] = GetSlidingState(iMarker, iVertex, nDim+6, jVertex); /*--- Get the weight computed in the interpolator class for the j-th donor vertex ---*/ - + weight = GetSlidingState(iMarker, iVertex, nPrimVar, jVertex); - + /*--- Set the normal vector and the coordinates ---*/ visc_numerics->SetNormal(Normal); @@ -4998,26 +4996,26 @@ void CIncEulerSolver::BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_c visc_numerics->SetTurbKineticEnergy(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0), solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0)); /*--- Set the wall shear stress values (wall functions) to -1 (no evaluation using wall functions) ---*/ - + visc_numerics->SetTauWall(-1.0, -1.0); /*--- Compute and update residual ---*/ visc_numerics->ComputeResidual(tmp_residual, Jacobian_i, Jacobian_j, config); - + /*--- Accumulate the residuals to compute the average ---*/ - + for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] += weight*tmp_residual[iVar]; } - + LinSysRes.SubtractBlock(iPoint, Residual); - + /*--- Jacobian contribution for implicit integration ---*/ if (implicit) Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - + } } } @@ -5030,23 +5028,23 @@ void CIncEulerSolver::BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_c delete [] Normal; delete [] PrimVar_i; delete [] PrimVar_j; - + } void CIncEulerSolver::BC_Periodic(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config) { - + /*--- Complete residuals for periodic boundary conditions. We loop over the periodic BCs in matching pairs so that, in the event that there are adjacent periodic markers, the repeated points will have their residuals accumulated correctly during the communications. For implicit calculations, the Jacobians and linear system are also correctly adjusted here. ---*/ - + for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_RESIDUAL); CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_RESIDUAL); } - + } void CIncEulerSolver::BC_Custom(CGeometry *geometry, @@ -5055,102 +5053,102 @@ void CIncEulerSolver::BC_Custom(CGeometry *geometry, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + /* Check for a verification solution. */ - + if (VerificationSolution) { - + unsigned short iVar; unsigned long iVertex, iPoint, total_index; - + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); - + /*--- Get the physical time. ---*/ - + su2double time = 0.0; if (config->GetTime_Marching()) time = config->GetPhysicalTime(); - + /*--- Loop over all the vertices on this boundary marker ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + /*--- Get the point index for the current node. ---*/ - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ - + if (geometry->node[iPoint]->GetDomain()) { - + /*--- Get the coordinates for the current node. ---*/ - + const su2double *coor = geometry->node[iPoint]->GetCoord(); - + /*--- Get the conservative state from the verification solution. ---*/ - + VerificationSolution->GetBCState(coor, time, Solution); - + /*--- For verification cases, we will apply a strong Dirichlet condition by setting the solution values at the boundary nodes directly and setting the residual to zero at those nodes. ---*/ - + nodes->SetSolution_Old(iPoint,Solution); nodes->SetSolution(iPoint,Solution); nodes->SetRes_TruncErrorZero(iPoint); LinSysRes.SetBlock_Zero(iPoint); - + /*--- Adjust rows of the Jacobian (includes 1 in the diagonal) ---*/ - + if (implicit){ for (iVar = 0; iVar < nVar; iVar++) { total_index = iPoint*nVar+iVar; Jacobian.DeleteValsRowi(total_index); } } - + } } - + } else { - + /* The user must specify the custom BC's here. */ SU2_MPI::Error("Implement customized boundary conditions here.", CURRENT_FUNCTION); - + } - + } void CIncEulerSolver::SetResidual_DualTime(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iRKStep, unsigned short iMesh, unsigned short RunTime_EqSystem) { - + /*--- Local variables ---*/ - + unsigned short iVar, jVar, iMarker, iDim; unsigned long iPoint, jPoint, iEdge, iVertex; - + su2double Density, Cp; su2double *V_time_nM1, *V_time_n, *V_time_nP1; su2double U_time_nM1[5], U_time_n[5], U_time_nP1[5]; su2double Volume_nM1, Volume_nP1, TimeStep; su2double *Normal = NULL, *GridVel_i = NULL, *GridVel_j = NULL, Residual_GCL; - + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); bool energy = config->GetEnergy_Equation(); - + /*--- Store the physical time step ---*/ - + TimeStep = config->GetDelta_UnstTimeND(); - + /*--- Compute the dual time-stepping source term for static meshes ---*/ - + if (!dynamic_grid) { - + /*--- Loop over all nodes (excluding halos) ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /*--- Initialize the Residual / Jacobian container to zero. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { Residual[iVar] = 0.0; if (implicit) { @@ -5158,47 +5156,47 @@ void CIncEulerSolver::SetResidual_DualTime(CGeometry *geometry, CSolver **solver Jacobian_i[iVar][jVar] = 0.0; } } - + /*--- Retrieve the solution at time levels n-1, n, and n+1. Note that we are currently iterating on U^n+1 and that U^n & U^n-1 are fixed, previous solutions that are stored in memory. These are actually the primitive values, but we will convert to conservatives. ---*/ - + V_time_nM1 = nodes->GetSolution_time_n1(iPoint); V_time_n = nodes->GetSolution_time_n(iPoint); V_time_nP1 = nodes->GetSolution(iPoint); - + /*--- Access the density and Cp at this node (constant for now). ---*/ - + Density = nodes->GetDensity(iPoint); Cp = nodes->GetSpecificHeatCp(iPoint); - + /*--- Compute the conservative variable vector for all time levels. ---*/ - + U_time_nM1[0] = Density; U_time_n[0] = Density; U_time_nP1[0] = Density; - + for (iDim = 0; iDim < nDim; iDim++) { U_time_nM1[iDim+1] = Density*V_time_nM1[iDim+1]; U_time_n[iDim+1] = Density*V_time_n[iDim+1]; U_time_nP1[iDim+1] = Density*V_time_nP1[iDim+1]; } - + U_time_nM1[nDim+1] = Density*Cp*V_time_nM1[nDim+1]; U_time_n[nDim+1] = Density*Cp*V_time_n[nDim+1]; U_time_nP1[nDim+1] = Density*Cp*V_time_nP1[nDim+1]; - + /*--- CV volume at time n+1. As we are on a static mesh, the volume of the CV will remained fixed for all time steps. ---*/ - + Volume_nP1 = geometry->node[iPoint]->GetVolume(); - + /*--- Compute the dual time-stepping source term based on the chosen time discretization scheme (1st- or 2nd-order). Note that for an incompressible problem, the pressure equation does not have a contribution, as the time derivative should always be zero. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { if (config->GetTime_Marching() == DT_STEPPING_1ST) Residual[iVar] = (U_time_nP1[iVar] - U_time_n[iVar])*Volume_nP1 / TimeStep; @@ -5206,14 +5204,14 @@ void CIncEulerSolver::SetResidual_DualTime(CGeometry *geometry, CSolver **solver Residual[iVar] = ( 3.0*U_time_nP1[iVar] - 4.0*U_time_n[iVar] +1.0*U_time_nM1[iVar])*Volume_nP1 / (2.0*TimeStep); } - + if (!energy) Residual[nDim+1] = 0.0; - + /*--- Store the residual and compute the Jacobian contribution due to the dual time source term. ---*/ - + LinSysRes.AddBlock(iPoint, Residual); - + if (implicit) { SetPreconditioner(config, iPoint); @@ -5238,16 +5236,16 @@ void CIncEulerSolver::SetResidual_DualTime(CGeometry *geometry, CSolver **solver Jacobian_i[nDim+1][iVar] = 0.0; } } - + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - + } } - + } - + else { - + /*--- For unsteady flows on dynamic meshes (rigidly transforming or dynamically deforming), the Geometric Conservation Law (GCL) should be satisfied in conjunction with the ALE formulation of the governing @@ -5255,131 +5253,131 @@ void CIncEulerSolver::SetResidual_DualTime(CGeometry *geometry, CSolver **solver a uniform free-stream should be preserved through a moving grid. First, we will loop over the edges and boundaries to compute the GCL component of the dual time source term that depends on grid velocities. ---*/ - + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - + /*--- Initialize the Residual / Jacobian container to zero. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = 0.0; - + /*--- Get indices for nodes i & j plus the face normal ---*/ - + iPoint = geometry->edge[iEdge]->GetNode(0); jPoint = geometry->edge[iEdge]->GetNode(1); Normal = geometry->edge[iEdge]->GetNormal(); - + /*--- Grid velocities stored at nodes i & j ---*/ - + GridVel_i = geometry->node[iPoint]->GetGridVel(); GridVel_j = geometry->node[jPoint]->GetGridVel(); - + /*--- Compute the GCL term by averaging the grid velocities at the edge mid-point and dotting with the face normal. ---*/ - + Residual_GCL = 0.0; for (iDim = 0; iDim < nDim; iDim++) Residual_GCL += 0.5*(GridVel_i[iDim]+GridVel_j[iDim])*Normal[iDim]; - + /*--- Compute the GCL component of the source term for node i ---*/ - + V_time_n = nodes->GetSolution_time_n(iPoint); - + /*--- Access the density and Cp at this node (constant for now). ---*/ - + Density = nodes->GetDensity(iPoint); Cp = nodes->GetSpecificHeatCp(iPoint); - + /*--- Compute the conservative variable vector for all time levels. ---*/ - + U_time_n[0] = Density; for (iDim = 0; iDim < nDim; iDim++) { U_time_n[iDim+1] = Density*V_time_n[iDim+1]; } U_time_n[nDim+1] = Density*Cp*V_time_n[nDim+1]; - + for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = U_time_n[iVar]*Residual_GCL; - + if (!energy) Residual[nDim+1] = 0.0; LinSysRes.AddBlock(iPoint, Residual); - + /*--- Compute the GCL component of the source term for node j ---*/ - + V_time_n = nodes->GetSolution_time_n(jPoint); - + U_time_n[0] = Density; for (iDim = 0; iDim < nDim; iDim++) { U_time_n[iDim+1] = Density*V_time_n[iDim+1]; } U_time_n[nDim+1] = Density*Cp*V_time_n[nDim+1]; - + for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = U_time_n[iVar]*Residual_GCL; - + if (!energy) Residual[nDim+1] = 0.0; LinSysRes.SubtractBlock(jPoint, Residual); - + } - + /*--- Loop over the boundary edges ---*/ - + for (iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) != INTERNAL_BOUNDARY) && (config->GetMarker_All_KindBC(iMarker) != PERIODIC_BOUNDARY)) { for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { - + /*--- Initialize the Residual / Jacobian container to zero. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = 0.0; - + /*--- Get the index for node i plus the boundary face normal ---*/ - + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - + /*--- Grid velocities stored at boundary node i ---*/ - + GridVel_i = geometry->node[iPoint]->GetGridVel(); - + /*--- Compute the GCL term by dotting the grid velocity with the face normal. The normal is negated to match the boundary convention. ---*/ - + Residual_GCL = 0.0; for (iDim = 0; iDim < nDim; iDim++) Residual_GCL -= 0.5*(GridVel_i[iDim]+GridVel_i[iDim])*Normal[iDim]; - + /*--- Compute the GCL component of the source term for node i ---*/ - + V_time_n = nodes->GetSolution_time_n(iPoint); - + /*--- Access the density and Cp at this node (constant for now). ---*/ - + Density = nodes->GetDensity(iPoint); Cp = nodes->GetSpecificHeatCp(iPoint); - + U_time_n[0] = Density; for (iDim = 0; iDim < nDim; iDim++) { U_time_n[iDim+1] = Density*V_time_n[iDim+1]; } U_time_n[nDim+1] = Density*Cp*V_time_n[nDim+1]; - + for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = U_time_n[iVar]*Residual_GCL; - + if (!energy) Residual[nDim+1] = 0.0; LinSysRes.AddBlock(iPoint, Residual); - + } } } - + /*--- Loop over all nodes (excluding halos) to compute the remainder of the dual time-stepping source term. ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /*--- Initialize the Residual / Jacobian container to zero. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { Residual[iVar] = 0.0; if (implicit) { @@ -5387,47 +5385,47 @@ void CIncEulerSolver::SetResidual_DualTime(CGeometry *geometry, CSolver **solver Jacobian_i[iVar][jVar] = 0.0; } } - + /*--- Retrieve the solution at time levels n-1, n, and n+1. Note that we are currently iterating on U^n+1 and that U^n & U^n-1 are fixed, previous solutions that are stored in memory. ---*/ - + V_time_nM1 = nodes->GetSolution_time_n1(iPoint); V_time_n = nodes->GetSolution_time_n(iPoint); V_time_nP1 = nodes->GetSolution(iPoint); - + /*--- Access the density and Cp at this node (constant for now). ---*/ - + Density = nodes->GetDensity(iPoint); Cp = nodes->GetSpecificHeatCp(iPoint); - + /*--- Compute the conservative variable vector for all time levels. ---*/ - + U_time_nM1[0] = Density; U_time_n[0] = Density; U_time_nP1[0] = Density; - + for (iDim = 0; iDim < nDim; iDim++) { U_time_nM1[iDim+1] = Density*V_time_nM1[iDim+1]; U_time_n[iDim+1] = Density*V_time_n[iDim+1]; U_time_nP1[iDim+1] = Density*V_time_nP1[iDim+1]; } - + U_time_nM1[nDim+1] = Density*Cp*V_time_nM1[nDim+1]; U_time_n[nDim+1] = Density*Cp*V_time_n[nDim+1]; U_time_nP1[nDim+1] = Density*Cp*V_time_nP1[nDim+1]; - + /*--- CV volume at time n-1 and n+1. In the case of dynamically deforming grids, the volumes will change. On rigidly transforming grids, the volumes will remain constant. ---*/ - + Volume_nM1 = geometry->node[iPoint]->GetVolume_nM1(); Volume_nP1 = geometry->node[iPoint]->GetVolume(); - + /*--- Compute the dual time-stepping source residual. Due to the introduction of the GCL term above, the remainder of the source residual due to the time discretization has a new form.---*/ - + for (iVar = 0; iVar < nVar; iVar++) { if (config->GetTime_Marching() == DT_STEPPING_1ST) Residual[iVar] = (U_time_nP1[iVar] - U_time_n[iVar])*(Volume_nP1/TimeStep); @@ -5435,7 +5433,7 @@ void CIncEulerSolver::SetResidual_DualTime(CGeometry *geometry, CSolver **solver Residual[iVar] = (U_time_nP1[iVar] - U_time_n[iVar])*(3.0*Volume_nP1/(2.0*TimeStep)) + (U_time_nM1[iVar] - U_time_n[iVar])*(Volume_nM1/(2.0*TimeStep)); } - + /*--- Store the residual and compute the Jacobian contribution due to the dual time source term. ---*/ if (!energy) Residual[nDim+1] = 0.0; @@ -5467,26 +5465,26 @@ void CIncEulerSolver::SetResidual_DualTime(CGeometry *geometry, CSolver **solver } } } - + } void CIncEulerSolver::GetOutlet_Properties(CGeometry *geometry, CConfig *config, unsigned short iMesh, bool Output) { - + unsigned short iDim, iMarker; unsigned long iVertex, iPoint; su2double *V_outlet = NULL, Velocity[3], MassFlow, Velocity2, Density, Area, AxiFactor; unsigned short iMarker_Outlet, nMarker_Outlet; string Inlet_TagBound, Outlet_TagBound; - + bool axisymmetric = config->GetAxisymmetric(); bool write_heads = ((((config->GetInnerIter() % (config->GetWrt_Con_Freq()*40)) == 0) && (config->GetInnerIter()!= 0)) || (config->GetInnerIter() == 1)); - + /*--- Get the number of outlet markers and check for any mass flow BCs. ---*/ - + nMarker_Outlet = config->GetnMarker_Outlet(); bool Evaluate_BC = false; for (iMarker_Outlet = 0; iMarker_Outlet < nMarker_Outlet; iMarker_Outlet++) { @@ -5494,7 +5492,7 @@ void CIncEulerSolver::GetOutlet_Properties(CGeometry *geometry, CConfig *config, if (config->GetKind_Inc_Outlet(Outlet_TagBound) == MASS_FLOW_OUTLET) Evaluate_BC = true; } - + /*--- If we have a massflow outlet BC, then we need to compute and communicate the total massflow, density, and area through each outlet boundary, so that it can be used in the iterative procedure to update @@ -5502,33 +5500,33 @@ void CIncEulerSolver::GetOutlet_Properties(CGeometry *geometry, CConfig *config, routine is called only once per iteration as a preprocessing and the values for all outlets are stored and retrieved later in the BC_Outlet routines. ---*/ - + if (Evaluate_BC) { - + su2double *Outlet_MassFlow = new su2double[config->GetnMarker_All()]; su2double *Outlet_Density = new su2double[config->GetnMarker_All()]; su2double *Outlet_Area = new su2double[config->GetnMarker_All()]; - + /*--- Comute MassFlow, average temp, press, etc. ---*/ - + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { - + Outlet_MassFlow[iMarker] = 0.0; Outlet_Density[iMarker] = 0.0; Outlet_Area[iMarker] = 0.0; - + if ((config->GetMarker_All_KindBC(iMarker) == OUTLET_FLOW) ) { - + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - + if (geometry->node[iPoint]->GetDomain()) { - + V_outlet = nodes->GetPrimitive(iPoint); - + geometry->vertex[iMarker][iVertex]->GetNormal(Vector); - + if (axisymmetric) { if (geometry->node[iPoint]->GetCoord(1) != 0.0) AxiFactor = 2.0*PI_NUMBER*geometry->node[iPoint]->GetCoord(1); @@ -5537,11 +5535,11 @@ void CIncEulerSolver::GetOutlet_Properties(CGeometry *geometry, CConfig *config, } else { AxiFactor = 1.0; } - + Density = V_outlet[nDim+2]; - + Velocity2 = 0.0; Area = 0.0; MassFlow = 0.0; - + for (iDim = 0; iDim < nDim; iDim++) { Area += (Vector[iDim] * AxiFactor) * (Vector[iDim] * AxiFactor); Velocity[iDim] = V_outlet[iDim+1]; @@ -5549,38 +5547,38 @@ void CIncEulerSolver::GetOutlet_Properties(CGeometry *geometry, CConfig *config, MassFlow += Vector[iDim] * AxiFactor * Density * Velocity[iDim]; } Area = sqrt (Area); - + Outlet_MassFlow[iMarker] += MassFlow; Outlet_Density[iMarker] += Density*Area; Outlet_Area[iMarker] += Area; - + } } } } - + /*--- Copy to the appropriate structure ---*/ - + su2double *Outlet_MassFlow_Local = new su2double[nMarker_Outlet]; su2double *Outlet_Density_Local = new su2double[nMarker_Outlet]; su2double *Outlet_Area_Local = new su2double[nMarker_Outlet]; - + su2double *Outlet_MassFlow_Total = new su2double[nMarker_Outlet]; su2double *Outlet_Density_Total = new su2double[nMarker_Outlet]; su2double *Outlet_Area_Total = new su2double[nMarker_Outlet]; - + for (iMarker_Outlet = 0; iMarker_Outlet < nMarker_Outlet; iMarker_Outlet++) { Outlet_MassFlow_Local[iMarker_Outlet] = 0.0; Outlet_Density_Local[iMarker_Outlet] = 0.0; Outlet_Area_Local[iMarker_Outlet] = 0.0; - + Outlet_MassFlow_Total[iMarker_Outlet] = 0.0; Outlet_Density_Total[iMarker_Outlet] = 0.0; Outlet_Area_Total[iMarker_Outlet] = 0.0; } - + /*--- Copy the values to the local array for MPI ---*/ - + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) == OUTLET_FLOW)) { for (iMarker_Outlet = 0; iMarker_Outlet < nMarker_Outlet; iMarker_Outlet++) { @@ -5593,25 +5591,25 @@ void CIncEulerSolver::GetOutlet_Properties(CGeometry *geometry, CConfig *config, } } } - + /*--- All the ranks to compute the total value ---*/ - + #ifdef HAVE_MPI - + SU2_MPI::Allreduce(Outlet_MassFlow_Local, Outlet_MassFlow_Total, nMarker_Outlet, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); SU2_MPI::Allreduce(Outlet_Density_Local, Outlet_Density_Total, nMarker_Outlet, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); SU2_MPI::Allreduce(Outlet_Area_Local, Outlet_Area_Total, nMarker_Outlet, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - + #else - + for (iMarker_Outlet = 0; iMarker_Outlet < nMarker_Outlet; iMarker_Outlet++) { Outlet_MassFlow_Total[iMarker_Outlet] = Outlet_MassFlow_Local[iMarker_Outlet]; Outlet_Density_Total[iMarker_Outlet] = Outlet_Density_Local[iMarker_Outlet]; Outlet_Area_Total[iMarker_Outlet] = Outlet_Area_Local[iMarker_Outlet]; } - + #endif - + for (iMarker_Outlet = 0; iMarker_Outlet < nMarker_Outlet; iMarker_Outlet++) { if (Outlet_Area_Total[iMarker_Outlet] != 0.0) { Outlet_Density_Total[iMarker_Outlet] /= Outlet_Area_Total[iMarker_Outlet]; @@ -5619,69 +5617,69 @@ void CIncEulerSolver::GetOutlet_Properties(CGeometry *geometry, CConfig *config, else { Outlet_Density_Total[iMarker_Outlet] = 0.0; } - + if (iMesh == MESH_0) { config->SetOutlet_MassFlow(iMarker_Outlet, Outlet_MassFlow_Total[iMarker_Outlet]); config->SetOutlet_Density(iMarker_Outlet, Outlet_Density_Total[iMarker_Outlet]); config->SetOutlet_Area(iMarker_Outlet, Outlet_Area_Total[iMarker_Outlet]); } } - + /*--- Screen output using the values already stored in the config container ---*/ - + if ((rank == MASTER_NODE) && (iMesh == MESH_0) ) { - + cout.precision(5); cout.setf(ios::fixed, ios::floatfield); - + if (write_heads && Output && !config->GetDiscrete_Adjoint()) { cout << endl << "---------------------------- Outlet properties --------------------------" << endl; } - + for (iMarker_Outlet = 0; iMarker_Outlet < nMarker_Outlet; iMarker_Outlet++) { Outlet_TagBound = config->GetMarker_Outlet_TagBound(iMarker_Outlet); if (write_heads && Output && !config->GetDiscrete_Adjoint()) { - + /*--- Geometry defintion ---*/ - + cout <<"Outlet surface: " << Outlet_TagBound << "." << endl; - + if ((nDim ==3) || axisymmetric) { cout <<"Area (m^2): " << config->GetOutlet_Area(Outlet_TagBound) << endl; } if (nDim == 2) { cout <<"Length (m): " << config->GetOutlet_Area(Outlet_TagBound) << "." << endl; } - + cout << setprecision(5) << "Outlet Avg. Density (kg/m^3): " << config->GetOutlet_Density(Outlet_TagBound) * config->GetDensity_Ref() << endl; su2double Outlet_mDot = fabs(config->GetOutlet_MassFlow(Outlet_TagBound)) * config->GetDensity_Ref() * config->GetVelocity_Ref(); cout << "Outlet mass flow (kg/s): "; cout << setprecision(5) << Outlet_mDot; - + } } - + if (write_heads && Output && !config->GetDiscrete_Adjoint()) {cout << endl; cout << "-------------------------------------------------------------------------" << endl << endl; } - + cout.unsetf(ios_base::floatfield); - + } - + delete [] Outlet_MassFlow_Local; delete [] Outlet_Density_Local; delete [] Outlet_Area_Local; - + delete [] Outlet_MassFlow_Total; delete [] Outlet_Density_Total; delete [] Outlet_Area_Total; - + delete [] Outlet_MassFlow; delete [] Outlet_Density; delete [] Outlet_Area; - + } - + } void CIncEulerSolver::ComputeVerificationError(CGeometry *geometry, @@ -5689,44 +5687,44 @@ void CIncEulerSolver::ComputeVerificationError(CGeometry *geometry, /*--- The errors only need to be computed on the finest grid. ---*/ if(MGLevel != MESH_0) return; - + /*--- If this is a verification case, we can compute the global error metrics by using the difference between the local error and the known solution at each DOF. This is then collected into RMS (L2) and maximum (Linf) global error norms. From these global measures, one can compute the order of accuracy. ---*/ - + bool write_heads = ((((config->GetInnerIter() % (config->GetWrt_Con_Freq()*40)) == 0) && (config->GetInnerIter()!= 0)) || (config->GetInnerIter() == 1)); if( !write_heads ) return; - + /*--- Check if there actually is an exact solution for this verification case, if computed at all. ---*/ if (VerificationSolution) { if (VerificationSolution->ExactSolutionKnown()) { - + /*--- Get the physical time if necessary. ---*/ su2double time = 0.0; if (config->GetTime_Marching()) time = config->GetPhysicalTime(); - + /*--- Reset the global error measures to zero. ---*/ for (unsigned short iVar = 0; iVar < nVar; iVar++) { VerificationSolution->SetError_RMS(iVar, 0.0); VerificationSolution->SetError_Max(iVar, 0.0, 0); } - + /*--- Loop over all owned points. ---*/ for (unsigned long iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /* Set the pointers to the coordinates and solution of this DOF. */ const su2double *coor = geometry->node[iPoint]->GetCoord(); su2double *solDOF = nodes->GetSolution(iPoint); - + /* Get local error from the verification solution class. */ vector error(nVar,0.0); VerificationSolution->GetLocalError(coor, time, solDOF, error.data()); - + /* Increment the global error measures */ for (unsigned short iVar = 0; iVar < nVar; iVar++) { VerificationSolution->AddError_RMS(iVar, error[iVar]*error[iVar]); @@ -5735,58 +5733,58 @@ void CIncEulerSolver::ComputeVerificationError(CGeometry *geometry, geometry->node[iPoint]->GetCoord()); } } - + /* Finalize the calculation of the global error measures. */ VerificationSolution->SetVerificationError(geometry->GetGlobal_nPointDomain(), config); - + /*--- Screen output of the error metrics. This can be improved once the new output classes are in place. ---*/ - + if ((rank == MASTER_NODE) && (geometry->GetMGLevel() == MESH_0)) { - + cout.precision(6); cout.setf(ios::scientific, ios::floatfield); - + if (!config->GetDiscrete_Adjoint()) { - + cout << endl << "------------------------ Global Error Analysis --------------------------" << endl; - + cout << setw(20) << "RMS Error [P]: " << setw(12) << VerificationSolution->GetError_RMS(0) << " | "; cout << setw(20) << "Max Error [P]: " << setw(12) << VerificationSolution->GetError_Max(0); cout << endl; - + cout << setw(20) << "RMS Error [U]: " << setw(12) << VerificationSolution->GetError_RMS(1) << " | "; cout << setw(20) << "Max Error [U]: " << setw(12) << VerificationSolution->GetError_Max(1); cout << endl; - + cout << setw(20) << "RMS Error [V]: " << setw(12) << VerificationSolution->GetError_RMS(2) << " | "; cout << setw(20) << "Max Error [V]: " << setw(12) << VerificationSolution->GetError_Max(2); cout << endl; - + if (nDim == 3) { cout << setw(20) << "RMS Error [W]: " << setw(12) << VerificationSolution->GetError_RMS(3) << " | "; cout << setw(20) << "Max Error [W]: " << setw(12) << VerificationSolution->GetError_Max(3); cout << endl; } - + if (config->GetEnergy_Equation()) { cout << setw(20) << "RMS Error [T]: " << setw(12) << VerificationSolution->GetError_RMS(nDim+1) << " | "; cout << setw(20) << "Max Error [T]: " << setw(12) << VerificationSolution->GetError_Max(nDim+1); cout << endl; } - + cout << "-------------------------------------------------------------------------" << endl << endl; cout.unsetf(ios_base::floatfield); } } } - + } - + } void CIncEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo) { - + /*--- Restart the solution from file information ---*/ unsigned short iDim, iVar, iMesh, iMeshFine; unsigned long iPoint, index, iChildren, Point_Fine; @@ -5798,13 +5796,13 @@ void CIncEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConf (config->GetTime_Marching() == DT_STEPPING_2ND)); bool steady_restart = config->GetSteadyRestart(); bool turbulent = (config->GetKind_Solver() == INC_RANS) || (config->GetKind_Solver() == DISC_ADJ_INC_RANS); - + string restart_filename = config->GetFilename(config->GetSolution_FileName(), "", val_iter); Coord = new su2double [nDim]; for (iDim = 0; iDim < nDim; iDim++) Coord[iDim] = 0.0; - + int counter = 0; long iPoint_Local = 0; unsigned long iPoint_Global = 0; unsigned long iPoint_Global_Local = 0; @@ -5821,19 +5819,19 @@ void CIncEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConf if ((turb_model == SST) || (turb_model == SST_SUST)) turbVars = 2; else turbVars = 1; } - + /*--- Adjust the number of solution variables in the restart. We always carry a space in nVar for the energy equation in the solver, but we only write it to the restart if it is active. Therefore, we must reduce nVar here if energy is inactive so that the restart is read correctly. ---*/ - + bool energy = config->GetEnergy_Equation(); bool weakly_coupled_heat = config->GetWeakly_Coupled_Heat(); - + unsigned short nVar_Restart = nVar; if ((!energy) && (!weakly_coupled_heat)) nVar_Restart--; Solution[nVar-1] = GetTemperature_Inf(); - + /*--- Read the restart data from either an ASCII or binary SU2 file. ---*/ if (config->GetRead_Binary_Restart()) { @@ -5888,7 +5886,7 @@ void CIncEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConf geometry[MESH_0]->node[iPoint_Local]->SetGridVel(iDim, GridVel[iDim]); } } - + /*--- For static FSI problems, grid_movement is 0 but we need to read in and store the grid coordinates for each node (but not the grid velocities, as there are none). ---*/ @@ -5905,7 +5903,7 @@ void CIncEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConf /*--- Increment the overall counter for how many points have been loaded. ---*/ counter++; - + } } @@ -5922,19 +5920,19 @@ void CIncEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConf SU2_MPI::Error(string("The solution file ") + restart_filename + string(" doesn't match with the mesh file!\n") + string("It could be empty lines at the end of the file."), CURRENT_FUNCTION); } - + /*--- Communicate the loaded solution on the fine grid before we transfer it down to the coarse levels. We alo call the preprocessing routine on the fine level in order to have all necessary quantities updated, especially if this is a turbulent simulation (eddy viscosity). ---*/ - + solver[MESH_0][FLOW_SOL]->InitiateComms(geometry[MESH_0], config, SOLUTION); solver[MESH_0][FLOW_SOL]->CompleteComms(geometry[MESH_0], config, SOLUTION); - + solver[MESH_0][FLOW_SOL]->Preprocessing(geometry[MESH_0], solver[MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); /*--- Interpolate the solution down to the coarse multigrid levels ---*/ - + for (iMesh = 1; iMesh <= config->GetnMGLevels(); iMesh++) { for (iPoint = 0; iPoint < geometry[iMesh]->GetnPoint(); iPoint++) { Area_Parent = geometry[iMesh]->node[iPoint]->GetVolume(); @@ -5953,29 +5951,29 @@ void CIncEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConf solver[iMesh][FLOW_SOL]->CompleteComms(geometry[iMesh], config, SOLUTION); solver[iMesh][FLOW_SOL]->Preprocessing(geometry[iMesh], solver[iMesh], config, iMesh, NO_RK_ITER, RUNTIME_FLOW_SYS, false); } - + /*--- Update the geometry for flows on dynamic meshes ---*/ - + if (dynamic_grid && val_update_geo) { - + /*--- Communicate the new coordinates and grid velocities at the halos ---*/ - + geometry[MESH_0]->InitiateComms(geometry[MESH_0], config, COORDINATES); geometry[MESH_0]->CompleteComms(geometry[MESH_0], config, COORDINATES); - + geometry[MESH_0]->InitiateComms(geometry[MESH_0], config, GRID_VELOCITY); geometry[MESH_0]->CompleteComms(geometry[MESH_0], config, GRID_VELOCITY); - + /*--- Recompute the edges and dual mesh control volumes in the domain and on the boundaries. ---*/ - + geometry[MESH_0]->SetCoord_CG(); geometry[MESH_0]->SetControlVolume(config, UPDATE); geometry[MESH_0]->SetBoundControlVolume(config, UPDATE); - + /*--- Update the multigrid structure after setting up the finest grid, including computing the grid velocities on the coarser levels. ---*/ - + for (iMesh = 1; iMesh <= config->GetnMGLevels(); iMesh++) { iMeshFine = iMesh-1; geometry[iMesh]->SetControlVolume(config, geometry[iMeshFine], UPDATE); @@ -5984,27 +5982,27 @@ void CIncEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConf geometry[iMesh]->SetRestricted_GridVelocity(geometry[iMeshFine], config); } } - + /*--- Update the geometry for flows on static FSI problems with moving meshes ---*/ - + if (static_fsi && val_update_geo) { - + /*--- Communicate the new coordinates and grid velocities at the halos ---*/ - + geometry[MESH_0]->InitiateComms(geometry[MESH_0], config, COORDINATES); geometry[MESH_0]->CompleteComms(geometry[MESH_0], config, COORDINATES); - + /*--- Recompute the edges and dual mesh control volumes in the domain and on the boundaries. ---*/ - + geometry[MESH_0]->SetCoord_CG(); geometry[MESH_0]->SetControlVolume(config, UPDATE); geometry[MESH_0]->SetBoundControlVolume(config, UPDATE); geometry[MESH_0]->SetMaxLength(config); - + /*--- Update the multigrid structure after setting up the finest grid, including computing the grid velocities on the coarser levels. ---*/ - + for (iMesh = 1; iMesh <= config->GetnMGLevels(); iMesh++) { iMeshFine = iMesh-1; geometry[iMesh]->SetControlVolume(config, geometry[iMeshFine], UPDATE); @@ -6013,7 +6011,7 @@ void CIncEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConf geometry[iMesh]->SetMaxLength(config); } } - + /*--- Update the old geometry (coordinates n and n-1) in dual time-stepping strategy ---*/ if (dual_time && config->GetGrid_Movement() && (config->GetKind_GridMovement() != RIGID_MOTION)) Restart_OldGeometry(geometry[MESH_0], config); @@ -6025,7 +6023,7 @@ void CIncEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConf if (Restart_Vars != NULL) delete [] Restart_Vars; if (Restart_Data != NULL) delete [] Restart_Data; Restart_Vars = NULL; Restart_Data = NULL; - + } void CIncEulerSolver::SetFreeStream_Solution(CConfig *config){ @@ -6041,1945 +6039,3 @@ void CIncEulerSolver::SetFreeStream_Solution(CConfig *config){ nodes->SetSolution(iPoint,nDim+1, Temperature_Inf); } } - -CIncNSSolver::CIncNSSolver(void) : CIncEulerSolver() { - - /*--- Basic array initialization ---*/ - - CD_Visc = NULL; CL_Visc = NULL; CSF_Visc = NULL; CEff_Visc = NULL; - CMx_Visc = NULL; CMy_Visc = NULL; CMz_Visc = NULL; - CFx_Visc = NULL; CFy_Visc = NULL; CFz_Visc = NULL; - CoPx_Visc = NULL; CoPy_Visc = NULL; CoPz_Visc = NULL; - - ForceViscous = NULL; MomentViscous = NULL; CSkinFriction = NULL; - - /*--- Surface based array initialization ---*/ - - Surface_CL_Visc = NULL; Surface_CD_Visc = NULL; Surface_CSF_Visc = NULL; Surface_CEff_Visc = NULL; - Surface_CFx_Visc = NULL; Surface_CFy_Visc = NULL; Surface_CFz_Visc = NULL; - Surface_CMx_Visc = NULL; Surface_CMy_Visc = NULL; Surface_CMz_Visc = NULL; - Surface_HF_Visc = NULL; Surface_MaxHF_Visc = NULL; - - /*--- Rotorcraft simulation array initialization ---*/ - - CMerit_Visc = NULL; CT_Visc = NULL; CQ_Visc = NULL; - - SlidingState = NULL; - SlidingStateNodes = NULL; - -} - -CIncNSSolver::CIncNSSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh) : CIncEulerSolver() { - - unsigned long iPoint, iVertex; - unsigned short iVar, iDim, iMarker, nLineLets; - ifstream restart_file; - unsigned short nZone = geometry->GetnZone(); - bool restart = (config->GetRestart() || config->GetRestart_Flow()); - int Unst_RestartIter; - unsigned short iZone = config->GetiZone(); - bool dual_time = ((config->GetTime_Marching() == DT_STEPPING_1ST) || - (config->GetTime_Marching() == DT_STEPPING_2ND)); - bool time_stepping = config->GetTime_Marching() == TIME_STEPPING; - bool adjoint = (config->GetContinuous_Adjoint()) || (config->GetDiscrete_Adjoint()); - string filename_ = config->GetSolution_FileName(); - - /* A grid is defined as dynamic if there's rigid grid movement or grid deformation AND the problem is time domain */ - dynamic_grid = config->GetDynamic_Grid(); - - unsigned short direct_diff = config->GetDirectDiff(); - - /*--- Store the multigrid level. ---*/ - MGLevel = iMesh; - - /*--- Check for a restart file to evaluate if there is a change in the angle of attack - before computing all the non-dimesional quantities. ---*/ - - if (!(!restart || (iMesh != MESH_0) || nZone > 1)) { - - /*--- Multizone problems require the number of the zone to be appended. ---*/ - - if (nZone > 1) filename_ = config->GetMultizone_FileName(filename_, iZone, ".dat"); - - /*--- Modify file name for a dual-time unsteady restart ---*/ - - if (dual_time) { - if (adjoint) Unst_RestartIter = SU2_TYPE::Int(config->GetUnst_AdjointIter())-1; - else if (config->GetTime_Marching() == DT_STEPPING_1ST) - Unst_RestartIter = SU2_TYPE::Int(config->GetRestart_Iter())-1; - else Unst_RestartIter = SU2_TYPE::Int(config->GetRestart_Iter())-2; - filename_ = config->GetUnsteady_FileName(filename_, Unst_RestartIter, ".dat"); - } - - /*--- Modify file name for a time stepping unsteady restart ---*/ - - if (time_stepping) { - if (adjoint) Unst_RestartIter = SU2_TYPE::Int(config->GetUnst_AdjointIter())-1; - else Unst_RestartIter = SU2_TYPE::Int(config->GetRestart_Iter())-1; - filename_ = config->GetUnsteady_FileName(filename_, Unst_RestartIter, ".dat"); - } - - /*--- Read and store the restart metadata. ---*/ - -// Read_SU2_Restart_Metadata(geometry, config, false, filename_); - - } - - /*--- Array initialization ---*/ - - CD_Visc = NULL; CL_Visc = NULL; CSF_Visc = NULL; CEff_Visc = NULL; - CMx_Visc = NULL; CMy_Visc = NULL; CMz_Visc = NULL; - CFx_Visc = NULL; CFy_Visc = NULL; CFz_Visc = NULL; - CoPx_Visc = NULL; CoPy_Visc = NULL; CoPz_Visc = NULL; - - Surface_CL_Visc = NULL; Surface_CD_Visc = NULL; Surface_CSF_Visc = NULL; Surface_CEff_Visc = NULL; - Surface_CFx_Visc = NULL; Surface_CFy_Visc = NULL; Surface_CFz_Visc = NULL; - Surface_CMx_Visc = NULL; Surface_CMy_Visc = NULL; Surface_CMz_Visc = NULL; - Surface_HF_Visc = NULL; Surface_MaxHF_Visc = NULL; - - CMerit_Visc = NULL; CT_Visc = NULL; CQ_Visc = NULL; - MaxHF_Visc = NULL; ForceViscous = NULL; MomentViscous = NULL; - CSkinFriction = NULL; HF_Visc = NULL; - - /*--- Set the gamma value ---*/ - - Gamma = config->GetGamma(); - Gamma_Minus_One = Gamma - 1.0; - - /*--- Define geometry constants in the solver structure - * Incompressible flow, primitive variables (P, vx, vy, vz, T, rho, beta, lamMu, EddyMu, Kt_eff, Cp, Cv) --- */ - - nDim = geometry->GetnDim(); - - nVar = nDim+2; nPrimVar = nDim+9; nPrimVarGrad = nDim+4; - - /*--- Initialize nVarGrad for deallocation ---*/ - - nVarGrad = nPrimVarGrad; - - nMarker = config->GetnMarker_All(); - nPoint = geometry->GetnPoint(); - nPointDomain = geometry->GetnPointDomain(); - - /*--- Store the number of vertices on each marker for deallocation later ---*/ - - nVertex = new unsigned long[nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) - nVertex[iMarker] = geometry->nVertex[iMarker]; - - /*--- Fluid model intialization. ---*/ - - FluidModel = NULL; - - /*--- Perform the non-dimensionalization for the flow equations using the - specified reference values. ---*/ - - SetNondimensionalization(config, iMesh); - - /*--- Check if we are executing a verification case. If so, the - VerificationSolution object will be instantiated for a particular - option from the available library of verification solutions. Note - that this is done after SetNondim(), as problem-specific initial - parameters are needed by the solution constructors. ---*/ - - SetVerificationSolution(nDim, nVar, config); - - /*--- Define some auxiliar vector related with the residual ---*/ - - Residual = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = 0.0; - Residual_RMS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_RMS[iVar] = 0.0; - Residual_Max = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_Max[iVar] = 0.0; - Res_Conv = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Conv[iVar] = 0.0; - Res_Visc = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Visc[iVar] = 0.0; - Res_Sour = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Sour[iVar] = 0.0; - - /*--- Define some structures for locating max residuals ---*/ - - Point_Max = new unsigned long[nVar]; for (iVar = 0; iVar < nVar; iVar++) Point_Max[iVar] = 0; - Point_Max_Coord = new su2double*[nVar]; - for (iVar = 0; iVar < nVar; iVar++) { - Point_Max_Coord[iVar] = new su2double[nDim]; - for (iDim = 0; iDim < nDim; iDim++) Point_Max_Coord[iVar][iDim] = 0.0; - } - - /*--- Define some auxiliary vectors related to the solution ---*/ - - Solution = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution[iVar] = 0.0; - Solution_i = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution_i[iVar] = 0.0; - Solution_j = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution_j[iVar] = 0.0; - - /*--- Define some auxiliary vectors related to the geometry ---*/ - - Vector = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = 0.0; - Vector_i = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector_i[iDim] = 0.0; - Vector_j = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector_j[iDim] = 0.0; - - /*--- Define some auxiliary vectors related to the primitive solution ---*/ - - Primitive = new su2double[nPrimVar]; for (iVar = 0; iVar < nPrimVar; iVar++) Primitive[iVar] = 0.0; - Primitive_i = new su2double[nPrimVar]; for (iVar = 0; iVar < nPrimVar; iVar++) Primitive_i[iVar] = 0.0; - Primitive_j = new su2double[nPrimVar]; for (iVar = 0; iVar < nPrimVar; iVar++) Primitive_j[iVar] = 0.0; - - /*--- Define some auxiliar vector related with the undivided lapalacian computation ---*/ - - if (config->GetKind_ConvNumScheme_Flow() == SPACE_CENTERED) { - iPoint_UndLapl = new su2double [nPoint]; - jPoint_UndLapl = new su2double [nPoint]; - } - - Preconditioner = new su2double* [nVar]; - for (iVar = 0; iVar < nVar; iVar ++) - Preconditioner[iVar] = new su2double[nVar]; - - /*--- Initialize the solution and right hand side vectors for storing - the residuals and updating the solution (always needed even for - explicit schemes). ---*/ - - LinSysSol.Initialize(nPoint, nPointDomain, nVar, 0.0); - LinSysRes.Initialize(nPoint, nPointDomain, nVar, 0.0); - - /*--- Jacobians and vector structures for implicit computations ---*/ - - if (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT) { - - Jacobian_i = new su2double* [nVar]; - Jacobian_j = new su2double* [nVar]; - for (iVar = 0; iVar < nVar; iVar++) { - Jacobian_i[iVar] = new su2double [nVar]; - Jacobian_j[iVar] = new su2double [nVar]; - } - - if (rank == MASTER_NODE) cout << "Initialize Jacobian structure (Navier-Stokes). MG level: " << iMesh <<"." << endl; - Jacobian.Initialize(nPoint, nPointDomain, nVar, nVar, true, geometry, config); - - if (config->GetKind_Linear_Solver_Prec() == LINELET) { - nLineLets = Jacobian.BuildLineletPreconditioner(geometry, config); - if (rank == MASTER_NODE) cout << "Compute linelet structure. " << nLineLets << " elements in each line (average)." << endl; - } - - } - - else { - if (rank == MASTER_NODE) - cout << "Explicit scheme. No Jacobian structure (Navier-Stokes). MG level: " << iMesh <<"." << endl; - } - - /*--- Define some auxiliary vectors for computing flow variable - gradients by least squares, S matrix := inv(R)*traspose(inv(R)), - c vector := transpose(WA)*(Wb) ---*/ - - if (config->GetLeastSquaresRequired()) { - Smatrix = new su2double* [nDim]; - for (iDim = 0; iDim < nDim; iDim++) - Smatrix[iDim] = new su2double [nDim]; - - Cvector = new su2double* [nPrimVarGrad]; - for (iVar = 0; iVar < nPrimVarGrad; iVar++) - Cvector[iVar] = new su2double [nDim]; - } - - /*--- Store the value of the characteristic primitive variables at the boundaries ---*/ - - CharacPrimVar = new su2double** [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - CharacPrimVar[iMarker] = new su2double* [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - CharacPrimVar[iMarker][iVertex] = new su2double [nPrimVar]; - for (iVar = 0; iVar < nPrimVar; iVar++) { - CharacPrimVar[iMarker][iVertex][iVar] = 0.0; - } - } - } - - /*--- Store the values of the temperature and the heat flux density at the boundaries, - used for coupling with a solid donor cell ---*/ - unsigned short nHeatConjugateVar = 4; - - HeatConjugateVar = new su2double** [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - HeatConjugateVar[iMarker] = new su2double* [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - - HeatConjugateVar[iMarker][iVertex] = new su2double [nHeatConjugateVar]; - for (iVar = 1; iVar < nHeatConjugateVar ; iVar++) { - HeatConjugateVar[iMarker][iVertex][iVar] = 0.0; - } - HeatConjugateVar[iMarker][iVertex][0] = config->GetTemperature_FreeStreamND(); - } - } - - /*--- Inviscid force definition and coefficient in all the markers ---*/ - - CPressure = new su2double* [nMarker]; - CPressureTarget = new su2double* [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - CPressure[iMarker] = new su2double [geometry->nVertex[iMarker]]; - CPressureTarget[iMarker] = new su2double [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - CPressure[iMarker][iVertex] = 0.0; - CPressureTarget[iMarker][iVertex] = 0.0; - } - } - - /*--- Heat flux in all the markers ---*/ - - HeatFlux = new su2double* [nMarker]; - HeatFluxTarget = new su2double* [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - HeatFlux[iMarker] = new su2double [geometry->nVertex[iMarker]]; - HeatFluxTarget[iMarker] = new su2double [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - HeatFlux[iMarker][iVertex] = 0.0; - HeatFluxTarget[iMarker][iVertex] = 0.0; - } - } - - /*--- Y plus in all the markers ---*/ - - YPlus = new su2double* [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - YPlus[iMarker] = new su2double [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - YPlus[iMarker][iVertex] = 0.0; - } - } - - /*--- Skin friction in all the markers ---*/ - - CSkinFriction = new su2double** [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - CSkinFriction[iMarker] = new su2double*[nDim]; - for (iDim = 0; iDim < nDim; iDim++) { - CSkinFriction[iMarker][iDim] = new su2double[geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - CSkinFriction[iMarker][iDim][iVertex] = 0.0; - } - } - } - - /*--- Store the value of the Total Pressure at the inlet BC ---*/ - - Inlet_Ttotal = new su2double* [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - Inlet_Ttotal[iMarker] = new su2double [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - Inlet_Ttotal[iMarker][iVertex] = 0; - } - } - - /*--- Store the value of the Total Temperature at the inlet BC ---*/ - - Inlet_Ptotal = new su2double* [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - Inlet_Ptotal[iMarker] = new su2double [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - Inlet_Ptotal[iMarker][iVertex] = 0; - } - } - - /*--- Store the value of the Flow direction at the inlet BC ---*/ - - Inlet_FlowDir = new su2double** [nMarker]; - for (iMarker = 0; iMarker < nMarker; iMarker++) { - Inlet_FlowDir[iMarker] = new su2double* [geometry->nVertex[iMarker]]; - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - Inlet_FlowDir[iMarker][iVertex] = new su2double [nDim]; - for (iDim = 0; iDim < nDim; iDim++) { - Inlet_FlowDir[iMarker][iVertex][iDim] = 0; - } - } - } - - /*--- Non dimensional coefficients ---*/ - - ForceInviscid = new su2double[3]; - MomentInviscid = new su2double[3]; - CD_Inv = new su2double[nMarker]; - CL_Inv = new su2double[nMarker]; - CSF_Inv = new su2double[nMarker]; - CMx_Inv = new su2double[nMarker]; - CMy_Inv = new su2double[nMarker]; - CMz_Inv = new su2double[nMarker]; - CEff_Inv = new su2double[nMarker]; - CFx_Inv = new su2double[nMarker]; - CFy_Inv = new su2double[nMarker]; - CFz_Inv = new su2double[nMarker]; - CoPx_Inv = new su2double[nMarker]; - CoPy_Inv = new su2double[nMarker]; - CoPz_Inv = new su2double[nMarker]; - - ForceMomentum = new su2double[3]; - MomentMomentum = new su2double[3]; - CD_Mnt = new su2double[nMarker]; - CL_Mnt = new su2double[nMarker]; - CSF_Mnt = new su2double[nMarker]; - CMx_Mnt = new su2double[nMarker]; - CMy_Mnt = new su2double[nMarker]; - CMz_Mnt = new su2double[nMarker]; - CEff_Mnt = new su2double[nMarker]; - CFx_Mnt = new su2double[nMarker]; - CFy_Mnt = new su2double[nMarker]; - CFz_Mnt = new su2double[nMarker]; - CoPx_Mnt = new su2double[nMarker]; - CoPy_Mnt = new su2double[nMarker]; - CoPz_Mnt = new su2double[nMarker]; - - ForceViscous = new su2double[3]; - MomentViscous = new su2double[3]; - CD_Visc = new su2double[nMarker]; - CL_Visc = new su2double[nMarker]; - CSF_Visc = new su2double[nMarker]; - CMx_Visc = new su2double[nMarker]; - CMy_Visc = new su2double[nMarker]; - CMz_Visc = new su2double[nMarker]; - CEff_Visc = new su2double[nMarker]; - CFx_Visc = new su2double[nMarker]; - CFy_Visc = new su2double[nMarker]; - CFz_Visc = new su2double[nMarker]; - CoPx_Visc = new su2double[nMarker]; - CoPy_Visc = new su2double[nMarker]; - CoPz_Visc = new su2double[nMarker]; - - Surface_CL_Inv = new su2double[config->GetnMarker_Monitoring()]; - Surface_CD_Inv = new su2double[config->GetnMarker_Monitoring()]; - Surface_CSF_Inv = new su2double[config->GetnMarker_Monitoring()]; - Surface_CEff_Inv = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFx_Inv = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFy_Inv = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFz_Inv = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMx_Inv = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMy_Inv = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMz_Inv = new su2double[config->GetnMarker_Monitoring()]; - - Surface_CL_Mnt = new su2double[config->GetnMarker_Monitoring()]; - Surface_CD_Mnt = new su2double[config->GetnMarker_Monitoring()]; - Surface_CSF_Mnt = new su2double[config->GetnMarker_Monitoring()]; - Surface_CEff_Mnt = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFx_Mnt = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFy_Mnt = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFz_Mnt = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMx_Mnt = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMy_Mnt = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMz_Mnt = new su2double[config->GetnMarker_Monitoring()]; - - Surface_CL = new su2double[config->GetnMarker_Monitoring()]; - Surface_CD = new su2double[config->GetnMarker_Monitoring()]; - Surface_CSF = new su2double[config->GetnMarker_Monitoring()]; - Surface_CEff = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFx = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFy = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFz = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMx = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMy = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMz = new su2double[config->GetnMarker_Monitoring()]; - - Surface_CL_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CD_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CSF_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CEff_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFx_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFy_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CFz_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMx_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMy_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_CMz_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_HF_Visc = new su2double[config->GetnMarker_Monitoring()]; - Surface_MaxHF_Visc = new su2double[config->GetnMarker_Monitoring()]; - - /*--- Rotorcraft coefficients ---*/ - - CT_Inv = new su2double[nMarker]; - CQ_Inv = new su2double[nMarker]; - CMerit_Inv = new su2double[nMarker]; - - CT_Mnt = new su2double[nMarker]; - CQ_Mnt = new su2double[nMarker]; - CMerit_Mnt = new su2double[nMarker]; - - CMerit_Visc = new su2double[nMarker]; - CT_Visc = new su2double[nMarker]; - CQ_Visc = new su2double[nMarker]; - - /*--- Heat based coefficients ---*/ - - HF_Visc = new su2double[nMarker]; - MaxHF_Visc = new su2double[nMarker]; - - /*--- Init total coefficients ---*/ - - Total_CD = 0.0; Total_CL = 0.0; Total_CSF = 0.0; - Total_CMx = 0.0; Total_CMy = 0.0; Total_CMz = 0.0; - Total_CoPx = 0.0; Total_CoPy = 0.0; Total_CoPz = 0.0; - Total_CEff = 0.0; - Total_CFx = 0.0; Total_CFy = 0.0; Total_CFz = 0.0; - Total_CT = 0.0; Total_CQ = 0.0; Total_CMerit = 0.0; - Total_MaxHeat = 0.0; Total_Heat = 0.0; Total_ComboObj = 0.0; - Total_CpDiff = 0.0; Total_HeatFluxDiff = 0.0; Total_Custom_ObjFunc = 0.0; - - /*--- Read farfield conditions from config ---*/ - - Density_Inf = config->GetDensity_FreeStreamND(); - Pressure_Inf = config->GetPressure_FreeStreamND(); - Temperature_Inf = config->GetTemperature_FreeStreamND(); - Velocity_Inf = config->GetVelocity_FreeStreamND(); - Viscosity_Inf = config->GetViscosity_FreeStreamND(); - Tke_Inf = config->GetTke_FreeStreamND(); - - /*--- Initialize the secondary values for direct derivative approxiations ---*/ - - switch(direct_diff){ - case NO_DERIVATIVE: - break; - case D_DENSITY: - SU2_TYPE::SetDerivative(Density_Inf, 1.0); - break; - case D_PRESSURE: - SU2_TYPE::SetDerivative(Pressure_Inf, 1.0); - break; - case D_TEMPERATURE: - SU2_TYPE::SetDerivative(Temperature_Inf, 1.0); - break; - case D_VISCOSITY: - SU2_TYPE::SetDerivative(Viscosity_Inf, 1.0); - break; - case D_MACH: case D_AOA: - case D_SIDESLIP: case D_REYNOLDS: - case D_TURB2LAM: case D_DESIGN: - /*--- Already done in postprocessing of config ---*/ - break; - default: - break; - } - - /*--- Initializate quantities for SlidingMesh Interface ---*/ - - SlidingState = new su2double*** [nMarker]; - SlidingStateNodes = new int* [nMarker]; - - for (iMarker = 0; iMarker < nMarker; iMarker++){ - - SlidingState[iMarker] = NULL; - SlidingStateNodes[iMarker] = NULL; - - if (config->GetMarker_All_KindBC(iMarker) == FLUID_INTERFACE){ - - SlidingState[iMarker] = new su2double**[geometry->GetnVertex(iMarker)]; - SlidingStateNodes[iMarker] = new int [geometry->GetnVertex(iMarker)]; - - for (iPoint = 0; iPoint < geometry->GetnVertex(iMarker); iPoint++){ - SlidingState[iMarker][iPoint] = new su2double*[nPrimVar+1]; - - SlidingStateNodes[iMarker][iPoint] = 0; - for (iVar = 0; iVar < nPrimVar+1; iVar++) - SlidingState[iMarker][iPoint][iVar] = NULL; - } - - } - } - - /*--- Only initialize when there is a Marker_Fluid_Load defined - *--- (this avoids overhead in all other cases while a more permanent structure is being developed) ---*/ - if((config->GetnMarker_Fluid_Load() > 0) && (MGLevel == MESH_0)){ - - InitVertexTractionContainer(geometry, config); - - if (config->GetDiscrete_Adjoint()) - InitVertexTractionAdjointContainer(geometry, config); - - } - - /*--- Initialize the solution to the far-field state everywhere. ---*/ - - nodes = new CIncNSVariable(Pressure_Inf, Velocity_Inf, Temperature_Inf, nPoint, nDim, nVar, config); - SetBaseClassPointerToNodes(); - - /*--- Initialize the BGS residuals in FSI problems. ---*/ - if (config->GetMultizone_Residual()){ - Residual_BGS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_RMS[iVar] = 0.0; - Residual_Max_BGS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_Max_BGS[iVar] = 0.0; - - /*--- Define some structures for locating max residuals ---*/ - - Point_Max_BGS = new unsigned long[nVar]; for (iVar = 0; iVar < nVar; iVar++) Point_Max_BGS[iVar] = 0; - Point_Max_Coord_BGS = new su2double*[nVar]; - for (iVar = 0; iVar < nVar; iVar++) { - Point_Max_Coord_BGS[iVar] = new su2double[nDim]; - for (iDim = 0; iDim < nDim; iDim++) Point_Max_Coord_BGS[iVar][iDim] = 0.0; - } - } - - /*--- Define solver parameters needed for execution of destructor ---*/ - - if (config->GetKind_ConvNumScheme_Flow() == SPACE_CENTERED) space_centered = true; - else space_centered = false; - - if (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT) euler_implicit = true; - else euler_implicit = false; - - if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) least_squares = true; - else least_squares = false; - - /*--- Communicate and store volume and the number of neighbors for - any dual CVs that lie on on periodic markers. ---*/ - - for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { - InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_VOLUME); - CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_VOLUME); - InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_NEIGHBORS); - CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_NEIGHBORS); - } - SetImplicitPeriodic(euler_implicit); - if (iMesh == MESH_0) SetRotatePeriodic(true); - - /*--- Perform the MPI communication of the solution ---*/ - - InitiateComms(geometry, config, SOLUTION); - CompleteComms(geometry, config, SOLUTION); - - /* Store the initial CFL number for all grid points. */ - - const su2double CFL = config->GetCFL(MGLevel); - for (iPoint = 0; iPoint < nPoint; iPoint++) { - nodes->SetLocalCFL(iPoint, CFL); - } - Min_CFL_Local = CFL; - Max_CFL_Local = CFL; - Avg_CFL_Local = CFL; - - /*--- Add the solver name (max 8 characters) ---*/ - SolverName = "INC.FLOW"; - -} - -CIncNSSolver::~CIncNSSolver(void) { - - unsigned short iMarker, iDim; - - unsigned long iVertex; - - if (CD_Visc != NULL) delete [] CD_Visc; - if (CL_Visc != NULL) delete [] CL_Visc; - if (CSF_Visc != NULL) delete [] CSF_Visc; - if (CMx_Visc != NULL) delete [] CMx_Visc; - if (CMy_Visc != NULL) delete [] CMy_Visc; - if (CMz_Visc != NULL) delete [] CMz_Visc; - if (CoPx_Visc != NULL) delete [] CoPx_Visc; - if (CoPy_Visc != NULL) delete [] CoPy_Visc; - if (CoPz_Visc != NULL) delete [] CoPz_Visc; - if (CFx_Visc != NULL) delete [] CFx_Visc; - if (CFy_Visc != NULL) delete [] CFy_Visc; - if (CFz_Visc != NULL) delete [] CFz_Visc; - if (CEff_Visc != NULL) delete [] CEff_Visc; - if (CMerit_Visc != NULL) delete [] CMerit_Visc; - if (CT_Visc != NULL) delete [] CT_Visc; - if (CQ_Visc != NULL) delete [] CQ_Visc; - if (HF_Visc != NULL) delete [] HF_Visc; - if (MaxHF_Visc != NULL) delete [] MaxHF_Visc; - if (ForceViscous != NULL) delete [] ForceViscous; - if (MomentViscous != NULL) delete [] MomentViscous; - - if (Surface_CL_Visc != NULL) delete [] Surface_CL_Visc; - if (Surface_CD_Visc != NULL) delete [] Surface_CD_Visc; - if (Surface_CSF_Visc != NULL) delete [] Surface_CSF_Visc; - if (Surface_CEff_Visc != NULL) delete [] Surface_CEff_Visc; - if (Surface_CFx_Visc != NULL) delete [] Surface_CFx_Visc; - if (Surface_CFy_Visc != NULL) delete [] Surface_CFy_Visc; - if (Surface_CFz_Visc != NULL) delete [] Surface_CFz_Visc; - if (Surface_CMx_Visc != NULL) delete [] Surface_CMx_Visc; - if (Surface_CMy_Visc != NULL) delete [] Surface_CMy_Visc; - if (Surface_CMz_Visc != NULL) delete [] Surface_CMz_Visc; - if (Surface_HF_Visc != NULL) delete [] Surface_HF_Visc; - if (Surface_MaxHF_Visc != NULL) delete [] Surface_MaxHF_Visc; - - if (CSkinFriction != NULL) { - for (iMarker = 0; iMarker < nMarker; iMarker++) { - for (iDim = 0; iDim < nDim; iDim++) { - delete [] CSkinFriction[iMarker][iDim]; - } - delete [] CSkinFriction[iMarker]; - } - delete [] CSkinFriction; - } - - if (HeatConjugateVar != NULL) { - for (iMarker = 0; iMarker < nMarker; iMarker++) { - for (iVertex = 0; iVertex < nVertex[iMarker]; iVertex++) { - delete [] HeatConjugateVar[iMarker][iVertex]; - } - delete [] HeatConjugateVar[iMarker]; - } - delete [] HeatConjugateVar; - } - -} - -void CIncNSSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output) { - - unsigned long iPoint, ErrorCounter = 0; - su2double StrainMag = 0.0, Omega = 0.0, *Vorticity; - - unsigned long InnerIter = config->GetInnerIter(); - bool cont_adjoint = config->GetContinuous_Adjoint(); - bool disc_adjoint = config->GetDiscrete_Adjoint(); - bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); - bool center = ((config->GetKind_ConvNumScheme_Flow() == SPACE_CENTERED) || (cont_adjoint && config->GetKind_ConvNumScheme_AdjFlow() == SPACE_CENTERED)); - bool center_jst = center && config->GetKind_Centered_Flow() == JST; - bool limiter_flow = (config->GetKind_SlopeLimit_Flow() != NO_LIMITER) && (InnerIter <= config->GetLimiterIter()); - bool limiter_turb = (config->GetKind_SlopeLimit_Turb() != NO_LIMITER) && (InnerIter <= config->GetLimiterIter()); - bool limiter_adjflow = (cont_adjoint && (config->GetKind_SlopeLimit_AdjFlow() != NO_LIMITER) && (InnerIter <= config->GetLimiterIter())); - bool van_albada = config->GetKind_SlopeLimit_Flow() == VAN_ALBADA_EDGE; - bool outlet = ((config->GetnMarker_Outlet() != 0)); - - /*--- Set the primitive variables ---*/ - - ErrorCounter = SetPrimitive_Variables(solver_container, config, Output); - - /*--- Compute gradient for MUSCL reconstruction. ---*/ - - if (config->GetReconstructionGradientRequired() && (iMesh == MESH_0)) { - if (config->GetKind_Gradient_Method_Recon() == GREEN_GAUSS) - SetPrimitive_Gradient_GG(geometry, config, true); - if (config->GetKind_Gradient_Method_Recon() == LEAST_SQUARES) - SetPrimitive_Gradient_LS(geometry, config, true); - if (config->GetKind_Gradient_Method_Recon() == WEIGHTED_LEAST_SQUARES) - SetPrimitive_Gradient_LS(geometry, config, true); - } - - /*--- Compute gradient of the primitive variables ---*/ - - if (config->GetKind_Gradient_Method() == GREEN_GAUSS) { - SetPrimitive_Gradient_GG(geometry, config); - } - if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) { - SetPrimitive_Gradient_LS(geometry, config); - } - - /*--- Compute the limiter in case we need it in the turbulence model - or to limit the viscous terms (check this logic with JST and 2nd order turbulence model) ---*/ - - if ((iMesh == MESH_0) && (limiter_flow || limiter_turb || limiter_adjflow) - && !Output && !van_albada) { SetPrimitive_Limiter(geometry, config); } - - /*--- Artificial dissipation for centered schemes. ---*/ - - if (center && !Output) { - SetMax_Eigenvalue(geometry, config); - if ((center_jst) && (iMesh == MESH_0)) { - SetCentered_Dissipation_Sensor(geometry, config); - SetUndivided_Laplacian(geometry, config); - } - } - - /*--- Update the beta value based on the maximum velocity / viscosity. ---*/ - - SetBeta_Parameter(geometry, solver_container, config, iMesh); - - /*--- Compute properties needed for mass flow BCs. ---*/ - - if (outlet) GetOutlet_Properties(geometry, config, iMesh, Output); - - /*--- Evaluate the vorticity and strain rate magnitude ---*/ - - solver_container[FLOW_SOL]->GetNodes()->SetVorticity_StrainMag(); - - StrainMag_Max = 0.0; Omega_Max = 0.0; - for (iPoint = 0; iPoint < nPoint; iPoint++) { - - StrainMag = solver_container[FLOW_SOL]->GetNodes()->GetStrainMag(iPoint); - Vorticity = solver_container[FLOW_SOL]->GetNodes()->GetVorticity(iPoint); - Omega = sqrt(Vorticity[0]*Vorticity[0]+ Vorticity[1]*Vorticity[1]+ Vorticity[2]*Vorticity[2]); - - StrainMag_Max = max(StrainMag_Max, StrainMag); - Omega_Max = max(Omega_Max, Omega); - - } - - /*--- Initialize the Jacobian matrices ---*/ - - if (implicit && !disc_adjoint) Jacobian.SetValZero(); - - /*--- Error message ---*/ - - if (config->GetComm_Level() == COMM_FULL) { - -#ifdef HAVE_MPI - unsigned long MyErrorCounter = ErrorCounter; ErrorCounter = 0; - su2double MyOmega_Max = Omega_Max; Omega_Max = 0.0; - su2double MyStrainMag_Max = StrainMag_Max; StrainMag_Max = 0.0; - - SU2_MPI::Allreduce(&MyErrorCounter, &ErrorCounter, 1, MPI_UNSIGNED_LONG, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyStrainMag_Max, &StrainMag_Max, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyOmega_Max, &Omega_Max, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); -#endif - - if (iMesh == MESH_0) { - config->SetNonphysical_Points(ErrorCounter); - solver_container[FLOW_SOL]->SetStrainMag_Max(StrainMag_Max); - solver_container[FLOW_SOL]->SetOmega_Max(Omega_Max); - } - - } - -} - -unsigned long CIncNSSolver::SetPrimitive_Variables(CSolver **solver_container, CConfig *config, bool Output) { - - unsigned long iPoint, nonPhysicalPoints = 0; - su2double eddy_visc = 0.0, turb_ke = 0.0, DES_LengthScale = 0.0; - unsigned short turb_model = config->GetKind_Turb_Model(); - bool physical = true; - - bool tkeNeeded = ((turb_model == SST) || (turb_model == SST_SUST)); - - for (iPoint = 0; iPoint < nPoint; iPoint++) { - - /*--- Retrieve the value of the kinetic energy (if needed) ---*/ - - if (turb_model != NONE) { - eddy_visc = solver_container[TURB_SOL]->GetNodes()->GetmuT(iPoint); - if (tkeNeeded) turb_ke = solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0); - - if (config->GetKind_HybridRANSLES() != NO_HYBRIDRANSLES){ - DES_LengthScale = solver_container[TURB_SOL]->GetNodes()->GetDES_LengthScale(iPoint); - } - } - - /*--- Incompressible flow, primitive variables --- */ - - physical = static_cast(nodes)->SetPrimVar(iPoint,eddy_visc, turb_ke, FluidModel); - - /* Check for non-realizable states for reporting. */ - - if (!physical) nonPhysicalPoints++; - - /*--- Set the DES length scale ---*/ - - nodes->SetDES_LengthScale(iPoint,DES_LengthScale); - - /*--- Initialize the convective, source and viscous residual vector ---*/ - - if (!Output) LinSysRes.SetBlock_Zero(iPoint); - - } - - return nonPhysicalPoints; - -} - -void CIncNSSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned long Iteration) { - - su2double Mean_BetaInc2, *Normal, Area, Vol, Mean_SoundSpeed = 0.0, Mean_ProjVel = 0.0, Lambda, Local_Delta_Time, Local_Delta_Time_Visc, - Global_Delta_Time = 1E6, Mean_LaminarVisc = 0.0, Mean_EddyVisc = 0.0, Mean_Density = 0.0, Mean_Thermal_Conductivity = 0.0, Mean_Cv = 0.0, Lambda_1, Lambda_2, K_v = 0.25, Global_Delta_UnstTimeND; - unsigned long iEdge, iVertex, iPoint = 0, jPoint = 0; - unsigned short iDim, iMarker; - su2double ProjVel, ProjVel_i, ProjVel_j; - - bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); - bool dual_time = ((config->GetTime_Marching() == DT_STEPPING_1ST) || - (config->GetTime_Marching() == DT_STEPPING_2ND)); - bool energy = config->GetEnergy_Equation(); - - Min_Delta_Time = 1.E30; Max_Delta_Time = 0.0; - - /*--- Set maximum inviscid eigenvalue to zero, and compute sound speed and viscosity ---*/ - - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - nodes->SetMax_Lambda_Inv(iPoint,0.0); - nodes->SetMax_Lambda_Visc(iPoint,0.0); - } - - /*--- Loop interior edges ---*/ - - for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - - /*--- Point identification, Normal vector and area ---*/ - - iPoint = geometry->edge[iEdge]->GetNode(0); - jPoint = geometry->edge[iEdge]->GetNode(1); - - Normal = geometry->edge[iEdge]->GetNormal(); - Area = 0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); - - /*--- Mean Values ---*/ - - Mean_ProjVel = 0.5 * (nodes->GetProjVel(iPoint,Normal) + nodes->GetProjVel(jPoint,Normal)); - Mean_BetaInc2 = 0.5 * (nodes->GetBetaInc2(iPoint) + nodes->GetBetaInc2(jPoint)); - Mean_Density = 0.5 * (nodes->GetDensity(iPoint) + nodes->GetDensity(jPoint)); - Mean_SoundSpeed = sqrt(Mean_BetaInc2*Area*Area); - - /*--- Adjustment for grid movement ---*/ - - if (dynamic_grid) { - su2double *GridVel_i = geometry->node[iPoint]->GetGridVel(); - su2double *GridVel_j = geometry->node[jPoint]->GetGridVel(); - ProjVel_i = 0.0; ProjVel_j =0.0; - for (iDim = 0; iDim < nDim; iDim++) { - ProjVel_i += GridVel_i[iDim]*Normal[iDim]; - ProjVel_j += GridVel_j[iDim]*Normal[iDim]; - } - Mean_ProjVel -= 0.5 * (ProjVel_i + ProjVel_j); - } - - /*--- Inviscid contribution ---*/ - - Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; - if (geometry->node[iPoint]->GetDomain()) nodes->AddMax_Lambda_Inv(iPoint,Lambda); - if (geometry->node[jPoint]->GetDomain()) nodes->AddMax_Lambda_Inv(jPoint,Lambda); - - /*--- Viscous contribution ---*/ - - Mean_LaminarVisc = 0.5*(nodes->GetLaminarViscosity(iPoint) + nodes->GetLaminarViscosity(jPoint)); - Mean_EddyVisc = 0.5*(nodes->GetEddyViscosity(iPoint) + nodes->GetEddyViscosity(jPoint)); - Mean_Density = 0.5*(nodes->GetDensity(iPoint) + nodes->GetDensity(jPoint)); - Mean_Thermal_Conductivity = 0.5*(nodes->GetThermalConductivity(iPoint) + nodes->GetThermalConductivity(jPoint)); - Mean_Cv = 0.5*(nodes->GetSpecificHeatCv(iPoint) + nodes->GetSpecificHeatCv(jPoint)); - - Lambda_1 = (4.0/3.0)*(Mean_LaminarVisc + Mean_EddyVisc); - Lambda_2 = 0.0; - if (energy) Lambda_2 = (1.0/Mean_Cv)*Mean_Thermal_Conductivity; - Lambda = (Lambda_1 + Lambda_2)*Area*Area/Mean_Density; - - if (geometry->node[iPoint]->GetDomain()) nodes->AddMax_Lambda_Visc(iPoint,Lambda); - if (geometry->node[jPoint]->GetDomain()) nodes->AddMax_Lambda_Visc(jPoint,Lambda); - - } - - /*--- Loop boundary edges ---*/ - - for (iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { - if ((config->GetMarker_All_KindBC(iMarker) != INTERNAL_BOUNDARY) && - (config->GetMarker_All_KindBC(iMarker) != PERIODIC_BOUNDARY)) { - for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { - - /*--- Point identification, Normal vector and area ---*/ - - iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); - - /*--- Mean Values ---*/ - - Mean_ProjVel = nodes->GetProjVel(iPoint,Normal); - Mean_BetaInc2 = nodes->GetBetaInc2(iPoint); - Mean_Density = nodes->GetDensity(iPoint); - Mean_SoundSpeed = sqrt(Mean_BetaInc2*Area*Area); - - /*--- Adjustment for grid movement ---*/ - - if (dynamic_grid) { - su2double *GridVel = geometry->node[iPoint]->GetGridVel(); - ProjVel = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - ProjVel += GridVel[iDim]*Normal[iDim]; - Mean_ProjVel -= ProjVel; - } - - /*--- Inviscid contribution ---*/ - - Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; - if (geometry->node[iPoint]->GetDomain()) { - nodes->AddMax_Lambda_Inv(iPoint,Lambda); - } - - /*--- Viscous contribution ---*/ - - Mean_LaminarVisc = nodes->GetLaminarViscosity(iPoint); - Mean_EddyVisc = nodes->GetEddyViscosity(iPoint); - Mean_Density = nodes->GetDensity(iPoint); - Mean_Thermal_Conductivity = nodes->GetThermalConductivity(iPoint); - Mean_Cv = nodes->GetSpecificHeatCv(iPoint); - - Lambda_1 = (4.0/3.0)*(Mean_LaminarVisc + Mean_EddyVisc); - Lambda_2 = 0.0; - if (energy) Lambda_2 = (1.0/Mean_Cv)*Mean_Thermal_Conductivity; - Lambda = (Lambda_1 + Lambda_2)*Area*Area/Mean_Density; - - if (geometry->node[iPoint]->GetDomain()) nodes->AddMax_Lambda_Visc(iPoint,Lambda); - - } - } - } - - /*--- Each element uses their own speed, steady state simulation ---*/ - - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - - Vol = geometry->node[iPoint]->GetVolume(); - - if (Vol != 0.0) { - Local_Delta_Time = nodes->GetLocalCFL(iPoint)*Vol / nodes->GetMax_Lambda_Inv(iPoint); - Local_Delta_Time_Visc = nodes->GetLocalCFL(iPoint)*K_v*Vol*Vol/ nodes->GetMax_Lambda_Visc(iPoint); - Local_Delta_Time = min(Local_Delta_Time, Local_Delta_Time_Visc); - Global_Delta_Time = min(Global_Delta_Time, Local_Delta_Time); - Min_Delta_Time = min(Min_Delta_Time, Local_Delta_Time); - Max_Delta_Time = max(Max_Delta_Time, Local_Delta_Time); - if (Local_Delta_Time > config->GetMax_DeltaTime()) - Local_Delta_Time = config->GetMax_DeltaTime(); - nodes->SetDelta_Time(iPoint,Local_Delta_Time); - } - else { - nodes->SetDelta_Time(iPoint,0.0); - } - - } - - /*--- Compute the max and the min dt (in parallel) ---*/ - if (config->GetComm_Level() == COMM_FULL) { -#ifdef HAVE_MPI - su2double rbuf_time, sbuf_time; - sbuf_time = Min_Delta_Time; - SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, MPI_COMM_WORLD); - SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); - Min_Delta_Time = rbuf_time; - - sbuf_time = Max_Delta_Time; - SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MAX, MASTER_NODE, MPI_COMM_WORLD); - SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); - Max_Delta_Time = rbuf_time; -#endif - } - - /*--- For exact time solution use the minimum delta time of the whole mesh ---*/ - if (config->GetTime_Marching() == TIME_STEPPING) { -#ifdef HAVE_MPI - su2double rbuf_time, sbuf_time; - sbuf_time = Global_Delta_Time; - SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, MPI_COMM_WORLD); - SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); - Global_Delta_Time = rbuf_time; -#endif - /*--- If the unsteady CFL is set to zero, it uses the defined - unsteady time step, otherwise it computes the time step based - on the unsteady CFL ---*/ - - if (config->GetUnst_CFL() == 0.0) { - Global_Delta_Time = config->GetDelta_UnstTime(); - } - config->SetDelta_UnstTimeND(Global_Delta_Time); - for (iPoint = 0; iPoint < nPointDomain; iPoint++){ - - /*--- Sets the regular CFL equal to the unsteady CFL ---*/ - - nodes->SetLocalCFL(iPoint, config->GetUnst_CFL()); - nodes->SetDelta_Time(iPoint, Global_Delta_Time); - Min_Delta_Time = Global_Delta_Time; - Max_Delta_Time = Global_Delta_Time; - - } - } - - /*--- Recompute the unsteady time step for the dual time strategy - if the unsteady CFL is diferent from 0 ---*/ - if ((dual_time) && (Iteration == 0) && (config->GetUnst_CFL() != 0.0) && (iMesh == MESH_0)) { - - Global_Delta_UnstTimeND = 1e30; - for (iPoint = 0; iPoint < nPointDomain; iPoint++){ - Global_Delta_UnstTimeND = min(Global_Delta_UnstTimeND,config->GetUnst_CFL()*Global_Delta_Time/nodes->GetLocalCFL(iPoint)); - } - -#ifdef HAVE_MPI - su2double rbuf_time, sbuf_time; - sbuf_time = Global_Delta_UnstTimeND; - SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, MPI_COMM_WORLD); - SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); - Global_Delta_UnstTimeND = rbuf_time; -#endif - config->SetDelta_UnstTimeND(Global_Delta_UnstTimeND); - } - - /*--- The pseudo local time (explicit integration) cannot be greater than the physical time ---*/ - if (dual_time) - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - if (!implicit) { - Local_Delta_Time = min((2.0/3.0)*config->GetDelta_UnstTimeND(), nodes->GetDelta_Time(iPoint)); - nodes->SetDelta_Time(iPoint,Local_Delta_Time); - } - } - -} - -void CIncNSSolver::Viscous_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh, unsigned short iRKStep) { - - unsigned long iPoint, jPoint, iEdge; - - bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); - - for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - - /*--- Points, coordinates and normal vector in edge ---*/ - - iPoint = geometry->edge[iEdge]->GetNode(0); - jPoint = geometry->edge[iEdge]->GetNode(1); - numerics->SetCoord(geometry->node[iPoint]->GetCoord(), - geometry->node[jPoint]->GetCoord()); - numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); - - /*--- Primitive and secondary variables ---*/ - - numerics->SetPrimitive(nodes->GetPrimitive(iPoint), - nodes->GetPrimitive(jPoint)); - - /*--- Gradient and limiters ---*/ - - numerics->SetPrimVarGradient(nodes->GetGradient_Primitive(iPoint), - nodes->GetGradient_Primitive(jPoint)); - - /*--- Turbulent kinetic energy ---*/ - - if ((config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST)) - numerics->SetTurbKineticEnergy(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0), - solver_container[TURB_SOL]->GetNodes()->GetSolution(jPoint,0)); - - /*--- Compute and update residual ---*/ - - numerics->ComputeResidual(Res_Visc, Jacobian_i, Jacobian_j, config); - - LinSysRes.SubtractBlock(iPoint, Res_Visc); - LinSysRes.AddBlock(jPoint, Res_Visc); - - /*--- Implicit part ---*/ - - if (implicit) { - Jacobian.UpdateBlocks(iEdge, iPoint, jPoint, Jacobian_i, Jacobian_j); - } - - } - -} - -void CIncNSSolver::Friction_Forces(CGeometry *geometry, CConfig *config) { - - unsigned long iVertex, iPoint, iPointNormal; - unsigned short Boundary, Monitoring, iMarker, iMarker_Monitoring, iDim, jDim; - su2double Viscosity = 0.0, div_vel, *Normal, MomentDist[3] = {0.0, 0.0, 0.0}, WallDist[3] = {0.0, 0.0, 0.0}, - *Coord, *Coord_Normal, Area, WallShearStress, TauNormal, factor, RefVel2 = 0.0, - RefDensity = 0.0, Density = 0.0, WallDistMod, FrictionVel, UnitNormal[3] = {0.0, 0.0, 0.0}, TauElem[3] = {0.0, 0.0, 0.0}, TauTangent[3] = {0.0, 0.0, 0.0}, - Tau[3][3] = {{0.0, 0.0, 0.0},{0.0, 0.0, 0.0},{0.0, 0.0, 0.0}}, Force[3] = {0.0, 0.0, 0.0}, - Grad_Vel[3][3] = {{0.0, 0.0, 0.0},{0.0, 0.0, 0.0},{0.0, 0.0, 0.0}}, - delta[3][3] = {{1.0, 0.0, 0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}}, - Grad_Temp[3] = {0.0, 0.0, 0.0}, GradTemperature, thermal_conductivity, MaxNorm = 8.0; - su2double MomentX_Force[3] = {0.0,0.0,0.0}, MomentY_Force[3] = {0.0,0.0,0.0}, MomentZ_Force[3] = {0.0,0.0,0.0}; - su2double AxiFactor; - -#ifdef HAVE_MPI - su2double MyAllBound_CD_Visc, MyAllBound_CL_Visc, MyAllBound_CSF_Visc, MyAllBound_CMx_Visc, MyAllBound_CMy_Visc, MyAllBound_CMz_Visc, MyAllBound_CoPx_Visc, MyAllBound_CoPy_Visc, MyAllBound_CoPz_Visc, MyAllBound_CFx_Visc, MyAllBound_CFy_Visc, MyAllBound_CFz_Visc, MyAllBound_CT_Visc, MyAllBound_CQ_Visc, MyAllBound_HF_Visc, MyAllBound_MaxHF_Visc, *MySurface_CL_Visc = NULL, *MySurface_CD_Visc = NULL, *MySurface_CSF_Visc = NULL, *MySurface_CEff_Visc = NULL, *MySurface_CFx_Visc = NULL, *MySurface_CFy_Visc = NULL, *MySurface_CFz_Visc = NULL, *MySurface_CMx_Visc = NULL, *MySurface_CMy_Visc = NULL, *MySurface_CMz_Visc = NULL, *MySurface_HF_Visc = NULL, *MySurface_MaxHF_Visc = NULL; -#endif - - string Marker_Tag, Monitoring_Tag; - - su2double Alpha = config->GetAoA()*PI_NUMBER/180.0; - su2double Beta = config->GetAoS()*PI_NUMBER/180.0; - su2double RefArea = config->GetRefArea(); - su2double RefLength = config->GetRefLength(); - su2double RefHeatFlux = config->GetHeat_Flux_Ref(); - su2double *Origin = NULL; - - if (config->GetnMarker_Monitoring() != 0) { Origin = config->GetRefOriginMoment(0); } - - bool axisymmetric = config->GetAxisymmetric(); - bool energy = config->GetEnergy_Equation(); - - /*--- Evaluate reference values for non-dimensionalization. - For dimensional or non-dim based on initial values, use - the far-field state (inf). For a custom non-dim based - on user-provided reference values, use the ref values - to compute the forces. ---*/ - - if ((config->GetRef_Inc_NonDim() == DIMENSIONAL) || - (config->GetRef_Inc_NonDim() == INITIAL_VALUES)) { - RefDensity = Density_Inf; - RefVel2 = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - RefVel2 += Velocity_Inf[iDim]*Velocity_Inf[iDim]; - } - else if (config->GetRef_Inc_NonDim() == REFERENCE_VALUES) { - RefDensity = config->GetInc_Density_Ref(); - RefVel2 = config->GetInc_Velocity_Ref()*config->GetInc_Velocity_Ref(); - } - - /*--- Compute factor for force coefficients. ---*/ - - factor = 1.0 / (0.5*RefDensity*RefArea*RefVel2); - - /*--- Variables initialization ---*/ - - AllBound_CD_Visc = 0.0; AllBound_CL_Visc = 0.0; AllBound_CSF_Visc = 0.0; - AllBound_CMx_Visc = 0.0; AllBound_CMy_Visc = 0.0; AllBound_CMz_Visc = 0.0; - AllBound_CFx_Visc = 0.0; AllBound_CFy_Visc = 0.0; AllBound_CFz_Visc = 0.0; - AllBound_CoPx_Visc = 0.0; AllBound_CoPy_Visc = 0.0; AllBound_CoPz_Visc = 0.0; - AllBound_CT_Visc = 0.0; AllBound_CQ_Visc = 0.0; AllBound_CMerit_Visc = 0.0; - AllBound_HF_Visc = 0.0; AllBound_MaxHF_Visc = 0.0; AllBound_CEff_Visc = 0.0; - - for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { - Surface_CL_Visc[iMarker_Monitoring] = 0.0; Surface_CD_Visc[iMarker_Monitoring] = 0.0; - Surface_CSF_Visc[iMarker_Monitoring] = 0.0; Surface_CEff_Visc[iMarker_Monitoring] = 0.0; - Surface_CFx_Visc[iMarker_Monitoring] = 0.0; Surface_CFy_Visc[iMarker_Monitoring] = 0.0; - Surface_CFz_Visc[iMarker_Monitoring] = 0.0; Surface_CMx_Visc[iMarker_Monitoring] = 0.0; - Surface_CMy_Visc[iMarker_Monitoring] = 0.0; Surface_CMz_Visc[iMarker_Monitoring] = 0.0; - Surface_HF_Visc[iMarker_Monitoring] = 0.0; Surface_MaxHF_Visc[iMarker_Monitoring] = 0.0; - } - - /*--- Loop over the Navier-Stokes markers ---*/ - - for (iMarker = 0; iMarker < nMarker; iMarker++) { - - Boundary = config->GetMarker_All_KindBC(iMarker); - Monitoring = config->GetMarker_All_Monitoring(iMarker); - - /*--- Obtain the origin for the moment computation for a particular marker ---*/ - - if (Monitoring == YES) { - for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { - Monitoring_Tag = config->GetMarker_Monitoring_TagBound(iMarker_Monitoring); - Marker_Tag = config->GetMarker_All_TagBound(iMarker); - if (Marker_Tag == Monitoring_Tag) - Origin = config->GetRefOriginMoment(iMarker_Monitoring); - } - } - - if ((Boundary == HEAT_FLUX) || (Boundary == ISOTHERMAL) || (Boundary == CHT_WALL_INTERFACE)) { - - /*--- Forces initialization at each Marker ---*/ - - CD_Visc[iMarker] = 0.0; CL_Visc[iMarker] = 0.0; CSF_Visc[iMarker] = 0.0; - CMx_Visc[iMarker] = 0.0; CMy_Visc[iMarker] = 0.0; CMz_Visc[iMarker] = 0.0; - CFx_Visc[iMarker] = 0.0; CFy_Visc[iMarker] = 0.0; CFz_Visc[iMarker] = 0.0; - CoPx_Visc[iMarker] = 0.0; CoPy_Visc[iMarker] = 0.0; CoPz_Visc[iMarker] = 0.0; - CT_Visc[iMarker] = 0.0; CQ_Visc[iMarker] = 0.0; CMerit_Visc[iMarker] = 0.0; - HF_Visc[iMarker] = 0.0; MaxHF_Visc[iMarker] = 0.0; CEff_Visc[iMarker] = 0.0; - - for (iDim = 0; iDim < nDim; iDim++) ForceViscous[iDim] = 0.0; - MomentViscous[0] = 0.0; MomentViscous[1] = 0.0; MomentViscous[2] = 0.0; - MomentX_Force[0] = 0.0; MomentX_Force[1] = 0.0; MomentX_Force[2] = 0.0; - MomentY_Force[0] = 0.0; MomentY_Force[1] = 0.0; MomentY_Force[2] = 0.0; - MomentZ_Force[0] = 0.0; MomentZ_Force[1] = 0.0; MomentZ_Force[2] = 0.0; - - /*--- Loop over the vertices to compute the forces ---*/ - - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - - iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - iPointNormal = geometry->vertex[iMarker][iVertex]->GetNormal_Neighbor(); - - Coord = geometry->node[iPoint]->GetCoord(); - Coord_Normal = geometry->node[iPointNormal]->GetCoord(); - - Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - - for (iDim = 0; iDim < nDim; iDim++) { - for (jDim = 0 ; jDim < nDim; jDim++) { - Grad_Vel[iDim][jDim] = nodes->GetGradient_Primitive(iPoint,iDim+1, jDim); - } - Grad_Temp[iDim] = nodes->GetGradient_Primitive(iPoint,nDim+1, iDim); - } - - Viscosity = nodes->GetLaminarViscosity(iPoint); - Density = nodes->GetDensity(iPoint); - - Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); - for (iDim = 0; iDim < nDim; iDim++) { - UnitNormal[iDim] = Normal[iDim]/Area; - } - - /*--- Evaluate Tau ---*/ - - div_vel = 0.0; for (iDim = 0; iDim < nDim; iDim++) div_vel += Grad_Vel[iDim][iDim]; - - for (iDim = 0; iDim < nDim; iDim++) { - for (jDim = 0 ; jDim < nDim; jDim++) { - Tau[iDim][jDim] = Viscosity*(Grad_Vel[jDim][iDim] + Grad_Vel[iDim][jDim]) - TWO3*Viscosity*div_vel*delta[iDim][jDim]; - } - } - - /*--- Project Tau in each surface element ---*/ - - for (iDim = 0; iDim < nDim; iDim++) { - TauElem[iDim] = 0.0; - for (jDim = 0; jDim < nDim; jDim++) { - TauElem[iDim] += Tau[iDim][jDim]*UnitNormal[jDim]; - } - } - - /*--- Compute wall shear stress (using the stress tensor). Compute wall skin friction coefficient, and heat flux on the wall ---*/ - - TauNormal = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - TauNormal += TauElem[iDim] * UnitNormal[iDim]; - - WallShearStress = 0.0; - for (iDim = 0; iDim < nDim; iDim++) { - TauTangent[iDim] = TauElem[iDim] - TauNormal * UnitNormal[iDim]; - CSkinFriction[iMarker][iDim][iVertex] = TauTangent[iDim] / (0.5*RefDensity*RefVel2); - WallShearStress += TauTangent[iDim] * TauTangent[iDim]; - } - WallShearStress = sqrt(WallShearStress); - - for (iDim = 0; iDim < nDim; iDim++) WallDist[iDim] = (Coord[iDim] - Coord_Normal[iDim]); - WallDistMod = 0.0; for (iDim = 0; iDim < nDim; iDim++) WallDistMod += WallDist[iDim]*WallDist[iDim]; WallDistMod = sqrt(WallDistMod); - - /*--- Compute y+ and non-dimensional velocity ---*/ - - FrictionVel = sqrt(fabs(WallShearStress)/Density); - YPlus[iMarker][iVertex] = WallDistMod*FrictionVel/(Viscosity/Density); - - /*--- Compute total and maximum heat flux on the wall ---*/ - - GradTemperature = 0.0; - if (energy) { - for (iDim = 0; iDim < nDim; iDim++) - GradTemperature -= Grad_Temp[iDim]*UnitNormal[iDim]; - } - - thermal_conductivity = nodes->GetThermalConductivity(iPoint); - HeatFlux[iMarker][iVertex] = -thermal_conductivity*GradTemperature*RefHeatFlux; - - /*--- Note that y+, and heat are computed at the - halo cells (for visualization purposes), but not the forces ---*/ - - if ((geometry->node[iPoint]->GetDomain()) && (Monitoring == YES)) { - - /*--- Axisymmetric simulations ---*/ - - if (axisymmetric) AxiFactor = 2.0*PI_NUMBER*geometry->node[iPoint]->GetCoord(1); - else AxiFactor = 1.0; - - /*--- Force computation ---*/ - - for (iDim = 0; iDim < nDim; iDim++) { - Force[iDim] = TauElem[iDim] * Area * factor * AxiFactor; - ForceViscous[iDim] += Force[iDim]; - MomentDist[iDim] = Coord[iDim] - Origin[iDim]; - } - - /*--- Moment with respect to the reference axis ---*/ - - if (iDim == 3) { - MomentViscous[0] += (Force[2]*MomentDist[1] - Force[1]*MomentDist[2])/RefLength; - MomentX_Force[1] += (-Force[1]*Coord[2]); - MomentX_Force[2] += (Force[2]*Coord[1]); - - MomentViscous[1] += (Force[0]*MomentDist[2] - Force[2]*MomentDist[0])/RefLength; - MomentY_Force[2] += (-Force[2]*Coord[0]); - MomentY_Force[0] += (Force[0]*Coord[2]); - } - MomentViscous[2] += (Force[1]*MomentDist[0] - Force[0]*MomentDist[1])/RefLength; - MomentZ_Force[0] += (-Force[0]*Coord[1]); - MomentZ_Force[1] += (Force[1]*Coord[0]); - - HF_Visc[iMarker] += HeatFlux[iMarker][iVertex]*Area; - MaxHF_Visc[iMarker] += pow(HeatFlux[iMarker][iVertex], MaxNorm); - - } - - } - - /*--- Project forces and store the non-dimensional coefficients ---*/ - - if (Monitoring == YES) { - if (nDim == 2) { - CD_Visc[iMarker] = ForceViscous[0]*cos(Alpha) + ForceViscous[1]*sin(Alpha); - CL_Visc[iMarker] = -ForceViscous[0]*sin(Alpha) + ForceViscous[1]*cos(Alpha); - CEff_Visc[iMarker] = CL_Visc[iMarker] / (CD_Visc[iMarker]+EPS); - CMz_Visc[iMarker] = MomentViscous[2]; - CFx_Visc[iMarker] = ForceViscous[0]; - CFy_Visc[iMarker] = ForceViscous[1]; - CoPx_Visc[iMarker] = MomentZ_Force[1]; - CoPy_Visc[iMarker] = -MomentZ_Force[0]; - CT_Visc[iMarker] = -CFx_Visc[iMarker]; - CQ_Visc[iMarker] = -CMz_Visc[iMarker]; - CMerit_Visc[iMarker] = CT_Visc[iMarker] / (CQ_Visc[iMarker]+EPS); - MaxHF_Visc[iMarker] = pow(MaxHF_Visc[iMarker], 1.0/MaxNorm); - } - if (nDim == 3) { - CD_Visc[iMarker] = ForceViscous[0]*cos(Alpha)*cos(Beta) + ForceViscous[1]*sin(Beta) + ForceViscous[2]*sin(Alpha)*cos(Beta); - CL_Visc[iMarker] = -ForceViscous[0]*sin(Alpha) + ForceViscous[2]*cos(Alpha); - CSF_Visc[iMarker] = -ForceViscous[0]*sin(Beta)*cos(Alpha) + ForceViscous[1]*cos(Beta) - ForceViscous[2]*sin(Beta)*sin(Alpha); - CEff_Visc[iMarker] = CL_Visc[iMarker]/(CD_Visc[iMarker] + EPS); - CMx_Visc[iMarker] = MomentViscous[0]; - CMy_Visc[iMarker] = MomentViscous[1]; - CMz_Visc[iMarker] = MomentViscous[2]; - CFx_Visc[iMarker] = ForceViscous[0]; - CFy_Visc[iMarker] = ForceViscous[1]; - CFz_Visc[iMarker] = ForceViscous[2]; - CoPx_Visc[iMarker] = -MomentY_Force[0]; - CoPz_Visc[iMarker] = MomentY_Force[2]; - CT_Visc[iMarker] = -CFz_Visc[iMarker]; - CQ_Visc[iMarker] = -CMz_Visc[iMarker]; - CMerit_Visc[iMarker] = CT_Visc[iMarker] / (CQ_Visc[iMarker] + EPS); - MaxHF_Visc[iMarker] = pow(MaxHF_Visc[iMarker], 1.0/MaxNorm); - } - - AllBound_CD_Visc += CD_Visc[iMarker]; - AllBound_CL_Visc += CL_Visc[iMarker]; - AllBound_CSF_Visc += CSF_Visc[iMarker]; - AllBound_CMx_Visc += CMx_Visc[iMarker]; - AllBound_CMy_Visc += CMy_Visc[iMarker]; - AllBound_CMz_Visc += CMz_Visc[iMarker]; - AllBound_CFx_Visc += CFx_Visc[iMarker]; - AllBound_CFy_Visc += CFy_Visc[iMarker]; - AllBound_CFz_Visc += CFz_Visc[iMarker]; - AllBound_CoPx_Visc += CoPx_Visc[iMarker]; - AllBound_CoPy_Visc += CoPy_Visc[iMarker]; - AllBound_CoPz_Visc += CoPz_Visc[iMarker]; - AllBound_CT_Visc += CT_Visc[iMarker]; - AllBound_CQ_Visc += CQ_Visc[iMarker]; - AllBound_HF_Visc += HF_Visc[iMarker]; - AllBound_MaxHF_Visc += pow(MaxHF_Visc[iMarker], MaxNorm); - - /*--- Compute the coefficients per surface ---*/ - - for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { - Monitoring_Tag = config->GetMarker_Monitoring_TagBound(iMarker_Monitoring); - Marker_Tag = config->GetMarker_All_TagBound(iMarker); - if (Marker_Tag == Monitoring_Tag) { - Surface_CL_Visc[iMarker_Monitoring] += CL_Visc[iMarker]; - Surface_CD_Visc[iMarker_Monitoring] += CD_Visc[iMarker]; - Surface_CSF_Visc[iMarker_Monitoring] += CSF_Visc[iMarker]; - Surface_CEff_Visc[iMarker_Monitoring] += CEff_Visc[iMarker]; - Surface_CFx_Visc[iMarker_Monitoring] += CFx_Visc[iMarker]; - Surface_CFy_Visc[iMarker_Monitoring] += CFy_Visc[iMarker]; - Surface_CFz_Visc[iMarker_Monitoring] += CFz_Visc[iMarker]; - Surface_CMx_Visc[iMarker_Monitoring] += CMx_Visc[iMarker]; - Surface_CMy_Visc[iMarker_Monitoring] += CMy_Visc[iMarker]; - Surface_CMz_Visc[iMarker_Monitoring] += CMz_Visc[iMarker]; - Surface_HF_Visc[iMarker_Monitoring] += HF_Visc[iMarker]; - Surface_MaxHF_Visc[iMarker_Monitoring] += pow(MaxHF_Visc[iMarker],MaxNorm); - } - } - - } - - } - } - - /*--- Update some global coeffients ---*/ - - AllBound_CEff_Visc = AllBound_CL_Visc / (AllBound_CD_Visc + EPS); - AllBound_CMerit_Visc = AllBound_CT_Visc / (AllBound_CQ_Visc + EPS); - AllBound_MaxHF_Visc = pow(AllBound_MaxHF_Visc, 1.0/MaxNorm); - - -#ifdef HAVE_MPI - - /*--- Add AllBound information using all the nodes ---*/ - - MyAllBound_CD_Visc = AllBound_CD_Visc; AllBound_CD_Visc = 0.0; - MyAllBound_CL_Visc = AllBound_CL_Visc; AllBound_CL_Visc = 0.0; - MyAllBound_CSF_Visc = AllBound_CSF_Visc; AllBound_CSF_Visc = 0.0; - AllBound_CEff_Visc = 0.0; - MyAllBound_CMx_Visc = AllBound_CMx_Visc; AllBound_CMx_Visc = 0.0; - MyAllBound_CMy_Visc = AllBound_CMy_Visc; AllBound_CMy_Visc = 0.0; - MyAllBound_CMz_Visc = AllBound_CMz_Visc; AllBound_CMz_Visc = 0.0; - MyAllBound_CFx_Visc = AllBound_CFx_Visc; AllBound_CFx_Visc = 0.0; - MyAllBound_CFy_Visc = AllBound_CFy_Visc; AllBound_CFy_Visc = 0.0; - MyAllBound_CFz_Visc = AllBound_CFz_Visc; AllBound_CFz_Visc = 0.0; - MyAllBound_CoPx_Visc = AllBound_CoPx_Visc; AllBound_CoPx_Visc = 0.0; - MyAllBound_CoPy_Visc = AllBound_CoPy_Visc; AllBound_CoPy_Visc = 0.0; - MyAllBound_CoPz_Visc = AllBound_CoPz_Visc; AllBound_CoPz_Visc = 0.0; - MyAllBound_CT_Visc = AllBound_CT_Visc; AllBound_CT_Visc = 0.0; - MyAllBound_CQ_Visc = AllBound_CQ_Visc; AllBound_CQ_Visc = 0.0; - AllBound_CMerit_Visc = 0.0; - MyAllBound_HF_Visc = AllBound_HF_Visc; AllBound_HF_Visc = 0.0; - MyAllBound_MaxHF_Visc = pow(AllBound_MaxHF_Visc, MaxNorm); AllBound_MaxHF_Visc = 0.0; - - if (config->GetComm_Level() == COMM_FULL) { - SU2_MPI::Allreduce(&MyAllBound_CD_Visc, &AllBound_CD_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CL_Visc, &AllBound_CL_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CSF_Visc, &AllBound_CSF_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - AllBound_CEff_Visc = AllBound_CL_Visc / (AllBound_CD_Visc + EPS); - SU2_MPI::Allreduce(&MyAllBound_CMx_Visc, &AllBound_CMx_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CMy_Visc, &AllBound_CMy_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CMz_Visc, &AllBound_CMz_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CFx_Visc, &AllBound_CFx_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CFy_Visc, &AllBound_CFy_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CFz_Visc, &AllBound_CFz_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CoPx_Visc, &AllBound_CoPx_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CoPy_Visc, &AllBound_CoPy_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CoPz_Visc, &AllBound_CoPz_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CT_Visc, &AllBound_CT_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_CQ_Visc, &AllBound_CQ_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - AllBound_CMerit_Visc = AllBound_CT_Visc / (AllBound_CQ_Visc + EPS); - SU2_MPI::Allreduce(&MyAllBound_HF_Visc, &AllBound_HF_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(&MyAllBound_MaxHF_Visc, &AllBound_MaxHF_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - AllBound_MaxHF_Visc = pow(AllBound_MaxHF_Visc, 1.0/MaxNorm); - } - - /*--- Add the forces on the surfaces using all the nodes ---*/ - - MySurface_CL_Visc = new su2double[config->GetnMarker_Monitoring()]; - MySurface_CD_Visc = new su2double[config->GetnMarker_Monitoring()]; - MySurface_CSF_Visc = new su2double[config->GetnMarker_Monitoring()]; - MySurface_CEff_Visc = new su2double[config->GetnMarker_Monitoring()]; - MySurface_CFx_Visc = new su2double[config->GetnMarker_Monitoring()]; - MySurface_CFy_Visc = new su2double[config->GetnMarker_Monitoring()]; - MySurface_CFz_Visc = new su2double[config->GetnMarker_Monitoring()]; - MySurface_CMx_Visc = new su2double[config->GetnMarker_Monitoring()]; - MySurface_CMy_Visc = new su2double[config->GetnMarker_Monitoring()]; - MySurface_CMz_Visc = new su2double[config->GetnMarker_Monitoring()]; - MySurface_HF_Visc = new su2double[config->GetnMarker_Monitoring()]; - MySurface_MaxHF_Visc = new su2double[config->GetnMarker_Monitoring()]; - - for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { - - MySurface_CL_Visc[iMarker_Monitoring] = Surface_CL_Visc[iMarker_Monitoring]; - MySurface_CD_Visc[iMarker_Monitoring] = Surface_CD_Visc[iMarker_Monitoring]; - MySurface_CSF_Visc[iMarker_Monitoring] = Surface_CSF_Visc[iMarker_Monitoring]; - MySurface_CEff_Visc[iMarker_Monitoring] = Surface_CEff_Visc[iMarker_Monitoring]; - MySurface_CFx_Visc[iMarker_Monitoring] = Surface_CFx_Visc[iMarker_Monitoring]; - MySurface_CFy_Visc[iMarker_Monitoring] = Surface_CFy_Visc[iMarker_Monitoring]; - MySurface_CFz_Visc[iMarker_Monitoring] = Surface_CFz_Visc[iMarker_Monitoring]; - MySurface_CMx_Visc[iMarker_Monitoring] = Surface_CMx_Visc[iMarker_Monitoring]; - MySurface_CMy_Visc[iMarker_Monitoring] = Surface_CMy_Visc[iMarker_Monitoring]; - MySurface_CMz_Visc[iMarker_Monitoring] = Surface_CMz_Visc[iMarker_Monitoring]; - MySurface_HF_Visc[iMarker_Monitoring] = Surface_HF_Visc[iMarker_Monitoring]; - MySurface_MaxHF_Visc[iMarker_Monitoring] = Surface_MaxHF_Visc[iMarker_Monitoring]; - - Surface_CL_Visc[iMarker_Monitoring] = 0.0; - Surface_CD_Visc[iMarker_Monitoring] = 0.0; - Surface_CSF_Visc[iMarker_Monitoring] = 0.0; - Surface_CEff_Visc[iMarker_Monitoring] = 0.0; - Surface_CFx_Visc[iMarker_Monitoring] = 0.0; - Surface_CFy_Visc[iMarker_Monitoring] = 0.0; - Surface_CFz_Visc[iMarker_Monitoring] = 0.0; - Surface_CMx_Visc[iMarker_Monitoring] = 0.0; - Surface_CMy_Visc[iMarker_Monitoring] = 0.0; - Surface_CMz_Visc[iMarker_Monitoring] = 0.0; - Surface_HF_Visc[iMarker_Monitoring] = 0.0; - Surface_MaxHF_Visc[iMarker_Monitoring] = 0.0; - } - - if (config->GetComm_Level() == COMM_FULL) { - SU2_MPI::Allreduce(MySurface_CL_Visc, Surface_CL_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(MySurface_CD_Visc, Surface_CD_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(MySurface_CSF_Visc, Surface_CSF_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) - Surface_CEff_Visc[iMarker_Monitoring] = Surface_CL_Visc[iMarker_Monitoring] / (Surface_CD_Visc[iMarker_Monitoring] + EPS); - SU2_MPI::Allreduce(MySurface_CFx_Visc, Surface_CFx_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(MySurface_CFy_Visc, Surface_CFy_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(MySurface_CFz_Visc, Surface_CFz_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(MySurface_CMx_Visc, Surface_CMx_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(MySurface_CMy_Visc, Surface_CMy_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(MySurface_CMz_Visc, Surface_CMz_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(MySurface_HF_Visc, Surface_HF_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - SU2_MPI::Allreduce(MySurface_MaxHF_Visc, Surface_MaxHF_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - } - - delete [] MySurface_CL_Visc; delete [] MySurface_CD_Visc; delete [] MySurface_CSF_Visc; - delete [] MySurface_CEff_Visc; delete [] MySurface_CFx_Visc; delete [] MySurface_CFy_Visc; - delete [] MySurface_CFz_Visc; delete [] MySurface_CMx_Visc; delete [] MySurface_CMy_Visc; - delete [] MySurface_CMz_Visc; delete [] MySurface_HF_Visc; delete [] MySurface_MaxHF_Visc; - -#endif - - /*--- Update the total coefficients (note that all the nodes have the same value)---*/ - - Total_CD += AllBound_CD_Visc; - Total_CL += AllBound_CL_Visc; - Total_CSF += AllBound_CSF_Visc; - Total_CEff = Total_CL / (Total_CD + EPS); - Total_CMx += AllBound_CMx_Visc; - Total_CMy += AllBound_CMy_Visc; - Total_CMz += AllBound_CMz_Visc; - Total_CFx += AllBound_CFx_Visc; - Total_CFy += AllBound_CFy_Visc; - Total_CFz += AllBound_CFz_Visc; - Total_CoPx += AllBound_CoPx_Visc; - Total_CoPy += AllBound_CoPy_Visc; - Total_CoPz += AllBound_CoPz_Visc; - Total_CT += AllBound_CT_Visc; - Total_CQ += AllBound_CQ_Visc; - Total_CMerit = AllBound_CT_Visc / (AllBound_CQ_Visc + EPS); - Total_Heat = AllBound_HF_Visc; - Total_MaxHeat = AllBound_MaxHF_Visc; - - /*--- Update the total coefficients per surface (note that all the nodes have the same value)---*/ - - for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { - Surface_CL[iMarker_Monitoring] += Surface_CL_Visc[iMarker_Monitoring]; - Surface_CD[iMarker_Monitoring] += Surface_CD_Visc[iMarker_Monitoring]; - Surface_CSF[iMarker_Monitoring] += Surface_CSF_Visc[iMarker_Monitoring]; - Surface_CEff[iMarker_Monitoring] = Surface_CL[iMarker_Monitoring] / (Surface_CD[iMarker_Monitoring] + EPS); - Surface_CFx[iMarker_Monitoring] += Surface_CFx_Visc[iMarker_Monitoring]; - Surface_CFy[iMarker_Monitoring] += Surface_CFy_Visc[iMarker_Monitoring]; - Surface_CFz[iMarker_Monitoring] += Surface_CFz_Visc[iMarker_Monitoring]; - Surface_CMx[iMarker_Monitoring] += Surface_CMx_Visc[iMarker_Monitoring]; - Surface_CMy[iMarker_Monitoring] += Surface_CMy_Visc[iMarker_Monitoring]; - Surface_CMz[iMarker_Monitoring] += Surface_CMz_Visc[iMarker_Monitoring]; - } - -} - -void CIncNSSolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - - unsigned short iDim, iVar, jVar;// Wall_Function; - unsigned long iVertex, iPoint, total_index; - - su2double *GridVel, *Normal, Area, Wall_HeatFlux; - - bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); - bool energy = config->GetEnergy_Equation(); - - /*--- Identify the boundary by string name ---*/ - - string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - - /*--- Get the specified wall heat flux from config ---*/ - - Wall_HeatFlux = config->GetWall_HeatFlux(Marker_Tag)/config->GetHeat_Flux_Ref(); - -// /*--- Get wall function treatment from config. ---*/ -// -// Wall_Function = config->GetWallFunction_Treatment(Marker_Tag); -// if (Wall_Function != NO_WALL_FUNCTION) { -// SU2_MPI::Error("Wall function treament not implemented yet", CURRENT_FUNCTION); -// } - - /*--- Loop over all of the vertices on this boundary marker ---*/ - - for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - - /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ - - if (geometry->node[iPoint]->GetDomain()) { - - /*--- Compute dual-grid area and boundary normal ---*/ - - Normal = geometry->vertex[val_marker][iVertex]->GetNormal(); - - Area = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - Area += Normal[iDim]*Normal[iDim]; - Area = sqrt (Area); - - /*--- Initialize the convective & viscous residuals to zero ---*/ - - for (iVar = 0; iVar < nVar; iVar++) { - Res_Conv[iVar] = 0.0; - Res_Visc[iVar] = 0.0; - if (implicit) { - for (jVar = 0; jVar < nVar; jVar++) - Jacobian_i[iVar][jVar] = 0.0; - } - } - - /*--- Store the corrected velocity at the wall which will - be zero (v = 0), unless there are moving walls (v = u_wall)---*/ - - if (dynamic_grid) { - GridVel = geometry->node[iPoint]->GetGridVel(); - for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = GridVel[iDim]; - } else { - for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = 0.0; - } - - /*--- Impose the value of the velocity as a strong boundary - condition (Dirichlet). Fix the velocity and remove any - contribution to the residual at this node. ---*/ - - nodes->SetVelocity_Old(iPoint,Vector); - - for (iDim = 0; iDim < nDim; iDim++) - LinSysRes.SetBlock_Zero(iPoint, iDim+1); - nodes->SetVel_ResTruncError_Zero(iPoint); - - if (energy) { - - /*--- Apply a weak boundary condition for the energy equation. - Compute the residual due to the prescribed heat flux. ---*/ - - Res_Visc[nDim+1] = Wall_HeatFlux*Area; - - /*--- Viscous contribution to the residual at the wall ---*/ - - LinSysRes.SubtractBlock(iPoint, Res_Visc); - - } - - /*--- Enforce the no-slip boundary condition in a strong way by - modifying the velocity-rows of the Jacobian (1 on the diagonal). ---*/ - - if (implicit) { - for (iVar = 1; iVar <= nDim; iVar++) { - total_index = iPoint*nVar+iVar; - Jacobian.DeleteValsRowi(total_index); - } - } - - } - } -} - -void CIncNSSolver::BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - - unsigned short iDim, iVar, jVar, Wall_Function; - unsigned long iVertex, iPoint, Point_Normal, total_index; - - su2double *GridVel; - su2double *Normal, *Coord_i, *Coord_j, Area, dist_ij; - su2double Twall, dTdn; - su2double thermal_conductivity; - - bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); - bool energy = config->GetEnergy_Equation(); - - /*--- Identify the boundary by string name ---*/ - - string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - - /*--- Retrieve the specified wall temperature ---*/ - - Twall = config->GetIsothermal_Temperature(Marker_Tag)/config->GetTemperature_Ref(); - - /*--- Get wall function treatment from config. ---*/ - - Wall_Function = config->GetWallFunction_Treatment(Marker_Tag); - if (Wall_Function != NO_WALL_FUNCTION) { - SU2_MPI::Error("Wall function treatment not implemented yet.", CURRENT_FUNCTION); - } - - /*--- Loop over all of the vertices on this boundary marker ---*/ - - for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - - iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - - /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ - - if (geometry->node[iPoint]->GetDomain()) { - - /*--- Initialize the convective & viscous residuals to zero ---*/ - - for (iVar = 0; iVar < nVar; iVar++) { - Res_Conv[iVar] = 0.0; - Res_Visc[iVar] = 0.0; - if (implicit) { - for (jVar = 0; jVar < nVar; jVar++) - Jacobian_i[iVar][jVar] = 0.0; - } - } - - /*--- Store the corrected velocity at the wall which will - be zero (v = 0), unless there are moving walls (v = u_wall)---*/ - - if (dynamic_grid) { - GridVel = geometry->node[iPoint]->GetGridVel(); - for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = GridVel[iDim]; - } else { - for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = 0.0; - } - - /*--- Impose the value of the velocity as a strong boundary - condition (Dirichlet). Fix the velocity and remove any - contribution to the residual at this node. ---*/ - - nodes->SetVelocity_Old(iPoint,Vector); - - for (iDim = 0; iDim < nDim; iDim++) - LinSysRes.SetBlock_Zero(iPoint, iDim+1); - nodes->SetVel_ResTruncError_Zero(iPoint); - - if (energy) { - - /*--- Compute dual grid area and boundary normal ---*/ - - Normal = geometry->vertex[val_marker][iVertex]->GetNormal(); - - Area = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - Area += Normal[iDim]*Normal[iDim]; - Area = sqrt (Area); - - /*--- Compute closest normal neighbor ---*/ - - Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); - - /*--- Get coordinates of i & nearest normal and compute distance ---*/ - - Coord_i = geometry->node[iPoint]->GetCoord(); - Coord_j = geometry->node[Point_Normal]->GetCoord(); - dist_ij = 0; - for (iDim = 0; iDim < nDim; iDim++) - dist_ij += (Coord_j[iDim]-Coord_i[iDim])*(Coord_j[iDim]-Coord_i[iDim]); - dist_ij = sqrt(dist_ij); - - /*--- Compute the normal gradient in temperature using Twall ---*/ - - dTdn = -(nodes->GetTemperature(Point_Normal) - Twall)/dist_ij; - - /*--- Get thermal conductivity ---*/ - - thermal_conductivity = nodes->GetThermalConductivity(iPoint); - - /*--- Apply a weak boundary condition for the energy equation. - Compute the residual due to the prescribed heat flux. ---*/ - - Res_Visc[nDim+1] = thermal_conductivity*dTdn*Area; - - /*--- Jacobian contribution for temperature equation. ---*/ - - if (implicit) { - su2double Edge_Vector[3]; - su2double dist_ij_2 = 0, proj_vector_ij = 0; - for (iDim = 0; iDim < nDim; iDim++) { - Edge_Vector[iDim] = Coord_j[iDim]-Coord_i[iDim]; - dist_ij_2 += Edge_Vector[iDim]*Edge_Vector[iDim]; - proj_vector_ij += Edge_Vector[iDim]*Normal[iDim]; - } - if (dist_ij_2 == 0.0) proj_vector_ij = 0.0; - else proj_vector_ij = proj_vector_ij/dist_ij_2; - - Jacobian_i[nDim+1][nDim+1] = -thermal_conductivity*proj_vector_ij; - - Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - } - - /*--- Viscous contribution to the residual at the wall ---*/ - - LinSysRes.SubtractBlock(iPoint, Res_Visc); - - } - - /*--- Enforce the no-slip boundary condition in a strong way by - modifying the velocity-rows of the Jacobian (1 on the diagonal). ---*/ - - if (implicit) { - for (iVar = 1; iVar <= nDim; iVar++) { - total_index = iPoint*nVar+iVar; - Jacobian.DeleteValsRowi(total_index); - } - } - - } - } -} - - -void CIncNSSolver::BC_ConjugateHeat_Interface(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CConfig *config, unsigned short val_marker) { - - unsigned short iVar, jVar, iDim, Wall_Function; - unsigned long iVertex, iPoint, total_index, Point_Normal; - - su2double *Coord_i, *Coord_j, dist_ij; - su2double *GridVel, There, Tconjugate, Twall, Temperature_Ref, thermal_conductivity, HF_FactorHere, HF_FactorConjugate; - - Temperature_Ref = config->GetTemperature_Ref(); - - bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); - bool energy = config->GetEnergy_Equation(); - - /*--- Identify the boundary ---*/ - - string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - - /*--- Retrieve the specified wall function treatment.---*/ - - Wall_Function = config->GetWallFunction_Treatment(Marker_Tag); - if(Wall_Function != NO_WALL_FUNCTION) { - SU2_MPI::Error("Wall function treament not implemented yet", CURRENT_FUNCTION); - } - - /*--- Loop over boundary points ---*/ - - for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - - iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - - if (geometry->node[iPoint]->GetDomain()) { - - /*--- Initialize the convective & viscous residuals to zero ---*/ - - for (iVar = 0; iVar < nVar; iVar++) { - Res_Conv[iVar] = 0.0; - Res_Visc[iVar] = 0.0; - if (implicit) { - for (jVar = 0; jVar < nVar; jVar++) - Jacobian_i[iVar][jVar] = 0.0; - } - } - - /*--- Store the corrected velocity at the wall which will - be zero (v = 0), unless there are moving walls (v = u_wall)---*/ - - if (dynamic_grid) { - GridVel = geometry->node[iPoint]->GetGridVel(); - for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = GridVel[iDim]; - } else { - for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = 0.0; - } - - /*--- Impose the value of the velocity as a strong boundary - condition (Dirichlet). Fix the velocity and remove any - contribution to the residual at this node. ---*/ - - nodes->SetVelocity_Old(iPoint,Vector); - - for (iDim = 0; iDim < nDim; iDim++) - LinSysRes.SetBlock_Zero(iPoint, iDim+1); - nodes->SetVel_ResTruncError_Zero(iPoint); - - if (energy) { - - Tconjugate = GetConjugateHeatVariable(val_marker, iVertex, 0)/Temperature_Ref; - - if ((config->GetKind_CHT_Coupling() == AVERAGED_TEMPERATURE_NEUMANN_HEATFLUX) || - (config->GetKind_CHT_Coupling() == AVERAGED_TEMPERATURE_ROBIN_HEATFLUX)) { - - /*--- Compute closest normal neighbor ---*/ - - Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); - - /*--- Get coordinates of i & nearest normal and compute distance ---*/ - - Coord_i = geometry->node[iPoint]->GetCoord(); - Coord_j = geometry->node[Point_Normal]->GetCoord(); - dist_ij = 0; - for (iDim = 0; iDim < nDim; iDim++) - dist_ij += (Coord_j[iDim]-Coord_i[iDim])*(Coord_j[iDim]-Coord_i[iDim]); - dist_ij = sqrt(dist_ij); - - /*--- Compute wall temperature from both temperatures ---*/ - - thermal_conductivity = nodes->GetThermalConductivity(iPoint); - There = nodes->GetTemperature(Point_Normal); - HF_FactorHere = thermal_conductivity*config->GetViscosity_Ref()/dist_ij; - HF_FactorConjugate = GetConjugateHeatVariable(val_marker, iVertex, 2); - - Twall = (There*HF_FactorHere + Tconjugate*HF_FactorConjugate)/(HF_FactorHere + HF_FactorConjugate); - } - else if ((config->GetKind_CHT_Coupling() == DIRECT_TEMPERATURE_NEUMANN_HEATFLUX) || - (config->GetKind_CHT_Coupling() == DIRECT_TEMPERATURE_ROBIN_HEATFLUX)) { - - /*--- (Directly) Set wall temperature to conjugate temperature. ---*/ - - Twall = Tconjugate; - } - else { - - SU2_MPI::Error(string("Unknown CHT coupling method."), CURRENT_FUNCTION); - } - - /*--- Strong imposition of the temperature on the fluid zone. ---*/ - - LinSysRes.SetBlock_Zero(iPoint, nDim+1); - nodes->SetSolution_Old(iPoint, nDim+1, Twall); - nodes->SetEnergy_ResTruncError_Zero(iPoint); - } - - /*--- Enforce the no-slip boundary condition in a strong way by - modifying the velocity-rows of the Jacobian (1 on the diagonal). ---*/ - - if (implicit) { - for (iVar = 1; iVar <= nDim; iVar++) { - total_index = iPoint*nVar+iVar; - Jacobian.DeleteValsRowi(total_index); - } - if(energy) { - total_index = iPoint*nVar+nDim+1; - Jacobian.DeleteValsRowi(total_index); - } - } - } - } -} diff --git a/SU2_CFD/src/solvers/CIncNSSolver.cpp b/SU2_CFD/src/solvers/CIncNSSolver.cpp new file mode 100644 index 000000000000..9808afd4e897 --- /dev/null +++ b/SU2_CFD/src/solvers/CIncNSSolver.cpp @@ -0,0 +1,1976 @@ +/*! + * \file CIncNSSolver.cpp + * \brief Main subroutines for solving Navier-Stokes incompressible flow. + * \author F. Palacios, T. Economon + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + + +#include "../../include/solvers/CIncNSSolver.hpp" +#include "../../include/variables/CIncNSVariable.hpp" +#include "../../../Common/include/toolboxes/printing_toolbox.hpp" + +CIncNSSolver::CIncNSSolver(void) : CIncEulerSolver() { + + /*--- Basic array initialization ---*/ + + CD_Visc = NULL; CL_Visc = NULL; CSF_Visc = NULL; CEff_Visc = NULL; + CMx_Visc = NULL; CMy_Visc = NULL; CMz_Visc = NULL; + CFx_Visc = NULL; CFy_Visc = NULL; CFz_Visc = NULL; + CoPx_Visc = NULL; CoPy_Visc = NULL; CoPz_Visc = NULL; + + ForceViscous = NULL; MomentViscous = NULL; CSkinFriction = NULL; + + /*--- Surface based array initialization ---*/ + + Surface_CL_Visc = NULL; Surface_CD_Visc = NULL; Surface_CSF_Visc = NULL; Surface_CEff_Visc = NULL; + Surface_CFx_Visc = NULL; Surface_CFy_Visc = NULL; Surface_CFz_Visc = NULL; + Surface_CMx_Visc = NULL; Surface_CMy_Visc = NULL; Surface_CMz_Visc = NULL; + Surface_HF_Visc = NULL; Surface_MaxHF_Visc = NULL; + + /*--- Rotorcraft simulation array initialization ---*/ + + CMerit_Visc = NULL; CT_Visc = NULL; CQ_Visc = NULL; + + SlidingState = NULL; + SlidingStateNodes = NULL; + +} + +CIncNSSolver::CIncNSSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh) : CIncEulerSolver() { + + unsigned long iPoint, iVertex; + unsigned short iVar, iDim, iMarker, nLineLets; + ifstream restart_file; + unsigned short nZone = geometry->GetnZone(); + bool restart = (config->GetRestart() || config->GetRestart_Flow()); + int Unst_RestartIter; + unsigned short iZone = config->GetiZone(); + bool dual_time = ((config->GetTime_Marching() == DT_STEPPING_1ST) || + (config->GetTime_Marching() == DT_STEPPING_2ND)); + bool time_stepping = config->GetTime_Marching() == TIME_STEPPING; + bool adjoint = (config->GetContinuous_Adjoint()) || (config->GetDiscrete_Adjoint()); + string filename_ = config->GetSolution_FileName(); + + /* A grid is defined as dynamic if there's rigid grid movement or grid deformation AND the problem is time domain */ + dynamic_grid = config->GetDynamic_Grid(); + + unsigned short direct_diff = config->GetDirectDiff(); + + /*--- Store the multigrid level. ---*/ + MGLevel = iMesh; + + /*--- Check for a restart file to evaluate if there is a change in the angle of attack + before computing all the non-dimesional quantities. ---*/ + + if (!(!restart || (iMesh != MESH_0) || nZone > 1)) { + + /*--- Multizone problems require the number of the zone to be appended. ---*/ + + if (nZone > 1) filename_ = config->GetMultizone_FileName(filename_, iZone, ".dat"); + + /*--- Modify file name for a dual-time unsteady restart ---*/ + + if (dual_time) { + if (adjoint) Unst_RestartIter = SU2_TYPE::Int(config->GetUnst_AdjointIter())-1; + else if (config->GetTime_Marching() == DT_STEPPING_1ST) + Unst_RestartIter = SU2_TYPE::Int(config->GetRestart_Iter())-1; + else Unst_RestartIter = SU2_TYPE::Int(config->GetRestart_Iter())-2; + filename_ = config->GetUnsteady_FileName(filename_, Unst_RestartIter, ".dat"); + } + + /*--- Modify file name for a time stepping unsteady restart ---*/ + + if (time_stepping) { + if (adjoint) Unst_RestartIter = SU2_TYPE::Int(config->GetUnst_AdjointIter())-1; + else Unst_RestartIter = SU2_TYPE::Int(config->GetRestart_Iter())-1; + filename_ = config->GetUnsteady_FileName(filename_, Unst_RestartIter, ".dat"); + } + + /*--- Read and store the restart metadata. ---*/ + +// Read_SU2_Restart_Metadata(geometry, config, false, filename_); + + } + + /*--- Array initialization ---*/ + + CD_Visc = NULL; CL_Visc = NULL; CSF_Visc = NULL; CEff_Visc = NULL; + CMx_Visc = NULL; CMy_Visc = NULL; CMz_Visc = NULL; + CFx_Visc = NULL; CFy_Visc = NULL; CFz_Visc = NULL; + CoPx_Visc = NULL; CoPy_Visc = NULL; CoPz_Visc = NULL; + + Surface_CL_Visc = NULL; Surface_CD_Visc = NULL; Surface_CSF_Visc = NULL; Surface_CEff_Visc = NULL; + Surface_CFx_Visc = NULL; Surface_CFy_Visc = NULL; Surface_CFz_Visc = NULL; + Surface_CMx_Visc = NULL; Surface_CMy_Visc = NULL; Surface_CMz_Visc = NULL; + Surface_HF_Visc = NULL; Surface_MaxHF_Visc = NULL; + + CMerit_Visc = NULL; CT_Visc = NULL; CQ_Visc = NULL; + MaxHF_Visc = NULL; ForceViscous = NULL; MomentViscous = NULL; + CSkinFriction = NULL; HF_Visc = NULL; + + /*--- Set the gamma value ---*/ + + Gamma = config->GetGamma(); + Gamma_Minus_One = Gamma - 1.0; + + /*--- Define geometry constants in the solver structure + * Incompressible flow, primitive variables (P, vx, vy, vz, T, rho, beta, lamMu, EddyMu, Kt_eff, Cp, Cv) --- */ + + nDim = geometry->GetnDim(); + + nVar = nDim+2; nPrimVar = nDim+9; nPrimVarGrad = nDim+4; + + /*--- Initialize nVarGrad for deallocation ---*/ + + nVarGrad = nPrimVarGrad; + + nMarker = config->GetnMarker_All(); + nPoint = geometry->GetnPoint(); + nPointDomain = geometry->GetnPointDomain(); + + /*--- Store the number of vertices on each marker for deallocation later ---*/ + + nVertex = new unsigned long[nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) + nVertex[iMarker] = geometry->nVertex[iMarker]; + + /*--- Fluid model intialization. ---*/ + + FluidModel = NULL; + + /*--- Perform the non-dimensionalization for the flow equations using the + specified reference values. ---*/ + + SetNondimensionalization(config, iMesh); + + /*--- Check if we are executing a verification case. If so, the + VerificationSolution object will be instantiated for a particular + option from the available library of verification solutions. Note + that this is done after SetNondim(), as problem-specific initial + parameters are needed by the solution constructors. ---*/ + + SetVerificationSolution(nDim, nVar, config); + + /*--- Define some auxiliar vector related with the residual ---*/ + + Residual = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = 0.0; + Residual_RMS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_RMS[iVar] = 0.0; + Residual_Max = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_Max[iVar] = 0.0; + Res_Conv = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Conv[iVar] = 0.0; + Res_Visc = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Visc[iVar] = 0.0; + Res_Sour = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Sour[iVar] = 0.0; + + /*--- Define some structures for locating max residuals ---*/ + + Point_Max = new unsigned long[nVar]; for (iVar = 0; iVar < nVar; iVar++) Point_Max[iVar] = 0; + Point_Max_Coord = new su2double*[nVar]; + for (iVar = 0; iVar < nVar; iVar++) { + Point_Max_Coord[iVar] = new su2double[nDim]; + for (iDim = 0; iDim < nDim; iDim++) Point_Max_Coord[iVar][iDim] = 0.0; + } + + /*--- Define some auxiliary vectors related to the solution ---*/ + + Solution = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution[iVar] = 0.0; + Solution_i = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution_i[iVar] = 0.0; + Solution_j = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution_j[iVar] = 0.0; + + /*--- Define some auxiliary vectors related to the geometry ---*/ + + Vector = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = 0.0; + Vector_i = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector_i[iDim] = 0.0; + Vector_j = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector_j[iDim] = 0.0; + + /*--- Define some auxiliary vectors related to the primitive solution ---*/ + + Primitive = new su2double[nPrimVar]; for (iVar = 0; iVar < nPrimVar; iVar++) Primitive[iVar] = 0.0; + Primitive_i = new su2double[nPrimVar]; for (iVar = 0; iVar < nPrimVar; iVar++) Primitive_i[iVar] = 0.0; + Primitive_j = new su2double[nPrimVar]; for (iVar = 0; iVar < nPrimVar; iVar++) Primitive_j[iVar] = 0.0; + + /*--- Define some auxiliar vector related with the undivided lapalacian computation ---*/ + + if (config->GetKind_ConvNumScheme_Flow() == SPACE_CENTERED) { + iPoint_UndLapl = new su2double [nPoint]; + jPoint_UndLapl = new su2double [nPoint]; + } + + Preconditioner = new su2double* [nVar]; + for (iVar = 0; iVar < nVar; iVar ++) + Preconditioner[iVar] = new su2double[nVar]; + + /*--- Initialize the solution and right hand side vectors for storing + the residuals and updating the solution (always needed even for + explicit schemes). ---*/ + + LinSysSol.Initialize(nPoint, nPointDomain, nVar, 0.0); + LinSysRes.Initialize(nPoint, nPointDomain, nVar, 0.0); + + /*--- Jacobians and vector structures for implicit computations ---*/ + + if (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT) { + + Jacobian_i = new su2double* [nVar]; + Jacobian_j = new su2double* [nVar]; + for (iVar = 0; iVar < nVar; iVar++) { + Jacobian_i[iVar] = new su2double [nVar]; + Jacobian_j[iVar] = new su2double [nVar]; + } + + if (rank == MASTER_NODE) cout << "Initialize Jacobian structure (Navier-Stokes). MG level: " << iMesh <<"." << endl; + Jacobian.Initialize(nPoint, nPointDomain, nVar, nVar, true, geometry, config); + + if (config->GetKind_Linear_Solver_Prec() == LINELET) { + nLineLets = Jacobian.BuildLineletPreconditioner(geometry, config); + if (rank == MASTER_NODE) cout << "Compute linelet structure. " << nLineLets << " elements in each line (average)." << endl; + } + + } + + else { + if (rank == MASTER_NODE) + cout << "Explicit scheme. No Jacobian structure (Navier-Stokes). MG level: " << iMesh <<"." << endl; + } + + /*--- Define some auxiliary vectors for computing flow variable + gradients by least squares, S matrix := inv(R)*traspose(inv(R)), + c vector := transpose(WA)*(Wb) ---*/ + + if (config->GetLeastSquaresRequired()) { + Smatrix = new su2double* [nDim]; + for (iDim = 0; iDim < nDim; iDim++) + Smatrix[iDim] = new su2double [nDim]; + + Cvector = new su2double* [nPrimVarGrad]; + for (iVar = 0; iVar < nPrimVarGrad; iVar++) + Cvector[iVar] = new su2double [nDim]; + } + + /*--- Store the value of the characteristic primitive variables at the boundaries ---*/ + + CharacPrimVar = new su2double** [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + CharacPrimVar[iMarker] = new su2double* [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + CharacPrimVar[iMarker][iVertex] = new su2double [nPrimVar]; + for (iVar = 0; iVar < nPrimVar; iVar++) { + CharacPrimVar[iMarker][iVertex][iVar] = 0.0; + } + } + } + + /*--- Store the values of the temperature and the heat flux density at the boundaries, + used for coupling with a solid donor cell ---*/ + unsigned short nHeatConjugateVar = 4; + + HeatConjugateVar = new su2double** [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + HeatConjugateVar[iMarker] = new su2double* [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + + HeatConjugateVar[iMarker][iVertex] = new su2double [nHeatConjugateVar]; + for (iVar = 1; iVar < nHeatConjugateVar ; iVar++) { + HeatConjugateVar[iMarker][iVertex][iVar] = 0.0; + } + HeatConjugateVar[iMarker][iVertex][0] = config->GetTemperature_FreeStreamND(); + } + } + + /*--- Inviscid force definition and coefficient in all the markers ---*/ + + CPressure = new su2double* [nMarker]; + CPressureTarget = new su2double* [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + CPressure[iMarker] = new su2double [geometry->nVertex[iMarker]]; + CPressureTarget[iMarker] = new su2double [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + CPressure[iMarker][iVertex] = 0.0; + CPressureTarget[iMarker][iVertex] = 0.0; + } + } + + /*--- Heat flux in all the markers ---*/ + + HeatFlux = new su2double* [nMarker]; + HeatFluxTarget = new su2double* [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + HeatFlux[iMarker] = new su2double [geometry->nVertex[iMarker]]; + HeatFluxTarget[iMarker] = new su2double [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + HeatFlux[iMarker][iVertex] = 0.0; + HeatFluxTarget[iMarker][iVertex] = 0.0; + } + } + + /*--- Y plus in all the markers ---*/ + + YPlus = new su2double* [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + YPlus[iMarker] = new su2double [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + YPlus[iMarker][iVertex] = 0.0; + } + } + + /*--- Skin friction in all the markers ---*/ + + CSkinFriction = new su2double** [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + CSkinFriction[iMarker] = new su2double*[nDim]; + for (iDim = 0; iDim < nDim; iDim++) { + CSkinFriction[iMarker][iDim] = new su2double[geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + CSkinFriction[iMarker][iDim][iVertex] = 0.0; + } + } + } + + /*--- Store the value of the Total Pressure at the inlet BC ---*/ + + Inlet_Ttotal = new su2double* [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + Inlet_Ttotal[iMarker] = new su2double [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + Inlet_Ttotal[iMarker][iVertex] = 0; + } + } + + /*--- Store the value of the Total Temperature at the inlet BC ---*/ + + Inlet_Ptotal = new su2double* [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + Inlet_Ptotal[iMarker] = new su2double [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + Inlet_Ptotal[iMarker][iVertex] = 0; + } + } + + /*--- Store the value of the Flow direction at the inlet BC ---*/ + + Inlet_FlowDir = new su2double** [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + Inlet_FlowDir[iMarker] = new su2double* [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + Inlet_FlowDir[iMarker][iVertex] = new su2double [nDim]; + for (iDim = 0; iDim < nDim; iDim++) { + Inlet_FlowDir[iMarker][iVertex][iDim] = 0; + } + } + } + + /*--- Non dimensional coefficients ---*/ + + ForceInviscid = new su2double[3]; + MomentInviscid = new su2double[3]; + CD_Inv = new su2double[nMarker]; + CL_Inv = new su2double[nMarker]; + CSF_Inv = new su2double[nMarker]; + CMx_Inv = new su2double[nMarker]; + CMy_Inv = new su2double[nMarker]; + CMz_Inv = new su2double[nMarker]; + CEff_Inv = new su2double[nMarker]; + CFx_Inv = new su2double[nMarker]; + CFy_Inv = new su2double[nMarker]; + CFz_Inv = new su2double[nMarker]; + CoPx_Inv = new su2double[nMarker]; + CoPy_Inv = new su2double[nMarker]; + CoPz_Inv = new su2double[nMarker]; + + ForceMomentum = new su2double[3]; + MomentMomentum = new su2double[3]; + CD_Mnt = new su2double[nMarker]; + CL_Mnt = new su2double[nMarker]; + CSF_Mnt = new su2double[nMarker]; + CMx_Mnt = new su2double[nMarker]; + CMy_Mnt = new su2double[nMarker]; + CMz_Mnt = new su2double[nMarker]; + CEff_Mnt = new su2double[nMarker]; + CFx_Mnt = new su2double[nMarker]; + CFy_Mnt = new su2double[nMarker]; + CFz_Mnt = new su2double[nMarker]; + CoPx_Mnt = new su2double[nMarker]; + CoPy_Mnt = new su2double[nMarker]; + CoPz_Mnt = new su2double[nMarker]; + + ForceViscous = new su2double[3]; + MomentViscous = new su2double[3]; + CD_Visc = new su2double[nMarker]; + CL_Visc = new su2double[nMarker]; + CSF_Visc = new su2double[nMarker]; + CMx_Visc = new su2double[nMarker]; + CMy_Visc = new su2double[nMarker]; + CMz_Visc = new su2double[nMarker]; + CEff_Visc = new su2double[nMarker]; + CFx_Visc = new su2double[nMarker]; + CFy_Visc = new su2double[nMarker]; + CFz_Visc = new su2double[nMarker]; + CoPx_Visc = new su2double[nMarker]; + CoPy_Visc = new su2double[nMarker]; + CoPz_Visc = new su2double[nMarker]; + + Surface_CL_Inv = new su2double[config->GetnMarker_Monitoring()]; + Surface_CD_Inv = new su2double[config->GetnMarker_Monitoring()]; + Surface_CSF_Inv = new su2double[config->GetnMarker_Monitoring()]; + Surface_CEff_Inv = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFx_Inv = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFy_Inv = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFz_Inv = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMx_Inv = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMy_Inv = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMz_Inv = new su2double[config->GetnMarker_Monitoring()]; + + Surface_CL_Mnt = new su2double[config->GetnMarker_Monitoring()]; + Surface_CD_Mnt = new su2double[config->GetnMarker_Monitoring()]; + Surface_CSF_Mnt = new su2double[config->GetnMarker_Monitoring()]; + Surface_CEff_Mnt = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFx_Mnt = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFy_Mnt = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFz_Mnt = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMx_Mnt = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMy_Mnt = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMz_Mnt = new su2double[config->GetnMarker_Monitoring()]; + + Surface_CL = new su2double[config->GetnMarker_Monitoring()]; + Surface_CD = new su2double[config->GetnMarker_Monitoring()]; + Surface_CSF = new su2double[config->GetnMarker_Monitoring()]; + Surface_CEff = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFx = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFy = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFz = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMx = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMy = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMz = new su2double[config->GetnMarker_Monitoring()]; + + Surface_CL_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CD_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CSF_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CEff_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFx_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFy_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFz_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMx_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMy_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMz_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_HF_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_MaxHF_Visc = new su2double[config->GetnMarker_Monitoring()]; + + /*--- Rotorcraft coefficients ---*/ + + CT_Inv = new su2double[nMarker]; + CQ_Inv = new su2double[nMarker]; + CMerit_Inv = new su2double[nMarker]; + + CT_Mnt = new su2double[nMarker]; + CQ_Mnt = new su2double[nMarker]; + CMerit_Mnt = new su2double[nMarker]; + + CMerit_Visc = new su2double[nMarker]; + CT_Visc = new su2double[nMarker]; + CQ_Visc = new su2double[nMarker]; + + /*--- Heat based coefficients ---*/ + + HF_Visc = new su2double[nMarker]; + MaxHF_Visc = new su2double[nMarker]; + + /*--- Init total coefficients ---*/ + + Total_CD = 0.0; Total_CL = 0.0; Total_CSF = 0.0; + Total_CMx = 0.0; Total_CMy = 0.0; Total_CMz = 0.0; + Total_CoPx = 0.0; Total_CoPy = 0.0; Total_CoPz = 0.0; + Total_CEff = 0.0; + Total_CFx = 0.0; Total_CFy = 0.0; Total_CFz = 0.0; + Total_CT = 0.0; Total_CQ = 0.0; Total_CMerit = 0.0; + Total_MaxHeat = 0.0; Total_Heat = 0.0; Total_ComboObj = 0.0; + Total_CpDiff = 0.0; Total_HeatFluxDiff = 0.0; Total_Custom_ObjFunc = 0.0; + + /*--- Read farfield conditions from config ---*/ + + Density_Inf = config->GetDensity_FreeStreamND(); + Pressure_Inf = config->GetPressure_FreeStreamND(); + Temperature_Inf = config->GetTemperature_FreeStreamND(); + Velocity_Inf = config->GetVelocity_FreeStreamND(); + Viscosity_Inf = config->GetViscosity_FreeStreamND(); + Tke_Inf = config->GetTke_FreeStreamND(); + + /*--- Initialize the secondary values for direct derivative approxiations ---*/ + + switch(direct_diff){ + case NO_DERIVATIVE: + break; + case D_DENSITY: + SU2_TYPE::SetDerivative(Density_Inf, 1.0); + break; + case D_PRESSURE: + SU2_TYPE::SetDerivative(Pressure_Inf, 1.0); + break; + case D_TEMPERATURE: + SU2_TYPE::SetDerivative(Temperature_Inf, 1.0); + break; + case D_VISCOSITY: + SU2_TYPE::SetDerivative(Viscosity_Inf, 1.0); + break; + case D_MACH: case D_AOA: + case D_SIDESLIP: case D_REYNOLDS: + case D_TURB2LAM: case D_DESIGN: + /*--- Already done in postprocessing of config ---*/ + break; + default: + break; + } + + /*--- Initializate quantities for SlidingMesh Interface ---*/ + + SlidingState = new su2double*** [nMarker]; + SlidingStateNodes = new int* [nMarker]; + + for (iMarker = 0; iMarker < nMarker; iMarker++){ + + SlidingState[iMarker] = NULL; + SlidingStateNodes[iMarker] = NULL; + + if (config->GetMarker_All_KindBC(iMarker) == FLUID_INTERFACE){ + + SlidingState[iMarker] = new su2double**[geometry->GetnVertex(iMarker)]; + SlidingStateNodes[iMarker] = new int [geometry->GetnVertex(iMarker)]; + + for (iPoint = 0; iPoint < geometry->GetnVertex(iMarker); iPoint++){ + SlidingState[iMarker][iPoint] = new su2double*[nPrimVar+1]; + + SlidingStateNodes[iMarker][iPoint] = 0; + for (iVar = 0; iVar < nPrimVar+1; iVar++) + SlidingState[iMarker][iPoint][iVar] = NULL; + } + + } + } + + /*--- Only initialize when there is a Marker_Fluid_Load defined + *--- (this avoids overhead in all other cases while a more permanent structure is being developed) ---*/ + if((config->GetnMarker_Fluid_Load() > 0) && (MGLevel == MESH_0)){ + + InitVertexTractionContainer(geometry, config); + + if (config->GetDiscrete_Adjoint()) + InitVertexTractionAdjointContainer(geometry, config); + + } + + /*--- Initialize the solution to the far-field state everywhere. ---*/ + + nodes = new CIncNSVariable(Pressure_Inf, Velocity_Inf, Temperature_Inf, nPoint, nDim, nVar, config); + SetBaseClassPointerToNodes(); + + /*--- Initialize the BGS residuals in FSI problems. ---*/ + if (config->GetMultizone_Residual()){ + Residual_BGS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_RMS[iVar] = 0.0; + Residual_Max_BGS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_Max_BGS[iVar] = 0.0; + + /*--- Define some structures for locating max residuals ---*/ + + Point_Max_BGS = new unsigned long[nVar]; for (iVar = 0; iVar < nVar; iVar++) Point_Max_BGS[iVar] = 0; + Point_Max_Coord_BGS = new su2double*[nVar]; + for (iVar = 0; iVar < nVar; iVar++) { + Point_Max_Coord_BGS[iVar] = new su2double[nDim]; + for (iDim = 0; iDim < nDim; iDim++) Point_Max_Coord_BGS[iVar][iDim] = 0.0; + } + } + + /*--- Define solver parameters needed for execution of destructor ---*/ + + if (config->GetKind_ConvNumScheme_Flow() == SPACE_CENTERED) space_centered = true; + else space_centered = false; + + if (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT) euler_implicit = true; + else euler_implicit = false; + + if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) least_squares = true; + else least_squares = false; + + /*--- Communicate and store volume and the number of neighbors for + any dual CVs that lie on on periodic markers. ---*/ + + for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { + InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_VOLUME); + CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_VOLUME); + InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_NEIGHBORS); + CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_NEIGHBORS); + } + SetImplicitPeriodic(euler_implicit); + if (iMesh == MESH_0) SetRotatePeriodic(true); + + /*--- Perform the MPI communication of the solution ---*/ + + InitiateComms(geometry, config, SOLUTION); + CompleteComms(geometry, config, SOLUTION); + + /* Store the initial CFL number for all grid points. */ + + const su2double CFL = config->GetCFL(MGLevel); + for (iPoint = 0; iPoint < nPoint; iPoint++) { + nodes->SetLocalCFL(iPoint, CFL); + } + Min_CFL_Local = CFL; + Max_CFL_Local = CFL; + Avg_CFL_Local = CFL; + + /*--- Add the solver name (max 8 characters) ---*/ + SolverName = "INC.FLOW"; + +} + +CIncNSSolver::~CIncNSSolver(void) { + + unsigned short iMarker, iDim; + + unsigned long iVertex; + + if (CD_Visc != NULL) delete [] CD_Visc; + if (CL_Visc != NULL) delete [] CL_Visc; + if (CSF_Visc != NULL) delete [] CSF_Visc; + if (CMx_Visc != NULL) delete [] CMx_Visc; + if (CMy_Visc != NULL) delete [] CMy_Visc; + if (CMz_Visc != NULL) delete [] CMz_Visc; + if (CoPx_Visc != NULL) delete [] CoPx_Visc; + if (CoPy_Visc != NULL) delete [] CoPy_Visc; + if (CoPz_Visc != NULL) delete [] CoPz_Visc; + if (CFx_Visc != NULL) delete [] CFx_Visc; + if (CFy_Visc != NULL) delete [] CFy_Visc; + if (CFz_Visc != NULL) delete [] CFz_Visc; + if (CEff_Visc != NULL) delete [] CEff_Visc; + if (CMerit_Visc != NULL) delete [] CMerit_Visc; + if (CT_Visc != NULL) delete [] CT_Visc; + if (CQ_Visc != NULL) delete [] CQ_Visc; + if (HF_Visc != NULL) delete [] HF_Visc; + if (MaxHF_Visc != NULL) delete [] MaxHF_Visc; + if (ForceViscous != NULL) delete [] ForceViscous; + if (MomentViscous != NULL) delete [] MomentViscous; + + if (Surface_CL_Visc != NULL) delete [] Surface_CL_Visc; + if (Surface_CD_Visc != NULL) delete [] Surface_CD_Visc; + if (Surface_CSF_Visc != NULL) delete [] Surface_CSF_Visc; + if (Surface_CEff_Visc != NULL) delete [] Surface_CEff_Visc; + if (Surface_CFx_Visc != NULL) delete [] Surface_CFx_Visc; + if (Surface_CFy_Visc != NULL) delete [] Surface_CFy_Visc; + if (Surface_CFz_Visc != NULL) delete [] Surface_CFz_Visc; + if (Surface_CMx_Visc != NULL) delete [] Surface_CMx_Visc; + if (Surface_CMy_Visc != NULL) delete [] Surface_CMy_Visc; + if (Surface_CMz_Visc != NULL) delete [] Surface_CMz_Visc; + if (Surface_HF_Visc != NULL) delete [] Surface_HF_Visc; + if (Surface_MaxHF_Visc != NULL) delete [] Surface_MaxHF_Visc; + + if (CSkinFriction != NULL) { + for (iMarker = 0; iMarker < nMarker; iMarker++) { + for (iDim = 0; iDim < nDim; iDim++) { + delete [] CSkinFriction[iMarker][iDim]; + } + delete [] CSkinFriction[iMarker]; + } + delete [] CSkinFriction; + } + + if (HeatConjugateVar != NULL) { + for (iMarker = 0; iMarker < nMarker; iMarker++) { + for (iVertex = 0; iVertex < nVertex[iMarker]; iVertex++) { + delete [] HeatConjugateVar[iMarker][iVertex]; + } + delete [] HeatConjugateVar[iMarker]; + } + delete [] HeatConjugateVar; + } + +} + +void CIncNSSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output) { + + unsigned long iPoint, ErrorCounter = 0; + su2double StrainMag = 0.0, Omega = 0.0, *Vorticity; + + unsigned long InnerIter = config->GetInnerIter(); + bool cont_adjoint = config->GetContinuous_Adjoint(); + bool disc_adjoint = config->GetDiscrete_Adjoint(); + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + bool center = ((config->GetKind_ConvNumScheme_Flow() == SPACE_CENTERED) || (cont_adjoint && config->GetKind_ConvNumScheme_AdjFlow() == SPACE_CENTERED)); + bool center_jst = center && config->GetKind_Centered_Flow() == JST; + bool limiter_flow = (config->GetKind_SlopeLimit_Flow() != NO_LIMITER) && (InnerIter <= config->GetLimiterIter()); + bool limiter_turb = (config->GetKind_SlopeLimit_Turb() != NO_LIMITER) && (InnerIter <= config->GetLimiterIter()); + bool limiter_adjflow = (cont_adjoint && (config->GetKind_SlopeLimit_AdjFlow() != NO_LIMITER) && (InnerIter <= config->GetLimiterIter())); + bool van_albada = config->GetKind_SlopeLimit_Flow() == VAN_ALBADA_EDGE; + bool outlet = ((config->GetnMarker_Outlet() != 0)); + + /*--- Set the primitive variables ---*/ + + ErrorCounter = SetPrimitive_Variables(solver_container, config, Output); + + /*--- Compute gradient for MUSCL reconstruction. ---*/ + + if (config->GetReconstructionGradientRequired() && (iMesh == MESH_0)) { + if (config->GetKind_Gradient_Method_Recon() == GREEN_GAUSS) + SetPrimitive_Gradient_GG(geometry, config, true); + if (config->GetKind_Gradient_Method_Recon() == LEAST_SQUARES) + SetPrimitive_Gradient_LS(geometry, config, true); + if (config->GetKind_Gradient_Method_Recon() == WEIGHTED_LEAST_SQUARES) + SetPrimitive_Gradient_LS(geometry, config, true); + } + + /*--- Compute gradient of the primitive variables ---*/ + + if (config->GetKind_Gradient_Method() == GREEN_GAUSS) { + SetPrimitive_Gradient_GG(geometry, config); + } + if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) { + SetPrimitive_Gradient_LS(geometry, config); + } + + /*--- Compute the limiter in case we need it in the turbulence model + or to limit the viscous terms (check this logic with JST and 2nd order turbulence model) ---*/ + + if ((iMesh == MESH_0) && (limiter_flow || limiter_turb || limiter_adjflow) + && !Output && !van_albada) { SetPrimitive_Limiter(geometry, config); } + + /*--- Artificial dissipation for centered schemes. ---*/ + + if (center && !Output) { + SetMax_Eigenvalue(geometry, config); + if ((center_jst) && (iMesh == MESH_0)) { + SetCentered_Dissipation_Sensor(geometry, config); + SetUndivided_Laplacian(geometry, config); + } + } + + /*--- Update the beta value based on the maximum velocity / viscosity. ---*/ + + SetBeta_Parameter(geometry, solver_container, config, iMesh); + + /*--- Compute properties needed for mass flow BCs. ---*/ + + if (outlet) GetOutlet_Properties(geometry, config, iMesh, Output); + + /*--- Evaluate the vorticity and strain rate magnitude ---*/ + + solver_container[FLOW_SOL]->GetNodes()->SetVorticity_StrainMag(); + + StrainMag_Max = 0.0; Omega_Max = 0.0; + for (iPoint = 0; iPoint < nPoint; iPoint++) { + + StrainMag = solver_container[FLOW_SOL]->GetNodes()->GetStrainMag(iPoint); + Vorticity = solver_container[FLOW_SOL]->GetNodes()->GetVorticity(iPoint); + Omega = sqrt(Vorticity[0]*Vorticity[0]+ Vorticity[1]*Vorticity[1]+ Vorticity[2]*Vorticity[2]); + + StrainMag_Max = max(StrainMag_Max, StrainMag); + Omega_Max = max(Omega_Max, Omega); + + } + + /*--- Initialize the Jacobian matrices ---*/ + + if (implicit && !disc_adjoint) Jacobian.SetValZero(); + + /*--- Error message ---*/ + + if (config->GetComm_Level() == COMM_FULL) { + +#ifdef HAVE_MPI + unsigned long MyErrorCounter = ErrorCounter; ErrorCounter = 0; + su2double MyOmega_Max = Omega_Max; Omega_Max = 0.0; + su2double MyStrainMag_Max = StrainMag_Max; StrainMag_Max = 0.0; + + SU2_MPI::Allreduce(&MyErrorCounter, &ErrorCounter, 1, MPI_UNSIGNED_LONG, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyStrainMag_Max, &StrainMag_Max, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyOmega_Max, &Omega_Max, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); +#endif + + if (iMesh == MESH_0) { + config->SetNonphysical_Points(ErrorCounter); + solver_container[FLOW_SOL]->SetStrainMag_Max(StrainMag_Max); + solver_container[FLOW_SOL]->SetOmega_Max(Omega_Max); + } + + } + +} + +unsigned long CIncNSSolver::SetPrimitive_Variables(CSolver **solver_container, CConfig *config, bool Output) { + + unsigned long iPoint, nonPhysicalPoints = 0; + su2double eddy_visc = 0.0, turb_ke = 0.0, DES_LengthScale = 0.0; + unsigned short turb_model = config->GetKind_Turb_Model(); + bool physical = true; + + bool tkeNeeded = ((turb_model == SST) || (turb_model == SST_SUST)); + + for (iPoint = 0; iPoint < nPoint; iPoint++) { + + /*--- Retrieve the value of the kinetic energy (if needed) ---*/ + + if (turb_model != NONE) { + eddy_visc = solver_container[TURB_SOL]->GetNodes()->GetmuT(iPoint); + if (tkeNeeded) turb_ke = solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0); + + if (config->GetKind_HybridRANSLES() != NO_HYBRIDRANSLES){ + DES_LengthScale = solver_container[TURB_SOL]->GetNodes()->GetDES_LengthScale(iPoint); + } + } + + /*--- Incompressible flow, primitive variables --- */ + + physical = static_cast(nodes)->SetPrimVar(iPoint,eddy_visc, turb_ke, FluidModel); + + /* Check for non-realizable states for reporting. */ + + if (!physical) nonPhysicalPoints++; + + /*--- Set the DES length scale ---*/ + + nodes->SetDES_LengthScale(iPoint,DES_LengthScale); + + /*--- Initialize the convective, source and viscous residual vector ---*/ + + if (!Output) LinSysRes.SetBlock_Zero(iPoint); + + } + + return nonPhysicalPoints; + +} + +void CIncNSSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned long Iteration) { + + su2double Mean_BetaInc2, *Normal, Area, Vol, Mean_SoundSpeed = 0.0, Mean_ProjVel = 0.0, Lambda, Local_Delta_Time, Local_Delta_Time_Visc, + Global_Delta_Time = 1E6, Mean_LaminarVisc = 0.0, Mean_EddyVisc = 0.0, Mean_Density = 0.0, Mean_Thermal_Conductivity = 0.0, Mean_Cv = 0.0, Lambda_1, Lambda_2, K_v = 0.25, Global_Delta_UnstTimeND; + unsigned long iEdge, iVertex, iPoint = 0, jPoint = 0; + unsigned short iDim, iMarker; + su2double ProjVel, ProjVel_i, ProjVel_j; + + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + bool dual_time = ((config->GetTime_Marching() == DT_STEPPING_1ST) || + (config->GetTime_Marching() == DT_STEPPING_2ND)); + bool energy = config->GetEnergy_Equation(); + + Min_Delta_Time = 1.E30; Max_Delta_Time = 0.0; + + /*--- Set maximum inviscid eigenvalue to zero, and compute sound speed and viscosity ---*/ + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + nodes->SetMax_Lambda_Inv(iPoint,0.0); + nodes->SetMax_Lambda_Visc(iPoint,0.0); + } + + /*--- Loop interior edges ---*/ + + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { + + /*--- Point identification, Normal vector and area ---*/ + + iPoint = geometry->edge[iEdge]->GetNode(0); + jPoint = geometry->edge[iEdge]->GetNode(1); + + Normal = geometry->edge[iEdge]->GetNormal(); + Area = 0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); + + /*--- Mean Values ---*/ + + Mean_ProjVel = 0.5 * (nodes->GetProjVel(iPoint,Normal) + nodes->GetProjVel(jPoint,Normal)); + Mean_BetaInc2 = 0.5 * (nodes->GetBetaInc2(iPoint) + nodes->GetBetaInc2(jPoint)); + Mean_Density = 0.5 * (nodes->GetDensity(iPoint) + nodes->GetDensity(jPoint)); + Mean_SoundSpeed = sqrt(Mean_BetaInc2*Area*Area); + + /*--- Adjustment for grid movement ---*/ + + if (dynamic_grid) { + su2double *GridVel_i = geometry->node[iPoint]->GetGridVel(); + su2double *GridVel_j = geometry->node[jPoint]->GetGridVel(); + ProjVel_i = 0.0; ProjVel_j =0.0; + for (iDim = 0; iDim < nDim; iDim++) { + ProjVel_i += GridVel_i[iDim]*Normal[iDim]; + ProjVel_j += GridVel_j[iDim]*Normal[iDim]; + } + Mean_ProjVel -= 0.5 * (ProjVel_i + ProjVel_j); + } + + /*--- Inviscid contribution ---*/ + + Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; + if (geometry->node[iPoint]->GetDomain()) nodes->AddMax_Lambda_Inv(iPoint,Lambda); + if (geometry->node[jPoint]->GetDomain()) nodes->AddMax_Lambda_Inv(jPoint,Lambda); + + /*--- Viscous contribution ---*/ + + Mean_LaminarVisc = 0.5*(nodes->GetLaminarViscosity(iPoint) + nodes->GetLaminarViscosity(jPoint)); + Mean_EddyVisc = 0.5*(nodes->GetEddyViscosity(iPoint) + nodes->GetEddyViscosity(jPoint)); + Mean_Density = 0.5*(nodes->GetDensity(iPoint) + nodes->GetDensity(jPoint)); + Mean_Thermal_Conductivity = 0.5*(nodes->GetThermalConductivity(iPoint) + nodes->GetThermalConductivity(jPoint)); + Mean_Cv = 0.5*(nodes->GetSpecificHeatCv(iPoint) + nodes->GetSpecificHeatCv(jPoint)); + + Lambda_1 = (4.0/3.0)*(Mean_LaminarVisc + Mean_EddyVisc); + Lambda_2 = 0.0; + if (energy) Lambda_2 = (1.0/Mean_Cv)*Mean_Thermal_Conductivity; + Lambda = (Lambda_1 + Lambda_2)*Area*Area/Mean_Density; + + if (geometry->node[iPoint]->GetDomain()) nodes->AddMax_Lambda_Visc(iPoint,Lambda); + if (geometry->node[jPoint]->GetDomain()) nodes->AddMax_Lambda_Visc(jPoint,Lambda); + + } + + /*--- Loop boundary edges ---*/ + + for (iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { + if ((config->GetMarker_All_KindBC(iMarker) != INTERNAL_BOUNDARY) && + (config->GetMarker_All_KindBC(iMarker) != PERIODIC_BOUNDARY)) { + for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { + + /*--- Point identification, Normal vector and area ---*/ + + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); + + /*--- Mean Values ---*/ + + Mean_ProjVel = nodes->GetProjVel(iPoint,Normal); + Mean_BetaInc2 = nodes->GetBetaInc2(iPoint); + Mean_Density = nodes->GetDensity(iPoint); + Mean_SoundSpeed = sqrt(Mean_BetaInc2*Area*Area); + + /*--- Adjustment for grid movement ---*/ + + if (dynamic_grid) { + su2double *GridVel = geometry->node[iPoint]->GetGridVel(); + ProjVel = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + ProjVel += GridVel[iDim]*Normal[iDim]; + Mean_ProjVel -= ProjVel; + } + + /*--- Inviscid contribution ---*/ + + Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; + if (geometry->node[iPoint]->GetDomain()) { + nodes->AddMax_Lambda_Inv(iPoint,Lambda); + } + + /*--- Viscous contribution ---*/ + + Mean_LaminarVisc = nodes->GetLaminarViscosity(iPoint); + Mean_EddyVisc = nodes->GetEddyViscosity(iPoint); + Mean_Density = nodes->GetDensity(iPoint); + Mean_Thermal_Conductivity = nodes->GetThermalConductivity(iPoint); + Mean_Cv = nodes->GetSpecificHeatCv(iPoint); + + Lambda_1 = (4.0/3.0)*(Mean_LaminarVisc + Mean_EddyVisc); + Lambda_2 = 0.0; + if (energy) Lambda_2 = (1.0/Mean_Cv)*Mean_Thermal_Conductivity; + Lambda = (Lambda_1 + Lambda_2)*Area*Area/Mean_Density; + + if (geometry->node[iPoint]->GetDomain()) nodes->AddMax_Lambda_Visc(iPoint,Lambda); + + } + } + } + + /*--- Each element uses their own speed, steady state simulation ---*/ + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + Vol = geometry->node[iPoint]->GetVolume(); + + if (Vol != 0.0) { + Local_Delta_Time = nodes->GetLocalCFL(iPoint)*Vol / nodes->GetMax_Lambda_Inv(iPoint); + Local_Delta_Time_Visc = nodes->GetLocalCFL(iPoint)*K_v*Vol*Vol/ nodes->GetMax_Lambda_Visc(iPoint); + Local_Delta_Time = min(Local_Delta_Time, Local_Delta_Time_Visc); + Global_Delta_Time = min(Global_Delta_Time, Local_Delta_Time); + Min_Delta_Time = min(Min_Delta_Time, Local_Delta_Time); + Max_Delta_Time = max(Max_Delta_Time, Local_Delta_Time); + if (Local_Delta_Time > config->GetMax_DeltaTime()) + Local_Delta_Time = config->GetMax_DeltaTime(); + nodes->SetDelta_Time(iPoint,Local_Delta_Time); + } + else { + nodes->SetDelta_Time(iPoint,0.0); + } + + } + + /*--- Compute the max and the min dt (in parallel) ---*/ + if (config->GetComm_Level() == COMM_FULL) { +#ifdef HAVE_MPI + su2double rbuf_time, sbuf_time; + sbuf_time = Min_Delta_Time; + SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, MPI_COMM_WORLD); + SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); + Min_Delta_Time = rbuf_time; + + sbuf_time = Max_Delta_Time; + SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MAX, MASTER_NODE, MPI_COMM_WORLD); + SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); + Max_Delta_Time = rbuf_time; +#endif + } + + /*--- For exact time solution use the minimum delta time of the whole mesh ---*/ + if (config->GetTime_Marching() == TIME_STEPPING) { +#ifdef HAVE_MPI + su2double rbuf_time, sbuf_time; + sbuf_time = Global_Delta_Time; + SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, MPI_COMM_WORLD); + SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); + Global_Delta_Time = rbuf_time; +#endif + /*--- If the unsteady CFL is set to zero, it uses the defined + unsteady time step, otherwise it computes the time step based + on the unsteady CFL ---*/ + + if (config->GetUnst_CFL() == 0.0) { + Global_Delta_Time = config->GetDelta_UnstTime(); + } + config->SetDelta_UnstTimeND(Global_Delta_Time); + for (iPoint = 0; iPoint < nPointDomain; iPoint++){ + + /*--- Sets the regular CFL equal to the unsteady CFL ---*/ + + nodes->SetLocalCFL(iPoint, config->GetUnst_CFL()); + nodes->SetDelta_Time(iPoint, Global_Delta_Time); + Min_Delta_Time = Global_Delta_Time; + Max_Delta_Time = Global_Delta_Time; + + } + } + + /*--- Recompute the unsteady time step for the dual time strategy + if the unsteady CFL is diferent from 0 ---*/ + if ((dual_time) && (Iteration == 0) && (config->GetUnst_CFL() != 0.0) && (iMesh == MESH_0)) { + + Global_Delta_UnstTimeND = 1e30; + for (iPoint = 0; iPoint < nPointDomain; iPoint++){ + Global_Delta_UnstTimeND = min(Global_Delta_UnstTimeND,config->GetUnst_CFL()*Global_Delta_Time/nodes->GetLocalCFL(iPoint)); + } + +#ifdef HAVE_MPI + su2double rbuf_time, sbuf_time; + sbuf_time = Global_Delta_UnstTimeND; + SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, MPI_COMM_WORLD); + SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); + Global_Delta_UnstTimeND = rbuf_time; +#endif + config->SetDelta_UnstTimeND(Global_Delta_UnstTimeND); + } + + /*--- The pseudo local time (explicit integration) cannot be greater than the physical time ---*/ + if (dual_time) + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + if (!implicit) { + Local_Delta_Time = min((2.0/3.0)*config->GetDelta_UnstTimeND(), nodes->GetDelta_Time(iPoint)); + nodes->SetDelta_Time(iPoint,Local_Delta_Time); + } + } + +} + +void CIncNSSolver::Viscous_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, + CConfig *config, unsigned short iMesh, unsigned short iRKStep) { + + unsigned long iPoint, jPoint, iEdge; + + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { + + /*--- Points, coordinates and normal vector in edge ---*/ + + iPoint = geometry->edge[iEdge]->GetNode(0); + jPoint = geometry->edge[iEdge]->GetNode(1); + numerics->SetCoord(geometry->node[iPoint]->GetCoord(), + geometry->node[jPoint]->GetCoord()); + numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); + + /*--- Primitive and secondary variables ---*/ + + numerics->SetPrimitive(nodes->GetPrimitive(iPoint), + nodes->GetPrimitive(jPoint)); + + /*--- Gradient and limiters ---*/ + + numerics->SetPrimVarGradient(nodes->GetGradient_Primitive(iPoint), + nodes->GetGradient_Primitive(jPoint)); + + /*--- Turbulent kinetic energy ---*/ + + if ((config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST)) + numerics->SetTurbKineticEnergy(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0), + solver_container[TURB_SOL]->GetNodes()->GetSolution(jPoint,0)); + + /*--- Compute and update residual ---*/ + + numerics->ComputeResidual(Res_Visc, Jacobian_i, Jacobian_j, config); + + LinSysRes.SubtractBlock(iPoint, Res_Visc); + LinSysRes.AddBlock(jPoint, Res_Visc); + + /*--- Implicit part ---*/ + + if (implicit) { + Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); + Jacobian.SubtractBlock(iPoint, jPoint, Jacobian_j); + Jacobian.AddBlock(jPoint, iPoint, Jacobian_i); + Jacobian.AddBlock(jPoint, jPoint, Jacobian_j); + } + + } + +} + +void CIncNSSolver::Friction_Forces(CGeometry *geometry, CConfig *config) { + + unsigned long iVertex, iPoint, iPointNormal; + unsigned short Boundary, Monitoring, iMarker, iMarker_Monitoring, iDim, jDim; + su2double Viscosity = 0.0, div_vel, *Normal, MomentDist[3] = {0.0, 0.0, 0.0}, WallDist[3] = {0.0, 0.0, 0.0}, + *Coord, *Coord_Normal, Area, WallShearStress, TauNormal, factor, RefVel2 = 0.0, + RefDensity = 0.0, Density = 0.0, WallDistMod, FrictionVel, UnitNormal[3] = {0.0, 0.0, 0.0}, TauElem[3] = {0.0, 0.0, 0.0}, TauTangent[3] = {0.0, 0.0, 0.0}, + Tau[3][3] = {{0.0, 0.0, 0.0},{0.0, 0.0, 0.0},{0.0, 0.0, 0.0}}, Force[3] = {0.0, 0.0, 0.0}, + Grad_Vel[3][3] = {{0.0, 0.0, 0.0},{0.0, 0.0, 0.0},{0.0, 0.0, 0.0}}, + delta[3][3] = {{1.0, 0.0, 0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}}, + Grad_Temp[3] = {0.0, 0.0, 0.0}, GradTemperature, thermal_conductivity, MaxNorm = 8.0; + su2double MomentX_Force[3] = {0.0,0.0,0.0}, MomentY_Force[3] = {0.0,0.0,0.0}, MomentZ_Force[3] = {0.0,0.0,0.0}; + su2double AxiFactor; + +#ifdef HAVE_MPI + su2double MyAllBound_CD_Visc, MyAllBound_CL_Visc, MyAllBound_CSF_Visc, MyAllBound_CMx_Visc, MyAllBound_CMy_Visc, MyAllBound_CMz_Visc, MyAllBound_CoPx_Visc, MyAllBound_CoPy_Visc, MyAllBound_CoPz_Visc, MyAllBound_CFx_Visc, MyAllBound_CFy_Visc, MyAllBound_CFz_Visc, MyAllBound_CT_Visc, MyAllBound_CQ_Visc, MyAllBound_HF_Visc, MyAllBound_MaxHF_Visc, *MySurface_CL_Visc = NULL, *MySurface_CD_Visc = NULL, *MySurface_CSF_Visc = NULL, *MySurface_CEff_Visc = NULL, *MySurface_CFx_Visc = NULL, *MySurface_CFy_Visc = NULL, *MySurface_CFz_Visc = NULL, *MySurface_CMx_Visc = NULL, *MySurface_CMy_Visc = NULL, *MySurface_CMz_Visc = NULL, *MySurface_HF_Visc = NULL, *MySurface_MaxHF_Visc = NULL; +#endif + + string Marker_Tag, Monitoring_Tag; + + su2double Alpha = config->GetAoA()*PI_NUMBER/180.0; + su2double Beta = config->GetAoS()*PI_NUMBER/180.0; + su2double RefArea = config->GetRefArea(); + su2double RefLength = config->GetRefLength(); + su2double RefHeatFlux = config->GetHeat_Flux_Ref(); + su2double *Origin = NULL; + + if (config->GetnMarker_Monitoring() != 0) { Origin = config->GetRefOriginMoment(0); } + + bool axisymmetric = config->GetAxisymmetric(); + bool energy = config->GetEnergy_Equation(); + + /*--- Evaluate reference values for non-dimensionalization. + For dimensional or non-dim based on initial values, use + the far-field state (inf). For a custom non-dim based + on user-provided reference values, use the ref values + to compute the forces. ---*/ + + if ((config->GetRef_Inc_NonDim() == DIMENSIONAL) || + (config->GetRef_Inc_NonDim() == INITIAL_VALUES)) { + RefDensity = Density_Inf; + RefVel2 = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + RefVel2 += Velocity_Inf[iDim]*Velocity_Inf[iDim]; + } + else if (config->GetRef_Inc_NonDim() == REFERENCE_VALUES) { + RefDensity = config->GetInc_Density_Ref(); + RefVel2 = config->GetInc_Velocity_Ref()*config->GetInc_Velocity_Ref(); + } + + /*--- Compute factor for force coefficients. ---*/ + + factor = 1.0 / (0.5*RefDensity*RefArea*RefVel2); + + /*--- Variables initialization ---*/ + + AllBound_CD_Visc = 0.0; AllBound_CL_Visc = 0.0; AllBound_CSF_Visc = 0.0; + AllBound_CMx_Visc = 0.0; AllBound_CMy_Visc = 0.0; AllBound_CMz_Visc = 0.0; + AllBound_CFx_Visc = 0.0; AllBound_CFy_Visc = 0.0; AllBound_CFz_Visc = 0.0; + AllBound_CoPx_Visc = 0.0; AllBound_CoPy_Visc = 0.0; AllBound_CoPz_Visc = 0.0; + AllBound_CT_Visc = 0.0; AllBound_CQ_Visc = 0.0; AllBound_CMerit_Visc = 0.0; + AllBound_HF_Visc = 0.0; AllBound_MaxHF_Visc = 0.0; AllBound_CEff_Visc = 0.0; + + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { + Surface_CL_Visc[iMarker_Monitoring] = 0.0; Surface_CD_Visc[iMarker_Monitoring] = 0.0; + Surface_CSF_Visc[iMarker_Monitoring] = 0.0; Surface_CEff_Visc[iMarker_Monitoring] = 0.0; + Surface_CFx_Visc[iMarker_Monitoring] = 0.0; Surface_CFy_Visc[iMarker_Monitoring] = 0.0; + Surface_CFz_Visc[iMarker_Monitoring] = 0.0; Surface_CMx_Visc[iMarker_Monitoring] = 0.0; + Surface_CMy_Visc[iMarker_Monitoring] = 0.0; Surface_CMz_Visc[iMarker_Monitoring] = 0.0; + Surface_HF_Visc[iMarker_Monitoring] = 0.0; Surface_MaxHF_Visc[iMarker_Monitoring] = 0.0; + } + + /*--- Loop over the Navier-Stokes markers ---*/ + + for (iMarker = 0; iMarker < nMarker; iMarker++) { + + Boundary = config->GetMarker_All_KindBC(iMarker); + Monitoring = config->GetMarker_All_Monitoring(iMarker); + + /*--- Obtain the origin for the moment computation for a particular marker ---*/ + + if (Monitoring == YES) { + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { + Monitoring_Tag = config->GetMarker_Monitoring_TagBound(iMarker_Monitoring); + Marker_Tag = config->GetMarker_All_TagBound(iMarker); + if (Marker_Tag == Monitoring_Tag) + Origin = config->GetRefOriginMoment(iMarker_Monitoring); + } + } + + if ((Boundary == HEAT_FLUX) || (Boundary == ISOTHERMAL) || (Boundary == CHT_WALL_INTERFACE)) { + + /*--- Forces initialization at each Marker ---*/ + + CD_Visc[iMarker] = 0.0; CL_Visc[iMarker] = 0.0; CSF_Visc[iMarker] = 0.0; + CMx_Visc[iMarker] = 0.0; CMy_Visc[iMarker] = 0.0; CMz_Visc[iMarker] = 0.0; + CFx_Visc[iMarker] = 0.0; CFy_Visc[iMarker] = 0.0; CFz_Visc[iMarker] = 0.0; + CoPx_Visc[iMarker] = 0.0; CoPy_Visc[iMarker] = 0.0; CoPz_Visc[iMarker] = 0.0; + CT_Visc[iMarker] = 0.0; CQ_Visc[iMarker] = 0.0; CMerit_Visc[iMarker] = 0.0; + HF_Visc[iMarker] = 0.0; MaxHF_Visc[iMarker] = 0.0; CEff_Visc[iMarker] = 0.0; + + for (iDim = 0; iDim < nDim; iDim++) ForceViscous[iDim] = 0.0; + MomentViscous[0] = 0.0; MomentViscous[1] = 0.0; MomentViscous[2] = 0.0; + MomentX_Force[0] = 0.0; MomentX_Force[1] = 0.0; MomentX_Force[2] = 0.0; + MomentY_Force[0] = 0.0; MomentY_Force[1] = 0.0; MomentY_Force[2] = 0.0; + MomentZ_Force[0] = 0.0; MomentZ_Force[1] = 0.0; MomentZ_Force[2] = 0.0; + + /*--- Loop over the vertices to compute the forces ---*/ + + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + iPointNormal = geometry->vertex[iMarker][iVertex]->GetNormal_Neighbor(); + + Coord = geometry->node[iPoint]->GetCoord(); + Coord_Normal = geometry->node[iPointNormal]->GetCoord(); + + Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); + + for (iDim = 0; iDim < nDim; iDim++) { + for (jDim = 0 ; jDim < nDim; jDim++) { + Grad_Vel[iDim][jDim] = nodes->GetGradient_Primitive(iPoint,iDim+1, jDim); + } + Grad_Temp[iDim] = nodes->GetGradient_Primitive(iPoint,nDim+1, iDim); + } + + Viscosity = nodes->GetLaminarViscosity(iPoint); + Density = nodes->GetDensity(iPoint); + + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); + for (iDim = 0; iDim < nDim; iDim++) { + UnitNormal[iDim] = Normal[iDim]/Area; + } + + /*--- Evaluate Tau ---*/ + + div_vel = 0.0; for (iDim = 0; iDim < nDim; iDim++) div_vel += Grad_Vel[iDim][iDim]; + + for (iDim = 0; iDim < nDim; iDim++) { + for (jDim = 0 ; jDim < nDim; jDim++) { + Tau[iDim][jDim] = Viscosity*(Grad_Vel[jDim][iDim] + Grad_Vel[iDim][jDim]) - TWO3*Viscosity*div_vel*delta[iDim][jDim]; + } + } + + /*--- Project Tau in each surface element ---*/ + + for (iDim = 0; iDim < nDim; iDim++) { + TauElem[iDim] = 0.0; + for (jDim = 0; jDim < nDim; jDim++) { + TauElem[iDim] += Tau[iDim][jDim]*UnitNormal[jDim]; + } + } + + /*--- Compute wall shear stress (using the stress tensor). Compute wall skin friction coefficient, and heat flux on the wall ---*/ + + TauNormal = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + TauNormal += TauElem[iDim] * UnitNormal[iDim]; + + WallShearStress = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + TauTangent[iDim] = TauElem[iDim] - TauNormal * UnitNormal[iDim]; + CSkinFriction[iMarker][iDim][iVertex] = TauTangent[iDim] / (0.5*RefDensity*RefVel2); + WallShearStress += TauTangent[iDim] * TauTangent[iDim]; + } + WallShearStress = sqrt(WallShearStress); + + for (iDim = 0; iDim < nDim; iDim++) WallDist[iDim] = (Coord[iDim] - Coord_Normal[iDim]); + WallDistMod = 0.0; for (iDim = 0; iDim < nDim; iDim++) WallDistMod += WallDist[iDim]*WallDist[iDim]; WallDistMod = sqrt(WallDistMod); + + /*--- Compute y+ and non-dimensional velocity ---*/ + + FrictionVel = sqrt(fabs(WallShearStress)/Density); + YPlus[iMarker][iVertex] = WallDistMod*FrictionVel/(Viscosity/Density); + + /*--- Compute total and maximum heat flux on the wall ---*/ + + GradTemperature = 0.0; + if (energy) { + for (iDim = 0; iDim < nDim; iDim++) + GradTemperature -= Grad_Temp[iDim]*UnitNormal[iDim]; + } + + thermal_conductivity = nodes->GetThermalConductivity(iPoint); + HeatFlux[iMarker][iVertex] = -thermal_conductivity*GradTemperature*RefHeatFlux; + + /*--- Note that y+, and heat are computed at the + halo cells (for visualization purposes), but not the forces ---*/ + + if ((geometry->node[iPoint]->GetDomain()) && (Monitoring == YES)) { + + /*--- Axisymmetric simulations ---*/ + + if (axisymmetric) AxiFactor = 2.0*PI_NUMBER*geometry->node[iPoint]->GetCoord(1); + else AxiFactor = 1.0; + + /*--- Force computation ---*/ + + for (iDim = 0; iDim < nDim; iDim++) { + Force[iDim] = TauElem[iDim] * Area * factor * AxiFactor; + ForceViscous[iDim] += Force[iDim]; + MomentDist[iDim] = Coord[iDim] - Origin[iDim]; + } + + /*--- Moment with respect to the reference axis ---*/ + + if (iDim == 3) { + MomentViscous[0] += (Force[2]*MomentDist[1] - Force[1]*MomentDist[2])/RefLength; + MomentX_Force[1] += (-Force[1]*Coord[2]); + MomentX_Force[2] += (Force[2]*Coord[1]); + + MomentViscous[1] += (Force[0]*MomentDist[2] - Force[2]*MomentDist[0])/RefLength; + MomentY_Force[2] += (-Force[2]*Coord[0]); + MomentY_Force[0] += (Force[0]*Coord[2]); + } + MomentViscous[2] += (Force[1]*MomentDist[0] - Force[0]*MomentDist[1])/RefLength; + MomentZ_Force[0] += (-Force[0]*Coord[1]); + MomentZ_Force[1] += (Force[1]*Coord[0]); + + HF_Visc[iMarker] += HeatFlux[iMarker][iVertex]*Area; + MaxHF_Visc[iMarker] += pow(HeatFlux[iMarker][iVertex], MaxNorm); + + } + + } + + /*--- Project forces and store the non-dimensional coefficients ---*/ + + if (Monitoring == YES) { + if (nDim == 2) { + CD_Visc[iMarker] = ForceViscous[0]*cos(Alpha) + ForceViscous[1]*sin(Alpha); + CL_Visc[iMarker] = -ForceViscous[0]*sin(Alpha) + ForceViscous[1]*cos(Alpha); + CEff_Visc[iMarker] = CL_Visc[iMarker] / (CD_Visc[iMarker]+EPS); + CMz_Visc[iMarker] = MomentViscous[2]; + CFx_Visc[iMarker] = ForceViscous[0]; + CFy_Visc[iMarker] = ForceViscous[1]; + CoPx_Visc[iMarker] = MomentZ_Force[1]; + CoPy_Visc[iMarker] = -MomentZ_Force[0]; + CT_Visc[iMarker] = -CFx_Visc[iMarker]; + CQ_Visc[iMarker] = -CMz_Visc[iMarker]; + CMerit_Visc[iMarker] = CT_Visc[iMarker] / (CQ_Visc[iMarker]+EPS); + MaxHF_Visc[iMarker] = pow(MaxHF_Visc[iMarker], 1.0/MaxNorm); + } + if (nDim == 3) { + CD_Visc[iMarker] = ForceViscous[0]*cos(Alpha)*cos(Beta) + ForceViscous[1]*sin(Beta) + ForceViscous[2]*sin(Alpha)*cos(Beta); + CL_Visc[iMarker] = -ForceViscous[0]*sin(Alpha) + ForceViscous[2]*cos(Alpha); + CSF_Visc[iMarker] = -ForceViscous[0]*sin(Beta)*cos(Alpha) + ForceViscous[1]*cos(Beta) - ForceViscous[2]*sin(Beta)*sin(Alpha); + CEff_Visc[iMarker] = CL_Visc[iMarker]/(CD_Visc[iMarker] + EPS); + CMx_Visc[iMarker] = MomentViscous[0]; + CMy_Visc[iMarker] = MomentViscous[1]; + CMz_Visc[iMarker] = MomentViscous[2]; + CFx_Visc[iMarker] = ForceViscous[0]; + CFy_Visc[iMarker] = ForceViscous[1]; + CFz_Visc[iMarker] = ForceViscous[2]; + CoPx_Visc[iMarker] = -MomentY_Force[0]; + CoPz_Visc[iMarker] = MomentY_Force[2]; + CT_Visc[iMarker] = -CFz_Visc[iMarker]; + CQ_Visc[iMarker] = -CMz_Visc[iMarker]; + CMerit_Visc[iMarker] = CT_Visc[iMarker] / (CQ_Visc[iMarker] + EPS); + MaxHF_Visc[iMarker] = pow(MaxHF_Visc[iMarker], 1.0/MaxNorm); + } + + AllBound_CD_Visc += CD_Visc[iMarker]; + AllBound_CL_Visc += CL_Visc[iMarker]; + AllBound_CSF_Visc += CSF_Visc[iMarker]; + AllBound_CMx_Visc += CMx_Visc[iMarker]; + AllBound_CMy_Visc += CMy_Visc[iMarker]; + AllBound_CMz_Visc += CMz_Visc[iMarker]; + AllBound_CFx_Visc += CFx_Visc[iMarker]; + AllBound_CFy_Visc += CFy_Visc[iMarker]; + AllBound_CFz_Visc += CFz_Visc[iMarker]; + AllBound_CoPx_Visc += CoPx_Visc[iMarker]; + AllBound_CoPy_Visc += CoPy_Visc[iMarker]; + AllBound_CoPz_Visc += CoPz_Visc[iMarker]; + AllBound_CT_Visc += CT_Visc[iMarker]; + AllBound_CQ_Visc += CQ_Visc[iMarker]; + AllBound_HF_Visc += HF_Visc[iMarker]; + AllBound_MaxHF_Visc += pow(MaxHF_Visc[iMarker], MaxNorm); + + /*--- Compute the coefficients per surface ---*/ + + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { + Monitoring_Tag = config->GetMarker_Monitoring_TagBound(iMarker_Monitoring); + Marker_Tag = config->GetMarker_All_TagBound(iMarker); + if (Marker_Tag == Monitoring_Tag) { + Surface_CL_Visc[iMarker_Monitoring] += CL_Visc[iMarker]; + Surface_CD_Visc[iMarker_Monitoring] += CD_Visc[iMarker]; + Surface_CSF_Visc[iMarker_Monitoring] += CSF_Visc[iMarker]; + Surface_CEff_Visc[iMarker_Monitoring] += CEff_Visc[iMarker]; + Surface_CFx_Visc[iMarker_Monitoring] += CFx_Visc[iMarker]; + Surface_CFy_Visc[iMarker_Monitoring] += CFy_Visc[iMarker]; + Surface_CFz_Visc[iMarker_Monitoring] += CFz_Visc[iMarker]; + Surface_CMx_Visc[iMarker_Monitoring] += CMx_Visc[iMarker]; + Surface_CMy_Visc[iMarker_Monitoring] += CMy_Visc[iMarker]; + Surface_CMz_Visc[iMarker_Monitoring] += CMz_Visc[iMarker]; + Surface_HF_Visc[iMarker_Monitoring] += HF_Visc[iMarker]; + Surface_MaxHF_Visc[iMarker_Monitoring] += pow(MaxHF_Visc[iMarker],MaxNorm); + } + } + + } + + } + } + + /*--- Update some global coeffients ---*/ + + AllBound_CEff_Visc = AllBound_CL_Visc / (AllBound_CD_Visc + EPS); + AllBound_CMerit_Visc = AllBound_CT_Visc / (AllBound_CQ_Visc + EPS); + AllBound_MaxHF_Visc = pow(AllBound_MaxHF_Visc, 1.0/MaxNorm); + + +#ifdef HAVE_MPI + + /*--- Add AllBound information using all the nodes ---*/ + + MyAllBound_CD_Visc = AllBound_CD_Visc; AllBound_CD_Visc = 0.0; + MyAllBound_CL_Visc = AllBound_CL_Visc; AllBound_CL_Visc = 0.0; + MyAllBound_CSF_Visc = AllBound_CSF_Visc; AllBound_CSF_Visc = 0.0; + AllBound_CEff_Visc = 0.0; + MyAllBound_CMx_Visc = AllBound_CMx_Visc; AllBound_CMx_Visc = 0.0; + MyAllBound_CMy_Visc = AllBound_CMy_Visc; AllBound_CMy_Visc = 0.0; + MyAllBound_CMz_Visc = AllBound_CMz_Visc; AllBound_CMz_Visc = 0.0; + MyAllBound_CFx_Visc = AllBound_CFx_Visc; AllBound_CFx_Visc = 0.0; + MyAllBound_CFy_Visc = AllBound_CFy_Visc; AllBound_CFy_Visc = 0.0; + MyAllBound_CFz_Visc = AllBound_CFz_Visc; AllBound_CFz_Visc = 0.0; + MyAllBound_CoPx_Visc = AllBound_CoPx_Visc; AllBound_CoPx_Visc = 0.0; + MyAllBound_CoPy_Visc = AllBound_CoPy_Visc; AllBound_CoPy_Visc = 0.0; + MyAllBound_CoPz_Visc = AllBound_CoPz_Visc; AllBound_CoPz_Visc = 0.0; + MyAllBound_CT_Visc = AllBound_CT_Visc; AllBound_CT_Visc = 0.0; + MyAllBound_CQ_Visc = AllBound_CQ_Visc; AllBound_CQ_Visc = 0.0; + AllBound_CMerit_Visc = 0.0; + MyAllBound_HF_Visc = AllBound_HF_Visc; AllBound_HF_Visc = 0.0; + MyAllBound_MaxHF_Visc = pow(AllBound_MaxHF_Visc, MaxNorm); AllBound_MaxHF_Visc = 0.0; + + if (config->GetComm_Level() == COMM_FULL) { + SU2_MPI::Allreduce(&MyAllBound_CD_Visc, &AllBound_CD_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CL_Visc, &AllBound_CL_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CSF_Visc, &AllBound_CSF_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + AllBound_CEff_Visc = AllBound_CL_Visc / (AllBound_CD_Visc + EPS); + SU2_MPI::Allreduce(&MyAllBound_CMx_Visc, &AllBound_CMx_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CMy_Visc, &AllBound_CMy_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CMz_Visc, &AllBound_CMz_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CFx_Visc, &AllBound_CFx_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CFy_Visc, &AllBound_CFy_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CFz_Visc, &AllBound_CFz_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CoPx_Visc, &AllBound_CoPx_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CoPy_Visc, &AllBound_CoPy_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CoPz_Visc, &AllBound_CoPz_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CT_Visc, &AllBound_CT_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CQ_Visc, &AllBound_CQ_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + AllBound_CMerit_Visc = AllBound_CT_Visc / (AllBound_CQ_Visc + EPS); + SU2_MPI::Allreduce(&MyAllBound_HF_Visc, &AllBound_HF_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_MaxHF_Visc, &AllBound_MaxHF_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + AllBound_MaxHF_Visc = pow(AllBound_MaxHF_Visc, 1.0/MaxNorm); + } + + /*--- Add the forces on the surfaces using all the nodes ---*/ + + MySurface_CL_Visc = new su2double[config->GetnMarker_Monitoring()]; + MySurface_CD_Visc = new su2double[config->GetnMarker_Monitoring()]; + MySurface_CSF_Visc = new su2double[config->GetnMarker_Monitoring()]; + MySurface_CEff_Visc = new su2double[config->GetnMarker_Monitoring()]; + MySurface_CFx_Visc = new su2double[config->GetnMarker_Monitoring()]; + MySurface_CFy_Visc = new su2double[config->GetnMarker_Monitoring()]; + MySurface_CFz_Visc = new su2double[config->GetnMarker_Monitoring()]; + MySurface_CMx_Visc = new su2double[config->GetnMarker_Monitoring()]; + MySurface_CMy_Visc = new su2double[config->GetnMarker_Monitoring()]; + MySurface_CMz_Visc = new su2double[config->GetnMarker_Monitoring()]; + MySurface_HF_Visc = new su2double[config->GetnMarker_Monitoring()]; + MySurface_MaxHF_Visc = new su2double[config->GetnMarker_Monitoring()]; + + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { + + MySurface_CL_Visc[iMarker_Monitoring] = Surface_CL_Visc[iMarker_Monitoring]; + MySurface_CD_Visc[iMarker_Monitoring] = Surface_CD_Visc[iMarker_Monitoring]; + MySurface_CSF_Visc[iMarker_Monitoring] = Surface_CSF_Visc[iMarker_Monitoring]; + MySurface_CEff_Visc[iMarker_Monitoring] = Surface_CEff_Visc[iMarker_Monitoring]; + MySurface_CFx_Visc[iMarker_Monitoring] = Surface_CFx_Visc[iMarker_Monitoring]; + MySurface_CFy_Visc[iMarker_Monitoring] = Surface_CFy_Visc[iMarker_Monitoring]; + MySurface_CFz_Visc[iMarker_Monitoring] = Surface_CFz_Visc[iMarker_Monitoring]; + MySurface_CMx_Visc[iMarker_Monitoring] = Surface_CMx_Visc[iMarker_Monitoring]; + MySurface_CMy_Visc[iMarker_Monitoring] = Surface_CMy_Visc[iMarker_Monitoring]; + MySurface_CMz_Visc[iMarker_Monitoring] = Surface_CMz_Visc[iMarker_Monitoring]; + MySurface_HF_Visc[iMarker_Monitoring] = Surface_HF_Visc[iMarker_Monitoring]; + MySurface_MaxHF_Visc[iMarker_Monitoring] = Surface_MaxHF_Visc[iMarker_Monitoring]; + + Surface_CL_Visc[iMarker_Monitoring] = 0.0; + Surface_CD_Visc[iMarker_Monitoring] = 0.0; + Surface_CSF_Visc[iMarker_Monitoring] = 0.0; + Surface_CEff_Visc[iMarker_Monitoring] = 0.0; + Surface_CFx_Visc[iMarker_Monitoring] = 0.0; + Surface_CFy_Visc[iMarker_Monitoring] = 0.0; + Surface_CFz_Visc[iMarker_Monitoring] = 0.0; + Surface_CMx_Visc[iMarker_Monitoring] = 0.0; + Surface_CMy_Visc[iMarker_Monitoring] = 0.0; + Surface_CMz_Visc[iMarker_Monitoring] = 0.0; + Surface_HF_Visc[iMarker_Monitoring] = 0.0; + Surface_MaxHF_Visc[iMarker_Monitoring] = 0.0; + } + + if (config->GetComm_Level() == COMM_FULL) { + SU2_MPI::Allreduce(MySurface_CL_Visc, Surface_CL_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(MySurface_CD_Visc, Surface_CD_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(MySurface_CSF_Visc, Surface_CSF_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) + Surface_CEff_Visc[iMarker_Monitoring] = Surface_CL_Visc[iMarker_Monitoring] / (Surface_CD_Visc[iMarker_Monitoring] + EPS); + SU2_MPI::Allreduce(MySurface_CFx_Visc, Surface_CFx_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(MySurface_CFy_Visc, Surface_CFy_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(MySurface_CFz_Visc, Surface_CFz_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(MySurface_CMx_Visc, Surface_CMx_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(MySurface_CMy_Visc, Surface_CMy_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(MySurface_CMz_Visc, Surface_CMz_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(MySurface_HF_Visc, Surface_HF_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(MySurface_MaxHF_Visc, Surface_MaxHF_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + } + + delete [] MySurface_CL_Visc; delete [] MySurface_CD_Visc; delete [] MySurface_CSF_Visc; + delete [] MySurface_CEff_Visc; delete [] MySurface_CFx_Visc; delete [] MySurface_CFy_Visc; + delete [] MySurface_CFz_Visc; delete [] MySurface_CMx_Visc; delete [] MySurface_CMy_Visc; + delete [] MySurface_CMz_Visc; delete [] MySurface_HF_Visc; delete [] MySurface_MaxHF_Visc; + +#endif + + /*--- Update the total coefficients (note that all the nodes have the same value)---*/ + + Total_CD += AllBound_CD_Visc; + Total_CL += AllBound_CL_Visc; + Total_CSF += AllBound_CSF_Visc; + Total_CEff = Total_CL / (Total_CD + EPS); + Total_CMx += AllBound_CMx_Visc; + Total_CMy += AllBound_CMy_Visc; + Total_CMz += AllBound_CMz_Visc; + Total_CFx += AllBound_CFx_Visc; + Total_CFy += AllBound_CFy_Visc; + Total_CFz += AllBound_CFz_Visc; + Total_CoPx += AllBound_CoPx_Visc; + Total_CoPy += AllBound_CoPy_Visc; + Total_CoPz += AllBound_CoPz_Visc; + Total_CT += AllBound_CT_Visc; + Total_CQ += AllBound_CQ_Visc; + Total_CMerit = AllBound_CT_Visc / (AllBound_CQ_Visc + EPS); + Total_Heat = AllBound_HF_Visc; + Total_MaxHeat = AllBound_MaxHF_Visc; + + /*--- Update the total coefficients per surface (note that all the nodes have the same value)---*/ + + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { + Surface_CL[iMarker_Monitoring] += Surface_CL_Visc[iMarker_Monitoring]; + Surface_CD[iMarker_Monitoring] += Surface_CD_Visc[iMarker_Monitoring]; + Surface_CSF[iMarker_Monitoring] += Surface_CSF_Visc[iMarker_Monitoring]; + Surface_CEff[iMarker_Monitoring] = Surface_CL[iMarker_Monitoring] / (Surface_CD[iMarker_Monitoring] + EPS); + Surface_CFx[iMarker_Monitoring] += Surface_CFx_Visc[iMarker_Monitoring]; + Surface_CFy[iMarker_Monitoring] += Surface_CFy_Visc[iMarker_Monitoring]; + Surface_CFz[iMarker_Monitoring] += Surface_CFz_Visc[iMarker_Monitoring]; + Surface_CMx[iMarker_Monitoring] += Surface_CMx_Visc[iMarker_Monitoring]; + Surface_CMy[iMarker_Monitoring] += Surface_CMy_Visc[iMarker_Monitoring]; + Surface_CMz[iMarker_Monitoring] += Surface_CMz_Visc[iMarker_Monitoring]; + } + +} + +void CIncNSSolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { + + unsigned short iDim, iVar, jVar;// Wall_Function; + unsigned long iVertex, iPoint, total_index; + + su2double *GridVel, *Normal, Area, Wall_HeatFlux; + + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + bool energy = config->GetEnergy_Equation(); + + /*--- Identify the boundary by string name ---*/ + + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); + + /*--- Get the specified wall heat flux from config ---*/ + + Wall_HeatFlux = config->GetWall_HeatFlux(Marker_Tag)/config->GetHeat_Flux_Ref(); + +// /*--- Get wall function treatment from config. ---*/ +// +// Wall_Function = config->GetWallFunction_Treatment(Marker_Tag); +// if (Wall_Function != NO_WALL_FUNCTION) { +// SU2_MPI::Error("Wall function treament not implemented yet", CURRENT_FUNCTION); +// } + + /*--- Loop over all of the vertices on this boundary marker ---*/ + + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); + + /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ + + if (geometry->node[iPoint]->GetDomain()) { + + /*--- Compute dual-grid area and boundary normal ---*/ + + Normal = geometry->vertex[val_marker][iVertex]->GetNormal(); + + Area = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + Area += Normal[iDim]*Normal[iDim]; + Area = sqrt (Area); + + /*--- Initialize the convective & viscous residuals to zero ---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + Res_Conv[iVar] = 0.0; + Res_Visc[iVar] = 0.0; + if (implicit) { + for (jVar = 0; jVar < nVar; jVar++) + Jacobian_i[iVar][jVar] = 0.0; + } + } + + /*--- Store the corrected velocity at the wall which will + be zero (v = 0), unless there are moving walls (v = u_wall)---*/ + + if (dynamic_grid) { + GridVel = geometry->node[iPoint]->GetGridVel(); + for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = GridVel[iDim]; + } else { + for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = 0.0; + } + + /*--- Impose the value of the velocity as a strong boundary + condition (Dirichlet). Fix the velocity and remove any + contribution to the residual at this node. ---*/ + + nodes->SetVelocity_Old(iPoint,Vector); + + for (iDim = 0; iDim < nDim; iDim++) + LinSysRes.SetBlock_Zero(iPoint, iDim+1); + nodes->SetVel_ResTruncError_Zero(iPoint); + + if (energy) { + + /*--- Apply a weak boundary condition for the energy equation. + Compute the residual due to the prescribed heat flux. ---*/ + + Res_Visc[nDim+1] = Wall_HeatFlux*Area; + + /*--- Viscous contribution to the residual at the wall ---*/ + + LinSysRes.SubtractBlock(iPoint, Res_Visc); + + } + + /*--- Enforce the no-slip boundary condition in a strong way by + modifying the velocity-rows of the Jacobian (1 on the diagonal). ---*/ + + if (implicit) { + for (iVar = 1; iVar <= nDim; iVar++) { + total_index = iPoint*nVar+iVar; + Jacobian.DeleteValsRowi(total_index); + } + } + + } + } +} + +void CIncNSSolver::BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { + + unsigned short iDim, iVar, jVar, Wall_Function; + unsigned long iVertex, iPoint, Point_Normal, total_index; + + su2double *GridVel; + su2double *Normal, *Coord_i, *Coord_j, Area, dist_ij; + su2double Twall, dTdn; + su2double thermal_conductivity; + + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + bool energy = config->GetEnergy_Equation(); + + /*--- Identify the boundary by string name ---*/ + + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); + + /*--- Retrieve the specified wall temperature ---*/ + + Twall = config->GetIsothermal_Temperature(Marker_Tag)/config->GetTemperature_Ref(); + + /*--- Get wall function treatment from config. ---*/ + + Wall_Function = config->GetWallFunction_Treatment(Marker_Tag); + if (Wall_Function != NO_WALL_FUNCTION) { + SU2_MPI::Error("Wall function treatment not implemented yet.", CURRENT_FUNCTION); + } + + /*--- Loop over all of the vertices on this boundary marker ---*/ + + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { + + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); + + /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ + + if (geometry->node[iPoint]->GetDomain()) { + + /*--- Initialize the convective & viscous residuals to zero ---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + Res_Conv[iVar] = 0.0; + Res_Visc[iVar] = 0.0; + if (implicit) { + for (jVar = 0; jVar < nVar; jVar++) + Jacobian_i[iVar][jVar] = 0.0; + } + } + + /*--- Store the corrected velocity at the wall which will + be zero (v = 0), unless there are moving walls (v = u_wall)---*/ + + if (dynamic_grid) { + GridVel = geometry->node[iPoint]->GetGridVel(); + for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = GridVel[iDim]; + } else { + for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = 0.0; + } + + /*--- Impose the value of the velocity as a strong boundary + condition (Dirichlet). Fix the velocity and remove any + contribution to the residual at this node. ---*/ + + nodes->SetVelocity_Old(iPoint,Vector); + + for (iDim = 0; iDim < nDim; iDim++) + LinSysRes.SetBlock_Zero(iPoint, iDim+1); + nodes->SetVel_ResTruncError_Zero(iPoint); + + if (energy) { + + /*--- Compute dual grid area and boundary normal ---*/ + + Normal = geometry->vertex[val_marker][iVertex]->GetNormal(); + + Area = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + Area += Normal[iDim]*Normal[iDim]; + Area = sqrt (Area); + + /*--- Compute closest normal neighbor ---*/ + + Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); + + /*--- Get coordinates of i & nearest normal and compute distance ---*/ + + Coord_i = geometry->node[iPoint]->GetCoord(); + Coord_j = geometry->node[Point_Normal]->GetCoord(); + dist_ij = 0; + for (iDim = 0; iDim < nDim; iDim++) + dist_ij += (Coord_j[iDim]-Coord_i[iDim])*(Coord_j[iDim]-Coord_i[iDim]); + dist_ij = sqrt(dist_ij); + + /*--- Compute the normal gradient in temperature using Twall ---*/ + + dTdn = -(nodes->GetTemperature(Point_Normal) - Twall)/dist_ij; + + /*--- Get thermal conductivity ---*/ + + thermal_conductivity = nodes->GetThermalConductivity(iPoint); + + /*--- Apply a weak boundary condition for the energy equation. + Compute the residual due to the prescribed heat flux. ---*/ + + Res_Visc[nDim+1] = thermal_conductivity*dTdn*Area; + + /*--- Jacobian contribution for temperature equation. ---*/ + + if (implicit) { + su2double Edge_Vector[3]; + su2double dist_ij_2 = 0, proj_vector_ij = 0; + for (iDim = 0; iDim < nDim; iDim++) { + Edge_Vector[iDim] = Coord_j[iDim]-Coord_i[iDim]; + dist_ij_2 += Edge_Vector[iDim]*Edge_Vector[iDim]; + proj_vector_ij += Edge_Vector[iDim]*Normal[iDim]; + } + if (dist_ij_2 == 0.0) proj_vector_ij = 0.0; + else proj_vector_ij = proj_vector_ij/dist_ij_2; + + Jacobian_i[nDim+1][nDim+1] = -thermal_conductivity*proj_vector_ij; + + Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); + } + + /*--- Viscous contribution to the residual at the wall ---*/ + + LinSysRes.SubtractBlock(iPoint, Res_Visc); + + } + + /*--- Enforce the no-slip boundary condition in a strong way by + modifying the velocity-rows of the Jacobian (1 on the diagonal). ---*/ + + if (implicit) { + for (iVar = 1; iVar <= nDim; iVar++) { + total_index = iPoint*nVar+iVar; + Jacobian.DeleteValsRowi(total_index); + } + } + + } + } +} + + +void CIncNSSolver::BC_ConjugateHeat_Interface(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, + CConfig *config, unsigned short val_marker) { + + unsigned short iVar, jVar, iDim, Wall_Function; + unsigned long iVertex, iPoint, total_index, Point_Normal; + + su2double *Coord_i, *Coord_j, dist_ij; + su2double *GridVel, There, Tconjugate, Twall= 0.0, Temperature_Ref, thermal_conductivity, HF_FactorHere, HF_FactorConjugate; + + Temperature_Ref = config->GetTemperature_Ref(); + + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + bool energy = config->GetEnergy_Equation(); + + /*--- Identify the boundary ---*/ + + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); + + /*--- Retrieve the specified wall function treatment.---*/ + + Wall_Function = config->GetWallFunction_Treatment(Marker_Tag); + if(Wall_Function != NO_WALL_FUNCTION) { + SU2_MPI::Error("Wall function treament not implemented yet", CURRENT_FUNCTION); + } + + /*--- Loop over boundary points ---*/ + + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { + + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); + + if (geometry->node[iPoint]->GetDomain()) { + + /*--- Initialize the convective & viscous residuals to zero ---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + Res_Conv[iVar] = 0.0; + Res_Visc[iVar] = 0.0; + if (implicit) { + for (jVar = 0; jVar < nVar; jVar++) + Jacobian_i[iVar][jVar] = 0.0; + } + } + + /*--- Store the corrected velocity at the wall which will + be zero (v = 0), unless there are moving walls (v = u_wall)---*/ + + if (dynamic_grid) { + GridVel = geometry->node[iPoint]->GetGridVel(); + for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = GridVel[iDim]; + } else { + for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = 0.0; + } + + /*--- Impose the value of the velocity as a strong boundary + condition (Dirichlet). Fix the velocity and remove any + contribution to the residual at this node. ---*/ + + nodes->SetVelocity_Old(iPoint,Vector); + + for (iDim = 0; iDim < nDim; iDim++) + LinSysRes.SetBlock_Zero(iPoint, iDim+1); + nodes->SetVel_ResTruncError_Zero(iPoint); + + if (energy) { + + Tconjugate = GetConjugateHeatVariable(val_marker, iVertex, 0)/Temperature_Ref; + + if ((config->GetKind_CHT_Coupling() == AVERAGED_TEMPERATURE_NEUMANN_HEATFLUX) || + (config->GetKind_CHT_Coupling() == AVERAGED_TEMPERATURE_ROBIN_HEATFLUX)) { + + /*--- Compute closest normal neighbor ---*/ + + Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); + + /*--- Get coordinates of i & nearest normal and compute distance ---*/ + + Coord_i = geometry->node[iPoint]->GetCoord(); + Coord_j = geometry->node[Point_Normal]->GetCoord(); + dist_ij = 0; + for (iDim = 0; iDim < nDim; iDim++) + dist_ij += (Coord_j[iDim]-Coord_i[iDim])*(Coord_j[iDim]-Coord_i[iDim]); + dist_ij = sqrt(dist_ij); + + /*--- Compute wall temperature from both temperatures ---*/ + + thermal_conductivity = nodes->GetThermalConductivity(iPoint); + There = nodes->GetTemperature(Point_Normal); + HF_FactorHere = thermal_conductivity*config->GetViscosity_Ref()/dist_ij; + HF_FactorConjugate = GetConjugateHeatVariable(val_marker, iVertex, 2); + + Twall = (There*HF_FactorHere + Tconjugate*HF_FactorConjugate)/(HF_FactorHere + HF_FactorConjugate); + } + else if ((config->GetKind_CHT_Coupling() == DIRECT_TEMPERATURE_NEUMANN_HEATFLUX) || + (config->GetKind_CHT_Coupling() == DIRECT_TEMPERATURE_ROBIN_HEATFLUX)) { + + /*--- (Directly) Set wall temperature to conjugate temperature. ---*/ + + Twall = Tconjugate; + } + else { + SU2_MPI::Error("Unknown CHT coupling method.", CURRENT_FUNCTION); + } + + /*--- Strong imposition of the temperature on the fluid zone. ---*/ + + LinSysRes.SetBlock_Zero(iPoint, nDim+1); + nodes->SetSolution_Old(iPoint, nDim+1, Twall); + nodes->SetEnergy_ResTruncError_Zero(iPoint); + } + + /*--- Enforce the no-slip boundary condition in a strong way by + modifying the velocity-rows of the Jacobian (1 on the diagonal). ---*/ + + if (implicit) { + for (iVar = 1; iVar <= nDim; iVar++) { + total_index = iPoint*nVar+iVar; + Jacobian.DeleteValsRowi(total_index); + } + if(energy) { + total_index = iPoint*nVar+nDim+1; + Jacobian.DeleteValsRowi(total_index); + } + } + } + } +} diff --git a/SU2_CFD/src/solvers/CMeshSolver.cpp b/SU2_CFD/src/solvers/CMeshSolver.cpp index e6a77637756c..a7111e61d8cc 100644 --- a/SU2_CFD/src/solvers/CMeshSolver.cpp +++ b/SU2_CFD/src/solvers/CMeshSolver.cpp @@ -6,7 +6,7 @@ * * SU2 Project Website: https://su2code.github.io * - * The SU2 Project is maintained by the SU2 Foundation + * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) @@ -30,7 +30,7 @@ #include "../../../Common/include/omp_structure.hpp" #include "../../include/solvers/CMeshSolver.hpp" #include "../../include/variables/CMeshBoundVariable.hpp" -#include "../../include/variables/CMeshElement.hpp" + CMeshSolver::CMeshSolver(CGeometry *geometry, CConfig *config) : CFEASolver(true) { diff --git a/SU2_CFD/src/solvers/CNSSolver.cpp b/SU2_CFD/src/solvers/CNSSolver.cpp new file mode 100644 index 000000000000..02ca9bf5a9be --- /dev/null +++ b/SU2_CFD/src/solvers/CNSSolver.cpp @@ -0,0 +1,3152 @@ +/*! + * \file CNSSolver.cpp + * \brief Main subrotuines for solving Finite-Volume Navier-Stokes flow problems. + * \author F. Palacios, T. Economon + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + + +#include "../../include/solvers/CNSSolver.hpp" +#include "../../include/variables/CNSVariable.hpp" +#include "../../../Common/include/toolboxes/printing_toolbox.hpp" + +CNSSolver::CNSSolver(void) : CEulerSolver() { + + /*--- Basic array initialization ---*/ + + CD_Visc = NULL; CL_Visc = NULL; CSF_Visc = NULL; CEff_Visc = NULL; + CFx_Visc = NULL; CFy_Visc = NULL; CFz_Visc = NULL; + CMx_Visc = NULL; CMy_Visc = NULL; CMz_Visc = NULL; + CoPx_Visc = NULL; CoPy_Visc = NULL; CoPz_Visc = NULL; + + ForceViscous = NULL; MomentViscous = NULL; CSkinFriction = NULL; + + Buffet_Sensor = NULL; Buffet_Metric = NULL; + + /*--- Surface based array initialization ---*/ + + Surface_CL_Visc = NULL; Surface_CD_Visc = NULL; Surface_CSF_Visc = NULL; Surface_CEff_Visc = NULL; + Surface_CFx_Visc = NULL; Surface_CFy_Visc = NULL; Surface_CFz_Visc = NULL; + Surface_CMx_Visc = NULL; Surface_CMy_Visc = NULL; Surface_CMz_Visc = NULL; + Surface_HF_Visc = NULL; Surface_MaxHF_Visc = NULL; Surface_Buffet_Metric = NULL; + + /*--- Rotorcraft simulation array initialization ---*/ + + CMerit_Visc = NULL; CT_Visc = NULL; CQ_Visc = NULL; + HF_Visc = NULL; MaxHF_Visc = NULL; + + /*--- Inlet Variables ---*/ + Inlet_Ttotal = NULL; + Inlet_Ptotal = NULL; + Inlet_FlowDir = NULL; + + SlidingState = NULL; + SlidingStateNodes = NULL; + + DonorPrimVar = NULL; DonorGlobalIndex = NULL; + + HeatConjugateVar = NULL; + +} + +CNSSolver::CNSSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh) : CEulerSolver() { + + unsigned long iPoint, counter_local = 0, counter_global = 0, iVertex; + unsigned short iVar, iDim, iMarker, nLineLets; + su2double Density, Velocity2, Pressure, Temperature, StaticEnergy; + ifstream restart_file; + unsigned short nZone = geometry->GetnZone(); + bool restart = (config->GetRestart() || config->GetRestart_Flow()); + int Unst_RestartIter = 0; + bool dual_time = ((config->GetTime_Marching() == DT_STEPPING_1ST) || + (config->GetTime_Marching() == DT_STEPPING_2ND)); + bool time_stepping = config->GetTime_Marching() == TIME_STEPPING; + + /* A grid is defined as dynamic if there's rigid grid movement or grid deformation AND the problem is time domain */ + dynamic_grid = config->GetDynamic_Grid(); + + bool roe_turkel = (config->GetKind_Upwind_Flow() == TURKEL); + bool low_mach_prec = config->Low_Mach_Preconditioning(); + + bool adjoint = (config->GetContinuous_Adjoint()) || (config->GetDiscrete_Adjoint()); + string filename_ = "flow"; + + unsigned short direct_diff = config->GetDirectDiff(); + bool rans = (config->GetKind_Turb_Model() != NONE); + + /*--- Store the multigrid level. ---*/ + MGLevel = iMesh; + + /*--- Check for a restart file to evaluate if there is a change in the angle of attack + before computing all the non-dimesional quantities. ---*/ + + if (!(!restart || (iMesh != MESH_0) || nZone > 1) && + (config->GetFixed_CL_Mode() || config->GetFixed_CM_Mode())) { + + /*--- Modify file name for a dual-time unsteady restart ---*/ + + if (dual_time) { + if (adjoint) Unst_RestartIter = SU2_TYPE::Int(config->GetUnst_AdjointIter())-1; + else if (config->GetTime_Marching() == DT_STEPPING_1ST) + Unst_RestartIter = SU2_TYPE::Int(config->GetRestart_Iter())-1; + else Unst_RestartIter = SU2_TYPE::Int(config->GetRestart_Iter())-2; + } + + /*--- Modify file name for a time stepping unsteady restart ---*/ + + if (time_stepping) { + if (adjoint) Unst_RestartIter = SU2_TYPE::Int(config->GetUnst_AdjointIter())-1; + else Unst_RestartIter = SU2_TYPE::Int(config->GetRestart_Iter())-1; + } + + filename_ = config->GetFilename(filename_, ".meta", Unst_RestartIter); + + /*--- Read and store the restart metadata. ---*/ + + Read_SU2_Restart_Metadata(geometry, config, adjoint, filename_); + + } + + /*--- Array initialization ---*/ + + CD_Visc = NULL; CL_Visc = NULL; CSF_Visc = NULL; CEff_Visc = NULL; + CFx_Visc = NULL; CFy_Visc = NULL; CFz_Visc = NULL; + CMx_Visc = NULL; CMy_Visc = NULL; CMz_Visc = NULL; + CoPx_Visc = NULL; CoPy_Visc = NULL; CoPz_Visc = NULL; + + Buffet_Sensor = NULL; Buffet_Metric = NULL; + + Surface_CL_Visc = NULL; Surface_CD_Visc = NULL; Surface_CSF_Visc = NULL; Surface_CEff_Visc = NULL; + Surface_CFx_Visc = NULL; Surface_CFy_Visc = NULL; Surface_CFz_Visc = NULL; + Surface_CMx_Visc = NULL; Surface_CMy_Visc = NULL; Surface_CMz_Visc = NULL; + Surface_HF_Visc = NULL; Surface_MaxHF_Visc = NULL; + + Surface_Buffet_Metric = NULL; + + CMerit_Visc = NULL; CT_Visc = NULL; CQ_Visc = NULL; + MaxHF_Visc = NULL; ForceViscous = NULL; MomentViscous = NULL; + CSkinFriction = NULL; HF_Visc = NULL; + HeatConjugateVar = NULL; + + /*--- Initialize quantities for the average process for internal flow ---*/ + + AverageVelocity = NULL; + AverageTurboVelocity = NULL; + OldAverageTurboVelocity = NULL; + ExtAverageTurboVelocity = NULL; + AverageFlux = NULL; + SpanTotalFlux = NULL; + AveragePressure = NULL; + OldAveragePressure = NULL; + RadialEquilibriumPressure = NULL; + ExtAveragePressure = NULL; + AverageDensity = NULL; + OldAverageDensity = NULL; + ExtAverageDensity = NULL; + AverageNu = NULL; + AverageKine = NULL; + AverageOmega = NULL; + ExtAverageNu = NULL; + ExtAverageKine = NULL; + ExtAverageOmega = NULL; + + + /*--- Initialize primitive quantities for turboperformace ---*/ + + DensityIn = NULL; + PressureIn = NULL; + TurboVelocityIn = NULL; + DensityOut = NULL; + PressureOut = NULL; + TurboVelocityOut = NULL; + + + /*--- Initialize quantities for Giles BC ---*/ + + CkInflow = NULL; + CkOutflow1 = NULL; + CkOutflow2 = NULL; + + + + /*--- Set the gamma value ---*/ + + Gamma = config->GetGamma(); + Gamma_Minus_One = Gamma - 1.0; + + /*--- Define geometry constants in the solver structure + Compressible flow, primitive variables (T, vx, vy, vz, P, rho, h, c, lamMu, EddyMu, ThCond, Cp). + ---*/ + + nDim = geometry->GetnDim(); + + nVar = nDim+2; + nPrimVar = nDim+9; nPrimVarGrad = nDim+4; + nSecondaryVar = 8; nSecondaryVarGrad = 2; + + + /*--- Initialize nVarGrad for deallocation ---*/ + + nVarGrad = nPrimVarGrad; + + nMarker = config->GetnMarker_All(); + nPoint = geometry->GetnPoint(); + nPointDomain = geometry->GetnPointDomain(); + + /*--- Store the number of vertices on each marker for deallocation later ---*/ + + nVertex = new unsigned long[nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) + nVertex[iMarker] = geometry->nVertex[iMarker]; + + /*--- Perform the non-dimensionalization for the flow equations using the + specified reference values. ---*/ + + SetNondimensionalization(config, iMesh); + + /*--- Check if we are executing a verification case. If so, the + VerificationSolution object will be instantiated for a particular + option from the available library of verification solutions. Note + that this is done after SetNondim(), as problem-specific initial + parameters are needed by the solution constructors. ---*/ + + SetVerificationSolution(nDim, nVar, config); + + /*--- Define some auxiliar vector related with the residual ---*/ + + Residual = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = 0.0; + Residual_RMS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_RMS[iVar] = 0.0; + Residual_Max = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_Max[iVar] = 0.0; + Residual_i = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_i[iVar] = 0.0; + Residual_j = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_j[iVar] = 0.0; + Res_Conv = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Conv[iVar] = 0.0; + Res_Visc = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Visc[iVar] = 0.0; + Res_Sour = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Res_Sour[iVar] = 0.0; + + /*--- Define some structures for locating max residuals ---*/ + + Point_Max = new unsigned long[nVar]; for (iVar = 0; iVar < nVar; iVar++) Point_Max[iVar] = 0; + Point_Max_Coord = new su2double*[nVar]; + for (iVar = 0; iVar < nVar; iVar++) { + Point_Max_Coord[iVar] = new su2double[nDim]; + for (iDim = 0; iDim < nDim; iDim++) Point_Max_Coord[iVar][iDim] = 0.0; + } + + /*--- Define some auxiliary vectors related to the solution ---*/ + + Solution = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution[iVar] = 0.0; + Solution_i = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution_i[iVar] = 0.0; + Solution_j = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Solution_j[iVar] = 0.0; + + /*--- Define some auxiliary vectors related to the geometry ---*/ + + Vector = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = 0.0; + Vector_i = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector_i[iDim] = 0.0; + Vector_j = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Vector_j[iDim] = 0.0; + + /*--- Define some auxiliary vectors related to the primitive solution ---*/ + + Primitive = new su2double[nPrimVar]; for (iVar = 0; iVar < nPrimVar; iVar++) Primitive[iVar] = 0.0; + Primitive_i = new su2double[nPrimVar]; for (iVar = 0; iVar < nPrimVar; iVar++) Primitive_i[iVar] = 0.0; + Primitive_j = new su2double[nPrimVar]; for (iVar = 0; iVar < nPrimVar; iVar++) Primitive_j[iVar] = 0.0; + + /*--- Define some auxiliary vectors related to the Secondary solution ---*/ + + Secondary = new su2double[nSecondaryVar]; for (iVar = 0; iVar < nSecondaryVar; iVar++) Secondary[iVar] = 0.0; + Secondary_i = new su2double[nSecondaryVar]; for (iVar = 0; iVar < nSecondaryVar; iVar++) Secondary_i[iVar] = 0.0; + Secondary_j = new su2double[nSecondaryVar]; for (iVar = 0; iVar < nSecondaryVar; iVar++) Secondary_j[iVar] = 0.0; + + /*--- Define some auxiliar vector related with the undivided lapalacian computation ---*/ + + if (config->GetKind_ConvNumScheme_Flow() == SPACE_CENTERED) { + iPoint_UndLapl = new su2double [nPoint]; + jPoint_UndLapl = new su2double [nPoint]; + } + + /*--- Define some auxiliary vectors related to low-speed preconditioning ---*/ + + if (roe_turkel || low_mach_prec) { + LowMach_Precontioner = new su2double* [nVar]; + for (iVar = 0; iVar < nVar; iVar ++) + LowMach_Precontioner[iVar] = new su2double[nVar]; + } + + /*--- Initialize the solution and right hand side vectors for storing + the residuals and updating the solution (always needed even for + explicit schemes). ---*/ + + LinSysSol.Initialize(nPoint, nPointDomain, nVar, 0.0); + LinSysRes.Initialize(nPoint, nPointDomain, nVar, 0.0); + + /*--- Jacobians and vector structures for implicit computations ---*/ + + if (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT) { + + Jacobian_i = new su2double* [nVar]; + Jacobian_j = new su2double* [nVar]; + for (iVar = 0; iVar < nVar; iVar++) { + Jacobian_i[iVar] = new su2double [nVar]; + Jacobian_j[iVar] = new su2double [nVar]; + } + + if (rank == MASTER_NODE) cout << "Initialize Jacobian structure (Navier-Stokes). MG level: " << iMesh <<"." << endl; + Jacobian.Initialize(nPoint, nPointDomain, nVar, nVar, true, geometry, config); + + if (config->GetKind_Linear_Solver_Prec() == LINELET) { + nLineLets = Jacobian.BuildLineletPreconditioner(geometry, config); + if (rank == MASTER_NODE) cout << "Compute linelet structure. " << nLineLets << " elements in each line (average)." << endl; + } + + } + + else { + if (rank == MASTER_NODE) + cout << "Explicit scheme. No Jacobian structure (Navier-Stokes). MG level: " << iMesh <<"." << endl; + } + + /*--- Define some auxiliary vectors for computing flow variable + gradients by least squares, S matrix := inv(R)*traspose(inv(R)), + c vector := transpose(WA)*(Wb) ---*/ + + if (config->GetLeastSquaresRequired()) { + Smatrix = new su2double* [nDim]; + for (iDim = 0; iDim < nDim; iDim++) + Smatrix[iDim] = new su2double [nDim]; + + Cvector = new su2double* [nPrimVarGrad]; + for (iVar = 0; iVar < nPrimVarGrad; iVar++) + Cvector[iVar] = new su2double [nDim]; + } + + /*--- Store the value of the characteristic primitive variables at the boundaries ---*/ + + CharacPrimVar = new su2double** [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + CharacPrimVar[iMarker] = new su2double* [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + CharacPrimVar[iMarker][iVertex] = new su2double [nPrimVar]; + for (iVar = 0; iVar < nPrimVar; iVar++) { + CharacPrimVar[iMarker][iVertex][iVar] = 0.0; + } + } + } + + /*--- Store the value of the primitive variables + 2 turb variables at the boundaries, + used for IO with a donor cell ---*/ + + DonorPrimVar = new su2double** [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + DonorPrimVar[iMarker] = new su2double* [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + if (rans) { + DonorPrimVar[iMarker][iVertex] = new su2double [nPrimVar+2]; + for (iVar = 0; iVar < nPrimVar + 2 ; iVar++) { + DonorPrimVar[iMarker][iVertex][iVar] = 0.0; + } + } + else { + DonorPrimVar[iMarker][iVertex] = new su2double [nPrimVar]; + for (iVar = 0; iVar < nPrimVar ; iVar++) { + DonorPrimVar[iMarker][iVertex][iVar] = 0.0; + } + } + } + } + + /*--- Store the value of the characteristic primitive variables index at the boundaries ---*/ + + DonorGlobalIndex = new unsigned long* [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + DonorGlobalIndex[iMarker] = new unsigned long [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + DonorGlobalIndex[iMarker][iVertex] = 0; + } + } + + /*--- Store the values of the temperature and the heat flux density at the boundaries, + used for coupling with a solid donor cell ---*/ + unsigned short nHeatConjugateVar = 4; + + HeatConjugateVar = new su2double** [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + HeatConjugateVar[iMarker] = new su2double* [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + + HeatConjugateVar[iMarker][iVertex] = new su2double [nHeatConjugateVar]; + for (iVar = 1; iVar < nHeatConjugateVar ; iVar++) { + HeatConjugateVar[iMarker][iVertex][iVar] = 0.0; + } + HeatConjugateVar[iMarker][iVertex][0] = config->GetTemperature_FreeStreamND(); + } + } + + /*--- Store the value of the Delta P at the Actuator Disk ---*/ + + ActDisk_DeltaP = new su2double* [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + ActDisk_DeltaP[iMarker] = new su2double [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + ActDisk_DeltaP[iMarker][iVertex] = 0; + } + } + + /*--- Store the value of the Delta T at the Actuator Disk ---*/ + + ActDisk_DeltaT = new su2double* [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + ActDisk_DeltaT[iMarker] = new su2double [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + ActDisk_DeltaT[iMarker][iVertex] = 0; + } + } + + /*--- Store the value of the Total Pressure at the inlet BC ---*/ + + Inlet_Ttotal = new su2double* [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + Inlet_Ttotal[iMarker] = new su2double [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + Inlet_Ttotal[iMarker][iVertex] = 0; + } + } + + /*--- Store the value of the Total Temperature at the inlet BC ---*/ + + Inlet_Ptotal = new su2double* [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + Inlet_Ptotal[iMarker] = new su2double [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + Inlet_Ptotal[iMarker][iVertex] = 0; + } + } + + /*--- Store the value of the Flow direction at the inlet BC ---*/ + + Inlet_FlowDir = new su2double** [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + Inlet_FlowDir[iMarker] = new su2double* [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + Inlet_FlowDir[iMarker][iVertex] = new su2double [nDim]; + for (iDim = 0; iDim < nDim; iDim++) { + Inlet_FlowDir[iMarker][iVertex][iDim] = 0; + } + } + } + + /*--- Inviscid force definition and coefficient in all the markers ---*/ + + CPressure = new su2double* [nMarker]; + CPressureTarget = new su2double* [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + CPressure[iMarker] = new su2double [geometry->nVertex[iMarker]]; + CPressureTarget[iMarker] = new su2double [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + CPressure[iMarker][iVertex] = 0.0; + CPressureTarget[iMarker][iVertex] = 0.0; + } + } + + /*--- Heat flux in all the markers ---*/ + + HeatFlux = new su2double* [nMarker]; + HeatFluxTarget = new su2double* [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + HeatFlux[iMarker] = new su2double [geometry->nVertex[iMarker]]; + HeatFluxTarget[iMarker] = new su2double [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + HeatFlux[iMarker][iVertex] = 0.0; + HeatFluxTarget[iMarker][iVertex] = 0.0; + } + } + + /*--- Y plus in all the markers ---*/ + + YPlus = new su2double* [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + YPlus[iMarker] = new su2double [geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + YPlus[iMarker][iVertex] = 0.0; + } + } + + /*--- Skin friction in all the markers ---*/ + + CSkinFriction = new su2double** [nMarker]; + for (iMarker = 0; iMarker < nMarker; iMarker++) { + CSkinFriction[iMarker] = new su2double*[nDim]; + for (iDim = 0; iDim < nDim; iDim++) { + CSkinFriction[iMarker][iDim] = new su2double[geometry->nVertex[iMarker]]; + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + CSkinFriction[iMarker][iDim][iVertex] = 0.0; + } + } + } + + /*--- Buffet sensor in all the markers ---*/ + + if(config->GetBuffet_Monitoring() || config->GetKind_ObjFunc() == BUFFET_SENSOR){ + + Buffet_Sensor = new su2double*[nMarker]; + for(iMarker = 0; iMarker < nMarker; iMarker++) { + Buffet_Sensor[iMarker] = new su2double[geometry->nVertex[iMarker]]; + } + + } + + /*--- Non dimensional coefficients ---*/ + + ForceInviscid = new su2double[3]; + MomentInviscid = new su2double[3]; + CD_Inv = new su2double[nMarker]; + CL_Inv = new su2double[nMarker]; + CSF_Inv = new su2double[nMarker]; + CEff_Inv = new su2double[nMarker]; + CFx_Inv = new su2double[nMarker]; + CFy_Inv = new su2double[nMarker]; + CFz_Inv = new su2double[nMarker]; + CMx_Inv = new su2double[nMarker]; + CMy_Inv = new su2double[nMarker]; + CMz_Inv = new su2double[nMarker]; + CoPx_Inv = new su2double[nMarker]; + CoPy_Inv = new su2double[nMarker]; + CoPz_Inv = new su2double[nMarker]; + + ForceMomentum = new su2double[3]; + MomentMomentum = new su2double[3]; + CD_Mnt = new su2double[nMarker]; + CL_Mnt = new su2double[nMarker]; + CSF_Mnt = new su2double[nMarker]; + CEff_Mnt = new su2double[nMarker]; + CFx_Mnt = new su2double[nMarker]; + CFy_Mnt = new su2double[nMarker]; + CFz_Mnt = new su2double[nMarker]; + CMx_Mnt = new su2double[nMarker]; + CMy_Mnt = new su2double[nMarker]; + CMz_Mnt = new su2double[nMarker]; + CoPx_Mnt = new su2double[nMarker]; + CoPy_Mnt = new su2double[nMarker]; + CoPz_Mnt = new su2double[nMarker]; + + ForceViscous = new su2double[3]; + MomentViscous = new su2double[3]; + CD_Visc = new su2double[nMarker]; + CL_Visc = new su2double[nMarker]; + CSF_Visc = new su2double[nMarker]; + CEff_Visc = new su2double[nMarker]; + CFx_Visc = new su2double[nMarker]; + CFy_Visc = new su2double[nMarker]; + CFz_Visc = new su2double[nMarker]; + CMx_Visc = new su2double[nMarker]; + CMy_Visc = new su2double[nMarker]; + CMz_Visc = new su2double[nMarker]; + CoPx_Visc = new su2double[nMarker]; + CoPy_Visc = new su2double[nMarker]; + CoPz_Visc = new su2double[nMarker]; + + Surface_CL_Inv = new su2double[config->GetnMarker_Monitoring()]; + Surface_CD_Inv = new su2double[config->GetnMarker_Monitoring()]; + Surface_CSF_Inv = new su2double[config->GetnMarker_Monitoring()]; + Surface_CEff_Inv = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFx_Inv = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFy_Inv = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFz_Inv = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMx_Inv = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMy_Inv = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMz_Inv = new su2double[config->GetnMarker_Monitoring()]; + + Surface_CL_Mnt = new su2double[config->GetnMarker_Monitoring()]; + Surface_CD_Mnt = new su2double[config->GetnMarker_Monitoring()]; + Surface_CSF_Mnt = new su2double[config->GetnMarker_Monitoring()]; + Surface_CEff_Mnt = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFx_Mnt = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFy_Mnt = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFz_Mnt = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMx_Mnt = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMy_Mnt = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMz_Mnt = new su2double[config->GetnMarker_Monitoring()]; + + Surface_CL = new su2double[config->GetnMarker_Monitoring()]; + Surface_CD = new su2double[config->GetnMarker_Monitoring()]; + Surface_CSF = new su2double[config->GetnMarker_Monitoring()]; + Surface_CEff = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFx = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFy = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFz = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMx = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMy = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMz = new su2double[config->GetnMarker_Monitoring()]; + + Surface_CL_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CD_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CSF_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CEff_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFx_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFy_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CFz_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMx_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMy_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_CMz_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_HF_Visc = new su2double[config->GetnMarker_Monitoring()]; + Surface_MaxHF_Visc = new su2double[config->GetnMarker_Monitoring()]; + + if(config->GetBuffet_Monitoring() || config->GetKind_ObjFunc() == BUFFET_SENSOR){ + + Buffet_Metric = new su2double[nMarker]; + Surface_Buffet_Metric = new su2double[config->GetnMarker_Monitoring()]; + + } + + + /*--- Rotational coefficients ---*/ + + CMerit_Inv = new su2double[nMarker]; + CT_Inv = new su2double[nMarker]; + CQ_Inv = new su2double[nMarker]; + + CMerit_Mnt = new su2double[nMarker]; + CT_Mnt = new su2double[nMarker]; + CQ_Mnt = new su2double[nMarker]; + + CMerit_Visc = new su2double[nMarker]; + CT_Visc = new su2double[nMarker]; + CQ_Visc = new su2double[nMarker]; + + /*--- Heat based coefficients ---*/ + + HF_Visc = new su2double[nMarker]; + MaxHF_Visc = new su2double[nMarker]; + + /*--- Supersonic coefficients ---*/ + + CEquivArea_Inv = new su2double[nMarker]; + CNearFieldOF_Inv = new su2double[nMarker]; + + /*--- Engine simulation ---*/ + + Inflow_MassFlow = new su2double[nMarker]; + Inflow_Pressure = new su2double[nMarker]; + Inflow_Mach = new su2double[nMarker]; + Inflow_Area = new su2double[nMarker]; + + Exhaust_MassFlow = new su2double[nMarker]; + Exhaust_Pressure = new su2double[nMarker]; + Exhaust_Temperature = new su2double[nMarker]; + Exhaust_Area = new su2double[nMarker]; + + /*--- Init total coefficients ---*/ + + Total_CD = 0.0; Total_CL = 0.0; Total_CSF = 0.0; + Total_CMx = 0.0; Total_CMy = 0.0; Total_CMz = 0.0; + Total_CoPx = 0.0; Total_CoPy = 0.0; Total_CoPz = 0.0; + Total_CEff = 0.0; Total_CEquivArea = 0.0; Total_CNearFieldOF = 0.0; + Total_CFx = 0.0; Total_CFy = 0.0; Total_CFz = 0.0; + Total_CT = 0.0; Total_CQ = 0.0; Total_CMerit = 0.0; + Total_MaxHeat = 0.0; Total_Heat = 0.0; Total_ComboObj = 0.0; + Total_CpDiff = 0.0; Total_HeatFluxDiff = 0.0; + Total_NetThrust = 0.0; Total_Power = 0.0; + Total_CL_Prev = 0.0; Total_CD_Prev = 0.0; Total_CMx_Prev = 0.0; + Total_CMy_Prev = 0.0; Total_CMz_Prev = 0.0; + Total_AeroCD = 0.0; Total_SolidCD = 0.0; Total_IDR = 0.0; + Total_IDC = 0.0; + Total_Custom_ObjFunc = 0.0; + + /*--- Read farfield conditions from config ---*/ + + Density_Inf = config->GetDensity_FreeStreamND(); + Pressure_Inf = config->GetPressure_FreeStreamND(); + Velocity_Inf = config->GetVelocity_FreeStreamND(); + Energy_Inf = config->GetEnergy_FreeStreamND(); + Temperature_Inf = config->GetTemperature_FreeStreamND(); + Viscosity_Inf = config->GetViscosity_FreeStreamND(); + Mach_Inf = config->GetMach(); + Prandtl_Lam = config->GetPrandtl_Lam(); + Prandtl_Turb = config->GetPrandtl_Turb(); + Tke_Inf = config->GetTke_FreeStreamND(); + + /*--- Initialize the secondary values for direct derivative approxiations ---*/ + + switch(direct_diff) { + case NO_DERIVATIVE: + break; + case D_DENSITY: + SU2_TYPE::SetDerivative(Density_Inf, 1.0); + break; + case D_PRESSURE: + SU2_TYPE::SetDerivative(Pressure_Inf, 1.0); + break; + case D_TEMPERATURE: + SU2_TYPE::SetDerivative(Temperature_Inf, 1.0); + break; + case D_VISCOSITY: + SU2_TYPE::SetDerivative(Viscosity_Inf, 1.0); + break; + case D_MACH: case D_AOA: + case D_SIDESLIP: case D_REYNOLDS: + case D_TURB2LAM: case D_DESIGN: + /*--- Already done in postprocessing of config ---*/ + break; + default: + break; + } + + /*--- Initialize fan face pressure, fan face mach number, and mass flow rate ---*/ + + for (iMarker = 0; iMarker < nMarker; iMarker++) { + Inflow_MassFlow[iMarker] = 0.0; + Inflow_Mach[iMarker] = Mach_Inf; + Inflow_Pressure[iMarker] = Pressure_Inf; + Inflow_Area[iMarker] = 0.0; + + Exhaust_MassFlow[iMarker] = 0.0; + Exhaust_Temperature[iMarker] = Temperature_Inf; + Exhaust_Pressure[iMarker] = Pressure_Inf; + Exhaust_Area[iMarker] = 0.0; + + } + /*--- Initializate quantities for SlidingMesh Interface ---*/ + + SlidingState = new su2double*** [nMarker]; + SlidingStateNodes = new int* [nMarker]; + + for (iMarker = 0; iMarker < nMarker; iMarker++){ + + SlidingState[iMarker] = NULL; + SlidingStateNodes[iMarker] = NULL; + + if (config->GetMarker_All_KindBC(iMarker) == FLUID_INTERFACE){ + + SlidingState[iMarker] = new su2double**[geometry->GetnVertex(iMarker)]; + SlidingStateNodes[iMarker] = new int [geometry->GetnVertex(iMarker)]; + + for (iPoint = 0; iPoint < geometry->GetnVertex(iMarker); iPoint++){ + SlidingState[iMarker][iPoint] = new su2double*[nPrimVar+1]; + + SlidingStateNodes[iMarker][iPoint] = 0; + for (iVar = 0; iVar < nPrimVar+1; iVar++) + SlidingState[iMarker][iPoint][iVar] = NULL; + } + + } + } + + /*--- Only initialize when there is a Marker_Fluid_Load + *--- (this avoids overhead in all other cases while a more permanent structure is being developed) ---*/ + if((config->GetnMarker_Fluid_Load() > 0) && (MGLevel == MESH_0)){ + + InitVertexTractionContainer(geometry, config); + + if (config->GetDiscrete_Adjoint()) + InitVertexTractionAdjointContainer(geometry, config); + + } + + /*--- Initialize the solution to the far-field state everywhere. ---*/ + + nodes = new CNSVariable(Density_Inf, Velocity_Inf, Energy_Inf, nPoint, nDim, nVar, config); + SetBaseClassPointerToNodes(); + + /*--- Check that the initial solution is physical, report any non-physical nodes ---*/ + + counter_local = 0; + + for (iPoint = 0; iPoint < nPoint; iPoint++) { + + Density = nodes->GetDensity(iPoint); + + Velocity2 = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + Velocity2 += pow(nodes->GetSolution(iPoint,iDim+1)/Density,2); + + StaticEnergy= nodes->GetEnergy(iPoint) - 0.5*Velocity2; + + FluidModel->SetTDState_rhoe(Density, StaticEnergy); + Pressure= FluidModel->GetPressure(); + Temperature= FluidModel->GetTemperature(); + + /*--- Use the values at the infinity ---*/ + + if ((Pressure < 0.0) || (Density < 0.0) || (Temperature < 0.0)) { + Solution[0] = Density_Inf; + for (iDim = 0; iDim < nDim; iDim++) + Solution[iDim+1] = Velocity_Inf[iDim]*Density_Inf; + Solution[nDim+1] = Energy_Inf*Density_Inf; + nodes->SetSolution(iPoint,Solution); + nodes->SetSolution_Old(iPoint,Solution); + counter_local++; + } + + } + + /*--- Warning message about non-physical points ---*/ + + if (config->GetComm_Level() == COMM_FULL) { +#ifdef HAVE_MPI + SU2_MPI::Reduce(&counter_local, &counter_global, 1, MPI_UNSIGNED_LONG, MPI_SUM, MASTER_NODE, MPI_COMM_WORLD); +#else + counter_global = counter_local; +#endif + if ((rank == MASTER_NODE) && (counter_global != 0)) + cout << "Warning. The original solution contains "<< counter_global << " points that are not physical." << endl; + } + + /*--- Initialize the BGS residuals in FSI problems. ---*/ + if (config->GetMultizone_Residual()){ + Residual_BGS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_BGS[iVar] = 1.0; + Residual_Max_BGS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_Max_BGS[iVar] = 1.0; + + /*--- Define some structures for locating max residuals ---*/ + + Point_Max_BGS = new unsigned long[nVar]; for (iVar = 0; iVar < nVar; iVar++) Point_Max_BGS[iVar] = 0; + Point_Max_Coord_BGS = new su2double*[nVar]; + for (iVar = 0; iVar < nVar; iVar++) { + Point_Max_Coord_BGS[iVar] = new su2double[nDim]; + for (iDim = 0; iDim < nDim; iDim++) Point_Max_Coord_BGS[iVar][iDim] = 0.0; + } + } + + /*--- Define solver parameters needed for execution of destructor ---*/ + + if (config->GetKind_ConvNumScheme_Flow() == SPACE_CENTERED) space_centered = true; + else space_centered = false; + + if (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT) euler_implicit = true; + else euler_implicit = false; + + if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) least_squares = true; + else least_squares = false; + + /*--- Communicate and store volume and the number of neighbors for + any dual CVs that lie on on periodic markers. ---*/ + + for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { + InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_VOLUME); + CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_VOLUME); + InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_NEIGHBORS); + CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_NEIGHBORS); + } + SetImplicitPeriodic(euler_implicit); + if (iMesh == MESH_0) SetRotatePeriodic(true); + + /*--- Perform the MPI communication of the solution ---*/ + + InitiateComms(geometry, config, SOLUTION); + CompleteComms(geometry, config, SOLUTION); + + /* Store the initial CFL number for all grid points. */ + + const su2double CFL = config->GetCFL(MGLevel); + for (iPoint = 0; iPoint < nPoint; iPoint++) { + nodes->SetLocalCFL(iPoint, CFL); + } + Min_CFL_Local = CFL; + Max_CFL_Local = CFL; + Avg_CFL_Local = CFL; + + /*--- Add the solver name (max 8 characters) ---*/ + SolverName = "C.FLOW"; + +} + +CNSSolver::~CNSSolver(void) { + + unsigned short iMarker, iDim; + + unsigned long iVertex; + + if (CD_Visc != NULL) delete [] CD_Visc; + if (CL_Visc != NULL) delete [] CL_Visc; + if (CSF_Visc != NULL) delete [] CSF_Visc; + if (CFx_Visc != NULL) delete [] CFx_Visc; + if (CFy_Visc != NULL) delete [] CFy_Visc; + if (CFz_Visc != NULL) delete [] CFz_Visc; + if (CMx_Visc != NULL) delete [] CMx_Visc; + if (CMy_Visc != NULL) delete [] CMy_Visc; + if (CMz_Visc != NULL) delete [] CMz_Visc; + if (CoPx_Visc != NULL) delete [] CoPx_Visc; + if (CoPy_Visc != NULL) delete [] CoPy_Visc; + if (CoPz_Visc != NULL) delete [] CoPz_Visc; + if (CEff_Visc != NULL) delete [] CEff_Visc; + if (CMerit_Visc != NULL) delete [] CMerit_Visc; + if (Buffet_Metric != NULL) delete [] Buffet_Metric; + if (CT_Visc != NULL) delete [] CT_Visc; + if (CQ_Visc != NULL) delete [] CQ_Visc; + if (HF_Visc != NULL) delete [] HF_Visc; + if (MaxHF_Visc != NULL) delete [] MaxHF_Visc; + if (ForceViscous != NULL) delete [] ForceViscous; + if (MomentViscous != NULL) delete [] MomentViscous; + + if (Surface_CL_Visc != NULL) delete [] Surface_CL_Visc; + if (Surface_CD_Visc != NULL) delete [] Surface_CD_Visc; + if (Surface_CSF_Visc != NULL) delete [] Surface_CSF_Visc; + if (Surface_CEff_Visc != NULL) delete [] Surface_CEff_Visc; + if (Surface_CFx_Visc != NULL) delete [] Surface_CFx_Visc; + if (Surface_CFy_Visc != NULL) delete [] Surface_CFy_Visc; + if (Surface_CFz_Visc != NULL) delete [] Surface_CFz_Visc; + if (Surface_CMx_Visc != NULL) delete [] Surface_CMx_Visc; + if (Surface_CMy_Visc != NULL) delete [] Surface_CMy_Visc; + if (Surface_CMz_Visc != NULL) delete [] Surface_CMz_Visc; + if (Surface_HF_Visc != NULL) delete [] Surface_HF_Visc; + if (Surface_MaxHF_Visc != NULL) delete [] Surface_MaxHF_Visc; + if (Surface_Buffet_Metric != NULL) delete [] Surface_Buffet_Metric; + + if (CSkinFriction != NULL) { + for (iMarker = 0; iMarker < nMarker; iMarker++) { + for (iDim = 0; iDim < nDim; iDim++) { + delete [] CSkinFriction[iMarker][iDim]; + } + delete [] CSkinFriction[iMarker]; + } + delete [] CSkinFriction; + } + + if (HeatConjugateVar != NULL) { + for (iMarker = 0; iMarker < nMarker; iMarker++) { + for (iVertex = 0; iVertex < nVertex[iMarker]; iVertex++) { + delete [] HeatConjugateVar[iMarker][iVertex]; + } + delete [] HeatConjugateVar[iMarker]; + } + delete [] HeatConjugateVar; + } + + if (Buffet_Sensor != NULL) { + for (iMarker = 0; iMarker < nMarker; iMarker++){ + delete [] Buffet_Sensor[iMarker]; + } + delete [] Buffet_Sensor; + } + +} + +void CNSSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output) { + + unsigned long iPoint, ErrorCounter = 0; + su2double StrainMag = 0.0, Omega = 0.0, *Vorticity; + + unsigned long InnerIter = config->GetInnerIter(); + bool cont_adjoint = config->GetContinuous_Adjoint(); + bool disc_adjoint = config->GetDiscrete_Adjoint(); + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + bool center = (config->GetKind_ConvNumScheme_Flow() == SPACE_CENTERED) || (cont_adjoint && config->GetKind_ConvNumScheme_AdjFlow() == SPACE_CENTERED); + bool center_jst = center && config->GetKind_Centered_Flow() == JST; + bool limiter_flow = (config->GetKind_SlopeLimit_Flow() != NO_LIMITER) && (InnerIter <= config->GetLimiterIter()); + bool limiter_turb = (config->GetKind_SlopeLimit_Turb() != NO_LIMITER) && (InnerIter <= config->GetLimiterIter()); + bool limiter_adjflow = (cont_adjoint && (config->GetKind_SlopeLimit_AdjFlow() != NO_LIMITER) && (InnerIter <= config->GetLimiterIter())); + bool fixed_cl = config->GetFixed_CL_Mode(); + bool engine = ((config->GetnMarker_EngineInflow() != 0) || (config->GetnMarker_EngineExhaust() != 0)); + bool actuator_disk = ((config->GetnMarker_ActDiskInlet() != 0) || (config->GetnMarker_ActDiskOutlet() != 0)); + bool nearfield = (config->GetnMarker_NearFieldBound() != 0); + bool van_albada = config->GetKind_SlopeLimit_Flow() == VAN_ALBADA_EDGE; + unsigned short kind_row_dissipation = config->GetKind_RoeLowDiss(); + bool roe_low_dissipation = (kind_row_dissipation != NO_ROELOWDISS) && + (config->GetKind_Upwind_Flow() == ROE || + config->GetKind_Upwind_Flow() == SLAU || + config->GetKind_Upwind_Flow() == SLAU2); + bool wall_functions = config->GetWall_Functions(); + + /*--- Update the angle of attack at the far-field for fixed CL calculations (only direct problem). ---*/ + + if ((fixed_cl) && (!disc_adjoint) && (!cont_adjoint)) { SetFarfield_AoA(geometry, solver_container, config, iMesh, Output); } + + /*--- Set the primitive variables ---*/ + + ErrorCounter = SetPrimitive_Variables(solver_container, config, Output); + + /*--- Compute the engine properties ---*/ + + if (engine) { GetPower_Properties(geometry, config, iMesh, Output); } + + /*--- Compute the actuator disk properties and distortion levels ---*/ + + if (actuator_disk) { + Set_MPI_ActDisk(solver_container, geometry, config); + SetActDisk_BCThrust(geometry, solver_container, config, iMesh, Output); + } + + /*--- Compute NearField MPI ---*/ + + if (nearfield) { Set_MPI_Nearfield(geometry, config); } + + /*--- Artificial dissipation ---*/ + + if (center && !Output) { + SetMax_Eigenvalue(geometry, config); + if ((center_jst) && (iMesh == MESH_0)) { + SetCentered_Dissipation_Sensor(geometry, config); + SetUndivided_Laplacian(geometry, config); + } + } + + /*--- Roe Low Dissipation Sensor ---*/ + + if (roe_low_dissipation){ + SetRoe_Dissipation(geometry, config); + if (kind_row_dissipation == FD_DUCROS || kind_row_dissipation == NTS_DUCROS){ + SetUpwind_Ducros_Sensor(geometry, config); + } + } + + /*--- Compute gradient for MUSCL reconstruction. ---*/ + + if (config->GetReconstructionGradientRequired() && (iMesh == MESH_0)) { + if (config->GetKind_Gradient_Method_Recon() == GREEN_GAUSS) + SetPrimitive_Gradient_GG(geometry, config, true); + if (config->GetKind_Gradient_Method_Recon() == LEAST_SQUARES) + SetPrimitive_Gradient_LS(geometry, config, true); + if (config->GetKind_Gradient_Method_Recon() == WEIGHTED_LEAST_SQUARES) + SetPrimitive_Gradient_LS(geometry, config, true); + } + + /*--- Compute gradient of the primitive variables ---*/ + + if (config->GetKind_Gradient_Method() == GREEN_GAUSS) { + SetPrimitive_Gradient_GG(geometry, config); + } + if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) { + SetPrimitive_Gradient_LS(geometry, config); + } + + /*--- Compute the limiter in case we need it in the turbulence model + or to limit the viscous terms (check this logic with JST and 2nd order turbulence model) ---*/ + + if ((iMesh == MESH_0) && (limiter_flow || limiter_turb || limiter_adjflow) + && !Output && !van_albada) { SetPrimitive_Limiter(geometry, config); } + + /*--- Evaluate the vorticity and strain rate magnitude ---*/ + + solver_container[FLOW_SOL]->GetNodes()->SetVorticity_StrainMag(); + + StrainMag_Max = 0.0; Omega_Max = 0.0; + for (iPoint = 0; iPoint < nPoint; iPoint++) { + + StrainMag = solver_container[FLOW_SOL]->GetNodes()->GetStrainMag(iPoint); + Vorticity = solver_container[FLOW_SOL]->GetNodes()->GetVorticity(iPoint); + Omega = sqrt(Vorticity[0]*Vorticity[0]+ Vorticity[1]*Vorticity[1]+ Vorticity[2]*Vorticity[2]); + + StrainMag_Max = max(StrainMag_Max, StrainMag); + Omega_Max = max(Omega_Max, Omega); + + } + + /*--- Compute the TauWall from the wall functions ---*/ + + if (wall_functions) + SetTauWall_WF(geometry, solver_container, config); + + /*--- Initialize the Jacobian matrices ---*/ + + if (implicit && !config->GetDiscrete_Adjoint()) Jacobian.SetValZero(); + + /*--- Error message ---*/ + + if (config->GetComm_Level() == COMM_FULL) { + +#ifdef HAVE_MPI + unsigned long MyErrorCounter = ErrorCounter; ErrorCounter = 0; + su2double MyOmega_Max = Omega_Max; Omega_Max = 0.0; + su2double MyStrainMag_Max = StrainMag_Max; StrainMag_Max = 0.0; + + SU2_MPI::Allreduce(&MyErrorCounter, &ErrorCounter, 1, MPI_UNSIGNED_LONG, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyStrainMag_Max, &StrainMag_Max, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyOmega_Max, &Omega_Max, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); +#endif + + if (iMesh == MESH_0) { + config->SetNonphysical_Points(ErrorCounter); + solver_container[FLOW_SOL]->SetStrainMag_Max(StrainMag_Max); + solver_container[FLOW_SOL]->SetOmega_Max(Omega_Max); + } + + } + +} + +unsigned long CNSSolver::SetPrimitive_Variables(CSolver **solver_container, CConfig *config, bool Output) { + + unsigned long iPoint, nonPhysicalPoints = 0; + su2double eddy_visc = 0.0, turb_ke = 0.0, DES_LengthScale = 0.0; + unsigned short turb_model = config->GetKind_Turb_Model(); + bool physical = true; + + bool tkeNeeded = ((turb_model == SST) || (turb_model == SST_SUST)) ; + + for (iPoint = 0; iPoint < nPoint; iPoint ++) { + + /*--- Retrieve the value of the kinetic energy (if need it) ---*/ + + if (turb_model != NONE) { + eddy_visc = solver_container[TURB_SOL]->GetNodes()->GetmuT(iPoint); + if (tkeNeeded) turb_ke = solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0); + + if (config->GetKind_HybridRANSLES() != NO_HYBRIDRANSLES){ + DES_LengthScale = solver_container[TURB_SOL]->GetNodes()->GetDES_LengthScale(iPoint); + } + } + + /*--- Compressible flow, primitive variables nDim+5, (T, vx, vy, vz, P, rho, h, c, lamMu, eddyMu, ThCond, Cp) ---*/ + + physical = static_cast(nodes)->SetPrimVar(iPoint,eddy_visc, turb_ke, FluidModel); + nodes->SetSecondaryVar(iPoint,FluidModel); + + /* Check for non-realizable states for reporting. */ + + if (!physical) nonPhysicalPoints++; + + /*--- Set the DES length scale ---*/ + + nodes->SetDES_LengthScale(iPoint,DES_LengthScale); + + /*--- Initialize the convective, source and viscous residual vector ---*/ + + if (!Output) LinSysRes.SetBlock_Zero(iPoint); + + } + + return nonPhysicalPoints; +} + +void CNSSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned long Iteration) { + + su2double *Normal, Area, Vol, Mean_SoundSpeed = 0.0, Mean_ProjVel = 0.0, Lambda, Local_Delta_Time, Local_Delta_Time_Visc, + Global_Delta_Time = 1E6, Mean_LaminarVisc = 0.0, Mean_EddyVisc = 0.0, Mean_Density = 0.0, Lambda_1, Lambda_2, K_v = 0.25, Global_Delta_UnstTimeND; + unsigned long iEdge, iVertex, iPoint = 0, jPoint = 0; + unsigned short iDim, iMarker; + su2double ProjVel, ProjVel_i, ProjVel_j; + + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + bool dual_time = ((config->GetTime_Marching() == DT_STEPPING_1ST) || + (config->GetTime_Marching() == DT_STEPPING_2ND)); + + Min_Delta_Time = 1.E30; Max_Delta_Time = 0.0; + + /*--- Set maximum inviscid eigenvalue to zero, and compute sound speed and viscosity ---*/ + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + nodes->SetMax_Lambda_Inv(iPoint,0.0); + nodes->SetMax_Lambda_Visc(iPoint,0.0); + } + + /*--- Loop interior edges ---*/ + + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { + + /*--- Point identification, Normal vector and area ---*/ + + iPoint = geometry->edge[iEdge]->GetNode(0); + jPoint = geometry->edge[iEdge]->GetNode(1); + + Normal = geometry->edge[iEdge]->GetNormal(); + Area = 0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); + + /*--- Mean Values ---*/ + + Mean_ProjVel = 0.5 * (nodes->GetProjVel(iPoint,Normal) + nodes->GetProjVel(jPoint,Normal)); + Mean_SoundSpeed = 0.5 * (nodes->GetSoundSpeed(iPoint) + nodes->GetSoundSpeed(jPoint)) * Area; + + /*--- Adjustment for grid movement ---*/ + + if (dynamic_grid) { + su2double *GridVel_i = geometry->node[iPoint]->GetGridVel(); + su2double *GridVel_j = geometry->node[jPoint]->GetGridVel(); + ProjVel_i = 0.0; ProjVel_j =0.0; + for (iDim = 0; iDim < nDim; iDim++) { + ProjVel_i += GridVel_i[iDim]*Normal[iDim]; + ProjVel_j += GridVel_j[iDim]*Normal[iDim]; + } + Mean_ProjVel -= 0.5 * (ProjVel_i + ProjVel_j) ; + } + + /*--- Inviscid contribution ---*/ + + Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed ; + if (geometry->node[iPoint]->GetDomain()) nodes->AddMax_Lambda_Inv(iPoint,Lambda); + if (geometry->node[jPoint]->GetDomain()) nodes->AddMax_Lambda_Inv(jPoint,Lambda); + + /*--- Viscous contribution ---*/ + + Mean_LaminarVisc = 0.5*(nodes->GetLaminarViscosity(iPoint) + nodes->GetLaminarViscosity(jPoint)); + Mean_EddyVisc = 0.5*(nodes->GetEddyViscosity(iPoint) + nodes->GetEddyViscosity(jPoint)); + Mean_Density = 0.5*(nodes->GetDensity(iPoint) + nodes->GetDensity(jPoint)); + + Lambda_1 = (4.0/3.0)*(Mean_LaminarVisc + Mean_EddyVisc); + //TODO (REAL_GAS) removing Gamma it cannot work with FLUIDPROP + Lambda_2 = (1.0 + (Prandtl_Lam/Prandtl_Turb)*(Mean_EddyVisc/Mean_LaminarVisc))*(Gamma*Mean_LaminarVisc/Prandtl_Lam); + Lambda = (Lambda_1 + Lambda_2)*Area*Area/Mean_Density; + + if (geometry->node[iPoint]->GetDomain()) nodes->AddMax_Lambda_Visc(iPoint, Lambda); + if (geometry->node[jPoint]->GetDomain()) nodes->AddMax_Lambda_Visc(jPoint, Lambda); + + } + + /*--- Loop boundary edges ---*/ + + for (iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { + if ((config->GetMarker_All_KindBC(iMarker) != INTERNAL_BOUNDARY) && + (config->GetMarker_All_KindBC(iMarker) != PERIODIC_BOUNDARY)) { + for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { + + /*--- Point identification, Normal vector and area ---*/ + + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); + + /*--- Mean Values ---*/ + + Mean_ProjVel = nodes->GetProjVel(iPoint,Normal); + Mean_SoundSpeed = nodes->GetSoundSpeed(iPoint) * Area; + + /*--- Adjustment for grid movement ---*/ + + if (dynamic_grid) { + su2double *GridVel = geometry->node[iPoint]->GetGridVel(); + ProjVel = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + ProjVel += GridVel[iDim]*Normal[iDim]; + Mean_ProjVel -= ProjVel; + } + + /*--- Inviscid contribution ---*/ + + Lambda = fabs(Mean_ProjVel) + Mean_SoundSpeed; + if (geometry->node[iPoint]->GetDomain()) { + nodes->AddMax_Lambda_Inv(iPoint,Lambda); + } + + /*--- Viscous contribution ---*/ + + Mean_LaminarVisc = nodes->GetLaminarViscosity(iPoint); + Mean_EddyVisc = nodes->GetEddyViscosity(iPoint); + Mean_Density = nodes->GetDensity(iPoint); + + Lambda_1 = (4.0/3.0)*(Mean_LaminarVisc + Mean_EddyVisc); + Lambda_2 = (1.0 + (Prandtl_Lam/Prandtl_Turb)*(Mean_EddyVisc/Mean_LaminarVisc))*(Gamma*Mean_LaminarVisc/Prandtl_Lam); + Lambda = (Lambda_1 + Lambda_2)*Area*Area/Mean_Density; + + if (geometry->node[iPoint]->GetDomain()) nodes->AddMax_Lambda_Visc(iPoint, Lambda); + + } + } + } + + /*--- Each element uses their own speed, steady state simulation ---*/ + + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + Vol = geometry->node[iPoint]->GetVolume(); + + if (Vol != 0.0) { + Local_Delta_Time = nodes->GetLocalCFL(iPoint)*Vol / nodes->GetMax_Lambda_Inv(iPoint); + Local_Delta_Time_Visc = nodes->GetLocalCFL(iPoint)*K_v*Vol*Vol/ nodes->GetMax_Lambda_Visc(iPoint); + Local_Delta_Time = min(Local_Delta_Time, Local_Delta_Time_Visc); + Global_Delta_Time = min(Global_Delta_Time, Local_Delta_Time); + Min_Delta_Time = min(Min_Delta_Time, Local_Delta_Time); + Max_Delta_Time = max(Max_Delta_Time, Local_Delta_Time); + if (Local_Delta_Time > config->GetMax_DeltaTime()) + Local_Delta_Time = config->GetMax_DeltaTime(); + nodes->SetDelta_Time(iPoint,Local_Delta_Time); + } + else { + nodes->SetDelta_Time(iPoint,0.0); + } + + } + + + /*--- Compute the max and the min dt (in parallel) ---*/ + if (config->GetComm_Level() == COMM_FULL) { +#ifdef HAVE_MPI + su2double rbuf_time, sbuf_time; + sbuf_time = Min_Delta_Time; + SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, MPI_COMM_WORLD); + SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); + Min_Delta_Time = rbuf_time; + + sbuf_time = Max_Delta_Time; + SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MAX, MASTER_NODE, MPI_COMM_WORLD); + SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); + Max_Delta_Time = rbuf_time; +#endif + } + + /*--- For exact time solution use the minimum delta time of the whole mesh ---*/ + if (config->GetTime_Marching() == TIME_STEPPING) { +#ifdef HAVE_MPI + su2double rbuf_time, sbuf_time; + sbuf_time = Global_Delta_Time; + SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, MPI_COMM_WORLD); + SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); + Global_Delta_Time = rbuf_time; +#endif + /*--- If the unsteady CFL is set to zero, it uses the defined + unsteady time step, otherwise it computes the time step based + on the unsteady CFL ---*/ + + if (config->GetUnst_CFL() == 0.0) { + Global_Delta_Time = config->GetDelta_UnstTime(); + } + config->SetDelta_UnstTimeND(Global_Delta_Time); + for (iPoint = 0; iPoint < nPointDomain; iPoint++){ + + /*--- Sets the regular CFL equal to the unsteady CFL ---*/ + + nodes->SetLocalCFL(iPoint, config->GetUnst_CFL()); + nodes->SetDelta_Time(iPoint, Global_Delta_Time); + Min_Delta_Time = Global_Delta_Time; + Max_Delta_Time = Global_Delta_Time; + + } + } + + /*--- Recompute the unsteady time step for the dual time strategy + if the unsteady CFL is diferent from 0 ---*/ + if ((dual_time) && (Iteration == 0) && (config->GetUnst_CFL() != 0.0) && (iMesh == MESH_0)) { + + Global_Delta_UnstTimeND = 1e30; + for (iPoint = 0; iPoint < nPointDomain; iPoint++){ + Global_Delta_UnstTimeND = min(Global_Delta_UnstTimeND,config->GetUnst_CFL()*Global_Delta_Time/nodes->GetLocalCFL(iPoint)); + } + +#ifdef HAVE_MPI + su2double rbuf_time, sbuf_time; + sbuf_time = Global_Delta_UnstTimeND; + SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, MPI_COMM_WORLD); + SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); + Global_Delta_UnstTimeND = rbuf_time; +#endif + config->SetDelta_UnstTimeND(Global_Delta_UnstTimeND); + } + + /*--- The pseudo local time (explicit integration) cannot be greater than the physical time ---*/ + if (dual_time) + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + if (!implicit) { + Local_Delta_Time = min((2.0/3.0)*config->GetDelta_UnstTimeND(), nodes->GetDelta_Time(iPoint)); + nodes->SetDelta_Time(iPoint,Local_Delta_Time); + } + } + +} + +void CNSSolver::Viscous_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, + CConfig *config, unsigned short iMesh, unsigned short iRKStep) { + + unsigned long iPoint, jPoint, iEdge; + + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { + + /*--- Points, coordinates and normal vector in edge ---*/ + + iPoint = geometry->edge[iEdge]->GetNode(0); + jPoint = geometry->edge[iEdge]->GetNode(1); + numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[jPoint]->GetCoord()); + numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); + + /*--- Primitive and secondary variables ---*/ + + numerics->SetPrimitive(nodes->GetPrimitive(iPoint), nodes->GetPrimitive(jPoint)); + numerics->SetSecondary(nodes->GetSecondary(iPoint), nodes->GetSecondary(jPoint)); + + /*--- Gradient and limiters ---*/ + + numerics->SetPrimVarGradient(nodes->GetGradient_Primitive(iPoint), nodes->GetGradient_Primitive(jPoint)); + + /*--- Turbulent kinetic energy ---*/ + + if ((config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST)) + numerics->SetTurbKineticEnergy(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0), + solver_container[TURB_SOL]->GetNodes()->GetSolution(jPoint,0)); + + /*--- Wall shear stress values (wall functions) ---*/ + + numerics->SetTauWall(nodes->GetTauWall(iPoint), nodes->GetTauWall(iPoint)); + + /*--- Compute and update residual ---*/ + + numerics->ComputeResidual(Res_Visc, Jacobian_i, Jacobian_j, config); + + LinSysRes.SubtractBlock(iPoint, Res_Visc); + LinSysRes.AddBlock(jPoint, Res_Visc); + + /*--- Implicit part ---*/ + + if (implicit) { + Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); + Jacobian.SubtractBlock(iPoint, jPoint, Jacobian_j); + Jacobian.AddBlock(jPoint, iPoint, Jacobian_i); + Jacobian.AddBlock(jPoint, jPoint, Jacobian_j); + } + + } + +} + +void CNSSolver::Friction_Forces(CGeometry *geometry, CConfig *config) { + + unsigned long iVertex, iPoint, iPointNormal; + unsigned short Boundary, Monitoring, iMarker, iMarker_Monitoring, iDim, jDim; + su2double Viscosity = 0.0, div_vel, *Normal, MomentDist[3] = {0.0, 0.0, 0.0}, WallDist[3] = {0.0, 0.0, 0.0}, + *Coord, *Coord_Normal, Area, WallShearStress, TauNormal, factor, RefTemp, RefVel2, + RefDensity, GradTemperature, Density = 0.0, WallDistMod, FrictionVel, + Mach2Vel, Mach_Motion, UnitNormal[3] = {0.0, 0.0, 0.0}, TauElem[3] = {0.0, 0.0, 0.0}, TauTangent[3] = {0.0, 0.0, 0.0}, + Tau[3][3] = {{0.0, 0.0, 0.0},{0.0, 0.0, 0.0},{0.0, 0.0, 0.0}}, Force[3] = {0.0, 0.0, 0.0}, Cp, thermal_conductivity, MaxNorm = 8.0, + Grad_Vel[3][3] = {{0.0, 0.0, 0.0},{0.0, 0.0, 0.0},{0.0, 0.0, 0.0}}, Grad_Temp[3] = {0.0, 0.0, 0.0}, + delta[3][3] = {{1.0, 0.0, 0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}}; + su2double MomentX_Force[3] = {0.0,0.0,0.0}, MomentY_Force[3] = {0.0,0.0,0.0}, MomentZ_Force[3] = {0.0,0.0,0.0}; + su2double AxiFactor; + +#ifdef HAVE_MPI + su2double MyAllBound_CD_Visc, MyAllBound_CL_Visc, MyAllBound_CSF_Visc, MyAllBound_CMx_Visc, MyAllBound_CMy_Visc, MyAllBound_CMz_Visc, MyAllBound_CoPx_Visc, MyAllBound_CoPy_Visc, MyAllBound_CoPz_Visc, MyAllBound_CFx_Visc, MyAllBound_CFy_Visc, MyAllBound_CFz_Visc, MyAllBound_CT_Visc, MyAllBound_CQ_Visc, MyAllBound_HF_Visc, MyAllBound_MaxHF_Visc, *MySurface_CL_Visc = NULL, *MySurface_CD_Visc = NULL, *MySurface_CSF_Visc = NULL, *MySurface_CEff_Visc = NULL, *MySurface_CFx_Visc = NULL, *MySurface_CFy_Visc = NULL, *MySurface_CFz_Visc = NULL, *MySurface_CMx_Visc = NULL, *MySurface_CMy_Visc = NULL, *MySurface_CMz_Visc = NULL, *MySurface_HF_Visc = NULL, *MySurface_MaxHF_Visc; +#endif + + string Marker_Tag, Monitoring_Tag; + + su2double Alpha = config->GetAoA()*PI_NUMBER/180.0; + su2double Beta = config->GetAoS()*PI_NUMBER/180.0; + su2double RefArea = config->GetRefArea(); + su2double RefLength = config->GetRefLength(); + su2double RefHeatFlux = config->GetHeat_Flux_Ref(); + su2double Gas_Constant = config->GetGas_ConstantND(); + su2double *Origin = NULL; + + if (config->GetnMarker_Monitoring() != 0) { Origin = config->GetRefOriginMoment(0); } + + su2double Prandtl_Lam = config->GetPrandtl_Lam(); + bool QCR = config->GetQCR(); + bool axisymmetric = config->GetAxisymmetric(); + + /*--- Evaluate reference values for non-dimensionalization. + For dynamic meshes, use the motion Mach number as a reference value + for computing the force coefficients. Otherwise, use the freestream values, + which is the standard convention. ---*/ + + RefTemp = Temperature_Inf; + RefDensity = Density_Inf; + if (dynamic_grid) { + Mach2Vel = sqrt(Gamma*Gas_Constant*RefTemp); + Mach_Motion = config->GetMach_Motion(); + RefVel2 = (Mach_Motion*Mach2Vel)*(Mach_Motion*Mach2Vel); + } else { + RefVel2 = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + RefVel2 += Velocity_Inf[iDim]*Velocity_Inf[iDim]; + } + + factor = 1.0 / (0.5*RefDensity*RefArea*RefVel2); + + /*--- Variables initialization ---*/ + + AllBound_CD_Visc = 0.0; AllBound_CL_Visc = 0.0; AllBound_CSF_Visc = 0.0; + AllBound_CFx_Visc = 0.0; AllBound_CFy_Visc = 0.0; AllBound_CFz_Visc = 0.0; + AllBound_CMx_Visc = 0.0; AllBound_CMy_Visc = 0.0; AllBound_CMz_Visc = 0.0; + AllBound_CoPx_Visc = 0.0; AllBound_CoPy_Visc = 0.0; AllBound_CoPz_Visc = 0.0; + AllBound_CT_Visc = 0.0; AllBound_CQ_Visc = 0.0; AllBound_CMerit_Visc = 0.0; + AllBound_HF_Visc = 0.0; AllBound_MaxHF_Visc = 0.0; AllBound_CEff_Visc = 0.0; + + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { + Surface_CL_Visc[iMarker_Monitoring] = 0.0; Surface_CD_Visc[iMarker_Monitoring] = 0.0; + Surface_CSF_Visc[iMarker_Monitoring] = 0.0; Surface_CEff_Visc[iMarker_Monitoring] = 0.0; + Surface_CFx_Visc[iMarker_Monitoring] = 0.0; Surface_CFy_Visc[iMarker_Monitoring] = 0.0; + Surface_CFz_Visc[iMarker_Monitoring] = 0.0; Surface_CMx_Visc[iMarker_Monitoring] = 0.0; + Surface_CMy_Visc[iMarker_Monitoring] = 0.0; Surface_CMz_Visc[iMarker_Monitoring] = 0.0; + Surface_HF_Visc[iMarker_Monitoring] = 0.0; Surface_MaxHF_Visc[iMarker_Monitoring] = 0.0; + } + + /*--- Loop over the Navier-Stokes markers ---*/ + + for (iMarker = 0; iMarker < nMarker; iMarker++) { + + Boundary = config->GetMarker_All_KindBC(iMarker); + Monitoring = config->GetMarker_All_Monitoring(iMarker); + + /*--- Obtain the origin for the moment computation for a particular marker ---*/ + + if (Monitoring == YES) { + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { + Monitoring_Tag = config->GetMarker_Monitoring_TagBound(iMarker_Monitoring); + Marker_Tag = config->GetMarker_All_TagBound(iMarker); + if (Marker_Tag == Monitoring_Tag) + Origin = config->GetRefOriginMoment(iMarker_Monitoring); + } + } + + if ((Boundary == HEAT_FLUX) || (Boundary == ISOTHERMAL) || (Boundary == HEAT_FLUX) || (Boundary == CHT_WALL_INTERFACE)) { + + /*--- Forces initialization at each Marker ---*/ + + CD_Visc[iMarker] = 0.0; CL_Visc[iMarker] = 0.0; CSF_Visc[iMarker] = 0.0; + CFx_Visc[iMarker] = 0.0; CFy_Visc[iMarker] = 0.0; CFz_Visc[iMarker] = 0.0; + CMx_Visc[iMarker] = 0.0; CMy_Visc[iMarker] = 0.0; CMz_Visc[iMarker] = 0.0; + CoPx_Visc[iMarker] = 0.0; CoPy_Visc[iMarker] = 0.0; CoPz_Visc[iMarker] = 0.0; + CT_Visc[iMarker] = 0.0; CQ_Visc[iMarker] = 0.0; CMerit_Visc[iMarker] = 0.0; + HF_Visc[iMarker] = 0.0; MaxHF_Visc[iMarker] = 0.0; CEff_Visc[iMarker] = 0.0; + + for (iDim = 0; iDim < nDim; iDim++) ForceViscous[iDim] = 0.0; + MomentViscous[0] = 0.0; MomentViscous[1] = 0.0; MomentViscous[2] = 0.0; + MomentX_Force[0] = 0.0; MomentX_Force[1] = 0.0; MomentX_Force[2] = 0.0; + MomentY_Force[0] = 0.0; MomentY_Force[1] = 0.0; MomentY_Force[2] = 0.0; + MomentZ_Force[0] = 0.0; MomentZ_Force[1] = 0.0; MomentZ_Force[2] = 0.0; + + /*--- Loop over the vertices to compute the forces ---*/ + + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + iPointNormal = geometry->vertex[iMarker][iVertex]->GetNormal_Neighbor(); + + Coord = geometry->node[iPoint]->GetCoord(); + Coord_Normal = geometry->node[iPointNormal]->GetCoord(); + + Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); + + for (iDim = 0; iDim < nDim; iDim++) { + for (jDim = 0 ; jDim < nDim; jDim++) { + Grad_Vel[iDim][jDim] = nodes->GetGradient_Primitive(iPoint,iDim+1, jDim); + } + Grad_Temp[iDim] = nodes->GetGradient_Primitive(iPoint,0, iDim); + } + + Viscosity = nodes->GetLaminarViscosity(iPoint); + Density = nodes->GetDensity(iPoint); + + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt(Area); + + + for (iDim = 0; iDim < nDim; iDim++) { + UnitNormal[iDim] = Normal[iDim]/Area; + } + + /*--- Evaluate Tau ---*/ + + div_vel = 0.0; for (iDim = 0; iDim < nDim; iDim++) div_vel += Grad_Vel[iDim][iDim]; + + for (iDim = 0; iDim < nDim; iDim++) { + for (jDim = 0 ; jDim < nDim; jDim++) { + Tau[iDim][jDim] = Viscosity*(Grad_Vel[jDim][iDim] + Grad_Vel[iDim][jDim]) - TWO3*Viscosity*div_vel*delta[iDim][jDim]; + } + } + + /*--- If necessary evaluate the QCR contribution to Tau ---*/ + + if (QCR){ + su2double den_aux, c_cr1=0.3, O_ik, O_jk; + unsigned short kDim; + + /*--- Denominator Antisymmetric normalized rotation tensor ---*/ + + den_aux = 0.0; + for (iDim = 0 ; iDim < nDim; iDim++) + for (jDim = 0 ; jDim < nDim; jDim++) + den_aux += Grad_Vel[iDim][jDim] * Grad_Vel[iDim][jDim]; + den_aux = sqrt(max(den_aux,1E-10)); + + /*--- Adding the QCR contribution ---*/ + + for (iDim = 0 ; iDim < nDim; iDim++){ + for (jDim = 0 ; jDim < nDim; jDim++){ + for (kDim = 0 ; kDim < nDim; kDim++){ + O_ik = (Grad_Vel[iDim][kDim] - Grad_Vel[kDim][iDim])/ den_aux; + O_jk = (Grad_Vel[jDim][kDim] - Grad_Vel[kDim][jDim])/ den_aux; + Tau[iDim][jDim] -= c_cr1 * (O_ik * Tau[jDim][kDim] + O_jk * Tau[iDim][kDim]); + } + } + } + + } + + /*--- Project Tau in each surface element ---*/ + + for (iDim = 0; iDim < nDim; iDim++) { + TauElem[iDim] = 0.0; + for (jDim = 0; jDim < nDim; jDim++) { + TauElem[iDim] += Tau[iDim][jDim]*UnitNormal[jDim]; + } + } + + /*--- Compute wall shear stress (using the stress tensor). Compute wall skin friction coefficient, and heat flux on the wall ---*/ + + TauNormal = 0.0; for (iDim = 0; iDim < nDim; iDim++) TauNormal += TauElem[iDim] * UnitNormal[iDim]; + + WallShearStress = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + TauTangent[iDim] = TauElem[iDim] - TauNormal * UnitNormal[iDim]; + CSkinFriction[iMarker][iDim][iVertex] = TauTangent[iDim] / (0.5*RefDensity*RefVel2); + WallShearStress += TauTangent[iDim] * TauTangent[iDim]; + } + WallShearStress = sqrt(WallShearStress); + + for (iDim = 0; iDim < nDim; iDim++) WallDist[iDim] = (Coord[iDim] - Coord_Normal[iDim]); + WallDistMod = 0.0; for (iDim = 0; iDim < nDim; iDim++) WallDistMod += WallDist[iDim]*WallDist[iDim]; WallDistMod = sqrt(WallDistMod); + + /*--- Compute y+ and non-dimensional velocity ---*/ + + FrictionVel = sqrt(fabs(WallShearStress)/Density); + YPlus[iMarker][iVertex] = WallDistMod*FrictionVel/(Viscosity/Density); + + /*--- Compute total and maximum heat flux on the wall ---*/ + + GradTemperature = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + GradTemperature -= Grad_Temp[iDim]*UnitNormal[iDim]; + + Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; + thermal_conductivity = Cp * Viscosity/Prandtl_Lam; + HeatFlux[iMarker][iVertex] = -thermal_conductivity*GradTemperature*RefHeatFlux; + + /*--- Note that y+, and heat are computed at the + halo cells (for visualization purposes), but not the forces ---*/ + + if ((geometry->node[iPoint]->GetDomain()) && (Monitoring == YES)) { + + /*--- Axisymmetric simulations ---*/ + + if (axisymmetric) AxiFactor = 2.0*PI_NUMBER*geometry->node[iPoint]->GetCoord(1); + else AxiFactor = 1.0; + + /*--- Force computation ---*/ + + for (iDim = 0; iDim < nDim; iDim++) { + Force[iDim] = TauElem[iDim] * Area * factor * AxiFactor; + ForceViscous[iDim] += Force[iDim]; + MomentDist[iDim] = Coord[iDim] - Origin[iDim]; + } + + /*--- Moment with respect to the reference axis ---*/ + + if (iDim == 3) { + MomentViscous[0] += (Force[2]*MomentDist[1] - Force[1]*MomentDist[2])/RefLength; + MomentX_Force[1] += (-Force[1]*Coord[2]); + MomentX_Force[2] += (Force[2]*Coord[1]); + + MomentViscous[1] += (Force[0]*MomentDist[2] - Force[2]*MomentDist[0])/RefLength; + MomentY_Force[2] += (-Force[2]*Coord[0]); + MomentY_Force[0] += (Force[0]*Coord[2]); + } + MomentViscous[2] += (Force[1]*MomentDist[0] - Force[0]*MomentDist[1])/RefLength; + MomentZ_Force[0] += (-Force[0]*Coord[1]); + MomentZ_Force[1] += (Force[1]*Coord[0]); + + } + + HF_Visc[iMarker] += HeatFlux[iMarker][iVertex]*Area; + MaxHF_Visc[iMarker] += pow(HeatFlux[iMarker][iVertex], MaxNorm); + + } + + /*--- Project forces and store the non-dimensional coefficients ---*/ + + if (Monitoring == YES) { + if (nDim == 2) { + CD_Visc[iMarker] = ForceViscous[0]*cos(Alpha) + ForceViscous[1]*sin(Alpha); + CL_Visc[iMarker] = -ForceViscous[0]*sin(Alpha) + ForceViscous[1]*cos(Alpha); + CEff_Visc[iMarker] = CL_Visc[iMarker] / (CD_Visc[iMarker]+EPS); + CFx_Visc[iMarker] = ForceViscous[0]; + CFy_Visc[iMarker] = ForceViscous[1]; + CMz_Visc[iMarker] = MomentViscous[2]; + CoPx_Visc[iMarker] = MomentZ_Force[1]; + CoPy_Visc[iMarker] = -MomentZ_Force[0]; + CT_Visc[iMarker] = -CFx_Visc[iMarker]; + CQ_Visc[iMarker] = -CMz_Visc[iMarker]; + CMerit_Visc[iMarker] = CT_Visc[iMarker] / (CQ_Visc[iMarker]+EPS); + MaxHF_Visc[iMarker] = pow(MaxHF_Visc[iMarker], 1.0/MaxNorm); + } + if (nDim == 3) { + CD_Visc[iMarker] = ForceViscous[0]*cos(Alpha)*cos(Beta) + ForceViscous[1]*sin(Beta) + ForceViscous[2]*sin(Alpha)*cos(Beta); + CL_Visc[iMarker] = -ForceViscous[0]*sin(Alpha) + ForceViscous[2]*cos(Alpha); + CSF_Visc[iMarker] = -ForceViscous[0]*sin(Beta)*cos(Alpha) + ForceViscous[1]*cos(Beta) - ForceViscous[2]*sin(Beta)*sin(Alpha); + CEff_Visc[iMarker] = CL_Visc[iMarker]/(CD_Visc[iMarker] + EPS); + CFx_Visc[iMarker] = ForceViscous[0]; + CFy_Visc[iMarker] = ForceViscous[1]; + CFz_Visc[iMarker] = ForceViscous[2]; + CMx_Visc[iMarker] = MomentViscous[0]; + CMy_Visc[iMarker] = MomentViscous[1]; + CMz_Visc[iMarker] = MomentViscous[2]; + CoPx_Visc[iMarker] = -MomentY_Force[0]; + CoPz_Visc[iMarker] = MomentY_Force[2]; + CT_Visc[iMarker] = -CFz_Visc[iMarker]; + CQ_Visc[iMarker] = -CMz_Visc[iMarker]; + CMerit_Visc[iMarker] = CT_Visc[iMarker] / (CQ_Visc[iMarker] + EPS); + MaxHF_Visc[iMarker] = pow(MaxHF_Visc[iMarker], 1.0/MaxNorm); + } + + AllBound_CD_Visc += CD_Visc[iMarker]; + AllBound_CL_Visc += CL_Visc[iMarker]; + AllBound_CSF_Visc += CSF_Visc[iMarker]; + AllBound_CFx_Visc += CFx_Visc[iMarker]; + AllBound_CFy_Visc += CFy_Visc[iMarker]; + AllBound_CFz_Visc += CFz_Visc[iMarker]; + AllBound_CMx_Visc += CMx_Visc[iMarker]; + AllBound_CMy_Visc += CMy_Visc[iMarker]; + AllBound_CMz_Visc += CMz_Visc[iMarker]; + AllBound_CoPx_Visc += CoPx_Visc[iMarker]; + AllBound_CoPy_Visc += CoPy_Visc[iMarker]; + AllBound_CoPz_Visc += CoPz_Visc[iMarker]; + AllBound_CT_Visc += CT_Visc[iMarker]; + AllBound_CQ_Visc += CQ_Visc[iMarker]; + AllBound_HF_Visc += HF_Visc[iMarker]; + AllBound_MaxHF_Visc += pow(MaxHF_Visc[iMarker], MaxNorm); + + /*--- Compute the coefficients per surface ---*/ + + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { + Monitoring_Tag = config->GetMarker_Monitoring_TagBound(iMarker_Monitoring); + Marker_Tag = config->GetMarker_All_TagBound(iMarker); + if (Marker_Tag == Monitoring_Tag) { + Surface_CL_Visc[iMarker_Monitoring] += CL_Visc[iMarker]; + Surface_CD_Visc[iMarker_Monitoring] += CD_Visc[iMarker]; + Surface_CSF_Visc[iMarker_Monitoring] += CSF_Visc[iMarker]; + Surface_CEff_Visc[iMarker_Monitoring] += CEff_Visc[iMarker]; + Surface_CFx_Visc[iMarker_Monitoring] += CFx_Visc[iMarker]; + Surface_CFy_Visc[iMarker_Monitoring] += CFy_Visc[iMarker]; + Surface_CFz_Visc[iMarker_Monitoring] += CFz_Visc[iMarker]; + Surface_CMx_Visc[iMarker_Monitoring] += CMx_Visc[iMarker]; + Surface_CMy_Visc[iMarker_Monitoring] += CMy_Visc[iMarker]; + Surface_CMz_Visc[iMarker_Monitoring] += CMz_Visc[iMarker]; + Surface_HF_Visc[iMarker_Monitoring] += HF_Visc[iMarker]; + Surface_MaxHF_Visc[iMarker_Monitoring] += pow(MaxHF_Visc[iMarker],MaxNorm); + } + } + + } + + } + } + + /*--- Update some global coeffients ---*/ + + AllBound_CEff_Visc = AllBound_CL_Visc / (AllBound_CD_Visc + EPS); + AllBound_CMerit_Visc = AllBound_CT_Visc / (AllBound_CQ_Visc + EPS); + AllBound_MaxHF_Visc = pow(AllBound_MaxHF_Visc, 1.0/MaxNorm); + + +#ifdef HAVE_MPI + + /*--- Add AllBound information using all the nodes ---*/ + + MyAllBound_CD_Visc = AllBound_CD_Visc; AllBound_CD_Visc = 0.0; + MyAllBound_CL_Visc = AllBound_CL_Visc; AllBound_CL_Visc = 0.0; + MyAllBound_CSF_Visc = AllBound_CSF_Visc; AllBound_CSF_Visc = 0.0; + AllBound_CEff_Visc = 0.0; + MyAllBound_CMx_Visc = AllBound_CMx_Visc; AllBound_CMx_Visc = 0.0; + MyAllBound_CMy_Visc = AllBound_CMy_Visc; AllBound_CMy_Visc = 0.0; + MyAllBound_CMz_Visc = AllBound_CMz_Visc; AllBound_CMz_Visc = 0.0; + MyAllBound_CoPx_Visc = AllBound_CoPx_Visc; AllBound_CoPx_Visc = 0.0; + MyAllBound_CoPy_Visc = AllBound_CoPy_Visc; AllBound_CoPy_Visc = 0.0; + MyAllBound_CoPz_Visc = AllBound_CoPz_Visc; AllBound_CoPz_Visc = 0.0; + MyAllBound_CFx_Visc = AllBound_CFx_Visc; AllBound_CFx_Visc = 0.0; + MyAllBound_CFy_Visc = AllBound_CFy_Visc; AllBound_CFy_Visc = 0.0; + MyAllBound_CFz_Visc = AllBound_CFz_Visc; AllBound_CFz_Visc = 0.0; + MyAllBound_CT_Visc = AllBound_CT_Visc; AllBound_CT_Visc = 0.0; + MyAllBound_CQ_Visc = AllBound_CQ_Visc; AllBound_CQ_Visc = 0.0; + AllBound_CMerit_Visc = 0.0; + MyAllBound_HF_Visc = AllBound_HF_Visc; AllBound_HF_Visc = 0.0; + MyAllBound_MaxHF_Visc = pow(AllBound_MaxHF_Visc, MaxNorm); AllBound_MaxHF_Visc = 0.0; + + if (config->GetComm_Level() == COMM_FULL) { + SU2_MPI::Allreduce(&MyAllBound_CD_Visc, &AllBound_CD_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CL_Visc, &AllBound_CL_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CSF_Visc, &AllBound_CSF_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + AllBound_CEff_Visc = AllBound_CL_Visc / (AllBound_CD_Visc + EPS); + SU2_MPI::Allreduce(&MyAllBound_CMx_Visc, &AllBound_CMx_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CMy_Visc, &AllBound_CMy_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CMz_Visc, &AllBound_CMz_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CFx_Visc, &AllBound_CFx_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CFy_Visc, &AllBound_CFy_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CFz_Visc, &AllBound_CFz_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CoPx_Visc, &AllBound_CoPx_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CoPy_Visc, &AllBound_CoPy_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CoPz_Visc, &AllBound_CoPz_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CT_Visc, &AllBound_CT_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_CQ_Visc, &AllBound_CQ_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + AllBound_CMerit_Visc = AllBound_CT_Visc / (AllBound_CQ_Visc + EPS); + SU2_MPI::Allreduce(&MyAllBound_HF_Visc, &AllBound_HF_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyAllBound_MaxHF_Visc, &AllBound_MaxHF_Visc, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + AllBound_MaxHF_Visc = pow(AllBound_MaxHF_Visc, 1.0/MaxNorm); + } + + /*--- Add the forces on the surfaces using all the nodes ---*/ + + MySurface_CL_Visc = new su2double[config->GetnMarker_Monitoring()]; + MySurface_CD_Visc = new su2double[config->GetnMarker_Monitoring()]; + MySurface_CSF_Visc = new su2double[config->GetnMarker_Monitoring()]; + MySurface_CEff_Visc = new su2double[config->GetnMarker_Monitoring()]; + MySurface_CFx_Visc = new su2double[config->GetnMarker_Monitoring()]; + MySurface_CFy_Visc = new su2double[config->GetnMarker_Monitoring()]; + MySurface_CFz_Visc = new su2double[config->GetnMarker_Monitoring()]; + MySurface_CMx_Visc = new su2double[config->GetnMarker_Monitoring()]; + MySurface_CMy_Visc = new su2double[config->GetnMarker_Monitoring()]; + MySurface_CMz_Visc = new su2double[config->GetnMarker_Monitoring()]; + MySurface_HF_Visc = new su2double[config->GetnMarker_Monitoring()]; + MySurface_MaxHF_Visc = new su2double[config->GetnMarker_Monitoring()]; + + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { + + MySurface_CL_Visc[iMarker_Monitoring] = Surface_CL_Visc[iMarker_Monitoring]; + MySurface_CD_Visc[iMarker_Monitoring] = Surface_CD_Visc[iMarker_Monitoring]; + MySurface_CSF_Visc[iMarker_Monitoring] = Surface_CSF_Visc[iMarker_Monitoring]; + MySurface_CEff_Visc[iMarker_Monitoring] = Surface_CEff_Visc[iMarker_Monitoring]; + MySurface_CFx_Visc[iMarker_Monitoring] = Surface_CFx_Visc[iMarker_Monitoring]; + MySurface_CFy_Visc[iMarker_Monitoring] = Surface_CFy_Visc[iMarker_Monitoring]; + MySurface_CFz_Visc[iMarker_Monitoring] = Surface_CFz_Visc[iMarker_Monitoring]; + MySurface_CMx_Visc[iMarker_Monitoring] = Surface_CMx_Visc[iMarker_Monitoring]; + MySurface_CMy_Visc[iMarker_Monitoring] = Surface_CMy_Visc[iMarker_Monitoring]; + MySurface_CMz_Visc[iMarker_Monitoring] = Surface_CMz_Visc[iMarker_Monitoring]; + MySurface_HF_Visc[iMarker_Monitoring] = Surface_HF_Visc[iMarker_Monitoring]; + MySurface_MaxHF_Visc[iMarker_Monitoring] = Surface_MaxHF_Visc[iMarker_Monitoring]; + + Surface_CL_Visc[iMarker_Monitoring] = 0.0; + Surface_CD_Visc[iMarker_Monitoring] = 0.0; + Surface_CSF_Visc[iMarker_Monitoring] = 0.0; + Surface_CEff_Visc[iMarker_Monitoring] = 0.0; + Surface_CFx_Visc[iMarker_Monitoring] = 0.0; + Surface_CFy_Visc[iMarker_Monitoring] = 0.0; + Surface_CFz_Visc[iMarker_Monitoring] = 0.0; + Surface_CMx_Visc[iMarker_Monitoring] = 0.0; + Surface_CMy_Visc[iMarker_Monitoring] = 0.0; + Surface_CMz_Visc[iMarker_Monitoring] = 0.0; + Surface_HF_Visc[iMarker_Monitoring] = 0.0; + Surface_MaxHF_Visc[iMarker_Monitoring] = 0.0; + } + + if (config->GetComm_Level() == COMM_FULL) { + SU2_MPI::Allreduce(MySurface_CL_Visc, Surface_CL_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(MySurface_CD_Visc, Surface_CD_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(MySurface_CSF_Visc, Surface_CSF_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) + Surface_CEff_Visc[iMarker_Monitoring] = Surface_CL_Visc[iMarker_Monitoring] / (Surface_CD_Visc[iMarker_Monitoring] + EPS); + SU2_MPI::Allreduce(MySurface_CFx_Visc, Surface_CFx_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(MySurface_CFy_Visc, Surface_CFy_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(MySurface_CFz_Visc, Surface_CFz_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(MySurface_CMx_Visc, Surface_CMx_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(MySurface_CMy_Visc, Surface_CMy_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(MySurface_CMz_Visc, Surface_CMz_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(MySurface_HF_Visc, Surface_HF_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(MySurface_MaxHF_Visc, Surface_MaxHF_Visc, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + } + + delete [] MySurface_CL_Visc; delete [] MySurface_CD_Visc; delete [] MySurface_CSF_Visc; + delete [] MySurface_CEff_Visc; delete [] MySurface_CFx_Visc; delete [] MySurface_CFy_Visc; + delete [] MySurface_CFz_Visc; delete [] MySurface_CMx_Visc; delete [] MySurface_CMy_Visc; + delete [] MySurface_CMz_Visc; delete [] MySurface_HF_Visc; delete [] MySurface_MaxHF_Visc; + +#endif + + /*--- Update the total coefficients (note that all the nodes have the same value)---*/ + + Total_CD += AllBound_CD_Visc; + Total_CL += AllBound_CL_Visc; + Total_CSF += AllBound_CSF_Visc; + Total_CEff = Total_CL / (Total_CD + EPS); + Total_CFx += AllBound_CFx_Visc; + Total_CFy += AllBound_CFy_Visc; + Total_CFz += AllBound_CFz_Visc; + Total_CMx += AllBound_CMx_Visc; + Total_CMy += AllBound_CMy_Visc; + Total_CMz += AllBound_CMz_Visc; + Total_CoPx += AllBound_CoPx_Visc; + Total_CoPy += AllBound_CoPy_Visc; + Total_CoPz += AllBound_CoPz_Visc; + Total_CT += AllBound_CT_Visc; + Total_CQ += AllBound_CQ_Visc; + Total_CMerit = AllBound_CT_Visc / (AllBound_CQ_Visc + EPS); + Total_Heat = AllBound_HF_Visc; + Total_MaxHeat = AllBound_MaxHF_Visc; + + /*--- Update the total coefficients per surface (note that all the nodes have the same value)---*/ + + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { + Surface_CL[iMarker_Monitoring] += Surface_CL_Visc[iMarker_Monitoring]; + Surface_CD[iMarker_Monitoring] += Surface_CD_Visc[iMarker_Monitoring]; + Surface_CSF[iMarker_Monitoring] += Surface_CSF_Visc[iMarker_Monitoring]; + Surface_CEff[iMarker_Monitoring] = Surface_CL[iMarker_Monitoring] / (Surface_CD[iMarker_Monitoring] + EPS); + Surface_CFx[iMarker_Monitoring] += Surface_CFx_Visc[iMarker_Monitoring]; + Surface_CFy[iMarker_Monitoring] += Surface_CFy_Visc[iMarker_Monitoring]; + Surface_CFz[iMarker_Monitoring] += Surface_CFz_Visc[iMarker_Monitoring]; + Surface_CMx[iMarker_Monitoring] += Surface_CMx_Visc[iMarker_Monitoring]; + Surface_CMy[iMarker_Monitoring] += Surface_CMy_Visc[iMarker_Monitoring]; + Surface_CMz[iMarker_Monitoring] += Surface_CMz_Visc[iMarker_Monitoring]; + } + +} + +void CNSSolver::Buffet_Monitoring(CGeometry *geometry, CConfig *config) { + + unsigned long iVertex; + unsigned short Boundary, Monitoring, iMarker, iMarker_Monitoring, iDim; + su2double *Vel_FS = config->GetVelocity_FreeStream(); + su2double VelMag_FS = 0.0, SkinFrictionMag = 0.0, SkinFrictionDot = 0.0, *Normal, Area, Sref = config->GetRefArea(); + su2double k = config->GetBuffet_k(), + lam = config->GetBuffet_lambda(); + string Marker_Tag, Monitoring_Tag; + + for (iDim = 0; iDim < nDim; iDim++){ + VelMag_FS += Vel_FS[iDim]*Vel_FS[iDim]; + } + VelMag_FS = sqrt(VelMag_FS); + + /*-- Variables initialization ---*/ + + Total_Buffet_Metric = 0.0; + + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { + Surface_Buffet_Metric[iMarker_Monitoring] = 0.0; + } + + /*--- Loop over the Euler and Navier-Stokes markers ---*/ + + for (iMarker = 0; iMarker < nMarker; iMarker++) { + + Buffet_Metric[iMarker] = 0.0; + + Boundary = config->GetMarker_All_KindBC(iMarker); + Monitoring = config->GetMarker_All_Monitoring(iMarker); + + if ((Boundary == HEAT_FLUX) || (Boundary == ISOTHERMAL) || (Boundary == HEAT_FLUX) || (Boundary == CHT_WALL_INTERFACE)) { + + /*--- Loop over the vertices to compute the buffet sensor ---*/ + + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + + /*--- Perform dot product of skin friction with freestream velocity ---*/ + + SkinFrictionMag = 0.0; + SkinFrictionDot = 0.0; + for(iDim = 0; iDim < nDim; iDim++){ + SkinFrictionMag += CSkinFriction[iMarker][iDim][iVertex]*CSkinFriction[iMarker][iDim][iVertex]; + SkinFrictionDot += CSkinFriction[iMarker][iDim][iVertex]*Vel_FS[iDim]; + } + SkinFrictionMag = sqrt(SkinFrictionMag); + + /*--- Normalize the dot product ---*/ + + SkinFrictionDot /= SkinFrictionMag*VelMag_FS; + + /*--- Compute Heaviside function ---*/ + + Buffet_Sensor[iMarker][iVertex] = 1./(1. + exp(2.*k*(SkinFrictionDot + lam))); + + /*--- Integrate buffet sensor ---*/ + + if(Monitoring == YES){ + + Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); + Area = 0.0; + for(iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; + Area = sqrt(Area); + + Buffet_Metric[iMarker] += Buffet_Sensor[iMarker][iVertex]*Area/Sref; + + } + + } + + if(Monitoring == YES){ + + Total_Buffet_Metric += Buffet_Metric[iMarker]; + + /*--- Per surface buffet metric ---*/ + + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { + Monitoring_Tag = config->GetMarker_Monitoring_TagBound(iMarker_Monitoring); + Marker_Tag = config->GetMarker_All_TagBound(iMarker); + if (Marker_Tag == Monitoring_Tag) Surface_Buffet_Metric[iMarker_Monitoring] = Buffet_Metric[iMarker]; + } + + } + + } + + } + +#ifdef HAVE_MPI + + /*--- Add buffet metric information using all the nodes ---*/ + + su2double MyTotal_Buffet_Metric = Total_Buffet_Metric; + Total_Buffet_Metric = 0.0; + + SU2_MPI::Allreduce(&MyTotal_Buffet_Metric, &Total_Buffet_Metric, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + + /*--- Add the buffet metric on the surfaces using all the nodes ---*/ + + su2double *MySurface_Buffet_Metric = new su2double[config->GetnMarker_Monitoring()]; + + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { + + MySurface_Buffet_Metric[iMarker_Monitoring] = Surface_Buffet_Metric[iMarker_Monitoring]; + Surface_Buffet_Metric[iMarker_Monitoring] = 0.0; + + } + + SU2_MPI::Allreduce(MySurface_Buffet_Metric, Surface_Buffet_Metric, config->GetnMarker_Monitoring(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + + delete [] MySurface_Buffet_Metric; + +#endif + +} + +void CNSSolver::Evaluate_ObjFunc(CConfig *config) { + + unsigned short iMarker_Monitoring, Kind_ObjFunc; + su2double Weight_ObjFunc; + + /*--- Evaluate objective functions common to Euler and NS solvers ---*/ + + CEulerSolver::Evaluate_ObjFunc(config); + + /*--- Evaluate objective functions specific to NS solver ---*/ + + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { + + Weight_ObjFunc = config->GetWeight_ObjFunc(iMarker_Monitoring); + Kind_ObjFunc = config->GetKind_ObjFunc(iMarker_Monitoring); + + switch(Kind_ObjFunc) { + case BUFFET_SENSOR: + Total_ComboObj +=Weight_ObjFunc*Surface_Buffet_Metric[iMarker_Monitoring]; + break; + default: + break; + } + } + +} + + +void CNSSolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { + + unsigned short iDim, jDim, iVar, jVar; + unsigned long iVertex, iPoint, Point_Normal, total_index; + + su2double Wall_HeatFlux, dist_ij, *Coord_i, *Coord_j, theta2; + su2double thetax, thetay, thetaz, etax, etay, etaz, pix, piy, piz, factor; + su2double ProjGridVel, *GridVel, GridVel2, *Normal, Area, Pressure = 0.0; + su2double total_viscosity, div_vel, Density, tau_vel[3] = {0.0, 0.0, 0.0}, UnitNormal[3] = {0.0, 0.0, 0.0}; + su2double laminar_viscosity = 0.0, eddy_viscosity = 0.0, Grad_Vel[3][3] = {{0.0,0.0,0.0},{0.0,0.0,0.0},{0.0,0.0,0.0}}, + tau[3][3] = {{0.0,0.0,0.0},{0.0,0.0,0.0},{0.0,0.0,0.0}}; + su2double delta[3][3] = {{1.0, 0.0, 0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}}; + + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + + /*--- Identify the boundary by string name ---*/ + + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); + + /*--- Get the specified wall heat flux from config as well as the + wall function treatment.---*/ + + Wall_HeatFlux = config->GetWall_HeatFlux(Marker_Tag)/config->GetHeat_Flux_Ref(); + +// Wall_Function = config->GetWallFunction_Treatment(Marker_Tag); +// if (Wall_Function != NO_WALL_FUNCTION) { +// SU2_MPI::Error("Wall function treament not implemented yet", CURRENT_FUNCTION); +// } + + /*--- Loop over all of the vertices on this boundary marker ---*/ + + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); + + /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ + + if (geometry->node[iPoint]->GetDomain()) { + + /*--- If it is a customizable patch, retrieve the specified wall heat flux. ---*/ + + if (config->GetMarker_All_PyCustom(val_marker)) Wall_HeatFlux = geometry->GetCustomBoundaryHeatFlux(val_marker, iVertex); + + /*--- Compute dual-grid area and boundary normal ---*/ + + Normal = geometry->vertex[val_marker][iVertex]->GetNormal(); + + Area = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + Area += Normal[iDim]*Normal[iDim]; + Area = sqrt (Area); + + for (iDim = 0; iDim < nDim; iDim++) + UnitNormal[iDim] = -Normal[iDim]/Area; + + /*--- Initialize the convective & viscous residuals to zero ---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + Res_Conv[iVar] = 0.0; + Res_Visc[iVar] = 0.0; + } + + /*--- Store the corrected velocity at the wall which will + be zero (v = 0), unless there are moving walls (v = u_wall)---*/ + + if (dynamic_grid) { + GridVel = geometry->node[iPoint]->GetGridVel(); + for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = GridVel[iDim]; + } else { + for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = 0.0; + } + + /*--- Impose the value of the velocity as a strong boundary + condition (Dirichlet). Fix the velocity and remove any + contribution to the residual at this node. ---*/ + + nodes->SetVelocity_Old(iPoint,Vector); + + for (iDim = 0; iDim < nDim; iDim++) + LinSysRes.SetBlock_Zero(iPoint, iDim+1); + nodes->SetVel_ResTruncError_Zero(iPoint); + + /*--- Apply a weak boundary condition for the energy equation. + Compute the residual due to the prescribed heat flux. ---*/ + + Res_Visc[nDim+1] = Wall_HeatFlux * Area; + + /*--- If the wall is moving, there are additional residual contributions + due to pressure (p v_wall.n) and shear stress (tau.v_wall.n). ---*/ + + if (dynamic_grid) { + + /*--- Get the grid velocity at the current boundary node ---*/ + + GridVel = geometry->node[iPoint]->GetGridVel(); + ProjGridVel = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + ProjGridVel += GridVel[iDim]*UnitNormal[iDim]*Area; + + /*--- Retrieve other primitive quantities and viscosities ---*/ + + Density = nodes->GetDensity(iPoint); + Pressure = nodes->GetPressure(iPoint); + laminar_viscosity = nodes->GetLaminarViscosity(iPoint); + eddy_viscosity = nodes->GetEddyViscosity(iPoint); + total_viscosity = laminar_viscosity + eddy_viscosity; + + for (iDim = 0; iDim < nDim; iDim++) { + for (jDim = 0 ; jDim < nDim; jDim++) { + Grad_Vel[iDim][jDim] = nodes->GetGradient_Primitive(iPoint,iDim+1, jDim); + } + } + + /*--- Divergence of the velocity ---*/ + + div_vel = 0.0; for (iDim = 0 ; iDim < nDim; iDim++) div_vel += Grad_Vel[iDim][iDim]; + + /*--- Compute the viscous stress tensor ---*/ + + for (iDim = 0; iDim < nDim; iDim++) { + for (jDim = 0; jDim < nDim; jDim++) { + tau[iDim][jDim] = total_viscosity*( Grad_Vel[jDim][iDim]+Grad_Vel[iDim][jDim] ) - TWO3*total_viscosity*div_vel*delta[iDim][jDim]; + } + } + + /*--- Dot product of the stress tensor with the grid velocity ---*/ + + for (iDim = 0 ; iDim < nDim; iDim++) { + tau_vel[iDim] = 0.0; + for (jDim = 0 ; jDim < nDim; jDim++) + tau_vel[iDim] += tau[iDim][jDim]*GridVel[jDim]; + } + + /*--- Compute the convective and viscous residuals (energy eqn.) ---*/ + + Res_Conv[nDim+1] = Pressure*ProjGridVel; + for (iDim = 0 ; iDim < nDim; iDim++) + Res_Visc[nDim+1] += tau_vel[iDim]*UnitNormal[iDim]*Area; + + /*--- Implicit Jacobian contributions due to moving walls ---*/ + + if (implicit) { + + /*--- Jacobian contribution related to the pressure term ---*/ + + GridVel2 = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + GridVel2 += GridVel[iDim]*GridVel[iDim]; + for (iVar = 0; iVar < nVar; iVar++) + for (jVar = 0; jVar < nVar; jVar++) + Jacobian_i[iVar][jVar] = 0.0; + Jacobian_i[nDim+1][0] = 0.5*(Gamma-1.0)*GridVel2*ProjGridVel; + for (jDim = 0; jDim < nDim; jDim++) + Jacobian_i[nDim+1][jDim+1] = -(Gamma-1.0)*GridVel[jDim]*ProjGridVel; + Jacobian_i[nDim+1][nDim+1] = (Gamma-1.0)*ProjGridVel; + + /*--- Add the block to the Global Jacobian structure ---*/ + + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); + + /*--- Now the Jacobian contribution related to the shear stress ---*/ + + for (iVar = 0; iVar < nVar; iVar++) + for (jVar = 0; jVar < nVar; jVar++) + Jacobian_i[iVar][jVar] = 0.0; + + /*--- Compute closest normal neighbor ---*/ + + Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); + + /*--- Get coordinates of i & nearest normal and compute distance ---*/ + + Coord_i = geometry->node[iPoint]->GetCoord(); + Coord_j = geometry->node[Point_Normal]->GetCoord(); + + dist_ij = 0; + for (iDim = 0; iDim < nDim; iDim++) + dist_ij += (Coord_j[iDim]-Coord_i[iDim])*(Coord_j[iDim]-Coord_i[iDim]); + dist_ij = sqrt(dist_ij); + + theta2 = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + theta2 += UnitNormal[iDim]*UnitNormal[iDim]; + + factor = total_viscosity*Area/(Density*dist_ij); + + if (nDim == 2) { + thetax = theta2 + UnitNormal[0]*UnitNormal[0]/3.0; + thetay = theta2 + UnitNormal[1]*UnitNormal[1]/3.0; + + etaz = UnitNormal[0]*UnitNormal[1]/3.0; + + pix = GridVel[0]*thetax + GridVel[1]*etaz; + piy = GridVel[0]*etaz + GridVel[1]*thetay; + + Jacobian_i[nDim+1][0] -= factor*(-pix*GridVel[0]+piy*GridVel[1]); + Jacobian_i[nDim+1][1] -= factor*pix; + Jacobian_i[nDim+1][2] -= factor*piy; + } else { + thetax = theta2 + UnitNormal[0]*UnitNormal[0]/3.0; + thetay = theta2 + UnitNormal[1]*UnitNormal[1]/3.0; + thetaz = theta2 + UnitNormal[2]*UnitNormal[2]/3.0; + + etaz = UnitNormal[0]*UnitNormal[1]/3.0; + etax = UnitNormal[1]*UnitNormal[2]/3.0; + etay = UnitNormal[0]*UnitNormal[2]/3.0; + + pix = GridVel[0]*thetax + GridVel[1]*etaz + GridVel[2]*etay; + piy = GridVel[0]*etaz + GridVel[1]*thetay + GridVel[2]*etax; + piz = GridVel[0]*etay + GridVel[1]*etax + GridVel[2]*thetaz; + + Jacobian_i[nDim+1][0] -= factor*(-pix*GridVel[0]+piy*GridVel[1]+piz*GridVel[2]); + Jacobian_i[nDim+1][1] -= factor*pix; + Jacobian_i[nDim+1][2] -= factor*piy; + Jacobian_i[nDim+1][3] -= factor*piz; + } + + /*--- Subtract the block from the Global Jacobian structure ---*/ + + Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); + + } + } + + /*--- Convective contribution to the residual at the wall ---*/ + + LinSysRes.AddBlock(iPoint, Res_Conv); + + /*--- Viscous contribution to the residual at the wall ---*/ + + LinSysRes.SubtractBlock(iPoint, Res_Visc); + + /*--- Enforce the no-slip boundary condition in a strong way by + modifying the velocity-rows of the Jacobian (1 on the diagonal). ---*/ + + if (implicit) { + for (iVar = 1; iVar <= nDim; iVar++) { + total_index = iPoint*nVar+iVar; + Jacobian.DeleteValsRowi(total_index); + } + } + + } + } +} + +void CNSSolver::BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { + + unsigned short iVar, jVar, iDim, jDim; + unsigned long iVertex, iPoint, Point_Normal, total_index; + + su2double *Normal, *Coord_i, *Coord_j, Area, dist_ij, theta2; + su2double Twall, dTdn, dTdrho, thermal_conductivity; + su2double thetax, thetay, thetaz, etax, etay, etaz, pix, piy, piz, factor; + su2double ProjGridVel, *GridVel, GridVel2, Pressure = 0.0, Density, Vel2; + su2double total_viscosity, div_vel, tau_vel[3] = {0.0,0.0,0.0}, UnitNormal[3] = {0.0,0.0,0.0}; + su2double laminar_viscosity, eddy_viscosity, Grad_Vel[3][3] = {{1.0, 0.0, 0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}}, + tau[3][3] = {{0.0, 0.0, 0.0},{0.0,0.0,0.0},{0.0,0.0,0.0}}, delta[3][3] = {{1.0, 0.0, 0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}}; + + su2double Prandtl_Lam = config->GetPrandtl_Lam(); + su2double Prandtl_Turb = config->GetPrandtl_Turb(); + su2double Gas_Constant = config->GetGas_ConstantND(); + su2double Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; + + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + + /*--- Identify the boundary ---*/ + + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); + + /*--- Retrieve the specified wall temperature from config + as well as the wall function treatment.---*/ + + Twall = config->GetIsothermal_Temperature(Marker_Tag)/config->GetTemperature_Ref(); + +// Wall_Function = config->GetWallFunction_Treatment(Marker_Tag); +// if (Wall_Function != NO_WALL_FUNCTION) { +// SU2_MPI::Error("Wall function treament not implemented yet", CURRENT_FUNCTION); +// } + + /*--- Loop over boundary points ---*/ + + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { + + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); + + if (geometry->node[iPoint]->GetDomain()) { + + /*--- If it is a customizable patch, retrieve the specified wall temperature. ---*/ + + if (config->GetMarker_All_PyCustom(val_marker)) Twall = geometry->GetCustomBoundaryTemperature(val_marker, iVertex); + + /*--- Compute dual-grid area and boundary normal ---*/ + + Normal = geometry->vertex[val_marker][iVertex]->GetNormal(); + + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt (Area); + + for (iDim = 0; iDim < nDim; iDim++) + UnitNormal[iDim] = -Normal[iDim]/Area; + + /*--- Calculate useful quantities ---*/ + + theta2 = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + theta2 += UnitNormal[iDim]*UnitNormal[iDim]; + + /*--- Compute closest normal neighbor ---*/ + + Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); + + /*--- Get coordinates of i & nearest normal and compute distance ---*/ + + Coord_i = geometry->node[iPoint]->GetCoord(); + Coord_j = geometry->node[Point_Normal]->GetCoord(); + dist_ij = 0; + for (iDim = 0; iDim < nDim; iDim++) + dist_ij += (Coord_j[iDim]-Coord_i[iDim])*(Coord_j[iDim]-Coord_i[iDim]); + dist_ij = sqrt(dist_ij); + + /*--- Store the corrected velocity at the wall which will + be zero (v = 0), unless there is grid motion (v = u_wall)---*/ + + if (dynamic_grid) { + GridVel = geometry->node[iPoint]->GetGridVel(); + for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = GridVel[iDim]; + } + else { + for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = 0.0; + } + + /*--- Initialize the convective & viscous residuals to zero ---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + Res_Conv[iVar] = 0.0; + Res_Visc[iVar] = 0.0; + } + + /*--- Set the residual, truncation error and velocity value on the boundary ---*/ + + nodes->SetVelocity_Old(iPoint,Vector); + + for (iDim = 0; iDim < nDim; iDim++) + LinSysRes.SetBlock_Zero(iPoint, iDim+1); + nodes->SetVel_ResTruncError_Zero(iPoint); + + /*--- Compute the normal gradient in temperature using Twall ---*/ + + dTdn = -(nodes->GetTemperature(Point_Normal) - Twall)/dist_ij; + + /*--- Get transport coefficients ---*/ + + laminar_viscosity = nodes->GetLaminarViscosity(iPoint); + eddy_viscosity = nodes->GetEddyViscosity(iPoint); + thermal_conductivity = Cp * ( laminar_viscosity/Prandtl_Lam + eddy_viscosity/Prandtl_Turb); + + // work in progress on real-gases... + //thermal_conductivity = nodes->GetThermalConductivity(iPoint); + //Cp = nodes->GetSpecificHeatCp(iPoint); + //thermal_conductivity += Cp*eddy_viscosity/Prandtl_Turb; + + /*--- Apply a weak boundary condition for the energy equation. + Compute the residual due to the prescribed heat flux. ---*/ + + Res_Visc[nDim+1] = thermal_conductivity * dTdn * Area; + + /*--- Calculate Jacobian for implicit time stepping ---*/ + + if (implicit) { + + for (iVar = 0; iVar < nVar; iVar ++) + for (jVar = 0; jVar < nVar; jVar ++) + Jacobian_i[iVar][jVar] = 0.0; + + /*--- Calculate useful quantities ---*/ + + Density = nodes->GetDensity(iPoint); + Vel2 = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + Vel2 += pow(nodes->GetVelocity(iPoint,iDim),2); + dTdrho = 1.0/Density * ( -Twall + (Gamma-1.0)/Gas_Constant*(Vel2/2.0) ); + + /*--- Enforce the no-slip boundary condition in a strong way ---*/ + + for (iVar = 1; iVar <= nDim; iVar++) { + total_index = iPoint*nVar+iVar; + Jacobian.DeleteValsRowi(total_index); + } + + /*--- Add contributions to the Jacobian from the weak enforcement of the energy equations ---*/ + + Jacobian_i[nDim+1][0] = -thermal_conductivity*theta2/dist_ij * dTdrho * Area; + Jacobian_i[nDim+1][nDim+1] = -thermal_conductivity*theta2/dist_ij * (Gamma-1.0)/(Gas_Constant*Density) * Area; + + /*--- Subtract the block from the Global Jacobian structure ---*/ + + Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); + + } + + /*--- If the wall is moving, there are additional residual contributions + due to pressure (p v_wall.n) and shear stress (tau.v_wall.n). ---*/ + + if (dynamic_grid) { + + /*--- Get the grid velocity at the current boundary node ---*/ + + GridVel = geometry->node[iPoint]->GetGridVel(); + ProjGridVel = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + ProjGridVel += GridVel[iDim]*UnitNormal[iDim]*Area; + + /*--- Retrieve other primitive quantities and viscosities ---*/ + + Density = nodes->GetDensity(iPoint); + Pressure = nodes->GetPressure(iPoint); + laminar_viscosity = nodes->GetLaminarViscosity(iPoint); + eddy_viscosity = nodes->GetEddyViscosity(iPoint); + + total_viscosity = laminar_viscosity + eddy_viscosity; + + for (iDim = 0; iDim < nDim; iDim++) { + for (jDim = 0 ; jDim < nDim; jDim++) { + Grad_Vel[iDim][jDim] = nodes->GetGradient_Primitive(iPoint,iDim+1, jDim); + } + } + + /*--- Divergence of the velocity ---*/ + + div_vel = 0.0; for (iDim = 0 ; iDim < nDim; iDim++) div_vel += Grad_Vel[iDim][iDim]; + + /*--- Compute the viscous stress tensor ---*/ + + for (iDim = 0; iDim < nDim; iDim++) + for (jDim = 0; jDim < nDim; jDim++) { + tau[iDim][jDim] = total_viscosity*( Grad_Vel[jDim][iDim] + Grad_Vel[iDim][jDim] ) - TWO3*total_viscosity*div_vel*delta[iDim][jDim]; + } + + /*--- Dot product of the stress tensor with the grid velocity ---*/ + + for (iDim = 0 ; iDim < nDim; iDim++) { + tau_vel[iDim] = 0.0; + for (jDim = 0 ; jDim < nDim; jDim++) + tau_vel[iDim] += tau[iDim][jDim]*GridVel[jDim]; + } + + /*--- Compute the convective and viscous residuals (energy eqn.) ---*/ + + Res_Conv[nDim+1] = Pressure*ProjGridVel; + for (iDim = 0 ; iDim < nDim; iDim++) + Res_Visc[nDim+1] += tau_vel[iDim]*UnitNormal[iDim]*Area; + + /*--- Implicit Jacobian contributions due to moving walls ---*/ + + if (implicit) { + + /*--- Jacobian contribution related to the pressure term ---*/ + + GridVel2 = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + GridVel2 += GridVel[iDim]*GridVel[iDim]; + for (iVar = 0; iVar < nVar; iVar++) + for (jVar = 0; jVar < nVar; jVar++) + Jacobian_i[iVar][jVar] = 0.0; + + Jacobian_i[nDim+1][0] = 0.5*(Gamma-1.0)*GridVel2*ProjGridVel; + for (jDim = 0; jDim < nDim; jDim++) + Jacobian_i[nDim+1][jDim+1] = -(Gamma-1.0)*GridVel[jDim]*ProjGridVel; + Jacobian_i[nDim+1][nDim+1] = (Gamma-1.0)*ProjGridVel; + + /*--- Add the block to the Global Jacobian structure ---*/ + + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); + + /*--- Now the Jacobian contribution related to the shear stress ---*/ + + for (iVar = 0; iVar < nVar; iVar++) + for (jVar = 0; jVar < nVar; jVar++) + Jacobian_i[iVar][jVar] = 0.0; + + factor = total_viscosity*Area/(Density*dist_ij); + + if (nDim == 2) { + thetax = theta2 + UnitNormal[0]*UnitNormal[0]/3.0; + thetay = theta2 + UnitNormal[1]*UnitNormal[1]/3.0; + + etaz = UnitNormal[0]*UnitNormal[1]/3.0; + + pix = GridVel[0]*thetax + GridVel[1]*etaz; + piy = GridVel[0]*etaz + GridVel[1]*thetay; + + Jacobian_i[nDim+1][0] -= factor*(-pix*GridVel[0]+piy*GridVel[1]); + Jacobian_i[nDim+1][1] -= factor*pix; + Jacobian_i[nDim+1][2] -= factor*piy; + } + else { + thetax = theta2 + UnitNormal[0]*UnitNormal[0]/3.0; + thetay = theta2 + UnitNormal[1]*UnitNormal[1]/3.0; + thetaz = theta2 + UnitNormal[2]*UnitNormal[2]/3.0; + + etaz = UnitNormal[0]*UnitNormal[1]/3.0; + etax = UnitNormal[1]*UnitNormal[2]/3.0; + etay = UnitNormal[0]*UnitNormal[2]/3.0; + + pix = GridVel[0]*thetax + GridVel[1]*etaz + GridVel[2]*etay; + piy = GridVel[0]*etaz + GridVel[1]*thetay + GridVel[2]*etax; + piz = GridVel[0]*etay + GridVel[1]*etax + GridVel[2]*thetaz; + + Jacobian_i[nDim+1][0] -= factor*(-pix*GridVel[0]+piy*GridVel[1]+piz*GridVel[2]); + Jacobian_i[nDim+1][1] -= factor*pix; + Jacobian_i[nDim+1][2] -= factor*piy; + Jacobian_i[nDim+1][3] -= factor*piz; + } + + /*--- Subtract the block from the Global Jacobian structure ---*/ + + Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); + } + + } + + /*--- Convective contribution to the residual at the wall ---*/ + + LinSysRes.AddBlock(iPoint, Res_Conv); + + /*--- Viscous contribution to the residual at the wall ---*/ + + LinSysRes.SubtractBlock(iPoint, Res_Visc); + + /*--- Enforce the no-slip boundary condition in a strong way by + modifying the velocity-rows of the Jacobian (1 on the diagonal). ---*/ + + if (implicit) { + for (iVar = 1; iVar <= nDim; iVar++) { + total_index = iPoint*nVar+iVar; + Jacobian.DeleteValsRowi(total_index); + } + } + + } + } +} + +void CNSSolver::SetRoe_Dissipation(CGeometry *geometry, CConfig *config){ + + unsigned long iPoint; + su2double wall_distance; + + unsigned short kind_roe_dissipation = config->GetKind_RoeLowDiss(); + + for (iPoint = 0; iPoint < nPoint; iPoint++){ + + if (kind_roe_dissipation == FD || kind_roe_dissipation == FD_DUCROS){ + + wall_distance = geometry->node[iPoint]->GetWall_Distance(); + + nodes->SetRoe_Dissipation_FD(iPoint,wall_distance); + + } else if (kind_roe_dissipation == NTS || kind_roe_dissipation == NTS_DUCROS) { + + const su2double delta = geometry->node[iPoint]->GetMaxLength(); + assert(delta > 0); // Delta must be initialized and non-negative + nodes->SetRoe_Dissipation_NTS(iPoint,delta, config->GetConst_DES()); + } + } +} + +void CNSSolver::BC_ConjugateHeat_Interface(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, + CConfig *config, unsigned short val_marker) { + + unsigned short iVar, jVar, iDim, jDim; + unsigned long iVertex, iPoint, Point_Normal, total_index; + + su2double *Normal, *Coord_i, *Coord_j, Area, dist_ij, theta2; + su2double Twall= 0.0, There, dTdn= 0.0, dTdrho, thermal_conductivity, Tconjugate, HF_FactorHere, HF_FactorConjugate; + su2double thetax, thetay, thetaz, etax, etay, etaz, pix, piy, piz, factor; + su2double ProjGridVel, *GridVel, GridVel2, Pressure = 0.0, Density, Vel2; + su2double total_viscosity, div_vel, tau_vel[3] = {0.0,0.0,0.0}, UnitNormal[3] = {0.0,0.0,0.0}; + su2double laminar_viscosity, eddy_viscosity, Grad_Vel[3][3] = {{1.0, 0.0, 0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}}, + tau[3][3] = {{0.0, 0.0, 0.0},{0.0,0.0,0.0},{0.0,0.0,0.0}}, delta[3][3] = {{1.0, 0.0, 0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}}; + + su2double Prandtl_Lam = config->GetPrandtl_Lam(); + su2double Prandtl_Turb = config->GetPrandtl_Turb(); + su2double Gas_Constant = config->GetGas_ConstantND(); + su2double Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; + + su2double Temperature_Ref = config->GetTemperature_Ref(); + + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + + /*--- Identify the boundary ---*/ + + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); + +// /*--- Retrieve the specified wall function treatment.---*/ +// +// Wall_Function = config->GetWallFunction_Treatment(Marker_Tag); +// if (Wall_Function != NO_WALL_FUNCTION) { +// SU2_MPI::Error("Wall function treament not implemented yet", CURRENT_FUNCTION); +// } + + /*--- Loop over boundary points ---*/ + + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { + + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); + + if (geometry->node[iPoint]->GetDomain()) { + + /*--- Compute dual-grid area and boundary normal ---*/ + + Normal = geometry->vertex[val_marker][iVertex]->GetNormal(); + + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt (Area); + + for (iDim = 0; iDim < nDim; iDim++) + UnitNormal[iDim] = -Normal[iDim]/Area; + + /*--- Calculate useful quantities ---*/ + + theta2 = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + theta2 += UnitNormal[iDim]*UnitNormal[iDim]; + + /*--- Compute closest normal neighbor ---*/ + + Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); + + /*--- Get coordinates of i & nearest normal and compute distance ---*/ + + Coord_i = geometry->node[iPoint]->GetCoord(); + Coord_j = geometry->node[Point_Normal]->GetCoord(); + dist_ij = 0; + for (iDim = 0; iDim < nDim; iDim++) + dist_ij += (Coord_j[iDim]-Coord_i[iDim])*(Coord_j[iDim]-Coord_i[iDim]); + dist_ij = sqrt(dist_ij); + + /*--- Store the corrected velocity at the wall which will + be zero (v = 0), unless there is grid motion (v = u_wall)---*/ + + if (dynamic_grid) { + GridVel = geometry->node[iPoint]->GetGridVel(); + for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = GridVel[iDim]; + } + else { + for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = 0.0; + } + + /*--- Initialize the convective & viscous residuals to zero ---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + Res_Conv[iVar] = 0.0; + Res_Visc[iVar] = 0.0; + } + + /*--- Set the residual, truncation error and velocity value on the boundary ---*/ + + nodes->SetVelocity_Old(iPoint,Vector); + + for (iDim = 0; iDim < nDim; iDim++) + LinSysRes.SetBlock_Zero(iPoint, iDim+1); + nodes->SetVel_ResTruncError_Zero(iPoint); + + /*--- Get transport coefficients ---*/ + + laminar_viscosity = nodes->GetLaminarViscosity(iPoint); + eddy_viscosity = nodes->GetEddyViscosity(iPoint); + thermal_conductivity = Cp * ( laminar_viscosity/Prandtl_Lam + eddy_viscosity/Prandtl_Turb); + + // work in progress on real-gases... + //thermal_conductivity = nodes->GetThermalConductivity(iPoint); + //Cp = nodes->GetSpecificHeatCp(iPoint); + //thermal_conductivity += Cp*eddy_viscosity/Prandtl_Turb; + + /*--- Compute the normal gradient in temperature using Twall ---*/ + + There = nodes->GetTemperature(Point_Normal); + Tconjugate = GetConjugateHeatVariable(val_marker, iVertex, 0)/Temperature_Ref; + + if ((config->GetKind_CHT_Coupling() == AVERAGED_TEMPERATURE_NEUMANN_HEATFLUX) || + (config->GetKind_CHT_Coupling() == AVERAGED_TEMPERATURE_ROBIN_HEATFLUX)) { + + /*--- Compute wall temperature from both temperatures ---*/ + + HF_FactorHere = thermal_conductivity*config->GetViscosity_Ref()/dist_ij; + HF_FactorConjugate = GetConjugateHeatVariable(val_marker, iVertex, 2); + + Twall = (There*HF_FactorHere + Tconjugate*HF_FactorConjugate)/(HF_FactorHere + HF_FactorConjugate); + dTdn = -(There - Twall)/dist_ij; + } + else if ((config->GetKind_CHT_Coupling() == DIRECT_TEMPERATURE_NEUMANN_HEATFLUX) || + (config->GetKind_CHT_Coupling() == DIRECT_TEMPERATURE_ROBIN_HEATFLUX)) { + + /*--- (Directly) Set wall temperature to conjugate temperature. ---*/ + + Twall = Tconjugate; + dTdn = -(There - Twall)/dist_ij; + } + else { + + SU2_MPI::Error("Unknown CHT coupling method.", CURRENT_FUNCTION); + } + + /*--- Apply a weak boundary condition for the energy equation. + Compute the residual due to the prescribed heat flux. ---*/ + + Res_Visc[nDim+1] = thermal_conductivity * dTdn * Area; + + /*--- Calculate Jacobian for implicit time stepping ---*/ + + if (implicit) { + + for (iVar = 0; iVar < nVar; iVar ++) + for (jVar = 0; jVar < nVar; jVar ++) + Jacobian_i[iVar][jVar] = 0.0; + + /*--- Calculate useful quantities ---*/ + + Density = nodes->GetDensity(iPoint); + Vel2 = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + Vel2 += pow(nodes->GetVelocity(iPoint,iDim),2); + dTdrho = 1.0/Density * ( -Twall + (Gamma-1.0)/Gas_Constant*(Vel2/2.0) ); + + /*--- Enforce the no-slip boundary condition in a strong way ---*/ + + for (iVar = 1; iVar <= nDim; iVar++) { + total_index = iPoint*nVar+iVar; + Jacobian.DeleteValsRowi(total_index); + } + + /*--- Add contributions to the Jacobian from the weak enforcement of the energy equations ---*/ + + Jacobian_i[nDim+1][0] = -thermal_conductivity*theta2/dist_ij * dTdrho * Area; + Jacobian_i[nDim+1][nDim+1] = -thermal_conductivity*theta2/dist_ij * (Gamma-1.0)/(Gas_Constant*Density) * Area; + + /*--- Subtract the block from the Global Jacobian structure ---*/ + + Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); + + } + + /*--- If the wall is moving, there are additional residual contributions + due to pressure (p v_wall.n) and shear stress (tau.v_wall.n). ---*/ + + if (dynamic_grid) { + + /*--- Get the grid velocity at the current boundary node ---*/ + + GridVel = geometry->node[iPoint]->GetGridVel(); + ProjGridVel = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + ProjGridVel += GridVel[iDim]*UnitNormal[iDim]*Area; + + /*--- Retrieve other primitive quantities and viscosities ---*/ + + Density = nodes->GetDensity(iPoint); + Pressure = nodes->GetPressure(iPoint); + laminar_viscosity = nodes->GetLaminarViscosity(iPoint); + eddy_viscosity = nodes->GetEddyViscosity(iPoint); + + total_viscosity = laminar_viscosity + eddy_viscosity; + + for (iDim = 0; iDim < nDim; iDim++) { + for (jDim = 0 ; jDim < nDim; jDim++) { + Grad_Vel[iDim][jDim] = nodes->GetGradient_Primitive(iPoint,iDim+1, jDim); + } + } + + /*--- Divergence of the velocity ---*/ + + div_vel = 0.0; for (iDim = 0 ; iDim < nDim; iDim++) div_vel += Grad_Vel[iDim][iDim]; + + /*--- Compute the viscous stress tensor ---*/ + + for (iDim = 0; iDim < nDim; iDim++) + for (jDim = 0; jDim < nDim; jDim++) { + tau[iDim][jDim] = total_viscosity*( Grad_Vel[jDim][iDim] + Grad_Vel[iDim][jDim] ) + - TWO3*total_viscosity*div_vel*delta[iDim][jDim]; + } + + /*--- Dot product of the stress tensor with the grid velocity ---*/ + + for (iDim = 0 ; iDim < nDim; iDim++) { + tau_vel[iDim] = 0.0; + for (jDim = 0 ; jDim < nDim; jDim++) + tau_vel[iDim] += tau[iDim][jDim]*GridVel[jDim]; + } + + /*--- Compute the convective and viscous residuals (energy eqn.) ---*/ + + Res_Conv[nDim+1] = Pressure*ProjGridVel; + for (iDim = 0 ; iDim < nDim; iDim++) + Res_Visc[nDim+1] += tau_vel[iDim]*UnitNormal[iDim]*Area; + + /*--- Implicit Jacobian contributions due to moving walls ---*/ + + if (implicit) { + + /*--- Jacobian contribution related to the pressure term ---*/ + + GridVel2 = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + GridVel2 += GridVel[iDim]*GridVel[iDim]; + for (iVar = 0; iVar < nVar; iVar++) + for (jVar = 0; jVar < nVar; jVar++) + Jacobian_i[iVar][jVar] = 0.0; + + Jacobian_i[nDim+1][0] = 0.5*(Gamma-1.0)*GridVel2*ProjGridVel; + for (jDim = 0; jDim < nDim; jDim++) + Jacobian_i[nDim+1][jDim+1] = -(Gamma-1.0)*GridVel[jDim]*ProjGridVel; + Jacobian_i[nDim+1][nDim+1] = (Gamma-1.0)*ProjGridVel; + + /*--- Add the block to the Global Jacobian structure ---*/ + + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); + + /*--- Now the Jacobian contribution related to the shear stress ---*/ + + for (iVar = 0; iVar < nVar; iVar++) + for (jVar = 0; jVar < nVar; jVar++) + Jacobian_i[iVar][jVar] = 0.0; + + factor = total_viscosity*Area/(Density*dist_ij); + + if (nDim == 2) { + thetax = theta2 + UnitNormal[0]*UnitNormal[0]/3.0; + thetay = theta2 + UnitNormal[1]*UnitNormal[1]/3.0; + + etaz = UnitNormal[0]*UnitNormal[1]/3.0; + + pix = GridVel[0]*thetax + GridVel[1]*etaz; + piy = GridVel[0]*etaz + GridVel[1]*thetay; + + Jacobian_i[nDim+1][0] -= factor*(-pix*GridVel[0]+piy*GridVel[1]); + Jacobian_i[nDim+1][1] -= factor*pix; + Jacobian_i[nDim+1][2] -= factor*piy; + } + else { + thetax = theta2 + UnitNormal[0]*UnitNormal[0]/3.0; + thetay = theta2 + UnitNormal[1]*UnitNormal[1]/3.0; + thetaz = theta2 + UnitNormal[2]*UnitNormal[2]/3.0; + + etaz = UnitNormal[0]*UnitNormal[1]/3.0; + etax = UnitNormal[1]*UnitNormal[2]/3.0; + etay = UnitNormal[0]*UnitNormal[2]/3.0; + + pix = GridVel[0]*thetax + GridVel[1]*etaz + GridVel[2]*etay; + piy = GridVel[0]*etaz + GridVel[1]*thetay + GridVel[2]*etax; + piz = GridVel[0]*etay + GridVel[1]*etax + GridVel[2]*thetaz; + + Jacobian_i[nDim+1][0] -= factor*(-pix*GridVel[0]+piy*GridVel[1]+piz*GridVel[2]); + Jacobian_i[nDim+1][1] -= factor*pix; + Jacobian_i[nDim+1][2] -= factor*piy; + Jacobian_i[nDim+1][3] -= factor*piz; + } + + /*--- Subtract the block from the Global Jacobian structure ---*/ + + Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); + } + + } + + /*--- Convective contribution to the residual at the wall ---*/ + + LinSysRes.AddBlock(iPoint, Res_Conv); + + /*--- Viscous contribution to the residual at the wall ---*/ + + LinSysRes.SubtractBlock(iPoint, Res_Visc); + + /*--- Enforce the no-slip boundary condition in a strong way by + modifying the velocity-rows of the Jacobian (1 on the diagonal). ---*/ + + if (implicit) { + for (iVar = 1; iVar <= nDim; iVar++) { + total_index = iPoint*nVar+iVar; + Jacobian.DeleteValsRowi(total_index); + } + } + } + } +} + +void CNSSolver::SetTauWall_WF(CGeometry *geometry, CSolver **solver_container, CConfig *config) { + + unsigned short iDim, jDim, iMarker; + unsigned long iVertex, iPoint, Point_Normal, counter; + + su2double Area, div_vel, UnitNormal[3], *Normal; + su2double **grad_primvar, tau[3][3]; + + su2double Vel[3] = {0.0, 0.0, 0.0}, VelNormal, VelTang[3], VelTangMod, VelInfMod, WallDist[3], WallDistMod; + su2double T_Normal, P_Normal; + su2double Density_Wall, T_Wall, P_Wall, Lam_Visc_Wall, Tau_Wall = 0.0, Tau_Wall_Old = 0.0; + su2double *Coord, *Coord_Normal; + su2double diff, Delta; + su2double U_Tau, U_Plus, Gam, Beta, Phi, Q, Y_Plus_White, Y_Plus; + su2double TauElem[3], TauNormal, TauTangent[3], WallShearStress; + su2double Gas_Constant = config->GetGas_ConstantND(); + su2double Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; + + unsigned short max_iter = 10; + su2double tol = 1e-6; + + /*--- Get the freestream velocity magnitude for non-dim. purposes ---*/ + + su2double *VelInf = config->GetVelocity_FreeStreamND(); + VelInfMod = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + VelInfMod += VelInf[iDim]; + VelInfMod = sqrt(VelInfMod); + + /*--- Compute the recovery factor ---*/ + // Double-check: laminar or turbulent Pr for this? + su2double Recovery = pow(config->GetPrandtl_Lam(), (1.0/3.0)); + + /*--- Typical constants from boundary layer theory ---*/ + + su2double kappa = 0.4; + su2double B = 5.5; + + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { + + if ((config->GetMarker_All_KindBC(iMarker) == HEAT_FLUX) || + (config->GetMarker_All_KindBC(iMarker) == ISOTHERMAL) ) { + + /*--- Identify the boundary by string name ---*/ + + string Marker_Tag = config->GetMarker_All_TagBound(iMarker); + + /*--- Get the specified wall heat flux from config ---*/ + + // Wall_HeatFlux = config->GetWall_HeatFlux(Marker_Tag); + + /*--- Loop over all of the vertices on this boundary marker ---*/ + + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + Point_Normal = geometry->vertex[iMarker][iVertex]->GetNormal_Neighbor(); + + /*--- Check if the node belongs to the domain (i.e, not a halo node) + and the neighbor is not part of the physical boundary ---*/ + + if (geometry->node[iPoint]->GetDomain()) { + + /*--- Get coordinates of the current vertex and nearest normal point ---*/ + + Coord = geometry->node[iPoint]->GetCoord(); + Coord_Normal = geometry->node[Point_Normal]->GetCoord(); + + /*--- Compute dual-grid area and boundary normal ---*/ + + Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); + + Area = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + Area += Normal[iDim]*Normal[iDim]; + Area = sqrt (Area); + + for (iDim = 0; iDim < nDim; iDim++) + UnitNormal[iDim] = -Normal[iDim]/Area; + + /*--- Get the velocity, pressure, and temperature at the nearest + (normal) interior point. ---*/ + + for (iDim = 0; iDim < nDim; iDim++) + Vel[iDim] = nodes->GetVelocity(Point_Normal,iDim); + P_Normal = nodes->GetPressure(Point_Normal); + T_Normal = nodes->GetTemperature(Point_Normal); + + /*--- Compute the wall-parallel velocity at first point off the wall ---*/ + + VelNormal = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + VelNormal += Vel[iDim] * UnitNormal[iDim]; + for (iDim = 0; iDim < nDim; iDim++) + VelTang[iDim] = Vel[iDim] - VelNormal*UnitNormal[iDim]; + + VelTangMod = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + VelTangMod += VelTang[iDim]*VelTang[iDim]; + VelTangMod = sqrt(VelTangMod); + + /*--- Compute normal distance of the interior point from the wall ---*/ + + for (iDim = 0; iDim < nDim; iDim++) + WallDist[iDim] = (Coord[iDim] - Coord_Normal[iDim]); + + WallDistMod = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + WallDistMod += WallDist[iDim]*WallDist[iDim]; + WallDistMod = sqrt(WallDistMod); + + /*--- Compute mach number ---*/ + + // M_Normal = VelTangMod / sqrt(Gamma * Gas_Constant * T_Normal); + + /*--- Compute the wall temperature using the Crocco-Buseman equation ---*/ + + //T_Wall = T_Normal * (1.0 + 0.5*Gamma_Minus_One*Recovery*M_Normal*M_Normal); + T_Wall = T_Normal + Recovery*pow(VelTangMod,2.0)/(2.0*Cp); + + /*--- Extrapolate the pressure from the interior & compute the + wall density using the equation of state ---*/ + + P_Wall = P_Normal; + Density_Wall = P_Wall/(Gas_Constant*T_Wall); + + /*--- Compute the shear stress at the wall in the regular fashion + by using the stress tensor on the surface ---*/ + + Lam_Visc_Wall = nodes->GetLaminarViscosity(iPoint); + grad_primvar = nodes->GetGradient_Primitive(iPoint); + + div_vel = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + div_vel += grad_primvar[iDim+1][iDim]; + + for (iDim = 0; iDim < nDim; iDim++) { + for (jDim = 0 ; jDim < nDim; jDim++) { + Delta = 0.0; if (iDim == jDim) Delta = 1.0; + tau[iDim][jDim] = Lam_Visc_Wall*( grad_primvar[jDim+1][iDim] + + grad_primvar[iDim+1][jDim]) - + TWO3*Lam_Visc_Wall*div_vel*Delta; + } + TauElem[iDim] = 0.0; + for (jDim = 0; jDim < nDim; jDim++) + TauElem[iDim] += tau[iDim][jDim]*UnitNormal[jDim]; + } + + /*--- Compute wall shear stress as the magnitude of the wall-tangential + component of the shear stress tensor---*/ + + TauNormal = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + TauNormal += TauElem[iDim] * UnitNormal[iDim]; + + for (iDim = 0; iDim < nDim; iDim++) + TauTangent[iDim] = TauElem[iDim] - TauNormal * UnitNormal[iDim]; + + WallShearStress = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + WallShearStress += TauTangent[iDim]*TauTangent[iDim]; + WallShearStress = sqrt(WallShearStress); + + /*--- Calculate the quantities from boundary layer theory and + iteratively solve for a new wall shear stress. Use the current wall + shear stress as a starting guess for the wall function. ---*/ + + Tau_Wall_Old = WallShearStress; + counter = 0; diff = 1.0; + + while (diff > tol) { + + /*--- Friction velocity and u+ ---*/ + + U_Tau = sqrt(Tau_Wall_Old/Density_Wall); + U_Plus = VelTangMod/U_Tau; + + /*--- Gamma, Beta, Q, and Phi, defined by Nichols & Nelson (2004) ---*/ + + Gam = Recovery*U_Tau*U_Tau/(2.0*Cp*T_Wall); + Beta = 0.0; // For adiabatic flows only + Q = sqrt(Beta*Beta + 4.0*Gam); + Phi = asin(-1.0*Beta/Q); + + /*--- Y+ defined by White & Christoph (compressibility and heat transfer) negative value for (2.0*Gam*U_Plus - Beta)/Q ---*/ + + Y_Plus_White = exp((kappa/sqrt(Gam))*(asin((2.0*Gam*U_Plus - Beta)/Q) - Phi))*exp(-1.0*kappa*B); + + /*--- Spalding's universal form for the BL velocity with the + outer velocity form of White & Christoph above. ---*/ + + Y_Plus = U_Plus + Y_Plus_White - (exp(-1.0*kappa*B)* + (1.0 + kappa*U_Plus + kappa*kappa*U_Plus*U_Plus/2.0 + + kappa*kappa*kappa*U_Plus*U_Plus*U_Plus/6.0)); + + /*--- Calculate an updated value for the wall shear stress + using the y+ value, the definition of y+, and the definition of + the friction velocity. ---*/ + + Tau_Wall = (1.0/Density_Wall)*pow(Y_Plus*Lam_Visc_Wall/WallDistMod,2.0); + + /*--- Difference between the old and new Tau. Update old value. ---*/ + + diff = fabs(Tau_Wall-Tau_Wall_Old); + Tau_Wall_Old += 0.25*(Tau_Wall-Tau_Wall_Old); + + counter++; + if (counter > max_iter) { + cout << "WARNING: Tau_Wall evaluation has not converged in solver_direct_mean.cpp" << endl; + cout << Tau_Wall_Old << " " << Tau_Wall << " " << diff << endl; + break; + } + + } + + + /*--- Store this value for the wall shear stress at the node. ---*/ + + nodes->SetTauWall(iPoint,Tau_Wall); + + + } + + } + + } + } + +} diff --git a/SU2_CFD/src/solver_structure.cpp b/SU2_CFD/src/solvers/CSolver.cpp similarity index 82% rename from SU2_CFD/src/solver_structure.cpp rename to SU2_CFD/src/solvers/CSolver.cpp index 5ca64a2718cb..5cfb9cc348d2 100644 --- a/SU2_CFD/src/solver_structure.cpp +++ b/SU2_CFD/src/solvers/CSolver.cpp @@ -1,12 +1,12 @@ /*! - * \file solver_structure.cpp - * \brief Main subroutines for solving primal and adjoint problems. + * \file CSolver.cpp + * \brief Main subroutines for CSolver class. * \author F. Palacios, T. Economon * \version 7.0.0 "Blackbird" * * SU2 Project Website: https://su2code.github.io * - * The SU2 Project is maintained by the SU2 Foundation + * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) @@ -26,40 +26,39 @@ */ -#include "../include/solver_structure.hpp" -#include "../include/variables/CBaselineVariable.hpp" -#include "../include/gradients/computeGradientsGreenGauss.hpp" -#include "../include/gradients/computeGradientsLeastSquares.hpp" -#include "../include/limiters/computeLimiters.hpp" -#include "../../Common/include/toolboxes/MMS/CIncTGVSolution.hpp" -#include "../../Common/include/toolboxes/MMS/CInviscidVortexSolution.hpp" -#include "../../Common/include/toolboxes/MMS/CMMSIncEulerSolution.hpp" -#include "../../Common/include/toolboxes/MMS/CMMSIncNSSolution.hpp" -#include "../../Common/include/toolboxes/MMS/CMMSNSTwoHalfCirclesSolution.hpp" -#include "../../Common/include/toolboxes/MMS/CMMSNSTwoHalfSpheresSolution.hpp" -#include "../../Common/include/toolboxes/MMS/CMMSNSUnitQuadSolution.hpp" -#include "../../Common/include/toolboxes/MMS/CMMSNSUnitQuadSolutionWallBC.hpp" -#include "../../Common/include/toolboxes/MMS/CNSUnitQuadSolution.hpp" -#include "../../Common/include/toolboxes/MMS/CRinglebSolution.hpp" -#include "../../Common/include/toolboxes/MMS/CTGVSolution.hpp" -#include "../../Common/include/toolboxes/MMS/CUserDefinedSolution.hpp" -#include "../../Common/include/toolboxes/printing_toolbox.hpp" -#include "../include/CMarkerProfileReaderFVM.hpp" +#include "../../include/solvers/CSolver.hpp" +#include "../../include/gradients/computeGradientsGreenGauss.hpp" +#include "../../include/gradients/computeGradientsLeastSquares.hpp" +#include "../../include/limiters/computeLimiters.hpp" +#include "../../../Common/include/toolboxes/MMS/CIncTGVSolution.hpp" +#include "../../../Common/include/toolboxes/MMS/CInviscidVortexSolution.hpp" +#include "../../../Common/include/toolboxes/MMS/CMMSIncEulerSolution.hpp" +#include "../../../Common/include/toolboxes/MMS/CMMSIncNSSolution.hpp" +#include "../../../Common/include/toolboxes/MMS/CMMSNSTwoHalfCirclesSolution.hpp" +#include "../../../Common/include/toolboxes/MMS/CMMSNSTwoHalfSpheresSolution.hpp" +#include "../../../Common/include/toolboxes/MMS/CMMSNSUnitQuadSolution.hpp" +#include "../../../Common/include/toolboxes/MMS/CMMSNSUnitQuadSolutionWallBC.hpp" +#include "../../../Common/include/toolboxes/MMS/CNSUnitQuadSolution.hpp" +#include "../../../Common/include/toolboxes/MMS/CRinglebSolution.hpp" +#include "../../../Common/include/toolboxes/MMS/CTGVSolution.hpp" +#include "../../../Common/include/toolboxes/MMS/CUserDefinedSolution.hpp" +#include "../../../Common/include/toolboxes/printing_toolbox.hpp" +#include "../../include/CMarkerProfileReaderFVM.hpp" CSolver::CSolver(bool mesh_deform_mode) : System(mesh_deform_mode) { rank = SU2_MPI::GetRank(); size = SU2_MPI::GetSize(); - + adjoint = false; /*--- Set the multigrid level to the finest grid. This can be overwritten in the constructors of the derived classes. ---*/ MGLevel = MESH_0; - + /*--- Array initialization ---*/ - + OutputHeadingNames = NULL; Residual_RMS = NULL; Residual_Max = NULL; @@ -102,14 +101,14 @@ CSolver::CSolver(bool mesh_deform_mode) : System(mesh_deform_mode) { ResLinSolver = 0.0; /*--- Variable initialization to avoid valgrid warnings when not used. ---*/ - + IterLinSolver = 0; /*--- Initialize pointer for any verification solution. ---*/ VerificationSolution = NULL; - + /*--- Flags for the periodic BC communications. ---*/ - + rotate_periodic = false; implicit_periodic = false; @@ -125,16 +124,16 @@ CSolver::CSolver(bool mesh_deform_mode) : System(mesh_deform_mode) { VertexTractionAdjoint = NULL; /*--- Auxiliary data needed for CFL adaption. ---*/ - + NonLinRes_Value = 0; NonLinRes_Func = 0; Old_Func = 0; New_Func = 0; NonLinRes_Counter = 0; - + nPrimVarGrad = 0; nPrimVar = 0; - + } CSolver::~CSolver(void) { @@ -263,7 +262,7 @@ CSolver::~CSolver(void) { if (Restart_Data != NULL) {delete [] Restart_Data; Restart_Data = NULL;} if (VerificationSolution != NULL) {delete VerificationSolution; VerificationSolution = NULL;} - + } void CSolver::InitiatePeriodicComms(CGeometry *geometry, @@ -286,29 +285,29 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, unsigned short MPI_TYPE = 0; unsigned short ICOUNT = nVar; unsigned short JCOUNT = nVar; - + int iMessage, iSend, nSend; unsigned long iPoint, jPoint, msg_offset, buf_offset, iPeriodic, Neighbor_Point; - + su2double *Diff = new su2double[nVar]; su2double *Und_Lapl = new su2double[nVar]; su2double *Sol_Min = new su2double[nPrimVarGrad]; su2double *Sol_Max = new su2double[nPrimVarGrad]; su2double *rotPrim_i = new su2double[nPrimVar]; su2double *rotPrim_j = new su2double[nPrimVar]; - + su2double Sensor_i = 0.0, Sensor_j = 0.0, Pressure_i, Pressure_j; su2double *Coord_i, *Coord_j, r11, r12, r13, r22, r23_a, r23_b, r33, weight; su2double *center, *angles, translation[3]={0.0,0.0,0.0}, *trans, dx, dy, dz; su2double rotMatrix[3][3] = {{1.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}}; su2double Theta, Phi, Psi, cosTheta, sinTheta, cosPhi, sinPhi, cosPsi, sinPsi; su2double rotCoord_i[3] = {0.0, 0.0, 0.0}, rotCoord_j[3] = {0.0, 0.0, 0.0}; - + string Marker_Tag; - + /*--- Set the size of the data packet and type depending on quantity. ---*/ - + switch (commType) { case PERIODIC_VOLUME: COUNT_PER_POINT = 1; @@ -379,144 +378,144 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, CURRENT_FUNCTION); break; } - + su2double **jacBlock = new su2double*[ICOUNT]; su2double **rotBlock = new su2double*[ICOUNT]; for (iVar = 0; iVar < ICOUNT; iVar++) { jacBlock[iVar] = new su2double[JCOUNT]; rotBlock[iVar] = new su2double[JCOUNT]; } - + /*--- Check to make sure we have created a large enough buffer for these comms during preprocessing. It will be reallocated whenever we find a larger count per point than currently exists. After the first cycle of comms, this should be inactive. ---*/ - + if (COUNT_PER_POINT > geometry->countPerPeriodicPoint) { geometry->AllocatePeriodicComms(COUNT_PER_POINT); } - + /*--- Set some local pointers to make access simpler. ---*/ - + su2double *bufDSend = geometry->bufD_PeriodicSend; - + unsigned short *bufSSend = geometry->bufS_PeriodicSend; - + /*--- Load the specified quantity from the solver into the generic communication buffer in the geometry class. ---*/ - + if (geometry->nPeriodicSend > 0) { - + /*--- Post all non-blocking recvs first before sends. ---*/ - + geometry->PostPeriodicRecvs(geometry, config, MPI_TYPE); - + for (iMessage = 0; iMessage < geometry->nPeriodicSend; iMessage++) { - + /*--- Get the offset in the buffer for the start of this message. ---*/ - + msg_offset = geometry->nPoint_PeriodicSend[iMessage]; - + /*--- Get the number of periodic points we need to communicate on the current periodic marker. ---*/ - + nSend = (geometry->nPoint_PeriodicSend[iMessage+1] - geometry->nPoint_PeriodicSend[iMessage]); - + for (iSend = 0; iSend < nSend; iSend++) { - + /*--- Get the local index for this communicated data. We need both the node and periodic face index (for rotations). ---*/ - + iPoint = geometry->Local_Point_PeriodicSend[msg_offset + iSend]; iPeriodic = geometry->Local_Marker_PeriodicSend[msg_offset + iSend]; - + /*--- Retrieve the supplied periodic information. ---*/ - + Marker_Tag = config->GetMarker_All_TagBound(iPeriodic); center = config->GetPeriodicRotCenter(Marker_Tag); angles = config->GetPeriodicRotAngles(Marker_Tag); trans = config->GetPeriodicTranslation(Marker_Tag); - + /*--- Store (center+trans) as it is constant and will be added. ---*/ - + translation[0] = center[0] + trans[0]; translation[1] = center[1] + trans[1]; translation[2] = center[2] + trans[2]; - + /*--- Store angles separately for clarity. Compute sines/cosines. ---*/ - + Theta = angles[0]; Phi = angles[1]; Psi = angles[2]; cosTheta = cos(Theta); cosPhi = cos(Phi); cosPsi = cos(Psi); sinTheta = sin(Theta); sinPhi = sin(Phi); sinPsi = sin(Psi); - + /*--- Compute the rotation matrix. Note that the implicit ordering is rotation about the x-axis, y-axis, then z-axis. ---*/ - + rotMatrix[0][0] = cosPhi*cosPsi; rotMatrix[1][0] = cosPhi*sinPsi; rotMatrix[2][0] = -sinPhi; - + rotMatrix[0][1] = sinTheta*sinPhi*cosPsi - cosTheta*sinPsi; rotMatrix[1][1] = sinTheta*sinPhi*sinPsi + cosTheta*cosPsi; rotMatrix[2][1] = sinTheta*cosPhi; - + rotMatrix[0][2] = cosTheta*sinPhi*cosPsi + sinTheta*sinPsi; rotMatrix[1][2] = cosTheta*sinPhi*sinPsi - sinTheta*cosPsi; rotMatrix[2][2] = cosTheta*cosPhi; - + /*--- Compute the offset in the recv buffer for this point. ---*/ - + buf_offset = (msg_offset + iSend)*geometry->countPerPeriodicPoint; - + /*--- Load the send buffers depending on the particular value that has been requested for communication. ---*/ - + switch (commType) { - + case PERIODIC_VOLUME: - + /*--- Load the volume of the current periodic CV so that we can accumulate the total control volume size on all periodic faces. ---*/ - + bufDSend[buf_offset] = geometry->node[iPoint]->GetVolume() + geometry->node[iPoint]->GetPeriodicVolume(); - + break; - + case PERIODIC_NEIGHBORS: - + nNeighbor = 0; for (iNeighbor = 0; iNeighbor < geometry->node[iPoint]->GetnPoint(); iNeighbor++) { Neighbor_Point = geometry->node[iPoint]->GetPoint(iNeighbor); - + /*--- Check if this neighbor lies on the periodic face so that we avoid double counting neighbors on both sides. If not, increment the count of neighbors for the donor. ---*/ - + if (!geometry->node[Neighbor_Point]->GetPeriodicBoundary()) nNeighbor++; - + } - + /*--- Store the number of neighbors in bufffer. ---*/ - + bufSSend[buf_offset] = nNeighbor; - + break; - + case PERIODIC_RESIDUAL: - + /*--- Communicate the residual from our partial control volume to the other side of the periodic face. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { bufDSend[buf_offset+iVar] = LinSysRes.GetBlock(iPoint, iVar); } - + /*--- Rotate the momentum components of the residual array. ---*/ - + if (rotate_periodic) { if (nDim == 2) { bufDSend[buf_offset+1] = (rotMatrix[0][0]*LinSysRes.GetBlock(iPoint, 1) + @@ -536,26 +535,26 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, } } buf_offset += nVar; - + /*--- Load the time step for the current point. ---*/ - + bufDSend[buf_offset] = base_nodes->GetDelta_Time(iPoint); buf_offset++; - + /*--- For implicit calculations, we will communicate the contributions to the Jacobian block diagonal, i.e., the impact of the point upon itself, J_ii. ---*/ - + if (implicit_periodic) { - + for (iVar = 0; iVar < nVar; iVar++) { for (jVar = 0; jVar < nVar; jVar++) { jacBlock[iVar][jVar] = Jacobian.GetBlock(iPoint, iPoint, iVar, jVar); } } - + /*--- Rotate the momentum columns of the Jacobian. ---*/ - + if (rotate_periodic) { for (iVar = 0; iVar < nVar; iVar++) { if (nDim == 2) { @@ -564,7 +563,7 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, jacBlock[2][iVar] = (rotMatrix[1][0]*Jacobian.GetBlock(iPoint, iPoint, 1, iVar) + rotMatrix[1][1]*Jacobian.GetBlock(iPoint, iPoint, 2, iVar)); } else { - + jacBlock[1][iVar] = (rotMatrix[0][0]*Jacobian.GetBlock(iPoint, iPoint, 1, iVar) + rotMatrix[0][1]*Jacobian.GetBlock(iPoint, iPoint, 2, iVar) + rotMatrix[0][2]*Jacobian.GetBlock(iPoint, iPoint, 3, iVar)); @@ -577,9 +576,9 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, } } } - + /*--- Load the Jacobian terms into the buffer for sending. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { for (jVar = 0; jVar < nVar; jVar++) { bufDSend[buf_offset] = jacBlock[iVar][jVar]; @@ -587,23 +586,23 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, } } } - + break; - + case PERIODIC_IMPLICIT: - + /*--- Communicate the solution from our master set of periodic nodes (from the linear solver perspective) to the passive periodic nodes on the matching face. This is done at the end of the iteration to synchronize the solution after the linear solve. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { bufDSend[buf_offset+iVar] = base_nodes->GetSolution(iPoint, iVar); } - + /*--- Rotate the momentum components of the solution array. ---*/ - + if (rotate_periodic) { if (nDim == 2) { bufDSend[buf_offset+1] = (rotMatrix[0][0]*base_nodes->GetSolution(iPoint,1) + @@ -622,46 +621,46 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, rotMatrix[2][2]*base_nodes->GetSolution(iPoint,3)); } } - + break; - + case PERIODIC_LAPLACIAN: - + /*--- For JST, the undivided Laplacian must be computed consistently by using the complete control volume info from both sides of the periodic face. ---*/ - + for (iVar = 0; iVar< nVar; iVar++) Und_Lapl[iVar] = 0.0; - + for (iNeighbor = 0; iNeighbor < geometry->node[iPoint]->GetnPoint(); iNeighbor++) { jPoint = geometry->node[iPoint]->GetPoint(iNeighbor); - + /*--- Avoid periodic boundary points so that we do not duplicate edges on both sides of the periodic BC. ---*/ - + if (!geometry->node[jPoint]->GetPeriodicBoundary()) { - + /*--- Solution differences ---*/ - + for (iVar = 0; iVar < nVar; iVar++) Diff[iVar] = (base_nodes->GetSolution(iPoint, iVar) - base_nodes->GetSolution(jPoint,iVar)); - + /*--- Correction for compressible flows (use enthalpy) ---*/ - + if (!(config->GetKind_Regime() == INCOMPRESSIBLE)) { Pressure_i = base_nodes->GetPressure(iPoint); Pressure_j = base_nodes->GetPressure(jPoint); Diff[nVar-1] = ((base_nodes->GetSolution(iPoint,nVar-1) + Pressure_i) - (base_nodes->GetSolution(jPoint,nVar-1) + Pressure_j)); } - + boundary_i = geometry->node[iPoint]->GetPhysicalBoundary(); boundary_j = geometry->node[jPoint]->GetPhysicalBoundary(); - + /*--- Both points inside the domain, or both in the boundary ---*/ - + if ((!boundary_i && !boundary_j) || ( boundary_i && boundary_j)) { if (geometry->node[iPoint]->GetDomain()) { @@ -669,25 +668,25 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, Und_Lapl[iVar] -= Diff[iVar]; } } - + /*--- iPoint inside the domain, jPoint on the boundary ---*/ - + if (!boundary_i && boundary_j) if (geometry->node[iPoint]->GetDomain()){ for (iVar = 0; iVar< nVar; iVar++) Und_Lapl[iVar] -= Diff[iVar]; } - + } } - + /*--- Store the components to be communicated in the buffer. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) bufDSend[buf_offset+iVar] = Und_Lapl[iVar]; - + /*--- Rotate the momentum components of the Laplacian. ---*/ - + if (rotate_periodic) { if (nDim == 2) { bufDSend[buf_offset+1] = (rotMatrix[0][0]*Und_Lapl[1] + @@ -707,34 +706,34 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, rotMatrix[2][2]*Und_Lapl[3]); } } - + break; - + case PERIODIC_MAX_EIG: - + /*--- Simple summation of eig calc on both periodic faces. ---*/ - + bufDSend[buf_offset] = base_nodes->GetLambda(iPoint); - + break; - + case PERIODIC_SENSOR: - + /*--- For the centered schemes, the sensor must be computed consistently using info from the entire control volume on both sides of the periodic face. ---*/ - + Sensor_i = 0.0; Sensor_j = 0.0; for (iNeighbor = 0; iNeighbor < geometry->node[iPoint]->GetnPoint(); iNeighbor++) { jPoint = geometry->node[iPoint]->GetPoint(iNeighbor); - + /*--- Avoid halos and boundary points so that we don't duplicate edges on both sides of the periodic BC. ---*/ - + if (!geometry->node[jPoint]->GetPeriodicBoundary()) { - + /*--- Use density instead of pressure for incomp. flows. ---*/ - + if ((config->GetKind_Regime() == INCOMPRESSIBLE)) { Pressure_i = base_nodes->GetDensity(iPoint); Pressure_j = base_nodes->GetDensity(jPoint); @@ -742,12 +741,12 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, Pressure_i = base_nodes->GetPressure(iPoint); Pressure_j = base_nodes->GetPressure(jPoint); } - + boundary_i = geometry->node[iPoint]->GetPhysicalBoundary(); boundary_j = geometry->node[jPoint]->GetPhysicalBoundary(); - + /*--- Both points inside domain, or both on boundary ---*/ - + if ((!boundary_i && !boundary_j) || (boundary_i && boundary_j)) { if (geometry->node[iPoint]->GetDomain()) { @@ -755,44 +754,44 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, Sensor_j += Pressure_i + Pressure_j; } } - + /*--- iPoint inside the domain, jPoint on the boundary ---*/ - + if (!boundary_i && boundary_j) { if (geometry->node[iPoint]->GetDomain()) { Sensor_i += (Pressure_j - Pressure_i); Sensor_j += (Pressure_i + Pressure_j); - + } } - + } } - + /*--- Store the sensor increments to buffer. After summing all contributions, these will be divided. ---*/ - + bufDSend[buf_offset] = Sensor_i; buf_offset++; bufDSend[buf_offset] = Sensor_j; - + break; - + case PERIODIC_SOL_GG: - + /*--- Access and rotate the partial G-G gradient. These will be summed on both sides of the periodic faces before dividing by the volume to complete the Green-Gauss gradient calc. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { for (iDim = 0; iDim < nDim; iDim++) { jacBlock[iVar][iDim] = base_nodes->GetGradient(iPoint, iVar, iDim); rotBlock[iVar][iDim] = base_nodes->GetGradient(iPoint, iVar, iDim); } } - + /*--- Rotate the gradients in x,y,z space for all variables. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { if (nDim == 2) { rotBlock[iVar][0] = (rotMatrix[0][0]*jacBlock[iVar][0] + @@ -800,7 +799,7 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, rotBlock[iVar][1] = (rotMatrix[1][0]*jacBlock[iVar][0] + rotMatrix[1][1]*jacBlock[iVar][1]); } else { - + rotBlock[iVar][0] = (rotMatrix[0][0]*jacBlock[iVar][0] + rotMatrix[0][1]*jacBlock[iVar][1] + rotMatrix[0][2]*jacBlock[iVar][2]); @@ -812,32 +811,32 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, rotMatrix[2][2]*jacBlock[iVar][2]); } } - + /*--- Store the partial gradient in the buffer. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { for (iDim = 0; iDim < nDim; iDim++) { bufDSend[buf_offset+iVar*nDim+iDim] = rotBlock[iVar][iDim]; } } - + break; - + case PERIODIC_PRIM_GG: - + /*--- Access and rotate the partial G-G gradient. These will be summed on both sides of the periodic faces before dividing by the volume to complete the Green-Gauss gradient calc. ---*/ - + for (iVar = 0; iVar < nPrimVarGrad; iVar++) { for (iDim = 0; iDim < nDim; iDim++){ jacBlock[iVar][iDim] = base_nodes->GetGradient_Primitive(iPoint, iVar, iDim); rotBlock[iVar][iDim] = base_nodes->GetGradient_Primitive(iPoint, iVar, iDim); } } - + /*--- Rotate the partial gradients in space for all variables. ---*/ - + for (iVar = 0; iVar < nPrimVarGrad; iVar++) { if (nDim == 2) { rotBlock[iVar][0] = (rotMatrix[0][0]*jacBlock[iVar][0] + @@ -856,62 +855,62 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, rotMatrix[2][2]*jacBlock[iVar][2]); } } - + /*--- Store the partial gradient in the buffer. ---*/ - + for (iVar = 0; iVar < nPrimVarGrad; iVar++) { for (iDim = 0; iDim < nDim; iDim++) { bufDSend[buf_offset+iVar*nDim+iDim] = rotBlock[iVar][iDim]; } } - + break; - + case PERIODIC_SOL_LS: case PERIODIC_SOL_ULS: - + /*--- For L-S gradient calculations with rotational periodicity, we will need to rotate the x,y,z components. To make the process easier, we choose to rotate the initial periodic point and their neighbor points into their location on the donor marker before computing the terms that we need to communicate. ---*/ - + /*--- Set a flag for unweighted or weighted least-squares. ---*/ weighted = true; if (commType == PERIODIC_SOL_ULS) { weighted = false; } - + /*--- Get coordinates for the current point. ---*/ - + Coord_i = geometry->node[iPoint]->GetCoord(); - + /*--- Get the position vector from rotation center to point. ---*/ - + dx = Coord_i[0] - center[0]; dy = Coord_i[1] - center[1]; if (nDim == 3) dz = Coord_i[2] - center[2]; else dz = 0.0; - + /*--- Compute transformed point coordinates. ---*/ - + rotCoord_i[0] = (rotMatrix[0][0]*dx + rotMatrix[0][1]*dy + rotMatrix[0][2]*dz + translation[0]); - + rotCoord_i[1] = (rotMatrix[1][0]*dx + rotMatrix[1][1]*dy + rotMatrix[1][2]*dz + translation[1]); - + rotCoord_i[2] = (rotMatrix[2][0]*dx + rotMatrix[2][1]*dy + rotMatrix[2][2]*dz + translation[2]); - + /*--- Get conservative solution and rotate if necessary. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) rotPrim_i[iVar] = base_nodes->GetSolution(iPoint, iVar); - + if (rotate_periodic) { if (nDim == 2) { rotPrim_i[1] = (rotMatrix[0][0]*base_nodes->GetSolution(iPoint,1) + @@ -931,54 +930,54 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, rotMatrix[2][2]*base_nodes->GetSolution(iPoint,3)); } } - + /*--- Inizialization of variables ---*/ - + for (iVar = 0; iVar < nVar; iVar++) for (iDim = 0; iDim < nDim; iDim++) Cvector[iVar][iDim] = 0.0; - + r11 = 0.0; r12 = 0.0; r22 = 0.0; r13 = 0.0; r23_a = 0.0; r23_b = 0.0; r33 = 0.0; - + for (iNeighbor = 0; iNeighbor < geometry->node[iPoint]->GetnPoint(); iNeighbor++) { jPoint = geometry->node[iPoint]->GetPoint(iNeighbor); - + /*--- Avoid periodic boundary points so that we do not duplicate edges on both sides of the periodic BC. ---*/ - + if (!geometry->node[jPoint]->GetPeriodicBoundary()) { - + /*--- Get coordinates for the neighbor point. ---*/ - + Coord_j = geometry->node[jPoint]->GetCoord(); - + /*--- Get the position vector from rotation center. ---*/ - + dx = Coord_j[0] - center[0]; dy = Coord_j[1] - center[1]; if (nDim == 3) dz = Coord_j[2] - center[2]; else dz = 0.0; - + /*--- Compute transformed point coordinates. ---*/ - + rotCoord_j[0] = (rotMatrix[0][0]*dx + rotMatrix[0][1]*dy + rotMatrix[0][2]*dz + translation[0]); - + rotCoord_j[1] = (rotMatrix[1][0]*dx + rotMatrix[1][1]*dy + rotMatrix[1][2]*dz + translation[1]); - + rotCoord_j[2] = (rotMatrix[2][0]*dx + rotMatrix[2][1]*dy + rotMatrix[2][2]*dz + translation[2]); - + /*--- Get conservative solution and rotte if necessary. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) rotPrim_j[iVar] = base_nodes->GetSolution(jPoint,iVar); - + if (rotate_periodic) { if (nDim == 2) { rotPrim_j[1] = (rotMatrix[0][0]*base_nodes->GetSolution(jPoint,1) + @@ -998,7 +997,7 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, rotMatrix[2][2]*base_nodes->GetSolution(jPoint,3)); } } - + if (weighted) { weight = 0.0; for (iDim = 0; iDim < nDim; iDim++) { @@ -1008,18 +1007,18 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, } else { weight = 1.0; } - + /*--- Sumations for entries of upper triangular matrix R ---*/ - + if (weight != 0.0) { - + r11 += ((rotCoord_j[0]-rotCoord_i[0])* (rotCoord_j[0]-rotCoord_i[0])/weight); r12 += ((rotCoord_j[0]-rotCoord_i[0])* (rotCoord_j[1]-rotCoord_i[1])/weight); r22 += ((rotCoord_j[1]-rotCoord_i[1])* (rotCoord_j[1]-rotCoord_i[1])/weight); - + if (nDim == 3) { r13 += ((rotCoord_j[0]-rotCoord_i[0])* (rotCoord_j[2]-rotCoord_i[2])/weight); @@ -1030,23 +1029,23 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, r33 += ((rotCoord_j[2]-rotCoord_i[2])* (rotCoord_j[2]-rotCoord_i[2])/weight); } - + /*--- Entries of c:= transpose(A)*b ---*/ - + for (iVar = 0; iVar < nVar; iVar++) for (iDim = 0; iDim < nDim; iDim++) Cvector[iVar][iDim] += ((rotCoord_j[iDim]-rotCoord_i[iDim])* (rotPrim_j[iVar]-rotPrim_i[iVar])/weight); - + } } } - + /*--- We store and communicate the increments for the matching upper triangular matrix (weights) and the r.h.s. vector. These will be accumulated before completing the L-S gradient calculation for each periodic point. ---*/ - + if (nDim == 2) { bufDSend[buf_offset] = r11; buf_offset++; bufDSend[buf_offset] = r12; buf_offset++; @@ -1057,70 +1056,70 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, bufDSend[buf_offset] = r11; buf_offset++; bufDSend[buf_offset] = r12; buf_offset++; bufDSend[buf_offset] = r13; buf_offset++; - + bufDSend[buf_offset] = 0.0; buf_offset++; bufDSend[buf_offset] = r22; buf_offset++; bufDSend[buf_offset] = r23_a; buf_offset++; - + bufDSend[buf_offset] = 0.0; buf_offset++; bufDSend[buf_offset] = r23_b; buf_offset++; bufDSend[buf_offset] = r33; buf_offset++; } - + for (iVar = 0; iVar < nVar; iVar++) { for (iDim = 0; iDim < nDim; iDim++) { bufDSend[buf_offset] = Cvector[iVar][iDim]; buf_offset++; } } - + break; - + case PERIODIC_PRIM_LS: case PERIODIC_PRIM_ULS: - + /*--- For L-S gradient calculations with rotational periodicity, we will need to rotate the x,y,z components. To make the process easier, we choose to rotate the initial periodic point and their neighbor points into their location on the donor marker before computing the terms that we need to communicate. ---*/ - + /*--- Set a flag for unweighted or weighted least-squares. ---*/ - + weighted = true; if (commType == PERIODIC_PRIM_ULS) { weighted = false; } - + /*--- Get coordinates ---*/ - + Coord_i = geometry->node[iPoint]->GetCoord(); - + /*--- Get the position vector from rot center to point. ---*/ - + dx = Coord_i[0] - center[0]; dy = Coord_i[1] - center[1]; if (nDim == 3) dz = Coord_i[2] - center[2]; else dz = 0.0; - + /*--- Compute transformed point coordinates. ---*/ - + rotCoord_i[0] = (rotMatrix[0][0]*dx + rotMatrix[0][1]*dy + rotMatrix[0][2]*dz + translation[0]); - + rotCoord_i[1] = (rotMatrix[1][0]*dx + rotMatrix[1][1]*dy + rotMatrix[1][2]*dz + translation[1]); - + rotCoord_i[2] = (rotMatrix[2][0]*dx + rotMatrix[2][1]*dy + rotMatrix[2][2]*dz + translation[2]); - + /*--- Get primitives and rotate if necessary. ---*/ - + for (iVar = 0; iVar < nPrimVar; iVar++) rotPrim_i[iVar] = base_nodes->GetPrimitive(iPoint, iVar); - + if (rotate_periodic) { if (nDim == 2) { rotPrim_i[1] = (rotMatrix[0][0]*base_nodes->GetPrimitive(iPoint,1) + @@ -1140,54 +1139,54 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, rotMatrix[2][2]*base_nodes->GetPrimitive(iPoint,3)); } } - + /*--- Inizialization of variables ---*/ - + for (iVar = 0; iVar < nPrimVarGrad; iVar++) for (iDim = 0; iDim < nDim; iDim++) Cvector[iVar][iDim] = 0.0; - + r11 = 0.0; r12 = 0.0; r22 = 0.0; r13 = 0.0; r23_a = 0.0; r23_b = 0.0; r33 = 0.0; - + for (iNeighbor = 0; iNeighbor < geometry->node[iPoint]->GetnPoint(); iNeighbor++) { jPoint = geometry->node[iPoint]->GetPoint(iNeighbor); - + /*--- Avoid periodic boundary points so that we do not duplicate edges on both sides of the periodic BC. ---*/ - + if (!geometry->node[jPoint]->GetPeriodicBoundary()) { - + /*--- Get coordinates for the neighbor point. ---*/ - + Coord_j = geometry->node[jPoint]->GetCoord(); - + /*--- Get the position vector from rotation center. ---*/ - + dx = Coord_j[0] - center[0]; dy = Coord_j[1] - center[1]; if (nDim == 3) dz = Coord_j[2] - center[2]; else dz = 0.0; - + /*--- Compute transformed point coordinates. ---*/ - + rotCoord_j[0] = (rotMatrix[0][0]*dx + rotMatrix[0][1]*dy + rotMatrix[0][2]*dz + translation[0]); - + rotCoord_j[1] = (rotMatrix[1][0]*dx + rotMatrix[1][1]*dy + rotMatrix[1][2]*dz + translation[1]); - + rotCoord_j[2] = (rotMatrix[2][0]*dx + rotMatrix[2][1]*dy + rotMatrix[2][2]*dz + translation[2]); - + /*--- Get primitives from CVariable ---*/ - + for (iVar = 0; iVar < nPrimVar; iVar++) rotPrim_j[iVar] = base_nodes->GetPrimitive(jPoint,iVar); - + if (rotate_periodic) { if (nDim == 2) { rotPrim_j[1] = (rotMatrix[0][0]*base_nodes->GetPrimitive(jPoint,1) + @@ -1207,7 +1206,7 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, rotMatrix[2][2]*base_nodes->GetPrimitive(jPoint,3)); } } - + if (weighted) { weight = 0.0; for (iDim = 0; iDim < nDim; iDim++) { @@ -1217,18 +1216,18 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, } else { weight = 1.0; } - + /*--- Sumations for entries of upper triangular matrix R ---*/ - + if (weight != 0.0) { - + r11 += ((rotCoord_j[0]-rotCoord_i[0])* (rotCoord_j[0]-rotCoord_i[0])/weight); r12 += ((rotCoord_j[0]-rotCoord_i[0])* (rotCoord_j[1]-rotCoord_i[1])/weight); r22 += ((rotCoord_j[1]-rotCoord_i[1])* (rotCoord_j[1]-rotCoord_i[1])/weight); - + if (nDim == 3) { r13 += ((rotCoord_j[0]-rotCoord_i[0])* (rotCoord_j[2]-rotCoord_i[2])/weight); @@ -1239,23 +1238,23 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, r33 += ((rotCoord_j[2]-rotCoord_i[2])* (rotCoord_j[2]-rotCoord_i[2])/weight); } - + /*--- Entries of c:= transpose(A)*b ---*/ - + for (iVar = 0; iVar < nPrimVarGrad; iVar++) for (iDim = 0; iDim < nDim; iDim++) Cvector[iVar][iDim] += ((rotCoord_j[iDim]-rotCoord_i[iDim])* (rotPrim_j[iVar]-rotPrim_i[iVar])/weight); - + } } } - + /*--- We store and communicate the increments for the matching upper triangular matrix (weights) and the r.h.s. vector. These will be accumulated before completing the L-S gradient calculation for each periodic point. ---*/ - + if (nDim == 2) { bufDSend[buf_offset] = r11; buf_offset++; bufDSend[buf_offset] = r12; buf_offset++; @@ -1266,38 +1265,38 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, bufDSend[buf_offset] = r11; buf_offset++; bufDSend[buf_offset] = r12; buf_offset++; bufDSend[buf_offset] = r13; buf_offset++; - + bufDSend[buf_offset] = 0.0; buf_offset++; bufDSend[buf_offset] = r22; buf_offset++; bufDSend[buf_offset] = r23_a; buf_offset++; - + bufDSend[buf_offset] = 0.0; buf_offset++; bufDSend[buf_offset] = r23_b; buf_offset++; bufDSend[buf_offset] = r33; buf_offset++; } - + for (iVar = 0; iVar < nPrimVarGrad; iVar++) { for (iDim = 0; iDim < nDim; iDim++) { bufDSend[buf_offset] = Cvector[iVar][iDim]; buf_offset++; } } - + break; - + case PERIODIC_LIM_PRIM_1: - + /*--- The first phase of the periodic limiter calculation ensures that the proper min and max of the solution are found among all nodes adjacent to periodic faces. ---*/ - + /*--- We send the min and max over "our" neighbours. ---*/ - + for (iVar = 0; iVar < nPrimVarGrad; iVar++) { Sol_Min[iVar] = base_nodes->GetSolution_Min(iPoint, iVar); Sol_Max[iVar] = base_nodes->GetSolution_Max(iPoint, iVar); } - + for (iNeighbor = 0; iNeighbor < geometry->node[iPoint]->GetnPoint(); iNeighbor++) { jPoint = geometry->node[iPoint]->GetPoint(iNeighbor); for (iVar = 0; iVar < nPrimVarGrad; iVar++) { @@ -1305,26 +1304,26 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, Sol_Max[iVar] = max(Sol_Max[iVar], base_nodes->GetPrimitive(jPoint, iVar)); } } - + for (iVar = 0; iVar < nPrimVarGrad; iVar++) { bufDSend[buf_offset+iVar] = Sol_Min[iVar]; bufDSend[buf_offset+nPrimVarGrad+iVar] = Sol_Max[iVar]; } - + /*--- Rotate the momentum components of the min/max. ---*/ - + if (rotate_periodic) { if (nDim == 2) { bufDSend[buf_offset+1] = (rotMatrix[0][0]*Sol_Min[1] + rotMatrix[0][1]*Sol_Min[2]); bufDSend[buf_offset+2] = (rotMatrix[1][0]*Sol_Min[1] + rotMatrix[1][1]*Sol_Min[2]); - + bufDSend[buf_offset+nPrimVarGrad+1] = (rotMatrix[0][0]*Sol_Max[1] + rotMatrix[0][1]*Sol_Max[2]); bufDSend[buf_offset+nPrimVarGrad+2] = (rotMatrix[1][0]*Sol_Max[1] + rotMatrix[1][1]*Sol_Max[2]); - + } else { bufDSend[buf_offset+1] = (rotMatrix[0][0]*Sol_Min[1] + rotMatrix[0][1]*Sol_Min[2] + @@ -1335,7 +1334,7 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, bufDSend[buf_offset+3] = (rotMatrix[2][0]*Sol_Min[1] + rotMatrix[2][1]*Sol_Min[2] + rotMatrix[2][2]*Sol_Min[3]); - + bufDSend[buf_offset+nPrimVarGrad+1] = (rotMatrix[0][0]*Sol_Max[1] + rotMatrix[0][1]*Sol_Max[2] + rotMatrix[0][2]*Sol_Max[3]); @@ -1347,26 +1346,26 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, rotMatrix[2][2]*Sol_Max[3]); } } - + break; - + case PERIODIC_LIM_PRIM_2: - + /*--- The second phase of the periodic limiter calculation ensures that the correct minimum value of the limiter is found for a node on a periodic face and stores it. ---*/ - + for (iVar = 0; iVar < nPrimVarGrad; iVar++) { bufDSend[buf_offset+iVar] = base_nodes->GetLimiter_Primitive(iPoint, iVar); } - + if (rotate_periodic) { if (nDim == 2) { bufDSend[buf_offset+1] = (rotMatrix[0][0]*base_nodes->GetLimiter_Primitive(iPoint,1) + rotMatrix[0][1]*base_nodes->GetLimiter_Primitive(iPoint,2)); bufDSend[buf_offset+2] = (rotMatrix[1][0]*base_nodes->GetLimiter_Primitive(iPoint,1) + rotMatrix[1][1]*base_nodes->GetLimiter_Primitive(iPoint,2)); - + } else { bufDSend[buf_offset+1] = (rotMatrix[0][0]*base_nodes->GetLimiter_Primitive(iPoint,1) + @@ -1380,22 +1379,22 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, rotMatrix[2][2]*base_nodes->GetLimiter_Primitive(iPoint,3)); } } - + break; - + case PERIODIC_LIM_SOL_1: - + /*--- The first phase of the periodic limiter calculation ensures that the proper min and max of the solution are found among all nodes adjacent to periodic faces. ---*/ - + /*--- We send the min and max over "our" neighbours. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { Sol_Min[iVar] = base_nodes->GetSolution_Min(iPoint, iVar); Sol_Max[iVar] = base_nodes->GetSolution_Max(iPoint, iVar); } - + for (iNeighbor = 0; iNeighbor < geometry->node[iPoint]->GetnPoint(); iNeighbor++) { jPoint = geometry->node[iPoint]->GetPoint(iNeighbor); for (iVar = 0; iVar < nVar; iVar++) { @@ -1403,27 +1402,27 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, Sol_Max[iVar] = max(Sol_Max[iVar], base_nodes->GetSolution(jPoint, iVar)); } } - + for (iVar = 0; iVar < nVar; iVar++) { bufDSend[buf_offset+iVar] = Sol_Min[iVar]; bufDSend[buf_offset+nVar+iVar] = Sol_Max[iVar]; } - + /*--- Rotate the momentum components of the min/max. ---*/ - + if (rotate_periodic) { - + if (nDim == 2) { bufDSend[buf_offset+1] = (rotMatrix[0][0]*Sol_Min[1] + rotMatrix[0][1]*Sol_Min[2]); bufDSend[buf_offset+2] = (rotMatrix[1][0]*Sol_Min[1] + rotMatrix[1][1]*Sol_Min[2]); - + bufDSend[buf_offset+nVar+1] = (rotMatrix[0][0]*Sol_Max[1] + rotMatrix[0][1]*Sol_Max[2]); bufDSend[buf_offset+nVar+2] = (rotMatrix[1][0]*Sol_Max[1] + rotMatrix[1][1]*Sol_Max[2]); - + } else { bufDSend[buf_offset+1] = (rotMatrix[0][0]*Sol_Min[1] + @@ -1435,7 +1434,7 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, bufDSend[buf_offset+3] = (rotMatrix[2][0]*Sol_Min[1] + rotMatrix[2][1]*Sol_Min[2] + rotMatrix[2][2]*Sol_Min[3]); - + bufDSend[buf_offset+nVar+1] = (rotMatrix[0][0]*Sol_Max[1] + rotMatrix[0][1]*Sol_Max[2] + rotMatrix[0][2]*Sol_Max[3]); @@ -1445,29 +1444,29 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, bufDSend[buf_offset+nVar+3] = (rotMatrix[2][0]*Sol_Max[1] + rotMatrix[2][1]*Sol_Max[2] + rotMatrix[2][2]*Sol_Max[3]); - + } } - + break; - + case PERIODIC_LIM_SOL_2: - + /*--- The second phase of the periodic limiter calculation ensures that the correct minimum value of the limiter is found for a node on a periodic face and stores it. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { bufDSend[buf_offset+iVar] = base_nodes->GetLimiter(iPoint, iVar); } - + if (rotate_periodic) { if (nDim == 2) { bufDSend[buf_offset+1] = (rotMatrix[0][0]*base_nodes->GetLimiter(iPoint,1) + rotMatrix[0][1]*base_nodes->GetLimiter(iPoint,2)); bufDSend[buf_offset+2] = (rotMatrix[1][0]*base_nodes->GetLimiter(iPoint,1) + rotMatrix[1][1]*base_nodes->GetLimiter(iPoint,2)); - + } else { bufDSend[buf_offset+1] = (rotMatrix[0][0]*base_nodes->GetLimiter(iPoint,1) + @@ -1481,37 +1480,37 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, rotMatrix[2][2]*base_nodes->GetLimiter(iPoint,3)); } } - + break; - + default: SU2_MPI::Error("Unrecognized quantity for periodic communication.", CURRENT_FUNCTION); break; } } - + /*--- Launch the point-to-point MPI send for this message. ---*/ - + geometry->PostPeriodicSends(geometry, config, MPI_TYPE, iMessage); - + } } - + delete [] Diff; delete [] Und_Lapl; delete [] Sol_Min; delete [] Sol_Max; delete [] rotPrim_i; delete [] rotPrim_j; - + for (iVar = 0; iVar < ICOUNT; iVar++) { delete [] jacBlock[iVar]; delete [] rotBlock[iVar]; } delete [] jacBlock; delete [] rotBlock; - + } void CSolver::CompletePeriodicComms(CGeometry *geometry, @@ -1527,33 +1526,33 @@ void CSolver::CompletePeriodicComms(CGeometry *geometry, unsigned short nPeriodic = config->GetnMarker_Periodic(); unsigned short iDim, jDim, iVar, jVar, iPeriodic, nNeighbor; - + unsigned long iPoint, iRecv, nRecv, msg_offset, buf_offset, total_index; - + int source, iMessage, jRecv; - + SU2_MPI::Status status; - + su2double *Diff = new su2double[nVar]; - + su2double Time_Step, Volume, Solution_Min, Solution_Max, Limiter_Min; - + /*--- Set some local pointers to make access simpler. ---*/ - + su2double *bufDRecv = geometry->bufD_PeriodicRecv; - + unsigned short *bufSRecv = geometry->bufS_PeriodicRecv; - + /*--- Store the data that was communicated into the appropriate location within the local class data structures. ---*/ - + if (geometry->nPeriodicRecv > 0) { - + for (iMessage = 0; iMessage < geometry->nPeriodicRecv; iMessage++) { - + /*--- For efficiency, recv the messages dynamically based on the order they arrive. ---*/ - + #ifdef HAVE_MPI /*--- Once we have recv'd a message, get the source rank. ---*/ int ind; @@ -1565,83 +1564,83 @@ void CSolver::CompletePeriodicComms(CGeometry *geometry, /*--- For serial calculations, we know the rank. ---*/ source = rank; #endif - + /*--- We know the offsets based on the source rank. ---*/ - + jRecv = geometry->PeriodicRecv2Neighbor[source]; - + /*--- Get the offset in the buffer for the start of this message. ---*/ - + msg_offset = geometry->nPoint_PeriodicRecv[jRecv]; - + /*--- Get the number of packets to be received in this message. ---*/ - + nRecv = (geometry->nPoint_PeriodicRecv[jRecv+1] - geometry->nPoint_PeriodicRecv[jRecv]); - + for (iRecv = 0; iRecv < nRecv; iRecv++) { - + /*--- Get the local index for this communicated data. ---*/ - + iPoint = geometry->Local_Point_PeriodicRecv[msg_offset + iRecv]; iPeriodic = geometry->Local_Marker_PeriodicRecv[msg_offset + iRecv]; - + /*--- While all periodic face data was accumulated, we only store the values for the current pair of periodic faces. This is slightly inefficient when we have multiple pairs of periodic faces, but it simplifies the communications. ---*/ - + if ((iPeriodic == val_periodic_index) || (iPeriodic == val_periodic_index + nPeriodic/2)) { - + /*--- Compute the offset in the recv buffer for this point. ---*/ - + buf_offset = (msg_offset + iRecv)*geometry->countPerPeriodicPoint; - + /*--- Store the data correctly depending on the quantity. ---*/ - + switch (commType) { - + case PERIODIC_VOLUME: - + /*--- The periodic points need to keep track of their total volume spread across the periodic faces. ---*/ - + Volume = (bufDRecv[buf_offset] + geometry->node[iPoint]->GetPeriodicVolume()); geometry->node[iPoint]->SetPeriodicVolume(Volume); - + break; - + case PERIODIC_NEIGHBORS: - + /*--- Store the extra neighbors on the periodic face. ---*/ - + nNeighbor = (geometry->node[iPoint]->GetnNeighbor() + bufSRecv[buf_offset]); geometry->node[iPoint]->SetnNeighbor(nNeighbor); - + break; - + case PERIODIC_RESIDUAL: - + /*--- Access the residual from the donor. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { Residual[iVar] = bufDRecv[buf_offset]; buf_offset++; } - + /*--- Check the computed time step against the donor value and keep the minimum in order to be conservative. ---*/ - + Time_Step = base_nodes->GetDelta_Time(iPoint); if (bufDRecv[buf_offset] < Time_Step) base_nodes->SetDelta_Time(iPoint,bufDRecv[buf_offset]); buf_offset++; - + /*--- Access the Jacobian from the donor if implicit. ---*/ - + if (implicit_periodic) { for (iVar = 0; iVar < nVar; iVar++) { for (jVar = 0; jVar < nVar; jVar++) { @@ -1650,11 +1649,11 @@ void CSolver::CompletePeriodicComms(CGeometry *geometry, } } } - + /*--- Add contributions to total residual. ---*/ - + LinSysRes.AddBlock(iPoint, Residual); - + /*--- For implicit integration, we choose the first periodic face of each pair to be the master/owner of the solution for the linear system while fixing the @@ -1662,11 +1661,11 @@ void CSolver::CompletePeriodicComms(CGeometry *geometry, we remove the Jacobian and residual contributions from the passive face such that it does not participate in the linear solve. ---*/ - + if (implicit_periodic) { - + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - + if (iPeriodic == val_periodic_index + nPeriodic/2) { for (iVar = 0; iVar < nVar; iVar++) { LinSysRes.SetBlock_Zero(iPoint, iVar); @@ -1674,98 +1673,98 @@ void CSolver::CompletePeriodicComms(CGeometry *geometry, Jacobian.DeleteValsRowi(total_index); } } - + } - + break; - + case PERIODIC_IMPLICIT: - + /*--- For implicit integration, we choose the first periodic face of each pair to be the master/owner of the solution for the linear system while fixing the solution at the matching face during the solve. Here, we are updating the solution at the passive nodes using the new solution from the master. ---*/ - + if ((implicit_periodic) && (iPeriodic == val_periodic_index + nPeriodic/2)) { - + /*--- Access the solution from the donor. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { Solution[iVar] = bufDRecv[buf_offset]; buf_offset++; } - + /*--- Directly set the solution on the passive periodic face that is provided from the master. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { base_nodes->SetSolution(iPoint, iVar, Solution[iVar]); base_nodes->SetSolution_Old(iPoint, iVar, Solution[iVar]); } - + } - + break; - + case PERIODIC_LAPLACIAN: - + /*--- Adjust the undivided Laplacian. The accumulation was with a subtraction before communicating, so now just add. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) Diff[iVar] = bufDRecv[buf_offset+iVar]; - + base_nodes->AddUnd_Lapl(iPoint,Diff); - + break; - + case PERIODIC_MAX_EIG: - + /*--- Simple accumulation of the max eig on periodic faces. ---*/ - + base_nodes->AddLambda(iPoint,bufDRecv[buf_offset]); - + break; - + case PERIODIC_SENSOR: - + /*--- Simple accumulation of the sensors on periodic faces. ---*/ - + iPoint_UndLapl[iPoint] += bufDRecv[buf_offset]; buf_offset++; jPoint_UndLapl[iPoint] += bufDRecv[buf_offset]; - + break; - + case PERIODIC_SOL_GG: - + /*--- For G-G, we accumulate partial gradients then compute the final value using the entire volume of the periodic cell. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) for (iDim = 0; iDim < nDim; iDim++) base_nodes->SetGradient(iPoint, iVar, iDim, bufDRecv[buf_offset+iVar*nDim+iDim] + base_nodes->GetGradient(iPoint, iVar, iDim)); - + break; - + case PERIODIC_PRIM_GG: - + /*--- For G-G, we accumulate partial gradients then compute the final value using the entire volume of the periodic cell. ---*/ - + for (iVar = 0; iVar < nPrimVarGrad; iVar++) for (iDim = 0; iDim < nDim; iDim++) base_nodes->SetGradient_Primitive(iPoint, iVar, iDim, bufDRecv[buf_offset+iVar*nDim+iDim] + base_nodes->GetGradient_Primitive(iPoint, iVar, iDim)); break; - + case PERIODIC_SOL_LS: case PERIODIC_SOL_ULS: - + /*--- For L-S, we build the upper triangular matrix and the r.h.s. vector by accumulating from all periodic partial control volumes. ---*/ - + for (iDim = 0; iDim < nDim; iDim++) { for (jDim = 0; jDim < nDim; jDim++) { base_nodes->AddRmatrix(iPoint, iDim,jDim,bufDRecv[buf_offset]); @@ -1778,15 +1777,15 @@ void CSolver::CompletePeriodicComms(CGeometry *geometry, buf_offset++; } } - + break; - + case PERIODIC_PRIM_LS: case PERIODIC_PRIM_ULS: - + /*--- For L-S, we build the upper triangular matrix and the r.h.s. vector by accumulating from all periodic partial control volumes. ---*/ - + for (iDim = 0; iDim < nDim; iDim++) { for (jDim = 0; jDim < nDim; jDim++) { base_nodes->AddRmatrix(iPoint, iDim,jDim,bufDRecv[buf_offset]); @@ -1799,125 +1798,125 @@ void CSolver::CompletePeriodicComms(CGeometry *geometry, buf_offset++; } } - + break; - + case PERIODIC_LIM_PRIM_1: - + /*--- Update solution min/max with min/max between "us" and the periodic match plus its neighbors, computation will need to be concluded on "our" side to account for "our" neighbors. ---*/ - + for (iVar = 0; iVar < nPrimVarGrad; iVar++) { - + /*--- Solution minimum. ---*/ - + Solution_Min = min(base_nodes->GetSolution_Min(iPoint, iVar), bufDRecv[buf_offset+iVar]); base_nodes->SetSolution_Min(iPoint, iVar, Solution_Min); - + /*--- Solution maximum. ---*/ - + Solution_Max = max(base_nodes->GetSolution_Max(iPoint, iVar), bufDRecv[buf_offset+nPrimVarGrad+iVar]); base_nodes->SetSolution_Max(iPoint, iVar, Solution_Max); } - + break; - + case PERIODIC_LIM_PRIM_2: - + /*--- Check the min values found on the matching periodic faces for the limiter, and store the proper min value. ---*/ - + for (iVar = 0; iVar < nPrimVarGrad; iVar++) { Limiter_Min = min(base_nodes->GetLimiter_Primitive(iPoint, iVar), bufDRecv[buf_offset+iVar]); base_nodes->SetLimiter_Primitive(iPoint, iVar, Limiter_Min); } - + break; - + case PERIODIC_LIM_SOL_1: - + /*--- Update solution min/max with min/max between "us" and the periodic match plus its neighbors, computation will need to be concluded on "our" side to account for "our" neighbors. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { - + /*--- Solution minimum. ---*/ - + Solution_Min = min(base_nodes->GetSolution_Min(iPoint, iVar), bufDRecv[buf_offset+iVar]); base_nodes->SetSolution_Min(iPoint, iVar, Solution_Min); - + /*--- Solution maximum. ---*/ - + Solution_Max = max(base_nodes->GetSolution_Max(iPoint, iVar), bufDRecv[buf_offset+nVar+iVar]); base_nodes->SetSolution_Max(iPoint, iVar, Solution_Max); - + } - + break; - + case PERIODIC_LIM_SOL_2: - + /*--- Check the min values found on the matching periodic faces for the limiter, and store the proper min value. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { Limiter_Min = min(base_nodes->GetLimiter_Primitive(iPoint, iVar), bufDRecv[buf_offset+iVar]); base_nodes->SetLimiter_Primitive(iPoint, iVar, Limiter_Min); } - + break; - + default: - + SU2_MPI::Error("Unrecognized quantity for periodic communication.", CURRENT_FUNCTION); break; - + } } } } - + /*--- Verify that all non-blocking point-to-point sends have finished. Note that this should be satisfied, as we have received all of the data in the loop above at this point. ---*/ - + #ifdef HAVE_MPI SU2_MPI::Waitall(geometry->nPeriodicSend, geometry->req_PeriodicSend, MPI_STATUS_IGNORE); #endif - + } - + delete [] Diff; - + } void CSolver::InitiateComms(CGeometry *geometry, CConfig *config, unsigned short commType) { - + /*--- Local variables ---*/ - + unsigned short iVar, iDim; unsigned short COUNT_PER_POINT = 0; unsigned short MPI_TYPE = 0; - + unsigned long iPoint, msg_offset, buf_offset; - + int iMessage, iSend, nSend; - + /*--- Set the size of the data packet and type depending on quantity. ---*/ - + switch (commType) { case SOLUTION: case SOLUTION_OLD: @@ -1991,50 +1990,50 @@ void CSolver::InitiateComms(CGeometry *geometry, CURRENT_FUNCTION); break; } - + /*--- Check to make sure we have created a large enough buffer for these comms during preprocessing. This is only for the su2double buffer. It will be reallocated whenever we find a larger count per point. After the first cycle of comms, this should be inactive. ---*/ - + if (COUNT_PER_POINT > geometry->countPerPoint) { geometry->AllocateP2PComms(COUNT_PER_POINT); } - + /*--- Set some local pointers to make access simpler. ---*/ - + su2double *bufDSend = geometry->bufD_P2PSend; - + /*--- Load the specified quantity from the solver into the generic communication buffer in the geometry class. ---*/ - + if (geometry->nP2PSend > 0) { - + /*--- Post all non-blocking recvs first before sends. ---*/ - + geometry->PostP2PRecvs(geometry, config, MPI_TYPE, false); - + for (iMessage = 0; iMessage < geometry->nP2PSend; iMessage++) { - + /*--- Get the offset in the buffer for the start of this message. ---*/ - + msg_offset = geometry->nPoint_P2PSend[iMessage]; - + /*--- Total count can include multiple pieces of data per element. ---*/ - + nSend = (geometry->nPoint_P2PSend[iMessage+1] - geometry->nPoint_P2PSend[iMessage]); - + for (iSend = 0; iSend < nSend; iSend++) { - + /*--- Get the local index for this communicated data. ---*/ - + iPoint = geometry->Local_Point_P2PSend[msg_offset + iSend]; - + /*--- Compute the offset in the recv buffer for this point. ---*/ - + buf_offset = (msg_offset + iSend)*geometry->countPerPoint; - + switch (commType) { case SOLUTION: for (iVar = 0; iVar < nVar; iVar++) @@ -2136,73 +2135,73 @@ void CSolver::InitiateComms(CGeometry *geometry, break; } } - + /*--- Launch the point-to-point MPI send for this message. ---*/ - + geometry->PostP2PSends(geometry, config, MPI_TYPE, iMessage, false); - + } } - + } void CSolver::CompleteComms(CGeometry *geometry, CConfig *config, unsigned short commType) { - + /*--- Local variables ---*/ - + unsigned short iDim, iVar; unsigned long iPoint, iRecv, nRecv, msg_offset, buf_offset; - + int ind, source, iMessage, jRecv; SU2_MPI::Status status; - + /*--- Set some local pointers to make access simpler. ---*/ - + su2double *bufDRecv = geometry->bufD_P2PRecv; - + /*--- Store the data that was communicated into the appropriate location within the local class data structures. ---*/ - + if (geometry->nP2PRecv > 0) { - + for (iMessage = 0; iMessage < geometry->nP2PRecv; iMessage++) { - + /*--- For efficiency, recv the messages dynamically based on the order they arrive. ---*/ - + SU2_MPI::Waitany(geometry->nP2PRecv, geometry->req_P2PRecv, &ind, &status); - + /*--- Once we have recv'd a message, get the source rank. ---*/ - + source = status.MPI_SOURCE; - + /*--- We know the offsets based on the source rank. ---*/ - + jRecv = geometry->P2PRecv2Neighbor[source]; - + /*--- Get the offset in the buffer for the start of this message. ---*/ - + msg_offset = geometry->nPoint_P2PRecv[jRecv]; - + /*--- Get the number of packets to be received in this message. ---*/ - + nRecv = (geometry->nPoint_P2PRecv[jRecv+1] - geometry->nPoint_P2PRecv[jRecv]); - + for (iRecv = 0; iRecv < nRecv; iRecv++) { - + /*--- Get the local index for this communicated data. ---*/ - + iPoint = geometry->Local_Point_P2PRecv[msg_offset + iRecv]; - + /*--- Compute the offset in the recv buffer for this point. ---*/ - + buf_offset = (msg_offset + iRecv)*geometry->countPerPoint; - + /*--- Store the data correctly depending on the quantity. ---*/ - + switch (commType) { case SOLUTION: for (iVar = 0; iVar < nVar; iVar++) @@ -2305,21 +2304,21 @@ void CSolver::CompleteComms(CGeometry *geometry, } } } - + /*--- Verify that all non-blocking point-to-point sends have finished. Note that this should be satisfied, as we have received all of the data in the loop above at this point. ---*/ - + #ifdef HAVE_MPI SU2_MPI::Waitall(geometry->nP2PSend, geometry->req_P2PSend, MPI_STATUS_IGNORE); #endif - + } - + } void CSolver::ResetCFLAdapt(){ - NonLinRes_Series.clear(); + NonLinRes_Series.clear(); NonLinRes_Value = 0; NonLinRes_Func = 0; Old_Func = 0; @@ -2331,7 +2330,7 @@ void CSolver::ResetCFLAdapt(){ void CSolver::AdaptCFLNumber(CGeometry **geometry, CSolver ***solver_container, CConfig *config) { - + /* Adapt the CFL number on all multigrid levels using an exponential progression with under-relaxation approach. */ @@ -2340,23 +2339,23 @@ void CSolver::AdaptCFLNumber(CGeometry **geometry, const su2double CFLFactorIncrease = config->GetCFL_AdaptParam(1); const su2double CFLMin = config->GetCFL_AdaptParam(2); const su2double CFLMax = config->GetCFL_AdaptParam(3); - + for (unsigned short iMesh = 0; iMesh <= config->GetnMGLevels(); iMesh++) { - + /* Store the mean flow, and turbulence solvers more clearly. */ - + CSolver *solverFlow = solver_container[iMesh][FLOW_SOL]; CSolver *solverTurb = solver_container[iMesh][TURB_SOL]; - + /* Compute the reduction factor for CFLs on the coarse levels. */ - + if (iMesh == MESH_0) { MGFactor[iMesh] = 1.0; } else { const su2double CFLRatio = config->GetCFL(iMesh)/config->GetCFL(iMesh-1); MGFactor[iMesh] = MGFactor[iMesh-1]*CFLRatio; } - + /* Check whether we achieved the requested reduction in the linear solver residual within the specified number of linear iterations. */ @@ -2378,9 +2377,9 @@ void CSolver::AdaptCFLNumber(CGeometry **geometry, Old_Func = New_Func; unsigned short Res_Count = 100; if (NonLinRes_Series.size() == 0) NonLinRes_Series.resize(Res_Count,0.0); - + /* Sum the RMS residuals for all equations. */ - + New_Func = 0.0; for (unsigned short iVar = 0; iVar < solverFlow->GetnVar(); iVar++) { New_Func += solverFlow->GetRes_RMS(iVar); @@ -2390,21 +2389,21 @@ void CSolver::AdaptCFLNumber(CGeometry **geometry, New_Func += solverTurb->GetRes_RMS(iVar); } } - + /* Compute the difference in the nonlinear residuals between the current and previous iterations. */ - + NonLinRes_Func = (New_Func - Old_Func); NonLinRes_Series[NonLinRes_Counter] = NonLinRes_Func; - + /* Increment the counter, if we hit the max size, then start over. */ - + NonLinRes_Counter++; if (NonLinRes_Counter == Res_Count) NonLinRes_Counter = 0; /* Sum the total change in nonlinear residuals over the previous set of all stored iterations. */ - + NonLinRes_Value = New_Func; if (config->GetTimeIter() >= Res_Count) { NonLinRes_Value = 0.0; @@ -2416,7 +2415,7 @@ void CSolver::AdaptCFLNumber(CGeometry **geometry, residual, then we are not decreasing the nonlinear residual at a high rate. In this situation, we force a reduction of the CFL in all cells. Reset the array so that we delay the next decrease for some iterations. */ - + if (fabs(NonLinRes_Value) < 0.1*New_Func) { reduceCFL = true; NonLinRes_Counter = 0; @@ -2425,32 +2424,32 @@ void CSolver::AdaptCFLNumber(CGeometry **geometry, } /* Loop over all points on this grid and apply CFL adaption. */ - + su2double myCFLMin = 1e30; su2double myCFLMax = 0.0; su2double myCFLSum = 0.0; for (unsigned long iPoint = 0; iPoint < geometry[iMesh]->GetnPointDomain(); iPoint++) { - + /* Get the current local flow CFL number at this point. */ - + su2double CFL = solverFlow->GetNodes()->GetLocalCFL(iPoint); - + /* Get the current under-relaxation parameters that were computed during the previous nonlinear update. If we have a turbulence model, take the minimum under-relaxation parameter between the mean flow and turbulence systems. */ - + su2double underRelaxationFlow = solverFlow->GetNodes()->GetUnderRelaxation(iPoint); su2double underRelaxationTurb = 1.0; if ((iMesh == MESH_0) && (config->GetKind_Turb_Model() != NONE)) underRelaxationTurb = solverTurb->GetNodes()->GetUnderRelaxation(iPoint); const su2double underRelaxation = min(underRelaxationFlow,underRelaxationTurb); - + /* If we apply a small under-relaxation parameter for stability, then we should reduce the CFL before the next iteration. If we are able to add the entire nonlinear update (under-relaxation = 1) then we schedule an increase the CFL number for the next iteration. */ - + su2double CFLFactor = 1.0; if ((underRelaxation < 0.1)) { CFLFactor = CFLFactorDecrease; @@ -2459,9 +2458,9 @@ void CSolver::AdaptCFLNumber(CGeometry **geometry, } else { CFLFactor = CFLFactorIncrease; } - + /* Check if we are hitting the min or max and adjust. */ - + if (CFL*CFLFactor <= CFLMin) { CFL = CFLMin; CFLFactor = MGFactor[iMesh]; @@ -2469,65 +2468,65 @@ void CSolver::AdaptCFLNumber(CGeometry **geometry, CFL = CFLMax; CFLFactor = MGFactor[iMesh]; } - + /* If we detect a stalled nonlinear residual, then force the CFL for all points to the minimum temporarily to restart the ramp. */ - + if (reduceCFL) { CFL = CFLMin; CFLFactor = MGFactor[iMesh]; } - + /* Apply the adjustment to the CFL and store local values. */ - + CFL *= CFLFactor; solverFlow->GetNodes()->SetLocalCFL(iPoint, CFL); if ((iMesh == MESH_0) && (config->GetKind_Turb_Model() != NONE)) { solverTurb->GetNodes()->SetLocalCFL(iPoint, CFL); } - + /* Store min and max CFL for reporting on fine grid. */ - + myCFLMin = min(CFL,myCFLMin); myCFLMax = max(CFL,myCFLMax); myCFLSum += CFL; - + } - + /* Reduce the min/max/avg local CFL numbers. */ - + su2double rbuf_min, sbuf_min; sbuf_min = myCFLMin; SU2_MPI::Allreduce(&sbuf_min, &rbuf_min, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); Min_CFL_Local = rbuf_min; - + su2double rbuf_max, sbuf_max; sbuf_max = myCFLMax; SU2_MPI::Allreduce(&sbuf_max, &rbuf_max, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); Max_CFL_Local = rbuf_max; - + su2double rbuf_sum, sbuf_sum; sbuf_sum = myCFLSum; SU2_MPI::Allreduce(&sbuf_sum, &rbuf_sum, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); Avg_CFL_Local = rbuf_sum; - + unsigned long Global_nPointDomain; unsigned long Local_nPointDomain = geometry[iMesh]->GetnPointDomain(); SU2_MPI::Allreduce(&Local_nPointDomain, &Global_nPointDomain, 1, MPI_UNSIGNED_LONG, MPI_SUM, MPI_COMM_WORLD); Avg_CFL_Local /= (su2double)Global_nPointDomain; - + } - + } void CSolver::SetResidual_RMS(CGeometry *geometry, CConfig *config) { unsigned short iVar; - + #ifndef HAVE_MPI - + for (iVar = 0; iVar < nVar; iVar++) { - + if (GetRes_RMS(iVar) != GetRes_RMS(iVar)) { SU2_MPI::Error("SU2 has diverged. (NaN detected)", CURRENT_FUNCTION); } @@ -2536,65 +2535,65 @@ void CSolver::SetResidual_RMS(CGeometry *geometry, CConfig *config) { } SetRes_RMS(iVar, max(EPS*EPS, sqrt(GetRes_RMS(iVar)/geometry->GetnPoint()))); - + } - + #else - + int nProcessor = size, iProcessor; su2double *sbuf_residual, *rbuf_residual, *sbuf_coord, *rbuf_coord, *Coord; unsigned long *sbuf_point, *rbuf_point, Global_nPointDomain; unsigned short iDim; - + /*--- Set the L2 Norm residual in all the processors ---*/ - + sbuf_residual = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) sbuf_residual[iVar] = 0.0; rbuf_residual = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) rbuf_residual[iVar] = 0.0; - + for (iVar = 0; iVar < nVar; iVar++) sbuf_residual[iVar] = GetRes_RMS(iVar); - + if (config->GetComm_Level() == COMM_FULL) { - + unsigned long Local_nPointDomain = geometry->GetnPointDomain(); SU2_MPI::Allreduce(sbuf_residual, rbuf_residual, nVar, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); SU2_MPI::Allreduce(&Local_nPointDomain, &Global_nPointDomain, 1, MPI_UNSIGNED_LONG, MPI_SUM, MPI_COMM_WORLD); - + } else { - + /*--- Reduced MPI comms have been requested. Use a local residual only. ---*/ - + for (iVar = 0; iVar < nVar; iVar++) rbuf_residual[iVar] = sbuf_residual[iVar]; Global_nPointDomain = geometry->GetnPointDomain(); - + } - - + + for (iVar = 0; iVar < nVar; iVar++) { - + if (rbuf_residual[iVar] != rbuf_residual[iVar]) { SU2_MPI::Error("SU2 has diverged. (NaN detected)", CURRENT_FUNCTION); } - + SetRes_RMS(iVar, max(EPS*EPS, sqrt(rbuf_residual[iVar]/Global_nPointDomain))); - + } delete [] sbuf_residual; delete [] rbuf_residual; - + /*--- Set the Maximum residual in all the processors ---*/ - + if (config->GetComm_Level() == COMM_FULL) { - + sbuf_residual = new su2double [nVar]; for (iVar = 0; iVar < nVar; iVar++) sbuf_residual[iVar] = 0.0; sbuf_point = new unsigned long [nVar]; for (iVar = 0; iVar < nVar; iVar++) sbuf_point[iVar] = 0; sbuf_coord = new su2double[nVar*nDim]; for (iVar = 0; iVar < nVar*nDim; iVar++) sbuf_coord[iVar] = 0.0; - + rbuf_residual = new su2double [nProcessor*nVar]; for (iVar = 0; iVar < nProcessor*nVar; iVar++) rbuf_residual[iVar] = 0.0; rbuf_point = new unsigned long [nProcessor*nVar]; for (iVar = 0; iVar < nProcessor*nVar; iVar++) rbuf_point[iVar] = 0; rbuf_coord = new su2double[nProcessor*nVar*nDim]; for (iVar = 0; iVar < nProcessor*nVar*nDim; iVar++) rbuf_coord[iVar] = 0.0; - + for (iVar = 0; iVar < nVar; iVar++) { sbuf_residual[iVar] = GetRes_Max(iVar); sbuf_point[iVar] = GetPoint_Max(iVar); @@ -2602,30 +2601,30 @@ void CSolver::SetResidual_RMS(CGeometry *geometry, CConfig *config) { for (iDim = 0; iDim < nDim; iDim++) sbuf_coord[iVar*nDim+iDim] = Coord[iDim]; } - + SU2_MPI::Allgather(sbuf_residual, nVar, MPI_DOUBLE, rbuf_residual, nVar, MPI_DOUBLE, MPI_COMM_WORLD); SU2_MPI::Allgather(sbuf_point, nVar, MPI_UNSIGNED_LONG, rbuf_point, nVar, MPI_UNSIGNED_LONG, MPI_COMM_WORLD); SU2_MPI::Allgather(sbuf_coord, nVar*nDim, MPI_DOUBLE, rbuf_coord, nVar*nDim, MPI_DOUBLE, MPI_COMM_WORLD); - + for (iVar = 0; iVar < nVar; iVar++) { for (iProcessor = 0; iProcessor < nProcessor; iProcessor++) { AddRes_Max(iVar, rbuf_residual[iProcessor*nVar+iVar], rbuf_point[iProcessor*nVar+iVar], &rbuf_coord[iProcessor*nVar*nDim+iVar*nDim]); } } - + delete [] sbuf_residual; delete [] rbuf_residual; - + delete [] sbuf_point; delete [] rbuf_point; - + delete [] sbuf_coord; delete [] rbuf_coord; - + } - + #endif - + } void CSolver::SetResidual_BGS(CGeometry *geometry, CConfig *config) { @@ -2720,7 +2719,7 @@ void CSolver::SetResidual_BGS(CGeometry *geometry, CConfig *config) { } void CSolver::SetRotatingFrame_GCL(CGeometry *geometry, CConfig *config) { - + unsigned short iDim, nDim = geometry->GetnDim(), iVar, nVar = GetnVar(), iMarker; unsigned long iVertex, iEdge; su2double ProjGridVel, *Normal; @@ -2793,11 +2792,11 @@ void CSolver::SetRotatingFrame_GCL(CGeometry *geometry, CConfig *config) { Residual[iVar] = ProjGridVel*Solution[iVar]; LinSysRes.SubtractBlock(Point, Residual); - + } } } - + } void CSolver::SetAuxVar_Gradient_GG(CGeometry *geometry, CConfig *config) { @@ -2892,33 +2891,33 @@ void CSolver::SetGridVel_Gradient(CGeometry *geometry, CConfig *config) { r11, r12, r13, r22, r23, r23_a, r23_b, r33, weight, detR2, z11, z12, z13, z22, z23, z33, product; su2double **Cvector; - + /*--- Note that all nVar entries in this routine have been changed to nDim ---*/ Cvector = new su2double* [nDim]; for (iVar = 0; iVar < nDim; iVar++) Cvector[iVar] = new su2double [nDim]; - + /*--- Loop over points of the grid ---*/ for (iPoint = 0; iPoint < geometry->GetnPointDomain(); iPoint++) { - + Coord_i = geometry->node[iPoint]->GetCoord(); Solution_i = geometry->node[iPoint]->GetGridVel(); - + /*--- Inizialization of variables ---*/ for (iVar = 0; iVar < nDim; iVar++) for (iDim = 0; iDim < nDim; iDim++) Cvector[iVar][iDim] = 0.0; r11 = 0.0; r12 = 0.0; r13 = 0.0; r22 = 0.0; r23 = 0.0; r23_a = 0.0; r23_b = 0.0; r33 = 0.0; - + for (iNeigh = 0; iNeigh < geometry->node[iPoint]->GetnPoint(); iNeigh++) { jPoint = geometry->node[iPoint]->GetPoint(iNeigh); Coord_j = geometry->node[jPoint]->GetCoord(); Solution_j = geometry->node[jPoint]->GetGridVel(); - + weight = 0.0; for (iDim = 0; iDim < nDim; iDim++) weight += (Coord_j[iDim]-Coord_i[iDim])*(Coord_j[iDim]-Coord_i[iDim]); - + /*--- Sumations for entries of upper triangular matrix R ---*/ r11 += (Coord_j[0]-Coord_i[0])*(Coord_j[0]-Coord_i[0])/(weight); r12 += (Coord_j[0]-Coord_i[0])*(Coord_j[1]-Coord_i[1])/(weight); @@ -2929,13 +2928,13 @@ void CSolver::SetGridVel_Gradient(CGeometry *geometry, CConfig *config) { r23_b += (Coord_j[0]-Coord_i[0])*(Coord_j[2]-Coord_i[2])/(weight); r33 += (Coord_j[2]-Coord_i[2])*(Coord_j[2]-Coord_i[2])/(weight); } - + /*--- Entries of c:= transpose(A)*b ---*/ for (iVar = 0; iVar < nDim; iVar++) for (iDim = 0; iDim < nDim; iDim++) Cvector[iVar][iDim] += (Coord_j[iDim]-Coord_i[iDim])*(Solution_j[iVar]-Solution_i[iVar])/(weight); } - + /*--- Entries of upper triangular matrix R ---*/ r11 = sqrt(r11); r12 = r12/(r11); @@ -2981,28 +2980,28 @@ void CSolver::SetGridVel_Gradient(CGeometry *geometry, CConfig *config) { } } } - + /*--- Deallocate memory ---*/ for (iVar = 0; iVar < nDim; iVar++) delete [] Cvector[iVar]; delete [] Cvector; - + } void CSolver::SetAuxVar_Surface_Gradient(CGeometry *geometry, CConfig *config) { - + unsigned short iDim, jDim, iNeigh, iMarker, Boundary; unsigned short nDim = geometry->GetnDim(); unsigned long iPoint, jPoint, iVertex; su2double *Coord_i, *Coord_j, AuxVar_i, AuxVar_j; su2double **Smatrix, *Cvector; - + Smatrix = new su2double* [nDim]; Cvector = new su2double [nDim]; for (iDim = 0; iDim < nDim; iDim++) Smatrix[iDim] = new su2double [nDim]; - - + + /*--- Loop over boundary markers to select those for Euler or NS walls ---*/ for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { Boundary = config->GetMarker_All_KindBC(iMarker); @@ -3011,28 +3010,28 @@ void CSolver::SetAuxVar_Surface_Gradient(CGeometry *geometry, CConfig *config) { case HEAT_FLUX: case ISOTHERMAL: case CHT_WALL_INTERFACE: - + /*--- Loop over points on the surface (Least-Squares approximation) ---*/ for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); if (geometry->node[iPoint]->GetDomain()) { Coord_i = geometry->node[iPoint]->GetCoord(); AuxVar_i = base_nodes->GetAuxVar(iPoint); - + /*--- Inizialization of variables ---*/ for (iDim = 0; iDim < nDim; iDim++) Cvector[iDim] = 0.0; su2double r11 = 0.0, r12 = 0.0, r13 = 0.0, r22 = 0.0, r23 = 0.0, r23_a = 0.0, r23_b = 0.0, r33 = 0.0; - + for (iNeigh = 0; iNeigh < geometry->node[iPoint]->GetnPoint(); iNeigh++) { jPoint = geometry->node[iPoint]->GetPoint(iNeigh); Coord_j = geometry->node[jPoint]->GetCoord(); AuxVar_j = base_nodes->GetAuxVar(jPoint); - + su2double weight = 0; for (iDim = 0; iDim < nDim; iDim++) weight += (Coord_j[iDim]-Coord_i[iDim])*(Coord_j[iDim]-Coord_i[iDim]); - + /*--- Sumations for entries of upper triangular matrix R ---*/ r11 += (Coord_j[0]-Coord_i[0])*(Coord_j[0]-Coord_i[0])/weight; r12 += (Coord_j[0]-Coord_i[0])*(Coord_j[1]-Coord_i[1])/weight; @@ -3043,12 +3042,12 @@ void CSolver::SetAuxVar_Surface_Gradient(CGeometry *geometry, CConfig *config) { r23_b += (Coord_j[0]-Coord_i[0])*(Coord_j[2]-Coord_i[2])/weight; r33 += (Coord_j[2]-Coord_i[2])*(Coord_j[2]-Coord_i[2])/weight; } - + /*--- Entries of c:= transpose(A)*b ---*/ for (iDim = 0; iDim < nDim; iDim++) Cvector[iDim] += (Coord_j[iDim]-Coord_i[iDim])*(AuxVar_j-AuxVar_i)/weight; } - + /*--- Entries of upper triangular matrix R ---*/ r11 = sqrt(r11); r12 = r12/r11; @@ -3100,7 +3099,7 @@ void CSolver::SetAuxVar_Surface_Gradient(CGeometry *geometry, CConfig *config) { break; } } - + /*--- Memory deallocation ---*/ for (iDim = 0; iDim < nDim; iDim++) delete [] Smatrix[iDim]; @@ -3122,16 +3121,16 @@ void CSolver::SetSolution_Limiter(CGeometry *geometry, CConfig *config) { } void CSolver::Gauss_Elimination(su2double** A, su2double* rhs, unsigned short nVar) { - + short iVar, jVar, kVar; su2double weight, aux; - + if (nVar == 1) rhs[0] /= A[0][0]; else { - + /*--- Transform system in Upper Matrix ---*/ - + for (iVar = 1; iVar < (short)nVar; iVar++) { for (jVar = 0; jVar < iVar; jVar++) { weight = A[iVar][jVar]/A[jVar][jVar]; @@ -3140,9 +3139,9 @@ void CSolver::Gauss_Elimination(su2double** A, su2double* rhs, unsigned short nV rhs[iVar] -= weight*rhs[jVar]; } } - + /*--- Backwards substitution ---*/ - + rhs[nVar-1] = rhs[nVar-1]/A[nVar-1][nVar-1]; for (iVar = (short)nVar-2; iVar >= 0; iVar--) { aux = 0; @@ -3152,53 +3151,53 @@ void CSolver::Gauss_Elimination(su2double** A, su2double* rhs, unsigned short nV if (iVar == 0) break; } } - + } void CSolver::Aeroelastic(CSurfaceMovement *surface_movement, CGeometry *geometry, CConfig *config, unsigned long TimeIter) { - + /*--- Variables used for Aeroelastic case ---*/ - + su2double Cl, Cd, Cn, Ct, Cm, Cn_rot; su2double Alpha = config->GetAoA()*PI_NUMBER/180.0; vector structural_solution(4,0.0); //contains solution(displacements and rates) of typical section wing model. - + unsigned short iMarker, iMarker_Monitoring, Monitoring; string Marker_Tag, Monitoring_Tag; - + /*--- Loop over markers and find the ones being monitored. ---*/ - + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { Monitoring = config->GetMarker_All_Monitoring(iMarker); if (Monitoring == YES) { - + /*--- Find the particular marker being monitored and get the forces acting on it. ---*/ - + for (iMarker_Monitoring = 0; iMarker_Monitoring < config->GetnMarker_Monitoring(); iMarker_Monitoring++) { Monitoring_Tag = config->GetMarker_Monitoring_TagBound(iMarker_Monitoring); Marker_Tag = config->GetMarker_All_TagBound(iMarker); if (Marker_Tag == Monitoring_Tag) { - + Cl = GetSurface_CL(iMarker_Monitoring); Cd = GetSurface_CD(iMarker_Monitoring); - + /*--- For typical section wing model want the force normal to the airfoil (in the direction of the spring) ---*/ Cn = Cl*cos(Alpha) + Cd*sin(Alpha); Ct = -Cl*sin(Alpha) + Cd*cos(Alpha); - + Cm = GetSurface_CMz(iMarker_Monitoring); - + /*--- Calculate forces for the Typical Section Wing Model taking into account rotation ---*/ - + /*--- Note that the calculation of the forces and the subsequent displacements ... is only correct for the airfoil that starts at the 0 degree position ---*/ - + if (config->GetKind_GridMovement() == AEROELASTIC_RIGID_MOTION) { su2double Omega, dt, psi; dt = config->GetDelta_UnstTimeND(); Omega = (config->GetRotation_Rate(2)/config->GetOmega_Ref()); psi = Omega*(dt*TimeIter); - + /*--- Correct for the airfoil starting position (This is hardcoded in here) ---*/ if (Monitoring_Tag == "Airfoil1") { psi = psi + 0.0; @@ -3211,55 +3210,55 @@ void CSolver::Aeroelastic(CSurfaceMovement *surface_movement, CGeometry *geometr } else cout << "WARNING: There is a marker that we are monitoring that doesn't match the values hardcoded above!" << endl; - + cout << Monitoring_Tag << " position " << psi*180.0/PI_NUMBER << " degrees. " << endl; - + Cn_rot = Cn*cos(psi) - Ct*sin(psi); //Note the signs are different for accounting for the AOA. Cn = Cn_rot; } - + /*--- Solve the aeroelastic equations for the particular marker(surface) ---*/ - + SolveTypicalSectionWingModel(geometry, Cn, Cm, config, iMarker_Monitoring, structural_solution); - + break; } } - + /*--- Compute the new surface node locations ---*/ surface_movement->AeroelasticDeform(geometry, config, TimeIter, iMarker, iMarker_Monitoring, structural_solution); - + } - + } - + } void CSolver::SetUpTypicalSectionWingModel(vector >& Phi, vector& omega, CConfig *config) { - + /*--- Retrieve values from the config file ---*/ su2double w_h = config->GetAeroelastic_Frequency_Plunge(); su2double w_a = config->GetAeroelastic_Frequency_Pitch(); su2double x_a = config->GetAeroelastic_CG_Location(); su2double r_a = sqrt(config->GetAeroelastic_Radius_Gyration_Squared()); su2double w = w_h/w_a; - + // Mass Matrix vector > M(2,vector(2,0.0)); M[0][0] = 1; M[0][1] = x_a; M[1][0] = x_a; M[1][1] = r_a*r_a; - + // Stiffness Matrix // vector > K(2,vector(2,0.0)); // K[0][0] = (w_h/w_a)*(w_h/w_a); // K[0][1] = 0.0; // K[1][0] = 0.0; // K[1][1] = r_a*r_a; - + /* Eigenvector and Eigenvalue Matrices of the Generalized EigenValue Problem. */ - + vector > Omega2(2,vector(2,0.0)); su2double aux; // auxiliary variable aux = sqrt(pow(r_a,2)*pow(w,4) - 2*pow(r_a,2)*pow(w,2) + pow(r_a,2) + 4*pow(x_a,2)*pow(w,2)); @@ -3267,17 +3266,17 @@ void CSolver::SetUpTypicalSectionWingModel(vector >& Phi, vect Phi[0][1] = (r_a * (r_a - r_a*pow(w,2) - aux)) / (2*x_a*pow(w, 2)); Phi[1][0] = 1.0; Phi[1][1] = 1.0; - + Omega2[0][0] = (r_a * (r_a + r_a*pow(w,2) - aux)) / (2*(pow(r_a, 2) - pow(x_a, 2))); Omega2[0][1] = 0; Omega2[1][0] = 0; Omega2[1][1] = (r_a * (r_a + r_a*pow(w,2) + aux)) / (2*(pow(r_a, 2) - pow(x_a, 2))); - + /* Nondimesionalize the Eigenvectors such that Phi'*M*Phi = I and PHI'*K*PHI = Omega */ // Phi'*M*Phi = D // D^(-1/2)*Phi'*M*Phi*D^(-1/2) = D^(-1/2)*D^(1/2)*D^(1/2)*D^(-1/2) = I, D^(-1/2) = inv(sqrt(D)) // Phi = Phi*D^(-1/2) - + vector > Aux(2,vector(2,0.0)); vector > D(2,vector(2,0.0)); // Aux = M*Phi @@ -3289,7 +3288,7 @@ void CSolver::SetUpTypicalSectionWingModel(vector >& Phi, vect } } } - + // D = Phi'*Aux for (int i=0; i<2; i++) { for (int j=0; j<2; j++) { @@ -3299,54 +3298,54 @@ void CSolver::SetUpTypicalSectionWingModel(vector >& Phi, vect } } } - + //Modify the first column Phi[0][0] = Phi[0][0] * 1/sqrt(D[0][0]); Phi[1][0] = Phi[1][0] * 1/sqrt(D[0][0]); //Modify the second column Phi[0][1] = Phi[0][1] * 1/sqrt(D[1][1]); Phi[1][1] = Phi[1][1] * 1/sqrt(D[1][1]); - + // Sqrt of the eigenvalues (frequency of vibration of the modes) omega[0] = sqrt(Omega2[0][0]); omega[1] = sqrt(Omega2[1][1]); - + } void CSolver::SolveTypicalSectionWingModel(CGeometry *geometry, su2double Cl, su2double Cm, CConfig *config, unsigned short iMarker, vector& displacements) { - + /*--- The aeroelastic model solved in this routine is the typical section wing model - The details of the implementation are similar to those found in J.J. Alonso + The details of the implementation are similar to those found in J.J. Alonso "Fully-Implicit Time-Marching Aeroelastic Solutions" 1994. ---*/ - + /*--- Retrieve values from the config file ---*/ su2double w_alpha = config->GetAeroelastic_Frequency_Pitch(); su2double vf = config->GetAeroelastic_Flutter_Speed_Index(); su2double b = config->GetLength_Reynolds()/2.0; // airfoil semichord, Reynolds length is by defaul 1.0 su2double dt = config->GetDelta_UnstTimeND(); dt = dt*w_alpha; //Non-dimensionalize the structural time. - + /*--- Structural Equation damping ---*/ vector xi(2,0.0); - + /*--- Eigenvectors and Eigenvalues of the Generalized EigenValue Problem. ---*/ vector > Phi(2,vector(2,0.0)); // generalized eigenvectors. vector w(2,0.0); // sqrt of the generalized eigenvalues (frequency of vibration of the modes). SetUpTypicalSectionWingModel(Phi, w, config); - + /*--- Solving the Decoupled Aeroelastic Problem with second order time discretization Eq (9) ---*/ - + /*--- Solution variables description. //x[j][i], j-entry, i-equation. // Time (n+1)->np1, n->n, (n-1)->n1 ---*/ vector > x_np1(2,vector(2,0.0)); - + /*--- Values from previous movement of spring at true time step n+1 We use this values because we are solving for delta changes not absolute changes ---*/ vector > x_np1_old = config->GetAeroelastic_np1(iMarker); - + /*--- Values at previous timesteps. ---*/ vector > x_n = config->GetAeroelastic_n(iMarker); vector > x_n1 = config->GetAeroelastic_n1(iMarker); - + /*--- Set up of variables used to solve the structural problem. ---*/ vector f_tilde(2,0.0); vector > A_inv(2,vector(2,0.0)); @@ -3355,13 +3354,13 @@ void CSolver::SolveTypicalSectionWingModel(CGeometry *geometry, su2double Cl, su vector rhs(2,0.0); //right hand side vector eta(2,0.0); vector eta_dot(2,0.0); - + /*--- Forcing Term ---*/ su2double cons = vf*vf/PI_NUMBER; vector f(2,0.0); f[0] = cons*(-Cl); f[1] = cons*(2*-Cm); - + //f_tilde = Phi'*f for (int i=0; i<2; i++) { f_tilde[i] = 0; @@ -3369,7 +3368,7 @@ void CSolver::SolveTypicalSectionWingModel(CGeometry *geometry, su2double Cl, su f_tilde[i] += Phi[k][i]*f[k]; //PHI transpose } } - + /*--- solve each decoupled equation (The inverse of the 2x2 matrix is provided) ---*/ for (int i=0; i<2; i++) { /* Matrix Inverse */ @@ -3378,23 +3377,23 @@ void CSolver::SolveTypicalSectionWingModel(CGeometry *geometry, su2double Cl, su A_inv[0][1] = 1/detA * 1; A_inv[1][0] = 1/detA * -w[i]*w[i]; A_inv[1][1] = 1/detA * 3/(2.0*dt); - + /* Source Terms from previous iterations */ s1 = (-4*x_n[0][i] + x_n1[0][i])/(2.0*dt); s2 = (-4*x_n[1][i] + x_n1[1][i])/(2.0*dt); - + /* Problem Right Hand Side */ rhs[0] = -s1; rhs[1] = f_tilde[i]-s2; - + /* Solve the equations */ x_np1[0][i] = A_inv[0][0]*rhs[0] + A_inv[0][1]*rhs[1]; x_np1[1][i] = A_inv[1][0]*rhs[0] + A_inv[1][1]*rhs[1]; - + eta[i] = x_np1[0][i]-x_np1_old[0][i]; // For displacements, the change(deltas) is used. eta_dot[i] = x_np1[1][i]; // For velocities, absolute values are used. } - + /*--- Transform back from the generalized coordinates to get the actual displacements in plunge and pitch q = Phi*eta ---*/ vector q(2,0.0); vector q_dot(2,0.0); @@ -3406,33 +3405,33 @@ void CSolver::SolveTypicalSectionWingModel(CGeometry *geometry, su2double Cl, su q_dot[i] += Phi[i][k]*eta_dot[k]; } } - + su2double dh = b*q[0]; su2double dalpha = q[1]; - + su2double h_dot = w_alpha*b*q_dot[0]; //The w_a brings it back to actual time. su2double alpha_dot = w_alpha*q_dot[1]; - + /*--- Set the solution of the structural equations ---*/ displacements[0] = dh; displacements[1] = dalpha; displacements[2] = h_dot; displacements[3] = alpha_dot; - + /*--- Calculate the total plunge and total pitch displacements for the unsteady step by summing the displacement at each sudo time step ---*/ su2double pitch, plunge; pitch = config->GetAeroelastic_pitch(iMarker); plunge = config->GetAeroelastic_plunge(iMarker); - + config->SetAeroelastic_pitch(iMarker , pitch+dalpha); config->SetAeroelastic_plunge(iMarker , plunge+dh/b); - + /*--- Set the Aeroelastic solution at time n+1. This gets update every sudo time step and after convering the sudo time step the solution at n+1 get moved to the solution at n in SetDualTime_Solver method ---*/ - + config->SetAeroelastic_np1(iMarker, x_np1); - + } void CSolver::Restart_OldGeometry(CGeometry *geometry, CConfig *config) { @@ -3479,9 +3478,9 @@ void CSolver::Restart_OldGeometry(CGeometry *geometry, CConfig *config) { getline (restart_file_n, text_line); for (iPoint_Global = 0; iPoint_Global < geometry->GetGlobal_nPointDomain(); iPoint_Global++ ) { - + getline (restart_file_n, text_line); - + vector point_line = PrintingToolbox::split(text_line, ','); /*--- Retrieve local index. If this node from the restart file lives @@ -3490,12 +3489,12 @@ void CSolver::Restart_OldGeometry(CGeometry *geometry, CConfig *config) { iPoint_Local = geometry->GetGlobal_to_Local_Point(iPoint_Global); if (iPoint_Local > -1) { - + Coord[0] = PrintingToolbox::stod(point_line[1]); Coord[1] = PrintingToolbox::stod(point_line[2]); if (nDim == 3){ - Coord[2] = PrintingToolbox::stod(point_line[3]); - } + Coord[2] = PrintingToolbox::stod(point_line[3]); + } geometry->node[iPoint_Local]->SetCoord_n(Coord); iPoint_Global_Local++; @@ -3550,23 +3549,23 @@ void CSolver::Restart_OldGeometry(CGeometry *geometry, CConfig *config) { getline (restart_file_n1, text_line); for (iPoint_Global = 0; iPoint_Global < geometry->GetGlobal_nPointDomain(); iPoint_Global++ ) { - + getline (restart_file_n1, text_line); vector point_line = PrintingToolbox::split(text_line, ','); - + /*--- Retrieve local index. If this node from the restart file lives on the current processor, we will load and instantiate the vars. ---*/ iPoint_Local = geometry->GetGlobal_to_Local_Point(iPoint_Global); if (iPoint_Local > -1) { - + Coord[0] = PrintingToolbox::stod(point_line[1]); Coord[1] = PrintingToolbox::stod(point_line[2]); if (nDim == 3){ - Coord[2] = PrintingToolbox::stod(point_line[3]); - } + Coord[2] = PrintingToolbox::stod(point_line[3]); + } geometry->node[iPoint_Local]->SetCoord_n1(Coord); @@ -3595,10 +3594,10 @@ void CSolver::Restart_OldGeometry(CGeometry *geometry, CConfig *config) { } /*--- It's necessary to communicate this information ---*/ - + geometry->InitiateComms(geometry, config, COORDINATES_OLD); geometry->CompleteComms(geometry, config, COORDINATES_OLD); - + delete [] Coord; } @@ -3613,7 +3612,7 @@ void CSolver::Read_SU2_Restart_ASCII(CGeometry *geometry, CConfig *config, strin fields.clear(); Restart_Vars = new int[5]; - + string error_string = "Note: ASCII restart files must be in CSV format since v7.0.\n" "Check https://su2code.github.io/docs/Guide-to-v7 for more information."; @@ -3671,7 +3670,7 @@ void CSolver::Read_SU2_Restart_ASCII(CGeometry *geometry, CConfig *config, strin /*--- Error check opening the file. ---*/ if (ierr) { - SU2_MPI::Error(string("SU2 ASCII restart file ") + string(fname) + string(" not found.\n") + error_string, + SU2_MPI::Error(string("SU2 ASCII restart file ") + string(fname) + string(" not found.\n") + error_string, CURRENT_FUNCTION); } @@ -3705,21 +3704,21 @@ void CSolver::Read_SU2_Restart_ASCII(CGeometry *geometry, CConfig *config, strin /*--- In case there is no restart file ---*/ if (restart_file.fail()) { - SU2_MPI::Error(string("SU2 ASCII restart file ") + string(fname) + string(" not found.\n") + error_string, + SU2_MPI::Error(string("SU2 ASCII restart file ") + string(fname) + string(" not found.\n") + error_string, CURRENT_FUNCTION); } /*--- Identify the number of fields (and names) in the restart file ---*/ getline (restart_file, text_line); - + char delimiter = ','; fields = PrintingToolbox::split(text_line, delimiter); - + if (fields.size() <= 1) { SU2_MPI::Error(string("Restart file does not seem to be a CSV file.\n") + error_string, CURRENT_FUNCTION); } - + for (unsigned short iField = 0; iField < fields.size(); iField++){ PrintingToolbox::trim(fields[iField]); } @@ -3738,7 +3737,7 @@ void CSolver::Read_SU2_Restart_ASCII(CGeometry *geometry, CConfig *config, strin for (iPoint_Global = 0; iPoint_Global < geometry->GetGlobal_nPointDomain(); iPoint_Global++ ) { getline (restart_file, text_line); - + vector point_line = PrintingToolbox::split(text_line, delimiter); /*--- Retrieve local index. If this node from the restart file lives @@ -3747,7 +3746,7 @@ void CSolver::Read_SU2_Restart_ASCII(CGeometry *geometry, CConfig *config, strin iPoint_Local = geometry->GetGlobal_to_Local_Point(iPoint_Global); if (iPoint_Local > -1) { - + /*--- Store the solution (starting with node coordinates) --*/ for (iVar = 0; iVar < Restart_Vars[1]; iVar++) @@ -3766,7 +3765,7 @@ void CSolver::Read_SU2_Restart_Binary(CGeometry *geometry, CConfig *config, stri char str_buf[CGNS_STRING_SIZE], fname[100]; unsigned short iVar; - val_filename += ".dat"; + val_filename += ".dat"; strcpy(fname, val_filename.c_str()); int nRestart_Vars = 5, nFields; Restart_Vars = new int[5]; @@ -3969,9 +3968,9 @@ void CSolver::Read_SU2_Restart_Binary(CGeometry *geometry, CConfig *config, stri delete [] blocklen; delete [] displace; - + #endif - + } void CSolver::Read_SU2_Restart_Metadata(CGeometry *geometry, CConfig *config, bool adjoint, string val_filename) { @@ -3986,91 +3985,91 @@ void CSolver::Read_SU2_Restart_Metadata(CGeometry *geometry, CConfig *config, bo string::size_type position; unsigned long InnerIter_ = 0; ifstream restart_file; - + /*--- Carry on with ASCII metadata reading. ---*/ - + restart_file.open(val_filename.data(), ios::in); if (restart_file.fail()) { if (rank == MASTER_NODE) { cout << " Warning: There is no restart file (" << val_filename.data() << ")."<< endl; cout << " Computation will continue without updating metadata parameters." << endl; } - } + } else { - + string text_line; - + /*--- Space for extra info (if any) ---*/ - + while (getline (restart_file, text_line)) { - + /*--- External iteration ---*/ - + position = text_line.find ("ITER=",0); if (position != string::npos) { text_line.erase (0,9); InnerIter_ = atoi(text_line.c_str()); } - + /*--- Angle of attack ---*/ - + position = text_line.find ("AOA=",0); if (position != string::npos) { text_line.erase (0,4); AoA_ = atof(text_line.c_str()); } - + /*--- Sideslip angle ---*/ - + position = text_line.find ("SIDESLIP_ANGLE=",0); if (position != string::npos) { text_line.erase (0,15); AoS_ = atof(text_line.c_str()); } - + /*--- BCThrust angle ---*/ - + position = text_line.find ("INITIAL_BCTHRUST=",0); if (position != string::npos) { text_line.erase (0,17); BCThrust_ = atof(text_line.c_str()); } - + /*--- dCD_dCL coefficient ---*/ - + position = text_line.find ("DCD_DCL_VALUE=",0); if (position != string::npos) { text_line.erase (0,14); dCD_dCL_ = atof(text_line.c_str()); } - + /*--- dCMx_dCL coefficient ---*/ - + position = text_line.find ("DCMX_DCL_VALUE=",0); if (position != string::npos) { text_line.erase (0,15); dCMx_dCL_ = atof(text_line.c_str()); } - + /*--- dCMy_dCL coefficient ---*/ - + position = text_line.find ("DCMY_DCL_VALUE=",0); if (position != string::npos) { text_line.erase (0,15); dCMy_dCL_ = atof(text_line.c_str()); } - + /*--- dCMz_dCL coefficient ---*/ - + position = text_line.find ("DCMZ_DCL_VALUE=",0); if (position != string::npos) { text_line.erase (0,15); dCMz_dCL_ = atof(text_line.c_str()); - } - + } + } - + /*--- Close the restart meta file. ---*/ - + restart_file.close(); - + } - + /*--- Load the metadata. ---*/ - + /*--- Angle of attack ---*/ if (config->GetDiscard_InFiles() == false) { @@ -4134,23 +4133,23 @@ void CSolver::Read_SU2_Restart_Metadata(CGeometry *geometry, CConfig *config, bo config->SetdCMz_dCL(dCMz_dCL_); } - + else { if ((config->GetdCD_dCL() != dCD_dCL_) && (rank == MASTER_NODE)) cout <<"WARNING: Discarding the dCD/dCL in the direct solution file." << endl; - + if ((config->GetdCMx_dCL() != dCMx_dCL_) && (rank == MASTER_NODE)) cout <<"WARNING: Discarding the dCMx/dCL in the direct solution file." << endl; - + if ((config->GetdCMy_dCL() != dCMy_dCL_) && (rank == MASTER_NODE)) cout <<"WARNING: Discarding the dCMy/dCL in the direct solution file." << endl; - + if ((config->GetdCMz_dCL() != dCMz_dCL_) && (rank == MASTER_NODE)) cout <<"WARNING: Discarding the dCMz/dCL in the direct solution file." << endl; } - + /*--- External iteration ---*/ if ((config->GetDiscard_InFiles() == false) && (!adjoint || (adjoint && config->GetRestart()))) @@ -4194,13 +4193,13 @@ void CSolver::LoadInletProfile(CGeometry **geometry, su2double *Normal = new su2double[nDim]; unsigned long Marker_Counter = 0; - + bool turbulent = (config->GetKind_Solver() == RANS || config->GetKind_Solver() == INC_RANS || config->GetKind_Solver() == ADJ_RANS || config->GetKind_Solver() == DISC_ADJ_RANS || config->GetKind_Solver() == DISC_ADJ_INC_RANS); - + unsigned short nVar_Turb = 0; if (turbulent) switch (config->GetKind_Turb_Model()) { @@ -4214,13 +4213,13 @@ void CSolver::LoadInletProfile(CGeometry **geometry, SU2_MPI::Error("Specified turbulence model unavailable or none selected", CURRENT_FUNCTION); break; } - + /*--- Count the number of columns that we have for this flow case, excluding the coordinates. Here, we have 2 entries for the total conditions or mass flow, another nDim for the direction vector, and finally entries for the number of turbulence variables. This is only necessary in case we are writing a template profile file. ---*/ - + unsigned short nCol_InletFile = 2 + nDim + nVar_Turb; /*--- Multizone problems require the number of the zone to be appended. ---*/ @@ -4240,7 +4239,7 @@ void CSolver::LoadInletProfile(CGeometry **geometry, /*--- Load data from the restart into correct containers. ---*/ Marker_Counter = 0; - + unsigned short global_failure = 0, local_failure = 0; ostringstream error_msg; @@ -4264,13 +4263,13 @@ void CSolver::LoadInletProfile(CGeometry **geometry, Marker_Counter++; /*--- Get data for this profile. ---*/ - + vector Inlet_Data = profileReader.GetDataForProfile(jMarker); - + unsigned short nColumns = profileReader.GetNumberOfColumnsInProfile(jMarker); vector Inlet_Values(nColumns); - + /*--- Loop through the nodes on this marker. ---*/ for (iVertex = 0; iVertex < geometry[MESH_0]->nVertex[iMarker]; iVertex++) { @@ -4350,9 +4349,9 @@ void CSolver::LoadInletProfile(CGeometry **geometry, if (config->GetMarker_All_KindBC(iMarker) == KIND_MARKER) { Marker_Tag = config->GetMarker_All_TagBound(iMarker); - + /* Check the number of columns and allocate temp array. */ - + unsigned short nColumns = 0; for (jMarker = 0; jMarker < profileReader.GetNumberOfProfiles(); jMarker++) { if (profileReader.GetTagForProfile(jMarker) == Marker_Tag) { @@ -4361,7 +4360,7 @@ void CSolver::LoadInletProfile(CGeometry **geometry, } vector Inlet_Values(nColumns); vector Inlet_Fine(nColumns); - + /*--- Loop through the nodes on this marker. ---*/ for (iVertex = 0; iVertex < geometry[iMesh]->nVertex[iMarker]; iVertex++) { @@ -4658,890 +4657,3 @@ void CSolver::UpdateSolution_BGS(CGeometry *geometry, CConfig *config){ /*--- To nPoint: The solution must be communicated beforehand ---*/ base_nodes->Set_BGSSolution_k(); } - -CBaselineSolver::CBaselineSolver(void) : CSolver() { } - -CBaselineSolver::CBaselineSolver(CGeometry *geometry, CConfig *config) { - - nPoint = geometry->GetnPoint(); - - /*--- Define geometry constants in the solver structure ---*/ - - nDim = geometry->GetnDim(); - - /*--- Routines to access the number of variables and string names. ---*/ - - SetOutputVariables(geometry, config); - - /*--- Initialize a zero solution and instantiate the CVariable class. ---*/ - - Solution = new su2double[nVar]; - for (unsigned short iVar = 0; iVar < nVar; iVar++) Solution[iVar] = 0.0; - - nodes = new CBaselineVariable(nPoint, nVar, config); - SetBaseClassPointerToNodes(); - - dynamic_grid = config->GetDynamic_Grid(); -} - -CBaselineSolver::CBaselineSolver(CGeometry *geometry, CConfig *config, unsigned short val_nvar, vector field_names) { - - /*--- Define geometry constants in the solver structure ---*/ - - nPoint = geometry->GetnPoint(); - nDim = geometry->GetnDim(); - nVar = val_nvar; - fields = field_names; - - /*--- Allocate the node variables ---*/ - - nodes = new CBaselineVariable(nPoint, nVar, config); - SetBaseClassPointerToNodes(); - - dynamic_grid = config->GetDynamic_Grid(); - -} - -void CBaselineSolver::SetOutputVariables(CGeometry *geometry, CConfig *config) { - - /*--- Open the restart file and extract the nVar and field names. ---*/ - - string Tag, text_line; - - ifstream restart_file; - string filename; - - /*--- Retrieve filename from config ---*/ - - if (config->GetContinuous_Adjoint() || config->GetDiscrete_Adjoint()) { - filename = config->GetSolution_AdjFileName(); - filename = config->GetObjFunc_Extension(filename); - } else { - filename = config->GetSolution_FileName(); - } - - - /*--- Read only the number of variables in the restart file. ---*/ - - if (config->GetRead_Binary_Restart()) { - - /*--- Multizone problems require the number of the zone to be appended. ---*/ - - filename = config->GetFilename(filename, ".dat", config->GetTimeIter()); - - char fname[100]; - strcpy(fname, filename.c_str()); - int nVar_Buf = 5; - int var_buf[5]; - -#ifndef HAVE_MPI - - /*--- Serial binary input. ---*/ - - FILE *fhw; - fhw = fopen(fname,"rb"); - size_t ret; - - /*--- Error check for opening the file. ---*/ - - if (!fhw) { - SU2_MPI::Error(string("Unable to open SU2 restart file ") + string(fname), CURRENT_FUNCTION); - } - - /*--- First, read the number of variables and points. ---*/ - - ret = fread(var_buf, sizeof(int), nVar_Buf, fhw); - if (ret != (unsigned long)nVar_Buf) { - SU2_MPI::Error("Error reading restart file.", CURRENT_FUNCTION); - } - - /*--- Check that this is an SU2 binary file. SU2 binary files - have the hex representation of "SU2" as the first int in the file. ---*/ - - if (var_buf[0] != 535532) { - SU2_MPI::Error(string("File ") + string(fname) + string(" is not a binary SU2 restart file.\n") + - string("SU2 reads/writes binary restart files by default.\n") + - string("Note that backward compatibility for ASCII restart files is\n") + - string("possible with the WRT_BINARY_RESTART / READ_BINARY_RESTART options."), CURRENT_FUNCTION); - } - - /*--- Close the file. ---*/ - - fclose(fhw); - - /*--- Set the number of variables, one per field in the - restart file (without including the PointID) ---*/ - - nVar = var_buf[1]; -#else - - /*--- Parallel binary input using MPI I/O. ---*/ - - MPI_File fhw; - int ierr; - MPI_Offset disp; - unsigned short iVar; - unsigned long index, iChar; - string field_buf; - char str_buf[CGNS_STRING_SIZE]; - - /*--- All ranks open the file using MPI. ---*/ - - ierr = MPI_File_open(MPI_COMM_WORLD, fname, MPI_MODE_RDONLY, MPI_INFO_NULL, &fhw); - - /*--- Error check opening the file. ---*/ - - if (ierr) { - SU2_MPI::Error(string("Unable to open SU2 restart file ") + string(fname), CURRENT_FUNCTION); - } - - /*--- First, read the number of variables and points (i.e., cols and rows), - which we will need in order to read the file later. Also, read the - variable string names here. Only the master rank reads the header. ---*/ - - if (rank == MASTER_NODE) { - MPI_File_read(fhw, var_buf, nVar_Buf, MPI_INT, MPI_STATUS_IGNORE); - } - - /*--- Broadcast the number of variables to all procs and store more clearly. ---*/ - - SU2_MPI::Bcast(var_buf, nVar_Buf, MPI_INT, MASTER_NODE, MPI_COMM_WORLD); - - /*--- Check that this is an SU2 binary file. SU2 binary files - have the hex representation of "SU2" as the first int in the file. ---*/ - - if (var_buf[0] != 535532) { - SU2_MPI::Error(string("File ") + string(fname) + string(" is not a binary SU2 restart file.\n") + - string("SU2 reads/writes binary restart files by default.\n") + - string("Note that backward compatibility for ASCII restart files is\n") + - string("possible with the WRT_BINARY_RESTART / READ_BINARY_RESTART options."), CURRENT_FUNCTION); - } - - - - /*--- Set the number of variables, one per field in the - restart file (without including the PointID) ---*/ - - nVar = var_buf[1]; - - /*--- Read the variable names from the file. Note that we are adopting a - fixed length of 33 for the string length to match with CGNS. This is - needed for when we read the strings later. ---*/ - - char *mpi_str_buf = new char[nVar*CGNS_STRING_SIZE]; - if (rank == MASTER_NODE) { - disp = nVar_Buf*sizeof(int); - MPI_File_read_at(fhw, disp, mpi_str_buf, nVar*CGNS_STRING_SIZE, - MPI_CHAR, MPI_STATUS_IGNORE); - } - - /*--- Broadcast the string names of the variables. ---*/ - - SU2_MPI::Bcast(mpi_str_buf, nVar*CGNS_STRING_SIZE, MPI_CHAR, - MASTER_NODE, MPI_COMM_WORLD); - - fields.push_back("Point_ID"); - - for (iVar = 0; iVar < nVar; iVar++) { - index = iVar*CGNS_STRING_SIZE; - field_buf.append("\""); - for (iChar = 0; iChar < (unsigned long)CGNS_STRING_SIZE; iChar++) { - str_buf[iChar] = mpi_str_buf[index + iChar]; - } - field_buf.append(str_buf); - field_buf.append("\""); - fields.push_back(field_buf.c_str()); - field_buf.clear(); - } - - /*--- All ranks close the file after writing. ---*/ - - MPI_File_close(&fhw); - -#endif - } else { - - /*--- Multizone problems require the number of the zone to be appended. ---*/ - - filename = config->GetFilename(filename, ".csv", config->GetTimeIter()); - - /*--- First, check that this is not a binary restart file. ---*/ - - char fname[100]; - strcpy(fname, filename.c_str()); - int magic_number; - -#ifndef HAVE_MPI - - /*--- Serial binary input. ---*/ - - FILE *fhw; - fhw = fopen(fname,"rb"); - size_t ret; - - /*--- Error check for opening the file. ---*/ - - if (!fhw) { - SU2_MPI::Error(string("Unable to open SU2 restart file ") + string(fname), CURRENT_FUNCTION); - } - - /*--- Attempt to read the first int, which should be our magic number. ---*/ - - ret = fread(&magic_number, sizeof(int), 1, fhw); - if (ret != 1) { - SU2_MPI::Error("Error reading restart file.", CURRENT_FUNCTION); - } - - /*--- Check that this is an SU2 binary file. SU2 binary files - have the hex representation of "SU2" as the first int in the file. ---*/ - - if (magic_number == 535532) { - SU2_MPI::Error(string("File ") + string(fname) + string(" is a binary SU2 restart file, expected ASCII.\n") + - string("SU2 reads/writes binary restart files by default.\n") + - string("Note that backward compatibility for ASCII restart files is\n") + - string("possible with the WRT_BINARY_RESTART / READ_BINARY_RESTART options."), CURRENT_FUNCTION); - } - - fclose(fhw); - -#else - - /*--- Parallel binary input using MPI I/O. ---*/ - - MPI_File fhw; - int ierr; - - /*--- All ranks open the file using MPI. ---*/ - - ierr = MPI_File_open(MPI_COMM_WORLD, fname, MPI_MODE_RDONLY, MPI_INFO_NULL, &fhw); - - /*--- Error check opening the file. ---*/ - - if (ierr) { - SU2_MPI::Error(string("Unable to open SU2 restart file ") + string(fname), CURRENT_FUNCTION); - } - - /*--- Have the master attempt to read the magic number. ---*/ - - if (rank == MASTER_NODE) - MPI_File_read(fhw, &magic_number, 1, MPI_INT, MPI_STATUS_IGNORE); - - /*--- Broadcast the number of variables to all procs and store clearly. ---*/ - - SU2_MPI::Bcast(&magic_number, 1, MPI_INT, MASTER_NODE, MPI_COMM_WORLD); - - /*--- Check that this is an SU2 binary file. SU2 binary files - have the hex representation of "SU2" as the first int in the file. ---*/ - - if (magic_number == 535532) { - SU2_MPI::Error(string("File ") + string(fname) + string(" is a binary SU2 restart file, expected ASCII.\n") + - string("SU2 reads/writes binary restart files by default.\n") + - string("Note that backward compatibility for ASCII restart files is\n") + - string("possible with the WRT_BINARY_RESTART / READ_BINARY_RESTART options."), CURRENT_FUNCTION); - } - - MPI_File_close(&fhw); - -#endif - - /*--- Open the restart file ---*/ - - restart_file.open(filename.data(), ios::in); - - /*--- In case there is no restart file ---*/ - - if (restart_file.fail()) { - SU2_MPI::Error(string("SU2 solution file ") + filename + string(" not found"), CURRENT_FUNCTION); - } - - /*--- Identify the number of fields (and names) in the restart file ---*/ - - getline (restart_file, text_line); - - fields = PrintingToolbox::split(text_line, ','); - - for (unsigned short iField = 0; iField < fields.size(); iField++){ - PrintingToolbox::trim(fields[iField]); - } - - /*--- Close the file (the solution date is read later). ---*/ - - restart_file.close(); - - /*--- Set the number of variables, one per field in the - restart file (without including the PointID) ---*/ - - nVar = fields.size() - 1; - - } - -} - -void CBaselineSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo) { - - /*--- Restart the solution from file information ---*/ - - string filename; - unsigned long index; - unsigned short iDim, iVar; - bool adjoint = ( config->GetContinuous_Adjoint() || config->GetDiscrete_Adjoint() ); - unsigned short iInst = config->GetiInst(); - bool steady_restart = config->GetSteadyRestart(); - unsigned short turb_model = config->GetKind_Turb_Model(); - - su2double *Coord = new su2double [nDim]; - for (iDim = 0; iDim < nDim; iDim++) - Coord[iDim] = 0.0; - - /*--- Skip coordinates ---*/ - - unsigned short skipVars = geometry[iInst]->GetnDim(); - - /*--- Retrieve filename from config ---*/ - - if (adjoint) { - filename = config->GetSolution_AdjFileName(); - filename = config->GetObjFunc_Extension(filename); - } else { - filename = config->GetSolution_FileName(); - } - - filename = config->GetFilename(filename, "", val_iter); - - /*--- Output the file name to the console. ---*/ - - if (rank == MASTER_NODE) - cout << "Reading and storing the solution from " << filename - << "." << endl; - - /*--- Read the restart data from either an ASCII or binary SU2 file. ---*/ - - if (config->GetRead_Binary_Restart()) { - Read_SU2_Restart_Binary(geometry[iInst], config, filename); - } else { - Read_SU2_Restart_ASCII(geometry[iInst], config, filename); - } - - int counter = 0; - long iPoint_Local = 0; unsigned long iPoint_Global = 0; - - /*--- Load data from the restart into correct containers. ---*/ - - for (iPoint_Global = 0; iPoint_Global < geometry[iInst]->GetGlobal_nPointDomain(); iPoint_Global++ ) { - - /*--- Retrieve local index. If this node from the restart file lives - on the current processor, we will load and instantiate the vars. ---*/ - - iPoint_Local = geometry[iInst]->GetGlobal_to_Local_Point(iPoint_Global); - - if (iPoint_Local > -1) { - - /*--- We need to store this point's data, so jump to the correct - offset in the buffer of data from the restart file and load it. ---*/ - - index = counter*Restart_Vars[1]; - for (iVar = 0; iVar < nVar; iVar++) Solution[iVar] = Restart_Data[index+iVar]; - nodes->SetSolution(iPoint_Local,Solution); - - /*--- For dynamic meshes, read in and store the - grid coordinates and grid velocities for each node. ---*/ - - if (dynamic_grid && val_update_geo) { - - /*--- First, remove any variables for the turbulence model that - appear in the restart file before the grid velocities. ---*/ - - if (turb_model == SA || turb_model == SA_NEG) { - index++; - } else if (turb_model == SST) { - index+=2; - } - - /*--- Read in the next 2 or 3 variables which are the grid velocities ---*/ - /*--- If we are restarting the solution from a previously computed static calculation (no grid movement) ---*/ - /*--- the grid velocities are set to 0. This is useful for FSI computations ---*/ - - su2double GridVel[3] = {0.0,0.0,0.0}; - if (!steady_restart) { - - /*--- Rewind the index to retrieve the Coords. ---*/ - index = counter*Restart_Vars[1]; - for (iDim = 0; iDim < nDim; iDim++) { Coord[iDim] = Restart_Data[index+iDim]; } - - /*--- Move the index forward to get the grid velocities. ---*/ - index = counter*Restart_Vars[1] + skipVars + nVar; - for (iDim = 0; iDim < nDim; iDim++) { GridVel[iDim] = Restart_Data[index+iDim]; } - } - - for (iDim = 0; iDim < nDim; iDim++) { - geometry[iInst]->node[iPoint_Local]->SetCoord(iDim, Coord[iDim]); - geometry[iInst]->node[iPoint_Local]->SetGridVel(iDim, GridVel[iDim]); - } - } - - /*--- Increment the overall counter for how many points have been loaded. ---*/ - counter++; - } - - } - - /*--- MPI solution ---*/ - - InitiateComms(geometry[iInst], config, SOLUTION); - CompleteComms(geometry[iInst], config, SOLUTION); - - /*--- Update the geometry for flows on dynamic meshes ---*/ - - if (dynamic_grid && val_update_geo) { - - /*--- Communicate the new coordinates and grid velocities at the halos ---*/ - - geometry[iInst]->InitiateComms(geometry[iInst], config, COORDINATES); - geometry[iInst]->CompleteComms(geometry[iInst], config, COORDINATES); - - geometry[iInst]->InitiateComms(geometry[iInst], config, GRID_VELOCITY); - geometry[iInst]->CompleteComms(geometry[iInst], config, GRID_VELOCITY); - - } - - delete [] Coord; - - /*--- Delete the class memory that is used to load the restart. ---*/ - - if (Restart_Vars != NULL) delete [] Restart_Vars; - if (Restart_Data != NULL) delete [] Restart_Data; - Restart_Vars = NULL; Restart_Data = NULL; - -} - -void CBaselineSolver::LoadRestart_FSI(CGeometry *geometry, CConfig *config, int val_iter) { - - /*--- Restart the solution from file information ---*/ - string filename; - unsigned long index; - unsigned short iVar; - bool adjoint = (config->GetContinuous_Adjoint() || config->GetDiscrete_Adjoint()); - - /*--- Retrieve filename from config ---*/ - if (adjoint) { - filename = config->GetSolution_AdjFileName(); - filename = config->GetObjFunc_Extension(filename); - } else { - filename = config->GetSolution_FileName(); - } - - /*--- Multizone problems require the number of the zone to be appended. ---*/ - - filename = config->GetFilename(filename, "", val_iter); - - /*--- Output the file name to the console. ---*/ - - if (rank == MASTER_NODE) - cout << "Reading and storing the solution from " << filename - << "." << endl; - - /*--- Read the restart data from either an ASCII or binary SU2 file. ---*/ - - if (config->GetRead_Binary_Restart()) { - Read_SU2_Restart_Binary(geometry, config, filename); - } else { - Read_SU2_Restart_ASCII(geometry, config, filename); - } - - unsigned short nVar_Local = Restart_Vars[1]; - su2double *Solution_Local = new su2double[nVar_Local]; - - int counter = 0; - long iPoint_Local = 0; unsigned long iPoint_Global = 0; - - /*--- Load data from the restart into correct containers. ---*/ - - for (iPoint_Global = 0; iPoint_Global < geometry->GetGlobal_nPointDomain(); iPoint_Global++ ) { - - /*--- Retrieve local index. If this node from the restart file lives - on the current processor, we will load and instantiate the vars. ---*/ - - iPoint_Local = geometry->GetGlobal_to_Local_Point(iPoint_Global); - - if (iPoint_Local > -1) { - - /*--- We need to store this point's data, so jump to the correct - offset in the buffer of data from the restart file and load it. ---*/ - - index = counter*Restart_Vars[1]; - for (iVar = 0; iVar < nVar_Local; iVar++) Solution[iVar] = Restart_Data[index+iVar]; - nodes->SetSolution(iPoint_Local,Solution); - - /*--- Increment the overall counter for how many points have been loaded. ---*/ - - counter++; - - } - - } - - delete [] Solution_Local; - -} - -CBaselineSolver::~CBaselineSolver(void) { - if (nodes != nullptr) delete nodes; -} - -CBaselineSolver_FEM::CBaselineSolver_FEM(void) : CSolver() { } - -CBaselineSolver_FEM::CBaselineSolver_FEM(CGeometry *geometry, CConfig *config) { - - /*--- Define geometry constants in the solver structure ---*/ - - nDim = geometry->GetnDim(); - - /*--- Create an object of the class CMeshFEM_DG and retrieve the necessary - geometrical information for the FEM DG solver. If necessary, it is - possible to increase nMatchingFacesWithHaloElem a bit, such that - the computation of the external faces may be more efficient when - using multiple threads. ---*/ - - CMeshFEM_DG *DGGeometry = dynamic_cast(geometry); - - nVolElemTot = DGGeometry->GetNVolElemTot(); - nVolElemOwned = DGGeometry->GetNVolElemOwned(); - volElem = DGGeometry->GetVolElem(); - - /*--- Routines to access the number of variables and string names. ---*/ - - SetOutputVariables(geometry, config); - - /*--- Determine the total number of DOFs stored on this rank and allocate the memory - to store the conservative variables. ---*/ - nDOFsLocOwned = 0; - for(unsigned long i=0; iSetnPointDomain(nDOFsLocOwned); - geometry->SetGlobal_nPointDomain(nDOFsGlobal); - - /*--- Initialize the solution to zero. ---*/ - - unsigned long ii = 0; - for(unsigned long i=0; iGetTimeIter(); - - ifstream restart_file; - string filename; - - /*--- Retrieve filename from config ---*/ - - filename = config->GetSolution_FileName(); - - /*--- Unsteady problems require an iteration number to be appended. ---*/ - - if (config->GetTime_Domain()) { - filename = config->GetUnsteady_FileName(filename, SU2_TYPE::Int(TimeIter), ".dat"); - } - - /*--- Read only the number of variables in the restart file. ---*/ - - if (config->GetRead_Binary_Restart()) { - - int nVar_Buf = 5; - int var_buf[5]; - -#ifndef HAVE_MPI - - /*--- Serial binary input. ---*/ - - FILE *fhw; - fhw = fopen(filename.c_str(),"rb"); - size_t ret; - - /*--- Error check for opening the file. ---*/ - - if (!fhw) - SU2_MPI::Error(string("Unable to open SU2 restart file ") + filename, - CURRENT_FUNCTION); - - /*--- First, read the number of variables and points. ---*/ - - ret = fread(var_buf, sizeof(int), nVar_Buf, fhw); - if (ret != (unsigned long)nVar_Buf) { - SU2_MPI::Error("Error reading restart file.", CURRENT_FUNCTION); - } - - /*--- Check that this is an SU2 binary file. SU2 binary files - have the hex representation of "SU2" as the first int in the file. ---*/ - - if (var_buf[0] != 535532) - SU2_MPI::Error(string("File ") + filename + string(" is not a binary SU2 restart file.\n") + - string("SU2 reads/writes binary restart files by default.\n") + - string("Note that backward compatibility for ASCII restart files is\n") + - string("possible with the WRT_BINARY_RESTART / READ_BINARY_RESTART options."), CURRENT_FUNCTION); - - /*--- Close the file. ---*/ - - fclose(fhw); - -#else - - /*--- Parallel binary input using MPI I/O. ---*/ - - MPI_File fhw; - int ierr; - - /*--- All ranks open the file using MPI. ---*/ - - char fname[100]; - strcpy(fname, filename.c_str()); - ierr = MPI_File_open(MPI_COMM_WORLD, fname, MPI_MODE_RDONLY, MPI_INFO_NULL, &fhw); - - /*--- Error check opening the file. ---*/ - - if (ierr) - SU2_MPI::Error(string("Unable to open SU2 restart file ") + filename, - CURRENT_FUNCTION); - - /*--- First, read the number of variables and points (i.e., cols and rows), - which we will need in order to read the file later. Also, read the - variable string names here. Only the master rank reads the header. ---*/ - - if (rank == MASTER_NODE) - MPI_File_read(fhw, var_buf, nVar_Buf, MPI_INT, MPI_STATUS_IGNORE); - - /*--- Broadcast the number of variables to all procs and store more clearly. ---*/ - - SU2_MPI::Bcast(var_buf, nVar_Buf, MPI_INT, MASTER_NODE, MPI_COMM_WORLD); - - /*--- Check that this is an SU2 binary file. SU2 binary files - have the hex representation of "SU2" as the first int in the file. ---*/ - - if (var_buf[0] != 535532) - SU2_MPI::Error(string("File ") + filename + string(" is not a binary SU2 restart file.\n") + - string("SU2 reads/writes binary restart files by default.\n") + - string("Note that backward compatibility for ASCII restart files is\n") + - string("possible with the WRT_BINARY_RESTART / READ_BINARY_RESTART options."), CURRENT_FUNCTION); - - /*--- All ranks close the file after writing. ---*/ - - MPI_File_close(&fhw); - -#endif - - /*--- Set the number of variables, one per field in the - restart file (without including the PointID) ---*/ - - nVar = var_buf[1]; - - } else { - - /*--- First, check that this is not a binary restart file. ---*/ - - int magic_number; - -#ifndef HAVE_MPI - - /*--- Serial binary input. ---*/ - - FILE *fhw; - fhw = fopen(filename.c_str(), "rb"); - size_t ret; - - /*--- Error check for opening the file. ---*/ - - if (!fhw) - SU2_MPI::Error(string("Unable to open SU2 restart file ") + filename, - CURRENT_FUNCTION); - - /*--- Attempt to read the first int, which should be our magic number. ---*/ - - ret = fread(&magic_number, sizeof(int), 1, fhw); - if (ret != 1) { - SU2_MPI::Error("Error reading restart file.", CURRENT_FUNCTION); - } - - /*--- Check that this is an SU2 binary file. SU2 binary files - have the hex representation of "SU2" as the first int in the file. ---*/ - - if (magic_number == 535532) - SU2_MPI::Error(string("File ") + filename + string(" is a binary SU2 restart file, expected ASCII.\n") + - string("SU2 reads/writes binary restart files by default.\n") + - string("Note that backward compatibility for ASCII restart files is\n") + - string("possible with the WRT_BINARY_RESTART / READ_BINARY_RESTART options."), CURRENT_FUNCTION); - fclose(fhw); - -#else - - /*--- Parallel binary input using MPI I/O. ---*/ - - MPI_File fhw; - int ierr; - - /*--- All ranks open the file using MPI. ---*/ - - char fname[100]; - strcpy(fname, filename.c_str()); - ierr = MPI_File_open(MPI_COMM_WORLD, fname, MPI_MODE_RDONLY, MPI_INFO_NULL, &fhw); - - /*--- Error check opening the file. ---*/ - - if (ierr) - SU2_MPI::Error(string("Unable to open SU2 restart file ") + filename, - CURRENT_FUNCTION); - - /*--- Have the master attempt to read the magic number. ---*/ - - if (rank == MASTER_NODE) - MPI_File_read(fhw, &magic_number, 1, MPI_INT, MPI_STATUS_IGNORE); - - /*--- Broadcast the number of variables to all procs and store clearly. ---*/ - - SU2_MPI::Bcast(&magic_number, 1, MPI_INT, MASTER_NODE, MPI_COMM_WORLD); - - /*--- Check that this is an SU2 binary file. SU2 binary files - have the hex representation of "SU2" as the first int in the file. ---*/ - - if (magic_number == 535532) - SU2_MPI::Error(string("File ") + filename + string(" is a binary SU2 restart file, expected ASCII.\n") + - string("SU2 reads/writes binary restart files by default.\n") + - string("Note that backward compatibility for ASCII restart files is\n") + - string("possible with the WRT_BINARY_RESTART / READ_BINARY_RESTART options."), CURRENT_FUNCTION); - - MPI_File_close(&fhw); - -#endif - - /*--- Open the restart file ---*/ - - restart_file.open(filename.data(), ios::in); - - /*--- In case there is no restart file ---*/ - - if (restart_file.fail()) - SU2_MPI::Error(string("SU2 solution file ") + filename + string(" not found"), CURRENT_FUNCTION); - - /*--- Identify the number of fields (and names) in the restart file ---*/ - - getline (restart_file, text_line); - - stringstream ss(text_line); - while (ss >> Tag) { - config->fields.push_back(Tag); - if (ss.peek() == ',') ss.ignore(); - } - - /*--- Close the file (the solution date is read later). ---*/ - - restart_file.close(); - - /*--- Set the number of variables, one per field in the - restart file (without including the PointID) ---*/ - - nVar = config->fields.size() - 1; - - /*--- Clear the fields vector since we'll read it again. ---*/ - - config->fields.clear(); - - } - -} - -void CBaselineSolver_FEM::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo) { - - /*--- Restart the solution from file information ---*/ - unsigned short iVar; - unsigned long index; - - string restart_filename = config->GetSolution_FileName(); - - if (config->GetTime_Domain()) { - restart_filename = config->GetUnsteady_FileName(restart_filename, SU2_TYPE::Int(val_iter), ""); - } - - int counter = 0; - long iPoint_Local = 0; unsigned long iPoint_Global = 0; - unsigned short rbuf_NotMatching = 0; - unsigned long nDOF_Read = 0; - - /*--- Read the restart data from either an ASCII or binary SU2 file. ---*/ - - if (config->GetRead_Binary_Restart()) { - Read_SU2_Restart_Binary(geometry[MESH_0], config, restart_filename); - } else { - Read_SU2_Restart_ASCII(geometry[MESH_0], config, restart_filename); - } - - /*--- Load data from the restart into correct containers. ---*/ - - counter = 0; - for (iPoint_Global = 0; iPoint_Global < geometry[MESH_0]->GetGlobal_nPointDomain(); iPoint_Global++) { - - /*--- Retrieve local index. If this node from the restart file lives - on the current processor, we will load and instantiate the vars. ---*/ - - iPoint_Local = geometry[MESH_0]->GetGlobal_to_Local_Point(iPoint_Global); - - if (iPoint_Local > -1) { - - /*--- We need to store this point's data, so jump to the correct - offset in the buffer of data from the restart file and load it. ---*/ - - index = counter*Restart_Vars[1]; - for (iVar = 0; iVar < nVar; iVar++) { - VecSolDOFs[nVar*iPoint_Local+iVar] = Restart_Data[index+iVar]; - } - /*--- Update the local counter nDOF_Read. ---*/ - ++nDOF_Read; - - /*--- Increment the overall counter for how many points have been loaded. ---*/ - counter++; - } - - } - - /*--- Detect a wrong solution file ---*/ - if(nDOF_Read < nDOFsLocOwned) rbuf_NotMatching = 1; - -#ifdef HAVE_MPI - unsigned short sbuf_NotMatching = rbuf_NotMatching; - SU2_MPI::Allreduce(&sbuf_NotMatching, &rbuf_NotMatching, 1, MPI_UNSIGNED_SHORT, MPI_MAX, MPI_COMM_WORLD); -#endif - - if (rbuf_NotMatching != 0) - SU2_MPI::Error(string("The solution file ") + restart_filename + - string(" doesn't match with the mesh file!\n") + - string("It could be empty lines at the end of the file."), - CURRENT_FUNCTION); - - /*--- Delete the class memory that is used to load the restart. ---*/ - - if (Restart_Vars != NULL) delete [] Restart_Vars; - if (Restart_Data != NULL) delete [] Restart_Data; - Restart_Vars = NULL; Restart_Data = NULL; - -} - -CBaselineSolver_FEM::~CBaselineSolver_FEM(void) { } diff --git a/SU2_CFD/src/solver_template.cpp b/SU2_CFD/src/solvers/CTemplateSolver.cpp similarity index 93% rename from SU2_CFD/src/solver_template.cpp rename to SU2_CFD/src/solvers/CTemplateSolver.cpp index 252f045035d9..481ff253acac 100644 --- a/SU2_CFD/src/solver_template.cpp +++ b/SU2_CFD/src/solvers/CTemplateSolver.cpp @@ -1,12 +1,12 @@ /*! - * \file solution_template.cpp - * \brief Main subrotuines for solving direct problems (Euler, Navier-Stokes, etc.). + * \file CTemplateSolver.cpp + * \brief Subrotuines to be implemented for any new solvers * \author F. Palacios * \version 7.0.0 "Blackbird" * * SU2 Project Website: https://su2code.github.io * - * The SU2 Project is maintained by the SU2 Foundation + * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) @@ -26,7 +26,7 @@ */ -#include "../include/solver_structure.hpp" +#include "../../include/solvers/CTemplateSolver.hpp" CTemplateSolver::CTemplateSolver(void) : CSolver() { } @@ -62,10 +62,10 @@ void CTemplateSolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_con void CTemplateSolver::BC_Far_Field(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { } -void CTemplateSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, +void CTemplateSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { } -void CTemplateSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, +void CTemplateSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { } void CTemplateSolver::BC_Sym_Plane(CGeometry *geometry, @@ -77,7 +77,7 @@ void CTemplateSolver::BC_Sym_Plane(CGeometry *geometry, void CTemplateSolver::BC_Custom(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { } -void CTemplateSolver::ExplicitRK_Iteration(CGeometry *geometry, CSolver **solver_container, +void CTemplateSolver::ExplicitRK_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iRKStep) { } void CTemplateSolver::ExplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { } diff --git a/SU2_CFD/src/solver_direct_transition.cpp b/SU2_CFD/src/solvers/CTransLMSolver.cpp similarity index 96% rename from SU2_CFD/src/solver_direct_transition.cpp rename to SU2_CFD/src/solvers/CTransLMSolver.cpp index 78cd1d60796c..df2c8d1d6059 100644 --- a/SU2_CFD/src/solver_direct_transition.cpp +++ b/SU2_CFD/src/solvers/CTransLMSolver.cpp @@ -1,12 +1,12 @@ /*! - * \file solution_direct_transition.cpp - * \brief Main subrotuines for solving direct problems (Euler, Navier-Stokes, etc.). + * \file CTransLMSolver.cpp + * \brief Main subrotuines for Transition model solver. * \author A. Aranake * \version 7.0.0 "Blackbird" * * SU2 Project Website: https://su2code.github.io * - * The SU2 Project is maintained by the SU2 Foundation + * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) @@ -26,9 +26,10 @@ */ -#include "../include/solver_structure.hpp" -#include "../include/variables/CTransLMVariable.hpp" -#include "../include/variables/CTurbSAVariable.hpp" +#include "../../include/solvers/CTransLMSolver.hpp" +#include "../../include/variables/CTransLMVariable.hpp" +#include "../../include/variables/CTurbSAVariable.hpp" + CTransLMSolver::CTransLMSolver(void) : CTurbSolver() {} @@ -39,27 +40,27 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh ifstream restart_file; char *cstr; string text_line; - + bool restart = (config->GetRestart() || config->GetRestart_Flow()); - + cout << "Entered constructor for CTransLMSolver -AA\n"; Gamma = config->GetGamma(); Gamma_Minus_One = Gamma - 1.0; - + /*--- Define geometry constans in the solver structure ---*/ nDim = geometry->GetnDim(); nPoint = geometry->GetnPoint(); nPointDomain = geometry->GetnPointDomain(); - + /*--- Dimension of the problem --> 2 Transport equations (intermittency, Reth) ---*/ nVar = 2; - + /*--- Initialize nVarGrad for deallocation ---*/ - + nVarGrad = nVar; - + if (iMesh == MESH_0) { - + /*--- Define some auxillary vectors related to the residual ---*/ Residual = new su2double[nVar]; Residual_RMS = new su2double[nVar]; Residual_i = new su2double[nVar]; Residual_j = new su2double[nVar]; @@ -77,13 +78,13 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh /*--- Define some auxiliar vector related with the solution ---*/ Solution = new su2double[nVar]; Solution_i = new su2double[nVar]; Solution_j = new su2double[nVar]; - + /*--- Define some auxiliar vector related with the geometry ---*/ Vector_i = new su2double[nDim]; Vector_j = new su2double[nDim]; - + LinSysSol.Initialize(nPoint, nPointDomain, nVar, 0.0); LinSysRes.Initialize(nPoint, nPointDomain, nVar, 0.0); - + /*--- Jacobians and vector structures for implicit computations ---*/ if (config->GetKind_TimeIntScheme_Turb() == EULER_IMPLICIT) { @@ -96,14 +97,14 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh } /*--- Initialization of the structure of the whole Jacobian ---*/ Jacobian.Initialize(nPoint, nPointDomain, nVar, nVar, true, geometry, config); - + if (config->GetKind_Linear_Solver_Prec() == LINELET) { nLineLets = Jacobian.BuildLineletPreconditioner(geometry, config); if (rank == MASTER_NODE) cout << "Compute linelet structure. " << nLineLets << " elements in each line (average)." << endl; } - + } - + /*--- Computation of gradients by least squares ---*/ if (config->GetLeastSquaresRequired()) { /*--- S matrix := inv(R)*traspose(inv(R)) ---*/ @@ -119,7 +120,7 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh /*--- Read farfield conditions from config ---*/ Intermittency_Inf = config->GetIntermittency_FreeStream(); tu_Inf = config->GetTurbulenceIntensity_FreeStream(); - + /*-- Initialize REth from correlation --*/ if (tu_Inf <= 1.3) { REth_Inf = (1173.51-589.428*tu_Inf+0.2196/(tu_Inf*tu_Inf)); @@ -130,12 +131,12 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh // REth_Inf *= mach/rey; cout << "REth_Inf = " << REth_Inf << ", rey: "<< rey << " -AA" << endl; - + /*--- Restart the solution from file information ---*/ if (!restart) nodes = new CTransLMVariable(Intermittency_Inf, REth_Inf, nPoint, nDim, nVar, config); } else { /*--- Coarse levels ---*/ - + cout << "No LM restart yet!!" << endl; // TODO, Aniket int j; cin >> j; @@ -146,9 +147,9 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh if (restart_file.fail()) { SU2_MPI::Error("There is no turbulent restart file.", CURRENT_FUNCTION); } - + nodes = new CTurbSAVariable(0.0, 0.0, nPoint, nDim, nVar, config); - + for (iPoint = 0; iPoint < geometry->GetnPoint(); iPoint++) { getline(restart_file, text_line); istringstream point_line(text_line); @@ -159,7 +160,7 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh } restart_file.close(); } - + SetBaseClassPointerToNodes(); /*--- Add the solver name (max 8 characters) ---*/ @@ -168,7 +169,7 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh } CTransLMSolver::~CTransLMSolver(void) { - + } void CTransLMSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output) { @@ -190,44 +191,44 @@ void CTransLMSolver::Postprocessing(CGeometry *geometry, CSolver **solver_contai } void CTransLMSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { - + unsigned short iVar; unsigned long iPoint, total_index; su2double Delta, Delta_flow, Vol; - - + + /*--- Set maximum residual to zero ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { SetRes_RMS(iVar, 0.0); SetRes_Max(iVar, 0.0, 0); } - + /*--- Build implicit system ---*/ - + for (iPoint = 0; iPoint < geometry->GetnPointDomain(); iPoint++) { Vol = geometry->node[iPoint]->GetVolume(); - + /*--- Modify matrix diagonal to assure diagonal dominance ---*/ - + Delta_flow = Vol / (solver_container[FLOW_SOL]->GetNodes()->GetDelta_Time(iPoint)); Delta = Delta_flow; Jacobian.AddVal2Diag(iPoint, Delta); - + for (iVar = 0; iVar < nVar; iVar++) { total_index = iPoint*nVar+iVar; - + /*--- Right hand side of the system (-Residual) and initial guess (x = 0) ---*/ - + LinSysRes[total_index] = -LinSysRes[total_index]; LinSysSol[total_index] = 0.0; AddRes_RMS(iVar, LinSysRes[total_index]*LinSysRes[total_index]*Vol); AddRes_Max(iVar, fabs(LinSysRes[total_index]), geometry->node[iPoint]->GetGlobalIndex(), geometry->node[iPoint]->GetCoord()); } } - + /*--- Initialize residual and solution at the ghost points ---*/ - + for (iPoint = geometry->GetnPointDomain(); iPoint < geometry->GetnPoint(); iPoint++) { for (iVar = 0; iVar < nVar; iVar++) { total_index = iPoint*nVar + iVar; @@ -235,27 +236,27 @@ void CTransLMSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solv LinSysSol[total_index] = 0.0; } } - + /*--- Solve or smooth the linear system ---*/ - + System.Solve(Jacobian, LinSysRes, LinSysSol, geometry, config); - + /*--- Update solution (system written in terms of increments) ---*/ - + for (iPoint = 0; iPoint < geometry->GetnPointDomain(); iPoint++) { for (iVar = 0; iVar < nVar; iVar++) nodes->AddSolution(iPoint,iVar, LinSysSol[iPoint*nVar+iVar]); } - + /*--- MPI solution ---*/ - + InitiateComms(geometry, config, SOLUTION); CompleteComms(geometry, config, SOLUTION); - + /*--- Compute the root mean square residual ---*/ - + SetResidual_RMS(geometry, config); - + } void CTransLMSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short iMesh) { @@ -298,51 +299,51 @@ void CTransLMSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_conta void CTransLMSolver::Viscous_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short iMesh, unsigned short iRKStep) { unsigned long iEdge, iPoint, jPoint; - + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - + /*--- Points in edge ---*/ iPoint = geometry->edge[iEdge]->GetNode(0); jPoint = geometry->edge[iEdge]->GetNode(1); - + /*--- Points coordinates, and normal vector ---*/ numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[jPoint]->GetCoord()); - + numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); - + /*--- Conservative variables w/o reconstruction ---*/ numerics->SetConservative(solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint), solver_container[FLOW_SOL]->GetNodes()->GetSolution(jPoint)); - + /*--- Laminar Viscosity ---*/ numerics->SetLaminarViscosity(solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint), solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(jPoint)); /*--- Eddy Viscosity ---*/ numerics->SetEddyViscosity(solver_container[FLOW_SOL]->GetNodes()->GetEddyViscosity(iPoint), solver_container[FLOW_SOL]->GetNodes()->GetEddyViscosity(jPoint)); - + /*--- Transition variables w/o reconstruction, and its gradients ---*/ numerics->SetTransVar(nodes->GetSolution(iPoint), nodes->GetSolution(jPoint)); numerics->SetTransVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(jPoint)); - + // ToDo: The flow solvers do not use the conservative variable gradients // numerics->SetConsVarGradient(solver_container[FLOW_SOL]->GetNodes()->GetGradient(iPoint), // solver_container[FLOW_SOL]->GetNodes()->GetGradient(jPoint)); - - + + /*--- Compute residual, and Jacobians ---*/ numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - + /*--- Add and subtract residual, and update Jacobians ---*/ LinSysRes.SubtractBlock(iPoint, Residual); LinSysRes.AddBlock(jPoint, Residual); - + Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); Jacobian.SubtractBlock(iPoint, jPoint, Jacobian_j); Jacobian.AddBlock(jPoint, iPoint, Jacobian_i); Jacobian.AddBlock(jPoint, jPoint, Jacobian_j); - + } } @@ -355,43 +356,43 @@ void CTransLMSolver::Source_Residual(CGeometry *geometry, CSolver **solver_conta cout << "\nBeginAA" << endl; for (iPoint = 0; iPoint < geometry->GetnPointDomain(); iPoint++) { cout << "\niPoint: " << iPoint << endl; - + /*--- Conservative variables w/o reconstruction ---*/ - + numerics->SetConservative(solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint), NULL); - + /*--- Gradient of the primitive and conservative variables ---*/ - + numerics->SetPrimVarGradient(solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint), NULL); - + /*--- Laminar and eddy viscosity ---*/ - + numerics->SetLaminarViscosity(solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint), 0.0); numerics->SetEddyViscosity(solver_container[FLOW_SOL]->GetNodes()->GetEddyViscosity(iPoint),0.0); - + /*--- Turbulent variables w/o reconstruction, and its gradient ---*/ - + numerics->SetTransVar(nodes->GetSolution(iPoint), NULL); // numerics->SetTransVarGradient(nodes->GetGradient(iPoint), NULL); // Is this needed?? - + /*--- Set volume ---*/ - + numerics->SetVolume(geometry->node[iPoint]->GetVolume()); - + /*--- Set distance to the surface ---*/ - + numerics->SetDistance(geometry->node[iPoint]->GetWall_Distance(), 0.0); - + /*--- Compute the source term ---*/ - + numerics->ComputeResidual_TransLM(Residual, Jacobian_i, NULL, config, gamma_sep); - + /*-- Store gamma_sep in variable class --*/ - + nodes->SetGammaSep(iPoint,gamma_sep); /*--- Subtract residual and the Jacobian ---*/ - + LinSysRes.SubtractBlock(iPoint, Residual); Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); @@ -411,13 +412,13 @@ void CTransLMSolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_cont su2double *Normal = new su2double[nDim]; su2double *Residual = new su2double[nVar]; - bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); // cout << "Setting wall BC -AA\n"; for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check if the node belongs to the domain (i.e., not a halo node) ---*/ if (geometry->node[iPoint]->GetDomain()) { @@ -428,7 +429,7 @@ void CTransLMSolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_cont /*--- Set both interior and exterior point to current value ---*/ for (iVar=0; iVar < nVar; iVar++) { U_domain[iVar] = nodes->GetSolution(iPoint,iVar); - U_wall[iVar] = nodes->GetSolution(iPoint,iVar); + U_wall[iVar] = nodes->GetSolution(iPoint,iVar); } /*--- Set various quantities in the solver class ---*/ @@ -473,12 +474,12 @@ void CTransLMSolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_cont // } // } // } - + delete [] U_domain; delete [] U_wall; delete [] Normal; delete [] Residual; - + } void CTransLMSolver::BC_Far_Field(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { diff --git a/SU2_CFD/src/solver_direct_turbulent.cpp b/SU2_CFD/src/solvers/CTurbSASolver.cpp similarity index 50% rename from SU2_CFD/src/solver_direct_turbulent.cpp rename to SU2_CFD/src/solvers/CTurbSASolver.cpp index 92e797b764a8..d296ccf7d419 100644 --- a/SU2_CFD/src/solver_direct_turbulent.cpp +++ b/SU2_CFD/src/solvers/CTurbSASolver.cpp @@ -1,12 +1,12 @@ /*! - * \file solution_direct_turbulent.cpp - * \brief Main subrotuines for solving direct problems + * \file CTurbSASolver.cpp + * \brief Main subrotuines of CTurbSASolver class * \author F. Palacios, A. Bueno * \version 7.0.0 "Blackbird" * * SU2 Project Website: https://su2code.github.io * - * The SU2 Project is maintained by the SU2 Foundation + * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) @@ -26,904 +26,8 @@ */ -#include "../include/solver_structure.hpp" -#include "../include/variables/CTurbSAVariable.hpp" -#include "../include/variables/CTurbSSTVariable.hpp" - -CTurbSolver::CTurbSolver(void) : CSolver() { - - FlowPrimVar_i = NULL; - FlowPrimVar_j = NULL; - lowerlimit = NULL; - upperlimit = NULL; - nVertex = NULL; - nMarker = 0; - Inlet_TurbVars = NULL; - snode = nullptr; -} - -CTurbSolver::CTurbSolver(CGeometry* geometry, CConfig *config) : CSolver() { - - Gamma = config->GetGamma(); - Gamma_Minus_One = Gamma - 1.0; - - FlowPrimVar_i = NULL; - FlowPrimVar_j = NULL; - lowerlimit = NULL; - upperlimit = NULL; - nMarker = config->GetnMarker_All(); - - /*--- Store the number of vertices on each marker for deallocation later ---*/ - nVertex = new unsigned long[nMarker]; - for (unsigned long iMarker = 0; iMarker < nMarker; iMarker++) - nVertex[iMarker] = geometry->nVertex[iMarker]; - - /* A grid is defined as dynamic if there's rigid grid movement or grid deformation AND the problem is time domain */ - dynamic_grid = config->GetDynamic_Grid(); - -} - -CTurbSolver::~CTurbSolver(void) { - - if (Inlet_TurbVars != NULL) { - for (unsigned short iMarker = 0; iMarker < nMarker; iMarker++) { - if (Inlet_TurbVars[iMarker] != NULL) { - for (unsigned long iVertex = 0; iVertex < nVertex[iMarker]; iVertex++) { - delete [] Inlet_TurbVars[iMarker][iVertex]; - } - delete [] Inlet_TurbVars[iMarker]; - } - } - delete [] Inlet_TurbVars; - } - - if (FlowPrimVar_i != NULL) delete [] FlowPrimVar_i; - if (FlowPrimVar_j != NULL) delete [] FlowPrimVar_j; - if (lowerlimit != NULL) delete [] lowerlimit; - if (upperlimit != NULL) delete [] upperlimit; - - if (nodes != nullptr) delete nodes; -} - -void CTurbSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short iMesh) { - - su2double *Turb_i, *Turb_j, *Limiter_i = NULL, *Limiter_j = NULL, *V_i, *V_j, **Gradient_i, **Gradient_j, Project_Grad_i, Project_Grad_j; - unsigned long iEdge, iPoint, jPoint; - unsigned short iDim, iVar; - - bool muscl = config->GetMUSCL_Turb(); - bool limiter = (config->GetKind_SlopeLimit_Turb() != NO_LIMITER); - - for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - - /*--- Points in edge and normal vectors ---*/ - - iPoint = geometry->edge[iEdge]->GetNode(0); - jPoint = geometry->edge[iEdge]->GetNode(1); - numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); - - /*--- Primitive variables w/o reconstruction ---*/ - - V_i = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); - V_j = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(jPoint); - numerics->SetPrimitive(V_i, V_j); - - /*--- Turbulent variables w/o reconstruction ---*/ - - Turb_i = nodes->GetSolution(iPoint); - Turb_j = nodes->GetSolution(jPoint); - numerics->SetTurbVar(Turb_i, Turb_j); - - /*--- Grid Movement ---*/ - - if (dynamic_grid) - numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[jPoint]->GetGridVel()); - - if (muscl) { - - for (iDim = 0; iDim < nDim; iDim++) { - Vector_i[iDim] = 0.5*(geometry->node[jPoint]->GetCoord(iDim) - geometry->node[iPoint]->GetCoord(iDim)); - Vector_j[iDim] = 0.5*(geometry->node[iPoint]->GetCoord(iDim) - geometry->node[jPoint]->GetCoord(iDim)); - } - - /*--- Mean flow primitive variables using gradient reconstruction and limiters ---*/ - - Gradient_i = solver_container[FLOW_SOL]->GetNodes()->GetGradient_Reconstruction(iPoint); - Gradient_j = solver_container[FLOW_SOL]->GetNodes()->GetGradient_Reconstruction(jPoint); - - if (limiter) { - Limiter_i = solver_container[FLOW_SOL]->GetNodes()->GetLimiter_Primitive(iPoint); - Limiter_j = solver_container[FLOW_SOL]->GetNodes()->GetLimiter_Primitive(jPoint); - } - - for (iVar = 0; iVar < solver_container[FLOW_SOL]->GetnPrimVarGrad(); iVar++) { - Project_Grad_i = 0.0; Project_Grad_j = 0.0; - for (iDim = 0; iDim < nDim; iDim++) { - Project_Grad_i += Vector_i[iDim]*Gradient_i[iVar][iDim]; - Project_Grad_j += Vector_j[iDim]*Gradient_j[iVar][iDim]; - } - if (limiter) { - FlowPrimVar_i[iVar] = V_i[iVar] + Limiter_i[iVar]*Project_Grad_i; - FlowPrimVar_j[iVar] = V_j[iVar] + Limiter_j[iVar]*Project_Grad_j; - } - else { - FlowPrimVar_i[iVar] = V_i[iVar] + Project_Grad_i; - FlowPrimVar_j[iVar] = V_j[iVar] + Project_Grad_j; - } - } - - numerics->SetPrimitive(FlowPrimVar_i, FlowPrimVar_j); - - /*--- Turbulent variables using gradient reconstruction and limiters ---*/ - - Gradient_i = nodes->GetGradient_Reconstruction(iPoint); - Gradient_j = nodes->GetGradient_Reconstruction(jPoint); - - if (limiter) { - Limiter_i = nodes->GetLimiter(iPoint); - Limiter_j = nodes->GetLimiter(jPoint); - } - - for (iVar = 0; iVar < nVar; iVar++) { - Project_Grad_i = 0.0; Project_Grad_j = 0.0; - for (iDim = 0; iDim < nDim; iDim++) { - Project_Grad_i += Vector_i[iDim]*Gradient_i[iVar][iDim]; - Project_Grad_j += Vector_j[iDim]*Gradient_j[iVar][iDim]; - } - if (limiter) { - Solution_i[iVar] = Turb_i[iVar] + Limiter_i[iVar]*Project_Grad_i; - Solution_j[iVar] = Turb_j[iVar] + Limiter_j[iVar]*Project_Grad_j; - } - else { - Solution_i[iVar] = Turb_i[iVar] + Project_Grad_i; - Solution_j[iVar] = Turb_j[iVar] + Project_Grad_j; - } - } - - numerics->SetTurbVar(Solution_i, Solution_j); - - } - - /*--- Add and subtract residual ---*/ - - numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - - LinSysRes.AddBlock(iPoint, Residual); - LinSysRes.SubtractBlock(jPoint, Residual); - - /*--- Implicit part ---*/ - - Jacobian.UpdateBlocks(iEdge, iPoint, jPoint, Jacobian_i, Jacobian_j); - - } - -} - -void CTurbSolver::Viscous_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh, unsigned short iRKStep) { - unsigned long iEdge, iPoint, jPoint; - - for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - - /*--- Points in edge ---*/ - - iPoint = geometry->edge[iEdge]->GetNode(0); - jPoint = geometry->edge[iEdge]->GetNode(1); - - /*--- Points coordinates, and normal vector ---*/ - - numerics->SetCoord(geometry->node[iPoint]->GetCoord(), - geometry->node[jPoint]->GetCoord()); - numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); - - /*--- Conservative variables w/o reconstruction ---*/ - - numerics->SetPrimitive(solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint), - solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(jPoint)); - - /*--- Turbulent variables w/o reconstruction, and its gradients ---*/ - - numerics->SetTurbVar(nodes->GetSolution(iPoint), nodes->GetSolution(jPoint)); - numerics->SetTurbVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(jPoint)); - - /*--- Menter's first blending function (only SST)---*/ - if ((config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST)) - numerics->SetF1blending(nodes->GetF1blending(iPoint), nodes->GetF1blending(jPoint)); - - /*--- Compute residual, and Jacobians ---*/ - - numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - - /*--- Add and subtract residual, and update Jacobians ---*/ - - LinSysRes.SubtractBlock(iPoint, Residual); - LinSysRes.AddBlock(jPoint, Residual); - - Jacobian.UpdateBlocks(iEdge, iPoint, jPoint, Jacobian_i, Jacobian_j); - - } - -} - -void CTurbSolver::BC_Sym_Plane(CGeometry *geometry, - CSolver **solver_container, - CNumerics *conv_numerics, - CNumerics *visc_numerics, - CConfig *config, - unsigned short val_marker) { - - /*--- Convective and viscous fluxes across symmetry plane are equal to zero. ---*/ - -} - -void CTurbSolver::BC_Euler_Wall(CGeometry *geometry, - CSolver **solver_container, - CNumerics *conv_numerics, - CNumerics *visc_numerics, - CConfig *config, - unsigned short val_marker) { - - /*--- Convective fluxes across euler wall are equal to zero. ---*/ - -} - -void CTurbSolver::BC_Riemann(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - - string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - - switch(config->GetKind_Data_Riemann(Marker_Tag)) - { - case TOTAL_CONDITIONS_PT: case STATIC_SUPERSONIC_INFLOW_PT: case STATIC_SUPERSONIC_INFLOW_PD: case DENSITY_VELOCITY: - BC_Inlet(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); - break; - case STATIC_PRESSURE: - BC_Outlet(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); - break; - } -} - -void CTurbSolver::BC_TurboRiemann(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - - string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - - switch(config->GetKind_Data_Riemann(Marker_Tag)) - { - case TOTAL_CONDITIONS_PT: case STATIC_SUPERSONIC_INFLOW_PT: case STATIC_SUPERSONIC_INFLOW_PD: case DENSITY_VELOCITY: - BC_Inlet_Turbo(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); - break; - case STATIC_PRESSURE: - BC_Outlet(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); - break; - } -} - - -void CTurbSolver::BC_Giles(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - - string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - - switch(config->GetKind_Data_Giles(Marker_Tag)) - { - case TOTAL_CONDITIONS_PT:case TOTAL_CONDITIONS_PT_1D: case DENSITY_VELOCITY: - BC_Inlet_Turbo(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); - break; - case MIXING_IN: - if (config->GetBoolTurbMixingPlane()){ - BC_Inlet_MixingPlane(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); - } - else{ - BC_Inlet_Turbo(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); - } - break; - - case STATIC_PRESSURE: case MIXING_OUT: case STATIC_PRESSURE_1D: case RADIAL_EQUILIBRIUM: - BC_Outlet(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); - break; - } -} - -void CTurbSolver::BC_Periodic(CGeometry *geometry, CSolver **solver_container, - CNumerics *numerics, CConfig *config) { - - /*--- Complete residuals for periodic boundary conditions. We loop over - the periodic BCs in matching pairs so that, in the event that there are - adjacent periodic markers, the repeated points will have their residuals - accumulated corectly during the communications. For implicit calculations - the Jacobians and linear system are also correctly adjusted here. ---*/ - - for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { - InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_RESIDUAL); - CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_RESIDUAL); - } - -} - -void CTurbSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { - - unsigned short iVar; - unsigned long iPoint, total_index; - su2double Delta, Vol, density_old = 0.0, density = 0.0; - - bool adjoint = config->GetContinuous_Adjoint() || (config->GetDiscrete_Adjoint() && config->GetFrozen_Visc_Disc()); - bool compressible = (config->GetKind_Regime() == COMPRESSIBLE); - bool incompressible = (config->GetKind_Regime() == INCOMPRESSIBLE); - - /*--- Set maximum residual to zero ---*/ - - for (iVar = 0; iVar < nVar; iVar++) { - SetRes_RMS(iVar, 0.0); - SetRes_Max(iVar, 0.0, 0); - } - - /*--- Build implicit system ---*/ - - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - - /*--- Read the volume ---*/ - - Vol = (geometry->node[iPoint]->GetVolume() + - geometry->node[iPoint]->GetPeriodicVolume()); - - /*--- Modify matrix diagonal to assure diagonal dominance ---*/ - - Delta = Vol / ((nodes->GetLocalCFL(iPoint)/solver_container[FLOW_SOL]->GetNodes()->GetLocalCFL(iPoint))*solver_container[FLOW_SOL]->GetNodes()->GetDelta_Time(iPoint)); - Jacobian.AddVal2Diag(iPoint, Delta); - - /*--- Right hand side of the system (-Residual) and initial guess (x = 0) ---*/ - - for (iVar = 0; iVar < nVar; iVar++) { - total_index = iPoint*nVar+iVar; - LinSysRes[total_index] = - LinSysRes[total_index]; - LinSysSol[total_index] = 0.0; - AddRes_RMS(iVar, LinSysRes[total_index]*LinSysRes[total_index]); - AddRes_Max(iVar, fabs(LinSysRes[total_index]), geometry->node[iPoint]->GetGlobalIndex(), geometry->node[iPoint]->GetCoord()); - } - } - - /*--- Initialize residual and solution at the ghost points ---*/ - - for (iPoint = nPointDomain; iPoint < nPoint; iPoint++) { - for (iVar = 0; iVar < nVar; iVar++) { - total_index = iPoint*nVar + iVar; - LinSysRes[total_index] = 0.0; - LinSysSol[total_index] = 0.0; - } - } - - /*--- Solve or smooth the linear system ---*/ - - unsigned long IterLinSol = System.Solve(Jacobian, LinSysRes, LinSysSol, geometry, config); - SetIterLinSolver(IterLinSol); - - /*--- Store the value of the residual. ---*/ - - SetResLinSolver(System.GetResidual()); - - ComputeUnderRelaxationFactor(solver_container, config); - - /*--- Update solution (system written in terms of increments) ---*/ - - if (!adjoint) { - - /*--- Update the turbulent solution. Only SST variants are clipped. ---*/ - - switch (config->GetKind_Turb_Model()) { - - case SA: case SA_E: case SA_COMP: case SA_E_COMP: case SA_NEG: - - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - nodes->AddSolution(iPoint, 0, nodes->GetUnderRelaxation(iPoint)*LinSysSol[iPoint]); - } - - break; - - case SST: case SST_SUST: - - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - - if (compressible) { - density_old = solver_container[FLOW_SOL]->GetNodes()->GetSolution_Old(iPoint,0); - density = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); - } - if (incompressible) { - density_old = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); - density = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); - } - - for (iVar = 0; iVar < nVar; iVar++) { - nodes->AddConservativeSolution(iPoint, iVar, nodes->GetUnderRelaxation(iPoint)*LinSysSol[iPoint*nVar+iVar], density, density_old, lowerlimit[iVar], upperlimit[iVar]); - } - - } - - break; - - } - } - - for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { - InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_IMPLICIT); - CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_IMPLICIT); - } - - /*--- MPI solution ---*/ - - InitiateComms(geometry, config, SOLUTION_EDDY); - CompleteComms(geometry, config, SOLUTION_EDDY); - - /*--- Compute the root mean square residual ---*/ - - SetResidual_RMS(geometry, config); - -} - -void CTurbSolver::ComputeUnderRelaxationFactor(CSolver **solver_container, CConfig *config) { - - /* Only apply the turbulent under-relaxation to the SA variants. The - SA_NEG model is more robust due to allowing for negative nu_tilde, - so the under-relaxation is not applied to that variant. */ - - bool sa_model = ((config->GetKind_Turb_Model() == SA) || - (config->GetKind_Turb_Model() == SA_E) || - (config->GetKind_Turb_Model() == SA_COMP) || - (config->GetKind_Turb_Model() == SA_E_COMP)); - - /* Loop over the solution update given by relaxing the linear - system for this nonlinear iteration. */ - - su2double localUnderRelaxation = 1.00; - const su2double allowableDecrease = -0.99; - const su2double allowableIncrease = 0.99; - - for (unsigned long iPoint = 0; iPoint < nPointDomain; iPoint++) { - - localUnderRelaxation = 1.0; - if (sa_model) { - for (unsigned short iVar = 0; iVar < nVar; iVar++) { - - /* We impose a limit on the maximum percentage that the - turbulence variables can change over a nonlinear iteration. */ - - const unsigned long index = iPoint*nVar + iVar; - su2double ratio = LinSysSol[index]/(nodes->GetSolution(iPoint, iVar)+EPS); - if (ratio > allowableIncrease) { - localUnderRelaxation = min(allowableIncrease/ratio, localUnderRelaxation); - } else if (ratio < allowableDecrease) { - localUnderRelaxation = min(fabs(allowableDecrease)/ratio, localUnderRelaxation); - } - - } - } - - /* Choose the minimum factor between mean flow and turbulence. */ - - localUnderRelaxation = min(localUnderRelaxation, solver_container[FLOW_SOL]->GetNodes()->GetUnderRelaxation(iPoint)); - - /* Threshold the relaxation factor in the event that there is - a very small value. This helps avoid catastrophic crashes due - to non-realizable states by canceling the update. */ - - if (localUnderRelaxation < 1e-10) localUnderRelaxation = 0.0; - - /* Store the under-relaxation factor for this point. */ - - nodes->SetUnderRelaxation(iPoint, localUnderRelaxation); - - } - -} - -void CTurbSolver::SetResidual_DualTime(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iRKStep, unsigned short iMesh, unsigned short RunTime_EqSystem) { - - /*--- Local variables ---*/ - - unsigned short iVar, jVar, iMarker, iDim; - unsigned long iPoint, jPoint, iEdge, iVertex; - - su2double *U_time_nM1, *U_time_n, *U_time_nP1; - su2double Volume_nM1, Volume_nP1, TimeStep; - su2double Density_nM1, Density_n, Density_nP1; - su2double *Normal = NULL, *GridVel_i = NULL, *GridVel_j = NULL, Residual_GCL; - - bool implicit = (config->GetKind_TimeIntScheme_Turb() == EULER_IMPLICIT); - - bool incompressible = (config->GetKind_Regime() == INCOMPRESSIBLE); - unsigned short turbModel = config->GetKind_Turb_Model(); - - /*--- Store the physical time step ---*/ - - TimeStep = config->GetDelta_UnstTimeND(); - - /*--- Compute the dual time-stepping source term for static meshes ---*/ - - if (!dynamic_grid) { - - /*--- Loop over all nodes (excluding halos) ---*/ - - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - - /*--- Retrieve the solution at time levels n-1, n, and n+1. Note that - we are currently iterating on U^n+1 and that U^n & U^n-1 are fixed, - previous solutions that are stored in memory. ---*/ - - U_time_nM1 = nodes->GetSolution_time_n1(iPoint); - U_time_n = nodes->GetSolution_time_n(iPoint); - U_time_nP1 = nodes->GetSolution(iPoint); - - /*--- CV volume at time n+1. As we are on a static mesh, the volume - of the CV will remained fixed for all time steps. ---*/ - - Volume_nP1 = geometry->node[iPoint]->GetVolume(); - - /*--- Compute the dual time-stepping source term based on the chosen - time discretization scheme (1st- or 2nd-order).---*/ - - if ((turbModel == SST) || (turbModel == SST_SUST)) { - - /*--- If this is the SST model, we need to multiply by the density - in order to get the conservative variables ---*/ - if (incompressible){ - /*--- This is temporary and only valid for constant-density problems: - density could also be temperature dependent, but as it is not a part - of the solution vector it's neither stored for previous time steps - nor updated with the solution at the end of each iteration. */ - Density_nM1 = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); - Density_n = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); - Density_nP1 = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); - } - else{ - Density_nM1 = solver_container[FLOW_SOL]->GetNodes()->GetSolution_time_n1(iPoint)[0]; - Density_n = solver_container[FLOW_SOL]->GetNodes()->GetSolution_time_n(iPoint,0); - Density_nP1 = solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint,0); - } - - for (iVar = 0; iVar < nVar; iVar++) { - if (config->GetTime_Marching() == DT_STEPPING_1ST) - Residual[iVar] = ( Density_nP1*U_time_nP1[iVar] - Density_n*U_time_n[iVar])*Volume_nP1 / TimeStep; - if (config->GetTime_Marching() == DT_STEPPING_2ND) - Residual[iVar] = ( 3.0*Density_nP1*U_time_nP1[iVar] - 4.0*Density_n*U_time_n[iVar] - +1.0*Density_nM1*U_time_nM1[iVar])*Volume_nP1 / (2.0*TimeStep); - } - - } else { - - for (iVar = 0; iVar < nVar; iVar++) { - if (config->GetTime_Marching() == DT_STEPPING_1ST) - Residual[iVar] = (U_time_nP1[iVar] - U_time_n[iVar])*Volume_nP1 / TimeStep; - if (config->GetTime_Marching() == DT_STEPPING_2ND) - Residual[iVar] = ( 3.0*U_time_nP1[iVar] - 4.0*U_time_n[iVar] - +1.0*U_time_nM1[iVar])*Volume_nP1 / (2.0*TimeStep); - } - } - - /*--- Store the residual and compute the Jacobian contribution due - to the dual time source term. ---*/ - - LinSysRes.AddBlock(iPoint, Residual); - if (implicit) { - for (iVar = 0; iVar < nVar; iVar++) { - for (jVar = 0; jVar < nVar; jVar++) Jacobian_i[iVar][jVar] = 0.0; - if (config->GetTime_Marching() == DT_STEPPING_1ST) - Jacobian_i[iVar][iVar] = Volume_nP1 / TimeStep; - if (config->GetTime_Marching() == DT_STEPPING_2ND) - Jacobian_i[iVar][iVar] = (Volume_nP1*3.0)/(2.0*TimeStep); - } - Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - } - } - - } else { - - /*--- For unsteady flows on dynamic meshes (rigidly transforming or - dynamically deforming), the Geometric Conservation Law (GCL) should be - satisfied in conjunction with the ALE formulation of the governing - equations. The GCL prevents accuracy issues caused by grid motion, i.e. - a uniform free-stream should be preserved through a moving grid. First, - we will loop over the edges and boundaries to compute the GCL component - of the dual time source term that depends on grid velocities. ---*/ - - for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { - - /*--- Get indices for nodes i & j plus the face normal ---*/ - - iPoint = geometry->edge[iEdge]->GetNode(0); - jPoint = geometry->edge[iEdge]->GetNode(1); - Normal = geometry->edge[iEdge]->GetNormal(); - - /*--- Grid velocities stored at nodes i & j ---*/ - - GridVel_i = geometry->node[iPoint]->GetGridVel(); - GridVel_j = geometry->node[jPoint]->GetGridVel(); - - /*--- Compute the GCL term by averaging the grid velocities at the - edge mid-point and dotting with the face normal. ---*/ - - Residual_GCL = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - Residual_GCL += 0.5*(GridVel_i[iDim]+GridVel_j[iDim])*Normal[iDim]; - - /*--- Compute the GCL component of the source term for node i ---*/ - - U_time_n = nodes->GetSolution_time_n(iPoint); - - /*--- Multiply by density at node i for the SST model ---*/ - - if ((turbModel == SST) || (turbModel == SST_SUST)) { - if (incompressible) Density_n = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); // Temporary fix - else Density_n = solver_container[FLOW_SOL]->GetNodes()->GetSolution_time_n(iPoint,0); - for (iVar = 0; iVar < nVar; iVar++) - Residual[iVar] = Density_n*U_time_n[iVar]*Residual_GCL; - } else { - for (iVar = 0; iVar < nVar; iVar++) - Residual[iVar] = U_time_n[iVar]*Residual_GCL; - } - LinSysRes.AddBlock(iPoint, Residual); - - /*--- Compute the GCL component of the source term for node j ---*/ - - U_time_n = nodes->GetSolution_time_n(jPoint); - - /*--- Multiply by density at node j for the SST model ---*/ - - if ((turbModel == SST) || (turbModel == SST_SUST)) { - if (incompressible) Density_n = solver_container[FLOW_SOL]->GetNodes()->GetDensity(jPoint); // Temporary fix - else Density_n = solver_container[FLOW_SOL]->GetNodes()->GetSolution_time_n(jPoint)[0]; - for (iVar = 0; iVar < nVar; iVar++) - Residual[iVar] = Density_n*U_time_n[iVar]*Residual_GCL; - } else { - for (iVar = 0; iVar < nVar; iVar++) - Residual[iVar] = U_time_n[iVar]*Residual_GCL; - } - LinSysRes.SubtractBlock(jPoint, Residual); - - } - - /*--- Loop over the boundary edges ---*/ - - for (iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { - if ((config->GetMarker_All_KindBC(iMarker) != INTERNAL_BOUNDARY) && - (config->GetMarker_All_KindBC(iMarker) != PERIODIC_BOUNDARY)) { - for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { - - /*--- Get the index for node i plus the boundary face normal ---*/ - - iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - - /*--- Grid velocities stored at boundary node i ---*/ - - GridVel_i = geometry->node[iPoint]->GetGridVel(); - - /*--- Compute the GCL term by dotting the grid velocity with the face - normal. The normal is negated to match the boundary convention. ---*/ - - Residual_GCL = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - Residual_GCL -= 0.5*(GridVel_i[iDim]+GridVel_i[iDim])*Normal[iDim]; - - /*--- Compute the GCL component of the source term for node i ---*/ - - U_time_n = nodes->GetSolution_time_n(iPoint); - - /*--- Multiply by density at node i for the SST model ---*/ - - if ((turbModel == SST) || (turbModel == SST_SUST)) { - if (incompressible) Density_n = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); // Temporary fix - else Density_n = solver_container[FLOW_SOL]->GetNodes()->GetSolution_time_n(iPoint,0); - for (iVar = 0; iVar < nVar; iVar++) - Residual[iVar] = Density_n*U_time_n[iVar]*Residual_GCL; - } else { - for (iVar = 0; iVar < nVar; iVar++) - Residual[iVar] = U_time_n[iVar]*Residual_GCL; - } - LinSysRes.AddBlock(iPoint, Residual); - - } - } - } - - /*--- Loop over all nodes (excluding halos) to compute the remainder - of the dual time-stepping source term. ---*/ - - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - - /*--- Retrieve the solution at time levels n-1, n, and n+1. Note that - we are currently iterating on U^n+1 and that U^n & U^n-1 are fixed, - previous solutions that are stored in memory. ---*/ - - U_time_nM1 = nodes->GetSolution_time_n1(iPoint); - U_time_n = nodes->GetSolution_time_n(iPoint); - U_time_nP1 = nodes->GetSolution(iPoint); - - /*--- CV volume at time n-1 and n+1. In the case of dynamically deforming - grids, the volumes will change. On rigidly transforming grids, the - volumes will remain constant. ---*/ - - Volume_nM1 = geometry->node[iPoint]->GetVolume_nM1(); - Volume_nP1 = geometry->node[iPoint]->GetVolume(); - - /*--- Compute the dual time-stepping source residual. Due to the - introduction of the GCL term above, the remainder of the source residual - due to the time discretization has a new form.---*/ - - if ((turbModel == SST) || (turbModel == SST_SUST)) { - - /*--- If this is the SST model, we need to multiply by the density - in order to get the conservative variables ---*/ - if (incompressible){ - /*--- This is temporary and only valid for constant-density problems: - density could also be temperature dependent, but as it is not a part - of the solution vector it's neither stored for previous time steps - nor updated with the solution at the end of each iteration. */ - Density_nM1 = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); - Density_n = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); - Density_nP1 = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); - } - else{ - Density_nM1 = solver_container[FLOW_SOL]->GetNodes()->GetSolution_time_n1(iPoint)[0]; - Density_n = solver_container[FLOW_SOL]->GetNodes()->GetSolution_time_n(iPoint,0); - Density_nP1 = solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint,0); - } - - for (iVar = 0; iVar < nVar; iVar++) { - if (config->GetTime_Marching() == DT_STEPPING_1ST) - Residual[iVar] = (Density_nP1*U_time_nP1[iVar] - Density_n*U_time_n[iVar])*(Volume_nP1/TimeStep); - if (config->GetTime_Marching() == DT_STEPPING_2ND) - Residual[iVar] = (Density_nP1*U_time_nP1[iVar] - Density_n*U_time_n[iVar])*(3.0*Volume_nP1/(2.0*TimeStep)) - + (Density_nM1*U_time_nM1[iVar] - Density_n*U_time_n[iVar])*(Volume_nM1/(2.0*TimeStep)); - } - - } else { - - for (iVar = 0; iVar < nVar; iVar++) { - if (config->GetTime_Marching() == DT_STEPPING_1ST) - Residual[iVar] = (U_time_nP1[iVar] - U_time_n[iVar])*(Volume_nP1/TimeStep); - if (config->GetTime_Marching() == DT_STEPPING_2ND) - Residual[iVar] = (U_time_nP1[iVar] - U_time_n[iVar])*(3.0*Volume_nP1/(2.0*TimeStep)) - + (U_time_nM1[iVar] - U_time_n[iVar])*(Volume_nM1/(2.0*TimeStep)); - } - } - - /*--- Store the residual and compute the Jacobian contribution due - to the dual time source term. ---*/ - - LinSysRes.AddBlock(iPoint, Residual); - if (implicit) { - for (iVar = 0; iVar < nVar; iVar++) { - for (jVar = 0; jVar < nVar; jVar++) Jacobian_i[iVar][jVar] = 0.0; - if (config->GetTime_Marching() == DT_STEPPING_1ST) - Jacobian_i[iVar][iVar] = Volume_nP1/TimeStep; - if (config->GetTime_Marching() == DT_STEPPING_2ND) - Jacobian_i[iVar][iVar] = (3.0*Volume_nP1)/(2.0*TimeStep); - } - Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - } - } - } - -} - - -void CTurbSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo) { - - /*--- Restart the solution from file information ---*/ - - unsigned short iVar, iMesh; - unsigned long iPoint, index, iChildren, Point_Fine; - su2double Area_Children, Area_Parent, *Solution_Fine; - - string restart_filename = config->GetFilename(config->GetSolution_FileName(), "", val_iter); - /*--- Read the restart data from either an ASCII or binary SU2 file. ---*/ - - if (config->GetRead_Binary_Restart()) { - Read_SU2_Restart_Binary(geometry[MESH_0], config, restart_filename); - } else { - Read_SU2_Restart_ASCII(geometry[MESH_0], config, restart_filename); - } - - int counter = 0; - long iPoint_Local = 0; unsigned long iPoint_Global = 0; - unsigned long iPoint_Global_Local = 0; - unsigned short rbuf_NotMatching = 0, sbuf_NotMatching = 0; - - /*--- Skip flow variables ---*/ - - unsigned short skipVars = 0; - - if (nDim == 2) skipVars += 6; - if (nDim == 3) skipVars += 8; - - /*--- Adjust the number of solution variables in the incompressible - restart. We always carry a space in nVar for the energy equation in the - mean flow solver, but we only write it to the restart if it is active. - Therefore, we must reduce skipVars here if energy is inactive so that - the turbulent variables are read correctly. ---*/ - - bool incompressible = (config->GetKind_Regime() == INCOMPRESSIBLE); - bool energy = config->GetEnergy_Equation(); - bool weakly_coupled_heat = config->GetWeakly_Coupled_Heat(); - - if (incompressible && ((!energy) && (!weakly_coupled_heat))) skipVars--; - - /*--- Load data from the restart into correct containers. ---*/ - - counter = 0; - for (iPoint_Global = 0; iPoint_Global < geometry[MESH_0]->GetGlobal_nPointDomain(); iPoint_Global++ ) { - - - /*--- Retrieve local index. If this node from the restart file lives - on the current processor, we will load and instantiate the vars. ---*/ - - iPoint_Local = geometry[MESH_0]->GetGlobal_to_Local_Point(iPoint_Global); - - if (iPoint_Local > -1) { - - /*--- We need to store this point's data, so jump to the correct - offset in the buffer of data from the restart file and load it. ---*/ - - index = counter*Restart_Vars[1] + skipVars; - for (iVar = 0; iVar < nVar; iVar++) Solution[iVar] = Restart_Data[index+iVar]; - nodes->SetSolution(iPoint_Local,Solution); - iPoint_Global_Local++; - - /*--- Increment the overall counter for how many points have been loaded. ---*/ - counter++; - } - - } - - /*--- Detect a wrong solution file ---*/ - - if (iPoint_Global_Local < nPointDomain) { sbuf_NotMatching = 1; } - -#ifndef HAVE_MPI - rbuf_NotMatching = sbuf_NotMatching; -#else - SU2_MPI::Allreduce(&sbuf_NotMatching, &rbuf_NotMatching, 1, MPI_UNSIGNED_SHORT, MPI_SUM, MPI_COMM_WORLD); -#endif - if (rbuf_NotMatching != 0) { - SU2_MPI::Error(string("The solution file ") + restart_filename + string(" doesn't match with the mesh file!\n") + - string("It could be empty lines at the end of the file."), CURRENT_FUNCTION); - } - - /*--- MPI solution and compute the eddy viscosity ---*/ - - solver[MESH_0][TURB_SOL]->InitiateComms(geometry[MESH_0], config, SOLUTION_EDDY); - solver[MESH_0][TURB_SOL]->CompleteComms(geometry[MESH_0], config, SOLUTION_EDDY); - - solver[MESH_0][FLOW_SOL]->Preprocessing(geometry[MESH_0], solver[MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); - solver[MESH_0][TURB_SOL]->Postprocessing(geometry[MESH_0], solver[MESH_0], config, MESH_0); - - /*--- Interpolate the solution down to the coarse multigrid levels ---*/ - - for (iMesh = 1; iMesh <= config->GetnMGLevels(); iMesh++) { - for (iPoint = 0; iPoint < geometry[iMesh]->GetnPoint(); iPoint++) { - Area_Parent = geometry[iMesh]->node[iPoint]->GetVolume(); - for (iVar = 0; iVar < nVar; iVar++) Solution[iVar] = 0.0; - for (iChildren = 0; iChildren < geometry[iMesh]->node[iPoint]->GetnChildren_CV(); iChildren++) { - Point_Fine = geometry[iMesh]->node[iPoint]->GetChildren_CV(iChildren); - Area_Children = geometry[iMesh-1]->node[Point_Fine]->GetVolume(); - Solution_Fine = solver[iMesh-1][TURB_SOL]->GetNodes()->GetSolution(Point_Fine); - for (iVar = 0; iVar < nVar; iVar++) { - Solution[iVar] += Solution_Fine[iVar]*Area_Children/Area_Parent; - } - } - solver[iMesh][TURB_SOL]->GetNodes()->SetSolution(iPoint,Solution); - } - solver[iMesh][TURB_SOL]->InitiateComms(geometry[iMesh], config, SOLUTION_EDDY); - solver[iMesh][TURB_SOL]->CompleteComms(geometry[iMesh], config, SOLUTION_EDDY); - solver[iMesh][FLOW_SOL]->Preprocessing(geometry[iMesh], solver[iMesh], config, iMesh, NO_RK_ITER, RUNTIME_FLOW_SYS, false); - solver[iMesh][TURB_SOL]->Postprocessing(geometry[iMesh], solver[iMesh], config, iMesh); - } - - /*--- Delete the class memory that is used to load the restart. ---*/ - - if (Restart_Vars != NULL) delete [] Restart_Vars; - if (Restart_Data != NULL) delete [] Restart_Data; - Restart_Vars = NULL; Restart_Data = NULL; - -} +#include "../../include/solvers/CTurbSASolver.hpp" +#include "../../include/variables/CTurbSAVariable.hpp" CTurbSASolver::CTurbSASolver(void) : CTurbSolver() { @@ -941,36 +45,36 @@ CTurbSASolver::CTurbSASolver(CGeometry *geometry, CConfig *config, unsigned shor Gamma = config->GetGamma(); Gamma_Minus_One = Gamma - 1.0; - + /*--- Dimension of the problem --> dependent of the turbulent model ---*/ - + nVar = 1; nPrimVar = 1; nPoint = geometry->GetnPoint(); nPointDomain = geometry->GetnPointDomain(); - + /*--- Initialize nVarGrad for deallocation ---*/ - + nVarGrad = nVar; - + /*--- Define geometry constants in the solver structure ---*/ - + nDim = geometry->GetnDim(); - + /*--- Single grid simulation ---*/ - + if (iMesh == MESH_0 || config->GetMGCycle() == FULLMG_CYCLE) { - + /*--- Define some auxiliar vector related with the residual ---*/ - + Residual = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = 0.0; Residual_RMS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_RMS[iVar] = 0.0; Residual_i = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_i[iVar] = 0.0; Residual_j = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_j[iVar] = 0.0; Residual_Max = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_Max[iVar] = 0.0; - + /*--- Define some structures for locating max residuals ---*/ - + Point_Max = new unsigned long[nVar]; for (iVar = 0; iVar < nVar; iVar++) Point_Max[iVar] = 0; Point_Max_Coord = new su2double*[nVar]; @@ -978,63 +82,63 @@ CTurbSASolver::CTurbSASolver(CGeometry *geometry, CConfig *config, unsigned shor Point_Max_Coord[iVar] = new su2double[nDim]; for (iDim = 0; iDim < nDim; iDim++) Point_Max_Coord[iVar][iDim] = 0.0; } - + /*--- Define some auxiliar vector related with the solution ---*/ - + Solution = new su2double[nVar]; Solution_i = new su2double[nVar]; Solution_j = new su2double[nVar]; - + /*--- Define some auxiliar vector related with the geometry ---*/ - + Vector_i = new su2double[nDim]; Vector_j = new su2double[nDim]; - + /*--- Define some auxiliar vector related with the flow solution ---*/ - + FlowPrimVar_i = new su2double [nDim+9]; FlowPrimVar_j = new su2double [nDim+9]; - + /*--- Jacobians and vector structures for implicit computations ---*/ - + Jacobian_i = new su2double* [nVar]; Jacobian_j = new su2double* [nVar]; for (iVar = 0; iVar < nVar; iVar++) { Jacobian_i[iVar] = new su2double [nVar]; Jacobian_j[iVar] = new su2double [nVar]; } - + /*--- Initialization of the structure of the whole Jacobian ---*/ - + if (rank == MASTER_NODE) cout << "Initialize Jacobian structure (SA model)." << endl; Jacobian.Initialize(nPoint, nPointDomain, nVar, nVar, true, geometry, config); - + if (config->GetKind_Linear_Solver_Prec() == LINELET) { nLineLets = Jacobian.BuildLineletPreconditioner(geometry, config); if (rank == MASTER_NODE) cout << "Compute linelet structure. " << nLineLets << " elements in each line (average)." << endl; } - + LinSysSol.Initialize(nPoint, nPointDomain, nVar, 0.0); LinSysRes.Initialize(nPoint, nPointDomain, nVar, 0.0); - + if (config->GetExtraOutput()) { if (nDim == 2) { nOutputVariables = 13; } else if (nDim == 3) { nOutputVariables = 19; } OutputVariables.Initialize(nPoint, nPointDomain, nOutputVariables, 0.0); OutputHeadingNames = new string[nOutputVariables]; } - + /*--- Computation of gradients by least squares ---*/ - + if (config->GetLeastSquaresRequired()) { /*--- S matrix := inv(R)*traspose(inv(R)) ---*/ Smatrix = new su2double* [nDim]; for (iDim = 0; iDim < nDim; iDim++) Smatrix[iDim] = new su2double [nDim]; - + /*--- c vector := transpose(WA)*(Wb) ---*/ Cvector = new su2double* [nVar]; for (iVar = 0; iVar < nVar; iVar++) Cvector[iVar] = new su2double [nDim]; } - + /*--- Initialize the BGS residuals in multizone problems. ---*/ if (multizone){ Residual_BGS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_BGS[iVar] = 0.0; @@ -1053,10 +157,10 @@ CTurbSASolver::CTurbSASolver(CGeometry *geometry, CConfig *config, unsigned shor } /*--- Read farfield conditions from config ---*/ - + Density_Inf = config->GetDensity_FreeStreamND(); Viscosity_Inf = config->GetViscosity_FreeStreamND(); - + /*--- Factor_nu_Inf in [3.0, 5.0] ---*/ Factor_nu_Inf = config->GetNuFactor_FreeStream(); @@ -1093,19 +197,19 @@ CTurbSASolver::CTurbSASolver(CGeometry *geometry, CConfig *config, unsigned shor InitiateComms(geometry, config, SOLUTION_EDDY); CompleteComms(geometry, config, SOLUTION_EDDY); - + /*--- Initializate quantities for SlidingMesh Interface ---*/ unsigned long iMarker; SlidingState = new su2double*** [nMarker]; SlidingStateNodes = new int* [nMarker]; - + for (iMarker = 0; iMarker < nMarker; iMarker++){ SlidingState[iMarker] = NULL; SlidingStateNodes[iMarker] = NULL; - + if (config->GetMarker_All_KindBC(iMarker) == FLUID_INTERFACE){ SlidingState[iMarker] = new su2double**[geometry->GetnVertex(iMarker)]; @@ -1133,7 +237,7 @@ CTurbSASolver::CTurbSASolver(CGeometry *geometry, CConfig *config, unsigned shor Inlet_TurbVars[iMarker][iVertex][0] = nu_tilde_Inf; } } - + /*--- The turbulence models are always solved implicitly, so set the implicit flag in case we have periodic BCs. ---*/ @@ -1148,17 +252,17 @@ CTurbSASolver::CTurbSASolver(CGeometry *geometry, CConfig *config, unsigned shor Min_CFL_Local = CFL; Max_CFL_Local = CFL; Avg_CFL_Local = CFL; - + /*--- Add the solver name (max 8 characters) ---*/ SolverName = "SA"; } CTurbSASolver::~CTurbSASolver(void) { - + unsigned long iMarker, iVertex; unsigned short iVar; - + if ( SlidingState != NULL ) { for (iMarker = 0; iMarker < nMarker; iMarker++) { if ( SlidingState[iMarker] != NULL ) { @@ -1173,11 +277,11 @@ CTurbSASolver::~CTurbSASolver(void) { } delete [] SlidingState; } - + if ( SlidingStateNodes != NULL ){ for (iMarker = 0; iMarker < nMarker; iMarker++){ if (SlidingStateNodes[iMarker] != NULL) - delete [] SlidingStateNodes[iMarker]; + delete [] SlidingStateNodes[iMarker]; } delete [] SlidingStateNodes; } @@ -1185,24 +289,24 @@ CTurbSASolver::~CTurbSASolver(void) { } void CTurbSASolver::Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output) { - + unsigned long iPoint; bool limiter_turb = (config->GetKind_SlopeLimit_Turb() != NO_LIMITER) && (config->GetInnerIter() <= config->GetLimiterIter()); unsigned short kind_hybridRANSLES = config->GetKind_HybridRANSLES(); su2double** PrimGrad_Flow = NULL; su2double* Vorticity = NULL; su2double Laminar_Viscosity = 0; - + for (iPoint = 0; iPoint < nPoint; iPoint ++) { - + /*--- Initialize the residual vector ---*/ - + LinSysRes.SetBlock_Zero(iPoint); - + } - + /*--- Initialize the Jacobian matrices ---*/ - + Jacobian.SetValZero(); /*--- Upwind second order reconstruction and gradients ---*/ @@ -1221,9 +325,9 @@ void CTurbSASolver::Preprocessing(CGeometry *geometry, CSolver **solver_containe if (limiter_turb) SetSolution_Limiter(geometry, config); if (kind_hybridRANSLES != NO_HYBRIDRANSLES){ - + /*--- Set the vortex tilting coefficient at every node if required ---*/ - + if (kind_hybridRANSLES == SA_EDDES){ for (iPoint = 0; iPoint < nPoint; iPoint++){ PrimGrad_Flow = solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint); @@ -1232,103 +336,103 @@ void CTurbSASolver::Preprocessing(CGeometry *geometry, CSolver **solver_containe nodes->SetVortex_Tilting(iPoint,PrimGrad_Flow, Vorticity, Laminar_Viscosity); } } - + /*--- Compute the DES length scale ---*/ - + SetDES_LengthScale(solver_container, geometry, config); - + } } void CTurbSASolver::Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh) { - + su2double rho = 0.0, mu = 0.0, nu, *nu_hat, muT, Ji, Ji_3, fv1; su2double cv1_3 = 7.1*7.1*7.1; unsigned long iPoint; - + bool neg_spalart_allmaras = (config->GetKind_Turb_Model() == SA_NEG); - + /*--- Compute eddy viscosity ---*/ - + for (iPoint = 0; iPoint < nPoint; iPoint ++) { - + rho = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); mu = solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); - + nu = mu/rho; nu_hat = nodes->GetSolution(iPoint); - + Ji = nu_hat[0]/nu; Ji_3 = Ji*Ji*Ji; fv1 = Ji_3/(Ji_3+cv1_3); - + muT = rho*fv1*nu_hat[0]; - + if (neg_spalart_allmaras && (muT < 0.0)) muT = 0.0; - + nodes->SetmuT(iPoint,muT); - + } - + } void CTurbSASolver::Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CNumerics *second_numerics, CConfig *config, unsigned short iMesh) { unsigned long iPoint; - + bool harmonic_balance = (config->GetTime_Marching() == HARMONIC_BALANCE); bool transition = (config->GetKind_Trans_Model() == LM); bool transition_BC = (config->GetKind_Trans_Model() == BC); - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /*--- Conservative variables w/o reconstruction ---*/ - + numerics->SetPrimitive(solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint), NULL); - + /*--- Gradient of the primitive and conservative variables ---*/ - + numerics->SetPrimVarGradient(solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint), NULL); - + /*--- Set vorticity and strain rate magnitude ---*/ - + numerics->SetVorticity(solver_container[FLOW_SOL]->GetNodes()->GetVorticity(iPoint), NULL); numerics->SetStrainMag(solver_container[FLOW_SOL]->GetNodes()->GetStrainMag(iPoint), 0.0); - + /*--- Set intermittency ---*/ - + if (transition) { numerics->SetIntermittency(solver_container[TRANS_SOL]->GetNodes()->GetIntermittency(iPoint)); } - + /*--- Turbulent variables w/o reconstruction, and its gradient ---*/ - + numerics->SetTurbVar(nodes->GetSolution(iPoint), NULL); numerics->SetTurbVarGradient(nodes->GetGradient(iPoint), NULL); - + /*--- Set volume ---*/ - + numerics->SetVolume(geometry->node[iPoint]->GetVolume()); - /*--- Get Hybrid RANS/LES Type and set the appropriate wall distance ---*/ - + /*--- Get Hybrid RANS/LES Type and set the appropriate wall distance ---*/ + if (config->GetKind_HybridRANSLES() == NO_HYBRIDRANSLES) { - + /*--- Set distance to the surface ---*/ - + numerics->SetDistance(geometry->node[iPoint]->GetWall_Distance(), 0.0); - + } else { - + /*--- Set DES length scale ---*/ - + numerics->SetDistance(nodes->GetDES_LengthScale(iPoint), 0.0); - + } /*--- Compute the source term ---*/ - + numerics->ComputeResidual(Residual, Jacobian_i, NULL, config); /*--- Store the intermittency ---*/ @@ -1336,86 +440,86 @@ void CTurbSASolver::Source_Residual(CGeometry *geometry, CSolver **solver_contai if (transition_BC) { nodes->SetGammaBC(iPoint,numerics->GetGammaBC()); } - + /*--- Subtract residual and the Jacobian ---*/ - + LinSysRes.SubtractBlock(iPoint, Residual); - + Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - + } - + if (harmonic_balance) { - + su2double Volume, Source; unsigned short nVar_Turb = solver_container[TURB_SOL]->GetnVar(); - + /*--- Loop over points ---*/ - + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - + /*--- Get control volume ---*/ - + Volume = geometry->node[iPoint]->GetVolume(); - + /*--- Access stored harmonic balance source term ---*/ - + for (unsigned short iVar = 0; iVar < nVar_Turb; iVar++) { Source = nodes->GetHarmonicBalance_Source(iPoint,iVar); Residual[iVar] = Source*Volume; } - + /*--- Add Residual ---*/ - + LinSysRes.AddBlock(iPoint, Residual); - + } } - + } void CTurbSASolver::Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short iMesh) { - + } void CTurbSASolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { unsigned long iPoint, iVertex; unsigned short iVar; - + /*--- The dirichlet condition is used only without wall function, otherwise the convergence is compromised as we are providing nu tilde values for the first point of the wall ---*/ - + if (!config->GetWall_Functions()) { - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ - + if (geometry->node[iPoint]->GetDomain()) { - + /*--- Get the velocity vector ---*/ - + for (iVar = 0; iVar < nVar; iVar++) Solution[iVar] = 0.0; - + nodes->SetSolution_Old(iPoint,Solution); LinSysRes.SetBlock_Zero(iPoint); - + /*--- Includes 1 in the diagonal ---*/ - + Jacobian.DeleteValsRowi(iPoint); } } } else { - + /*--- Evaluate nu tilde at the closest point to the surface using the wall functions ---*/ - + SetNuTilde_WF(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); - + } } @@ -1424,129 +528,129 @@ void CTurbSASolver::BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_con unsigned short val_marker) { unsigned long iPoint, iVertex; unsigned short iVar; - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ - + if (geometry->node[iPoint]->GetDomain()) { - + /*--- Get the velocity vector ---*/ for (iVar = 0; iVar < nVar; iVar++) Solution[iVar] = 0.0; - + nodes->SetSolution_Old(iPoint,Solution); LinSysRes.SetBlock_Zero(iPoint); - + /*--- Includes 1 in the diagonal ---*/ - + Jacobian.DeleteValsRowi(iPoint); } } - + } void CTurbSASolver::BC_Far_Field(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + unsigned long iPoint, iVertex; unsigned short iVar, iDim; su2double *Normal, *V_infty, *V_domain; - + Normal = new su2double[nDim]; - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ - + if (geometry->node[iPoint]->GetDomain()) { - + /*--- Allocate the value at the infinity ---*/ - + V_infty = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); - + /*--- Retrieve solution at the farfield boundary node ---*/ - + V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); - + /*--- Grid Movement ---*/ - + if (dynamic_grid) conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); - + conv_numerics->SetPrimitive(V_domain, V_infty); - + /*--- Set turbulent variable at the wall, and at infinity ---*/ - + for (iVar = 0; iVar < nVar; iVar++) Solution_i[iVar] = nodes->GetSolution(iPoint,iVar); Solution_j[0] = nu_tilde_Inf; conv_numerics->SetTurbVar(Solution_i, Solution_j); - + /*--- Set Normal (it is necessary to change the sign) ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); - + /*--- Compute residuals and Jacobians ---*/ - + conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - + /*--- Add residuals and Jacobians ---*/ - + LinSysRes.AddBlock(iPoint, Residual); Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - + } } - + delete [] Normal; - + } void CTurbSASolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + unsigned short iDim; unsigned long iVertex, iPoint; su2double *V_inlet, *V_domain, *Normal; - + Normal = new su2double[nDim]; - + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - + /*--- Loop over all the vertices on this boundary marker ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check if the node belongs to the domain (i.e., not a halo node) ---*/ - + if (geometry->node[iPoint]->GetDomain()) { - + /*--- Normal vector for this vertex (negate for outward convention) ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; - + /*--- Allocate the value at the inlet ---*/ - + V_inlet = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); - + /*--- Retrieve solution at the farfield boundary node ---*/ - + V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); - + /*--- Set various quantities in the solver class ---*/ - + conv_numerics->SetPrimitive(V_domain, V_inlet); - + /*--- Set the turbulent variable states (prescribed for an inflow) ---*/ - + Solution_i[0] = nodes->GetSolution(iPoint,0); /*--- Load the inlet turbulence variable (uniform by default). ---*/ @@ -1554,24 +658,24 @@ void CTurbSASolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, CN Solution_j[0] = Inlet_TurbVars[val_marker][iVertex][0]; conv_numerics->SetTurbVar(Solution_i, Solution_j); - + /*--- Set various other quantities in the conv_numerics class ---*/ - + conv_numerics->SetNormal(Normal); - + if (dynamic_grid) conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); - + /*--- Compute the residual using an upwind scheme ---*/ - + conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); LinSysRes.AddBlock(iPoint, Residual); - + /*--- Jacobian contribution for implicit integration ---*/ - + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - + // /*--- Viscous contribution, commented out because serious convergence problems ---*/ // // visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[Point_Normal]->GetCoord()); @@ -1594,13 +698,13 @@ void CTurbSASolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, CN // // LinSysRes.SubtractBlock(iPoint, Residual); // Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - + } } - + /*--- Free locally allocated memory ---*/ delete[] Normal; - + } void CTurbSASolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, @@ -1608,62 +712,62 @@ void CTurbSASolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, C unsigned long iPoint, iVertex; unsigned short iVar, iDim; su2double *V_outlet, *V_domain, *Normal; - + Normal = new su2double[nDim]; - + /*--- Loop over all the vertices on this boundary marker ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check if the node belongs to the domain (i.e., not a halo node) ---*/ - + if (geometry->node[iPoint]->GetDomain()) { - + /*--- Allocate the value at the outlet ---*/ - + V_outlet = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); - + /*--- Retrieve solution at the farfield boundary node ---*/ - + V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); - + /*--- Set various quantities in the solver class ---*/ - + conv_numerics->SetPrimitive(V_domain, V_outlet); - + /*--- Set the turbulent variables. Here we use a Neumann BC such that the turbulent variable is copied from the interior of the domain to the outlet before computing the residual. Solution_i --> TurbVar_internal, Solution_j --> TurbVar_outlet ---*/ - + for (iVar = 0; iVar < nVar; iVar++) { Solution_i[iVar] = nodes->GetSolution(iPoint,iVar); Solution_j[iVar] = nodes->GetSolution(iPoint,iVar); } conv_numerics->SetTurbVar(Solution_i, Solution_j); - + /*--- Set Normal (negate for outward convention) ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); - + if (dynamic_grid) conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); - + /*--- Compute the residual using an upwind scheme ---*/ - + conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); LinSysRes.AddBlock(iPoint, Residual); - + /*--- Jacobian contribution for implicit integration ---*/ - + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - + // /*--- Viscous contribution, commented out because serious convergence problems ---*/ // // visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[Point_Normal]->GetCoord()); @@ -1686,74 +790,74 @@ void CTurbSASolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, C // // LinSysRes.SubtractBlock(iPoint, Residual); // Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - + } } - + /*--- Free locally allocated memory ---*/ - + delete[] Normal; - + } void CTurbSASolver::BC_Engine_Inflow(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + unsigned long iPoint, iVertex; unsigned short iDim; su2double *V_inflow, *V_domain, *Normal; - + Normal = new su2double[nDim]; - + /*--- Loop over all the vertices on this boundary marker ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check if the node belongs to the domain (i.e., not a halo node) ---*/ - + if (geometry->node[iPoint]->GetDomain()) { - + /*--- Allocate the value at the infinity ---*/ - + V_inflow = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); - + /*--- Retrieve solution at the farfield boundary node ---*/ - + V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); - + /*--- Set various quantities in the solver class ---*/ - + conv_numerics->SetPrimitive(V_domain, V_inflow); - + /*--- Set the turbulent variables. Here we use a Neumann BC such that the turbulent variable is copied from the interior of the domain to the outlet before computing the residual. ---*/ - + conv_numerics->SetTurbVar(nodes->GetSolution(iPoint), nodes->GetSolution(iPoint)); - + /*--- Set Normal (negate for outward convention) ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); - + /*--- Set grid movement ---*/ - + if (dynamic_grid) conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); /*--- Compute the residual using an upwind scheme ---*/ - + conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); LinSysRes.AddBlock(iPoint, Residual); - + /*--- Jacobian contribution for implicit integration ---*/ - + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - + // /*--- Viscous contribution, commented out because serious convergence problems ---*/ // // visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[iPoint]->GetCoord()); @@ -1780,76 +884,76 @@ void CTurbSASolver::BC_Engine_Inflow(CGeometry *geometry, CSolver **solver_conta } } - + /*--- Free locally allocated memory ---*/ - + delete[] Normal; - + } void CTurbSASolver::BC_Engine_Exhaust(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + unsigned short iDim; unsigned long iVertex, iPoint; su2double *V_exhaust, *V_domain, *Normal; - + Normal = new su2double[nDim]; - + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - + /*--- Loop over all the vertices on this boundary marker ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- Check if the node belongs to the domain (i.e., not a halo node) ---*/ - + if (geometry->node[iPoint]->GetDomain()) { - + /*--- Normal vector for this vertex (negate for outward convention) ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; - + /*--- Allocate the value at the infinity ---*/ - + V_exhaust = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); - + /*--- Retrieve solution at the farfield boundary node ---*/ - + V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); - + /*--- Set various quantities in the solver class ---*/ - + conv_numerics->SetPrimitive(V_domain, V_exhaust); - + /*--- Set the turbulent variable states (prescribed for an inflow) ---*/ - + Solution_i[0] = nodes->GetSolution(iPoint,0); Solution_j[0] = nu_tilde_Engine; - + conv_numerics->SetTurbVar(Solution_i, Solution_j); - + /*--- Set various other quantities in the conv_numerics class ---*/ - + conv_numerics->SetNormal(Normal); /*--- Set grid movement ---*/ - + if (dynamic_grid) conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); - + /*--- Compute the residual using an upwind scheme ---*/ - + conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); LinSysRes.AddBlock(iPoint, Residual); - + /*--- Jacobian contribution for implicit integration ---*/ - + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - + // /*--- Viscous contribution, commented out because serious convergence problems ---*/ // // visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[iPoint]->GetCoord()); @@ -1872,87 +976,87 @@ void CTurbSASolver::BC_Engine_Exhaust(CGeometry *geometry, CSolver **solver_cont // // LinSysRes.SubtractBlock(iPoint, Residual); // Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - + } } - + /*--- Free locally allocated memory ---*/ - + delete[] Normal; - + } void CTurbSASolver::BC_ActDisk_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + BC_ActDisk(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker, true); - + } void CTurbSASolver::BC_ActDisk_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + BC_ActDisk(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker, false); - + } void CTurbSASolver::BC_ActDisk(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker, bool val_inlet_surface) { - + unsigned long iPoint, iVertex, GlobalIndex_donor, GlobalIndex; su2double *V_outlet, *V_inlet, *V_domain, *Normal, *UnitNormal, Area, Vn; bool ReverseFlow; unsigned short iDim; - + Normal = new su2double[nDim]; UnitNormal = new su2double[nDim]; - + /*--- Loop over all the vertices on this boundary marker ---*/ - + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); GlobalIndex_donor = solver_container[FLOW_SOL]->GetDonorGlobalIndex(val_marker, iVertex); GlobalIndex = geometry->node[iPoint]->GetGlobalIndex(); - + /*--- Check if the node belongs to the domain (i.e., not a halo node) ---*/ - + if ((geometry->node[iPoint]->GetDomain()) && (GlobalIndex != GlobalIndex_donor)) { - + /*--- Normal vector for this vertex (negate for outward convention) ---*/ - + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; conv_numerics->SetNormal(Normal); - + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt (Area); - + for (iDim = 0; iDim < nDim; iDim++) UnitNormal[iDim] = Normal[iDim]/Area; - + /*--- Retrieve solution at the farfield boundary node ---*/ - + V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); - + /*--- Check the flow direction. Project the flow into the normal to the inlet face ---*/ - + Vn = 0.0; ReverseFlow = false; for (iDim = 0; iDim < nDim; iDim++) { Vn += V_domain[iDim+1]*UnitNormal[iDim]; } - + if ((val_inlet_surface) && (Vn < 0.0)) { ReverseFlow = true; } if ((!val_inlet_surface) && (Vn > 0.0)) { ReverseFlow = true; } - + /*--- Do not anything if there is a reverse flow, Euler b.c. for the direct problem ---*/ - + if (!ReverseFlow) { - + /*--- Allocate the value at the infinity ---*/ - + if (val_inlet_surface) { V_inlet = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); V_outlet = solver_container[FLOW_SOL]->GetDonorPrimVar(val_marker, iVertex); @@ -1963,55 +1067,55 @@ void CTurbSASolver::BC_ActDisk(CGeometry *geometry, CSolver **solver_container, V_inlet = solver_container[FLOW_SOL]->GetDonorPrimVar(val_marker, iVertex); conv_numerics->SetPrimitive(V_domain, V_outlet); } - + /*--- Set the turb. variable solution set the turbulent variables. Here we use a Neumann BC such that the turbulent variable is copied from the interior of the domain to the outlet before computing the residual. or set the turbulent variable states (prescribed for an inflow) ----*/ - + Solution_i[0] = nodes->GetSolution(iPoint,0); - + // if (val_inlet_surface) Solution_j[0] = 0.5*(nodes->GetSolution(iPoint,0)+V_outlet [nDim+9]); // else Solution_j[0] = 0.5*(nodes->GetSolution(iPoint,0)+V_inlet [nDim+9]); - + // /*--- Inflow analysis (interior extrapolation) ---*/ // if (((val_inlet_surface) && (!ReverseFlow)) || ((!val_inlet_surface) && (ReverseFlow))) { // Solution_j[0] = 2.0*node[iPoint]->GetSolution(0) - node[iPoint_Normal]->GetSolution(0); // } - + // /*--- Outflow analysis ---*/ // else { // if (val_inlet_surface) Solution_j[0] = Factor_nu_ActDisk*V_outlet [nDim+9]; // else { Solution_j[0] = Factor_nu_ActDisk*V_inlet [nDim+9]; } // } - + /*--- Inflow analysis (interior extrapolation) ---*/ if (((val_inlet_surface) && (!ReverseFlow)) || ((!val_inlet_surface) && (ReverseFlow))) { Solution_j[0] = nodes->GetSolution(iPoint,0); } - + /*--- Outflow analysis ---*/ else { Solution_j[0] = nu_tilde_ActDisk; } - + conv_numerics->SetTurbVar(Solution_i, Solution_j); - + /*--- Grid Movement ---*/ - + if (dynamic_grid) conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); - + /*--- Compute the residual using an upwind scheme ---*/ - + conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); LinSysRes.AddBlock(iPoint, Residual); - + /*--- Jacobian contribution for implicit integration ---*/ - + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - + // /*--- Viscous contribution, commented out because serious convergence problems ---*/ // // visc_numerics->SetNormal(Normal); @@ -2036,16 +1140,16 @@ void CTurbSASolver::BC_ActDisk(CGeometry *geometry, CSolver **solver_container, // // LinSysRes.SubtractBlock(iPoint, Residual); // Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - + } } } - + /*--- Free locally allocated memory ---*/ - + delete[] Normal; delete[] UnitNormal; - + } void CTurbSASolver::BC_Inlet_MixingPlane(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { @@ -2271,7 +1375,7 @@ void CTurbSASolver::BC_Inlet_Turbo(CGeometry *geometry, CSolver **solver_contain void CTurbSASolver::BC_Interface_Boundary(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short val_marker) { - + // unsigned long iVertex, iPoint, jPoint; // unsigned short iVar, iDim; // @@ -2443,7 +1547,7 @@ void CTurbSASolver::BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_con su2double *PrimVar_i = new su2double[nPrimVar]; su2double *PrimVar_j = new su2double[nPrimVar]; su2double *tmp_residual = new su2double[nVar]; - + unsigned long nDonorVertex; su2double weight; @@ -2457,9 +1561,9 @@ void CTurbSASolver::BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_con Point_Normal = geometry->vertex[iMarker][iVertex]->GetNormal_Neighbor(); if (geometry->node[iPoint]->GetDomain()) { - + nDonorVertex = GetnSlidingStates(iMarker, iVertex); - + /*--- Initialize Residual, this will serve to accumulate the average ---*/ for (iVar = 0; iVar < nVar; iVar++) @@ -2502,10 +1606,10 @@ void CTurbSASolver::BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_con conv_numerics->ComputeResidual(tmp_residual, Jacobian_i, Jacobian_j, config); /*--- Accumulate the residuals to compute the average ---*/ - + for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] += weight*tmp_residual[iVar]; - + } /*--- Add Residuals and Jacobians ---*/ @@ -2555,7 +1659,7 @@ void CTurbSASolver::BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_con void CTurbSASolver::BC_NearField_Boundary(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short val_marker) { - + // unsigned long iVertex, iPoint, jPoint; // unsigned short iVar, iDim; // @@ -2718,12 +1822,12 @@ void CTurbSASolver::BC_NearField_Boundary(CGeometry *geometry, CSolver **solver_ void CTurbSASolver::SetNuTilde_WF(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - + /*--- Local variables ---*/ - + unsigned short iDim, jDim, iVar, iNode; unsigned long iVertex, iPoint, iPoint_Neighbor, counter; - + su2double func, func_prim; su2double *Normal, Area; su2double div_vel, UnitNormal[3]; @@ -2738,125 +1842,125 @@ void CTurbSASolver::SetNuTilde_WF(CGeometry *geometry, CSolver **solver_containe su2double TauElem[3], TauNormal, TauTangent[3], WallShearStress; su2double Gas_Constant = config->GetGas_ConstantND(); su2double Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; - + unsigned short max_iter = 100; su2double tol = 1e-10; /*--- Get the freestream velocity magnitude for non-dim. purposes ---*/ - + su2double *VelInf = config->GetVelocity_FreeStreamND(); VelInfMod = 0.0; for (iDim = 0; iDim < nDim; iDim++) VelInfMod += VelInf[iDim]; VelInfMod = sqrt(VelInfMod); - + /*--- Compute the recovery factor ---*/ // su2double-check: laminar or turbulent Pr for this? su2double Recovery = pow(config->GetPrandtl_Lam(),(1.0/3.0)); - + /*--- Typical constants from boundary layer theory ---*/ - + su2double kappa = 0.4; su2double B = 5.5; - + /*--- Identify the boundary by string name ---*/ - + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - + /*--- Get the specified wall heat flux from config ---*/ - + // Wall_HeatFlux = config->GetWall_HeatFlux(Marker_Tag); - + /*--- Loop over all of the vertices on this boundary marker ---*/ - + for(iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - + /*--- We can use also GetNormal_Neighbor, and eliminate the following loop ---*/ - + iPoint_Neighbor = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); for(iNode = 0; iNode < geometry->node[iPoint]->GetnPoint(); iNode++) { iPoint_Neighbor = geometry->node[iPoint]->GetPoint(iNode); - + /*--- Check if the node belongs to the domain (i.e, not a halo node) and the neighbor is not part of the physical boundary ---*/ - + if (geometry->node[iPoint]->GetDomain() && (!geometry->node[iPoint_Neighbor]->GetBoundary())) { - + /*--- Get coordinates of the current vertex and nearest normal point ---*/ - + Coord = geometry->node[iPoint]->GetCoord(); Coord_Normal = geometry->node[iPoint_Neighbor]->GetCoord(); - + /*--- Compute dual-grid area and boundary normal ---*/ - + Normal = geometry->vertex[val_marker][iVertex]->GetNormal(); - + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; Area = sqrt (Area); - + for (iDim = 0; iDim < nDim; iDim++) UnitNormal[iDim] = -Normal[iDim]/Area; - + /*--- Get the velocity, pressure, and temperature at the nearest (normal) interior point. ---*/ - + for (iDim = 0; iDim < nDim; iDim++) Vel[iDim] = solver_container[FLOW_SOL]->GetNodes()->GetVelocity(iPoint_Neighbor,iDim); P_Normal = solver_container[FLOW_SOL]->GetNodes()->GetPressure(iPoint_Neighbor); T_Normal = solver_container[FLOW_SOL]->GetNodes()->GetTemperature(iPoint_Neighbor); /*--- Compute the wall-parallel velocity at first point off the wall ---*/ - + VelNormal = 0.0; for (iDim = 0; iDim < nDim; iDim++) VelNormal += Vel[iDim] * UnitNormal[iDim]; for (iDim = 0; iDim < nDim; iDim++) VelTang[iDim] = Vel[iDim] - VelNormal*UnitNormal[iDim]; - + VelTangMod = 0.0; for (iDim = 0; iDim < nDim; iDim++) VelTangMod += VelTang[iDim]*VelTang[iDim]; VelTangMod = sqrt(VelTangMod); - + /*--- Compute normal distance of the interior point from the wall ---*/ - + for (iDim = 0; iDim < nDim; iDim++) WallDist[iDim] = (Coord[iDim] - Coord_Normal[iDim]); - + WallDistMod = 0.0; for (iDim = 0; iDim < nDim; iDim++) WallDistMod += WallDist[iDim]*WallDist[iDim]; WallDistMod = sqrt(WallDistMod); - + /*--- Compute mach number ---*/ - + // M_Normal = VelTangMod / sqrt(Gamma * Gas_Constant * T_Normal); - + /*--- Compute the wall temperature using the Crocco-Buseman equation ---*/ - + //T_Wall = T_Normal * (1.0 + 0.5*Gamma_Minus_One*Recovery*M_Normal*M_Normal); T_Wall = T_Normal + Recovery*pow(VelTangMod,2.0)/(2.0*Cp); - + /*--- Extrapolate the pressure from the interior & compute the wall density using the equation of state ---*/ - + P_Wall = P_Normal; Density_Wall = P_Wall/(Gas_Constant*T_Wall); - + /*--- Compute the shear stress at the wall in the regular fashion by using the stress tensor on the surface ---*/ - + Lam_Visc_Wall = solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); grad_primvar = solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint); - + div_vel = 0.0; for (iDim = 0; iDim < nDim; iDim++) div_vel += grad_primvar[iDim+1][iDim]; - + for (iDim = 0; iDim < nDim; iDim++) { for (jDim = 0 ; jDim < nDim; jDim++) { Delta = 0.0; if (iDim == jDim) Delta = 1.0; @@ -2868,50 +1972,50 @@ void CTurbSASolver::SetNuTilde_WF(CGeometry *geometry, CSolver **solver_containe for (jDim = 0; jDim < nDim; jDim++) TauElem[iDim] += tau[iDim][jDim]*UnitNormal[jDim]; } - + /*--- Compute wall shear stress as the magnitude of the wall-tangential component of the shear stress tensor---*/ - + TauNormal = 0.0; for (iDim = 0; iDim < nDim; iDim++) TauNormal += TauElem[iDim] * UnitNormal[iDim]; - + for (iDim = 0; iDim < nDim; iDim++) TauTangent[iDim] = TauElem[iDim] - TauNormal * UnitNormal[iDim]; - + WallShearStress = 0.0; for (iDim = 0; iDim < nDim; iDim++) WallShearStress += TauTangent[iDim]*TauTangent[iDim]; WallShearStress = sqrt(WallShearStress); - + /*--- Calculate the quantities from boundary layer theory and iteratively solve for a new wall shear stress. Use the current wall shear stress as a starting guess for the wall function. ---*/ - + Tau_Wall_Old = WallShearStress; counter = 0; diff = 1.0; - + while (diff > tol) { - + /*--- Friction velocity and u+ ---*/ - + U_Tau = sqrt(Tau_Wall_Old/Density_Wall); U_Plus = VelTangMod/U_Tau; - + /*--- Gamma, Beta, Q, and Phi, defined by Nichols & Nelson (2004) ---*/ - + Gam = Recovery*U_Tau*U_Tau/(2.0*Cp*T_Wall); Beta = 0.0; // For adiabatic flows only Q = sqrt(Beta*Beta + 4.0*Gam); Phi = asin(-1.0*Beta/Q); - + /*--- Y+ defined by White & Christoph (compressibility and heat transfer) ---*/ - + Y_Plus_White = exp((kappa/sqrt(Gam))*(asin((2.0*Gam*U_Plus - Beta)/Q) - Phi))*exp(-1.0*kappa*B); - + /*--- Spalding's universal form for the BL velocity with the outer velocity form of White & Christoph above. ---*/ - + Y_Plus = U_Plus + Y_Plus_White - (exp(-1.0*kappa*B)* (1.0 + kappa*U_Plus + kappa*kappa*U_Plus*U_Plus/2.0 + kappa*kappa*kappa*U_Plus*U_Plus*U_Plus/6.0)); @@ -2919,14 +2023,14 @@ void CTurbSASolver::SetNuTilde_WF(CGeometry *geometry, CSolver **solver_containe /*--- Calculate an updated value for the wall shear stress using the y+ value, the definition of y+, and the definition of the friction velocity. ---*/ - + Tau_Wall = (1.0/Density_Wall)*pow(Y_Plus*Lam_Visc_Wall/WallDistMod,2.0); - + /*--- Difference between the old and new Tau. Update old value. ---*/ - + diff = fabs(Tau_Wall-Tau_Wall_Old); Tau_Wall_Old += 0.25*(Tau_Wall-Tau_Wall_Old); - + counter++; if (counter > max_iter) { cout << "WARNING: Tau_Wall evaluation has not converged in solver_direct_turbulent" << endl; @@ -2934,9 +2038,9 @@ void CTurbSASolver::SetNuTilde_WF(CGeometry *geometry, CSolver **solver_containe } } - + /*--- Now compute the Eddy viscosity at the first point off of the wall ---*/ - + Lam_Visc_Normal = solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint_Neighbor); Density_Normal = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint_Neighbor); Kin_Visc_Normal = Lam_Visc_Normal/Density_Normal; @@ -2946,65 +2050,65 @@ void CTurbSASolver::SetNuTilde_WF(CGeometry *geometry, CSolver **solver_containe (1.0 + kappa*U_Plus + kappa*kappa*U_Plus*U_Plus/2.0) - Lam_Visc_Normal/Lam_Visc_Wall); - + /*--- Eddy viscosity should be always a positive number ---*/ - + Eddy_Visc = max(0.0, Eddy_Visc); - + /*--- Solve for the new value of nu_tilde given the eddy viscosity and using a Newton method ---*/ - + nu_til_old = 0.0; nu_til = 0.0; cv1_3 = 7.1*7.1*7.1; nu_til_old = nodes->GetSolution(iPoint,0); counter = 0; diff = 1.0; - + while (diff > tol) { - + func = nu_til_old*nu_til_old*nu_til_old*nu_til_old - (Eddy_Visc/Density_Normal)*(nu_til_old*nu_til_old*nu_til_old + Kin_Visc_Normal*Kin_Visc_Normal*Kin_Visc_Normal*cv1_3); func_prim = 4.0 * nu_til_old*nu_til_old*nu_til_old - 3.0*(Eddy_Visc/Density_Normal)*(nu_til_old*nu_til_old); nu_til = nu_til_old - func/func_prim; - + diff = fabs(nu_til-nu_til_old); nu_til_old = nu_til; - + counter++; if (counter > max_iter) { cout << "WARNING: Nu_tilde evaluation has not converged." << endl; break; } - + } - + for (iVar = 0; iVar < nVar; iVar++) Solution[iVar] = nu_til; - + nodes->SetSolution_Old(iPoint_Neighbor,Solution); LinSysRes.SetBlock_Zero(iPoint_Neighbor); - + /*--- includes 1 in the diagonal ---*/ - + Jacobian.DeleteValsRowi(iPoint_Neighbor); - + } - + } } } void CTurbSASolver::SetDES_LengthScale(CSolver **solver, CGeometry *geometry, CConfig *config){ - + unsigned short kindHybridRANSLES = config->GetKind_HybridRANSLES(); unsigned long iPoint = 0, jPoint = 0; unsigned short iDim = 0, jDim = 0, iNeigh = 0, nNeigh = 0; - + su2double constDES = config->GetConst_DES(); - + su2double density = 0.0, laminarViscosity = 0.0, kinematicViscosity = 0.0, eddyViscosity = 0.0, kinematicViscosityTurb = 0.0, wallDistance = 0.0, lengthScale = 0.0; - + su2double maxDelta = 0.0, deltaAux = 0.0, distDES = 0.0, uijuij = 0.0, k2 = 0.0, r_d = 0.0, f_d = 0.0, deltaDDES = 0.0, omega = 0.0, ln_max = 0.0, ln[3] = {0.0, 0.0, 0.0}, aux_ln = 0.0, f_kh = 0.0; - + su2double nu_hat, fw_star = 0.424, cv1_3 = pow(7.1, 3.0); k2 = pow(0.41, 2.0); su2double cb1 = 0.1355, ct3 = 1.2, ct4 = 0.5; su2double sigma = 2./3., cb2 = 0.622, f_max=1.0, f_min=0.1, a1=0.15, a2=0.3; @@ -3013,18 +2117,18 @@ void CTurbSASolver::SetDES_LengthScale(CSolver **solver, CGeometry *geometry, CC ratioOmega[3] = {0.0, 0.0, 0.0}, vortexTiltingMeasure = 0.0; for (iPoint = 0; iPoint < nPointDomain; iPoint++){ - + coord_i = geometry->node[iPoint]->GetCoord(); nNeigh = geometry->node[iPoint]->GetnPoint(); wallDistance = geometry->node[iPoint]->GetWall_Distance(); primVarGrad = solver[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint); - vorticity = solver[FLOW_SOL]->GetNodes()->GetVorticity(iPoint); + vorticity = solver[FLOW_SOL]->GetNodes()->GetVorticity(iPoint); density = solver[FLOW_SOL]->GetNodes()->GetDensity(iPoint); laminarViscosity = solver[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); eddyViscosity = solver[TURB_SOL]->GetNodes()->GetmuT(iPoint); kinematicViscosity = laminarViscosity/density; kinematicViscosityTurb = eddyViscosity/density; - + uijuij = 0.0; for(iDim = 0; iDim < nDim; iDim++){ for(jDim = 0; jDim < nDim; jDim++){ @@ -3033,9 +2137,9 @@ void CTurbSASolver::SetDES_LengthScale(CSolver **solver, CGeometry *geometry, CC } uijuij = sqrt(fabs(uijuij)); uijuij = max(uijuij,1e-10); - + /*--- Low Reynolds number correction term ---*/ - + nu_hat = nodes->GetSolution(iPoint,0); Ji = nu_hat/kinematicViscosity; Ji_2 = Ji * Ji; @@ -3044,44 +2148,44 @@ void CTurbSASolver::SetDES_LengthScale(CSolver **solver, CGeometry *geometry, CC fv2 = 1.0 - Ji/(1.0+Ji*fv1); ft2 = ct3*exp(-ct4*Ji_2); cw1 = cb1/k2+(1.0+cb2)/sigma; - + psi_2 = (1.0 - (cb1/(cw1*k2*fw_star))*(ft2 + (1.0 - ft2)*fv2))/(fv1 * max(1.0e-10,1.0-ft2)); psi_2 = min(100.0,psi_2); - + switch(kindHybridRANSLES){ case SA_DES: /*--- Original Detached Eddy Simulation (DES97) Spalart 1997 ---*/ - + maxDelta = geometry->node[iPoint]->GetMaxLength(); distDES = constDES * maxDelta; lengthScale = min(distDES,wallDistance); - + break; - + case SA_DDES: /*--- A New Version of Detached-eddy Simulation, Resistant to Ambiguous Grid Densities. Spalart et al. Theoretical and Computational Fluid Dynamics - 2006 ---*/ - + maxDelta = geometry->node[iPoint]->GetMaxLength(); - + r_d = (kinematicViscosityTurb+kinematicViscosity)/(uijuij*k2*pow(wallDistance, 2.0)); f_d = 1.0-tanh(pow(8.0*r_d,3.0)); - + distDES = constDES * maxDelta; lengthScale = wallDistance-f_d*max(0.0,(wallDistance-distDES)); - + break; case SA_ZDES: /*--- Recent improvements in the Zonal Detached Eddy Simulation (ZDES) formulation. Deck Theoretical and Computational Fluid Dynamics - 2012 ---*/ - + for (iNeigh = 0; iNeigh < nNeigh; iNeigh++){ jPoint = geometry->node[iPoint]->GetPoint(iNeigh); coord_j = geometry->node[jPoint]->GetCoord(); @@ -3091,55 +2195,55 @@ void CTurbSASolver::SetDES_LengthScale(CSolver **solver, CGeometry *geometry, CC } deltaDDES = geometry->node[iPoint]->GetMaxLength(); } - - omega = sqrt(vorticity[0]*vorticity[0] + + + omega = sqrt(vorticity[0]*vorticity[0] + vorticity[1]*vorticity[1] + vorticity[2]*vorticity[2]); - + for (iDim = 0; iDim < 3; iDim++){ ratioOmega[iDim] = vorticity[iDim]/omega; } - + maxDelta = sqrt(pow(ratioOmega[0],2.0)*delta[1]*delta[2] + pow(ratioOmega[1],2.0)*delta[0]*delta[2] + pow(ratioOmega[2],2.0)*delta[0]*delta[1]); - + r_d = (kinematicViscosityTurb+kinematicViscosity)/(uijuij*k2*pow(wallDistance, 2.0)); f_d = 1.0-tanh(pow(8.0*r_d,3.0)); - + if (f_d < 0.99){ maxDelta = deltaDDES; } - + distDES = constDES * maxDelta; lengthScale = wallDistance-f_d*max(0.0,(wallDistance-distDES)); - + break; - + case SA_EDDES: - + /*--- An Enhanced Version of DES with Rapid Transition from RANS to LES in Separated Flows. Shur et al. Flow Turbulence Combust - 2015 ---*/ - + vortexTiltingMeasure = nodes->GetVortex_Tilting(iPoint); - - omega = sqrt(vorticity[0]*vorticity[0] + + + omega = sqrt(vorticity[0]*vorticity[0] + vorticity[1]*vorticity[1] + vorticity[2]*vorticity[2]); - + for (iDim = 0; iDim < 3; iDim++){ ratioOmega[iDim] = vorticity[iDim]/omega; } - + ln_max = 0.0; deltaDDES = 0.0; for (iNeigh = 0;iNeigh < nNeigh; iNeigh++){ jPoint = geometry->node[iPoint]->GetPoint(iNeigh); coord_j = geometry->node[jPoint]->GetCoord(); for (iDim = 0; iDim < nDim; iDim++){ - delta[iDim] = fabs(coord_j[iDim] - coord_i[iDim]); + delta[iDim] = fabs(coord_j[iDim] - coord_i[iDim]); } deltaDDES = geometry->node[iPoint]->GetMaxLength(); ln[0] = delta[1]*ratioOmega[2] - delta[2]*ratioOmega[1]; @@ -3151,9 +2255,9 @@ void CTurbSASolver::SetDES_LengthScale(CSolver **solver, CGeometry *geometry, CC } vortexTiltingMeasure = (vortexTiltingMeasure/fabs(nNeigh + 1.0)); - + f_kh = max(f_min, min(f_max, f_min + ((f_max - f_min)/(a2 - a1)) * (vortexTiltingMeasure - a1))); - + r_d = (kinematicViscosityTurb+kinematicViscosity)/(uijuij*k2*pow(wallDistance, 2.0)); f_d = 1.0-tanh(pow(8.0*r_d,3.0)); @@ -3161,16 +2265,16 @@ void CTurbSASolver::SetDES_LengthScale(CSolver **solver, CGeometry *geometry, CC if (f_d < 0.999){ maxDelta = deltaDDES; } - + distDES = constDES * maxDelta; lengthScale=wallDistance-f_d*max(0.0,(wallDistance-distDES)); - + break; - + } - + nodes->SetDES_LengthScale(iPoint,lengthScale); - + } } @@ -3187,7 +2291,7 @@ su2double CTurbSASolver::GetInletAtVertex(su2double *val_inlet, unsigned short val_kind_marker, string val_marker, CGeometry *geometry, - CConfig *config) { + CConfig *config) const { /*--- Local variables ---*/ @@ -3205,7 +2309,7 @@ su2double CTurbSASolver::GetInletAtVertex(su2double *val_inlet, for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) == INLET_FLOW) && (config->GetMarker_All_TagBound(iMarker) == val_marker)) { - + for (iVertex = 0; iVertex < nVertex[iMarker]; iVertex++){ iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); @@ -3238,9 +2342,9 @@ su2double CTurbSASolver::GetInletAtVertex(su2double *val_inlet, /*--- If we don't find a match, then the child point is not on the current inlet boundary marker. Return zero area so this point does not contribute to the restriction operator and continue. ---*/ - + return Area; - + } void CTurbSASolver::SetUniformInlet(CConfig* config, unsigned short iMarker) { @@ -3248,1216 +2352,5 @@ void CTurbSASolver::SetUniformInlet(CConfig* config, unsigned short iMarker) { for(unsigned long iVertex=0; iVertex < nVertex[iMarker]; iVertex++){ Inlet_TurbVars[iMarker][iVertex][0] = nu_tilde_Inf; } - -} - -CTurbSSTSolver::CTurbSSTSolver(void) : CTurbSolver() { - - /*--- Array initialization ---*/ - constants = NULL; - Inlet_TurbVars = NULL; - -} - -CTurbSSTSolver::CTurbSSTSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh) - : CTurbSolver(geometry, config) { - unsigned short iVar, iDim, nLineLets; - unsigned long iPoint; - ifstream restart_file; - string text_line; - - bool multizone = config->GetMultizone_Problem(); - - /*--- Array initialization ---*/ - - constants = NULL; - - Gamma = config->GetGamma(); - Gamma_Minus_One = Gamma - 1.0; - - /*--- Dimension of the problem --> dependent on the turbulence model. ---*/ - - nVar = 2; - nPrimVar = 2; - nPoint = geometry->GetnPoint(); - nPointDomain = geometry->GetnPointDomain(); - - /*--- Initialize nVarGrad for deallocation ---*/ - - nVarGrad = nVar; - - /*--- Define geometry constants in the solver structure ---*/ - - nDim = geometry->GetnDim(); - - /*--- Single grid simulation ---*/ - - if (iMesh == MESH_0) { - - /*--- Define some auxiliary vector related with the residual ---*/ - - Residual = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = 0.0; - Residual_RMS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_RMS[iVar] = 0.0; - Residual_i = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_i[iVar] = 0.0; - Residual_j = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_j[iVar] = 0.0; - Residual_Max = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_Max[iVar] = 0.0; - - /*--- Define some structures for locating max residuals ---*/ - - Point_Max = new unsigned long[nVar]; - for (iVar = 0; iVar < nVar; iVar++) Point_Max[iVar] = 0; - Point_Max_Coord = new su2double*[nVar]; - for (iVar = 0; iVar < nVar; iVar++) { - Point_Max_Coord[iVar] = new su2double[nDim]; - for (iDim = 0; iDim < nDim; iDim++) Point_Max_Coord[iVar][iDim] = 0.0; - } - - /*--- Define some auxiliary vector related with the solution ---*/ - - Solution = new su2double[nVar]; - Solution_i = new su2double[nVar]; Solution_j = new su2double[nVar]; - - /*--- Define some auxiliary vector related with the geometry ---*/ - - Vector_i = new su2double[nDim]; Vector_j = new su2double[nDim]; - - /*--- Define some auxiliary vector related with the flow solution ---*/ - - FlowPrimVar_i = new su2double [nDim+9]; FlowPrimVar_j = new su2double [nDim+9]; - - /*--- Jacobians and vector structures for implicit computations ---*/ - - Jacobian_i = new su2double* [nVar]; - Jacobian_j = new su2double* [nVar]; - for (iVar = 0; iVar < nVar; iVar++) { - Jacobian_i[iVar] = new su2double [nVar]; - Jacobian_j[iVar] = new su2double [nVar]; - } - - /*--- Initialization of the structure of the whole Jacobian ---*/ - - if (rank == MASTER_NODE) cout << "Initialize Jacobian structure (SST model)." << endl; - Jacobian.Initialize(nPoint, nPointDomain, nVar, nVar, true, geometry, config); - - if (config->GetKind_Linear_Solver_Prec() == LINELET) { - nLineLets = Jacobian.BuildLineletPreconditioner(geometry, config); - if (rank == MASTER_NODE) cout << "Compute linelet structure. " << nLineLets << " elements in each line (average)." << endl; - } - - LinSysSol.Initialize(nPoint, nPointDomain, nVar, 0.0); - LinSysRes.Initialize(nPoint, nPointDomain, nVar, 0.0); - - /*--- Initialize the BGS residuals in multizone problems. ---*/ - if (multizone){ - Residual_BGS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_BGS[iVar] = 0.0; - Residual_Max_BGS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_Max_BGS[iVar] = 0.0; - - /*--- Define some structures for locating max residuals ---*/ - - Point_Max_BGS = new unsigned long[nVar]; for (iVar = 0; iVar < nVar; iVar++) Point_Max_BGS[iVar] = 0; - Point_Max_Coord_BGS = new su2double*[nVar]; - for (iVar = 0; iVar < nVar; iVar++) { - Point_Max_Coord_BGS[iVar] = new su2double[nDim]; - for (iDim = 0; iDim < nDim; iDim++) Point_Max_Coord_BGS[iVar][iDim] = 0.0; - } - } - - } - - /*--- Computation of gradients by least squares ---*/ - - if (config->GetLeastSquaresRequired()) { - /*--- S matrix := inv(R)*traspose(inv(R)) ---*/ - Smatrix = new su2double* [nDim]; - for (iDim = 0; iDim < nDim; iDim++) - Smatrix[iDim] = new su2double [nDim]; - /*--- c vector := transpose(WA)*(Wb) ---*/ - Cvector = new su2double* [nVar]; - for (iVar = 0; iVar < nVar; iVar++) - Cvector[iVar] = new su2double [nDim]; - } - - /*--- Initialize value for model constants ---*/ - constants = new su2double[10]; - constants[0] = 0.85; //sigma_k1 - constants[1] = 1.0; //sigma_k2 - constants[2] = 0.5; //sigma_om1 - constants[3] = 0.856; //sigma_om2 - constants[4] = 0.075; //beta_1 - constants[5] = 0.0828; //beta_2 - constants[6] = 0.09; //betaStar - constants[7] = 0.31; //a1 - constants[8] = constants[4]/constants[6] - constants[2]*0.41*0.41/sqrt(constants[6]); //alfa_1 - constants[9] = constants[5]/constants[6] - constants[3]*0.41*0.41/sqrt(constants[6]); //alfa_2 - - /*--- Initialize lower and upper limits---*/ - lowerlimit = new su2double[nVar]; - upperlimit = new su2double[nVar]; - - lowerlimit[0] = 1.0e-10; - upperlimit[0] = 1.0e10; - - lowerlimit[1] = 1.0e-4; - upperlimit[1] = 1.0e15; - - /*--- Far-field flow state quantities and initialization. ---*/ - su2double rhoInf, *VelInf, muLamInf, Intensity, viscRatio, muT_Inf; - - rhoInf = config->GetDensity_FreeStreamND(); - VelInf = config->GetVelocity_FreeStreamND(); - muLamInf = config->GetViscosity_FreeStreamND(); - Intensity = config->GetTurbulenceIntensity_FreeStream(); - viscRatio = config->GetTurb2LamViscRatio_FreeStream(); - - su2double VelMag = 0; - for (iDim = 0; iDim < nDim; iDim++) - VelMag += VelInf[iDim]*VelInf[iDim]; - VelMag = sqrt(VelMag); - - kine_Inf = 3.0/2.0*(VelMag*VelMag*Intensity*Intensity); - omega_Inf = rhoInf*kine_Inf/(muLamInf*viscRatio); - - /*--- Eddy viscosity, initialized without stress limiter at the infinity ---*/ - muT_Inf = rhoInf*kine_Inf/omega_Inf; - - /*--- Initialize the solution to the far-field state everywhere. ---*/ - - nodes = new CTurbSSTVariable(kine_Inf, omega_Inf, muT_Inf, nPoint, nDim, nVar, constants, config); - SetBaseClassPointerToNodes(); - - /*--- MPI solution ---*/ - - InitiateComms(geometry, config, SOLUTION_EDDY); - CompleteComms(geometry, config, SOLUTION_EDDY); - - /*--- Initializate quantities for SlidingMesh Interface ---*/ - - unsigned long iMarker; - - SlidingState = new su2double*** [nMarker]; - SlidingStateNodes = new int* [nMarker]; - - for (iMarker = 0; iMarker < nMarker; iMarker++){ - - SlidingState[iMarker] = NULL; - SlidingStateNodes[iMarker] = NULL; - - if (config->GetMarker_All_KindBC(iMarker) == FLUID_INTERFACE){ - - SlidingState[iMarker] = new su2double**[geometry->GetnVertex(iMarker)]; - SlidingStateNodes[iMarker] = new int [geometry->GetnVertex(iMarker)]; - - for (iPoint = 0; iPoint < geometry->GetnVertex(iMarker); iPoint++){ - SlidingState[iMarker][iPoint] = new su2double*[nPrimVar+1]; - - SlidingStateNodes[iMarker][iPoint] = 0; - for (iVar = 0; iVar < nPrimVar+1; iVar++) - SlidingState[iMarker][iPoint][iVar] = NULL; - } - - } - } - - /*-- Allocation of inlets has to happen in derived classes (not CTurbSolver), - due to arbitrary number of turbulence variables ---*/ - - Inlet_TurbVars = new su2double**[nMarker]; - for (unsigned long iMarker = 0; iMarker < nMarker; iMarker++) { - Inlet_TurbVars[iMarker] = new su2double*[nVertex[iMarker]]; - for(unsigned long iVertex=0; iVertex < nVertex[iMarker]; iVertex++){ - Inlet_TurbVars[iMarker][iVertex] = new su2double[nVar]; - Inlet_TurbVars[iMarker][iVertex][0] = kine_Inf; - Inlet_TurbVars[iMarker][iVertex][1] = omega_Inf; - } - } - - /*--- The turbulence models are always solved implicitly, so set the - implicit flag in case we have periodic BCs. ---*/ - - SetImplicitPeriodic(true); - - /* Store the initial CFL number for all grid points. */ - - const su2double CFL = config->GetCFL(MGLevel); - for (iPoint = 0; iPoint < nPoint; iPoint++) { - nodes->SetLocalCFL(iPoint, CFL); - } - Min_CFL_Local = CFL; - Max_CFL_Local = CFL; - Avg_CFL_Local = CFL; - - /*--- Add the solver name (max 8 characters) ---*/ - SolverName = "K-W SST"; - -} - -CTurbSSTSolver::~CTurbSSTSolver(void) { - - if (constants != NULL) delete [] constants; - - unsigned long iMarker, iVertex; - unsigned short iVar; - - if ( SlidingState != NULL ) { - for (iMarker = 0; iMarker < nMarker; iMarker++) { - if ( SlidingState[iMarker] != NULL ) { - for (iVertex = 0; iVertex < nVertex[iMarker]; iVertex++) - if ( SlidingState[iMarker][iVertex] != NULL ){ - for (iVar = 0; iVar < nPrimVar+1; iVar++) - delete [] SlidingState[iMarker][iVertex][iVar]; - delete [] SlidingState[iMarker][iVertex]; - } - delete [] SlidingState[iMarker]; - } - } - delete [] SlidingState; - } - - if ( SlidingStateNodes != NULL ){ - for (iMarker = 0; iMarker < nMarker; iMarker++){ - if (SlidingStateNodes[iMarker] != NULL) - delete [] SlidingStateNodes[iMarker]; - } - delete [] SlidingStateNodes; - } - -} - -void CTurbSSTSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output) { - - unsigned long iPoint; - - bool limiter_turb = (config->GetKind_SlopeLimit_Turb() != NO_LIMITER) && (config->GetInnerIter() <= config->GetLimiterIter()); - - - for (iPoint = 0; iPoint < nPoint; iPoint ++) { - - /*--- Initialize the residual vector ---*/ - - LinSysRes.SetBlock_Zero(iPoint); - - } - - /*--- Initialize the Jacobian matrices ---*/ - - Jacobian.SetValZero(); - - /*--- Upwind second order reconstruction and gradients ---*/ - - if (config->GetReconstructionGradientRequired()) { - if (config->GetKind_Gradient_Method_Recon() == GREEN_GAUSS) - SetSolution_Gradient_GG(geometry, config, true); - if (config->GetKind_Gradient_Method_Recon() == LEAST_SQUARES) - SetSolution_Gradient_LS(geometry, config, true); - if (config->GetKind_Gradient_Method_Recon() == WEIGHTED_LEAST_SQUARES) - SetSolution_Gradient_LS(geometry, config, true); - } - if (config->GetKind_Gradient_Method() == GREEN_GAUSS) SetSolution_Gradient_GG(geometry, config); - if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) SetSolution_Gradient_LS(geometry, config); - - if (limiter_turb) SetSolution_Limiter(geometry, config); - -} - -void CTurbSSTSolver::Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh) { - su2double rho = 0.0, mu = 0.0, dist, omega, kine, F2, muT, zeta; - su2double a1 = constants[7]; - unsigned long iPoint; - - /*--- Compute mean flow and turbulence gradients ---*/ - - if (config->GetKind_Gradient_Method() == GREEN_GAUSS) { - SetSolution_Gradient_GG(geometry, config); - } - if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) { - SetSolution_Gradient_LS(geometry, config); - } - - for (iPoint = 0; iPoint < nPoint; iPoint ++) { - - /*--- Compute blending functions and cross diffusion ---*/ - - rho = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); - mu = solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); - - dist = geometry->node[iPoint]->GetWall_Distance(); - - su2double *Vorticity = solver_container[FLOW_SOL]->GetNodes()->GetVorticity(iPoint); - su2double VorticityMag = sqrt(Vorticity[0]*Vorticity[0] + - Vorticity[1]*Vorticity[1] + - Vorticity[2]*Vorticity[2]); - - nodes->SetBlendingFunc(iPoint,mu, dist, rho); - - F2 = nodes->GetF2blending(iPoint); - - /*--- Compute the eddy viscosity ---*/ - - kine = nodes->GetSolution(iPoint,0); - omega = nodes->GetSolution(iPoint,1); - zeta = min(1.0/omega, a1/(VorticityMag*F2)); - muT = max(rho*kine*zeta,0.0); - nodes->SetmuT(iPoint,muT); - - } - -} - -void CTurbSSTSolver::Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CNumerics *second_numerics, CConfig *config, unsigned short iMesh) { - - unsigned long iPoint; - - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - - /*--- Conservative variables w/o reconstruction ---*/ - - numerics->SetPrimitive(solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint), NULL); - - /*--- Gradient of the primitive and conservative variables ---*/ - - numerics->SetPrimVarGradient(solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint), NULL); - - /*--- Turbulent variables w/o reconstruction, and its gradient ---*/ - - numerics->SetTurbVar(nodes->GetSolution(iPoint), NULL); - numerics->SetTurbVarGradient(nodes->GetGradient(iPoint), NULL); - - /*--- Set volume ---*/ - - numerics->SetVolume(geometry->node[iPoint]->GetVolume()); - - /*--- Set distance to the surface ---*/ - - numerics->SetDistance(geometry->node[iPoint]->GetWall_Distance(), 0.0); - - /*--- Menter's first blending function ---*/ - - numerics->SetF1blending(nodes->GetF1blending(iPoint),0.0); - - /*--- Menter's second blending function ---*/ - - numerics->SetF2blending(nodes->GetF2blending(iPoint),0.0); - - /*--- Set vorticity and strain rate magnitude ---*/ - - numerics->SetVorticity(solver_container[FLOW_SOL]->GetNodes()->GetVorticity(iPoint), NULL); - - numerics->SetStrainMag(solver_container[FLOW_SOL]->GetNodes()->GetStrainMag(iPoint), 0.0); - - /*--- Cross diffusion ---*/ - - numerics->SetCrossDiff(nodes->GetCrossDiff(iPoint),0.0); - - /*--- Compute the source term ---*/ - - numerics->ComputeResidual(Residual, Jacobian_i, NULL, config); - - /*--- Subtract residual and the Jacobian ---*/ - - LinSysRes.SubtractBlock(iPoint, Residual); - Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - - } - -} - -void CTurbSSTSolver::Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh) { - -} - -void CTurbSSTSolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - - unsigned long iPoint, jPoint, iVertex, total_index; - unsigned short iDim, iVar; - su2double distance, density = 0.0, laminar_viscosity = 0.0, beta_1; - - for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - - /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ - if (geometry->node[iPoint]->GetDomain()) { - - /*--- distance to closest neighbor ---*/ - jPoint = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); - distance = 0.0; - for (iDim = 0; iDim < nDim; iDim++) { - distance += (geometry->node[iPoint]->GetCoord(iDim) - geometry->node[jPoint]->GetCoord(iDim))* - (geometry->node[iPoint]->GetCoord(iDim) - geometry->node[jPoint]->GetCoord(iDim)); - } - distance = sqrt(distance); - - /*--- Set wall values ---*/ - - density = solver_container[FLOW_SOL]->GetNodes()->GetDensity(jPoint); - laminar_viscosity = solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(jPoint); - - beta_1 = constants[4]; - - Solution[0] = 0.0; - Solution[1] = 60.0*laminar_viscosity/(density*beta_1*distance*distance); - - /*--- Set the solution values and zero the residual ---*/ - nodes->SetSolution_Old(iPoint,Solution); - nodes->SetSolution(iPoint,Solution); - LinSysRes.SetBlock_Zero(iPoint); - - /*--- Change rows of the Jacobian (includes 1 in the diagonal) ---*/ - for (iVar = 0; iVar < nVar; iVar++) { - total_index = iPoint*nVar+iVar; - Jacobian.DeleteValsRowi(total_index); - } - - } - } - -} - -void CTurbSSTSolver::BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker) { - - unsigned long iPoint, jPoint, iVertex, total_index; - unsigned short iDim, iVar; - su2double distance, density = 0.0, laminar_viscosity = 0.0, beta_1; - - for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - - /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ - if (geometry->node[iPoint]->GetDomain()) { - - /*--- distance to closest neighbor ---*/ - jPoint = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); - distance = 0.0; - for (iDim = 0; iDim < nDim; iDim++) { - distance += (geometry->node[iPoint]->GetCoord(iDim) - geometry->node[jPoint]->GetCoord(iDim))* - (geometry->node[iPoint]->GetCoord(iDim) - geometry->node[jPoint]->GetCoord(iDim)); - } - distance = sqrt(distance); - - /*--- Set wall values ---*/ - - density = solver_container[FLOW_SOL]->GetNodes()->GetDensity(jPoint); - laminar_viscosity = solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(jPoint); - - beta_1 = constants[4]; - - Solution[0] = 0.0; - Solution[1] = 60.0*laminar_viscosity/(density*beta_1*distance*distance); - - /*--- Set the solution values and zero the residual ---*/ - nodes->SetSolution_Old(iPoint,Solution); - nodes->SetSolution(iPoint,Solution); - LinSysRes.SetBlock_Zero(iPoint); - - /*--- Change rows of the Jacobian (includes 1 in the diagonal) ---*/ - for (iVar = 0; iVar < nVar; iVar++) { - total_index = iPoint*nVar+iVar; - Jacobian.DeleteValsRowi(total_index); - } - - } - } - -} - -void CTurbSSTSolver::BC_Far_Field(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - - unsigned long iPoint, iVertex; - su2double *Normal, *V_infty, *V_domain; - unsigned short iVar, iDim; - - Normal = new su2double[nDim]; - - for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - - iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - - /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ - - if (geometry->node[iPoint]->GetDomain()) { - - /*--- Allocate the value at the infinity ---*/ - - V_infty = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); - - /*--- Retrieve solution at the farfield boundary node ---*/ - - V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); - - conv_numerics->SetPrimitive(V_domain, V_infty); - - /*--- Set turbulent variable at the wall, and at infinity ---*/ - - for (iVar = 0; iVar < nVar; iVar++) - Solution_i[iVar] = nodes->GetSolution(iPoint,iVar); - - Solution_j[0] = kine_Inf; - Solution_j[1] = omega_Inf; - - conv_numerics->SetTurbVar(Solution_i, Solution_j); - - /*--- Set Normal (it is necessary to change the sign) ---*/ - - geometry->vertex[val_marker][iVertex]->GetNormal(Normal); - for (iDim = 0; iDim < nDim; iDim++) - Normal[iDim] = -Normal[iDim]; - conv_numerics->SetNormal(Normal); - - /*--- Grid Movement ---*/ - - if (dynamic_grid) - conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); - - /*--- Compute residuals and Jacobians ---*/ - - conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - - /*--- Add residuals and Jacobians ---*/ - - LinSysRes.AddBlock(iPoint, Residual); - Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - - } - } - - delete [] Normal; - -} - -void CTurbSSTSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker) { - - unsigned short iVar, iDim; - unsigned long iVertex, iPoint; - su2double *V_inlet, *V_domain, *Normal; - - Normal = new su2double[nDim]; - - string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - - /*--- Loop over all the vertices on this boundary marker ---*/ - - for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - - iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - - /*--- Check if the node belongs to the domain (i.e., not a halo node) ---*/ - - if (geometry->node[iPoint]->GetDomain()) { - - /*--- Normal vector for this vertex (negate for outward convention) ---*/ - - geometry->vertex[val_marker][iVertex]->GetNormal(Normal); - for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; - - /*--- Allocate the value at the inlet ---*/ - - V_inlet = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); - - /*--- Retrieve solution at the farfield boundary node ---*/ - - V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); - - /*--- Set various quantities in the solver class ---*/ - - conv_numerics->SetPrimitive(V_domain, V_inlet); - - /*--- Set the turbulent variable states. Use free-stream SST - values for the turbulent state at the inflow. ---*/ - - for (iVar = 0; iVar < nVar; iVar++) - Solution_i[iVar] = nodes->GetSolution(iPoint,iVar); - - /*--- Load the inlet turbulence variables (uniform by default). ---*/ - - Solution_j[0] = Inlet_TurbVars[val_marker][iVertex][0]; - Solution_j[1] = Inlet_TurbVars[val_marker][iVertex][1]; - - conv_numerics->SetTurbVar(Solution_i, Solution_j); - - /*--- Set various other quantities in the solver class ---*/ - - conv_numerics->SetNormal(Normal); - - if (dynamic_grid) - conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), - geometry->node[iPoint]->GetGridVel()); - - /*--- Compute the residual using an upwind scheme ---*/ - - conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - LinSysRes.AddBlock(iPoint, Residual); - - /*--- Jacobian contribution for implicit integration ---*/ - - Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - - // /*--- Viscous contribution, commented out because serious convergence problems ---*/ - // - // visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[Point_Normal]->GetCoord()); - // visc_numerics->SetNormal(Normal); - // - // /*--- Conservative variables w/o reconstruction ---*/ - // - // visc_numerics->SetPrimitive(V_domain, V_inlet); - // - // /*--- Turbulent variables w/o reconstruction, and its gradients ---*/ - // - // visc_numerics->SetTurbVar(Solution_i, Solution_j); - // visc_numerics->SetTurbVarGradient(node[iPoint]->GetGradient(), node[iPoint]->GetGradient()); - // - // /*--- Menter's first blending function ---*/ - // - // visc_numerics->SetF1blending(node[iPoint]->GetF1blending(), node[iPoint]->GetF1blending()); - // - // /*--- Compute residual, and Jacobians ---*/ - // - // visc_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - // - // /*--- Subtract residual, and update Jacobians ---*/ - // - // LinSysRes.SubtractBlock(iPoint, Residual); - // Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - - } - - } - - /*--- Free locally allocated memory ---*/ - - delete [] Normal; - -} - -void CTurbSSTSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - - unsigned long iPoint, iVertex; - unsigned short iVar, iDim; - su2double *V_outlet, *V_domain, *Normal; - - Normal = new su2double[nDim]; - - /*--- Loop over all the vertices on this boundary marker ---*/ - - for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { - iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - - /*--- Check if the node belongs to the domain (i.e., not a halo node) ---*/ - - if (geometry->node[iPoint]->GetDomain()) { - - /*--- Allocate the value at the outlet ---*/ - - V_outlet = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); - - /*--- Retrieve solution at the farfield boundary node ---*/ - - V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); - - /*--- Set various quantities in the solver class ---*/ - - conv_numerics->SetPrimitive(V_domain, V_outlet); - - /*--- Set the turbulent variables. Here we use a Neumann BC such - that the turbulent variable is copied from the interior of the - domain to the outlet before computing the residual. - Solution_i --> TurbVar_internal, - Solution_j --> TurbVar_outlet ---*/ - - for (iVar = 0; iVar < nVar; iVar++) { - Solution_i[iVar] = nodes->GetSolution(iPoint,iVar); - Solution_j[iVar] = nodes->GetSolution(iPoint,iVar); - } - conv_numerics->SetTurbVar(Solution_i, Solution_j); - - /*--- Set Normal (negate for outward convention) ---*/ - - geometry->vertex[val_marker][iVertex]->GetNormal(Normal); - for (iDim = 0; iDim < nDim; iDim++) - Normal[iDim] = -Normal[iDim]; - conv_numerics->SetNormal(Normal); - - if (dynamic_grid) - conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), - geometry->node[iPoint]->GetGridVel()); - - /*--- Compute the residual using an upwind scheme ---*/ - - conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - LinSysRes.AddBlock(iPoint, Residual); - - /*--- Jacobian contribution for implicit integration ---*/ - - Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - -// /*--- Viscous contribution, commented out because serious convergence problems ---*/ -// -// visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[Point_Normal]->GetCoord()); -// visc_numerics->SetNormal(Normal); -// -// /*--- Conservative variables w/o reconstruction ---*/ -// -// visc_numerics->SetPrimitive(V_domain, V_outlet); -// -// /*--- Turbulent variables w/o reconstruction, and its gradients ---*/ -// -// visc_numerics->SetTurbVar(Solution_i, Solution_j); -// visc_numerics->SetTurbVarGradient(node[iPoint]->GetGradient(), node[iPoint]->GetGradient()); -// -// /*--- Menter's first blending function ---*/ -// -// visc_numerics->SetF1blending(node[iPoint]->GetF1blending(), node[iPoint]->GetF1blending()); -// -// /*--- Compute residual, and Jacobians ---*/ -// -// visc_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); -// -// /*--- Subtract residual, and update Jacobians ---*/ -// -// LinSysRes.SubtractBlock(iPoint, Residual); -// Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - - } - } - - /*--- Free locally allocated memory ---*/ - delete[] Normal; - -} - - -void CTurbSSTSolver::BC_Inlet_MixingPlane(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker) { - - unsigned short iVar, iSpan, iDim; - unsigned long oldVertex, iPoint, Point_Normal, iVertex; - su2double *V_inlet, *V_domain, *Normal; - su2double extAverageKine, extAverageOmega; - unsigned short nSpanWiseSections = config->GetnSpanWiseSections(); - - Normal = new su2double[nDim]; - - string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - - /*--- Loop over all the vertices on this boundary marker ---*/ - for (iSpan= 0; iSpan < nSpanWiseSections ; iSpan++){ - extAverageKine = solver_container[FLOW_SOL]->GetExtAverageKine(val_marker, iSpan); - extAverageOmega = solver_container[FLOW_SOL]->GetExtAverageOmega(val_marker, iSpan); - - - /*--- Loop over all the vertices on this boundary marker ---*/ - - for (iVertex = 0; iVertex < geometry->GetnVertexSpan(val_marker,iSpan); iVertex++) { - - /*--- find the node related to the vertex ---*/ - iPoint = geometry->turbovertex[val_marker][iSpan][iVertex]->GetNode(); - - /*--- using the other vertex information for retrieving some information ---*/ - oldVertex = geometry->turbovertex[val_marker][iSpan][iVertex]->GetOldVertex(); - - /*--- Index of the closest interior node ---*/ - Point_Normal = geometry->vertex[val_marker][oldVertex]->GetNormal_Neighbor(); - - /*--- Normal vector for this vertex (negate for outward convention) ---*/ - - geometry->vertex[val_marker][oldVertex]->GetNormal(Normal); - for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; - - /*--- Allocate the value at the inlet ---*/ - V_inlet = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, oldVertex); - - /*--- Retrieve solution at the farfield boundary node ---*/ - - V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); - - /*--- Set various quantities in the solver class ---*/ - - conv_numerics->SetPrimitive(V_domain, V_inlet); - - /*--- Set the turbulent variable states (prescribed for an inflow) ---*/ - - for (iVar = 0; iVar < nVar; iVar++) - Solution_i[iVar] = nodes->GetSolution(iPoint,iVar); - - Solution_j[0]= extAverageKine; - Solution_j[1]= extAverageOmega; - - conv_numerics->SetTurbVar(Solution_i, Solution_j); - - /*--- Set various other quantities in the solver class ---*/ - conv_numerics->SetNormal(Normal); - - if (dynamic_grid) - conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), - geometry->node[iPoint]->GetGridVel()); - - /*--- Compute the residual using an upwind scheme ---*/ - conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - LinSysRes.AddBlock(iPoint, Residual); - - /*--- Jacobian contribution for implicit integration ---*/ - Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - - /*--- Viscous contribution ---*/ - visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[Point_Normal]->GetCoord()); - visc_numerics->SetNormal(Normal); - - /*--- Conservative variables w/o reconstruction ---*/ - visc_numerics->SetPrimitive(V_domain, V_inlet); - - /*--- Turbulent variables w/o reconstruction, and its gradients ---*/ - visc_numerics->SetTurbVar(Solution_i, Solution_j); - visc_numerics->SetTurbVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(iPoint)); - - /*--- Menter's first blending function ---*/ - visc_numerics->SetF1blending(nodes->GetF1blending(iPoint), nodes->GetF1blending(iPoint)); - - /*--- Compute residual, and Jacobians ---*/ - visc_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - - /*--- Subtract residual, and update Jacobians ---*/ - LinSysRes.SubtractBlock(iPoint, Residual); - Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - - } - } - - /*--- Free locally allocated memory ---*/ - delete[] Normal; - -} - -void CTurbSSTSolver::BC_Inlet_Turbo(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker) { - - unsigned short iVar, iSpan, iDim; - unsigned long oldVertex, iPoint, Point_Normal, iVertex; - su2double *V_inlet, *V_domain, *Normal; - unsigned short nSpanWiseSections = config->GetnSpanWiseSections(); - - /*--- Quantities for computing the kine and omega to impose at the inlet boundary. ---*/ - su2double rho, pressure, *Vel, VelMag, muLam, Intensity, viscRatio, kine_b, omega_b, kine; - CFluidModel *FluidModel; - - FluidModel = solver_container[FLOW_SOL]->GetFluidModel(); - Intensity = config->GetTurbulenceIntensity_FreeStream(); - viscRatio = config->GetTurb2LamViscRatio_FreeStream(); - - Normal = new su2double[nDim]; - Vel = new su2double[nDim]; - - string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - - - for (iSpan= 0; iSpan < nSpanWiseSections ; iSpan++){ - - /*--- Compute the inflow kine and omega using the span wise averge quntities---*/ - for (iDim = 0; iDim < nDim; iDim++) - Vel[iDim] = solver_container[FLOW_SOL]->GetAverageTurboVelocity(val_marker, iSpan)[iDim]; - - rho = solver_container[FLOW_SOL]->GetAverageDensity(val_marker, iSpan); - pressure = solver_container[FLOW_SOL]->GetAveragePressure(val_marker, iSpan); - kine = solver_container[FLOW_SOL]->GetAverageKine(val_marker, iSpan); - - FluidModel->SetTDState_Prho(pressure, rho); - muLam = FluidModel->GetLaminarViscosity(); - - VelMag = 0; - for (iDim = 0; iDim < nDim; iDim++) - VelMag += Vel[iDim]*Vel[iDim]; - VelMag = sqrt(VelMag); - - kine_b = 3.0/2.0*(VelMag*VelMag*Intensity*Intensity); - omega_b = rho*kine/(muLam*viscRatio); - - /*--- Loop over all the vertices on this boundary marker ---*/ - for (iVertex = 0; iVertex < geometry->GetnVertexSpan(val_marker,iSpan); iVertex++) { - - /*--- find the node related to the vertex ---*/ - iPoint = geometry->turbovertex[val_marker][iSpan][iVertex]->GetNode(); - - /*--- using the other vertex information for retrieving some information ---*/ - oldVertex = geometry->turbovertex[val_marker][iSpan][iVertex]->GetOldVertex(); - - /*--- Index of the closest interior node ---*/ - Point_Normal = geometry->vertex[val_marker][oldVertex]->GetNormal_Neighbor(); - - /*--- Normal vector for this vertex (negate for outward convention) ---*/ - - geometry->vertex[val_marker][oldVertex]->GetNormal(Normal); - for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; - - /*--- Allocate the value at the inlet ---*/ - V_inlet = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, oldVertex); - - /*--- Retrieve solution at the farfield boundary node ---*/ - - V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); - - /*--- Set various quantities in the solver class ---*/ - - conv_numerics->SetPrimitive(V_domain, V_inlet); - - for (iVar = 0; iVar < nVar; iVar++) - Solution_i[iVar] = nodes->GetSolution(iPoint,iVar); - - /*--- Set the turbulent variable states. Use average span-wise values - values for the turbulent state at the inflow. ---*/ - - Solution_j[0]= kine_b; - Solution_j[1]= omega_b; - - conv_numerics->SetTurbVar(Solution_i, Solution_j); - - /*--- Set various other quantities in the solver class ---*/ - conv_numerics->SetNormal(Normal); - - if (dynamic_grid) - conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), - geometry->node[iPoint]->GetGridVel()); - - /*--- Compute the residual using an upwind scheme ---*/ - conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - LinSysRes.AddBlock(iPoint, Residual); - - /*--- Jacobian contribution for implicit integration ---*/ - Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - - /*--- Viscous contribution ---*/ - visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[Point_Normal]->GetCoord()); - visc_numerics->SetNormal(Normal); - - /*--- Conservative variables w/o reconstruction ---*/ - visc_numerics->SetPrimitive(V_domain, V_inlet); - - /*--- Turbulent variables w/o reconstruction, and its gradients ---*/ - visc_numerics->SetTurbVar(Solution_i, Solution_j); - visc_numerics->SetTurbVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(iPoint)); - - /*--- Menter's first blending function ---*/ - visc_numerics->SetF1blending(nodes->GetF1blending(iPoint), nodes->GetF1blending(iPoint)); - - /*--- Compute residual, and Jacobians ---*/ - visc_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - - /*--- Subtract residual, and update Jacobians ---*/ - LinSysRes.SubtractBlock(iPoint, Residual); - Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - - } - } - - /*--- Free locally allocated memory ---*/ - delete[] Normal; - delete[] Vel; - -} - - -void CTurbSSTSolver::BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, - CNumerics *visc_numerics, CConfig *config){ - - unsigned long iVertex, jVertex, iPoint, Point_Normal = 0; - unsigned short iDim, iVar, iMarker; - - unsigned short nPrimVar = solver_container[FLOW_SOL]->GetnPrimVar(); - su2double *Normal = new su2double[nDim]; - su2double *PrimVar_i = new su2double[nPrimVar]; - su2double *PrimVar_j = new su2double[nPrimVar]; - su2double *tmp_residual = new su2double[nVar]; - - unsigned long nDonorVertex; - su2double weight; - - for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { - - if (config->GetMarker_All_KindBC(iMarker) == FLUID_INTERFACE) { - - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - - iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - Point_Normal = geometry->vertex[iMarker][iVertex]->GetNormal_Neighbor(); - - if (geometry->node[iPoint]->GetDomain()) { - - nDonorVertex = GetnSlidingStates(iMarker, iVertex); - - /*--- Initialize Residual, this will serve to accumulate the average ---*/ - - for (iVar = 0; iVar < nVar; iVar++) - Residual[iVar] = 0.0; - - /*--- Loop over the nDonorVertexes and compute the averaged flux ---*/ - - for (jVertex = 0; jVertex < nDonorVertex; jVertex++){ - - geometry->vertex[iMarker][iVertex]->GetNormal(Normal); - for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; - - for (iVar = 0; iVar < nPrimVar; iVar++) { - PrimVar_i[iVar] = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint,iVar); - PrimVar_j[iVar] = solver_container[FLOW_SOL]->GetSlidingState(iMarker, iVertex, iVar, jVertex); - } - - /*--- Get the weight computed in the interpolator class for the j-th donor vertex ---*/ - - weight = solver_container[FLOW_SOL]->GetSlidingState(iMarker, iVertex, nPrimVar, jVertex); - - /*--- Set primitive variables ---*/ - - conv_numerics->SetPrimitive( PrimVar_i, PrimVar_j ); - - /*--- Set the turbulent variable states ---*/ - Solution_i[0] = nodes->GetSolution(iPoint,0); - Solution_i[1] = nodes->GetSolution(iPoint,1); - - Solution_j[0] = GetSlidingState(iMarker, iVertex, 0, jVertex); - Solution_j[1] = GetSlidingState(iMarker, iVertex, 1, jVertex); - - conv_numerics->SetTurbVar(Solution_i, Solution_j); - - /*--- Set the normal vector ---*/ - - conv_numerics->SetNormal(Normal); - - if (dynamic_grid) - conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); - - conv_numerics->ComputeResidual(tmp_residual, Jacobian_i, Jacobian_j, config); - - /*--- Accumulate the residuals to compute the average ---*/ - - for (iVar = 0; iVar < nVar; iVar++) - Residual[iVar] += weight*tmp_residual[iVar]; - } - - /*--- Add Residuals and Jacobians ---*/ - - LinSysRes.AddBlock(iPoint, Residual); - - Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); - - /*--- Set the normal vector and the coordinates ---*/ - - visc_numerics->SetNormal(Normal); - visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[Point_Normal]->GetCoord()); - - /*--- Primitive variables, and gradient ---*/ - - visc_numerics->SetPrimitive(PrimVar_i, PrimVar_j); - // visc_numerics->SetPrimVarGradient(node[iPoint]->GetGradient_Primitive(), node[iPoint]->GetGradient_Primitive()); - - /*--- Turbulent variables and its gradients ---*/ - - visc_numerics->SetTurbVar(Solution_i, Solution_j); - visc_numerics->SetTurbVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(iPoint)); - - /*--- Compute and update residual ---*/ - - visc_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); - - LinSysRes.SubtractBlock(iPoint, Residual); - - /*--- Jacobian contribution for implicit integration ---*/ - - Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); - - } - } - } - } - - /*--- Free locally allocated memory ---*/ - - delete [] tmp_residual; - delete [] Normal; - delete [] PrimVar_i; - delete [] PrimVar_j; - -} - -su2double* CTurbSSTSolver::GetConstants() { - return constants; -} - -void CTurbSSTSolver::SetInletAtVertex(su2double *val_inlet, - unsigned short iMarker, - unsigned long iVertex) { - - Inlet_TurbVars[iMarker][iVertex][0] = val_inlet[nDim+2+nDim]; - Inlet_TurbVars[iMarker][iVertex][1] = val_inlet[nDim+2+nDim+1]; - -} - -su2double CTurbSSTSolver::GetInletAtVertex(su2double *val_inlet, - unsigned long val_inlet_point, - unsigned short val_kind_marker, - string val_marker, - CGeometry *geometry, - CConfig *config) { - - /*--- Local variables ---*/ - - unsigned short iMarker, iDim; - unsigned long iPoint, iVertex; - su2double Area = 0.0; - su2double Normal[3] = {0.0,0.0,0.0}; - - /*--- Alias positions within inlet file for readability ---*/ - - if (val_kind_marker == INLET_FLOW) { - - unsigned short tke_position = nDim+2+nDim; - unsigned short omega_position = nDim+2+nDim+1; - - for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { - if ((config->GetMarker_All_KindBC(iMarker) == INLET_FLOW) && - (config->GetMarker_All_TagBound(iMarker) == val_marker)) { - - for (iVertex = 0; iVertex < nVertex[iMarker]; iVertex++){ - - iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - - if (iPoint == val_inlet_point) { - - /*-- Compute boundary face area for this vertex. ---*/ - - geometry->vertex[iMarker][iVertex]->GetNormal(Normal); - Area = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - Area += Normal[iDim]*Normal[iDim]; - Area = sqrt(Area); - - /*--- Access and store the inlet variables for this vertex. ---*/ - - val_inlet[tke_position] = Inlet_TurbVars[iMarker][iVertex][0]; - val_inlet[omega_position] = Inlet_TurbVars[iMarker][iVertex][1]; - - /*--- Exit once we find the point. ---*/ - - return Area; - - } - } - } - } - - } - - /*--- If we don't find a match, then the child point is not on the - current inlet boundary marker. Return zero area so this point does - not contribute to the restriction operator and continue. ---*/ - - return Area; - -} - -void CTurbSSTSolver::SetUniformInlet(CConfig* config, unsigned short iMarker) { - - for(unsigned long iVertex=0; iVertex < nVertex[iMarker]; iVertex++){ - Inlet_TurbVars[iMarker][iVertex][0] = kine_Inf; - Inlet_TurbVars[iMarker][iVertex][1] = omega_Inf; - } } diff --git a/SU2_CFD/src/solvers/CTurbSSTSolver.cpp b/SU2_CFD/src/solvers/CTurbSSTSolver.cpp new file mode 100644 index 000000000000..c30873da000a --- /dev/null +++ b/SU2_CFD/src/solvers/CTurbSSTSolver.cpp @@ -0,0 +1,1237 @@ +/*! + * \file CTurbSSTSolver.cpp + * \brief Main subrotuines of CTurbSSTSolver class + * \author F. Palacios, A. Bueno + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + + +#include "../../include/solvers/CTurbSSTSolver.hpp" +#include "../../include/variables/CTurbSSTVariable.hpp" + +CTurbSSTSolver::CTurbSSTSolver(void) : CTurbSolver() { + + /*--- Array initialization ---*/ + constants = NULL; + Inlet_TurbVars = NULL; + +} + +CTurbSSTSolver::CTurbSSTSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh) + : CTurbSolver(geometry, config) { + unsigned short iVar, iDim, nLineLets; + unsigned long iPoint; + ifstream restart_file; + string text_line; + + bool multizone = config->GetMultizone_Problem(); + + /*--- Array initialization ---*/ + + constants = NULL; + + Gamma = config->GetGamma(); + Gamma_Minus_One = Gamma - 1.0; + + /*--- Dimension of the problem --> dependent on the turbulence model. ---*/ + + nVar = 2; + nPrimVar = 2; + nPoint = geometry->GetnPoint(); + nPointDomain = geometry->GetnPointDomain(); + + /*--- Initialize nVarGrad for deallocation ---*/ + + nVarGrad = nVar; + + /*--- Define geometry constants in the solver structure ---*/ + + nDim = geometry->GetnDim(); + + /*--- Single grid simulation ---*/ + + if (iMesh == MESH_0) { + + /*--- Define some auxiliary vector related with the residual ---*/ + + Residual = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = 0.0; + Residual_RMS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_RMS[iVar] = 0.0; + Residual_i = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_i[iVar] = 0.0; + Residual_j = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_j[iVar] = 0.0; + Residual_Max = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_Max[iVar] = 0.0; + + /*--- Define some structures for locating max residuals ---*/ + + Point_Max = new unsigned long[nVar]; + for (iVar = 0; iVar < nVar; iVar++) Point_Max[iVar] = 0; + Point_Max_Coord = new su2double*[nVar]; + for (iVar = 0; iVar < nVar; iVar++) { + Point_Max_Coord[iVar] = new su2double[nDim]; + for (iDim = 0; iDim < nDim; iDim++) Point_Max_Coord[iVar][iDim] = 0.0; + } + + /*--- Define some auxiliary vector related with the solution ---*/ + + Solution = new su2double[nVar]; + Solution_i = new su2double[nVar]; Solution_j = new su2double[nVar]; + + /*--- Define some auxiliary vector related with the geometry ---*/ + + Vector_i = new su2double[nDim]; Vector_j = new su2double[nDim]; + + /*--- Define some auxiliary vector related with the flow solution ---*/ + + FlowPrimVar_i = new su2double [nDim+9]; FlowPrimVar_j = new su2double [nDim+9]; + + /*--- Jacobians and vector structures for implicit computations ---*/ + + Jacobian_i = new su2double* [nVar]; + Jacobian_j = new su2double* [nVar]; + for (iVar = 0; iVar < nVar; iVar++) { + Jacobian_i[iVar] = new su2double [nVar]; + Jacobian_j[iVar] = new su2double [nVar]; + } + + /*--- Initialization of the structure of the whole Jacobian ---*/ + + if (rank == MASTER_NODE) cout << "Initialize Jacobian structure (SST model)." << endl; + Jacobian.Initialize(nPoint, nPointDomain, nVar, nVar, true, geometry, config); + + if (config->GetKind_Linear_Solver_Prec() == LINELET) { + nLineLets = Jacobian.BuildLineletPreconditioner(geometry, config); + if (rank == MASTER_NODE) cout << "Compute linelet structure. " << nLineLets << " elements in each line (average)." << endl; + } + + LinSysSol.Initialize(nPoint, nPointDomain, nVar, 0.0); + LinSysRes.Initialize(nPoint, nPointDomain, nVar, 0.0); + + /*--- Initialize the BGS residuals in multizone problems. ---*/ + if (multizone){ + Residual_BGS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_BGS[iVar] = 0.0; + Residual_Max_BGS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_Max_BGS[iVar] = 0.0; + + /*--- Define some structures for locating max residuals ---*/ + + Point_Max_BGS = new unsigned long[nVar]; for (iVar = 0; iVar < nVar; iVar++) Point_Max_BGS[iVar] = 0; + Point_Max_Coord_BGS = new su2double*[nVar]; + for (iVar = 0; iVar < nVar; iVar++) { + Point_Max_Coord_BGS[iVar] = new su2double[nDim]; + for (iDim = 0; iDim < nDim; iDim++) Point_Max_Coord_BGS[iVar][iDim] = 0.0; + } + } + + } + + /*--- Computation of gradients by least squares ---*/ + + if (config->GetLeastSquaresRequired()) { + /*--- S matrix := inv(R)*traspose(inv(R)) ---*/ + Smatrix = new su2double* [nDim]; + for (iDim = 0; iDim < nDim; iDim++) + Smatrix[iDim] = new su2double [nDim]; + /*--- c vector := transpose(WA)*(Wb) ---*/ + Cvector = new su2double* [nVar]; + for (iVar = 0; iVar < nVar; iVar++) + Cvector[iVar] = new su2double [nDim]; + } + + /*--- Initialize value for model constants ---*/ + constants = new su2double[10]; + constants[0] = 0.85; //sigma_k1 + constants[1] = 1.0; //sigma_k2 + constants[2] = 0.5; //sigma_om1 + constants[3] = 0.856; //sigma_om2 + constants[4] = 0.075; //beta_1 + constants[5] = 0.0828; //beta_2 + constants[6] = 0.09; //betaStar + constants[7] = 0.31; //a1 + constants[8] = constants[4]/constants[6] - constants[2]*0.41*0.41/sqrt(constants[6]); //alfa_1 + constants[9] = constants[5]/constants[6] - constants[3]*0.41*0.41/sqrt(constants[6]); //alfa_2 + + /*--- Initialize lower and upper limits---*/ + lowerlimit = new su2double[nVar]; + upperlimit = new su2double[nVar]; + + lowerlimit[0] = 1.0e-10; + upperlimit[0] = 1.0e10; + + lowerlimit[1] = 1.0e-4; + upperlimit[1] = 1.0e15; + + /*--- Far-field flow state quantities and initialization. ---*/ + su2double rhoInf, *VelInf, muLamInf, Intensity, viscRatio, muT_Inf; + + rhoInf = config->GetDensity_FreeStreamND(); + VelInf = config->GetVelocity_FreeStreamND(); + muLamInf = config->GetViscosity_FreeStreamND(); + Intensity = config->GetTurbulenceIntensity_FreeStream(); + viscRatio = config->GetTurb2LamViscRatio_FreeStream(); + + su2double VelMag = 0; + for (iDim = 0; iDim < nDim; iDim++) + VelMag += VelInf[iDim]*VelInf[iDim]; + VelMag = sqrt(VelMag); + + kine_Inf = 3.0/2.0*(VelMag*VelMag*Intensity*Intensity); + omega_Inf = rhoInf*kine_Inf/(muLamInf*viscRatio); + + /*--- Eddy viscosity, initialized without stress limiter at the infinity ---*/ + muT_Inf = rhoInf*kine_Inf/omega_Inf; + + /*--- Initialize the solution to the far-field state everywhere. ---*/ + + nodes = new CTurbSSTVariable(kine_Inf, omega_Inf, muT_Inf, nPoint, nDim, nVar, constants, config); + SetBaseClassPointerToNodes(); + + /*--- MPI solution ---*/ + + InitiateComms(geometry, config, SOLUTION_EDDY); + CompleteComms(geometry, config, SOLUTION_EDDY); + + /*--- Initializate quantities for SlidingMesh Interface ---*/ + + unsigned long iMarker; + + SlidingState = new su2double*** [nMarker]; + SlidingStateNodes = new int* [nMarker]; + + for (iMarker = 0; iMarker < nMarker; iMarker++){ + + SlidingState[iMarker] = NULL; + SlidingStateNodes[iMarker] = NULL; + + if (config->GetMarker_All_KindBC(iMarker) == FLUID_INTERFACE){ + + SlidingState[iMarker] = new su2double**[geometry->GetnVertex(iMarker)]; + SlidingStateNodes[iMarker] = new int [geometry->GetnVertex(iMarker)]; + + for (iPoint = 0; iPoint < geometry->GetnVertex(iMarker); iPoint++){ + SlidingState[iMarker][iPoint] = new su2double*[nPrimVar+1]; + + SlidingStateNodes[iMarker][iPoint] = 0; + for (iVar = 0; iVar < nPrimVar+1; iVar++) + SlidingState[iMarker][iPoint][iVar] = NULL; + } + + } + } + + /*-- Allocation of inlets has to happen in derived classes (not CTurbSolver), + due to arbitrary number of turbulence variables ---*/ + + Inlet_TurbVars = new su2double**[nMarker]; + for (unsigned long iMarker = 0; iMarker < nMarker; iMarker++) { + Inlet_TurbVars[iMarker] = new su2double*[nVertex[iMarker]]; + for(unsigned long iVertex=0; iVertex < nVertex[iMarker]; iVertex++){ + Inlet_TurbVars[iMarker][iVertex] = new su2double[nVar]; + Inlet_TurbVars[iMarker][iVertex][0] = kine_Inf; + Inlet_TurbVars[iMarker][iVertex][1] = omega_Inf; + } + } + + /*--- The turbulence models are always solved implicitly, so set the + implicit flag in case we have periodic BCs. ---*/ + + SetImplicitPeriodic(true); + + /* Store the initial CFL number for all grid points. */ + + const su2double CFL = config->GetCFL(MGLevel); + for (iPoint = 0; iPoint < nPoint; iPoint++) { + nodes->SetLocalCFL(iPoint, CFL); + } + Min_CFL_Local = CFL; + Max_CFL_Local = CFL; + Avg_CFL_Local = CFL; + + /*--- Add the solver name (max 8 characters) ---*/ + SolverName = "K-W SST"; + +} + +CTurbSSTSolver::~CTurbSSTSolver(void) { + + if (constants != NULL) delete [] constants; + + unsigned long iMarker, iVertex; + unsigned short iVar; + + if ( SlidingState != NULL ) { + for (iMarker = 0; iMarker < nMarker; iMarker++) { + if ( SlidingState[iMarker] != NULL ) { + for (iVertex = 0; iVertex < nVertex[iMarker]; iVertex++) + if ( SlidingState[iMarker][iVertex] != NULL ){ + for (iVar = 0; iVar < nPrimVar+1; iVar++) + delete [] SlidingState[iMarker][iVertex][iVar]; + delete [] SlidingState[iMarker][iVertex]; + } + delete [] SlidingState[iMarker]; + } + } + delete [] SlidingState; + } + + if ( SlidingStateNodes != NULL ){ + for (iMarker = 0; iMarker < nMarker; iMarker++){ + if (SlidingStateNodes[iMarker] != NULL) + delete [] SlidingStateNodes[iMarker]; + } + delete [] SlidingStateNodes; + } + +} + +void CTurbSSTSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output) { + + unsigned long iPoint; + + bool limiter_turb = (config->GetKind_SlopeLimit_Turb() != NO_LIMITER) && (config->GetInnerIter() <= config->GetLimiterIter()); + + + for (iPoint = 0; iPoint < nPoint; iPoint ++) { + + /*--- Initialize the residual vector ---*/ + + LinSysRes.SetBlock_Zero(iPoint); + + } + + /*--- Initialize the Jacobian matrices ---*/ + + Jacobian.SetValZero(); + + /*--- Upwind second order reconstruction and gradients ---*/ + + if (config->GetReconstructionGradientRequired()) { + if (config->GetKind_Gradient_Method_Recon() == GREEN_GAUSS) + SetSolution_Gradient_GG(geometry, config, true); + if (config->GetKind_Gradient_Method_Recon() == LEAST_SQUARES) + SetSolution_Gradient_LS(geometry, config, true); + if (config->GetKind_Gradient_Method_Recon() == WEIGHTED_LEAST_SQUARES) + SetSolution_Gradient_LS(geometry, config, true); + } + if (config->GetKind_Gradient_Method() == GREEN_GAUSS) SetSolution_Gradient_GG(geometry, config); + if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) SetSolution_Gradient_LS(geometry, config); + + if (limiter_turb) SetSolution_Limiter(geometry, config); + +} + +void CTurbSSTSolver::Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh) { + su2double rho = 0.0, mu = 0.0, dist, omega, kine, F2, muT, zeta; + su2double a1 = constants[7]; + unsigned long iPoint; + + /*--- Compute mean flow and turbulence gradients ---*/ + + if (config->GetKind_Gradient_Method() == GREEN_GAUSS) { + SetSolution_Gradient_GG(geometry, config); + } + if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) { + SetSolution_Gradient_LS(geometry, config); + } + + for (iPoint = 0; iPoint < nPoint; iPoint ++) { + + /*--- Compute blending functions and cross diffusion ---*/ + + rho = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + mu = solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); + + dist = geometry->node[iPoint]->GetWall_Distance(); + + su2double *Vorticity = solver_container[FLOW_SOL]->GetNodes()->GetVorticity(iPoint); + su2double VorticityMag = sqrt(Vorticity[0]*Vorticity[0] + + Vorticity[1]*Vorticity[1] + + Vorticity[2]*Vorticity[2]); + + nodes->SetBlendingFunc(iPoint,mu, dist, rho); + + F2 = nodes->GetF2blending(iPoint); + + /*--- Compute the eddy viscosity ---*/ + + kine = nodes->GetSolution(iPoint,0); + omega = nodes->GetSolution(iPoint,1); + zeta = min(1.0/omega, a1/(VorticityMag*F2)); + muT = max(rho*kine*zeta,0.0); + nodes->SetmuT(iPoint,muT); + + } + +} + +void CTurbSSTSolver::Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CNumerics *second_numerics, CConfig *config, unsigned short iMesh) { + + unsigned long iPoint; + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + /*--- Conservative variables w/o reconstruction ---*/ + + numerics->SetPrimitive(solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint), NULL); + + /*--- Gradient of the primitive and conservative variables ---*/ + + numerics->SetPrimVarGradient(solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint), NULL); + + /*--- Turbulent variables w/o reconstruction, and its gradient ---*/ + + numerics->SetTurbVar(nodes->GetSolution(iPoint), NULL); + numerics->SetTurbVarGradient(nodes->GetGradient(iPoint), NULL); + + /*--- Set volume ---*/ + + numerics->SetVolume(geometry->node[iPoint]->GetVolume()); + + /*--- Set distance to the surface ---*/ + + numerics->SetDistance(geometry->node[iPoint]->GetWall_Distance(), 0.0); + + /*--- Menter's first blending function ---*/ + + numerics->SetF1blending(nodes->GetF1blending(iPoint),0.0); + + /*--- Menter's second blending function ---*/ + + numerics->SetF2blending(nodes->GetF2blending(iPoint),0.0); + + /*--- Set vorticity and strain rate magnitude ---*/ + + numerics->SetVorticity(solver_container[FLOW_SOL]->GetNodes()->GetVorticity(iPoint), NULL); + + numerics->SetStrainMag(solver_container[FLOW_SOL]->GetNodes()->GetStrainMag(iPoint), 0.0); + + /*--- Cross diffusion ---*/ + + numerics->SetCrossDiff(nodes->GetCrossDiff(iPoint),0.0); + + /*--- Compute the source term ---*/ + + numerics->ComputeResidual(Residual, Jacobian_i, NULL, config); + + /*--- Subtract residual and the Jacobian ---*/ + + LinSysRes.SubtractBlock(iPoint, Residual); + Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); + + } + +} + +void CTurbSSTSolver::Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, + CConfig *config, unsigned short iMesh) { + +} + +void CTurbSSTSolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { + + unsigned long iPoint, jPoint, iVertex, total_index; + unsigned short iDim, iVar; + su2double distance, density = 0.0, laminar_viscosity = 0.0, beta_1; + + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); + + /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ + if (geometry->node[iPoint]->GetDomain()) { + + /*--- distance to closest neighbor ---*/ + jPoint = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); + distance = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + distance += (geometry->node[iPoint]->GetCoord(iDim) - geometry->node[jPoint]->GetCoord(iDim))* + (geometry->node[iPoint]->GetCoord(iDim) - geometry->node[jPoint]->GetCoord(iDim)); + } + distance = sqrt(distance); + + /*--- Set wall values ---*/ + + density = solver_container[FLOW_SOL]->GetNodes()->GetDensity(jPoint); + laminar_viscosity = solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(jPoint); + + beta_1 = constants[4]; + + Solution[0] = 0.0; + Solution[1] = 60.0*laminar_viscosity/(density*beta_1*distance*distance); + + /*--- Set the solution values and zero the residual ---*/ + nodes->SetSolution_Old(iPoint,Solution); + nodes->SetSolution(iPoint,Solution); + LinSysRes.SetBlock_Zero(iPoint); + + /*--- Change rows of the Jacobian (includes 1 in the diagonal) ---*/ + for (iVar = 0; iVar < nVar; iVar++) { + total_index = iPoint*nVar+iVar; + Jacobian.DeleteValsRowi(total_index); + } + + } + } + +} + +void CTurbSSTSolver::BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, + unsigned short val_marker) { + + unsigned long iPoint, jPoint, iVertex, total_index; + unsigned short iDim, iVar; + su2double distance, density = 0.0, laminar_viscosity = 0.0, beta_1; + + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); + + /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ + if (geometry->node[iPoint]->GetDomain()) { + + /*--- distance to closest neighbor ---*/ + jPoint = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); + distance = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + distance += (geometry->node[iPoint]->GetCoord(iDim) - geometry->node[jPoint]->GetCoord(iDim))* + (geometry->node[iPoint]->GetCoord(iDim) - geometry->node[jPoint]->GetCoord(iDim)); + } + distance = sqrt(distance); + + /*--- Set wall values ---*/ + + density = solver_container[FLOW_SOL]->GetNodes()->GetDensity(jPoint); + laminar_viscosity = solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(jPoint); + + beta_1 = constants[4]; + + Solution[0] = 0.0; + Solution[1] = 60.0*laminar_viscosity/(density*beta_1*distance*distance); + + /*--- Set the solution values and zero the residual ---*/ + nodes->SetSolution_Old(iPoint,Solution); + nodes->SetSolution(iPoint,Solution); + LinSysRes.SetBlock_Zero(iPoint); + + /*--- Change rows of the Jacobian (includes 1 in the diagonal) ---*/ + for (iVar = 0; iVar < nVar; iVar++) { + total_index = iPoint*nVar+iVar; + Jacobian.DeleteValsRowi(total_index); + } + + } + } + +} + +void CTurbSSTSolver::BC_Far_Field(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { + + unsigned long iPoint, iVertex; + su2double *Normal, *V_infty, *V_domain; + unsigned short iVar, iDim; + + Normal = new su2double[nDim]; + + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { + + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); + + /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ + + if (geometry->node[iPoint]->GetDomain()) { + + /*--- Allocate the value at the infinity ---*/ + + V_infty = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); + + /*--- Retrieve solution at the farfield boundary node ---*/ + + V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); + + conv_numerics->SetPrimitive(V_domain, V_infty); + + /*--- Set turbulent variable at the wall, and at infinity ---*/ + + for (iVar = 0; iVar < nVar; iVar++) + Solution_i[iVar] = nodes->GetSolution(iPoint,iVar); + + Solution_j[0] = kine_Inf; + Solution_j[1] = omega_Inf; + + conv_numerics->SetTurbVar(Solution_i, Solution_j); + + /*--- Set Normal (it is necessary to change the sign) ---*/ + + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); + for (iDim = 0; iDim < nDim; iDim++) + Normal[iDim] = -Normal[iDim]; + conv_numerics->SetNormal(Normal); + + /*--- Grid Movement ---*/ + + if (dynamic_grid) + conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); + + /*--- Compute residuals and Jacobians ---*/ + + conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); + + /*--- Add residuals and Jacobians ---*/ + + LinSysRes.AddBlock(iPoint, Residual); + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); + + } + } + + delete [] Normal; + +} + +void CTurbSSTSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, + unsigned short val_marker) { + + unsigned short iVar, iDim; + unsigned long iVertex, iPoint; + su2double *V_inlet, *V_domain, *Normal; + + Normal = new su2double[nDim]; + + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); + + /*--- Loop over all the vertices on this boundary marker ---*/ + + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { + + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); + + /*--- Check if the node belongs to the domain (i.e., not a halo node) ---*/ + + if (geometry->node[iPoint]->GetDomain()) { + + /*--- Normal vector for this vertex (negate for outward convention) ---*/ + + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); + for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; + + /*--- Allocate the value at the inlet ---*/ + + V_inlet = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); + + /*--- Retrieve solution at the farfield boundary node ---*/ + + V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); + + /*--- Set various quantities in the solver class ---*/ + + conv_numerics->SetPrimitive(V_domain, V_inlet); + + /*--- Set the turbulent variable states. Use free-stream SST + values for the turbulent state at the inflow. ---*/ + + for (iVar = 0; iVar < nVar; iVar++) + Solution_i[iVar] = nodes->GetSolution(iPoint,iVar); + + /*--- Load the inlet turbulence variables (uniform by default). ---*/ + + Solution_j[0] = Inlet_TurbVars[val_marker][iVertex][0]; + Solution_j[1] = Inlet_TurbVars[val_marker][iVertex][1]; + + conv_numerics->SetTurbVar(Solution_i, Solution_j); + + /*--- Set various other quantities in the solver class ---*/ + + conv_numerics->SetNormal(Normal); + + if (dynamic_grid) + conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), + geometry->node[iPoint]->GetGridVel()); + + /*--- Compute the residual using an upwind scheme ---*/ + + conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); + LinSysRes.AddBlock(iPoint, Residual); + + /*--- Jacobian contribution for implicit integration ---*/ + + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); + + // /*--- Viscous contribution, commented out because serious convergence problems ---*/ + // + // visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[Point_Normal]->GetCoord()); + // visc_numerics->SetNormal(Normal); + // + // /*--- Conservative variables w/o reconstruction ---*/ + // + // visc_numerics->SetPrimitive(V_domain, V_inlet); + // + // /*--- Turbulent variables w/o reconstruction, and its gradients ---*/ + // + // visc_numerics->SetTurbVar(Solution_i, Solution_j); + // visc_numerics->SetTurbVarGradient(node[iPoint]->GetGradient(), node[iPoint]->GetGradient()); + // + // /*--- Menter's first blending function ---*/ + // + // visc_numerics->SetF1blending(node[iPoint]->GetF1blending(), node[iPoint]->GetF1blending()); + // + // /*--- Compute residual, and Jacobians ---*/ + // + // visc_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); + // + // /*--- Subtract residual, and update Jacobians ---*/ + // + // LinSysRes.SubtractBlock(iPoint, Residual); + // Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); + + } + + } + + /*--- Free locally allocated memory ---*/ + + delete [] Normal; + +} + +void CTurbSSTSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { + + unsigned long iPoint, iVertex; + unsigned short iVar, iDim; + su2double *V_outlet, *V_domain, *Normal; + + Normal = new su2double[nDim]; + + /*--- Loop over all the vertices on this boundary marker ---*/ + + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); + + /*--- Check if the node belongs to the domain (i.e., not a halo node) ---*/ + + if (geometry->node[iPoint]->GetDomain()) { + + /*--- Allocate the value at the outlet ---*/ + + V_outlet = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); + + /*--- Retrieve solution at the farfield boundary node ---*/ + + V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); + + /*--- Set various quantities in the solver class ---*/ + + conv_numerics->SetPrimitive(V_domain, V_outlet); + + /*--- Set the turbulent variables. Here we use a Neumann BC such + that the turbulent variable is copied from the interior of the + domain to the outlet before computing the residual. + Solution_i --> TurbVar_internal, + Solution_j --> TurbVar_outlet ---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + Solution_i[iVar] = nodes->GetSolution(iPoint,iVar); + Solution_j[iVar] = nodes->GetSolution(iPoint,iVar); + } + conv_numerics->SetTurbVar(Solution_i, Solution_j); + + /*--- Set Normal (negate for outward convention) ---*/ + + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); + for (iDim = 0; iDim < nDim; iDim++) + Normal[iDim] = -Normal[iDim]; + conv_numerics->SetNormal(Normal); + + if (dynamic_grid) + conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), + geometry->node[iPoint]->GetGridVel()); + + /*--- Compute the residual using an upwind scheme ---*/ + + conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); + LinSysRes.AddBlock(iPoint, Residual); + + /*--- Jacobian contribution for implicit integration ---*/ + + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); + +// /*--- Viscous contribution, commented out because serious convergence problems ---*/ +// +// visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[Point_Normal]->GetCoord()); +// visc_numerics->SetNormal(Normal); +// +// /*--- Conservative variables w/o reconstruction ---*/ +// +// visc_numerics->SetPrimitive(V_domain, V_outlet); +// +// /*--- Turbulent variables w/o reconstruction, and its gradients ---*/ +// +// visc_numerics->SetTurbVar(Solution_i, Solution_j); +// visc_numerics->SetTurbVarGradient(node[iPoint]->GetGradient(), node[iPoint]->GetGradient()); +// +// /*--- Menter's first blending function ---*/ +// +// visc_numerics->SetF1blending(node[iPoint]->GetF1blending(), node[iPoint]->GetF1blending()); +// +// /*--- Compute residual, and Jacobians ---*/ +// +// visc_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); +// +// /*--- Subtract residual, and update Jacobians ---*/ +// +// LinSysRes.SubtractBlock(iPoint, Residual); +// Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); + + } + } + + /*--- Free locally allocated memory ---*/ + delete[] Normal; + +} + + +void CTurbSSTSolver::BC_Inlet_MixingPlane(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, + unsigned short val_marker) { + + unsigned short iVar, iSpan, iDim; + unsigned long oldVertex, iPoint, Point_Normal, iVertex; + su2double *V_inlet, *V_domain, *Normal; + su2double extAverageKine, extAverageOmega; + unsigned short nSpanWiseSections = config->GetnSpanWiseSections(); + + Normal = new su2double[nDim]; + + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); + + /*--- Loop over all the vertices on this boundary marker ---*/ + for (iSpan= 0; iSpan < nSpanWiseSections ; iSpan++){ + extAverageKine = solver_container[FLOW_SOL]->GetExtAverageKine(val_marker, iSpan); + extAverageOmega = solver_container[FLOW_SOL]->GetExtAverageOmega(val_marker, iSpan); + + + /*--- Loop over all the vertices on this boundary marker ---*/ + + for (iVertex = 0; iVertex < geometry->GetnVertexSpan(val_marker,iSpan); iVertex++) { + + /*--- find the node related to the vertex ---*/ + iPoint = geometry->turbovertex[val_marker][iSpan][iVertex]->GetNode(); + + /*--- using the other vertex information for retrieving some information ---*/ + oldVertex = geometry->turbovertex[val_marker][iSpan][iVertex]->GetOldVertex(); + + /*--- Index of the closest interior node ---*/ + Point_Normal = geometry->vertex[val_marker][oldVertex]->GetNormal_Neighbor(); + + /*--- Normal vector for this vertex (negate for outward convention) ---*/ + + geometry->vertex[val_marker][oldVertex]->GetNormal(Normal); + for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; + + /*--- Allocate the value at the inlet ---*/ + V_inlet = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, oldVertex); + + /*--- Retrieve solution at the farfield boundary node ---*/ + + V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); + + /*--- Set various quantities in the solver class ---*/ + + conv_numerics->SetPrimitive(V_domain, V_inlet); + + /*--- Set the turbulent variable states (prescribed for an inflow) ---*/ + + for (iVar = 0; iVar < nVar; iVar++) + Solution_i[iVar] = nodes->GetSolution(iPoint,iVar); + + Solution_j[0]= extAverageKine; + Solution_j[1]= extAverageOmega; + + conv_numerics->SetTurbVar(Solution_i, Solution_j); + + /*--- Set various other quantities in the solver class ---*/ + conv_numerics->SetNormal(Normal); + + if (dynamic_grid) + conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), + geometry->node[iPoint]->GetGridVel()); + + /*--- Compute the residual using an upwind scheme ---*/ + conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); + LinSysRes.AddBlock(iPoint, Residual); + + /*--- Jacobian contribution for implicit integration ---*/ + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); + + /*--- Viscous contribution ---*/ + visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[Point_Normal]->GetCoord()); + visc_numerics->SetNormal(Normal); + + /*--- Conservative variables w/o reconstruction ---*/ + visc_numerics->SetPrimitive(V_domain, V_inlet); + + /*--- Turbulent variables w/o reconstruction, and its gradients ---*/ + visc_numerics->SetTurbVar(Solution_i, Solution_j); + visc_numerics->SetTurbVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(iPoint)); + + /*--- Menter's first blending function ---*/ + visc_numerics->SetF1blending(nodes->GetF1blending(iPoint), nodes->GetF1blending(iPoint)); + + /*--- Compute residual, and Jacobians ---*/ + visc_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); + + /*--- Subtract residual, and update Jacobians ---*/ + LinSysRes.SubtractBlock(iPoint, Residual); + Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); + + } + } + + /*--- Free locally allocated memory ---*/ + delete[] Normal; + +} + +void CTurbSSTSolver::BC_Inlet_Turbo(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, + unsigned short val_marker) { + + unsigned short iVar, iSpan, iDim; + unsigned long oldVertex, iPoint, Point_Normal, iVertex; + su2double *V_inlet, *V_domain, *Normal; + unsigned short nSpanWiseSections = config->GetnSpanWiseSections(); + + /*--- Quantities for computing the kine and omega to impose at the inlet boundary. ---*/ + su2double rho, pressure, *Vel, VelMag, muLam, Intensity, viscRatio, kine_b, omega_b, kine; + CFluidModel *FluidModel; + + FluidModel = solver_container[FLOW_SOL]->GetFluidModel(); + Intensity = config->GetTurbulenceIntensity_FreeStream(); + viscRatio = config->GetTurb2LamViscRatio_FreeStream(); + + Normal = new su2double[nDim]; + Vel = new su2double[nDim]; + + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); + + + for (iSpan= 0; iSpan < nSpanWiseSections ; iSpan++){ + + /*--- Compute the inflow kine and omega using the span wise averge quntities---*/ + for (iDim = 0; iDim < nDim; iDim++) + Vel[iDim] = solver_container[FLOW_SOL]->GetAverageTurboVelocity(val_marker, iSpan)[iDim]; + + rho = solver_container[FLOW_SOL]->GetAverageDensity(val_marker, iSpan); + pressure = solver_container[FLOW_SOL]->GetAveragePressure(val_marker, iSpan); + kine = solver_container[FLOW_SOL]->GetAverageKine(val_marker, iSpan); + + FluidModel->SetTDState_Prho(pressure, rho); + muLam = FluidModel->GetLaminarViscosity(); + + VelMag = 0; + for (iDim = 0; iDim < nDim; iDim++) + VelMag += Vel[iDim]*Vel[iDim]; + VelMag = sqrt(VelMag); + + kine_b = 3.0/2.0*(VelMag*VelMag*Intensity*Intensity); + omega_b = rho*kine/(muLam*viscRatio); + + /*--- Loop over all the vertices on this boundary marker ---*/ + for (iVertex = 0; iVertex < geometry->GetnVertexSpan(val_marker,iSpan); iVertex++) { + + /*--- find the node related to the vertex ---*/ + iPoint = geometry->turbovertex[val_marker][iSpan][iVertex]->GetNode(); + + /*--- using the other vertex information for retrieving some information ---*/ + oldVertex = geometry->turbovertex[val_marker][iSpan][iVertex]->GetOldVertex(); + + /*--- Index of the closest interior node ---*/ + Point_Normal = geometry->vertex[val_marker][oldVertex]->GetNormal_Neighbor(); + + /*--- Normal vector for this vertex (negate for outward convention) ---*/ + + geometry->vertex[val_marker][oldVertex]->GetNormal(Normal); + for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; + + /*--- Allocate the value at the inlet ---*/ + V_inlet = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, oldVertex); + + /*--- Retrieve solution at the farfield boundary node ---*/ + + V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); + + /*--- Set various quantities in the solver class ---*/ + + conv_numerics->SetPrimitive(V_domain, V_inlet); + + for (iVar = 0; iVar < nVar; iVar++) + Solution_i[iVar] = nodes->GetSolution(iPoint,iVar); + + /*--- Set the turbulent variable states. Use average span-wise values + values for the turbulent state at the inflow. ---*/ + + Solution_j[0]= kine_b; + Solution_j[1]= omega_b; + + conv_numerics->SetTurbVar(Solution_i, Solution_j); + + /*--- Set various other quantities in the solver class ---*/ + conv_numerics->SetNormal(Normal); + + if (dynamic_grid) + conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), + geometry->node[iPoint]->GetGridVel()); + + /*--- Compute the residual using an upwind scheme ---*/ + conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); + LinSysRes.AddBlock(iPoint, Residual); + + /*--- Jacobian contribution for implicit integration ---*/ + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); + + /*--- Viscous contribution ---*/ + visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[Point_Normal]->GetCoord()); + visc_numerics->SetNormal(Normal); + + /*--- Conservative variables w/o reconstruction ---*/ + visc_numerics->SetPrimitive(V_domain, V_inlet); + + /*--- Turbulent variables w/o reconstruction, and its gradients ---*/ + visc_numerics->SetTurbVar(Solution_i, Solution_j); + visc_numerics->SetTurbVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(iPoint)); + + /*--- Menter's first blending function ---*/ + visc_numerics->SetF1blending(nodes->GetF1blending(iPoint), nodes->GetF1blending(iPoint)); + + /*--- Compute residual, and Jacobians ---*/ + visc_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); + + /*--- Subtract residual, and update Jacobians ---*/ + LinSysRes.SubtractBlock(iPoint, Residual); + Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); + + } + } + + /*--- Free locally allocated memory ---*/ + delete[] Normal; + delete[] Vel; + +} + + +void CTurbSSTSolver::BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, + CNumerics *visc_numerics, CConfig *config){ + + unsigned long iVertex, jVertex, iPoint, Point_Normal = 0; + unsigned short iDim, iVar, iMarker; + + unsigned short nPrimVar = solver_container[FLOW_SOL]->GetnPrimVar(); + su2double *Normal = new su2double[nDim]; + su2double *PrimVar_i = new su2double[nPrimVar]; + su2double *PrimVar_j = new su2double[nPrimVar]; + su2double *tmp_residual = new su2double[nVar]; + + unsigned long nDonorVertex; + su2double weight; + + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { + + if (config->GetMarker_All_KindBC(iMarker) == FLUID_INTERFACE) { + + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + Point_Normal = geometry->vertex[iMarker][iVertex]->GetNormal_Neighbor(); + + if (geometry->node[iPoint]->GetDomain()) { + + nDonorVertex = GetnSlidingStates(iMarker, iVertex); + + /*--- Initialize Residual, this will serve to accumulate the average ---*/ + + for (iVar = 0; iVar < nVar; iVar++) + Residual[iVar] = 0.0; + + /*--- Loop over the nDonorVertexes and compute the averaged flux ---*/ + + for (jVertex = 0; jVertex < nDonorVertex; jVertex++){ + + geometry->vertex[iMarker][iVertex]->GetNormal(Normal); + for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; + + for (iVar = 0; iVar < nPrimVar; iVar++) { + PrimVar_i[iVar] = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint,iVar); + PrimVar_j[iVar] = solver_container[FLOW_SOL]->GetSlidingState(iMarker, iVertex, iVar, jVertex); + } + + /*--- Get the weight computed in the interpolator class for the j-th donor vertex ---*/ + + weight = solver_container[FLOW_SOL]->GetSlidingState(iMarker, iVertex, nPrimVar, jVertex); + + /*--- Set primitive variables ---*/ + + conv_numerics->SetPrimitive( PrimVar_i, PrimVar_j ); + + /*--- Set the turbulent variable states ---*/ + Solution_i[0] = nodes->GetSolution(iPoint,0); + Solution_i[1] = nodes->GetSolution(iPoint,1); + + Solution_j[0] = GetSlidingState(iMarker, iVertex, 0, jVertex); + Solution_j[1] = GetSlidingState(iMarker, iVertex, 1, jVertex); + + conv_numerics->SetTurbVar(Solution_i, Solution_j); + + /*--- Set the normal vector ---*/ + + conv_numerics->SetNormal(Normal); + + if (dynamic_grid) + conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[iPoint]->GetGridVel()); + + conv_numerics->ComputeResidual(tmp_residual, Jacobian_i, Jacobian_j, config); + + /*--- Accumulate the residuals to compute the average ---*/ + + for (iVar = 0; iVar < nVar; iVar++) + Residual[iVar] += weight*tmp_residual[iVar]; + } + + /*--- Add Residuals and Jacobians ---*/ + + LinSysRes.AddBlock(iPoint, Residual); + + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); + + /*--- Set the normal vector and the coordinates ---*/ + + visc_numerics->SetNormal(Normal); + visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[Point_Normal]->GetCoord()); + + /*--- Primitive variables, and gradient ---*/ + + visc_numerics->SetPrimitive(PrimVar_i, PrimVar_j); + // visc_numerics->SetPrimVarGradient(node[iPoint]->GetGradient_Primitive(), node[iPoint]->GetGradient_Primitive()); + + /*--- Turbulent variables and its gradients ---*/ + + visc_numerics->SetTurbVar(Solution_i, Solution_j); + visc_numerics->SetTurbVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(iPoint)); + + /*--- Compute and update residual ---*/ + + visc_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); + + LinSysRes.SubtractBlock(iPoint, Residual); + + /*--- Jacobian contribution for implicit integration ---*/ + + Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); + + } + } + } + } + + /*--- Free locally allocated memory ---*/ + + delete [] tmp_residual; + delete [] Normal; + delete [] PrimVar_i; + delete [] PrimVar_j; + +} + +void CTurbSSTSolver::SetInletAtVertex(su2double *val_inlet, + unsigned short iMarker, + unsigned long iVertex) { + + Inlet_TurbVars[iMarker][iVertex][0] = val_inlet[nDim+2+nDim]; + Inlet_TurbVars[iMarker][iVertex][1] = val_inlet[nDim+2+nDim+1]; + +} + +su2double CTurbSSTSolver::GetInletAtVertex(su2double *val_inlet, + unsigned long val_inlet_point, + unsigned short val_kind_marker, + string val_marker, + CGeometry *geometry, + CConfig *config) const { + + /*--- Local variables ---*/ + + unsigned short iMarker, iDim; + unsigned long iPoint, iVertex; + su2double Area = 0.0; + su2double Normal[3] = {0.0,0.0,0.0}; + + /*--- Alias positions within inlet file for readability ---*/ + + if (val_kind_marker == INLET_FLOW) { + + unsigned short tke_position = nDim+2+nDim; + unsigned short omega_position = nDim+2+nDim+1; + + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { + if ((config->GetMarker_All_KindBC(iMarker) == INLET_FLOW) && + (config->GetMarker_All_TagBound(iMarker) == val_marker)) { + + for (iVertex = 0; iVertex < nVertex[iMarker]; iVertex++){ + + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + if (iPoint == val_inlet_point) { + + /*-- Compute boundary face area for this vertex. ---*/ + + geometry->vertex[iMarker][iVertex]->GetNormal(Normal); + Area = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + Area += Normal[iDim]*Normal[iDim]; + Area = sqrt(Area); + + /*--- Access and store the inlet variables for this vertex. ---*/ + + val_inlet[tke_position] = Inlet_TurbVars[iMarker][iVertex][0]; + val_inlet[omega_position] = Inlet_TurbVars[iMarker][iVertex][1]; + + /*--- Exit once we find the point. ---*/ + + return Area; + + } + } + } + } + + } + + /*--- If we don't find a match, then the child point is not on the + current inlet boundary marker. Return zero area so this point does + not contribute to the restriction operator and continue. ---*/ + + return Area; + +} + +void CTurbSSTSolver::SetUniformInlet(CConfig* config, unsigned short iMarker) { + + for(unsigned long iVertex=0; iVertex < nVertex[iMarker]; iVertex++){ + Inlet_TurbVars[iMarker][iVertex][0] = kine_Inf; + Inlet_TurbVars[iMarker][iVertex][1] = omega_Inf; + } + +} diff --git a/SU2_CFD/src/solvers/CTurbSolver.cpp b/SU2_CFD/src/solvers/CTurbSolver.cpp new file mode 100644 index 000000000000..d21873dfd043 --- /dev/null +++ b/SU2_CFD/src/solvers/CTurbSolver.cpp @@ -0,0 +1,925 @@ +/*! + * \file CTurbSolver.cpp + * \brief Main subrotuines of CTurbSolver class + * \author F. Palacios, A. Bueno + * \version 7.0.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2019, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + + +#include "../../include/solvers/CTurbSolver.hpp" + + +CTurbSolver::CTurbSolver(void) : CSolver() { + + FlowPrimVar_i = NULL; + FlowPrimVar_j = NULL; + lowerlimit = NULL; + upperlimit = NULL; + nVertex = NULL; + nMarker = 0; + Inlet_TurbVars = NULL; + snode = nullptr; +} + +CTurbSolver::CTurbSolver(CGeometry* geometry, CConfig *config) : CSolver() { + + Gamma = config->GetGamma(); + Gamma_Minus_One = Gamma - 1.0; + + FlowPrimVar_i = NULL; + FlowPrimVar_j = NULL; + lowerlimit = NULL; + upperlimit = NULL; + nMarker = config->GetnMarker_All(); + + /*--- Store the number of vertices on each marker for deallocation later ---*/ + nVertex = new unsigned long[nMarker]; + for (unsigned long iMarker = 0; iMarker < nMarker; iMarker++) + nVertex[iMarker] = geometry->nVertex[iMarker]; + + /* A grid is defined as dynamic if there's rigid grid movement or grid deformation AND the problem is time domain */ + dynamic_grid = config->GetDynamic_Grid(); + +} + +CTurbSolver::~CTurbSolver(void) { + + if (Inlet_TurbVars != NULL) { + for (unsigned short iMarker = 0; iMarker < nMarker; iMarker++) { + if (Inlet_TurbVars[iMarker] != NULL) { + for (unsigned long iVertex = 0; iVertex < nVertex[iMarker]; iVertex++) { + delete [] Inlet_TurbVars[iMarker][iVertex]; + } + delete [] Inlet_TurbVars[iMarker]; + } + } + delete [] Inlet_TurbVars; + } + + if (FlowPrimVar_i != NULL) delete [] FlowPrimVar_i; + if (FlowPrimVar_j != NULL) delete [] FlowPrimVar_j; + if (lowerlimit != NULL) delete [] lowerlimit; + if (upperlimit != NULL) delete [] upperlimit; + + if (nodes != nullptr) delete nodes; +} + +void CTurbSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short iMesh) { + + su2double *Turb_i, *Turb_j, *Limiter_i = NULL, *Limiter_j = NULL, *V_i, *V_j, **Gradient_i, **Gradient_j, Project_Grad_i, Project_Grad_j; + unsigned long iEdge, iPoint, jPoint; + unsigned short iDim, iVar; + + bool muscl = config->GetMUSCL_Turb(); + bool limiter = (config->GetKind_SlopeLimit_Turb() != NO_LIMITER); + + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { + + /*--- Points in edge and normal vectors ---*/ + + iPoint = geometry->edge[iEdge]->GetNode(0); + jPoint = geometry->edge[iEdge]->GetNode(1); + numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); + + /*--- Primitive variables w/o reconstruction ---*/ + + V_i = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); + V_j = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(jPoint); + numerics->SetPrimitive(V_i, V_j); + + /*--- Turbulent variables w/o reconstruction ---*/ + + Turb_i = nodes->GetSolution(iPoint); + Turb_j = nodes->GetSolution(jPoint); + numerics->SetTurbVar(Turb_i, Turb_j); + + /*--- Grid Movement ---*/ + + if (dynamic_grid) + numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[jPoint]->GetGridVel()); + + if (muscl) { + + for (iDim = 0; iDim < nDim; iDim++) { + Vector_i[iDim] = 0.5*(geometry->node[jPoint]->GetCoord(iDim) - geometry->node[iPoint]->GetCoord(iDim)); + Vector_j[iDim] = 0.5*(geometry->node[iPoint]->GetCoord(iDim) - geometry->node[jPoint]->GetCoord(iDim)); + } + + /*--- Mean flow primitive variables using gradient reconstruction and limiters ---*/ + + Gradient_i = solver_container[FLOW_SOL]->GetNodes()->GetGradient_Reconstruction(iPoint); + Gradient_j = solver_container[FLOW_SOL]->GetNodes()->GetGradient_Reconstruction(jPoint); + + if (limiter) { + Limiter_i = solver_container[FLOW_SOL]->GetNodes()->GetLimiter_Primitive(iPoint); + Limiter_j = solver_container[FLOW_SOL]->GetNodes()->GetLimiter_Primitive(jPoint); + } + + for (iVar = 0; iVar < solver_container[FLOW_SOL]->GetnPrimVarGrad(); iVar++) { + Project_Grad_i = 0.0; Project_Grad_j = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + Project_Grad_i += Vector_i[iDim]*Gradient_i[iVar][iDim]; + Project_Grad_j += Vector_j[iDim]*Gradient_j[iVar][iDim]; + } + if (limiter) { + FlowPrimVar_i[iVar] = V_i[iVar] + Limiter_i[iVar]*Project_Grad_i; + FlowPrimVar_j[iVar] = V_j[iVar] + Limiter_j[iVar]*Project_Grad_j; + } + else { + FlowPrimVar_i[iVar] = V_i[iVar] + Project_Grad_i; + FlowPrimVar_j[iVar] = V_j[iVar] + Project_Grad_j; + } + } + + numerics->SetPrimitive(FlowPrimVar_i, FlowPrimVar_j); + + /*--- Turbulent variables using gradient reconstruction and limiters ---*/ + + Gradient_i = nodes->GetGradient_Reconstruction(iPoint); + Gradient_j = nodes->GetGradient_Reconstruction(jPoint); + + if (limiter) { + Limiter_i = nodes->GetLimiter(iPoint); + Limiter_j = nodes->GetLimiter(jPoint); + } + + for (iVar = 0; iVar < nVar; iVar++) { + Project_Grad_i = 0.0; Project_Grad_j = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + Project_Grad_i += Vector_i[iDim]*Gradient_i[iVar][iDim]; + Project_Grad_j += Vector_j[iDim]*Gradient_j[iVar][iDim]; + } + if (limiter) { + Solution_i[iVar] = Turb_i[iVar] + Limiter_i[iVar]*Project_Grad_i; + Solution_j[iVar] = Turb_j[iVar] + Limiter_j[iVar]*Project_Grad_j; + } + else { + Solution_i[iVar] = Turb_i[iVar] + Project_Grad_i; + Solution_j[iVar] = Turb_j[iVar] + Project_Grad_j; + } + } + + numerics->SetTurbVar(Solution_i, Solution_j); + + } + + /*--- Add and subtract residual ---*/ + + numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); + + LinSysRes.AddBlock(iPoint, Residual); + LinSysRes.SubtractBlock(jPoint, Residual); + + /*--- Implicit part ---*/ + + Jacobian.UpdateBlocks(iEdge, iPoint, jPoint, Jacobian_i, Jacobian_j); + + } + +} + +void CTurbSolver::Viscous_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, + CConfig *config, unsigned short iMesh, unsigned short iRKStep) { + unsigned long iEdge, iPoint, jPoint; + + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { + + /*--- Points in edge ---*/ + + iPoint = geometry->edge[iEdge]->GetNode(0); + jPoint = geometry->edge[iEdge]->GetNode(1); + + /*--- Points coordinates, and normal vector ---*/ + + numerics->SetCoord(geometry->node[iPoint]->GetCoord(), + geometry->node[jPoint]->GetCoord()); + numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); + + /*--- Conservative variables w/o reconstruction ---*/ + + numerics->SetPrimitive(solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint), + solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(jPoint)); + + /*--- Turbulent variables w/o reconstruction, and its gradients ---*/ + + numerics->SetTurbVar(nodes->GetSolution(iPoint), nodes->GetSolution(jPoint)); + numerics->SetTurbVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(jPoint)); + + /*--- Menter's first blending function (only SST)---*/ + if ((config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST)) + numerics->SetF1blending(nodes->GetF1blending(iPoint), nodes->GetF1blending(jPoint)); + + /*--- Compute residual, and Jacobians ---*/ + + numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); + + /*--- Add and subtract residual, and update Jacobians ---*/ + + LinSysRes.SubtractBlock(iPoint, Residual); + LinSysRes.AddBlock(jPoint, Residual); + + Jacobian.UpdateBlocks(iEdge, iPoint, jPoint, Jacobian_i, Jacobian_j); + + } + +} + +void CTurbSolver::BC_Sym_Plane(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { + + /*--- Convective and viscous fluxes across symmetry plane are equal to zero. ---*/ + +} + +void CTurbSolver::BC_Euler_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { + + /*--- Convective fluxes across euler wall are equal to zero. ---*/ + +} + +void CTurbSolver::BC_Riemann(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { + + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); + + switch(config->GetKind_Data_Riemann(Marker_Tag)) + { + case TOTAL_CONDITIONS_PT: case STATIC_SUPERSONIC_INFLOW_PT: case STATIC_SUPERSONIC_INFLOW_PD: case DENSITY_VELOCITY: + BC_Inlet(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); + break; + case STATIC_PRESSURE: + BC_Outlet(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); + break; + } +} + +void CTurbSolver::BC_TurboRiemann(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { + + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); + + switch(config->GetKind_Data_Riemann(Marker_Tag)) + { + case TOTAL_CONDITIONS_PT: case STATIC_SUPERSONIC_INFLOW_PT: case STATIC_SUPERSONIC_INFLOW_PD: case DENSITY_VELOCITY: + BC_Inlet_Turbo(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); + break; + case STATIC_PRESSURE: + BC_Outlet(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); + break; + } +} + + +void CTurbSolver::BC_Giles(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { + + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); + + switch(config->GetKind_Data_Giles(Marker_Tag)) + { + case TOTAL_CONDITIONS_PT:case TOTAL_CONDITIONS_PT_1D: case DENSITY_VELOCITY: + BC_Inlet_Turbo(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); + break; + case MIXING_IN: + if (config->GetBoolTurbMixingPlane()){ + BC_Inlet_MixingPlane(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); + } + else{ + BC_Inlet_Turbo(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); + } + break; + + case STATIC_PRESSURE: case MIXING_OUT: case STATIC_PRESSURE_1D: case RADIAL_EQUILIBRIUM: + BC_Outlet(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); + break; + } +} + +void CTurbSolver::BC_Periodic(CGeometry *geometry, CSolver **solver_container, + CNumerics *numerics, CConfig *config) { + + /*--- Complete residuals for periodic boundary conditions. We loop over + the periodic BCs in matching pairs so that, in the event that there are + adjacent periodic markers, the repeated points will have their residuals + accumulated corectly during the communications. For implicit calculations + the Jacobians and linear system are also correctly adjusted here. ---*/ + + for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { + InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_RESIDUAL); + CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_RESIDUAL); + } + +} + +void CTurbSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { + + unsigned short iVar; + unsigned long iPoint, total_index; + su2double Delta, Vol, density_old = 0.0, density = 0.0; + + bool adjoint = config->GetContinuous_Adjoint() || (config->GetDiscrete_Adjoint() && config->GetFrozen_Visc_Disc()); + bool compressible = (config->GetKind_Regime() == COMPRESSIBLE); + bool incompressible = (config->GetKind_Regime() == INCOMPRESSIBLE); + + /*--- Set maximum residual to zero ---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + SetRes_RMS(iVar, 0.0); + SetRes_Max(iVar, 0.0, 0); + } + + /*--- Build implicit system ---*/ + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + /*--- Read the volume ---*/ + + Vol = (geometry->node[iPoint]->GetVolume() + + geometry->node[iPoint]->GetPeriodicVolume()); + + /*--- Modify matrix diagonal to assure diagonal dominance ---*/ + + Delta = Vol / ((nodes->GetLocalCFL(iPoint)/solver_container[FLOW_SOL]->GetNodes()->GetLocalCFL(iPoint))*solver_container[FLOW_SOL]->GetNodes()->GetDelta_Time(iPoint)); + Jacobian.AddVal2Diag(iPoint, Delta); + + /*--- Right hand side of the system (-Residual) and initial guess (x = 0) ---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + total_index = iPoint*nVar+iVar; + LinSysRes[total_index] = - LinSysRes[total_index]; + LinSysSol[total_index] = 0.0; + AddRes_RMS(iVar, LinSysRes[total_index]*LinSysRes[total_index]); + AddRes_Max(iVar, fabs(LinSysRes[total_index]), geometry->node[iPoint]->GetGlobalIndex(), geometry->node[iPoint]->GetCoord()); + } + } + + /*--- Initialize residual and solution at the ghost points ---*/ + + for (iPoint = nPointDomain; iPoint < nPoint; iPoint++) { + for (iVar = 0; iVar < nVar; iVar++) { + total_index = iPoint*nVar + iVar; + LinSysRes[total_index] = 0.0; + LinSysSol[total_index] = 0.0; + } + } + + /*--- Solve or smooth the linear system ---*/ + + unsigned long IterLinSol = System.Solve(Jacobian, LinSysRes, LinSysSol, geometry, config); + SetIterLinSolver(IterLinSol); + + /*--- Store the value of the residual. ---*/ + + SetResLinSolver(System.GetResidual()); + + ComputeUnderRelaxationFactor(solver_container, config); + + /*--- Update solution (system written in terms of increments) ---*/ + + if (!adjoint) { + + /*--- Update the turbulent solution. Only SST variants are clipped. ---*/ + + switch (config->GetKind_Turb_Model()) { + + case SA: case SA_E: case SA_COMP: case SA_E_COMP: case SA_NEG: + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + nodes->AddSolution(iPoint, 0, nodes->GetUnderRelaxation(iPoint)*LinSysSol[iPoint]); + } + + break; + + case SST: case SST_SUST: + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + if (compressible) { + density_old = solver_container[FLOW_SOL]->GetNodes()->GetSolution_Old(iPoint,0); + density = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + } + if (incompressible) { + density_old = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + density = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + } + + for (iVar = 0; iVar < nVar; iVar++) { + nodes->AddConservativeSolution(iPoint, iVar, nodes->GetUnderRelaxation(iPoint)*LinSysSol[iPoint*nVar+iVar], density, density_old, lowerlimit[iVar], upperlimit[iVar]); + } + + } + + break; + + } + } + + for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { + InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_IMPLICIT); + CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_IMPLICIT); + } + + /*--- MPI solution ---*/ + + InitiateComms(geometry, config, SOLUTION_EDDY); + CompleteComms(geometry, config, SOLUTION_EDDY); + + /*--- Compute the root mean square residual ---*/ + + SetResidual_RMS(geometry, config); + +} + +void CTurbSolver::ComputeUnderRelaxationFactor(CSolver **solver_container, CConfig *config) { + + /* Only apply the turbulent under-relaxation to the SA variants. The + SA_NEG model is more robust due to allowing for negative nu_tilde, + so the under-relaxation is not applied to that variant. */ + + bool sa_model = ((config->GetKind_Turb_Model() == SA) || + (config->GetKind_Turb_Model() == SA_E) || + (config->GetKind_Turb_Model() == SA_COMP) || + (config->GetKind_Turb_Model() == SA_E_COMP)); + + /* Loop over the solution update given by relaxing the linear + system for this nonlinear iteration. */ + + su2double localUnderRelaxation = 1.00; + const su2double allowableDecrease = -0.99; + const su2double allowableIncrease = 0.99; + + for (unsigned long iPoint = 0; iPoint < nPointDomain; iPoint++) { + + localUnderRelaxation = 1.0; + if (sa_model) { + for (unsigned short iVar = 0; iVar < nVar; iVar++) { + + /* We impose a limit on the maximum percentage that the + turbulence variables can change over a nonlinear iteration. */ + + const unsigned long index = iPoint*nVar + iVar; + su2double ratio = LinSysSol[index]/(nodes->GetSolution(iPoint, iVar)+EPS); + if (ratio > allowableIncrease) { + localUnderRelaxation = min(allowableIncrease/ratio, localUnderRelaxation); + } else if (ratio < allowableDecrease) { + localUnderRelaxation = min(fabs(allowableDecrease)/ratio, localUnderRelaxation); + } + + } + } + + /* Choose the minimum factor between mean flow and turbulence. */ + + localUnderRelaxation = min(localUnderRelaxation, solver_container[FLOW_SOL]->GetNodes()->GetUnderRelaxation(iPoint)); + + /* Threshold the relaxation factor in the event that there is + a very small value. This helps avoid catastrophic crashes due + to non-realizable states by canceling the update. */ + + if (localUnderRelaxation < 1e-10) localUnderRelaxation = 0.0; + + /* Store the under-relaxation factor for this point. */ + + nodes->SetUnderRelaxation(iPoint, localUnderRelaxation); + + } + +} + +void CTurbSolver::SetResidual_DualTime(CGeometry *geometry, CSolver **solver_container, CConfig *config, + unsigned short iRKStep, unsigned short iMesh, unsigned short RunTime_EqSystem) { + + /*--- Local variables ---*/ + + unsigned short iVar, jVar, iMarker, iDim; + unsigned long iPoint, jPoint, iEdge, iVertex; + + su2double *U_time_nM1, *U_time_n, *U_time_nP1; + su2double Volume_nM1, Volume_nP1, TimeStep; + su2double Density_nM1, Density_n, Density_nP1; + su2double *Normal = NULL, *GridVel_i = NULL, *GridVel_j = NULL, Residual_GCL; + + bool implicit = (config->GetKind_TimeIntScheme_Turb() == EULER_IMPLICIT); + + bool incompressible = (config->GetKind_Regime() == INCOMPRESSIBLE); + unsigned short turbModel = config->GetKind_Turb_Model(); + + /*--- Store the physical time step ---*/ + + TimeStep = config->GetDelta_UnstTimeND(); + + /*--- Compute the dual time-stepping source term for static meshes ---*/ + + if (!dynamic_grid) { + + /*--- Loop over all nodes (excluding halos) ---*/ + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + /*--- Retrieve the solution at time levels n-1, n, and n+1. Note that + we are currently iterating on U^n+1 and that U^n & U^n-1 are fixed, + previous solutions that are stored in memory. ---*/ + + U_time_nM1 = nodes->GetSolution_time_n1(iPoint); + U_time_n = nodes->GetSolution_time_n(iPoint); + U_time_nP1 = nodes->GetSolution(iPoint); + + /*--- CV volume at time n+1. As we are on a static mesh, the volume + of the CV will remained fixed for all time steps. ---*/ + + Volume_nP1 = geometry->node[iPoint]->GetVolume(); + + /*--- Compute the dual time-stepping source term based on the chosen + time discretization scheme (1st- or 2nd-order).---*/ + + if ((turbModel == SST) || (turbModel == SST_SUST)) { + + /*--- If this is the SST model, we need to multiply by the density + in order to get the conservative variables ---*/ + if (incompressible){ + /*--- This is temporary and only valid for constant-density problems: + density could also be temperature dependent, but as it is not a part + of the solution vector it's neither stored for previous time steps + nor updated with the solution at the end of each iteration. */ + Density_nM1 = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + Density_n = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + Density_nP1 = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + } + else{ + Density_nM1 = solver_container[FLOW_SOL]->GetNodes()->GetSolution_time_n1(iPoint)[0]; + Density_n = solver_container[FLOW_SOL]->GetNodes()->GetSolution_time_n(iPoint,0); + Density_nP1 = solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint,0); + } + + for (iVar = 0; iVar < nVar; iVar++) { + if (config->GetTime_Marching() == DT_STEPPING_1ST) + Residual[iVar] = ( Density_nP1*U_time_nP1[iVar] - Density_n*U_time_n[iVar])*Volume_nP1 / TimeStep; + if (config->GetTime_Marching() == DT_STEPPING_2ND) + Residual[iVar] = ( 3.0*Density_nP1*U_time_nP1[iVar] - 4.0*Density_n*U_time_n[iVar] + +1.0*Density_nM1*U_time_nM1[iVar])*Volume_nP1 / (2.0*TimeStep); + } + + } else { + + for (iVar = 0; iVar < nVar; iVar++) { + if (config->GetTime_Marching() == DT_STEPPING_1ST) + Residual[iVar] = (U_time_nP1[iVar] - U_time_n[iVar])*Volume_nP1 / TimeStep; + if (config->GetTime_Marching() == DT_STEPPING_2ND) + Residual[iVar] = ( 3.0*U_time_nP1[iVar] - 4.0*U_time_n[iVar] + +1.0*U_time_nM1[iVar])*Volume_nP1 / (2.0*TimeStep); + } + } + + /*--- Store the residual and compute the Jacobian contribution due + to the dual time source term. ---*/ + + LinSysRes.AddBlock(iPoint, Residual); + if (implicit) { + for (iVar = 0; iVar < nVar; iVar++) { + for (jVar = 0; jVar < nVar; jVar++) Jacobian_i[iVar][jVar] = 0.0; + if (config->GetTime_Marching() == DT_STEPPING_1ST) + Jacobian_i[iVar][iVar] = Volume_nP1 / TimeStep; + if (config->GetTime_Marching() == DT_STEPPING_2ND) + Jacobian_i[iVar][iVar] = (Volume_nP1*3.0)/(2.0*TimeStep); + } + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); + } + } + + } else { + + /*--- For unsteady flows on dynamic meshes (rigidly transforming or + dynamically deforming), the Geometric Conservation Law (GCL) should be + satisfied in conjunction with the ALE formulation of the governing + equations. The GCL prevents accuracy issues caused by grid motion, i.e. + a uniform free-stream should be preserved through a moving grid. First, + we will loop over the edges and boundaries to compute the GCL component + of the dual time source term that depends on grid velocities. ---*/ + + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { + + /*--- Get indices for nodes i & j plus the face normal ---*/ + + iPoint = geometry->edge[iEdge]->GetNode(0); + jPoint = geometry->edge[iEdge]->GetNode(1); + Normal = geometry->edge[iEdge]->GetNormal(); + + /*--- Grid velocities stored at nodes i & j ---*/ + + GridVel_i = geometry->node[iPoint]->GetGridVel(); + GridVel_j = geometry->node[jPoint]->GetGridVel(); + + /*--- Compute the GCL term by averaging the grid velocities at the + edge mid-point and dotting with the face normal. ---*/ + + Residual_GCL = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + Residual_GCL += 0.5*(GridVel_i[iDim]+GridVel_j[iDim])*Normal[iDim]; + + /*--- Compute the GCL component of the source term for node i ---*/ + + U_time_n = nodes->GetSolution_time_n(iPoint); + + /*--- Multiply by density at node i for the SST model ---*/ + + if ((turbModel == SST) || (turbModel == SST_SUST)) { + if (incompressible) Density_n = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); // Temporary fix + else Density_n = solver_container[FLOW_SOL]->GetNodes()->GetSolution_time_n(iPoint,0); + for (iVar = 0; iVar < nVar; iVar++) + Residual[iVar] = Density_n*U_time_n[iVar]*Residual_GCL; + } else { + for (iVar = 0; iVar < nVar; iVar++) + Residual[iVar] = U_time_n[iVar]*Residual_GCL; + } + LinSysRes.AddBlock(iPoint, Residual); + + /*--- Compute the GCL component of the source term for node j ---*/ + + U_time_n = nodes->GetSolution_time_n(jPoint); + + /*--- Multiply by density at node j for the SST model ---*/ + + if ((turbModel == SST) || (turbModel == SST_SUST)) { + if (incompressible) Density_n = solver_container[FLOW_SOL]->GetNodes()->GetDensity(jPoint); // Temporary fix + else Density_n = solver_container[FLOW_SOL]->GetNodes()->GetSolution_time_n(jPoint)[0]; + for (iVar = 0; iVar < nVar; iVar++) + Residual[iVar] = Density_n*U_time_n[iVar]*Residual_GCL; + } else { + for (iVar = 0; iVar < nVar; iVar++) + Residual[iVar] = U_time_n[iVar]*Residual_GCL; + } + LinSysRes.SubtractBlock(jPoint, Residual); + + } + + /*--- Loop over the boundary edges ---*/ + + for (iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { + if ((config->GetMarker_All_KindBC(iMarker) != INTERNAL_BOUNDARY) && + (config->GetMarker_All_KindBC(iMarker) != PERIODIC_BOUNDARY)) { + for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { + + /*--- Get the index for node i plus the boundary face normal ---*/ + + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); + + /*--- Grid velocities stored at boundary node i ---*/ + + GridVel_i = geometry->node[iPoint]->GetGridVel(); + + /*--- Compute the GCL term by dotting the grid velocity with the face + normal. The normal is negated to match the boundary convention. ---*/ + + Residual_GCL = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + Residual_GCL -= 0.5*(GridVel_i[iDim]+GridVel_i[iDim])*Normal[iDim]; + + /*--- Compute the GCL component of the source term for node i ---*/ + + U_time_n = nodes->GetSolution_time_n(iPoint); + + /*--- Multiply by density at node i for the SST model ---*/ + + if ((turbModel == SST) || (turbModel == SST_SUST)) { + if (incompressible) Density_n = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); // Temporary fix + else Density_n = solver_container[FLOW_SOL]->GetNodes()->GetSolution_time_n(iPoint,0); + for (iVar = 0; iVar < nVar; iVar++) + Residual[iVar] = Density_n*U_time_n[iVar]*Residual_GCL; + } else { + for (iVar = 0; iVar < nVar; iVar++) + Residual[iVar] = U_time_n[iVar]*Residual_GCL; + } + LinSysRes.AddBlock(iPoint, Residual); + + } + } + } + + /*--- Loop over all nodes (excluding halos) to compute the remainder + of the dual time-stepping source term. ---*/ + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + /*--- Retrieve the solution at time levels n-1, n, and n+1. Note that + we are currently iterating on U^n+1 and that U^n & U^n-1 are fixed, + previous solutions that are stored in memory. ---*/ + + U_time_nM1 = nodes->GetSolution_time_n1(iPoint); + U_time_n = nodes->GetSolution_time_n(iPoint); + U_time_nP1 = nodes->GetSolution(iPoint); + + /*--- CV volume at time n-1 and n+1. In the case of dynamically deforming + grids, the volumes will change. On rigidly transforming grids, the + volumes will remain constant. ---*/ + + Volume_nM1 = geometry->node[iPoint]->GetVolume_nM1(); + Volume_nP1 = geometry->node[iPoint]->GetVolume(); + + /*--- Compute the dual time-stepping source residual. Due to the + introduction of the GCL term above, the remainder of the source residual + due to the time discretization has a new form.---*/ + + if ((turbModel == SST) || (turbModel == SST_SUST)) { + + /*--- If this is the SST model, we need to multiply by the density + in order to get the conservative variables ---*/ + if (incompressible){ + /*--- This is temporary and only valid for constant-density problems: + density could also be temperature dependent, but as it is not a part + of the solution vector it's neither stored for previous time steps + nor updated with the solution at the end of each iteration. */ + Density_nM1 = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + Density_n = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + Density_nP1 = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + } + else{ + Density_nM1 = solver_container[FLOW_SOL]->GetNodes()->GetSolution_time_n1(iPoint)[0]; + Density_n = solver_container[FLOW_SOL]->GetNodes()->GetSolution_time_n(iPoint,0); + Density_nP1 = solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint,0); + } + + for (iVar = 0; iVar < nVar; iVar++) { + if (config->GetTime_Marching() == DT_STEPPING_1ST) + Residual[iVar] = (Density_nP1*U_time_nP1[iVar] - Density_n*U_time_n[iVar])*(Volume_nP1/TimeStep); + if (config->GetTime_Marching() == DT_STEPPING_2ND) + Residual[iVar] = (Density_nP1*U_time_nP1[iVar] - Density_n*U_time_n[iVar])*(3.0*Volume_nP1/(2.0*TimeStep)) + + (Density_nM1*U_time_nM1[iVar] - Density_n*U_time_n[iVar])*(Volume_nM1/(2.0*TimeStep)); + } + + } else { + + for (iVar = 0; iVar < nVar; iVar++) { + if (config->GetTime_Marching() == DT_STEPPING_1ST) + Residual[iVar] = (U_time_nP1[iVar] - U_time_n[iVar])*(Volume_nP1/TimeStep); + if (config->GetTime_Marching() == DT_STEPPING_2ND) + Residual[iVar] = (U_time_nP1[iVar] - U_time_n[iVar])*(3.0*Volume_nP1/(2.0*TimeStep)) + + (U_time_nM1[iVar] - U_time_n[iVar])*(Volume_nM1/(2.0*TimeStep)); + } + } + + /*--- Store the residual and compute the Jacobian contribution due + to the dual time source term. ---*/ + + LinSysRes.AddBlock(iPoint, Residual); + if (implicit) { + for (iVar = 0; iVar < nVar; iVar++) { + for (jVar = 0; jVar < nVar; jVar++) Jacobian_i[iVar][jVar] = 0.0; + if (config->GetTime_Marching() == DT_STEPPING_1ST) + Jacobian_i[iVar][iVar] = Volume_nP1/TimeStep; + if (config->GetTime_Marching() == DT_STEPPING_2ND) + Jacobian_i[iVar][iVar] = (3.0*Volume_nP1)/(2.0*TimeStep); + } + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); + } + } + } + +} + + +void CTurbSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo) { + + /*--- Restart the solution from file information ---*/ + + unsigned short iVar, iMesh; + unsigned long iPoint, index, iChildren, Point_Fine; + su2double Area_Children, Area_Parent, *Solution_Fine; + + string restart_filename = config->GetFilename(config->GetSolution_FileName(), "", val_iter); + /*--- Read the restart data from either an ASCII or binary SU2 file. ---*/ + + if (config->GetRead_Binary_Restart()) { + Read_SU2_Restart_Binary(geometry[MESH_0], config, restart_filename); + } else { + Read_SU2_Restart_ASCII(geometry[MESH_0], config, restart_filename); + } + + int counter = 0; + long iPoint_Local = 0; unsigned long iPoint_Global = 0; + unsigned long iPoint_Global_Local = 0; + unsigned short rbuf_NotMatching = 0, sbuf_NotMatching = 0; + + /*--- Skip flow variables ---*/ + + unsigned short skipVars = 0; + + if (nDim == 2) skipVars += 6; + if (nDim == 3) skipVars += 8; + + /*--- Adjust the number of solution variables in the incompressible + restart. We always carry a space in nVar for the energy equation in the + mean flow solver, but we only write it to the restart if it is active. + Therefore, we must reduce skipVars here if energy is inactive so that + the turbulent variables are read correctly. ---*/ + + bool incompressible = (config->GetKind_Regime() == INCOMPRESSIBLE); + bool energy = config->GetEnergy_Equation(); + bool weakly_coupled_heat = config->GetWeakly_Coupled_Heat(); + + if (incompressible && ((!energy) && (!weakly_coupled_heat))) skipVars--; + + /*--- Load data from the restart into correct containers. ---*/ + + counter = 0; + for (iPoint_Global = 0; iPoint_Global < geometry[MESH_0]->GetGlobal_nPointDomain(); iPoint_Global++ ) { + + + /*--- Retrieve local index. If this node from the restart file lives + on the current processor, we will load and instantiate the vars. ---*/ + + iPoint_Local = geometry[MESH_0]->GetGlobal_to_Local_Point(iPoint_Global); + + if (iPoint_Local > -1) { + + /*--- We need to store this point's data, so jump to the correct + offset in the buffer of data from the restart file and load it. ---*/ + + index = counter*Restart_Vars[1] + skipVars; + for (iVar = 0; iVar < nVar; iVar++) Solution[iVar] = Restart_Data[index+iVar]; + nodes->SetSolution(iPoint_Local,Solution); + iPoint_Global_Local++; + + /*--- Increment the overall counter for how many points have been loaded. ---*/ + counter++; + } + + } + + /*--- Detect a wrong solution file ---*/ + + if (iPoint_Global_Local < nPointDomain) { sbuf_NotMatching = 1; } + +#ifndef HAVE_MPI + rbuf_NotMatching = sbuf_NotMatching; +#else + SU2_MPI::Allreduce(&sbuf_NotMatching, &rbuf_NotMatching, 1, MPI_UNSIGNED_SHORT, MPI_SUM, MPI_COMM_WORLD); +#endif + if (rbuf_NotMatching != 0) { + SU2_MPI::Error(string("The solution file ") + restart_filename + string(" doesn't match with the mesh file!\n") + + string("It could be empty lines at the end of the file."), CURRENT_FUNCTION); + } + + /*--- MPI solution and compute the eddy viscosity ---*/ + + solver[MESH_0][TURB_SOL]->InitiateComms(geometry[MESH_0], config, SOLUTION_EDDY); + solver[MESH_0][TURB_SOL]->CompleteComms(geometry[MESH_0], config, SOLUTION_EDDY); + + solver[MESH_0][FLOW_SOL]->Preprocessing(geometry[MESH_0], solver[MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); + solver[MESH_0][TURB_SOL]->Postprocessing(geometry[MESH_0], solver[MESH_0], config, MESH_0); + + /*--- Interpolate the solution down to the coarse multigrid levels ---*/ + + for (iMesh = 1; iMesh <= config->GetnMGLevels(); iMesh++) { + for (iPoint = 0; iPoint < geometry[iMesh]->GetnPoint(); iPoint++) { + Area_Parent = geometry[iMesh]->node[iPoint]->GetVolume(); + for (iVar = 0; iVar < nVar; iVar++) Solution[iVar] = 0.0; + for (iChildren = 0; iChildren < geometry[iMesh]->node[iPoint]->GetnChildren_CV(); iChildren++) { + Point_Fine = geometry[iMesh]->node[iPoint]->GetChildren_CV(iChildren); + Area_Children = geometry[iMesh-1]->node[Point_Fine]->GetVolume(); + Solution_Fine = solver[iMesh-1][TURB_SOL]->GetNodes()->GetSolution(Point_Fine); + for (iVar = 0; iVar < nVar; iVar++) { + Solution[iVar] += Solution_Fine[iVar]*Area_Children/Area_Parent; + } + } + solver[iMesh][TURB_SOL]->GetNodes()->SetSolution(iPoint,Solution); + } + solver[iMesh][TURB_SOL]->InitiateComms(geometry[iMesh], config, SOLUTION_EDDY); + solver[iMesh][TURB_SOL]->CompleteComms(geometry[iMesh], config, SOLUTION_EDDY); + solver[iMesh][FLOW_SOL]->Preprocessing(geometry[iMesh], solver[iMesh], config, iMesh, NO_RK_ITER, RUNTIME_FLOW_SYS, false); + solver[iMesh][TURB_SOL]->Postprocessing(geometry[iMesh], solver[iMesh], config, iMesh); + } + + /*--- Delete the class memory that is used to load the restart. ---*/ + + if (Restart_Vars != NULL) delete [] Restart_Vars; + if (Restart_Data != NULL) delete [] Restart_Data; + Restart_Vars = NULL; Restart_Data = NULL; + +} diff --git a/SU2_DEF/include/SU2_DEF.hpp b/SU2_DEF/include/SU2_DEF.hpp index ff0da4a73ad2..acf219517124 100644 --- a/SU2_DEF/include/SU2_DEF.hpp +++ b/SU2_DEF/include/SU2_DEF.hpp @@ -37,7 +37,7 @@ #include #include -#include "../../SU2_CFD/include/solver_structure.hpp" +#include "../../SU2_CFD/include/solvers/CSolver.hpp" #include "../../SU2_CFD/include/output/CMeshOutput.hpp" #include "../../Common/include/geometry/CPhysicalGeometry.hpp" #include "../../Common/include/config_structure.hpp" diff --git a/SU2_DEF/src/meson.build b/SU2_DEF/src/meson.build index 140cafadd3d6..2345213ee33e 100644 --- a/SU2_DEF/src/meson.build +++ b/SU2_DEF/src/meson.build @@ -1,7 +1,8 @@ su2_def_src = ['SU2_DEF.cpp'] if get_option('enable-normal') - su2_cfd_obj = su2_cfd.extract_objects(['solver_structure.cpp', + su2_cfd_obj = su2_cfd.extract_objects(['solvers/CSolver.cpp', + 'solvers/CBaselineSolver.cpp', 'CMarkerProfileReaderFVM.cpp', 'output/COutput.cpp', 'output/tools/CWindowingTools.cpp', diff --git a/SU2_DOT/include/SU2_DOT.hpp b/SU2_DOT/include/SU2_DOT.hpp index b2c2e4e28479..c09084fd5f4a 100644 --- a/SU2_DOT/include/SU2_DOT.hpp +++ b/SU2_DOT/include/SU2_DOT.hpp @@ -42,7 +42,7 @@ #include "../../Common/include/config_structure.hpp" #include "../../Common/include/grid_movement_structure.hpp" #include "../../SU2_CFD/include/output/CBaselineOutput.hpp" -#include "../../SU2_CFD/include/solver_structure.hpp" +#include "../../SU2_CFD/include/solvers/CBaselineSolver.hpp" using namespace std; diff --git a/SU2_DOT/src/meson.build b/SU2_DOT/src/meson.build index 702802b6a63c..a955902367e7 100644 --- a/SU2_DOT/src/meson.build +++ b/SU2_DOT/src/meson.build @@ -1,6 +1,7 @@ su2_dot_src = ['SU2_DOT.cpp'] if get_option('enable-normal') - su2_cfd_obj = su2_cfd.extract_objects(['solver_structure.cpp', + su2_cfd_obj = su2_cfd.extract_objects(['solvers/CSolver.cpp', + 'solvers/CBaselineSolver.cpp', 'CMarkerProfileReaderFVM.cpp', 'output/COutput.cpp', 'output/output_structure_legacy.cpp', @@ -21,8 +22,8 @@ if get_option('enable-normal') 'output/filewriter/CSU2FileWriter.cpp', 'output/filewriter/CSU2BinaryFileWriter.cpp', 'output/filewriter/CSU2MeshFileWriter.cpp', - 'variables/CBaselineVariable.cpp', - 'variables/CVariable.cpp']) + 'variables/CBaselineVariable.cpp', + 'variables/CVariable.cpp']) su2_dot = executable('SU2_DOT', su2_dot_src, @@ -35,35 +36,36 @@ endif if get_option('enable-autodiff') su2_dot_src_ad = ['SU2_DOT.cpp'] - su2_cfd_obj_ad = su2_cfd_ad.extract_objects(['solver_structure.cpp', - 'CMarkerProfileReaderFVM.cpp', - 'output/COutput.cpp', - 'output/tools/CWindowingTools.cpp', - 'output/output_structure_legacy.cpp', - 'output/CBaselineOutput.cpp', - 'output/filewriter/CParallelDataSorter.cpp', - 'output/filewriter/CParallelFileWriter.cpp', - 'output/filewriter/CFEMDataSorter.cpp', - 'output/filewriter/CSurfaceFEMDataSorter.cpp', - 'output/filewriter/CFVMDataSorter.cpp', - 'output/filewriter/CSurfaceFVMDataSorter.cpp', - 'output/filewriter/CCSVFileWriter.cpp', - 'output/filewriter/CSTLFileWriter.cpp', - 'output/filewriter/CTecplotFileWriter.cpp', - 'output/filewriter/CTecplotBinaryFileWriter.cpp', - 'output/filewriter/CParaviewFileWriter.cpp', - 'output/filewriter/CParaviewBinaryFileWriter.cpp', - 'output/filewriter/CSU2FileWriter.cpp', - 'output/filewriter/CSU2BinaryFileWriter.cpp', - 'output/filewriter/CSU2MeshFileWriter.cpp', - 'variables/CBaselineVariable.cpp', - 'variables/CVariable.cpp']) + su2_cfd_obj_ad = su2_cfd_ad.extract_objects(['solvers/CSolver.cpp', + 'solvers/CBaselineSolver.cpp', + 'CMarkerProfileReaderFVM.cpp', + 'output/COutput.cpp', + 'output/tools/CWindowingTools.cpp', + 'output/output_structure_legacy.cpp', + 'output/CBaselineOutput.cpp', + 'output/filewriter/CParallelDataSorter.cpp', + 'output/filewriter/CParallelFileWriter.cpp', + 'output/filewriter/CFEMDataSorter.cpp', + 'output/filewriter/CSurfaceFEMDataSorter.cpp', + 'output/filewriter/CFVMDataSorter.cpp', + 'output/filewriter/CSurfaceFVMDataSorter.cpp', + 'output/filewriter/CCSVFileWriter.cpp', + 'output/filewriter/CSTLFileWriter.cpp', + 'output/filewriter/CTecplotFileWriter.cpp', + 'output/filewriter/CTecplotBinaryFileWriter.cpp', + 'output/filewriter/CParaviewFileWriter.cpp', + 'output/filewriter/CParaviewBinaryFileWriter.cpp', + 'output/filewriter/CSU2FileWriter.cpp', + 'output/filewriter/CSU2BinaryFileWriter.cpp', + 'output/filewriter/CSU2MeshFileWriter.cpp', + 'variables/CBaselineVariable.cpp', + 'variables/CVariable.cpp']) su2_dot_ad = executable('SU2_DOT_AD', - su2_dot_src_ad, - install: true, - dependencies: [su2_deps, codi_dep, commonAD_dep], - objects : su2_cfd_obj_ad, - cpp_args : [default_warning_flags, su2_cpp_args, codi_rev_args]) + su2_dot_src_ad, + install: true, + dependencies: [su2_deps, codi_dep, commonAD_dep], + objects : su2_cfd_obj_ad, + cpp_args : [default_warning_flags, su2_cpp_args, codi_rev_args]) endif diff --git a/SU2_SOL/include/SU2_SOL.hpp b/SU2_SOL/include/SU2_SOL.hpp index 043ad6d7f547..c239a1cccbda 100644 --- a/SU2_SOL/include/SU2_SOL.hpp +++ b/SU2_SOL/include/SU2_SOL.hpp @@ -33,7 +33,8 @@ #include -#include "../../SU2_CFD/include/solver_structure.hpp" +#include "../../SU2_CFD/include/solvers/CBaselineSolver.hpp" +#include "../../SU2_CFD/include/solvers/CBaselineSolver_FEM.hpp" #include "../../SU2_CFD/include/output/CBaselineOutput.hpp" #include "../../Common/include/geometry/CPhysicalGeometry.hpp" #include "../../Common/include/config_structure.hpp" diff --git a/SU2_SOL/src/meson.build b/SU2_SOL/src/meson.build index 6144604d4eb5..9b9338508580 100644 --- a/SU2_SOL/src/meson.build +++ b/SU2_SOL/src/meson.build @@ -1,6 +1,8 @@ su2_sol_src = ['SU2_SOL.cpp'] if get_option('enable-normal') - su2_cfd_obj = su2_cfd.extract_objects(['solver_structure.cpp', + su2_cfd_obj = su2_cfd.extract_objects(['solvers/CSolver.cpp', + 'solvers/CBaselineSolver.cpp', + 'solvers/CBaselineSolver_FEM.cpp', 'CMarkerProfileReaderFVM.cpp', 'output/COutput.cpp', 'output/output_structure_legacy.cpp',