diff --git a/.clang-format b/.clang-format index cb363900eb6..211546de046 100644 --- a/.clang-format +++ b/.clang-format @@ -2,4 +2,4 @@ BasedOnStyle: Google PointerAlignment: Left DerivePointerAlignment: false ColumnLimit: 120 -SortIncludes: Never +SortIncludes: false diff --git a/AUTHORS.md b/AUTHORS.md index f47640de49a..f8c364f411b 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -71,6 +71,7 @@ Eduardo Molina Edwin van der Weide Ethan Alan Hereth Florian Dittmann +Filip Hahs Francesco Poli Francisco D. Palacios Gaurav Bansal diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index aab9decdb80..910be2231ac 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -71,7 +71,6 @@ class CConfig { unsigned short Kind_PerformanceAverageProcess; /*!< \brief Kind of mixing process.*/ unsigned short Kind_MixingPlaneInterface; /*!< \brief Kind of mixing process.*/ unsigned short Kind_SpanWise; /*!< \brief Kind of span-wise section computation.*/ - unsigned short *Kind_TurboMachinery; /*!< \brief Kind of turbomachynery architecture.*/ unsigned short iZone, nZone; /*!< \brief Number of zones in the mesh. */ unsigned short nZoneSpecified; /*!< \brief Number of zones that are specified in config file. */ su2double Highlite_Area; /*!< \brief Highlite area. */ @@ -435,6 +434,9 @@ class CConfig { Max_DeltaTime, /*!< \brief Max delta time. */ Unst_CFL; /*!< \brief Unsteady CFL number. */ + TURBO_PERF_KIND *Kind_TurboPerf; /*!< \brief Kind of turbomachynery architecture.*/ + TURBOMACHINERY_TYPE *Kind_TurboMachinery; + /* Gradient smoothing options */ su2double SmoothingEps1; /*!< \brief Parameter for the identity part in gradient smoothing. */ su2double SmoothingEps2; /*!< \brief Parameter for the Laplace part in gradient smoothing. */ @@ -1173,6 +1175,7 @@ class CConfig { string caseName; /*!< \brief Name of the current case */ unsigned long edgeColorGroupSize; /*!< \brief Size of the edge groups colored for OpenMP parallelization of edge loops. */ + bool edgeColoringRelaxDiscAdj; /*!< \brief Allow fallback to smaller edge color group sizes and use more colors for the discrete adjoint. */ INLET_SPANWISE_INTERP Kind_InletInterpolationFunction; /*!brief type of spanwise interpolation function to use for the inlet face. */ INLET_INTERP_TYPE Kind_Inlet_InterpolationType; /*!brief type of spanwise interpolation data to use for the inlet face. */ @@ -5117,7 +5120,7 @@ class CConfig { * \brief Get the kind of turbomachinery architecture. * \return Kind of turbomachinery architecture. */ - unsigned short GetKind_TurboMachinery(unsigned short val_iZone) const { return Kind_TurboMachinery[val_iZone]; } + TURBOMACHINERY_TYPE GetKind_TurboMachinery(unsigned short val_iZone) const { return Kind_TurboMachinery[val_iZone]; } /*! * \brief Get the kind of turbomachinery architecture. @@ -5232,7 +5235,7 @@ class CConfig { void SetnSpanWiseSections(unsigned short nSpan) { nSpanWiseSections = nSpan;} /*! - * \brief set number span-wise sections to compute 3D BC and performance for turbomachinery. + * \brief get number span-wise sections to compute 3D BC and performance for turbomachinery. */ unsigned short GetnSpan_iZones(unsigned short iZone) const { return nSpan_iZones[iZone];} @@ -5257,7 +5260,7 @@ class CConfig { * \brief get marker kind for Turbomachinery performance calculation. * \return kind index. */ - unsigned short GetKind_TurboPerf(unsigned short index); + TURBO_PERF_KIND GetKind_TurboPerf(unsigned short val_iZone) const { return Kind_TurboPerf[val_iZone]; }; /*! * \brief get outlet bounds name for Turbomachinery performance calculation. @@ -5910,6 +5913,15 @@ class CConfig { */ su2double GetMarkerTranslationRate(unsigned short iMarkerMoving, unsigned short iDim) const { return MarkerTranslation_Rate[3*iMarkerMoving + iDim];} + /*! + * \brief Set the translation rate of the marker. + * \param[in] iDim - spatial component + * \param[in] val - translational velocity + */ + void SetMarkerTranslationRate(unsigned short iMarkerMoving, unsigned short iDim, su2double val) { + MarkerTranslation_Rate[3 * iMarkerMoving + iDim] = val; + } + /*! * \brief Get the rotation rate of the mesh. * \param[in] iDim - spatial component @@ -5933,6 +5945,16 @@ class CConfig { */ su2double GetMarkerRotationRate(unsigned short iMarkerMoving, unsigned short iDim) const { return MarkerRotation_Rate[3*iMarkerMoving + iDim];} + /*! + * \brief Set the rotation rate of the marker. + * \param[in] iMarkerMoving - Index of the moving marker (as specified in Marker_Moving) + * \param[in] iDim - spatial component + * \param[in] val - Rotational velocity + */ + void SetMarkerRotationRate(unsigned short iMarkerMoving, unsigned short iDim, su2double val) { + MarkerRotation_Rate[3 * iMarkerMoving + iDim] = val; + } + /*! * \brief Get the pitching rate of the mesh. * \param[in] iDim - spatial component @@ -9641,6 +9663,11 @@ class CConfig { */ unsigned long GetEdgeColoringGroupSize(void) const { return edgeColorGroupSize; } + /*! + * \brief Check if the discrete adjoint is allowed to relax the coloring, that is, allow smaller edge color group sizes and allow more colors. + */ + bool GetEdgeColoringRelaxDiscAdj() const { return edgeColoringRelaxDiscAdj; } + /*! * \brief Get the ParMETIS load balancing tolerance. */ diff --git a/Common/include/geometry/CGeometry.hpp b/Common/include/geometry/CGeometry.hpp index f8111060725..adc7b800a81 100644 --- a/Common/include/geometry/CGeometry.hpp +++ b/Common/include/geometry/CGeometry.hpp @@ -772,6 +772,15 @@ class CGeometry { */ inline virtual void GatherInOutAverageValues(CConfig* config, bool allocate) {} + /*! + * \brief Store all the turboperformance in the solver in ZONE_0. + * \param[in] donor_geometry - Solution from the donor mesh. + * \param[in] target_geometry - Solution from the target mesh. + * \param[in] donorZone - counter of the donor solution + */ + inline virtual void SetAvgTurboGeoValues(const CConfig* donor_config, CGeometry* donor_geometry, + unsigned short donorZone){}; + /*! * \brief Set max length. * \param[in] config - Definition of the particular problem. @@ -1720,10 +1729,14 @@ class CGeometry { /*! * \brief Get the edge coloring. * \note This method computes the coloring if that has not been done yet. + * \note Can be instructed to determine and use the maximum edge color group size between 1 and + * CGeometry::edgeColorGroupSize that yields a coloring that is at least as efficient as #COLORING_EFF_THRESH. * \param[out] efficiency - optional output of the coloring efficiency. + * \param[in] maximizeEdgeColorGroupSize - use the maximum edge color group size that gives an efficient coloring. * \return Reference to the coloring. */ - const CCompressedSparsePatternUL& GetEdgeColoring(su2double* efficiency = nullptr); + const CCompressedSparsePatternUL& GetEdgeColoring(su2double* efficiency = nullptr, + bool maximizeEdgeColorGroupSize = false); /*! * \brief Force the natural (sequential) edge coloring. diff --git a/Common/include/geometry/CPhysicalGeometry.hpp b/Common/include/geometry/CPhysicalGeometry.hpp index 8e10bc2e685..740b0429bbd 100644 --- a/Common/include/geometry/CPhysicalGeometry.hpp +++ b/Common/include/geometry/CPhysicalGeometry.hpp @@ -408,6 +408,14 @@ class CPhysicalGeometry final : public CGeometry { */ void GatherInOutAverageValues(CConfig* config, bool allocate) override; + /*! + * \brief Store all the turboperformance in the solver in ZONE_0. + * \param[in] donor_geometry - Solution from the donor mesh. + * \param[in] target_geometry - Solution from the target mesh. + * \param[in] donorZone - counter of the donor solution + */ + void SetAvgTurboGeoValues(const CConfig* donor_config, CGeometry* donor_geometry, unsigned short donorZone) override; + /*! * \brief Set the edge structure of the control volume. * \param[in] config - Definition of the particular problem. diff --git a/Common/include/option_structure.hpp b/Common/include/option_structure.hpp index b26b4fcf699..a2b5f551525 100644 --- a/Common/include/option_structure.hpp +++ b/Common/include/option_structure.hpp @@ -1780,19 +1780,33 @@ static const MapType SpanWise_Map = { /*! * \brief Types of mixing process for averaging quantities at the boundaries. */ -enum TURBOMACHINERY_TYPE { - AXIAL = 1, /*!< \brief axial turbomachinery. */ - CENTRIFUGAL = 2, /*!< \brief centrifugal turbomachinery. */ - CENTRIPETAL = 3, /*!< \brief centripetal turbomachinery. */ - CENTRIPETAL_AXIAL = 4, /*!< \brief mixed flow turbine. */ - AXIAL_CENTRIFUGAL = 5 /*!< \brief mixed flow turbine. */ +enum class TURBOMACHINERY_TYPE { + AXIAL, /*!< \brief axial turbomachinery. */ + CENTRIFUGAL, /*!< \brief centrifugal turbomachinery. */ + CENTRIPETAL, /*!< \brief centripetal turbomachinery. */ + CENTRIPETAL_AXIAL, /*!< \brief mixed flow turbine. */ + AXIAL_CENTRIFUGAL /*!< \brief mixed flow turbine. */ }; static const MapType TurboMachinery_Map = { - MakePair("AXIAL", AXIAL) - MakePair("CENTRIFUGAL", CENTRIFUGAL) - MakePair("CENTRIPETAL", CENTRIPETAL) - MakePair("CENTRIPETAL_AXIAL", CENTRIPETAL_AXIAL) - MakePair("AXIAL_CENTRIFUGAL", AXIAL_CENTRIFUGAL) + MakePair("AXIAL", TURBOMACHINERY_TYPE::AXIAL) + MakePair("CENTRIFUGAL", TURBOMACHINERY_TYPE::CENTRIFUGAL) + MakePair("CENTRIPETAL", TURBOMACHINERY_TYPE::CENTRIPETAL) + MakePair("CENTRIPETAL_AXIAL", TURBOMACHINERY_TYPE::CENTRIPETAL_AXIAL) + MakePair("AXIAL_CENTRIFUGAL", TURBOMACHINERY_TYPE::AXIAL_CENTRIFUGAL) +}; + +/*! + * \brief Types of Turbomachinery performance Type. + */ +enum class TURBO_PERF_KIND{ + TURBINE, /*!< \brief Turbine Performance. */ + COMPRESSOR, /*!< \brief Compressor Performance. */ + PROPELLOR /*!< \brief Propellor Performance. */ +}; +static const MapType TurboPerfKind_Map = { + MakePair("TURBINE", TURBO_PERF_KIND::TURBINE) + MakePair("COMPRESSOR", TURBO_PERF_KIND::COMPRESSOR) + MakePair("PROPELLOR", TURBO_PERF_KIND::PROPELLOR) }; /*! diff --git a/Common/include/toolboxes/graph_toolbox.hpp b/Common/include/toolboxes/graph_toolbox.hpp index c5929e8f8da..f1c0854ce27 100644 --- a/Common/include/toolboxes/graph_toolbox.hpp +++ b/Common/include/toolboxes/graph_toolbox.hpp @@ -484,7 +484,7 @@ T createNaturalColoring(Index_t numInnerIndexes) { * \param[out] indexColor - Optional, vector with colors given to the outer indices. * \return Coloring in the same type of the input pattern. */ -template +template T colorSparsePattern(const T& pattern, size_t groupSize = 1, bool balanceColors = false, std::vector* indexColor = nullptr) { static_assert(std::is_integral::value, ""); diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index 35c66022926..86a0d31e456 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -1627,6 +1627,9 @@ void CConfig::SetConfig_Options() { /*!\brief TURBOMACHINERY_KIND \n DESCRIPTION: types of turbomachinery architecture. \n OPTIONS: see \link TurboMachinery_Map \endlink \n Default: AXIAL */ addEnumListOption("TURBOMACHINERY_KIND",nTurboMachineryKind, Kind_TurboMachinery, TurboMachinery_Map); + /*!\brief TURBOMACHINERY_KIND \n DESCRIPTION: types of turbomachynery Performance Calculations. + \n OPTIONS: see \link TurboPerfKind_Map \endlink \n Default: TURBINE */ + addEnumListOption("TURBO_PERF_KIND", nTurboMachineryKind, Kind_TurboPerf, TurboPerfKind_Map); /*!\brief MARKER_SHROUD \n DESCRIPTION: markers in which velocity is forced to 0.0. * \n Format: (shroud1, shroud2, ...)*/ addStringListOption("MARKER_SHROUD", nMarker_Shroud, Marker_Shroud); @@ -2924,6 +2927,9 @@ void CConfig::SetConfig_Options() { /* DESCRIPTION: Size of the edge groups colored for thread parallel edge loops (0 forces the reducer strategy). */ addUnsignedLongOption("EDGE_COLORING_GROUP_SIZE", edgeColorGroupSize, 512); + /* DESCRIPTION: Allow fallback to smaller edge color group sizes for the discrete adjoint and allow more colors. */ + addBoolOption("EDGE_COLORING_RELAX_DISC_ADJ", edgeColoringRelaxDiscAdj, true); + /*--- options that are used for libROM ---*/ /*!\par CONFIG_CATEGORY:libROM options \ingroup Config*/ @@ -4017,6 +4023,11 @@ void CConfig::SetPostprocessing(SU2_COMPONENT val_software, unsigned short val_i SU2_MPI::Error("Giles Boundary conditions can only be used with turbomachinery markers", CURRENT_FUNCTION); } + /*--- Check if turbomachinery performance kind is specified with turbo markers ---*/ + if (GetBoolTurbomachinery() && !(nTurboMachineryKind/nZone == 1)){ + SU2_MPI::Error("Insufficient TURBO_PERF_KIND options specified with turbomachinery markers", CURRENT_FUNCTION); + } + /*--- Check for Boundary condition available for NICFD ---*/ if ((!ideal_gas) && (!noneq_gas)) { @@ -6903,16 +6914,16 @@ void CConfig::SetOutput(SU2_COMPONENT val_software, unsigned short val_izone) { default: break; + } } - } - else { - if (Time_Domain) { - cout << "Dynamic structural analysis."<< endl; - cout << "Time step provided by the user for the dynamic analysis(s): "<< Time_Step << "." << endl; - } else { - cout << "Static structural analysis." << endl; + else { + if (Time_Domain) { + cout << "Dynamic structural analysis."<< endl; + cout << "Time step provided by the user for the dynamic analysis(s): "<< Time_Step << "." << endl; + } else { + cout << "Static structural analysis." << endl; + } } - } if ((Kind_Solver == MAIN_SOLVER::EULER) || (Kind_Solver == MAIN_SOLVER::NAVIER_STOKES) || (Kind_Solver == MAIN_SOLVER::RANS) || (Kind_Solver == MAIN_SOLVER::INC_EULER) || (Kind_Solver == MAIN_SOLVER::INC_NAVIER_STOKES) || (Kind_Solver == MAIN_SOLVER::INC_RANS) || diff --git a/Common/src/geometry/CGeometry.cpp b/Common/src/geometry/CGeometry.cpp index 9ed1804186a..aeca6421763 100644 --- a/Common/src/geometry/CGeometry.cpp +++ b/Common/src/geometry/CGeometry.cpp @@ -3609,7 +3609,7 @@ const su2vector& CGeometry::GetTransposeSparsePatternMap(Connecti return pattern.transposePtr(); } -const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficiency) { +const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficiency, bool maximizeEdgeColorGroupSize) { /*--- Check for dry run mode with dummy geometry. ---*/ if (nEdge == 0) return edgeColoring; @@ -3637,7 +3637,60 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien /*--- Color the edges. ---*/ constexpr bool balanceColors = true; - edgeColoring = colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); + + /*--- If requested, find an efficient coloring with maximum color group size (up to edgeColorGroupSize). ---*/ + if (maximizeEdgeColorGroupSize) { + auto upperEdgeColorGroupSize = edgeColorGroupSize + 1; /* upper bound that is deemed too large */ + auto nextEdgeColorGroupSize = edgeColorGroupSize; /* next value that we are going to try */ + auto lowerEdgeColorGroupSize = 1ul; /* lower bound that is known to work */ + + bool admissibleColoring = false; /* keep track wether the last tested coloring is admissible */ + + while (true) { + edgeColoring = colorSparsePattern(pattern, nextEdgeColorGroupSize, balanceColors); + + /*--- If the coloring fails, reduce the color group size. ---*/ + if (edgeColoring.empty()) { + upperEdgeColorGroupSize = nextEdgeColorGroupSize; + admissibleColoring = false; + } + /*--- If the coloring succeeds, check the efficiency. ---*/ + else { + const su2double currentEfficiency = + coloringEfficiency(edgeColoring, omp_get_max_threads(), nextEdgeColorGroupSize); + + /*--- If the coloring is not efficient, reduce the color group size. ---*/ + if (currentEfficiency < COLORING_EFF_THRESH) { + upperEdgeColorGroupSize = nextEdgeColorGroupSize; + admissibleColoring = false; + } + /*--- Otherwise, enlarge the color group size. ---*/ + else { + lowerEdgeColorGroupSize = nextEdgeColorGroupSize; + admissibleColoring = true; + } + } + + const auto increment = (upperEdgeColorGroupSize - lowerEdgeColorGroupSize) / 2; + nextEdgeColorGroupSize = lowerEdgeColorGroupSize + increment; + + /*--- Terminating condition. ---*/ + if (increment == 0) { + break; + } + } + + edgeColorGroupSize = nextEdgeColorGroupSize; + + /*--- If the last tested coloring was not admissible, recompute the final coloring. ---*/ + if (!admissibleColoring) { + edgeColoring = colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); + } + } + /*--- No adaptivity. ---*/ + else { + edgeColoring = colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); + } /*--- If the coloring fails use the natural coloring. This is a * "soft" failure as this "bad" coloring should be detected diff --git a/Common/src/geometry/CPhysicalGeometry.cpp b/Common/src/geometry/CPhysicalGeometry.cpp index 54d667e0fbd..8be327af7a7 100644 --- a/Common/src/geometry/CPhysicalGeometry.cpp +++ b/Common/src/geometry/CPhysicalGeometry.cpp @@ -4830,23 +4830,23 @@ void CPhysicalGeometry::ComputeNSpan(CConfig* config, unsigned short val_iZone, coord = nodes->GetCoord(iPoint); radius = sqrt(coord[0] * coord[0] + coord[1] * coord[1]); switch (config->GetKind_TurboMachinery(val_iZone)) { - case CENTRIFUGAL: + case TURBOMACHINERY_TYPE::CENTRIFUGAL: valueSpan[nSpan_loc] = coord[2]; break; - case CENTRIPETAL: + case TURBOMACHINERY_TYPE::CENTRIPETAL: valueSpan[nSpan_loc] = coord[2]; break; - case AXIAL: + case TURBOMACHINERY_TYPE::AXIAL: valueSpan[nSpan_loc] = radius; break; - case CENTRIPETAL_AXIAL: + case TURBOMACHINERY_TYPE::CENTRIPETAL_AXIAL: if (marker_flag == OUTFLOW) { valueSpan[nSpan_loc] = radius; } else { valueSpan[nSpan_loc] = coord[2]; } break; - case AXIAL_CENTRIFUGAL: + case TURBOMACHINERY_TYPE::AXIAL_CENTRIFUGAL: if (marker_flag == INFLOW) { valueSpan[nSpan_loc] = radius; } else { @@ -4922,16 +4922,16 @@ void CPhysicalGeometry::ComputeNSpan(CConfig* config, unsigned short val_iZone, coord = nodes->GetCoord(iPoint); radius = sqrt(coord[0] * coord[0] + coord[1] * coord[1]); switch (config->GetKind_TurboMachinery(val_iZone)) { - case CENTRIFUGAL: - case CENTRIPETAL: + case TURBOMACHINERY_TYPE::CENTRIFUGAL: + case TURBOMACHINERY_TYPE::CENTRIPETAL: if (coord[2] < min) min = coord[2]; if (coord[2] > max) max = coord[2]; break; - case AXIAL: + case TURBOMACHINERY_TYPE::AXIAL: if (radius < min) min = radius; if (radius > max) max = radius; break; - case CENTRIPETAL_AXIAL: + case TURBOMACHINERY_TYPE::CENTRIPETAL_AXIAL: if (marker_flag == OUTFLOW) { if (radius < min) min = radius; if (radius > max) max = radius; @@ -4940,7 +4940,7 @@ void CPhysicalGeometry::ComputeNSpan(CConfig* config, unsigned short val_iZone, if (coord[2] > max) max = coord[2]; } break; - case AXIAL_CENTRIFUGAL: + case TURBOMACHINERY_TYPE::AXIAL_CENTRIFUGAL: if (marker_flag == INFLOW) { if (radius < min) min = radius; if (radius > max) max = radius; @@ -5094,8 +5094,8 @@ void CPhysicalGeometry::SetTurboVertex(CConfig* config, unsigned short val_iZone coord = nodes->GetCoord(iPoint); switch (config->GetKind_TurboMachinery(val_iZone)) { - case CENTRIFUGAL: - case CENTRIPETAL: + case TURBOMACHINERY_TYPE::CENTRIFUGAL: + case TURBOMACHINERY_TYPE::CENTRIPETAL: for (iSpan = 0; iSpan < nSpanWiseSections[marker_flag - 1]; iSpan++) { if (dist > (abs(coord[2] - SpanWiseValue[marker_flag - 1][iSpan]))) { dist = abs(coord[2] - SpanWiseValue[marker_flag - 1][iSpan]); @@ -5103,7 +5103,7 @@ void CPhysicalGeometry::SetTurboVertex(CConfig* config, unsigned short val_iZone } } break; - case AXIAL: + case TURBOMACHINERY_TYPE::AXIAL: radius = sqrt(coord[0] * coord[0] + coord[1] * coord[1]); for (iSpan = 0; iSpan < nSpanWiseSections[marker_flag - 1]; iSpan++) { if (dist > (abs(radius - SpanWiseValue[marker_flag - 1][iSpan]))) { @@ -5112,7 +5112,7 @@ void CPhysicalGeometry::SetTurboVertex(CConfig* config, unsigned short val_iZone } } break; - case CENTRIPETAL_AXIAL: + case TURBOMACHINERY_TYPE::CENTRIPETAL_AXIAL: if (marker_flag == OUTFLOW) { radius = sqrt(coord[0] * coord[0] + coord[1] * coord[1]); for (iSpan = 0; iSpan < nSpanWiseSections[marker_flag - 1]; iSpan++) { @@ -5131,7 +5131,7 @@ void CPhysicalGeometry::SetTurboVertex(CConfig* config, unsigned short val_iZone } break; - case AXIAL_CENTRIFUGAL: + case TURBOMACHINERY_TYPE::AXIAL_CENTRIFUGAL: if (marker_flag == INFLOW) { radius = sqrt(coord[0] * coord[0] + coord[1] * coord[1]); for (iSpan = 0; iSpan < nSpanWiseSections[marker_flag - 1]; iSpan++) { @@ -5194,8 +5194,8 @@ void CPhysicalGeometry::SetTurboVertex(CConfig* config, unsigned short val_iZone coord = nodes->GetCoord(iPoint); switch (config->GetKind_TurboMachinery(val_iZone)) { - case CENTRIFUGAL: - case CENTRIPETAL: + case TURBOMACHINERY_TYPE::CENTRIFUGAL: + case TURBOMACHINERY_TYPE::CENTRIPETAL: for (iSpan = 0; iSpan < nSpanWiseSections[marker_flag - 1]; iSpan++) { if (dist > (abs(coord[2] - SpanWiseValue[marker_flag - 1][iSpan]))) { dist = abs(coord[2] - SpanWiseValue[marker_flag - 1][iSpan]); @@ -5203,7 +5203,7 @@ void CPhysicalGeometry::SetTurboVertex(CConfig* config, unsigned short val_iZone } } break; - case AXIAL: + case TURBOMACHINERY_TYPE::AXIAL: radius = sqrt(coord[0] * coord[0] + coord[1] * coord[1]); for (iSpan = 0; iSpan < nSpanWiseSections[marker_flag - 1]; iSpan++) { if (dist > (abs(radius - SpanWiseValue[marker_flag - 1][iSpan]))) { @@ -5212,7 +5212,7 @@ void CPhysicalGeometry::SetTurboVertex(CConfig* config, unsigned short val_iZone } } break; - case CENTRIPETAL_AXIAL: + case TURBOMACHINERY_TYPE::CENTRIPETAL_AXIAL: if (marker_flag == OUTFLOW) { radius = sqrt(coord[0] * coord[0] + coord[1] * coord[1]); for (iSpan = 0; iSpan < nSpanWiseSections[marker_flag - 1]; iSpan++) { @@ -5231,7 +5231,7 @@ void CPhysicalGeometry::SetTurboVertex(CConfig* config, unsigned short val_iZone } break; - case AXIAL_CENTRIFUGAL: + case TURBOMACHINERY_TYPE::AXIAL_CENTRIFUGAL: if (marker_flag == INFLOW) { radius = sqrt(coord[0] * coord[0] + coord[1] * coord[1]); for (iSpan = 0; iSpan < nSpanWiseSections[marker_flag - 1]; iSpan++) { @@ -5285,7 +5285,7 @@ void CPhysicalGeometry::SetTurboVertex(CConfig* config, unsigned short val_iZone /*--- find nodes at minimum pitch among all nodes---*/ if (coord[1] < min) { min = coord[1]; - if (nDim == 2 && config->GetKind_TurboMachinery(val_iZone) == AXIAL) { + if (nDim == 2 && config->GetKind_TurboMachinery(val_iZone) == TURBOMACHINERY_TYPE::AXIAL) { MinAngularCoord[iMarker][iSpan] = coord[1]; } else { MinAngularCoord[iMarker][iSpan] = atan(coord[1] / coord[0]); @@ -5298,7 +5298,7 @@ void CPhysicalGeometry::SetTurboVertex(CConfig* config, unsigned short val_iZone if (coord[1] < minInt) { if (nodes->GetDomain(iPoint)) { minInt = coord[1]; - if (nDim == 2 && config->GetKind_TurboMachinery(val_iZone) == AXIAL) { + if (nDim == 2 && config->GetKind_TurboMachinery(val_iZone) == TURBOMACHINERY_TYPE::AXIAL) { minIntAngPitch[iSpan] = coord[1]; } else { minIntAngPitch[iSpan] = atan(coord[1] / coord[0]); @@ -5310,7 +5310,7 @@ void CPhysicalGeometry::SetTurboVertex(CConfig* config, unsigned short val_iZone if (coord[1] > max) { if (nodes->GetDomain(iPoint)) { max = coord[1]; - if (nDim == 2 && config->GetKind_TurboMachinery(val_iZone) == AXIAL) { + if (nDim == 2 && config->GetKind_TurboMachinery(val_iZone) == TURBOMACHINERY_TYPE::AXIAL) { MaxAngularCoord[iMarker][iSpan] = coord[1]; } else { MaxAngularCoord[iMarker][iSpan] = atan(coord[1] / coord[0]); @@ -5329,7 +5329,7 @@ void CPhysicalGeometry::SetTurboVertex(CConfig* config, unsigned short val_iZone checkAssign[iSpan][kSpanVertex] = true; coord = nodes->GetCoord(ordered[iSpan][iSpanVertex]); target = coord[1]; - if (nDim == 2 && config->GetKind_TurboMachinery(val_iZone) == AXIAL) { + if (nDim == 2 && config->GetKind_TurboMachinery(val_iZone) == TURBOMACHINERY_TYPE::AXIAL) { angPitch[iSpan][iSpanVertex] = coord[1]; } else { angPitch[iSpan][iSpanVertex] = atan(coord[1] / coord[0]); @@ -5350,7 +5350,7 @@ void CPhysicalGeometry::SetTurboVertex(CConfig* config, unsigned short val_iZone turbovertex[iMarker][iSpan][iInternalVertex]->SetAngularCoord(angPitch[iSpan][iSpanVertex]); turbovertex[iMarker][iSpan][iInternalVertex]->SetDeltaAngularCoord(deltaAngPitch[iSpan][iSpanVertex]); switch (config->GetKind_TurboMachinery(val_iZone)) { - case CENTRIFUGAL: + case TURBOMACHINERY_TYPE::CENTRIFUGAL: Normal2 = 0.0; for (iDim = 0; iDim < 2; iDim++) Normal2 += coord[iDim] * coord[iDim]; if (marker_flag == INFLOW) { @@ -5363,7 +5363,7 @@ void CPhysicalGeometry::SetTurboVertex(CConfig* config, unsigned short val_iZone TurboNormal[2] = 0.0; } break; - case CENTRIPETAL: + case TURBOMACHINERY_TYPE::CENTRIPETAL: Normal2 = 0.0; for (iDim = 0; iDim < 2; iDim++) Normal2 += coord[iDim] * coord[iDim]; if (marker_flag == OUTFLOW) { @@ -5376,7 +5376,7 @@ void CPhysicalGeometry::SetTurboVertex(CConfig* config, unsigned short val_iZone TurboNormal[2] = 0.0; } break; - case AXIAL: + case TURBOMACHINERY_TYPE::AXIAL: Normal2 = 0.0; for (iDim = 0; iDim < 2; iDim++) Normal2 += coord[iDim] * coord[iDim]; if (nDim == 3) { @@ -5402,7 +5402,7 @@ void CPhysicalGeometry::SetTurboVertex(CConfig* config, unsigned short val_iZone } break; - case CENTRIPETAL_AXIAL: + case TURBOMACHINERY_TYPE::CENTRIPETAL_AXIAL: Normal2 = 0.0; for (iDim = 0; iDim < 2; iDim++) Normal2 += coord[iDim] * coord[iDim]; if (marker_flag == INFLOW) { @@ -5416,7 +5416,7 @@ void CPhysicalGeometry::SetTurboVertex(CConfig* config, unsigned short val_iZone } break; - case AXIAL_CENTRIFUGAL: + case TURBOMACHINERY_TYPE::AXIAL_CENTRIFUGAL: Normal2 = 0.0; for (iDim = 0; iDim < 2; iDim++) Normal2 += coord[iDim] * coord[iDim]; if (marker_flag == INFLOW) { @@ -5720,7 +5720,7 @@ void CPhysicalGeometry::SetTurboVertex(CConfig* config, unsigned short val_iZone myfile << z_loc[iSpan][iSpanVertex]; myfile.width(20); myfile << radius; - if (nDim == 2 && config->GetKind_TurboMachinery(val_iZone)) { + if (nDim == 2) { myfile.width(20); myfile << angCoord_loc[iSpan][iSpanVertex]; myfile.width(20); @@ -5788,7 +5788,7 @@ void CPhysicalGeometry::UpdateTurboVertex(CConfig* config, unsigned short val_iZ coord = nodes->GetCoord(iPoint); /*--- compute appropriate turbo normal ---*/ switch (config->GetKind_TurboMachinery(val_iZone)) { - case CENTRIFUGAL: + case TURBOMACHINERY_TYPE::CENTRIFUGAL: Normal2 = 0.0; for (iDim = 0; iDim < 2; iDim++) Normal2 += coord[iDim] * coord[iDim]; if (marker_flag == INFLOW) { @@ -5801,7 +5801,7 @@ void CPhysicalGeometry::UpdateTurboVertex(CConfig* config, unsigned short val_iZ TurboNormal[2] = 0.0; } break; - case CENTRIPETAL: + case TURBOMACHINERY_TYPE::CENTRIPETAL: Normal2 = 0.0; for (iDim = 0; iDim < 2; iDim++) Normal2 += coord[iDim] * coord[iDim]; if (marker_flag == OUTFLOW) { @@ -5814,7 +5814,7 @@ void CPhysicalGeometry::UpdateTurboVertex(CConfig* config, unsigned short val_iZ TurboNormal[2] = 0.0; } break; - case AXIAL: + case TURBOMACHINERY_TYPE::AXIAL: Normal2 = 0.0; for (iDim = 0; iDim < 2; iDim++) Normal2 += coord[iDim] * coord[iDim]; if (nDim == 3) { @@ -5840,7 +5840,7 @@ void CPhysicalGeometry::UpdateTurboVertex(CConfig* config, unsigned short val_iZ } break; - case CENTRIPETAL_AXIAL: + case TURBOMACHINERY_TYPE::CENTRIPETAL_AXIAL: Normal2 = 0.0; for (iDim = 0; iDim < 2; iDim++) Normal2 += coord[iDim] * coord[iDim]; if (marker_flag == INFLOW) { @@ -5854,7 +5854,7 @@ void CPhysicalGeometry::UpdateTurboVertex(CConfig* config, unsigned short val_iZ } break; - case AXIAL_CENTRIFUGAL: + case TURBOMACHINERY_TYPE::AXIAL_CENTRIFUGAL: Normal2 = 0.0; for (iDim = 0; iDim < 2; iDim++) Normal2 += coord[iDim] * coord[iDim]; if (marker_flag == INFLOW) { @@ -6030,8 +6030,8 @@ void CPhysicalGeometry::SetAvgTurboValue(CConfig* config, unsigned short val_iZo AverageGridVel[iMarker][iSpan][iDim] = TotalGridVel[iDim] / nTotVertexSpan[iMarker][iSpan]; } switch (config->GetKind_TurboMachinery(val_iZone)) { - case CENTRIFUGAL: - case CENTRIPETAL: + case TURBOMACHINERY_TYPE::CENTRIFUGAL: + case TURBOMACHINERY_TYPE::CENTRIPETAL: if (marker_flag == INFLOW) { AverageTangGridVel[iMarker][iSpan] = -(AverageTurboNormal[iMarker][iSpan][0] * AverageGridVel[iMarker][iSpan][1] - @@ -6042,7 +6042,7 @@ void CPhysicalGeometry::SetAvgTurboValue(CConfig* config, unsigned short val_iZo AverageTurboNormal[iMarker][iSpan][1] * AverageGridVel[iMarker][iSpan][0]; } break; - case AXIAL: + case TURBOMACHINERY_TYPE::AXIAL: if (marker_flag == INFLOW && nDim == 2) { AverageTangGridVel[iMarker][iSpan] = -AverageTurboNormal[iMarker][iSpan][0] * AverageGridVel[iMarker][iSpan][1] + @@ -6053,7 +6053,7 @@ void CPhysicalGeometry::SetAvgTurboValue(CConfig* config, unsigned short val_iZo AverageTurboNormal[iMarker][iSpan][1] * AverageGridVel[iMarker][iSpan][0]; } break; - case CENTRIPETAL_AXIAL: + case TURBOMACHINERY_TYPE::CENTRIPETAL_AXIAL: if (marker_flag == OUTFLOW) { AverageTangGridVel[iMarker][iSpan] = (AverageTurboNormal[iMarker][iSpan][0] * AverageGridVel[iMarker][iSpan][1] - @@ -6064,7 +6064,7 @@ void CPhysicalGeometry::SetAvgTurboValue(CConfig* config, unsigned short val_iZo AverageTurboNormal[iMarker][iSpan][1] * AverageGridVel[iMarker][iSpan][0]); } break; - case AXIAL_CENTRIFUGAL: + case TURBOMACHINERY_TYPE::AXIAL_CENTRIFUGAL: if (marker_flag == INFLOW) { AverageTangGridVel[iMarker][iSpan] = AverageTurboNormal[iMarker][iSpan][0] * AverageGridVel[iMarker][iSpan][1] - @@ -6289,7 +6289,7 @@ void CPhysicalGeometry::GatherInOutAverageValues(CConfig* config, bool allocate) if (iSpan == nSpanWiseSections) { config->SetFreeStreamTurboNormal(turboNormal); - if (config->GetKind_TurboMachinery(config->GetiZone()) == AXIAL && nDim == 2) { + if (config->GetKind_TurboMachinery(config->GetiZone()) == TURBOMACHINERY_TYPE::AXIAL && nDim == 2) { nBlades = 1 / Pitch; } else { nBlades = 2 * PI_NUMBER / Pitch; @@ -6311,6 +6311,21 @@ void CPhysicalGeometry::GatherInOutAverageValues(CConfig* config, bool allocate) delete[] turboNormal; } +void CPhysicalGeometry::SetAvgTurboGeoValues(const CConfig* donor_config, CGeometry* donor_geometry, + unsigned short donorZone) { + unsigned short iSpan; + unsigned short nSpanMaxAllZones = donor_config->GetnSpanMaxAllZones(); + + for (iSpan = 0; iSpan < nSpanMaxAllZones + 1; iSpan++) { + SetTurboRadiusIn(donor_geometry->GetTurboRadiusIn(donorZone, iSpan), donorZone, iSpan); + SetSpanAreaIn(donor_geometry->GetSpanAreaIn(donorZone, iSpan), donorZone, iSpan); + SetTangGridVelIn(donor_geometry->GetTangGridVelIn(donorZone, iSpan), donorZone, iSpan); + SetTurboRadiusOut(donor_geometry->GetTurboRadiusOut(donorZone, iSpan), donorZone, iSpan); + SetSpanAreaOut(donor_geometry->GetSpanAreaOut(donorZone, iSpan), donorZone, iSpan); + SetTangGridVelOut(donor_geometry->GetTangGridVelOut(donorZone, iSpan), donorZone, iSpan); + } +} + void CPhysicalGeometry::SetMaxLength(CConfig* config) { SU2_OMP_FOR_STAT(roundUpDiv(nPointDomain, omp_get_max_threads())) for (unsigned long iPoint = 0; iPoint < nPointDomain; iPoint++) { diff --git a/SU2_CFD/include/drivers/CDriver.hpp b/SU2_CFD/include/drivers/CDriver.hpp index 5ac33896849..a6983857dcb 100644 --- a/SU2_CFD/include/drivers/CDriver.hpp +++ b/SU2_CFD/include/drivers/CDriver.hpp @@ -290,9 +290,10 @@ class CDriver : public CDriverBase { * \param[in] geometry - Geometrical definition of the problem. * \param[in] solver - Container vector with all the solutions. * \param[in] interface - Class defining the physical transfer of information. + * \param[in] dummy - Definition of dummy driver */ void PreprocessTurbomachinery(CConfig** config, CGeometry**** geometry, CSolver***** solver, - CInterface*** interface); + CInterface*** interface, bool dummy); /*! * \brief Ramp some simulation settings for turbomachinery problems. @@ -536,6 +537,24 @@ class CDriver : public CDriverBase { */ void SetRotationRate(passivedouble rot_x, passivedouble rot_y, passivedouble rot_z); + /*! + * \brief Set the moving wall marker rotation rates. + * \param[in] iMaker - Index of moving wall marker. + * \param[in] rot_x - Value of Angular velocity about x-axes. + * \param[in] rot_y - Value of Angular velocity about y-axes. + * \param[in] rot_z - Value of Angular velocity about z-axes. + */ + void SetMarkerRotationRate(unsigned short iMarker, passivedouble rot_x, passivedouble rot_y, passivedouble rot_z); + + /*! + * \brief Set the moving wall marker translation rates. + * \param[in] iMaker - Index of moving wall marker. + * \param[in] vel_x - Value of velocity along x-axis. + * \param[in] vel_y - Value of velocity along y-axis. + * \param[in] vel_z - Value of velocity along z-axis. + */ + void SetMarkerTranslationRate(unsigned short iMarker, passivedouble vel_x, passivedouble vel_y, passivedouble vel_z); + /// \} }; diff --git a/SU2_CFD/include/drivers/CMultizoneDriver.hpp b/SU2_CFD/include/drivers/CMultizoneDriver.hpp index 9779f0dc410..621c7288ce1 100644 --- a/SU2_CFD/include/drivers/CMultizoneDriver.hpp +++ b/SU2_CFD/include/drivers/CMultizoneDriver.hpp @@ -83,10 +83,6 @@ class CMultizoneDriver : public CDriver { */ bool TransferData(unsigned short donorZone, unsigned short targetZone); - /*! - * \brief Set Mixing Plane interface within multiple zones. - */ - void SetMixingPlane(unsigned short donorZone); /*! * \brief Transfer the local turboperfomance quantities (for each blade row) from all the donorZones to the diff --git a/SU2_CFD/include/interfaces/CInterface.hpp b/SU2_CFD/include/interfaces/CInterface.hpp index 7830e091085..b65db7196b5 100644 --- a/SU2_CFD/include/interfaces/CInterface.hpp +++ b/SU2_CFD/include/interfaces/CInterface.hpp @@ -219,13 +219,4 @@ class CInterface { */ void GatherAverageValues(CSolver *donor_solution, CSolver *target_solution, unsigned short donorZone); - /*! - * \brief Exchange Average geometrical value beteween zones . - * \param[in] donor_geometry - Geometry of the donor mesh. - * \param[in] target_geometry - Geometry of the target mesh. - * \param[in] donor_config - Definition of the problem at the donor mesh. - * \param[in] target_config - Definition of the problem at the target mesh. - */ - void GatherAverageTurboGeoValues(CGeometry *donor_geometry, CGeometry *target_geometry, unsigned short donorZone); - }; diff --git a/SU2_CFD/include/interfaces/cfd/CMixingPlaneInterface.hpp b/SU2_CFD/include/interfaces/cfd/CMixingPlaneInterface.hpp index 8eb2ee0aa0f..80c19db9b6b 100644 --- a/SU2_CFD/include/interfaces/cfd/CMixingPlaneInterface.hpp +++ b/SU2_CFD/include/interfaces/cfd/CMixingPlaneInterface.hpp @@ -81,14 +81,6 @@ class CMixingPlaneInterface : public CInterface { */ void SetAverageValues(CSolver *donor_solution, CSolver *target_solution, unsigned short donorZone) override; - /*! - * \brief Store all the turboperformance in the solver in ZONE_0. - * \param[in] donor_geometry - Solution from the donor mesh. - * \param[in] target_geometry - Solution from the target mesh. - * \param[in] donorZone - counter of the donor solution - */ - void SetAverageTurboGeoValues(CGeometry *donor_geometry, CGeometry *target_geometry, unsigned short donorZone) override; - }; diff --git a/SU2_CFD/include/iteration/CFluidIteration.hpp b/SU2_CFD/include/iteration/CFluidIteration.hpp index c960b635e35..f8f0f72c624 100644 --- a/SU2_CFD/include/iteration/CFluidIteration.hpp +++ b/SU2_CFD/include/iteration/CFluidIteration.hpp @@ -107,6 +107,16 @@ class CFluidIteration : public CIteration { CVolumetricMovement*** grid_movement, CFreeFormDefBox*** FFDBox, unsigned short val_iZone, unsigned short val_iInst) override; + /*! + * \brief Monitors turbo computation (pressure and turbo ramps). + */ + void TurboMonitor(CGeometry**** geometry_container, CConfig** config_container, unsigned long ExtIter); + + /*! + * \brief Computes turboperformance. + */ + void ComputeTurboPerformance(CSolver***** solver, CGeometry**** geometry_container, CConfig** config_container, unsigned long ExtIter); + /*! * \brief Postprocesses the fluid system before heading to another physics system or the next iteration. * \param[in] solver - Container vector with all the solutions. diff --git a/SU2_CFD/include/iteration/CIteration.hpp b/SU2_CFD/include/iteration/CIteration.hpp index da807245967..483712a8a16 100644 --- a/SU2_CFD/include/iteration/CIteration.hpp +++ b/SU2_CFD/include/iteration/CIteration.hpp @@ -35,6 +35,7 @@ #include "../../../Common/include/grid_movement/CFreeFormDefBox.hpp" #include "../../../Common/include/parallelization/mpi_structure.hpp" #include "../integration/CIntegration.hpp" +#include "../output/CTurboOutput.hpp" using namespace std; @@ -59,6 +60,9 @@ class CIteration { su2double StartTime{0.0}, /*!< \brief Tracking wall time. */ StopTime{0.0}, UsedTime{0.0}; + std::shared_ptr TurbomachineryPerformance; /*!< \brief turbo performance calculator. */ + CTurbomachineryStagePerformance* TurbomachineryStagePerformance; /*!< \brief turbo stage performance calculator. */ + public: /*! * \brief Constructor of the class. @@ -247,7 +251,6 @@ class CIteration { unsigned short val_iInst) { return false; } - /*! * \brief A virtual member. * \param[in] output - Pointer to the COutput class. diff --git a/SU2_CFD/include/iteration/CTurboIteration.hpp b/SU2_CFD/include/iteration/CTurboIteration.hpp index 438e23bfd1d..4b4d9adad04 100644 --- a/SU2_CFD/include/iteration/CTurboIteration.hpp +++ b/SU2_CFD/include/iteration/CTurboIteration.hpp @@ -63,4 +63,9 @@ class CTurboIteration : public CFluidIteration { CNumerics****** numerics, CConfig** config, CSurfaceMovement** surface_movement, CVolumetricMovement*** grid_movement, CFreeFormDefBox*** FFDBox, unsigned short val_iZone, unsigned short val_iInst) override; + + /*! + * \brief Initialises turboperformance classes. + */ + void InitTurboPerformance(CGeometry *geometry, CConfig** config, CFluidModel *fluid); }; diff --git a/SU2_CFD/include/output/CFlowCompOutput.hpp b/SU2_CFD/include/output/CFlowCompOutput.hpp index e458e78b161..9b624d4bfee 100644 --- a/SU2_CFD/include/output/CFlowCompOutput.hpp +++ b/SU2_CFD/include/output/CFlowCompOutput.hpp @@ -92,4 +92,40 @@ class CFlowCompOutput final: public CFlowOutput { * \param[in] config - Definition of the particular problem. */ bool WriteHistoryFileOutput(const CConfig *config) override ; + + /*! + * \brief Sets the turboperformance screen output + * \param[in] TurboPerf - Turboperformance class + * \param[in] config - Definition of the particular problem + * \param[in] TimeIter - Index of the current time-step + * \param[in] OuterIter - Index of current outer iteration + * \param[in] InnerIter - Index of current inner iteration + */ + void SetTurboPerformance_Output(std::shared_ptr TurboPerf, CConfig *config, unsigned long TimeIter, unsigned long OuterIter, unsigned long InnerIter) override; + + /*! + * \brief Sets the multizone turboperformacne screen output + * \param[in] TurboStagePerf - Stage turboperformance class + * \param[in] TurboPerf - Turboperformance class + * \param[in] config - Definition of the particular problem + */ + void SetTurboMultiZonePerformance_Output(CTurbomachineryStagePerformance* TurboStagePerf, std::shared_ptr TurboPerf, CConfig *config) override; + + /*! + * \brief Loads the turboperformacne history data + * \param[in] TurboStagePerf - Stage turboperformance class + * \param[in] TurboPerf - Turboperformance class + * \param[in] config - Definition of the particular problem + */ + void LoadTurboHistoryData(CTurbomachineryStagePerformance* TurboStagePerf, std::shared_ptr TurboPerf, CConfig *config) override; + + /*! + * \brief Write the kinematic and thermodynamic variables at each spanwise division + * \param[in] TurboPerf - Turboperformance class + * \param[in] geometry - Geometrical definiton of the problem + * \param[in] config - Descripiton of the particular problem + * \param[in] val_iZone - Idientifier of current zone + */ + void WriteTurboSpanwisePerformance(std::shared_ptr TurboPerf, CGeometry *geometry, CConfig **config, + unsigned short val_iZone) override; }; diff --git a/SU2_CFD/include/output/CFlowOutput.hpp b/SU2_CFD/include/output/CFlowOutput.hpp index c9b63cb1ed6..b3a7382006a 100644 --- a/SU2_CFD/include/output/CFlowOutput.hpp +++ b/SU2_CFD/include/output/CFlowOutput.hpp @@ -44,6 +44,12 @@ class CFlowOutput : public CFVMOutput{ */ CFlowOutput(const CConfig *config, unsigned short nDim, bool femOutput); + /* + * \brief Add turboperformance outputs as history field + * \param[in] nZone - Number of zones in problem + */ + void AddTurboOutput(unsigned short nZone); + /*! * \brief Set the values of the volume output fields for a surface point. * \param[in] config - Definition of the particular problem. @@ -346,5 +352,4 @@ class CFlowOutput : public CFVMOutput{ * \param[in] config - Definition of the particular problem per zone. */ void SetFixedCLScreenOutput(const CConfig *config); - }; diff --git a/SU2_CFD/include/output/COutput.hpp b/SU2_CFD/include/output/COutput.hpp index 2ce54f87e48..08a4f6be9fe 100644 --- a/SU2_CFD/include/output/COutput.hpp +++ b/SU2_CFD/include/output/COutput.hpp @@ -38,6 +38,7 @@ #include "../../../Common/include/toolboxes/printing_toolbox.hpp" #include "tools/CWindowingTools.hpp" #include "../../../Common/include/option_structure.hpp" +#include "CTurboOutput.hpp" /*--- AD workaround for a cmath function not defined in CoDi. ---*/ namespace mel { @@ -325,7 +326,6 @@ class COutput { bool TimeConvergence; /*!< \brief To indicate, if the windowed time average of the time loop has converged*/ public: - /*----------------------------- Public member functions ----------------------------*/ /*! @@ -375,7 +375,6 @@ class COutput { */ void SetHistoryOutput(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned long TimeIter, unsigned long OuterIter, unsigned long InnerIter); - /*! * \brief Collects history data from the solvers and monitors the convergence. Does not write to screen or file. * \param[in] geometry - Geometrical definition of the problem. @@ -384,10 +383,24 @@ class COutput { */ void SetHistoryOutput(CGeometry *geometry, CSolver **solver_container, CConfig *config); + /*! + * \brief Collects history data from the solvers, monitors the convergence and writes to screen and history file. + * \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] TimeIter - Value of the time iteration index + * \param[in] OuterIter - Value of outer iteration index + * \param[in] InnerIter - Value of the inner iteration index + * \param[in] val_iInst - Index of the instance layer + */ + void SetHistoryOutput(CGeometry ****geometry, CSolver *****solver_container, CConfig **config, + CTurbomachineryStagePerformance* TurboStagePerf, + std::shared_ptr TurboPerf, unsigned short val_iZone, + unsigned long TimeIter, unsigned long OuterIter, unsigned long InnerIter, unsigned short val_iInst); + /*! * Collects history data from the individual output per zone, * monitors the convergence and writes to screen and history file. - * \param[in] output - Container holding the output instances per zone. * \param[in] config - Definition of the particular problem per zone. * \param[in] driver_config - Base definition of the particular problem. @@ -754,7 +767,7 @@ class COutput { /*! * \brief CheckHistoryOutput */ - void CheckHistoryOutput(); + void CheckHistoryOutput(unsigned short nZone); /*! * \brief Open the history file and write the header. @@ -929,7 +942,6 @@ class COutput { */ inline virtual void SetVolumeOutputFields(CConfig *config){} - /*! * \brief Load the history output field values * \param[in] config - Definition of the particular problem. @@ -945,6 +957,42 @@ class COutput { */ inline virtual void LoadMultizoneHistoryData(const COutput* const* output, const CConfig* const* config) {} + /*! + * \brief Sets the turboperformance screen output + * \param[in] TurboPerf - Turboperformance class + * \param[in] config - Definition of the particular problem + * \param[in] TimeIter - Index of the current time-step + * \param[in] OuterIter - Index of current outer iteration + * \param[in] InnerIter - Index of current inner iteration + */ + inline virtual void SetTurboPerformance_Output(std::shared_ptr TurboPerf, CConfig *config, unsigned long TimeIter, unsigned long OuterIter, unsigned long InnerIter) {} + + /*! + * \brief Sets the multizone turboperformacne screen output + * \param[in] TurboStagePerf - Stage turboperformance class + * \param[in] TurboPerf - Turboperformance class + * \param[in] config - Definition of the particular problem + */ + inline virtual void SetTurboMultiZonePerformance_Output(CTurbomachineryStagePerformance* TurboStagePerf, std::shared_ptr TurboPerf, CConfig *config) {} + + /*! + * \brief Loads the turboperformacne history data + * \param[in] TurboStagePerf - Stage turboperformance class + * \param[in] TurboPerf - Turboperformance class + * \param[in] config - Definition of the particular problem + */ + inline virtual void LoadTurboHistoryData(CTurbomachineryStagePerformance* TurboStagePerf, std::shared_ptr TurboPerf, CConfig *config) {} + + /*! + * \brief Write the kinematic and thermodynamic variables at each spanwise division + * \param[in] solver - The container hold all solution data + * \param[in] geometry - Geometrical definiton of the problem + * \param[in] config - Descripiton of the particular problem + * \param[in] val_iZone - Idientifier of current zone + */ + inline virtual void WriteTurboSpanwisePerformance(std::shared_ptr TurboPerf, CGeometry *geometry, CConfig **config, + unsigned short val_iZone) {}; + /*! * \brief Set the available history output fields * \param[in] config - Definition of the particular problem. diff --git a/SU2_CFD/include/output/CTurboOutput.hpp b/SU2_CFD/include/output/CTurboOutput.hpp new file mode 100644 index 00000000000..2d0e08c0489 --- /dev/null +++ b/SU2_CFD/include/output/CTurboOutput.hpp @@ -0,0 +1,256 @@ +/*! + * \file CTurboOutput.hpp + * \brief Headers of the Turbomachinery Performance class. + * \author S. Vitale, N. Anand + * \version 7.5.1 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2023, 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 +#include +#include +#include +#include +#include "../../../Common/include/geometry/CGeometry.hpp" +#include "../../../Common/include/CConfig.hpp" +#include "../fluid/CFluidModel.hpp" + +/*! + * \brief Class containing the required primitive variables for initiating a turboperformance calculation + * \author S. Vitale, N. Anand, J. Kelly + * \ingroup Output + */ +class CTurbomachineryPrimitiveState { + private: + su2double Density, Pressure, TangVelocity; + vector Velocity; + + public: + CTurbomachineryPrimitiveState(); + + CTurbomachineryPrimitiveState(vector TurboPrimitives, unsigned short nDim, su2double tangVel); + + const su2double& GetDensity() const { return Density; } + + const su2double& GetPressure() const { return Pressure; } + + const su2double& GetTangVelocity() const { return TangVelocity; } + + const std::vector& GetVelocity() const { return Velocity; } +}; + +/*! + * \brief Class containing the combined primitive inlet and outlet states for a given blade + * \author S. Vitale, N. Anand, J. Kelly + * \ingroup Output + */ +class CTurbomachineryCombinedPrimitiveStates { + private: + CTurbomachineryPrimitiveState InletPrimitiveState; + CTurbomachineryPrimitiveState OutletPrimitiveState; + + public: + CTurbomachineryCombinedPrimitiveStates(const CTurbomachineryPrimitiveState& inletPrimitiveState, + const CTurbomachineryPrimitiveState& outletPrimitiveState); + + const CTurbomachineryPrimitiveState& GetInletPrimitiveState() const& { return InletPrimitiveState; } + + const CTurbomachineryPrimitiveState& GetOutletPrimitiveState() const& { return OutletPrimitiveState; } +}; + +/*! + * \brief Class containing state information for a turbomachine + * \author S. Vitale, N. Anand, J. Kelly + * \ingroup Output + */ +class CTurbomachineryState { + private: + su2double Density, Pressure, Entropy, Enthalpy, Temperature, TotalTemperature, TotalPressure, TotalEnthalpy; + su2double AbsFlowAngle, FlowAngle, MassFlow, Rothalpy, TotalRelPressure; + vector Velocity, RelVelocity, Mach, RelMach; + su2double Area, Radius; + + public: + CTurbomachineryState(); + + CTurbomachineryState(unsigned short nDim, su2double area, su2double radius); + + void ComputeState(CFluidModel& fluidModel, const CTurbomachineryPrimitiveState& primitiveState); + + const su2double& GetDensity() const { return Density; } + + const su2double& GetPressure() const { return Pressure; } + + const su2double& GetEntropy() const { return Entropy; } + + const su2double& GetEnthalpy() const { return Enthalpy; } + + const su2double& GetTemperature() const { return Temperature; } + + const su2double& GetTotalTemperature() const { return TotalTemperature; } + + const su2double& GetTotalPressure() const { return TotalPressure; } + + const su2double& GetTotalRelPressure() const { return TotalRelPressure; } + + const su2double& GetTotalEnthalpy() const { return TotalEnthalpy; } + + const su2double& GetAbsFlowAngle() const { return AbsFlowAngle; } + + const su2double& GetFlowAngle() const { return FlowAngle; } + + const su2double& GetMassFlow() const { return MassFlow; } + + const su2double& GetRothalpy() const { return Rothalpy; } + + const vector& GetVelocity() const { return Velocity; } + + const vector& GetMach() const { return Mach; } + + su2double GetVelocityValue() const { return Norm(Velocity); } + + su2double GetMachValue() const { return Norm(Mach); } + + su2double GetRelVelocityValue() const { return Norm(RelVelocity); } + + su2double GetRelMachValue() const { return Norm(RelMach); } + + su2double Norm(const vector& u) const { + su2double accum = 0.; + for (auto i = 0u; i < u.size(); ++i) { + accum += u[i] * u[i]; + } + return sqrt(accum); + } +}; + +/*! + * \brief Class containing additional states and performance calculation routines for blades in different turbomachines + * \author S. Vitale, N. Anand, J. Kelly + * \ingroup Output + */ +class CTurbomachineryBladePerformance { + protected: + CTurbomachineryState InletState; + CTurbomachineryState OutletState; + su2double KineticEnergyLoss, TotalPressureLoss, EntropyGen, PressureRatio, EulerianWork; + CFluidModel& FluidModel; + + public: + CTurbomachineryBladePerformance(CFluidModel& fluidModel, unsigned short nDim, su2double areaIn, su2double radiusIn, su2double areaOut, su2double radiusOut); + + virtual ~CTurbomachineryBladePerformance() = default; + + virtual void ComputePerformance(const CTurbomachineryCombinedPrimitiveStates& primitives){}; + + const CTurbomachineryState& GetInletState() { return InletState; } + + const CTurbomachineryState& GetOutletState() { return OutletState; } + + const su2double& GetKineticEnergyLoss() const { return KineticEnergyLoss; } + + const su2double& GetTotalPressureLoss() const { return TotalPressureLoss; } + + const su2double& GetEntropyGen() const { return EntropyGen; } + + const su2double& GetPressureRatio() const { return PressureRatio; } + + const su2double& GetEulerianWork() const { return EulerianWork; } +}; + +class CTurbineBladePerformance : public CTurbomachineryBladePerformance { + public: + CTurbineBladePerformance(CFluidModel& fluidModel, unsigned short nDim, su2double areaIn, su2double radiusIn, su2double areaOut, su2double radiusOut); + + void ComputePerformance(const CTurbomachineryCombinedPrimitiveStates& primitives) override; +}; + +class CCompressorBladePerformance : public CTurbomachineryBladePerformance { + public: + CCompressorBladePerformance(CFluidModel& fluidModel, unsigned short nDim, su2double areaIn, su2double radiusIn, su2double areaOut, su2double radiusOut); + + void ComputePerformance(const CTurbomachineryCombinedPrimitiveStates& primitives) override; +}; + +class CPropellorBladePerformance : public CTurbomachineryBladePerformance { + public: + CPropellorBladePerformance(CFluidModel& fluidModel, unsigned short nDim, su2double areaIn, su2double radiusIn, su2double areaOut, su2double radiusOut); + + void ComputePerformance(const CTurbomachineryCombinedPrimitiveStates& primitives) override; +}; + +/*! + * \brief Class for computng full stage performance + * \author S. Vitale, N. Anand, J. Kelly + * \ingroup Output + */ +class CTurbomachineryStagePerformance { + protected: + su2double TotalStaticEfficiency, TotalTotalEfficiency, NormEntropyGen, TotalStaticPressureRatio, TotalTotalPressureRatio, EulerianWork; + CFluidModel& fluidModel; + + public: + CTurbomachineryStagePerformance(CFluidModel& fluid); + + virtual ~CTurbomachineryStagePerformance() = default; + + virtual void ComputePerformanceStage(const CTurbomachineryState& InState, const CTurbomachineryState& OutState, const CConfig* config); + + virtual void ComputeTurbineStagePerformance(const CTurbomachineryState& InState, const CTurbomachineryState& OutState); + + virtual void ComputeCompressorStagePerformance(const CTurbomachineryState& InState, const CTurbomachineryState& OutState); + + su2double GetTotalStaticEfficiency() const { return TotalStaticEfficiency; } + + su2double GetTotalTotalEfficiency() const { return TotalTotalEfficiency; } + + su2double GetEulerianWork() const { return EulerianWork; } + + su2double GetNormEntropyGen() const { return NormEntropyGen; } + + su2double GetTotalStaticPressureRatio() const { return TotalStaticPressureRatio; } + + su2double GetTotalTotalPressureRatio() const { return TotalTotalPressureRatio; } +}; + +/*! + * \brief Class for handling the calculation of turboperformance variables across a blade, span and full machine + * \author S. Vitale, N. Anand, J. Kelly + * \ingroup Output + */ +class CTurboOutput { + private: + vector>> BladesPerformances; + + static void ComputePerBlade(vector> const bladePerformances, vector const bladePrimitives); + + static void ComputePerSpan(shared_ptr const spanPerformances, const CTurbomachineryCombinedPrimitiveStates& spanPrimitives); + + public: + CTurboOutput(CConfig** config, const CGeometry& geometry, CFluidModel& fluidModel); + + const vector>>& GetBladesPerformances() const { return BladesPerformances; } + + void ComputeTurbomachineryPerformance(vector> const primitives); +}; \ No newline at end of file diff --git a/SU2_CFD/include/solvers/CEulerSolver.hpp b/SU2_CFD/include/solvers/CEulerSolver.hpp index 6ffc84a3237..7a6aa9fb3d8 100644 --- a/SU2_CFD/include/solvers/CEulerSolver.hpp +++ b/SU2_CFD/include/solvers/CEulerSolver.hpp @@ -1044,13 +1044,38 @@ class CEulerSolver : public CFVMFlowSolverBase GetTurboPrimitive(unsigned short iBlade, unsigned short iSpan, bool INLET) override { + vector TurboPrimitive; + TurboPrimitive.reserve(5); + if (INLET) { + TurboPrimitive.push_back(DensityIn[iBlade][iSpan]); + TurboPrimitive.push_back(PressureIn[iBlade][iSpan]); + TurboPrimitive.push_back(TurboVelocityIn[iBlade][iSpan][0]); + TurboPrimitive.push_back(TurboVelocityIn[iBlade][iSpan][1]); + if (nDim==3) + TurboPrimitive.push_back(TurboVelocityIn[iBlade][iSpan][2]); + } + else { + TurboPrimitive.push_back(DensityOut[iBlade][iSpan]); + TurboPrimitive.push_back(PressureOut[iBlade][iSpan]); + TurboPrimitive.push_back(TurboVelocityOut[iBlade][iSpan][0]); + TurboPrimitive.push_back(TurboVelocityOut[iBlade][iSpan][1]); + if (nDim==3) + TurboPrimitive.push_back(TurboVelocityOut[iBlade][iSpan][2]); + } + return TurboPrimitive; + } /*! * \brief Set the solution using the Freestream values. * \param[in] config - Definition of the particular problem. */ - void SetFreeStream_TurboSolution(const CConfig *config) final; - + 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. @@ -1107,9 +1132,9 @@ class CEulerSolver : public CFVMFlowSolverBase::HybridParallelInitialization(const CConfig& confi * sum the fluxes for each cell and set the diagonal of the system matrix. ---*/ su2double parallelEff = 1.0; + +#ifdef CODI_REVERSE_TYPE + /*--- For the discrete adjoint, the reducer strategy is costly. Prefer coloring, possibly with reduced edge color + * group size. Find the maximum edge color group size that yields an efficient coloring. Also, allow larger numbers + * of colors. ---*/ + const bool relax = config.GetEdgeColoringRelaxDiscAdj(); + const auto& coloring = geometry.GetEdgeColoring(¶llelEff, relax); +#else const auto& coloring = geometry.GetEdgeColoring(¶llelEff); +#endif /*--- The decision to use the strategy is local to each rank. ---*/ ReducerStrategy = parallelEff < COLORING_EFF_THRESH; @@ -324,6 +333,29 @@ void CFVMFlowSolverBase::HybridParallelInitialization(const CConfig& confi << "\n The memory usage of the discrete adjoint solver is higher when using the fallback." #endif << endl; + } else { + if (SU2_MPI::GetRank() == MASTER_NODE) { + cout << "All ranks use edge coloring." << endl; + } + } + + const su2double coloredParallelEff = ReducerStrategy ? 1.0 : parallelEff; + su2double minColoredParallelEff = 1.0; + SU2_MPI::Reduce(&coloredParallelEff, &minColoredParallelEff, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, SU2_MPI::GetComm()); + + const unsigned long coloredNumColors = ReducerStrategy ? 0 : coloring.getOuterSize(); + unsigned long maxColoredNumColors = 0; + SU2_MPI::Reduce(&coloredNumColors, &maxColoredNumColors, 1, MPI_UNSIGNED_LONG, MPI_MAX, MASTER_NODE, SU2_MPI::GetComm()); + + const unsigned long coloredEdgeColorGroupSize = ReducerStrategy ? 1 << 30 : geometry.GetEdgeColorGroupSize(); + unsigned long minColoredEdgeColorGroupSize = 1 << 30; + SU2_MPI::Reduce(&coloredEdgeColorGroupSize, &minColoredEdgeColorGroupSize, 1, MPI_UNSIGNED_LONG, MPI_MIN, MASTER_NODE, SU2_MPI::GetComm()); + + if (SU2_MPI::GetRank() == MASTER_NODE && numRanksUsingReducer != SU2_MPI::GetSize()) { + cout << "Among the ranks that use edge coloring,\n" + << " the minimum efficiency is " << minColoredParallelEff << ",\n" + << " the maximum number of colors is " << maxColoredNumColors << ",\n" + << " the minimum edge color group size is " << minColoredEdgeColorGroupSize << "." << endl; } } diff --git a/SU2_CFD/include/solvers/CScalarSolver.inl b/SU2_CFD/include/solvers/CScalarSolver.inl index 5b6415d65b0..343944ebd6c 100644 --- a/SU2_CFD/include/solvers/CScalarSolver.inl +++ b/SU2_CFD/include/solvers/CScalarSolver.inl @@ -46,7 +46,15 @@ CScalarSolver::CScalarSolver(CGeometry* geometry, CConfig* config, #ifdef HAVE_OMP /*--- Get the edge coloring, see notes in CEulerSolver's constructor. ---*/ su2double parallelEff = 1.0; +#ifdef CODI_REVERSE_TYPE + /*--- For the discrete adjoint, the reducer strategy is costly. Prefer coloring, possibly with reduced edge color + * group size. Find the maximum edge color group size that yields an efficient coloring. Also, allow larger numbers + * of colors. ---*/ + const bool relax = config->GetEdgeColoringRelaxDiscAdj(); + const auto& coloring = geometry->GetEdgeColoring(¶llelEff, relax); +#else const auto& coloring = geometry->GetEdgeColoring(¶llelEff); +#endif ReducerStrategy = parallelEff < COLORING_EFF_THRESH; diff --git a/SU2_CFD/include/solvers/CSolver.hpp b/SU2_CFD/include/solvers/CSolver.hpp index 691adf30b99..5bb17782f75 100644 --- a/SU2_CFD/include/solvers/CSolver.hpp +++ b/SU2_CFD/include/solvers/CSolver.hpp @@ -3754,6 +3754,13 @@ class CSolver { */ inline virtual void InitTurboContainers(CGeometry *geometry, CConfig *config) { } + /*! + * \brief Get Primal variables for turbo performance computation + * iteration can be executed by multiple threads. + * \return returns Density, pressure and TurboVelocity (IN/OUTLET) + */ + virtual vector GetTurboPrimitive(unsigned short iBlade, unsigned short iSpan, bool Inlet) { return {}; } + /*! * \brief virtual member. * \param[in] geometry - Geometrical definition of the problem. diff --git a/SU2_CFD/src/drivers/CDriver.cpp b/SU2_CFD/src/drivers/CDriver.cpp index d8ba985fafa..0fdfb2c2a2e 100644 --- a/SU2_CFD/src/drivers/CDriver.cpp +++ b/SU2_CFD/src/drivers/CDriver.cpp @@ -247,7 +247,7 @@ CDriverBase(confFile, val_nZone, MPICommunicator), StopCalc(false), fsi(false), if (rank == MASTER_NODE) cout << endl <<"---------------------- Turbomachinery Preprocessing ---------------------" << endl; - PreprocessTurbomachinery(config_container, geometry_container, solver_container, interface_container); + PreprocessTurbomachinery(config_container, geometry_container, solver_container, interface_container, dummy_geo); } else { mixingplane = false; } @@ -2488,10 +2488,22 @@ void CDriver::InitializeInterface(CConfig **config, CSolver***** solver, CGeomet if (rank == MASTER_NODE) cout << "boundary displacements from the structural solver." << endl; } else if (fluid_donor && fluid_target) { - interface_type = SLIDING_INTERFACE; - auto nVar = solver[donor][INST_0][MESH_0][FLOW_SOL]->GetnPrimVar(); - interface[donor][target] = new CSlidingInterface(nVar, 0); - if (rank == MASTER_NODE) cout << "sliding interface." << endl; + /*--- Mixing plane for turbo machinery applications. ---*/ + if (config[donor]->GetBoolMixingPlaneInterface()) { + interface_type = MIXING_PLANE; + auto nVar = solver[donor][INST_0][MESH_0][FLOW_SOL]->GetnVar(); + interface[donor][target] = new CMixingPlaneInterface(nVar, 0); + if (rank == MASTER_NODE) { + cout << "Set mixing-plane interface from donor zone " + << donor << " to target zone " << target << "." << endl; + } + } + else{ + auto nVar = solver[donor][INST_0][MESH_0][FLOW_SOL]->GetnPrimVar(); + interface_type = SLIDING_INTERFACE; + interface[donor][target] = new CSlidingInterface(nVar, 0); + if (rank == MASTER_NODE) cout << "sliding interface." << endl; + } } else if (heat_donor || heat_target) { if (heat_donor && heat_target) @@ -2527,18 +2539,6 @@ void CDriver::InitializeInterface(CConfig **config, CSolver***** solver, CGeomet } } - /*--- Mixing plane for turbo machinery applications. ---*/ - - if (config[donor]->GetBoolMixingPlaneInterface()) { - interface_type = MIXING_PLANE; - auto nVar = solver[donor][INST_0][MESH_0][FLOW_SOL]->GetnVar(); - interface[donor][target] = new CMixingPlaneInterface(nVar, 0); - if (rank == MASTER_NODE) { - cout << "Set mixing-plane interface from donor zone " - << donor << " to target zone " << target << "." << endl; - } - } - } } @@ -2630,7 +2630,7 @@ void CDriver::PreprocessOutput(CConfig **config, CConfig *driver_config, COutput void CDriver::PreprocessTurbomachinery(CConfig** config, CGeometry**** geometry, CSolver***** solver, - CInterface*** interface){ + CInterface*** interface, bool dummy){ unsigned short donorZone,targetZone, nMarkerInt, iMarkerInt; unsigned short nSpanMax = 0; @@ -2650,7 +2650,7 @@ void CDriver::PreprocessTurbomachinery(CConfig** config, CGeometry**** geometry, nSpanMax = config[iZone]->GetnSpanWiseSections(); } - config[ZONE_0]->SetnSpan_iZones(config[iZone]->GetnSpanWiseSections(), iZone); + config[nZone-1]->SetnSpan_iZones(config[iZone]->GetnSpanWiseSections(), iZone); geometry[iZone][INST_0][MESH_0]->SetTurboVertex(config[iZone], iZone, INFLOW, true); geometry[iZone][INST_0][MESH_0]->SetTurboVertex(config[iZone], iZone, OUTFLOW, true); @@ -2666,7 +2666,7 @@ void CDriver::PreprocessTurbomachinery(CConfig** config, CGeometry**** geometry, if (rank == MASTER_NODE) cout<<"Max number of span-wise sections among all zones: "<< nSpanMax<<"."<< endl; - if (rank == MASTER_NODE) cout<<"Initialize solver containers for average and performance quantities." << endl; + if (rank == MASTER_NODE) cout<<"Initialize solver containers for average quantities." << endl; for (iZone = 0; iZone < nZone; iZone++) { solver[iZone][INST_0][MESH_0][FLOW_SOL]->InitTurboContainers(geometry[iZone][INST_0][MESH_0],config[iZone]); } @@ -2684,16 +2684,15 @@ void CDriver::PreprocessTurbomachinery(CConfig** config, CGeometry**** geometry, if (rank == MASTER_NODE) cout << "Set span-wise sections between zones on Mixing-Plane interface." << endl; for (donorZone = 0; donorZone < nZone; donorZone++) { for (targetZone = 0; targetZone < nZone; targetZone++) { - if (targetZone != donorZone){ + if (interface_container[donorZone][targetZone] != nullptr){ interface[donorZone][targetZone]->SetSpanWiseLevels(config[donorZone], config[targetZone]); } } } } - if (rank == MASTER_NODE) cout << "Transfer average geometric quantities to zone 0." << endl; - for (iZone = 1; iZone < nZone; iZone++) { - interface[iZone][ZONE_0]->GatherAverageTurboGeoValues(geometry[iZone][INST_0][MESH_0],geometry[ZONE_0][INST_0][MESH_0], iZone); + for (iZone = 0; iZone < nZone-1; iZone++) { + geometry[nZone-1][INST_0][MESH_0]->SetAvgTurboGeoValues(config[iZone],geometry[iZone][INST_0][MESH_0], iZone); } /*--- Transfer number of blade to ZONE_0 to correctly compute turbo performance---*/ @@ -2702,7 +2701,7 @@ void CDriver::PreprocessTurbomachinery(CConfig** config, CGeometry**** geometry, config[ZONE_0]->SetnBlades(iZone, nBlades); } - if (rank == MASTER_NODE){ + if (rank == MASTER_NODE && !dummy){ for (iZone = 0; iZone < nZone; iZone++) { areaIn = geometry[iZone][INST_0][MESH_0]->GetSpanAreaIn(iZone, config[iZone]->GetnSpanWiseSections()); areaOut = geometry[iZone][INST_0][MESH_0]->GetSpanAreaOut(iZone, config[iZone]->GetnSpanWiseSections()); @@ -2720,7 +2719,7 @@ void CDriver::PreprocessTurbomachinery(CConfig** config, CGeometry**** geometry, nMarkerInt = config_container[donorZone]->GetnMarker_MixingPlaneInterface()/2; for (iMarkerInt = 1; iMarkerInt <= nMarkerInt; iMarkerInt++){ for (targetZone = 0; targetZone < nZone; targetZone++) { - if (targetZone != donorZone){ + if (interface_types[donorZone][targetZone]==MIXING_PLANE){ interface[donorZone][targetZone]->PreprocessAverage(geometry[donorZone][INST_0][MESH_0], geometry[targetZone][INST_0][MESH_0], config[donorZone], config[targetZone], iMarkerInt); @@ -2875,81 +2874,6 @@ void CDriver::PrintDirectResidual(RECORDING kind_recording) { } -void CDriver::RampTurbomachineryValues(unsigned long iter) { - auto* config = config_container[ZONE_0]; - - /*--- ROTATING FRAME Ramp: Compute the updated rotational velocity. ---*/ - if (config->GetGrid_Movement() && config->GetRampRotatingFrame()) { - const unsigned long rampFreq = SU2_TYPE::Int(config->GetRampRotatingFrame_Coeff(1)); - const unsigned long finalRamp_Iter = SU2_TYPE::Int(config->GetRampRotatingFrame_Coeff(2)); - const su2double rot_z_ini = config->GetRampRotatingFrame_Coeff(0); - const bool print = false; - - if(iter % rampFreq == 0 && iter <= finalRamp_Iter){ - - for (auto iZone = 0u; iZone < nZone; iZone++) { - const su2double rot_z_final = config_container[iZone]->GetFinalRotation_Rate_Z(); - - if (fabs(rot_z_final) > 0.0) { - const su2double rot_z = rot_z_ini + iter * ( rot_z_final - rot_z_ini) / finalRamp_Iter; - config_container[iZone]->SetRotation_Rate(2, rot_z); - if (rank == MASTER_NODE && print && iter > 0) { - cout << "\nUpdated rotating frame grid velocities for zone " << iZone << ".\n"; - } - geometry_container[iZone][INST_0][MESH_0]->SetRotationalVelocity(config_container[iZone], print); - geometry_container[iZone][INST_0][MESH_0]->SetShroudVelocity(config_container[iZone]); - } - } - - for (auto iZone = 0u; iZone < nZone; iZone++) { - geometry_container[iZone][INST_0][MESH_0]->SetAvgTurboValue(config_container[iZone], iZone, INFLOW, false); - geometry_container[iZone][INST_0][MESH_0]->SetAvgTurboValue(config_container[iZone],iZone, OUTFLOW, false); - geometry_container[iZone][INST_0][MESH_0]->GatherInOutAverageValues(config_container[iZone], false); - } - - for (auto iZone = 1u; iZone < nZone; iZone++) { - interface_container[iZone][ZONE_0]->GatherAverageTurboGeoValues( - geometry_container[iZone][INST_0][MESH_0], geometry_container[ZONE_0][INST_0][MESH_0], iZone); - } - } - } - - /*--- Outlet Pressure Ramp: Compute the updated pressure. ---*/ - if (config->GetRampOutletPressure()) { - const unsigned long rampFreq = SU2_TYPE::Int(config->GetRampOutletPressure_Coeff(1)); - const unsigned long finalRamp_Iter = SU2_TYPE::Int(config->GetRampOutletPressure_Coeff(2)); - const su2double outPres_ini = config->GetRampOutletPressure_Coeff(0); - const su2double outPres_final = config->GetFinalOutletPressure(); - - if (iter % rampFreq == 0 && iter <= finalRamp_Iter) { - const su2double outPres = outPres_ini + iter * (outPres_final - outPres_ini) / finalRamp_Iter; - if (rank == MASTER_NODE) config->SetMonitotOutletPressure(outPres); - - for (auto iZone = 0u; iZone < nZone; iZone++) { - for (auto iMarker = 0; iMarker < config_container[iZone]->GetnMarker_All(); iMarker++) { - const auto KindBC = config_container[iZone]->GetMarker_All_KindBC(iMarker); - const auto Marker_Tag = config_container[iZone]->GetMarker_All_TagBound(iMarker); - unsigned short KindBCOption; - switch (KindBC) { - case RIEMANN_BOUNDARY: - KindBCOption = config_container[iZone]->GetKind_Data_Riemann(Marker_Tag); - if (KindBCOption == STATIC_PRESSURE || KindBCOption == RADIAL_EQUILIBRIUM) { - SU2_MPI::Error("Outlet pressure ramp only implemented for NRBC", CURRENT_FUNCTION); - } - break; - case GILES_BOUNDARY: - KindBCOption = config_container[iZone]->GetKind_Data_Giles(Marker_Tag); - if (KindBCOption == STATIC_PRESSURE || KindBCOption == STATIC_PRESSURE_1D || - KindBCOption == RADIAL_EQUILIBRIUM ) { - config_container[iZone]->SetGiles_Var1(outPres, Marker_Tag); - } - break; - } - } - } - } - } -} CFluidDriver::CFluidDriver(char* confFile, unsigned short val_nZone, SU2_Comm MPICommunicator) : CDriver(confFile, val_nZone, MPICommunicator, false) { Max_Iter = config_container[ZONE_0]->GetnInner_Iter(); diff --git a/SU2_CFD/src/drivers/CMultizoneDriver.cpp b/SU2_CFD/src/drivers/CMultizoneDriver.cpp index 49a9c58e724..0cf6d838a65 100644 --- a/SU2_CFD/src/drivers/CMultizoneDriver.cpp +++ b/SU2_CFD/src/drivers/CMultizoneDriver.cpp @@ -181,7 +181,6 @@ void CMultizoneDriver::StartSolver() { Preprocess(TimeIter); /*--- Run a block iteration of the multizone problem. ---*/ - Run(); /*--- Update the solution for dual time stepping strategy ---*/ @@ -252,11 +251,6 @@ void CMultizoneDriver::Preprocess(unsigned long TimeIter) { } - /*--- Ramp turbo values for unsteady problems here, otherwise do it over outer iterations. ---*/ - if (config_container[ZONE_0]->GetTime_Domain()) { - RampTurbomachineryValues(TimeIter); - } - SU2_MPI::Barrier(SU2_MPI::GetComm()); /*--- Run a predictor step ---*/ @@ -290,19 +284,11 @@ void CMultizoneDriver::RunGaussSeidel() { for (iZone = 0; iZone < nZone; iZone++) { config_container[iZone]->SetOuterIter(0ul); - /*--- This is required for correct restarts with mixing plane interfaces and GS iterations, - * for Jacobi we always do all the transfers before iterating all zones. ---*/ - if (mixingplane) SetMixingPlane(iZone); } /*--- Loop over the number of outer iterations ---*/ for (auto iOuter_Iter = 0ul; iOuter_Iter < driver_config->GetnOuter_Iter(); iOuter_Iter++) { - /*--- Ramp turbo values for steady problems here, otherwise do it over time steps. ---*/ - if (!config_container[ZONE_0]->GetTime_Domain()) { - RampTurbomachineryValues(iOuter_Iter); - } - /*--- Loop over the number of zones (IZONE) ---*/ for (iZone = 0; iZone < nZone; iZone++) { @@ -322,7 +308,6 @@ void CMultizoneDriver::RunGaussSeidel() { if (DeformMesh) UpdateMesh+=1; } } - /*--- If a mesh update is required due to the transfer of data ---*/ if (UpdateMesh > 0) DynamicMeshUpdate(iZone, TimeIter); @@ -331,8 +316,6 @@ void CMultizoneDriver::RunGaussSeidel() { solver_container, numerics_container, config_container, surface_movement, grid_movement, FFDBox, iZone, INST_0); - if (mixingplane) SetMixingPlane(iZone); - /*--- A corrector step can help preventing numerical instabilities ---*/ Corrector(iZone); @@ -356,10 +339,6 @@ void CMultizoneDriver::RunJacobi() { /*--- Loop over the number of outer iterations ---*/ for (auto iOuter_Iter = 0ul; iOuter_Iter < driver_config->GetnOuter_Iter(); iOuter_Iter++){ - /*--- Ramp turbo values for steady problems here, otherwise do it over time steps. ---*/ - if (!config_container[ZONE_0]->GetTime_Domain()) { - RampTurbomachineryValues(iOuter_Iter); - } /*--- Transfer from all zones ---*/ for (iZone = 0; iZone < nZone; iZone++){ @@ -382,7 +361,6 @@ void CMultizoneDriver::RunJacobi() { /*--- If a mesh update is required due to the transfer of data ---*/ if (UpdateMesh > 0) DynamicMeshUpdate(iZone, TimeIter); - if (mixingplane) SetMixingPlane(iZone); } /*--- Loop over the number of zones (IZONE) ---*/ @@ -605,6 +583,25 @@ bool CMultizoneDriver::TransferData(unsigned short donorZone, unsigned short tar BroadcastData(FLOW_SOL, FEA_SOL); break; case MIXING_PLANE: + { + const auto nMarkerInt = config_container[donorZone]->GetnMarker_MixingPlaneInterface() / 2; + + /*--- Transfer the average value from the donorZone to the targetZone ---*/ + for (auto iMarkerInt = 1; iMarkerInt <= nMarkerInt; iMarkerInt++) { + interface_container[donorZone][targetZone]->AllgatherAverage(solver_container[donorZone][INST_0][MESH_0][FLOW_SOL],solver_container[targetZone][INST_0][MESH_0][FLOW_SOL], + geometry_container[donorZone][INST_0][MESH_0],geometry_container[targetZone][INST_0][MESH_0], + config_container[donorZone], config_container[targetZone], iMarkerInt ); + } + + for (donorZone = 0; donorZone < nZone; donorZone++) { + if (interface_types[donorZone][targetZone]==MIXING_PLANE) { + interface_container[donorZone][targetZone]->GatherAverageValues(solver_container[donorZone][INST_0][MESH_0][FLOW_SOL],solver_container[targetZone][INST_0][MESH_0][FLOW_SOL], donorZone); + geometry_container[targetZone][INST_0][MESH_0]->SetAvgTurboGeoValues(config_container[iZone],geometry_container[iZone][INST_0][MESH_0], iZone); + } + } + + break; + } case NO_TRANSFER: case ZONES_ARE_EQUAL: case NO_COMMON_INTERFACE: @@ -619,21 +616,7 @@ bool CMultizoneDriver::TransferData(unsigned short donorZone, unsigned short tar return UpdateMesh; } -void CMultizoneDriver::SetMixingPlane(unsigned short donorZone) { - const auto nMarkerInt = config_container[donorZone]->GetnMarker_MixingPlaneInterface() / 2; - - /*--- Transfer the average value from the donor zones to the target zones ---*/ - for (auto iMarkerInt = 1; iMarkerInt <= nMarkerInt; iMarkerInt++) { - for (auto targetZone = 0u; targetZone < nZone; targetZone++) { - if (targetZone == donorZone) continue; - interface_container[donorZone][targetZone]->AllgatherAverage( - solver_container[donorZone][INST_0][MESH_0][FLOW_SOL], solver_container[targetZone][INST_0][MESH_0][FLOW_SOL], - geometry_container[donorZone][INST_0][MESH_0], geometry_container[targetZone][INST_0][MESH_0], - config_container[donorZone], config_container[targetZone], iMarkerInt); - } - } -} void CMultizoneDriver::SetTurboPerformance() { for (auto donorZone = 1u; donorZone < nZone; donorZone++) { @@ -685,8 +668,6 @@ bool CMultizoneDriver::Monitor(unsigned long TimeIter) { cout << "-------------------------------------------------------------------------" << endl; } - if (rank == MASTER_NODE && driver_config->GetBoolTurbomachinery()) SetTurboPerformance(); - return (FinalTimeReached || MaxIterationsReached); } diff --git a/SU2_CFD/src/drivers/CSinglezoneDriver.cpp b/SU2_CFD/src/drivers/CSinglezoneDriver.cpp index c35d6b8eac5..f646f2b1525 100644 --- a/SU2_CFD/src/drivers/CSinglezoneDriver.cpp +++ b/SU2_CFD/src/drivers/CSinglezoneDriver.cpp @@ -119,8 +119,6 @@ void CSinglezoneDriver::Preprocess(unsigned long TimeIter) { else config_container[ZONE_0]->SetPhysicalTime(0.0); - /*--- Ramp turbo BCs for this time step. ---*/ - RampTurbomachineryValues(TimeIter); /*--- Set the initial condition for EULER/N-S/RANS ---------------------------------------------*/ if (config_container[ZONE_0]->GetFluidProblem()) { diff --git a/SU2_CFD/src/integration/CIntegration.cpp b/SU2_CFD/src/integration/CIntegration.cpp index 1ffc29364e2..ca612e7d236 100644 --- a/SU2_CFD/src/integration/CIntegration.cpp +++ b/SU2_CFD/src/integration/CIntegration.cpp @@ -89,6 +89,15 @@ void CIntegration::Space_Integration(CGeometry *geometry, solver_container[MainSolver]->PreprocessBC_Giles(geometry, config, conv_bound_numerics, OUTFLOW); } + BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { + if (config->GetBoolTurbomachinery()){ + /*--- Average quantities at the inflow and outflow boundaries ---*/ + solver_container[MainSolver]->TurboAverageProcess(solver_container, geometry,config,INFLOW); + solver_container[MainSolver]->TurboAverageProcess(solver_container, geometry, config, OUTFLOW); + } + } + END_SU2_OMP_SAFE_GLOBAL_ACCESS + /*--- Weak boundary conditions ---*/ for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { diff --git a/SU2_CFD/src/integration/CMultiGridIntegration.cpp b/SU2_CFD/src/integration/CMultiGridIntegration.cpp index 8f5b4f01de8..d335d4d14c4 100644 --- a/SU2_CFD/src/integration/CMultiGridIntegration.cpp +++ b/SU2_CFD/src/integration/CMultiGridIntegration.cpp @@ -668,6 +668,20 @@ void CMultiGridIntegration::NonDimensional_Parameters(CGeometry **geometry, CSol solver_container[FinestMesh][FLOW_SOL]->Momentum_Forces(geometry[FinestMesh], config); solver_container[FinestMesh][FLOW_SOL]->Friction_Forces(geometry[FinestMesh], config); + /*--- Calculate the turbo performance ---*/ + if (config->GetBoolTurbomachinery()){ + + /*--- Average quantities at the inflow and outflow boundaries ---*/ + + solver_container[FinestMesh][FLOW_SOL]->TurboAverageProcess(solver_container[FinestMesh], geometry[FinestMesh],config,INFLOW); + solver_container[FinestMesh][FLOW_SOL]->TurboAverageProcess(solver_container[FinestMesh], geometry[FinestMesh], config, OUTFLOW); + + /*--- Gather Inflow and Outflow quantities on the Master Node to compute performance ---*/ + + solver_container[FinestMesh][FLOW_SOL]->GatherInOutAverageValues(config, geometry[FinestMesh]); + + } + break; case RUNTIME_ADJFLOW_SYS: diff --git a/SU2_CFD/src/interfaces/CInterface.cpp b/SU2_CFD/src/interfaces/CInterface.cpp index 4d8d33b3ecf..aedebf32641 100644 --- a/SU2_CFD/src/interfaces/CInterface.cpp +++ b/SU2_CFD/src/interfaces/CInterface.cpp @@ -645,13 +645,3 @@ void CInterface::GatherAverageValues(CSolver *donor_solution, CSolver *target_so SetAverageValues(donor_solution, target_solution, donorZone); } - -void CInterface::GatherAverageTurboGeoValues(CGeometry *donor_geometry, CGeometry *target_geometry, - unsigned short donorZone){ - - - /*--- here we made the strong assumption that the mesh zone order - * follows the same order of the turbomachinery markers ---*/ - SetAverageTurboGeoValues(donor_geometry, target_geometry, donorZone); - -} diff --git a/SU2_CFD/src/interfaces/cfd/CMixingPlaneInterface.cpp b/SU2_CFD/src/interfaces/cfd/CMixingPlaneInterface.cpp index 76e7509edce..a2d52f7a829 100644 --- a/SU2_CFD/src/interfaces/cfd/CMixingPlaneInterface.cpp +++ b/SU2_CFD/src/interfaces/cfd/CMixingPlaneInterface.cpp @@ -136,18 +136,3 @@ void CMixingPlaneInterface::SetAverageValues(CSolver *donor_solution, CSolver *t } } - -void CMixingPlaneInterface::SetAverageTurboGeoValues(CGeometry *donor_geometry, CGeometry *target_geometry, - unsigned short donorZone){ - unsigned short iSpan; - - for(iSpan = 0; iSpanSetTurboRadiusIn(donor_geometry->GetTurboRadiusIn(donorZone, iSpan), donorZone, iSpan); - target_geometry->SetSpanAreaIn(donor_geometry->GetSpanAreaIn(donorZone, iSpan), donorZone, iSpan); - target_geometry->SetTangGridVelIn(donor_geometry->GetTangGridVelIn(donorZone, iSpan), donorZone, iSpan); - target_geometry->SetTurboRadiusOut(donor_geometry->GetTurboRadiusOut(donorZone, iSpan), donorZone, iSpan); - target_geometry->SetSpanAreaOut(donor_geometry->GetSpanAreaOut(donorZone, iSpan), donorZone, iSpan); - target_geometry->SetTangGridVelOut(donor_geometry->GetTangGridVelOut(donorZone, iSpan), donorZone, iSpan); - } - -} diff --git a/SU2_CFD/src/iteration/CFluidIteration.cpp b/SU2_CFD/src/iteration/CFluidIteration.cpp index f879606b66e..1d29f185ad8 100644 --- a/SU2_CFD/src/iteration/CFluidIteration.cpp +++ b/SU2_CFD/src/iteration/CFluidIteration.cpp @@ -213,11 +213,23 @@ bool CFluidIteration::Monitor(COutput* output, CIntegration**** integration, CGe UsedTime = StopTime - StartTime; + + /*--- Turbomachinery Specific Montior ---*/ + if (config[ZONE_0]->GetBoolTurbomachinery()){ + if (val_iZone == config[ZONE_0]->GetnZone()-1) { + ComputeTurboPerformance(solver, geometry, config, config[val_iZone]->GetnInner_Iter()); + + output->SetHistoryOutput(geometry, solver, + config, TurbomachineryStagePerformance, TurbomachineryPerformance, val_iZone, config[val_iZone]->GetTimeIter(), config[val_iZone]->GetOuterIter(), + config[val_iZone]->GetInnerIter(), val_iInst); + } + + TurboMonitor(geometry, config, config[val_iZone]->GetInnerIter()); + } output->SetHistoryOutput(geometry[val_iZone][val_iInst][MESH_0], solver[val_iZone][val_iInst][MESH_0], config[val_iZone], config[val_iZone]->GetTimeIter(), config[val_iZone]->GetOuterIter(), config[val_iZone]->GetInnerIter()); - - /*--- If convergence was reached --*/ + StopCalc = output->GetConvergence(); /* --- Checking convergence of Fixed CL mode to target CL, and perform finite differencing if needed --*/ @@ -230,6 +242,119 @@ bool CFluidIteration::Monitor(COutput* output, CIntegration**** integration, CGe return StopCalc; } +void CFluidIteration::TurboMonitor(CGeometry**** geometry_container, CConfig** config_container, unsigned long iter) { + + auto* config = config_container[ZONE_0]; + + if (config_container[ZONE_0]->GetMultizone_Problem()) + iter = config_container[ZONE_0]->GetOuterIter(); + + + /*--- ROTATING FRAME Ramp: Compute the updated rotational velocity. ---*/ + if (config->GetGrid_Movement() && config->GetRampRotatingFrame()) { + const unsigned long rampFreq = SU2_TYPE::Int(config->GetRampRotatingFrame_Coeff(1)); + const unsigned long finalRamp_Iter = SU2_TYPE::Int(config->GetRampRotatingFrame_Coeff(2)); + const su2double rot_z_ini = config->GetRampRotatingFrame_Coeff(0); + const bool print = false; + + if(iter % rampFreq == 0 && iter <= finalRamp_Iter){ + + for (auto iZone = 0u; iZone < nZone; iZone++) { + const su2double rot_z_final = config_container[iZone]->GetFinalRotation_Rate_Z(); + + if (fabs(rot_z_final) > 0.0) { + const su2double rot_z = rot_z_ini + iter * ( rot_z_final - rot_z_ini) / finalRamp_Iter; + config_container[iZone]->SetRotation_Rate(2, rot_z); + if (rank == MASTER_NODE && print && iter > 0) { + cout << "\nUpdated rotating frame grid velocities for zone " << iZone << ".\n"; + } + geometry_container[iZone][INST_0][MESH_0]->SetRotationalVelocity(config_container[iZone], print); + geometry_container[iZone][INST_0][MESH_0]->SetShroudVelocity(config_container[iZone]); + } + } + + for (auto iZone = 0u; iZone < nZone; iZone++) { + geometry_container[iZone][INST_0][MESH_0]->SetAvgTurboValue(config_container[iZone], iZone, INFLOW, false); + geometry_container[iZone][INST_0][MESH_0]->SetAvgTurboValue(config_container[iZone],iZone, OUTFLOW, false); + geometry_container[iZone][INST_0][MESH_0]->GatherInOutAverageValues(config_container[iZone], false); + } + + for (auto iZone = 0; iZone < nZone-1; iZone++) { + geometry_container[nZone-1][INST_0][MESH_0]->SetAvgTurboGeoValues(config_container[iZone],geometry_container[iZone][INST_0][MESH_0], iZone); + } + } + } + + /*--- Outlet Pressure Ramp: Compute the updated pressure. ---*/ + if (config->GetRampOutletPressure()) { + const unsigned long rampFreq = SU2_TYPE::Int(config->GetRampOutletPressure_Coeff(1)); + const unsigned long finalRamp_Iter = SU2_TYPE::Int(config->GetRampOutletPressure_Coeff(2)); + const su2double outPres_ini = config->GetRampOutletPressure_Coeff(0); + const su2double outPres_final = config->GetFinalOutletPressure(); + + if (iter % rampFreq == 0 && iter <= finalRamp_Iter) { + const su2double outPres = outPres_ini + iter * (outPres_final - outPres_ini) / finalRamp_Iter; + if (rank == MASTER_NODE) config->SetMonitotOutletPressure(outPres); + + for (auto iZone = 0u; iZone < nZone; iZone++) { + for (auto iMarker = 0; iMarker < config_container[iZone]->GetnMarker_All(); iMarker++) { + const auto KindBC = config_container[iZone]->GetMarker_All_KindBC(iMarker); + const auto Marker_Tag = config_container[iZone]->GetMarker_All_TagBound(iMarker); + unsigned short KindBCOption; + switch (KindBC) { + case RIEMANN_BOUNDARY: + KindBCOption = config_container[iZone]->GetKind_Data_Riemann(Marker_Tag); + if (KindBCOption == STATIC_PRESSURE || KindBCOption == RADIAL_EQUILIBRIUM) { + SU2_MPI::Error("Outlet pressure ramp only implemented for NRBC", CURRENT_FUNCTION); + } + break; + case GILES_BOUNDARY: + KindBCOption = config_container[iZone]->GetKind_Data_Giles(Marker_Tag); + if (KindBCOption == STATIC_PRESSURE || KindBCOption == STATIC_PRESSURE_1D || + KindBCOption == RADIAL_EQUILIBRIUM ) { + config_container[iZone]->SetGiles_Var1(outPres, Marker_Tag); + } + break; + } + } + } + } + } +} + +void CFluidIteration::ComputeTurboPerformance(CSolver***** solver, CGeometry**** geometry_container, CConfig** config_container, unsigned long ExtIter) { + unsigned short nDim = geometry_container[ZONE_0][INST_0][MESH_0]->GetnDim(); + unsigned short nBladesRow = config_container[ZONE_0]->GetnMarker_Turbomachinery(); + unsigned short iBlade=0, iSpan; + vector TurboPrimitiveIn, TurboPrimitiveOut; + std::vector> bladesPrimitives; + + if (rank == MASTER_NODE) { + for (iBlade = 0; iBlade < nBladesRow; iBlade++){ + /* Blade Primitive initialized per blade */ + std::vector bladePrimitives; + auto nSpan = config_container[iBlade]->GetnSpanWiseSections(); + for (iSpan = 0; iSpan < nSpan + 1; iSpan++) { + TurboPrimitiveIn= solver[iBlade][INST_0][MESH_0][FLOW_SOL]->GetTurboPrimitive(iBlade, iSpan, true); + TurboPrimitiveOut= solver[iBlade][INST_0][MESH_0][FLOW_SOL]->GetTurboPrimitive(iBlade, iSpan, false); + auto spanInletPrimitive = CTurbomachineryPrimitiveState(TurboPrimitiveIn, nDim, geometry_container[iBlade][INST_0][MESH_0]->GetTangGridVelIn(iBlade, iSpan)); + auto spanOutletPrimitive = CTurbomachineryPrimitiveState(TurboPrimitiveOut, nDim, geometry_container[iBlade][INST_0][MESH_0]->GetTangGridVelOut(iBlade, iSpan)); + auto spanCombinedPrimitive = CTurbomachineryCombinedPrimitiveStates(spanInletPrimitive, spanOutletPrimitive); + bladePrimitives.push_back(spanCombinedPrimitive); + } + bladesPrimitives.push_back(bladePrimitives); + } + TurbomachineryPerformance->ComputeTurbomachineryPerformance(bladesPrimitives); + + auto nSpan = config_container[ZONE_0]->GetnSpanWiseSections(); + auto InState = TurbomachineryPerformance->GetBladesPerformances().at(ZONE_0).at(nSpan)->GetInletState(); + nSpan = config_container[nZone-1]->GetnSpanWiseSections(); + auto OutState = TurbomachineryPerformance->GetBladesPerformances().at(nZone-1).at(nSpan)->GetOutletState(); + + TurbomachineryStagePerformance->ComputePerformanceStage(InState, OutState, config_container[nZone-1]); + } +} + void CFluidIteration::Postprocess(COutput* output, CIntegration**** integration, CGeometry**** geometry, CSolver***** solver, CNumerics****** numerics, CConfig** config, CSurfaceMovement** surface_movement, CVolumetricMovement*** grid_movement, diff --git a/SU2_CFD/src/iteration/CIteration.cpp b/SU2_CFD/src/iteration/CIteration.cpp index 98190ef3972..977e8b713ef 100644 --- a/SU2_CFD/src/iteration/CIteration.cpp +++ b/SU2_CFD/src/iteration/CIteration.cpp @@ -90,9 +90,11 @@ void CIteration::SetGrid_Movement(CGeometry** geometry, CSurfaceMovement* surfac break; } - if (config->GetSurface_Movement(AEROELASTIC) || config->GetSurface_Movement(AEROELASTIC_RIGID_MOTION)) { + if (config->GetSurface_Movement(AEROELASTIC) || config->GetSurface_Movement(AEROELASTIC_RIGID_MOTION) || config->GetSurface_Movement(MOVING_WALL)) { /*--- Apply rigid mesh transformation to entire grid first, if necessary ---*/ + if (IntIter == 0) { + if (Kind_Grid_Movement == AEROELASTIC_RIGID_MOTION) { if (rank == MASTER_NODE) cout << endl << " Performing rigid mesh transformation." << endl; @@ -110,6 +112,11 @@ void CIteration::SetGrid_Movement(CGeometry** geometry, CSurfaceMovement* surfac grid_movement->UpdateMultiGrid(geometry, config); } + if (config->GetSurface_Movement(MOVING_WALL)) { + for (auto iMGlevel = 0u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + geometry[iMGlevel]->SetWallVelocity(config, iMGlevel == 0u); + } + } } diff --git a/SU2_CFD/src/iteration/CTurboIteration.cpp b/SU2_CFD/src/iteration/CTurboIteration.cpp index 0028df639f7..196fa52f55a 100644 --- a/SU2_CFD/src/iteration/CTurboIteration.cpp +++ b/SU2_CFD/src/iteration/CTurboIteration.cpp @@ -27,6 +27,7 @@ #include "../../include/iteration/CTurboIteration.hpp" #include "../../include/output/COutput.hpp" +#include "../../include/output/CTurboOutput.hpp" void CTurboIteration::Preprocess(COutput* output, CIntegration**** integration, CGeometry**** geometry, CSolver***** solver, CNumerics****** numerics, CConfig** config, @@ -37,6 +38,11 @@ void CTurboIteration::Preprocess(COutput* output, CIntegration**** integration, solver[val_iZone][val_iInst][MESH_0], geometry[val_iZone][val_iInst][MESH_0], config[val_iZone], INFLOW); solver[val_iZone][val_iInst][MESH_0][FLOW_SOL]->TurboAverageProcess( solver[val_iZone][val_iInst][MESH_0], geometry[val_iZone][val_iInst][MESH_0], config[val_iZone], OUTFLOW); + + if (config[val_iZone]->GetBoolTurbomachinery()) { + InitTurboPerformance(geometry[val_iZone][INST_0][MESH_0], config, + solver[val_iZone][val_iInst][MESH_0][FLOW_SOL]->GetFluidModel()); + } } void CTurboIteration::Postprocess(COutput* output, CIntegration**** integration, CGeometry**** geometry, @@ -53,3 +59,8 @@ void CTurboIteration::Postprocess(COutput* output, CIntegration**** integration, solver[val_iZone][val_iInst][MESH_0][FLOW_SOL]->GatherInOutAverageValues(config[val_iZone], geometry[val_iZone][val_iInst][MESH_0]); } + +void CTurboIteration::InitTurboPerformance(CGeometry* geometry, CConfig** config, CFluidModel* fluid) { + TurbomachineryPerformance = std::make_shared(config, *geometry, *fluid); + TurbomachineryStagePerformance = new CTurbomachineryStagePerformance(*fluid); +} diff --git a/SU2_CFD/src/meson.build b/SU2_CFD/src/meson.build index 946227cd305..43e8aaed5de 100644 --- a/SU2_CFD/src/meson.build +++ b/SU2_CFD/src/meson.build @@ -32,6 +32,7 @@ su2_cfd_src += files(['output/COutputFactory.cpp', 'output/CHeatOutput.cpp', 'output/CMeshOutput.cpp', 'output/CNEMOCompOutput.cpp', + 'output/CTurboOutput.cpp' , 'output/COutput.cpp', 'output/filewriter/CParallelDataSorter.cpp', 'output/filewriter/CFVMDataSorter.cpp', diff --git a/SU2_CFD/src/output/CFlowCompOutput.cpp b/SU2_CFD/src/output/CFlowCompOutput.cpp index 73f528ece17..c44ee947ead 100644 --- a/SU2_CFD/src/output/CFlowCompOutput.cpp +++ b/SU2_CFD/src/output/CFlowCompOutput.cpp @@ -206,6 +206,8 @@ void CFlowCompOutput::SetHistoryOutputFields(CConfig *config){ AddNearfieldInverseDesignOutput(); + if (config->GetBoolTurbomachinery()) AddTurboOutput(config->GetnZone()); + } void CFlowCompOutput::SetVolumeOutputFields(CConfig *config){ @@ -477,7 +479,6 @@ void CFlowCompOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSol SetCustomOutputs(solver, geometry, config); SetCustomAndComboObjectives(FLOW_SOL, config, solver); - } bool CFlowCompOutput::SetInitResiduals(const CConfig *config){ @@ -497,3 +498,350 @@ void CFlowCompOutput::SetAdditionalScreenOutput(const CConfig *config){ bool CFlowCompOutput::WriteHistoryFileOutput(const CConfig *config) { return !config->GetFinite_Difference_Mode() && COutput::WriteHistoryFileOutput(config); } + +void CFlowCompOutput::SetTurboPerformance_Output(std::shared_ptr TurboPerf, + CConfig *config, + unsigned long TimeIter, + unsigned long OuterIter, + unsigned long InnerIter) { + + curTimeIter = TimeIter; + curAbsTimeIter = TimeIter - config->GetRestart_Iter(); + curOuterIter = OuterIter; + curInnerIter = InnerIter; + stringstream TurboInOutTable, TurboPerfTable; + + auto BladePerformance = TurboPerf->GetBladesPerformances(); + + /*-- Table for Turbomachinery Performance Values --*/ + PrintingToolbox::CTablePrinter TurboInOut(&TurboInOutTable); + + TurboInOutTable<<"-- Turbomachinery inlet and outlet property Summary:"<GetnZone()-1; iZone++) { + auto nSpan = config->GetnSpan_iZones(iZone); + const auto& BladePerf = BladePerformance.at(iZone).at(nSpan); + + TurboInOut<<" BLADE ROW INDEX "<GetInletState().GetEntropy() << BladePerf->GetOutletState().GetEntropy(); + TurboInOut << "Total Enthalpy " << BladePerf->GetInletState().GetTotalEnthalpy() << BladePerf->GetOutletState().GetTotalEnthalpy(); + TurboInOut << "Total Pressure " << BladePerf->GetInletState().GetTotalPressure() << BladePerf->GetOutletState().GetTotalPressure(); + TurboInOut << "Pressure " << BladePerf->GetInletState().GetPressure() << BladePerf->GetOutletState().GetPressure(); + TurboInOut << "Density " << BladePerf->GetInletState().GetDensity() << BladePerf->GetOutletState().GetDensity(); + TurboInOut << "Normal Velocity " << BladePerf->GetInletState().GetVelocity()[0] << BladePerf->GetOutletState().GetVelocity()[0]; + TurboInOut << "Tangential Velocity " << BladePerf->GetInletState().GetVelocity()[1] << BladePerf->GetOutletState().GetVelocity()[1]; + TurboInOut << "Mass Flow " << BladePerf->GetInletState().GetMassFlow() << BladePerf->GetOutletState().GetMassFlow(); + TurboInOut << "Mach " << BladePerf->GetInletState().GetMachValue() << BladePerf->GetOutletState().GetMachValue(); + TurboInOut << "Abs Flow Angle " << BladePerf->GetInletState().GetAbsFlowAngle()*180/PI_NUMBER << BladePerf->GetOutletState().GetAbsFlowAngle()*180/PI_NUMBER; + TurboInOut.PrintFooter(); + } + cout< TurboPerf, CConfig *config) { + + stringstream TurboMZPerf; + + PrintingToolbox::CTablePrinter TurboInOut(&TurboMZPerf); + + /*--- Print header for the stage performance computation ---*/ + TurboMZPerf<<"-- Turbomachinery Stage Performance --"<GetNormEntropyGen()*100 + <GetEulerianWork() + <GetTotalStaticEfficiency()*100 + <GetTotalTotalEfficiency()*100 + <GetTotalStaticPressureRatio() + <GetTotalTotalPressureRatio(); + TurboInOut.PrintFooter(); + cout< TurboPerf, CConfig *config) { + auto BladePerformance = TurboPerf->GetBladesPerformances(); + for (unsigned short iZone = 0; iZone <= config->GetnZone()-1; iZone++) { + auto nSpan = config->GetnSpan_iZones(iZone); + const auto& BladePerf = BladePerformance.at(iZone).at(nSpan); + + stringstream tag; + tag << iZone + 1; + + SetHistoryOutputValue("EntropyIn_" + tag.str(), BladePerf->GetInletState().GetEntropy()); + SetHistoryOutputValue("EntropyOut_" + tag.str(), BladePerf->GetOutletState().GetEntropy()); + SetHistoryOutputValue("TotalEntahalpyIn_" + tag.str(), BladePerf->GetInletState().GetTotalEnthalpy()); + SetHistoryOutputValue("TotalEnthalpyOut_" + tag.str(), BladePerf->GetOutletState().GetTotalEnthalpy()); + SetHistoryOutputValue("TotalPressureIn_" + tag.str(), BladePerf->GetInletState().GetTotalPressure()); + SetHistoryOutputValue("TotalPressureOut_" + tag.str(), BladePerf->GetOutletState().GetTotalPressure()); + SetHistoryOutputValue("PressureIn_" + tag.str(), BladePerf->GetInletState().GetPressure()); + SetHistoryOutputValue("PressureOut_" + tag.str(), BladePerf->GetOutletState().GetPressure()); + SetHistoryOutputValue("DensityIn_" + tag.str(), BladePerf->GetInletState().GetDensity()); + SetHistoryOutputValue("DensityOut_" + tag.str(), BladePerf->GetOutletState().GetDensity()); + SetHistoryOutputValue("NormalVelocityIn_" + tag.str(), BladePerf->GetInletState().GetVelocity()[0]); + SetHistoryOutputValue("NormalVelocityOut_" + tag.str(), BladePerf->GetOutletState().GetVelocity()[0]); + SetHistoryOutputValue("TangentialVelocityIn_" + tag.str(), BladePerf->GetInletState().GetVelocity()[1]); + SetHistoryOutputValue("TangentialVelocityOut_" + tag.str(), BladePerf->GetOutletState().GetVelocity()[1]); + SetHistoryOutputValue("MassFlowIn_" + tag.str(), BladePerf->GetInletState().GetMassFlow()); + SetHistoryOutputValue("MassFlowOut_" + tag.str(), BladePerf->GetOutletState().GetMassFlow()); + SetHistoryOutputValue("MachIn_" + tag.str(), BladePerf->GetInletState().GetMachValue()); + SetHistoryOutputValue("MachOut_" + tag.str(), BladePerf->GetOutletState().GetMachValue()); + SetHistoryOutputValue("AbsFlowAngleIn_" + tag.str(), BladePerf->GetInletState().GetAbsFlowAngle()*180/PI_NUMBER); + SetHistoryOutputValue("AbsFlowAngleOut_" + tag.str(), BladePerf->GetOutletState().GetAbsFlowAngle()*180/PI_NUMBER); + } + SetHistoryOutputValue("EntropyGeneration", TurboStagePerf->GetNormEntropyGen()*100); + SetHistoryOutputValue("EulerianWork", TurboStagePerf->GetEulerianWork()); + SetHistoryOutputValue("TotalStaticEfficiency", TurboStagePerf->GetTotalStaticEfficiency()*100); + SetHistoryOutputValue("TotalTotalEfficiency", TurboStagePerf->GetTotalTotalEfficiency()*100); + SetHistoryOutputValue("PressureRatioTS", TurboStagePerf->GetTotalStaticPressureRatio()); + SetHistoryOutputValue("PressureRatioTT", TurboStagePerf->GetTotalTotalPressureRatio()); +} + +void CFlowCompOutput::WriteTurboSpanwisePerformance(std::shared_ptr TurboPerf, CGeometry *geometry, CConfig **config, unsigned short val_iZone) { + + string inMarker_Tag, outMarker_Tag, inMarkerTag_Mix; + unsigned short nZone = config[val_iZone]->GetnZone(); + + unsigned short iDim, iSpan; + + unsigned long iExtIter = config[val_iZone]->GetOuterIter(); + const su2double* SpanWiseValuesIn, *SpanWiseValuesOut; + ofstream file; + string spanwise_performance_filename; + + auto BladePerformance = TurboPerf->GetBladesPerformances(); + + /*--- Start of write file turboperformance spanwise ---*/ + SpanWiseValuesIn = geometry->GetSpanWiseValue(INFLOW); + SpanWiseValuesOut = geometry->GetSpanWiseValue(OUTFLOW); + + /*--- Writing Span wise inflow thermodynamic quantities. ---*/ + spanwise_performance_filename = "TURBOMACHINERY/inflow_spanwise_thermodynamic_values.dat"; + if (nZone > 1) { + spanwise_performance_filename.append("_" + std::to_string(val_iZone) + ".dat"); + } else { + spanwise_performance_filename.append(".dat"); + } + file.open (spanwise_performance_filename.data(), ios::out | ios::trunc); + file.setf(ios::scientific); + file.precision(12); + + file << "TITLE = \"Inflow Spanwise Thermodynamic Values. iOuterIter = " << iExtIter << " \"" << endl; + file << "VARIABLES =" << endl; + + file.width(30); file << "\"SpanWise Value[m]\""; + file.width(15); file << "\"iSpan\""; + file.width(30); file << "\"Pressure[Pa]\""; + file.width(30); file << "\"TotalPressure[Pa]\""; + file.width(30); file << "\"Temperature[K]\""; + file.width(30); file << "\"TotalTemperature[K]\""; + file.width(30); file << "\"Enthalpy[J]\""; + file.width(30); file << "\"TotalEnthalpy[J]\""; + file.width(30); file << "\"Density[kg/m3]\""; + file.width(30); file << "\"Entropy[J/K]\""; + file << endl; + + for(iSpan = 0; iSpan < config[val_iZone]->GetnSpanWiseSections(); iSpan++){ + const auto& BladePerf = BladePerformance.at(val_iZone).at(iSpan); + + file.width(30); file << SpanWiseValuesIn[iSpan]; + file.width(15); file << iSpan; + file.width(30); file << BladePerf->GetInletState().GetPressure()*config[ZONE_0]->GetPressure_Ref(); + file.width(30); file << BladePerf->GetInletState().GetTotalPressure()*config[ZONE_0]->GetPressure_Ref(); + file.width(30); file << BladePerf->GetInletState().GetTemperature()*config[ZONE_0]->GetTemperature_Ref(); + file.width(30); file << BladePerf->GetInletState().GetTotalTemperature()*config[ZONE_0]->GetTemperature_Ref(); + file.width(30); file << BladePerf->GetInletState().GetEnthalpy()*config[ZONE_0]->GetEnergy_Ref(); + file.width(30); file << BladePerf->GetInletState().GetTotalEnthalpy()*config[ZONE_0]->GetEnergy_Ref(); + file.width(30); file << BladePerf->GetInletState().GetDensity()*config[ZONE_0]->GetDensity_Ref(); + file.width(30); file << BladePerf->GetInletState().GetEntropy()*config[ZONE_0]->GetEnergy_Ref()/config[ZONE_0]->GetTemperature_Ref(); + } + + file.close(); + + /*--- Writing Span wise outflow thermodynamic quantities. ---*/ + spanwise_performance_filename = "TURBOMACHINERY/outflow_spanwise_thermodynamic_values.dat"; + if (nZone > 1) { + spanwise_performance_filename.append("_" + std::to_string(val_iZone) + ".dat"); + } else { + spanwise_performance_filename.append(".dat"); + } + file.open (spanwise_performance_filename.data(), ios::out | ios::trunc); + file.setf(ios::scientific); + file.precision(12); + + file << "TITLE = \"Outflow Span-wise Thermodynamic Values. iOuterIter = " << iExtIter << " \"" << endl; + file << "VARIABLES =" << endl; + + file.width(30); file << "\"SpanWise Value[m]\""; + file.width(15); file << "\"iSpan\""; + file.width(30); file << "\"Pressure[Pa]\""; + file.width(30); file << "\"TotalPressure[Pa]\""; + file.width(30); file << "\"Temperature[K]\""; + file.width(30); file << "\"TotalTemperature[K]\""; + file.width(30); file << "\"Enthalpy[J]\""; + file.width(30); file << "\"TotalEnthalpy[J]\""; + file.width(30); file << "\"Density[kg/m3]\""; + file.width(30); file << "\"Entropy[J/K]\""; + file << endl; + + + for(iSpan = 0; iSpan < config[val_iZone]->GetnSpanWiseSections(); iSpan++){ + const auto& BladePerf = BladePerformance.at(val_iZone).at(iSpan); + + file.width(30); file << SpanWiseValuesOut[iSpan]; + file.width(15); file << iSpan; + file.width(30); file << BladePerf->GetOutletState().GetPressure()*config[ZONE_0]->GetPressure_Ref(); + file.width(30); file << BladePerf->GetOutletState().GetTotalPressure()*config[ZONE_0]->GetPressure_Ref(); + file.width(30); file << BladePerf->GetOutletState().GetTemperature()*config[ZONE_0]->GetTemperature_Ref(); + file.width(30); file << BladePerf->GetOutletState().GetTotalTemperature()*config[ZONE_0]->GetTemperature_Ref(); + file.width(30); file << BladePerf->GetOutletState().GetEnthalpy()*config[ZONE_0]->GetEnergy_Ref(); + file.width(30); file << BladePerf->GetOutletState().GetTotalEnthalpy()*config[ZONE_0]->GetEnergy_Ref(); + file.width(30); file << BladePerf->GetOutletState().GetDensity()*config[ZONE_0]->GetDensity_Ref(); + file.width(30); file << BladePerf->GetOutletState().GetEntropy()*config[ZONE_0]->GetEnergy_Ref()/config[ZONE_0]->GetTemperature_Ref(); + } + + file.close(); + + /*--- Writing Span wise inflow kinematic quantities. ---*/ + spanwise_performance_filename = "TURBOMACHINERY/inflow_spanwise_kinematic_values.dat"; + if (nZone > 1) { + spanwise_performance_filename.append("_" + std::to_string(val_iZone) + ".dat"); + } else { + spanwise_performance_filename.append(".dat"); + } + file.open (spanwise_performance_filename.data(), ios::out | ios::trunc); + file.setf(ios::scientific); + file.precision(12); + + file << "TITLE = \"Inflow Span-wise Kinematic Values. iOuterIter = " << iExtIter << " \"" << endl; + file << "VARIABLES =" << endl; + + file.width(30); file << "\"SpanWise Value[m]\""; + file.width(15); file << "\"iSpan\""; + file.width(30); file << "\"Normal Mach[-]\""; + file.width(30); file << "\"Tangential Mach[-]\""; + if (geometry->GetnDim() == 3) { + file.width(30); file << "\"3rd Component Mach[-]\""; + }; + file.width(30); file << "\"Mach Module[-]\""; + file.width(30); file << "\"Normal Velocity[m/s]\""; + file.width(30); file << "\"Tangential Velocity[m/s]\""; + if (geometry->GetnDim() == 3) { + file.width(30); file << "\"3rd Component Velocity[m/s]\""; + }; + file.width(30); file << "\"Velocity Module[m/s]\""; + file.width(30); file << "\"Absolute Flow Angle[deg]\""; + file.width(30); file << "\"Relative Flow Angle[deg]\""; + file << endl; + + + for(iSpan = 0; iSpan < config[val_iZone]->GetnSpanWiseSections(); iSpan++){ + const auto& BladePerf = BladePerformance.at(val_iZone).at(iSpan); + + file.width(30); file << SpanWiseValuesIn[iSpan]; + file.width(15); file << iSpan; + for (iDim = 0; iDim < geometry->GetnDim(); iDim++){ + file.width(30); file << BladePerf->GetInletState().GetMach()[iDim]; + } + file.width(30); file << BladePerf->GetInletState().GetMachValue(); + for (iDim = 0; iDim < geometry->GetnDim(); iDim++){ + file.width(30); file << BladePerf->GetInletState().GetVelocity()[iDim]*config[ZONE_0]->GetVelocity_Ref(); + } + file.width(30); file << BladePerf->GetInletState().GetVelocityValue()*config[ZONE_0]->GetVelocity_Ref(); + // This captures NaNs + if(isnan(BladePerf->GetInletState().GetAbsFlowAngle())){ + file.width(30); file << "0.0000"; + } + else { + file.width(30); file << BladePerf->GetInletState().GetAbsFlowAngle()*180.0/PI_NUMBER; + } + if(isnan(BladePerf->GetInletState().GetFlowAngle())){ + file.width(30); file << "0.0000"; + } + else{ + file.width(30); file << BladePerf->GetInletState().GetFlowAngle()*180.0/PI_NUMBER; + } + file << endl; + } + + file.close(); + + /*--- Writing Span wise outflow thermodynamic quantities. ---*/ + spanwise_performance_filename = "TURBOMACHINERY/outflow_spanwise_kinematic_values"; + if (nZone > 1) { + spanwise_performance_filename.append("_" + std::to_string(val_iZone) + ".dat"); + } else { + spanwise_performance_filename.append(".dat"); + } + file.open (spanwise_performance_filename.data(), ios::out | ios::trunc); + file.setf(ios::scientific); + file.precision(12); + + file << "TITLE = \"Outflow Span-wise Kinematic Values. iOuterIter = " << iExtIter << " \"" << endl; + file << "VARIABLES =" << endl; + + file.width(30); file << "\"SpanWise Value[m]\""; + file.width(15); file << "\"iSpan\""; + file.width(30); file << "\"Normal Mach[-]\""; + file.width(30); file << "\"Tangential Mach[-]\""; + if (geometry->GetnDim() == 3) { + file.width(30); file << "\"3rd Component Mach[-]\""; + }; + file.width(30); file << "\"Mach Module[-]\""; + file.width(30); file << "\"Normal Velocity[m/s]\""; + file.width(30); file << "\"Tangential Velocity[m/s]\""; + if (geometry->GetnDim() == 3) { + file.width(30); file << "\"3rd Component Velocity[m/s]\""; + }; + file.width(30); file << "\"Velocity Module[m/s]\""; + file.width(30); file << "\"Absolute Flow Angle[deg]\""; + file.width(30); file << "\"Relative Flow Angle[deg]\""; + file << endl; + + + for(iSpan = 0; iSpan < config[val_iZone]->GetnSpanWiseSections(); iSpan++){ + const auto& BladePerf = BladePerformance.at(val_iZone).at(iSpan); + + file.width(30); file << SpanWiseValuesOut[iSpan]; + file.width(15); file << iSpan; + for (iDim = 0; iDim < geometry->GetnDim(); iDim++){ + file.width(30); file << BladePerf->GetOutletState().GetMach()[iDim]; + } + file.width(30); file << BladePerf->GetInletState().GetMachValue(); + for (iDim = 0; iDim < geometry->GetnDim(); iDim++){ + file.width(30); file << BladePerf->GetOutletState().GetVelocity()[iDim]*config[ZONE_0]->GetVelocity_Ref(); + } + file.width(30); file << BladePerf->GetInletState().GetVelocityValue()*config[ZONE_0]->GetVelocity_Ref(); + if(isnan(BladePerf->GetInletState().GetAbsFlowAngle())){ + file.width(30); file << "0.0000"; + } + else { + file.width(30); file << BladePerf->GetOutletState().GetAbsFlowAngle()*180.0/PI_NUMBER; + } + if(isnan(BladePerf->GetInletState().GetAbsFlowAngle())){ + file.width(30); file << "0.0000"; + } + else{ + file.width(30); file << BladePerf->GetOutletState().GetFlowAngle()*180.0/PI_NUMBER; + } + file << endl; + } + + file.close(); +} \ No newline at end of file diff --git a/SU2_CFD/src/output/CFlowOutput.cpp b/SU2_CFD/src/output/CFlowOutput.cpp index 75bd80feebb..5ed2862922a 100644 --- a/SU2_CFD/src/output/CFlowOutput.cpp +++ b/SU2_CFD/src/output/CFlowOutput.cpp @@ -38,6 +38,7 @@ #include "../../include/variables/CPrimitiveIndices.hpp" #include "../../include/fluid/CCoolProp.hpp" + CFlowOutput::CFlowOutput(const CConfig *config, unsigned short nDim, bool fem_output) : CFVMOutput(config, nDim, fem_output), lastInnerIter(curInnerIter) { @@ -4049,3 +4050,37 @@ void CFlowOutput::SetFixedCLScreenOutput(const CConfig *config){ curInnerIter = config->GetInnerIter(); } } + +void CFlowOutput::AddTurboOutput(unsigned short nZone){ +//Adds zone turboperformance history variables + for (unsigned short iZone = 0; iZone <= nZone-1; iZone++) { + const auto tag = std::to_string(iZone + 1); + AddHistoryOutput("EntropyIn_" + tag, "EntropyIn_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Total pressure loss " + tag, HistoryFieldType::DEFAULT); + AddHistoryOutput("EntropyOut_" + tag, "EntropyOut_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Kinetic energy loss " + tag, HistoryFieldType::DEFAULT); + AddHistoryOutput("TotalEntahalpyIn_" + tag, "TotalEntahalpyIn_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Entropy generation " + tag, HistoryFieldType::DEFAULT); + AddHistoryOutput("TotalEnthalpyOut_" + tag, "TotalEnthalpyOut_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Eulerian work " + tag, HistoryFieldType::DEFAULT); + AddHistoryOutput("TotalPressureIn_" + tag, "TotPressureIn_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Pressure ratio " + tag, HistoryFieldType::DEFAULT); + AddHistoryOutput("TotalPressureOut_" + tag, "TotPressureOut_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Flow angle in " + tag, HistoryFieldType::DEFAULT); + AddHistoryOutput("PressureIn_" + tag, "PressureIn_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Pressure ratio " + tag, HistoryFieldType::DEFAULT); + AddHistoryOutput("PressureOut_" + tag, "PressureOut_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Flow angle in " + tag, HistoryFieldType::DEFAULT); + AddHistoryOutput("DensityIn_" + tag, "DensityIn_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Flow angle out " + tag, HistoryFieldType::DEFAULT); + AddHistoryOutput("DensityOut_" + tag, "DensityOut_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Absolute flow angle in " + tag, HistoryFieldType::DEFAULT); + AddHistoryOutput("NormalVelocityIn_" + tag, "NormalVelocityIn_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Absolute flow angle out " + tag, HistoryFieldType::DEFAULT); + AddHistoryOutput("NormalVelocityOut_" + tag, "NormalVelocityOut_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Mass flow in " + tag, HistoryFieldType::DEFAULT); + AddHistoryOutput("TangentialVelocityIn_" + tag, "TangentialVelocityIn_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Mass flow out " + tag, HistoryFieldType::DEFAULT); + AddHistoryOutput("TangentialVelocityOut_" + tag, "TangentialVelocityOut_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Mach in " + tag, HistoryFieldType::DEFAULT); + AddHistoryOutput("MassFlowIn_" + tag, "MassFlowIn_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Mach out " + tag, HistoryFieldType::DEFAULT); + AddHistoryOutput("MassFlowOut_" + tag, "MassFlowOut_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Total efficiency " + tag, HistoryFieldType::DEFAULT); + AddHistoryOutput("MachIn_" + tag, "MachIn_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Total-to-Static efficiency " + tag, HistoryFieldType::DEFAULT); + AddHistoryOutput("MachOut_" + tag, "MachOut_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Total-to-Static efficiency " + tag, HistoryFieldType::DEFAULT); + AddHistoryOutput("AbsFlowAngleIn_" + tag, "AbsFlowAngleIn_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Absolute flow angle in " + tag, HistoryFieldType::DEFAULT); + AddHistoryOutput("AbsFlowAngleOut_" + tag, "AbsFlowAngleOut_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Absolute flow angle out " + tag, HistoryFieldType::DEFAULT); + } + //Adds turbomachinery machine performance variables + AddHistoryOutput("EntropyGeneration", "EntropyGen", ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Machine entropy generation", HistoryFieldType::DEFAULT); + AddHistoryOutput("EulerianWork", "EulerianWork", ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Machine entropy generation", HistoryFieldType::DEFAULT); + AddHistoryOutput("TotalStaticEfficiency", "TotStaticEff", ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Machine entropy generation", HistoryFieldType::DEFAULT); + AddHistoryOutput("TotalTotalEfficiency", "TotTotEff", ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Machine entropy generation", HistoryFieldType::DEFAULT); + AddHistoryOutput("PressureRatioTS", "PRTS", ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Machine entropy generation", HistoryFieldType::DEFAULT); + AddHistoryOutput("PressureRatioTT", "PRTT", ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Machine entropy generation", HistoryFieldType::DEFAULT); +} diff --git a/SU2_CFD/src/output/COutput.cpp b/SU2_CFD/src/output/COutput.cpp index 4dad97f8e34..99f6203074a 100644 --- a/SU2_CFD/src/output/COutput.cpp +++ b/SU2_CFD/src/output/COutput.cpp @@ -29,6 +29,7 @@ #include "../../include/solvers/CSolver.hpp" #include "../../include/output/COutput.hpp" +#include "../../include/output/CTurboOutput.hpp" #include "../../include/output/filewriter/CFVMDataSorter.hpp" #include "../../include/output/filewriter/CFEMDataSorter.hpp" #include "../../include/output/filewriter/CCGNSFileWriter.hpp" @@ -168,8 +169,7 @@ COutput::COutput(const CConfig *config, unsigned short ndim, bool fem_output): volumeDataSorter = nullptr; surfaceDataSorter = nullptr; - headerNeeded = false; - + headerNeeded = false; } COutput::~COutput() { @@ -227,6 +227,34 @@ void COutput::SetHistoryOutput(CGeometry *geometry, } +void COutput::SetHistoryOutput(CGeometry ****geometry, CSolver *****solver, CConfig **config, CTurbomachineryStagePerformance* TurboStagePerf, std::shared_ptr TurboPerf, unsigned short val_iZone, unsigned long TimeIter, unsigned long OuterIter, unsigned long InnerIter, unsigned short val_iInst){ + + unsigned long Iter= InnerIter; + + if (config[ZONE_0]->GetMultizone_Problem()) + Iter = OuterIter; + + /*--- Turbomachinery Performance Screen summary output---*/ + if (Iter%100 == 0 && rank == MASTER_NODE) { + SetTurboPerformance_Output(TurboPerf, config[val_iZone], TimeIter, OuterIter, InnerIter); + SetTurboMultiZonePerformance_Output(TurboStagePerf, TurboPerf, config[val_iZone]); + } + + for (int iZone = 0; iZone < config[ZONE_0]->GetnZone(); iZone ++){ + if (rank == MASTER_NODE) { + WriteTurboSpanwisePerformance(TurboPerf, geometry[iZone][val_iInst][MESH_0], config, iZone); + } + } + + /*--- Update turboperformance history file*/ + if (rank == MASTER_NODE){ + LoadTurboHistoryData(TurboStagePerf, TurboPerf, config[val_iZone]); + } + SetHistoryOutput(geometry[val_iZone][val_iInst][MESH_0], solver[val_iZone][val_iInst][MESH_0], config[val_iZone], TimeIter, OuterIter,InnerIter); + +} + + void COutput::SetMultizoneHistoryOutput(COutput **output, CConfig **config, CConfig *driver_config, unsigned long TimeIter, unsigned long OuterIter){ curTimeIter = TimeIter; @@ -1151,7 +1179,7 @@ void COutput::PreprocessHistoryOutput(CConfig *config, bool wrt){ /*--- Check for consistency and remove fields that are requested but not available --- */ - CheckHistoryOutput(); + CheckHistoryOutput(config->GetnZone()); if (rank == MASTER_NODE && !noWriting){ @@ -1198,7 +1226,7 @@ void COutput::PreprocessMultizoneHistoryOutput(COutput **output, CConfig **confi /*--- Check for consistency and remove fields that are requested but not available --- */ - CheckHistoryOutput(); + CheckHistoryOutput(config[ZONE_0]->GetnZone()); if (rank == MASTER_NODE && !noWriting){ @@ -1240,7 +1268,7 @@ void COutput::PrepareHistoryFile(CConfig *config){ } -void COutput::CheckHistoryOutput() { +void COutput::CheckHistoryOutput(unsigned short nZone) { /*--- Set screen convergence output header and remove unavailable fields ---*/ @@ -1318,6 +1346,17 @@ void COutput::CheckHistoryOutput() { FieldsToRemove.clear(); vector FoundField(nRequestedHistoryFields, false); + /*--- Checks if TURBO_PERF is enabled in config and sets the final zone calculations to be output ---*/ + + for (unsigned short iReqField = 0; iReqField < nRequestedHistoryFields; iReqField++){ + if (requestedHistoryFields[iReqField] == "TURBO_PERF" && nZone > 1){ + std::stringstream reqField; + std::string strZones = std::to_string(nZone-1); + reqField << "TURBO_PERF[" << strZones << "]"; + reqField >> requestedHistoryFields[iReqField]; + } + } + for (const auto& fieldReference : historyOutput_List) { const auto &field = historyOutput_Map.at(fieldReference); for (unsigned short iReqField = 0; iReqField < nRequestedHistoryFields; iReqField++) { @@ -2375,4 +2414,4 @@ void COutput::PrintVolumeFields(){ VolumeFieldTable.PrintFooter(); } -} +} \ No newline at end of file diff --git a/SU2_CFD/src/output/CTurboOutput.cpp b/SU2_CFD/src/output/CTurboOutput.cpp new file mode 100644 index 00000000000..c17f78f87cc --- /dev/null +++ b/SU2_CFD/src/output/CTurboOutput.cpp @@ -0,0 +1,271 @@ +/*! + * \file CTurboOutput.cpp + * \brief Source of the Turbomachinery Performance class + * \author S. Vitale, N. Anand + * \version 8.0.0 "Harrier" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2023, 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/output/CTurboOutput.hpp" + +CTurbomachineryPrimitiveState::CTurbomachineryPrimitiveState() { Density = Pressure = TangVelocity = 0.0; } +CTurbomachineryPrimitiveState::CTurbomachineryPrimitiveState(vector TurboPrimitive, unsigned short nDim, + su2double tangVel) + : Density(TurboPrimitive[0]), Pressure(TurboPrimitive[1]), TangVelocity(tangVel) { + Velocity = {TurboPrimitive.begin() + 2, TurboPrimitive.end()}; +} + +CTurbomachineryCombinedPrimitiveStates::CTurbomachineryCombinedPrimitiveStates( + const CTurbomachineryPrimitiveState& inletPrimitiveState, const CTurbomachineryPrimitiveState& outletPrimitiveState) + : InletPrimitiveState(inletPrimitiveState), OutletPrimitiveState(outletPrimitiveState) {} + +CTurbomachineryState::CTurbomachineryState() { + Density = Pressure = Entropy = Enthalpy = Temperature = TotalTemperature = TotalPressure = TotalEnthalpy = 0.0; + AbsFlowAngle = FlowAngle = MassFlow = Rothalpy = TotalRelPressure = 0.0; + Area = Radius = 0.0; +} + +CTurbomachineryState::CTurbomachineryState(unsigned short nDim, su2double area, su2double radius) + : CTurbomachineryState() { + generate_n(back_inserter(Velocity), nDim, [] { return 0.0; }); + generate_n(back_inserter(RelVelocity), nDim, [] { return 0.0; }); + generate_n(back_inserter(Mach), nDim, [] { return 0.0; }); + generate_n(back_inserter(RelMach), nDim, [] { return 0.0; }); + Area = area; + Radius = radius; +} + +void CTurbomachineryState::ComputeState(CFluidModel& fluidModel, const CTurbomachineryPrimitiveState& primitiveState) { + /*--- Assign new primitive values ---*/ + Density = primitiveState.GetDensity(); + Pressure = primitiveState.GetPressure(); + std::vector velocity = primitiveState.GetVelocity(); + Velocity.assign(velocity.begin(), velocity.end()); + su2double tangVel = primitiveState.GetTangVelocity(); + + /*--- Compute static TD quantities ---*/ + fluidModel.SetTDState_Prho(Pressure, Density); + Entropy = fluidModel.GetEntropy(); + Enthalpy = fluidModel.GetStaticEnergy() + Pressure / Density; + su2double soundSpeed = fluidModel.GetSoundSpeed(); + + /*--- Compute total TD quantities ---*/ + TotalEnthalpy = Enthalpy + 0.5 * GetVelocityValue() * GetVelocityValue(); + fluidModel.SetTDState_hs(TotalEnthalpy, Entropy); + TotalPressure = fluidModel.GetPressure(); + TotalTemperature = fluidModel.GetTemperature(); + + /*--- Compute absolute kinematic quantities---*/ + MassFlow = Density * Velocity[0] * Area; + AbsFlowAngle = atan(Velocity[1] / Velocity[0]); + Mach.assign(Velocity.begin(), Velocity.end()); + std::for_each(Mach.begin(), Mach.end(), [&](su2double& el) { el /= soundSpeed; }); + + /*--- Compute relative kinematic quantities ---*/ + su2double tangVel2 = tangVel * tangVel; + RelVelocity.assign(Velocity.begin(), Velocity.end()); + RelVelocity[1] -= tangVel; + su2double relVel2 = GetRelVelocityValue(); + FlowAngle = atan(RelVelocity[1] / RelVelocity[0]); + RelMach.assign(RelVelocity.begin(), RelVelocity.end()); + std::for_each(RelMach.begin(), RelMach.end(), [&](su2double& el) { el /= soundSpeed; }); + + /*--- Compute total relative TD quantities ---*/ + Rothalpy = Enthalpy + 0.5 * relVel2 - 0.5 * tangVel2; + fluidModel.SetTDState_hs(Rothalpy, Entropy); + TotalRelPressure = fluidModel.GetPressure(); + + /*--- Compute isentropic quantities ---*/ + fluidModel.SetTDState_Ps(Pressure, Entropy); +} + +CTurbomachineryBladePerformance::CTurbomachineryBladePerformance(CFluidModel& fluidModel, unsigned short nDim, + su2double areaIn, su2double radiusIn, + su2double areaOut, su2double radiusOut) + : FluidModel(fluidModel) { + InletState = CTurbomachineryState(nDim, areaIn, radiusIn); + OutletState = CTurbomachineryState(nDim, areaOut, radiusOut); +} + +CTurbineBladePerformance::CTurbineBladePerformance(CFluidModel& fluidModel, unsigned short nDim, su2double areaIn, + su2double radiusIn, su2double areaOut, su2double radiusOut) + : CTurbomachineryBladePerformance(fluidModel, nDim, areaIn, radiusIn, areaOut, radiusOut) {} + +void CTurbineBladePerformance::ComputePerformance(const CTurbomachineryCombinedPrimitiveStates& primitives) { + /*--- Compute Inlet and Outlet state ---*/ + InletState.ComputeState(FluidModel, primitives.GetInletPrimitiveState()); + OutletState.ComputeState(FluidModel, primitives.GetOutletPrimitiveState()); + + /*--- Compute isentropic Outflow quantities ---*/ + FluidModel.SetTDState_Ps(OutletState.GetPressure(), InletState.GetEntropy()); + su2double enthalpyOutIs = FluidModel.GetStaticEnergy() + OutletState.GetPressure() / FluidModel.GetDensity(); + su2double tangVel = primitives.GetOutletPrimitiveState().GetTangVelocity(); + su2double relVelOutIs2 = 2 * (OutletState.GetRothalpy() - enthalpyOutIs) + tangVel * tangVel; + + /*--- Compute performance ---*/ + EntropyGen = (OutletState.GetEntropy() - InletState.GetEntropy()); + EulerianWork = InletState.GetTotalEnthalpy() - OutletState.GetTotalEnthalpy(); + TotalPressureLoss = (InletState.GetTotalRelPressure() - OutletState.GetTotalRelPressure()) / + (OutletState.GetTotalRelPressure() - OutletState.GetPressure()); + KineticEnergyLoss = 2 * (OutletState.GetEnthalpy() - enthalpyOutIs) / relVelOutIs2; +} + +CCompressorBladePerformance::CCompressorBladePerformance(CFluidModel& fluidModel, unsigned short nDim, su2double areaIn, + su2double radiusIn, su2double areaOut, su2double radiusOut) + : CTurbomachineryBladePerformance(fluidModel, nDim, areaIn, radiusIn, areaOut, radiusOut) {} + +void CCompressorBladePerformance::ComputePerformance(const CTurbomachineryCombinedPrimitiveStates& primitives) { + /*--- Compute Inlet and Outlet state ---*/ + InletState.ComputeState(FluidModel, primitives.GetInletPrimitiveState()); + OutletState.ComputeState(FluidModel, primitives.GetOutletPrimitiveState()); + + /*--- Compute isentropic Outflow quantities ---*/ + FluidModel.SetTDState_Ps(OutletState.GetPressure(), InletState.GetEntropy()); + su2double enthalpyOutIs = FluidModel.GetStaticEnergy() + OutletState.GetPressure() / FluidModel.GetDensity(); + su2double tangVel = primitives.GetOutletPrimitiveState().GetTangVelocity(); + su2double relVelOutIs2 = 2 * (OutletState.GetRothalpy() - enthalpyOutIs) + tangVel * tangVel; + + /*--- Compute performance ---*/ + EntropyGen = (OutletState.GetEntropy() - InletState.GetEntropy()); + EulerianWork = OutletState.GetTotalEnthalpy() - InletState.GetTotalEnthalpy(); + TotalPressureLoss = (InletState.GetTotalRelPressure() - OutletState.GetTotalRelPressure()) / + (InletState.GetTotalRelPressure() - InletState.GetPressure()); + KineticEnergyLoss = 2 * (OutletState.GetEnthalpy() - enthalpyOutIs) / relVelOutIs2; +} + +CPropellorBladePerformance::CPropellorBladePerformance(CFluidModel& fluidModel, unsigned short nDim, su2double areaIn, + su2double radiusIn, su2double areaOut, su2double radiusOut) + : CTurbomachineryBladePerformance(fluidModel, nDim, areaIn, radiusIn, areaOut, radiusOut) {} + +void CPropellorBladePerformance::ComputePerformance(const CTurbomachineryCombinedPrimitiveStates& primitives) { + // TODO: to be implemented +} + +CTurboOutput::CTurboOutput(CConfig** config, const CGeometry& geometry, CFluidModel& fluidModel) { + unsigned short nBladesRow = config[ZONE_0]->GetnMarker_Turbomachinery(); + unsigned short nDim = geometry.GetnDim(); + + for (unsigned short iBladeRow = 0; iBladeRow < nBladesRow; iBladeRow++) { + vector> bladeSpanPerformances; + unsigned short nSpan = config[iBladeRow]->GetnSpanWiseSections(); + for (unsigned short iSpan = 0; iSpan < nSpan + 1; iSpan++) { + su2double areaIn = geometry.GetSpanAreaIn(iBladeRow, iSpan); + su2double areaOut = geometry.GetSpanAreaOut(iBladeRow, iSpan); + su2double radiusIn = geometry.GetTurboRadiusIn(iBladeRow, iSpan); + su2double radiusOut = geometry.GetTurboRadiusOut(iBladeRow, iSpan); + + /* Switch between the Turbomachinery Performance Kind */ + switch (config[ZONE_0]->GetKind_TurboPerf(iBladeRow)) { + case TURBO_PERF_KIND::TURBINE: + bladeSpanPerformances.push_back( + make_shared(fluidModel, nDim, areaIn, radiusIn, areaOut, radiusOut)); + break; + + case TURBO_PERF_KIND::COMPRESSOR: + bladeSpanPerformances.push_back( + make_shared(fluidModel, nDim, areaIn, radiusIn, areaOut, radiusOut)); + break; + + case TURBO_PERF_KIND::PROPELLOR: + bladeSpanPerformances.push_back( + make_shared(fluidModel, nDim, areaIn, radiusIn, areaOut, radiusOut)); + break; + + default: + bladeSpanPerformances.push_back( + make_shared(fluidModel, nDim, areaIn, radiusIn, areaOut, radiusOut)); + break; + } + } + BladesPerformances.push_back(bladeSpanPerformances); + } +} + +void CTurboOutput::ComputeTurbomachineryPerformance( + vector> const bladesPrimitives) { + for (unsigned i = 0; i < BladesPerformances.size(); ++i) { + ComputePerBlade(BladesPerformances[i], bladesPrimitives[i]); + } +} + +void CTurboOutput::ComputePerBlade(vector> const bladePerformances, + vector const bladePrimitives) { + for (unsigned i = 0; i < bladePerformances.size(); ++i) { + ComputePerSpan(bladePerformances[i], bladePrimitives[i]); + } +} + +void CTurboOutput::ComputePerSpan(shared_ptr const spanPerformances, + const CTurbomachineryCombinedPrimitiveStates& spanPrimitives) { + spanPerformances->ComputePerformance(spanPrimitives); +} + +CTurbomachineryStagePerformance::CTurbomachineryStagePerformance(CFluidModel& fluid) : fluidModel(fluid) {} + +void CTurbomachineryStagePerformance::ComputePerformanceStage(const CTurbomachineryState& InState, + const CTurbomachineryState& OutState, const CConfig* config) { + switch (config->GetKind_TurboPerf(ZONE_0)) { + case TURBO_PERF_KIND::TURBINE: + ComputeTurbineStagePerformance(InState, OutState); + break; + + case TURBO_PERF_KIND::COMPRESSOR: + ComputeCompressorStagePerformance(InState, OutState); + break; + + default: + ComputeTurbineStagePerformance(InState, OutState); + break; + } +} + +void CTurbomachineryStagePerformance::ComputeTurbineStagePerformance(const CTurbomachineryState& InState, + const CTurbomachineryState& OutState) { + /*--- Compute isentropic Outflow quantities ---*/ + fluidModel.SetTDState_Ps(OutState.GetPressure(), InState.GetEntropy()); + su2double enthalpyOutIs = fluidModel.GetStaticEnergy() + OutState.GetPressure() / fluidModel.GetDensity(); + su2double totEnthalpyOutIs = enthalpyOutIs + 0.5 * OutState.GetVelocityValue() * OutState.GetVelocityValue(); + + /*--- Compute turbine stage performance ---*/ + NormEntropyGen = (OutState.GetEntropy() - InState.GetEntropy()) / InState.GetEntropy(); + EulerianWork = InState.GetTotalEnthalpy() - OutState.GetTotalEnthalpy(); + TotalStaticEfficiency = EulerianWork / (InState.GetTotalEnthalpy() - enthalpyOutIs); + TotalTotalEfficiency = EulerianWork / (InState.GetTotalEnthalpy() - totEnthalpyOutIs); + TotalStaticPressureRatio = InState.GetTotalPressure() / OutState.GetPressure(); + TotalTotalPressureRatio = InState.GetTotalPressure() / OutState.GetTotalPressure(); +} + +void CTurbomachineryStagePerformance::ComputeCompressorStagePerformance(const CTurbomachineryState& InState, + const CTurbomachineryState& OutState) { + /*--- Compute isentropic Outflow quantities ---*/ + fluidModel.SetTDState_Ps(OutState.GetPressure(), InState.GetEntropy()); + su2double enthalpyOutIs = fluidModel.GetStaticEnergy() + OutState.GetPressure() / fluidModel.GetDensity(); + su2double totEnthalpyOutIs = enthalpyOutIs + 0.5 * OutState.GetVelocityValue() * OutState.GetVelocityValue(); + + /*--- Compute compressor stage performance ---*/ + NormEntropyGen = (OutState.GetEntropy() - InState.GetEntropy()) / InState.GetEntropy(); + EulerianWork = OutState.GetTotalEnthalpy() - InState.GetTotalEnthalpy(); + TotalStaticEfficiency = (enthalpyOutIs - InState.GetTotalEnthalpy()) / EulerianWork; + TotalTotalEfficiency = (totEnthalpyOutIs - InState.GetTotalEnthalpy()) / EulerianWork; + TotalStaticPressureRatio = OutState.GetPressure() / InState.GetTotalPressure(); + TotalTotalPressureRatio = OutState.GetTotalPressure() / InState.GetTotalPressure(); +} \ No newline at end of file diff --git a/SU2_CFD/src/output/filewriter/CCGNSFileWriter.cpp b/SU2_CFD/src/output/filewriter/CCGNSFileWriter.cpp index 34f75473b61..a4b89f39551 100644 --- a/SU2_CFD/src/output/filewriter/CCGNSFileWriter.cpp +++ b/SU2_CFD/src/output/filewriter/CCGNSFileWriter.cpp @@ -38,7 +38,6 @@ void CCGNSFileWriter::WriteData(string val_filename) { /*--- We append the pre-defined suffix (extension) to the filename (prefix) ---*/ val_filename.append(fileExt); - /*--- Open the CGNS file for writing. ---*/ InitializeMeshFile(val_filename); @@ -132,15 +131,16 @@ void CCGNSFileWriter::WriteField(int iField, const string& FieldName) { /*--- Coordinate vector is written in blocks, one for each process. ---*/ cgsize_t nodeBegin = 1; auto nodeEnd = static_cast(nLocalPoints); - - if (isCoord) { - int CoordinateNumber; - CallCGNS(cg_coord_partial_write(cgnsFileID, cgnsBase, cgnsZone, dataType, FieldName.c_str(), &nodeBegin, &nodeEnd, - sendBufferField.data(), &CoordinateNumber)); - } else { - int fieldNumber; - CallCGNS(cg_field_partial_write(cgnsFileID, cgnsBase, cgnsZone, cgnsFields, dataType, FieldName.c_str(), &nodeBegin, - &nodeEnd, sendBufferField.data(), &fieldNumber)); + if (nLocalPoints > 0) { + if (isCoord) { + int CoordinateNumber; + CallCGNS(cg_coord_partial_write(cgnsFileID, cgnsBase, cgnsZone, dataType, FieldName.c_str(), &nodeBegin, &nodeEnd, + sendBufferField.data(), &CoordinateNumber)); + } else { + int fieldNumber; + CallCGNS(cg_field_partial_write(cgnsFileID, cgnsBase, cgnsZone, cgnsFields, dataType, FieldName.c_str(), &nodeBegin, + &nodeEnd, sendBufferField.data(), &fieldNumber)); + } } for (int i = 0; i < size; ++i) { diff --git a/SU2_CFD/src/python_wrapper_structure.cpp b/SU2_CFD/src/python_wrapper_structure.cpp index 490cc193953..cac6186e04c 100644 --- a/SU2_CFD/src/python_wrapper_structure.cpp +++ b/SU2_CFD/src/python_wrapper_structure.cpp @@ -163,3 +163,15 @@ void CDriver::SetRotationRate(passivedouble rot_x, passivedouble rot_y, passived main_config->SetRotation_Rate(2, rot_z); } +void CDriver::SetMarkerRotationRate(unsigned short iMarker, passivedouble rot_x, passivedouble rot_y, passivedouble rot_z) { + config_container[selected_zone]->SetMarkerRotationRate(iMarker, 0, rot_x); + config_container[selected_zone]->SetMarkerRotationRate(iMarker, 1, rot_y); + config_container[selected_zone]->SetMarkerRotationRate(iMarker, 2, rot_z); +} + +void CDriver::SetMarkerTranslationRate(unsigned short iMarker, passivedouble vel_x, passivedouble vel_y, passivedouble vel_z) { + config_container[selected_zone]->SetMarkerTranslationRate(iMarker, 0, vel_x); + config_container[selected_zone]->SetMarkerTranslationRate(iMarker, 1, vel_y); + config_container[selected_zone]->SetMarkerTranslationRate(iMarker, 2, vel_z); +} + diff --git a/SU2_CFD/src/solvers/CEulerSolver.cpp b/SU2_CFD/src/solvers/CEulerSolver.cpp index ca9233f7df2..b98dddbd109 100644 --- a/SU2_CFD/src/solvers/CEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CEulerSolver.cpp @@ -36,6 +36,7 @@ #include "../../include/fluid/CCoolProp.hpp" #include "../../include/numerics_simd/CNumericsSIMD.hpp" #include "../../include/limiters/CLimiterDetails.hpp" +#include "../../include/output/CTurboOutput.hpp" CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config, @@ -9135,7 +9136,7 @@ void CEulerSolver::TurboAverageProcess(CSolver **solver, CGeometry *geometry, CC const bool belowMachLimit = (abs(MachTest)< config->GetAverageMachLimit()); su2double avgDensity{0}, avgPressure{0}, avgKine{0}, avgOmega{0}, avgNu{0}, - avgVelocity[MAXNDIM] = {0}, avgMixTurboVelocity[MAXNDIM] = {0}; + avgVelocity[MAXNDIM] = {0}; for (auto iVar = 0u; iVarGetKind_TurboMachinery(iZone)); } diff --git a/TestCases/cgns_writer/config.cfg b/TestCases/cgns_writer/config.cfg new file mode 100644 index 00000000000..12930ef75c9 --- /dev/null +++ b/TestCases/cgns_writer/config.cfg @@ -0,0 +1,96 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Subsonic U-Turn % +% Author: Andrea Rausa % +% Institution: Politecnico di Milano % +% Date: 12/2/2023 % +% File Version 8.0.0 "Harrier" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +SOLVER= RANS +KIND_TURB_MODEL= SST +MATH_PROBLEM= DIRECT +RESTART_SOL= NO + +% -------------------- COMPRESSIBLE FREE-STREAM DEFINITION --------------------% +% +MACH_NUMBER= 0.2 +AOA= 0.0 +FREESTREAM_TEMPERATURE= 270.0 +REYNOLDS_NUMBER= 3.28E6 +REYNOLDS_LENGTH= 1 +REF_DIMENSIONALIZATION= FREESTREAM_VEL_EQ_MACH + +% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% +% +REF_ORIGIN_MOMENT_X = -0.2473 +REF_ORIGIN_MOMENT_Y = 0.00 +REF_ORIGIN_MOMENT_Z = 0.00 +REF_LENGTH= 1 +REF_AREA= 1 + +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +MARKER_HEATFLUX= ( OuterWall, 0.0, InnerWall, 0.0 ) +MARKER_FAR= ( Inlet, Outlet ) +MARKER_PLOTTING= ( InnerWall ) +MARKER_MONITORING= ( InnerWall ) + +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +LINEAR_SOLVER= FGMRES +LINEAR_SOLVER_PREC= ILU +LINEAR_SOLVER_ERROR= 1.0e-6 +LINEAR_SOLVER_ITER= 15 + +% -------------------------- MULTIGRID PARAMETERS -----------------------------% +% +CFL_ADAPT= YES +CFL_NUMBER= 1 +CFL_REDUCTION_TURB= 1.0 +CFL_ADAPT_PARAM= ( 0.5, 1.01, 1.0, 5, 0.0001) +ITER= 1 + +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +CONV_NUM_METHOD_FLOW= ROE +USE_VECTORIZATION= YES +MUSCL_FLOW= NO +SLOPE_LIMITER_FLOW= VENKATAKRISHNAN +VENKAT_LIMITER_COEFF= 0.03 +TIME_DISCRE_FLOW= EULER_IMPLICIT + +% -------------------- TURBULENT NUMERICAL METHOD DEFINITION ------------------% +% +CONV_NUM_METHOD_TURB= SCALAR_UPWIND +MUSCL_TURB= NO +TIME_DISCRE_TURB= EULER_IMPLICIT + + +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +CONV_FIELD= MOMENT_X +CONV_STARTITER= 10 +CONV_CAUCHY_ELEMS= 100 +CONV_CAUCHY_EPS= 1E-6 + +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +MESH_FILENAME= mesh.su2 +MESH_FORMAT= SU2 +SOLUTION_FILENAME= restart_flow +TABULAR_FORMAT= CSV +CONV_FILENAME= history_First +RESTART_FILENAME= restart_flow +VOLUME_FILENAME= flow +SURFACE_FILENAME= surface_flow +OUTPUT_WRT_FREQ= 100 +SCREEN_OUTPUT= (INNER_ITER, WALL_TIME, RMS_DENSITY, LIFT, DRAG, MOMENT_Z) +OUTPUT_FILES= (SURFACE_CGNS) +WRT_FORCES_BREAKDOWN= NO +VOLUME_OUTPUT= (COORDINATES) +HISTORY_OUTPUT= (ITER) diff --git a/TestCases/disc_adj_turbomachinery/transonic_stator_2D/transonic_stator.cfg b/TestCases/disc_adj_turbomachinery/transonic_stator_2D/transonic_stator.cfg index 0afb824397b..917b5c738e4 100644 --- a/TestCases/disc_adj_turbomachinery/transonic_stator_2D/transonic_stator.cfg +++ b/TestCases/disc_adj_turbomachinery/transonic_stator_2D/transonic_stator.cfg @@ -75,6 +75,7 @@ SPATIAL_FOURIER= YES %---------------------------- TURBOMACHINERY SIMULATION -----------------------------% % TURBOMACHINERY_KIND = AXIAL +TURBO_PERF_KIND = TURBINE RAMP_OUTLET_PRESSURE= NO RAMP_OUTLET_PRESSURE_COEFF= (700000.0, 10.0, 500) AVERAGE_PROCESS_KIND= MIXEDOUT diff --git a/TestCases/hybrid_regression.py b/TestCases/hybrid_regression.py index 1f21bf4a9ad..16176bd5d8a 100644 --- a/TestCases/hybrid_regression.py +++ b/TestCases/hybrid_regression.py @@ -436,7 +436,7 @@ def main(): cavity.cfg_dir = "moving_wall/cavity" cavity.cfg_file = "lam_cavity.cfg" cavity.test_iter = 25 - cavity.test_vals = [-5.627934, -0.164469, 0.052000, 2.547063] + cavity.test_vals = [-5.627868, -0.164404, 0.053310, 2.545839] test_list.append(cavity) # Spinning cylinder @@ -444,8 +444,8 @@ def main(): spinning_cylinder.cfg_dir = "moving_wall/spinning_cylinder" spinning_cylinder.cfg_file = "spinning_cylinder.cfg" spinning_cylinder.test_iter = 25 - spinning_cylinder.test_vals = [-8.001291, -2.607959, 1.501321, 1.488559] - spinning_cylinder.test_vals_aarch64 = [-8.001291, -2.607959, 1.501321, 1.488559] + spinning_cylinder.test_vals = [-8.006541, -2.609759, 1.495662, 1.486341] + spinning_cylinder.test_vals_aarch64 = [-8.006541, -2.609759, 1.495662, 1.486341] test_list.append(spinning_cylinder) ###################################### @@ -561,7 +561,7 @@ def main(): Jones_tc_restart.cfg_dir = "turbomachinery/APU_turbocharger" Jones_tc_restart.cfg_file = "Jones_restart.cfg" Jones_tc_restart.test_iter = 5 - Jones_tc_restart.test_vals = [-6.604542, -2.792279, -14.328530, -8.769313, -11.371439, -5.845633, 73273.000000, 73273.000000] + Jones_tc_restart.test_vals = [-6.594590, -2.792279, -14.336129, -8.776066, -11.371439, -5.845633, 73273, 73273, 0.019884, 82.491] test_list.append(Jones_tc_restart) # 2D axial stage @@ -569,7 +569,8 @@ def main(): axial_stage2D.cfg_dir = "turbomachinery/axial_stage_2D" axial_stage2D.cfg_file = "Axial_stage2D.cfg" axial_stage2D.test_iter = 20 - axial_stage2D.test_vals = [0.974788, 1.534326, -2.897693, 2.599374, -2.418314, 3.087291, 106380.000000, 106380.000000] + axial_stage2D.test_vals = [0.983739, 1.534333, -2.888521, 2.606770, -2.418339, 3.087275, 106380, 106380, 5.7325, 64.711] + axial_stage2D.test_vals_aarch64 = [0.983739, 1.534333, -2.888521, 2.606770, -2.418339, 3.087275, 106380, 106380, 5.7325, 64.711] test_list.append(axial_stage2D) # 2D transonic stator restart @@ -577,7 +578,8 @@ def main(): transonic_stator_restart.cfg_dir = "turbomachinery/transonic_stator_2D" transonic_stator_restart.cfg_file = "transonic_stator_restart.cfg" transonic_stator_restart.test_iter = 20 - transonic_stator_restart.test_vals = [-5.346503, -3.510597, -3.156830, 0.752511, -3.834382, 1.816610, -471690] + transonic_stator_restart.test_vals = [-5.007735, -3.099310, -2.751696, 1.091966, -3.542819, 2.163237, -471630, 94.866, -0.035738] + transonic_stator_restart.test_vals_aarch64 = [-5.007735, -3.099310, -2.751696, 1.091966, -3.542819, 2.163237, -471630, 94.866, -0.035738] test_list.append(transonic_stator_restart) ###################################### diff --git a/TestCases/hybrid_regression_AD.py b/TestCases/hybrid_regression_AD.py index 7205140ad4c..dbaab977df3 100644 --- a/TestCases/hybrid_regression_AD.py +++ b/TestCases/hybrid_regression_AD.py @@ -242,7 +242,7 @@ def main(): pywrapper_FEA_AD_FlowLoad.test_vals_aarch64 = [-0.131745, -0.553214, -0.000364, -0.003101] pywrapper_FEA_AD_FlowLoad.command = TestCase.Command(exec = "python", param = "run_adjoint.py --parallel -f") pywrapper_FEA_AD_FlowLoad.timeout = 1600 - pywrapper_FEA_AD_FlowLoad.tol = 5e-3 + pywrapper_FEA_AD_FlowLoad.tol = 1e-2 pywrapper_FEA_AD_FlowLoad.new_output = False pywrapper_FEA_AD_FlowLoad.enabled_with_tsan = False test_list.append(pywrapper_FEA_AD_FlowLoad) @@ -257,7 +257,7 @@ def main(): pywrapper_CFD_AD_MeshDisp.test_vals_aarch64 = [30.000000, -2.516536, 1.386443, 0.000000] pywrapper_CFD_AD_MeshDisp.command = TestCase.Command(exec = "python", param = "run_adjoint.py --parallel -f") pywrapper_CFD_AD_MeshDisp.timeout = 1600 - pywrapper_CFD_AD_MeshDisp.tol = 1e-3 + pywrapper_CFD_AD_MeshDisp.tol = 1e-2 pywrapper_CFD_AD_MeshDisp.new_output = False pywrapper_CFD_AD_MeshDisp.enabled_with_tsan = False test_list.append(pywrapper_CFD_AD_MeshDisp) diff --git a/TestCases/parallel_regression.py b/TestCases/parallel_regression.py index 3278b46e737..946cc6b52b3 100644 --- a/TestCases/parallel_regression.py +++ b/TestCases/parallel_regression.py @@ -925,7 +925,7 @@ def main(): cavity.cfg_dir = "moving_wall/cavity" cavity.cfg_file = "lam_cavity.cfg" cavity.test_iter = 25 - cavity.test_vals = [-5.611007, -0.146826, 1.113206, 1.491678] + cavity.test_vals = [-5.610928, -0.146749, 1.114461, 1.490381] test_list.append(cavity) # Spinning cylinder @@ -933,7 +933,7 @@ def main(): spinning_cylinder.cfg_dir = "moving_wall/spinning_cylinder" spinning_cylinder.cfg_file = "spinning_cylinder.cfg" spinning_cylinder.test_iter = 25 - spinning_cylinder.test_vals = [-7.802803, -2.362844, 1.687705, 1.519676] + spinning_cylinder.test_vals = [-7.806016, -2.364954, 1.683365, 1.517059] test_list.append(spinning_cylinder) ###################################### @@ -1049,7 +1049,7 @@ def main(): Jones_tc_restart.cfg_dir = "turbomachinery/APU_turbocharger" Jones_tc_restart.cfg_file = "Jones_restart.cfg" Jones_tc_restart.test_iter = 5 - Jones_tc_restart.test_vals = [-6.604542, -2.792281, -14.328530, -8.769313, -11.371439, -5.845632, 73273, 73273] + Jones_tc_restart.test_vals = [-6.594590, -2.792281, -14.336129, -8.776067, -11.371439, -5.845633, 73273, 73273, 0.019884, 82.491] test_list.append(Jones_tc_restart) # 2D axial stage @@ -1057,7 +1057,8 @@ def main(): axial_stage2D.cfg_dir = "turbomachinery/axial_stage_2D" axial_stage2D.cfg_file = "Axial_stage2D.cfg" axial_stage2D.test_iter = 20 - axial_stage2D.test_vals = [0.974805, 1.534447, -2.897694, 2.599376, -2.418379, 3.087219, 106380.000000, 106380.000000] + axial_stage2D.test_vals = [0.983754, 1.534455, -2.888523, 2.606770, -2.418403, 3.087203, 106380, 106380, 5.7325, 64.711] + axial_stage2D.test_vals_aarch64 = [0.983754, 1.534455, -2.888523, 2.606770, -2.418403, 3.087203, 106380, 106380, 5.7325, 64.711] test_list.append(axial_stage2D) # 2D transonic stator restart @@ -1065,7 +1066,8 @@ def main(): transonic_stator_restart.cfg_dir = "turbomachinery/transonic_stator_2D" transonic_stator_restart.cfg_file = "transonic_stator_restart.cfg" transonic_stator_restart.test_iter = 20 - transonic_stator_restart.test_vals = [-5.354418, -3.509964, -3.163206, 0.744733, -3.846691, 1.805587, -471690] + transonic_stator_restart.test_vals = [-5.011834, -3.091110, -2.757795, 1.087934, -3.544707, 2.166101, -471630, 94.868, -0.035888] + transonic_stator_restart.test_vals_aarch64 = [-5.011834, -3.091110, -2.757795, 1.087934, -3.544707, 2.166101, -471630, 94.868, -0.035888] test_list.append(transonic_stator_restart) ###################################### @@ -1555,6 +1557,20 @@ def main(): species3_multizone_restart.multizone = True test_list.append(species3_multizone_restart) + ##################### + ## CGNS writer ### + ##################### + + # CGNS writer + cgns_writer = TestCase('cgns_writer') + cgns_writer.cfg_dir = "cgns_writer" + cgns_writer.cfg_file = "config.cfg" + cgns_writer.test_iter = 1 + cgns_writer.test_vals = [-2.974473, 0.665204, 5.068846, -7.003873] + cgns_writer.command = TestCase.Command("mpirun -n 2", "SU2_CFD") + cgns_writer.new_output = True + test_list.append(cgns_writer) + ###################################### ### RUN TESTS ### ###################################### diff --git a/TestCases/parallel_regression_AD.py b/TestCases/parallel_regression_AD.py index 10a28c974e1..30309fac00c 100644 --- a/TestCases/parallel_regression_AD.py +++ b/TestCases/parallel_regression_AD.py @@ -230,8 +230,8 @@ def main(): discadj_trans_stator.cfg_dir = "disc_adj_turbomachinery/transonic_stator_2D" discadj_trans_stator.cfg_file = "transonic_stator.cfg" discadj_trans_stator.test_iter = 79 - discadj_trans_stator.test_vals = [79, 0.769972, 0.374328, 0.474458, -0.996522, 2.154079, -4.446062] - discadj_trans_stator.test_vals_aarch64 = [79.000000, 0.769908, 0.374328, 0.474687, -0.996522, 2.154079, -4.446062] + discadj_trans_stator.test_vals = [79, 0.769967, 0.374299, 0.474436, -0.996528, 2.154053, -4.446085] + discadj_trans_stator.test_vals_aarch64 = [79, 0.769967, 0.374299, 0.474436, -0.996528, 2.154053, -4.446085] test_list.append(discadj_trans_stator) ################################### diff --git a/TestCases/py_wrapper/rotating_cylinder/run.py b/TestCases/py_wrapper/rotating_cylinder/run.py new file mode 100644 index 00000000000..537cdcb696e --- /dev/null +++ b/TestCases/py_wrapper/rotating_cylinder/run.py @@ -0,0 +1,19 @@ +import pysu2 # imports the SU2 wrapped module +from mpi4py import MPI +import numpy as np + +comm = MPI.COMM_WORLD +rank = comm.Get_rank() +rotation_vector = np.linspace(0,20,10) +SU2Driver = pysu2.CSinglezoneDriver("spinning_cylinder.cfg",1, comm) + +for i, rate in enumerate(rotation_vector): + SU2Driver.SetMarkerRotationRate(0,0,0,rate) + SU2Driver.Preprocess(i) + SU2Driver.Run() + SU2Driver.Postprocess() + SU2Driver.Output(i) + SU2Driver.Update() +SU2Driver.Finalize() + + \ No newline at end of file diff --git a/TestCases/py_wrapper/rotating_cylinder/spinning_cylinder.cfg b/TestCases/py_wrapper/rotating_cylinder/spinning_cylinder.cfg new file mode 100644 index 00000000000..194a46064dd --- /dev/null +++ b/TestCases/py_wrapper/rotating_cylinder/spinning_cylinder.cfg @@ -0,0 +1,115 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Laminar flow around a spinning cylinder % +% Author: Thomas D. Economon % +% Institution: Stanford University % +% Date: 2013.08.21 % +% File Version 7.5.1 "Blackbird" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +SOLVER= NAVIER_STOKES +KIND_TURB_MODEL= NONE +MATH_PROBLEM= DIRECT +RESTART_SOL= NO + +% ----------- COMPRESSIBLE AND INCOMPRESSIBLE FREE-STREAM DEFINITION ----------% +% +MACH_NUMBER= 0.1 +AOA= 0.0 +SIDESLIP_ANGLE= 0.0 +FREESTREAM_TEMPERATURE= 288.15 +REYNOLDS_NUMBER= 200.0 +REYNOLDS_LENGTH= 1.0 + +% ----------------------- DYNAMIC MESH DEFINITION -----------------------------% +% +SURFACE_MOVEMENT= MOVING_WALL +MACH_MOTION= 0.1 +MARKER_MOVING= ( cylinder ) +SURFACE_MOTION_ORIGIN= 0.5 0.0 0.0 +SURFACE_ROTATION_RATE = 0.0 0.0 -199.0738 + +% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% +% +REF_ORIGIN_MOMENT_X = 0.00 +REF_ORIGIN_MOMENT_Y = 0.00 +REF_ORIGIN_MOMENT_Z = 0.00 +REF_LENGTH= 1.0 +REF_AREA= 1.0 + +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +MARKER_HEATFLUX= ( cylinder, 0.0 ) +MARKER_FAR= ( farfield ) +MARKER_PLOTTING= ( cylinder ) +MARKER_MONITORING= ( cylinder ) + +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES +CFL_NUMBER= 100.0 +CFL_ADAPT= NO +CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) +ITER= 99999 + +% ----------------------- SLOPE LIMITER DEFINITION ----------------------------% +% +VENKAT_LIMITER_COEFF= 0.03 +ADJ_SHARP_LIMITER_COEFF= 3.0 +REF_SHARP_EDGES= 3.0 +SENS_REMOVE_SHARP= NO + +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +LINEAR_SOLVER= FGMRES +LINEAR_SOLVER_PREC= LU_SGS +LINEAR_SOLVER_ERROR= 1E-4 +LINEAR_SOLVER_ITER= 5 + +% -------------------------- MULTIGRID PARAMETERS -----------------------------% +% +MGLEVEL= 3 +MGCYCLE= V_CYCLE +MG_PRE_SMOOTH= ( 1, 1, 1, 1 ) +MG_POST_SMOOTH= ( 0, 0, 0, 0 ) +MG_CORRECTION_SMOOTH= ( 0, 0, 0, 0 ) +MG_DAMP_RESTRICTION= 0.5 +MG_DAMP_PROLONGATION= 0.5 + +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +CONV_NUM_METHOD_FLOW= ROE +MUSCL_FLOW= YES +SLOPE_LIMITER_FLOW= NONE +JST_SENSOR_COEFF= ( 0.5, 0.02 ) +TIME_DISCRE_FLOW= EULER_IMPLICIT + +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +CONV_RESIDUAL_MINVAL= -15 +CONV_STARTITER= 10 +CONV_CAUCHY_ELEMS= 100 +CONV_CAUCHY_EPS= 1E-7 + +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +MESH_FILENAME= mesh_cylinder_lam.su2 +MESH_FORMAT= SU2 +MESH_OUT_FILENAME= mesh_out.su2 +SOLUTION_FILENAME= solution_flow.dat +SOLUTION_ADJ_FILENAME= solution_adj.dat +TABULAR_FORMAT= CSV +CONV_FILENAME= history +RESTART_FILENAME= restart_flow.dat +RESTART_ADJ_FILENAME= restart_adj.dat +VOLUME_FILENAME= flow +VOLUME_ADJ_FILENAME= adjoint +GRAD_OBJFUNC_FILENAME= of_grad.dat +SURFACE_FILENAME= surface_flow +SURFACE_ADJ_FILENAME= surface_adjoint +OUTPUT_WRT_FREQ= 100 +SCREEN_OUTPUT= (INNER_ITER, RMS_DENSITY, RMS_ENERGY, LIFT, DRAG) diff --git a/TestCases/serial_regression.py b/TestCases/serial_regression.py index 56d4d46938d..8b00b3c8f5b 100644 --- a/TestCases/serial_regression.py +++ b/TestCases/serial_regression.py @@ -750,7 +750,7 @@ def main(): cavity.cfg_dir = "moving_wall/cavity" cavity.cfg_file = "lam_cavity.cfg" cavity.test_iter = 25 - cavity.test_vals = [-5.627934, -0.164470, 0.051972, 2.547039] + cavity.test_vals = [ -5.627868, -0.164405, 0.053283, 2.545817] test_list.append(cavity) # Spinning cylinder @@ -758,7 +758,7 @@ def main(): spinning_cylinder.cfg_dir = "moving_wall/spinning_cylinder" spinning_cylinder.cfg_file = "spinning_cylinder.cfg" spinning_cylinder.test_iter = 25 - spinning_cylinder.test_vals = [-7.889994, -2.469385, 1.708162, 1.670039] + spinning_cylinder.test_vals = [-7.892807, -2.467378, 1.702819, 1.669208] test_list.append(spinning_cylinder) ###################################### @@ -849,7 +849,7 @@ def main(): ###################################### - ### turbomachinery ### + ### Turbomachinery ### ###################################### # Jones APU Turbocharger restart @@ -857,8 +857,7 @@ def main(): Jones_tc_restart.cfg_dir = "turbomachinery/APU_turbocharger" Jones_tc_restart.cfg_file = "Jones_restart.cfg" Jones_tc_restart.test_iter = 5 - Jones_tc_restart.test_vals = [-6.604538, -2.792279, -14.328534, -8.769317, -11.371438, -5.845632, 73273.000000, 73273.000000] - Jones_tc_restart.tol = 0.0001 + Jones_tc_restart.test_vals = [-6.594586, -2.792279, -14.336132, -8.776068, -11.371439, -5.845632, 73273, 73273, 0.019884, 82.491] test_list.append(Jones_tc_restart) # 2D axial stage @@ -866,7 +865,8 @@ def main(): axial_stage2D.cfg_dir = "turbomachinery/axial_stage_2D" axial_stage2D.cfg_file = "Axial_stage2D.cfg" axial_stage2D.test_iter = 20 - axial_stage2D.test_vals = [0.974801, 1.534472, -2.897692, 2.599377, -2.418396, 3.087203, 106380.000000, 106380.000000] + axial_stage2D.test_vals = [0.983751, 1.534480, -2.888520, 2.606773, -2.418421, 3.087187, 106380, 106380, 5.7325, 64.711] + axial_stage2D.test_vals_aarch64 = [0.983751, 1.534480, -2.888520, 2.606773, -2.418421, 3.087187, 106380, 106380, 5.7325, 64.711] test_list.append(axial_stage2D) # 2D transonic stator restart @@ -874,7 +874,8 @@ def main(): transonic_stator_restart.cfg_dir = "turbomachinery/transonic_stator_2D" transonic_stator_restart.cfg_file = "transonic_stator_restart.cfg" transonic_stator_restart.test_iter = 20 - transonic_stator_restart.test_vals = [-5.345491, -3.512311, -3.153972, 0.753530, -3.835478, 1.808296, -471690] + transonic_stator_restart.test_vals = [-5.008547, -3.102420, -2.752033, 1.091152, -3.543849, 2.169844, -471630, 94.866, -0.035806] + transonic_stator_restart.test_vals_aarch64 = [-5.008547, -3.102420, -2.752033, 1.091152, -3.543849, 2.169844, -471630, 94.866, -0.035806] test_list.append(transonic_stator_restart) @@ -1066,6 +1067,7 @@ def main(): airfoilRBF.cfg_dir = "fea_fsi/Airfoil_RBF" airfoilRBF.cfg_file = "config.cfg" airfoilRBF.test_iter = 1 + airfoilRBF.test_vals = [1.000000, -2.786186, -4.977944] airfoilRBF.tol = 0.0001 airfoilRBF.multizone = True diff --git a/TestCases/turbomachinery/APU_turbocharger/Jones_restart.cfg b/TestCases/turbomachinery/APU_turbocharger/Jones_restart.cfg index c1a9dec3889..42de00358bd 100755 --- a/TestCases/turbomachinery/APU_turbocharger/Jones_restart.cfg +++ b/TestCases/turbomachinery/APU_turbocharger/Jones_restart.cfg @@ -67,6 +67,7 @@ MARKER_PERIODIC= (PER1, PER2, 0.0, 0.0, 0.0, 0.0, 0.0, 18.947368421, 0.0, 0.0, 0 % MARKER_TURBOMACHINERY= (INFLOW, OUTMIX, INMIX, OUTFLOW) MARKER_ANALYZE= (OUTFLOW) +MARKER_ZONE_INTERFACE= (OUTMIX, INMIX) MARKER_MIXINGPLANE_INTERFACE= (OUTMIX, INMIX) MARKER_GILES= (INFLOW, TOTAL_CONDITIONS_PT, 413.6E+03, 477.6, 1.0, 0.0, 0.0, 1.0, 0.0, OUTMIX, MIXING_OUT, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3, 0.0, INMIX, MIXING_IN, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3, 0.0, OUTFLOW, STATIC_PRESSURE_1D, 67.46E+03, 0.0, 0.0, 0.0, 0.0 , 1.0, 0.0) GILES_EXTRA_RELAXFACTOR= (0.05, 0.05) @@ -75,6 +76,7 @@ SPATIAL_FOURIER= NO %---------------------------- TURBOMACHINERY SIMULATION -----------------------------% % TURBOMACHINERY_KIND= CENTRIPETAL CENTRIPETAL_AXIAL +TURBO_PERF_KIND = TURBINE TURBINE MIXINGPLANE_INTERFACE_KIND= LINEAR_INTERPOLATION TURBULENT_MIXINGPLANE= YES RAMP_OUTLET_PRESSURE= NO @@ -137,7 +139,7 @@ CONV_CAUCHY_EPS= 1E-6 % % ------------------------- INPUT/OUTPUT INFORMATION --------------------------% % -SCREEN_OUTPUT= OUTER_ITER, AVG_BGS_RES[0], AVG_BGS_RES[1], RMS_DENSITY[0], RMS_ENERGY[0], RMS_DENSITY[1], RMS_ENERGY[1], SURFACE_TOTAL_PRESSURE[1] +SCREEN_OUTPUT= OUTER_ITER, AVG_BGS_RES[0], AVG_BGS_RES[1], RMS_DENSITY[0], RMS_ENERGY[0], RMS_DENSITY[1], RMS_ENERGY[1], SURFACE_TOTAL_PRESSURE[1], MassFlowOut_2[1], TotalStaticEfficiency[1] MESH_FILENAME= mesh_jones_turbine.su2 MESH_FORMAT= SU2 MESH_OUT_FILENAME= meshout.su2 diff --git a/TestCases/turbomachinery/axial_stage_2D/Axial_stage2D.cfg b/TestCases/turbomachinery/axial_stage_2D/Axial_stage2D.cfg index 583ec2849eb..75be16ada08 100755 --- a/TestCases/turbomachinery/axial_stage_2D/Axial_stage2D.cfg +++ b/TestCases/turbomachinery/axial_stage_2D/Axial_stage2D.cfg @@ -69,6 +69,7 @@ MARKER_PERIODIC= ( periodic1, periodic2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.04 MARKER_TURBOMACHINERY= (inflow, outmix, inmix, outflow) MARKER_ANALYZE= (outflow) % +MARKER_ZONE_INTERFACE= (outmix, inmix) % Mixing-plane interface markers must be specified to activate the transfer of information between zones MARKER_MIXINGPLANE_INTERFACE= (outmix, inmix) % @@ -78,6 +79,7 @@ SPATIAL_FOURIER= NO %---------------------------- TURBOMACHINERY SIMULATION -----------------------------% % TURBOMACHINERY_KIND= AXIAL AXIAL +TURBO_PERF_KIND = TURBINE TURBINE TURBULENT_MIXINGPLANE= YES RAMP_OUTLET_PRESSURE= NO RAMP_OUTLET_PRESSURE_COEFF= (140000.0, 10.0, 2000) @@ -139,7 +141,7 @@ CONV_CAUCHY_EPS= 1E-6 % % ------------------------- INPUT/OUTPUT INFORMATION --------------------------% % -SCREEN_OUTPUT= OUTER_ITER, AVG_BGS_RES[0], AVG_BGS_RES[1], RMS_DENSITY[0], RMS_ENERGY[0], RMS_DENSITY[1], RMS_ENERGY[1], SURFACE_TOTAL_PRESSURE[1] +SCREEN_OUTPUT= OUTER_ITER, AVG_BGS_RES[0], AVG_BGS_RES[1], RMS_DENSITY[0], RMS_ENERGY[0], RMS_DENSITY[1], RMS_ENERGY[1], SURFACE_TOTAL_PRESSURE[1], MassFlowOut_2[1], TotalStaticEfficiency[1] MESH_FILENAME= mesh_axial_stage_2d_turb.su2 MESH_FORMAT= SU2 MESH_OUT_FILENAME= meshout.su2 diff --git a/TestCases/turbomachinery/centrifugal_blade/centrifugal_blade.cfg b/TestCases/turbomachinery/centrifugal_blade/centrifugal_blade.cfg index cd0716b7021..b319e9e074b 100755 --- a/TestCases/turbomachinery/centrifugal_blade/centrifugal_blade.cfg +++ b/TestCases/turbomachinery/centrifugal_blade/centrifugal_blade.cfg @@ -68,6 +68,7 @@ MARKER_PLOTTING= ( wall1, wall2 ) % % Marker(s) between turbomachinery performance are evaluated. Use BLADE for single blade, STAGE for stage and TURBINE for a multi-stage. MARKER_TURBO_PERFORMANCE= (inflow, outflow, BLADE) +TURBO_PERF_KIND = TURBINE % % ----------------------- DYNAMIC MESH DEFINITION -----------------------------% % diff --git a/TestCases/turbomachinery/centrifugal_stage/centrifugal_stage.cfg b/TestCases/turbomachinery/centrifugal_stage/centrifugal_stage.cfg index d3571d77a9b..22ab379423b 100755 --- a/TestCases/turbomachinery/centrifugal_stage/centrifugal_stage.cfg +++ b/TestCases/turbomachinery/centrifugal_stage/centrifugal_stage.cfg @@ -68,6 +68,7 @@ MARKER_PERIODIC= (periodic1, periodic2, 0.0, 0.0, 0.0, 0.0, 0.0, 10.29, 0.0, 0.0 MARKER_PLOTTING= ( wall1, wall2 ) MARKER_MONITORING= ( wall1, wall2 ) MARKER_TURBO_PERFORMANCE= (inflow, outflow, STAGE, inflow, outmix, BLADE, inmix, outflow, BLADE) +TURBO_PERF_KIND = TURBINE TURBINE % % ----------------------- DYNAMIC MESH DEFINITION -----------------------------% % diff --git a/TestCases/turbomachinery/transonic_stator_2D/transonic_stator_restart.cfg b/TestCases/turbomachinery/transonic_stator_2D/transonic_stator_restart.cfg index 4d2097fc80f..7608b5cebf3 100644 --- a/TestCases/turbomachinery/transonic_stator_2D/transonic_stator_restart.cfg +++ b/TestCases/turbomachinery/transonic_stator_2D/transonic_stator_restart.cfg @@ -75,6 +75,7 @@ SPATIAL_FOURIER= YES %---------------------------- TURBOMACHINERY SIMULATION -----------------------------% % TURBOMACHINERY_KIND = AXIAL +TURBO_PERF_KIND = TURBINE RAMP_OUTLET_PRESSURE= NO RAMP_OUTLET_PRESSURE_COEFF= (700000.0, 10.0, 500) AVERAGE_PROCESS_KIND= MIXEDOUT @@ -130,7 +131,7 @@ CFL_REDUCTION_TURB= 1.0 % % --------------------------- CONVERGENCE PARAMETERS --------------------------% % -ITER= 10000 +ITER= 21 CONV_RESIDUAL_MINVAL= -12 CONV_STARTITER= 10 CONV_CAUCHY_ELEMS= 100 @@ -138,7 +139,7 @@ CONV_CAUCHY_EPS= 1E-6 % % ------------------------- INPUT/OUTPUT INFORMATION --------------------------% % -SCREEN_OUTPUT= INNER_ITER, RMS_RES, SURFACE_PRESSURE_DROP +SCREEN_OUTPUT= INNER_ITER, RMS_RES, SURFACE_PRESSURE_DROP, MassFlowOut_1, TotalStaticEfficiency MESH_FILENAME= mesh_stator_turb.su2 MESH_FORMAT= SU2 MESH_OUT_FILENAME= su2mesh_per.su2 diff --git a/config_template.cfg b/config_template.cfg index 2a5b1c072e3..ccfd43485df 100644 --- a/config_template.cfg +++ b/config_template.cfg @@ -715,6 +715,10 @@ DISTORTION_RACK= (0.0, 0.0) % CENTRIPETAL_AXIAL, AXIAL_CENTRIFUGAL) TURBOMACHINERY_KIND= CENTRIPETAL CENTRIPETAL_AXIAL % +% Specify the machine architecture for performance analysis (TURBINE, COMPRESSOR, PROPELLOR) +% +TURBO_PERF_KIND = TURBINE TURBINE +% % Specify kind of interpolation for the mixing-plane (LINEAR_INTERPOLATION, % NEAREST_SPAN, MATCHING) MIXINGPLANE_INTERFACE_KIND= LINEAR_INTERPOLATION @@ -2140,6 +2144,14 @@ UQ_DELTA_B= 1.0 % The optimum value/strategy is case-dependent. EDGE_COLORING_GROUP_SIZE= 512 % +% Coloring tends to perform better for the discrete adjoint than reductions because +% it uses less memory and enables the shared reading optimization for color loops. +% This option allows an automatic fallback to smaller edge color group sizes on ranks +% where the requested edge color group size is not efficient. Specifically, the largest +% edge color group size up to EDGE_COLORING_GROUP_SIZE is chosen that is at least +% 0.875 efficient. Also, this option allows using more colors, up to 255 instead of up to 64. +EDGE_COLORING_RELAX_DISC_ADJ= YES +% % Independent "threads per MPI rank" setting for LU-SGS and ILU preconditioners. % For problems where time is spend mostly in the solution of linear systems (e.g. elasticity, % very high CFL central schemes), AND, if the memory bandwidth of the machine is saturated diff --git a/externals/codi b/externals/codi index 0ad036f2c82..9ca6c382806 160000 --- a/externals/codi +++ b/externals/codi @@ -1 +1 @@ -Subproject commit 0ad036f2c8254fa7b77180a443d99248c047c877 +Subproject commit 9ca6c38280610b3ea5337ca3e5b5085ee1c66b59 diff --git a/externals/medi b/externals/medi index aafc2d1966b..85711944f8d 160000 --- a/externals/medi +++ b/externals/medi @@ -1 +1 @@ -Subproject commit aafc2d1966ba1233640af737e71c77c1a86183fd +Subproject commit 85711944f8d5d03dd75c635f8a18e220b216040d diff --git a/externals/opdi b/externals/opdi index c42cca71a3d..93d05a762f1 160000 --- a/externals/opdi +++ b/externals/opdi @@ -1 +1 @@ -Subproject commit c42cca71a3d0b44fb482e268ecd40b623e71776b +Subproject commit 93d05a762f1b614a84767ea5ba75fd7e2c27f317 diff --git a/meson_scripts/init.py b/meson_scripts/init.py index 6bda759c734..5507767dbd4 100755 --- a/meson_scripts/init.py +++ b/meson_scripts/init.py @@ -55,11 +55,11 @@ def init_submodules( # This information of the modules is used if projects was not cloned using git # The sha tag must be maintained manually to point to the correct commit - sha_version_codi = "0ad036f2c8254fa7b77180a443d99248c047c877" + sha_version_codi = "9ca6c38280610b3ea5337ca3e5b5085ee1c66b59" github_repo_codi = "https://github.com/scicompkl/CoDiPack" - sha_version_medi = "aafc2d1966ba1233640af737e71c77c1a86183fd" + sha_version_medi = "85711944f8d5d03dd75c635f8a18e220b216040d" github_repo_medi = "https://github.com/SciCompKL/MeDiPack" - sha_version_opdi = "c42cca71a3d0b44fb482e268ecd40b623e71776b" + sha_version_opdi = "93d05a762f1b614a84767ea5ba75fd7e2c27f317" github_repo_opdi = "https://github.com/SciCompKL/OpDiLib" sha_version_meson = "41c650a040d50e0912d268af7a903a9ce1456dfa" github_repo_meson = "https://github.com/mesonbuild/meson"