diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index c5f256b220e9..76429a377db2 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -1,20 +1,28 @@ name-template: 'v$NEXT_PATCH_VERSION' tag-template: 'v$NEXT_PATCH_VERSION' + +branches: + - develop + categories: - title: ':rocket: Experimental Features' labels: - 'changelog:feature' + - title: ':pill: Bug Fixes' labels: - 'changelog:fix' + - title: ':wrench: Maintenance' labels: - 'changelog:chore' -change-template: '- $TITLE @$AUTHOR (#$NUMBER)' -branches: - - develop + exclude-labels: - 'changelog:none' + +change-template: '- $TITLE @$AUTHOR (#$NUMBER)' + template: | ## Changes + $CHANGES diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml index 02c94dd1198f..c4e3b652b069 100644 --- a/.github/workflows/regression.yml +++ b/.github/workflows/regression.yml @@ -30,7 +30,7 @@ jobs: - id: compute run: | if [[ "${{ inputs.runner || 'ubuntu-latest' }}" == *arm* ]]; then - echo "flags=" >> $GITHUB_OUTPUT + echo "flags=-Dcpu-arch=armv9-a+simd" >> $GITHUB_OUTPUT echo "werror=" >> $GITHUB_OUTPUT else echo "flags=-Dcpu-arch=skylake" >> $GITHUB_OUTPUT diff --git a/.github/workflows/release-management.yml b/.github/workflows/release-management.yml index 8acd87d4b2dd..e8c44d8ac399 100644 --- a/.github/workflows/release-management.yml +++ b/.github/workflows/release-management.yml @@ -2,17 +2,31 @@ name: Release Management on: push: - # branches to consider in the event; optional, defaults to all branches: - develop +permissions: + contents: write + +concurrency: + group: release-management-${{ github.ref }} + cancel-in-progress: true + jobs: - build_and_upload: - name: Build SU2 + build: + name: Build SU2 (${{ matrix.os_bin }}) + runs-on: ubuntu-latest + strategy: fail-fast: false matrix: - os_bin: [macos64, macos64-mpi, linux64-omp, linux64-mpi, win64-omp, win64-mpi] + os_bin: + - macos64 + - macos64-mpi + - linux64-omp + - linux64-mpi + - win64-omp + - win64-mpi include: - os_bin: win64-omp flags: '-Dcpu-arch=haswell -Dwith-omp=true -Dwith-mpi=disabled --cross-file=/hostfiles/hostfile_windows' @@ -26,42 +40,80 @@ jobs: flags: '-Dcpu-arch=haswell -Dwith-omp=true -Dwith-mpi=disabled -Dstatic-cgns-deps=true --cross-file=/hostfiles/hostfile_linux' - os_bin: linux64-mpi flags: '-Dcpu-arch=haswell -Dcustom-mpi=true --cross-file=/hostfiles/hostfile_linux_mpi' - runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + - name: Cache Object Files - uses: actions/cache@v5 + uses: actions/cache@v4 with: path: ccache key: ${{ matrix.os_bin }}-${{ github.sha }} - restore-keys: ${{ matrix.os_bin }} + restore-keys: | + ${{ matrix.os_bin }}- + - name: Build uses: docker://ghcr.io/su2code/su2/build-su2-cross:260405-0054 with: - args: -b ${{ github.sha }} -f "${{matrix.flags}}" + args: -b ${{ github.sha }} -f "${{ matrix.flags }}" + - name: Create Archive run: | cd install - zip -r ../${{matrix.os_bin}}.zip bin/* - # Uploads binaries as artifacts (just as a backup) - - name: Upload Binaries - uses: actions/upload-artifact@v7 + zip -r ../${{ matrix.os_bin }}.zip bin/* + + - name: Upload Build Artifact + uses: actions/upload-artifact@v5 + with: + name: ${{ matrix.os_bin }} + path: ${{ matrix.os_bin }}.zip + + - name: Update Release Draft + id: release_drafter + uses: release-drafter/release-drafter@v6 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + release: + name: Update Draft Release + runs-on: ubuntu-latest + needs: build + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Download All Build Artifacts + uses: actions/download-artifact@v5 with: - name: ${{matrix.os_bin}} - path: ${{matrix.os_bin}}.zip - # Update the release notes of latest draft release - - uses: talbring/jenkins-release-drafter@v5.2.0-jenkins-11 - name: Update Release - id: update_release + path: release-assets + + - name: Flatten Artifact Directory + run: | + find release-assets -name "*.zip" -exec mv {} . \; + + - name: Update Release Draft + id: release_drafter + uses: release-drafter/release-drafter@v6 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # Upload binaries as assets to draft release - - name: Upload Release Asset - id: upload-release-asset - uses: actions/upload-release-asset@v1.0.2 + + - name: Upload Release Assets env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.update_release.outputs.uploadurl }} - asset_path: ${{matrix.os_bin}}.zip - asset_name: SU2-${{ steps.update_release.outputs.tagname }}-${{matrix.os_bin}}.zip - asset_content_type: application/zip + TAG_NAME: ${{ steps.release_drafter.outputs.tag_name }} + run: | + set -e + + for file in *.zip; do + + asset_name="SU2-${TAG_NAME}-${file}" + + echo "Uploading $asset_name" + + gh release upload "$TAG_NAME" \ + "$file#$asset_name" \ + --clobber + + done diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index 71f780bbed07..7d85083eafbd 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -1147,6 +1147,8 @@ class CConfig { /*--- Multigrid options ---*/ unsigned short nMG_PreSmooth_p{0}, nMG_PostSmooth_p{0}, nMG_CorrecSmooth_p{0}; unsigned short *MG_PreSmooth_p{nullptr}, *MG_PostSmooth_p{nullptr}, *MG_CorrecSmooth_p{nullptr}; + unsigned short nMG_CflScaling_p{0}; + su2double *MG_CflScaling_p{nullptr}; ENUM_STREAMWISE_PERIODIC Kind_Streamwise_Periodic; /*!< \brief Kind of Streamwise periodic flow (pressure drop or massflow) */ bool Streamwise_Periodic_Temperature; /*!< \brief Use real periodicity for Energy equation or otherwise outlet source term. */ @@ -10265,4 +10267,12 @@ class CConfig { */ const FluidFlamelet_ParsedOptions& GetFlameletParsedOptions() const { return flamelet_ParsedOptions; } + /*! + * \brief Get the enthalpy BC mode for the flamelet solver. + * FLOW_MARKERS: derive enthalpy BCs from MARKER_ISOTHERMAL/MARKER_HEATFLUX/MARKER_INLET (temperature-based). + * SPECIES_MARKERS: take enthalpy BCs directly from MARKER_WALL_SPECIES/MARKER_INLET_SPECIES. + * \return FLAMELET_ENTHALPY_BC enum value. + */ + FLAMELET_ENTHALPY_BC GetFlamelet_Enthalpy_BC() const { return flamelet_ParsedOptions.enthalpy_bc; } + }; diff --git a/Common/include/code_config.hpp b/Common/include/code_config.hpp index 491777a01f3d..bc02c2830aab 100644 --- a/Common/include/code_config.hpp +++ b/Common/include/code_config.hpp @@ -27,6 +27,7 @@ #pragma once #include +#include #if defined(_MSC_VER) #define PRAGMIZE(X) __pragma(X) @@ -94,6 +95,31 @@ FORCEINLINE Out su2staticcast_p(In ptr) { #define HAVE_OMP #endif +/*--- No full single precision for AD builds. ---*/ +#if (defined(CODI_REVERSE_TYPE) || defined(CODI_FORWARD_TYPE)) && defined(USE_SINGLE_PRECISION) +#undef USE_SINGLE_PRECISION +#endif + +/*--- This type can be used for (rare) compatibility cases or for + * computations that are intended to be (always) passive. ---*/ +#ifdef USE_SINGLE_PRECISION +using passivedouble = float; +#else +using passivedouble = double; +#endif + +/*--- std::min/max do not compile if the arguments have inconsistent types, which + * happens in single precision due to floating point literals (double by default). + * These overloads delegate to fmin/fmax which do not have that problem. ---*/ +#ifdef USE_SINGLE_PRECISION +namespace std { +FORCEINLINE float min(const float& a, const double& b) { return fmin(a, static_cast(b)); } +FORCEINLINE float min(const double& b, const float& a) { return fmin(a, static_cast(b)); } +FORCEINLINE float max(const float& a, const double& b) { return fmax(a, static_cast(b)); } +FORCEINLINE float max(const double& b, const float& a) { return fmax(a, static_cast(b)); } +} // namespace std +#endif + /*--- Depending on the datatype defined during the configuration, * include the correct definition, and create the main typedef. ---*/ @@ -131,13 +157,9 @@ using su2double = codi::RealReverseTag; #include "codi.hpp" using su2double = codi::RealForward; #else // primal / direct / no AD -using su2double = double; +using su2double = passivedouble; #endif -/*--- This type can be used for (rare) compatibility cases or for - * computations that are intended to be (always) passive. ---*/ -using passivedouble = double; - /*--- Define a type for potentially lower precision operations. ---*/ #ifndef CODI_FORWARD_TYPE #ifdef USE_MIXED_PRECISION diff --git a/Common/include/linear_algebra/CMatrixVectorProduct.hpp b/Common/include/linear_algebra/CMatrixVectorProduct.hpp index 878bb132b984..a0cecaa63d76 100644 --- a/Common/include/linear_algebra/CMatrixVectorProduct.hpp +++ b/Common/include/linear_algebra/CMatrixVectorProduct.hpp @@ -72,6 +72,7 @@ class CSysMatrixVectorProduct final : public CMatrixVectorProduct { const CSysMatrix& matrix; /*!< \brief pointer to matrix that defines the product. */ CGeometry* geometry; /*!< \brief geometry associated with the matrix. */ const CConfig* config; /*!< \brief config of the problem. */ + mutable bool matrix_uploaded = false; /*!< \brief Upload the matrix lazily on the first actual GPU matvec. */ public: /*! @@ -97,6 +98,10 @@ class CSysMatrixVectorProduct final : public CMatrixVectorProduct { inline void operator()(const CSysVector& u, CSysVector& v) const override { if (config->GetCUDA()) { #ifdef HAVE_CUDA + if (!matrix_uploaded) { + matrix.HtDTransfer(); + matrix_uploaded = true; + } matrix.GPUMatrixVectorProduct(u, v, geometry, config); #else SU2_MPI::Error( diff --git a/Common/include/linear_algebra/CPastixWrapper.hpp b/Common/include/linear_algebra/CPastixWrapper.hpp index 7ee570010f0b..dcc320debe1c 100644 --- a/Common/include/linear_algebra/CPastixWrapper.hpp +++ b/Common/include/linear_algebra/CPastixWrapper.hpp @@ -62,8 +62,8 @@ class CPastixWrapper { vector perm; /*!< \brief Ordering computed by PaStiX. */ vector workvec; /*!< \brief RHS vector which then becomes the solution. */ - pastix_int_t iparm[IPARM_SIZE]; /*!< \brief Integer parameters for PaStiX. */ - passivedouble dparm[DPARM_SIZE]; /*!< \brief Floating point parameters for PaStiX. */ + pastix_int_t iparm[IPARM_SIZE]; /*!< \brief Integer parameters for PaStiX. */ + double dparm[DPARM_SIZE]; /*!< \brief Floating point parameters for PaStiX. */ struct { unsigned long nVar = 0; diff --git a/Common/include/linear_algebra/CSysSolve.hpp b/Common/include/linear_algebra/CSysSolve.hpp index 91e9b11f4e26..2ea3cbf7df30 100644 --- a/Common/include/linear_algebra/CSysSolve.hpp +++ b/Common/include/linear_algebra/CSysSolve.hpp @@ -442,13 +442,13 @@ class CSysSolve { * \brief Get the number of iterations. * \return The number of iterations done by Solve or Solve_b */ - inline unsigned long GetIterations(void) const { return Iterations; } + inline unsigned long GetIterations() const { return Iterations; } /*! * \brief Get the final residual. * \return The residual at the end of Solve or Solve_b */ - inline ScalarType GetResidual(void) const { return Residual; } + inline ScalarType GetResidual() const { return Residual; } /*! * \brief Set the type of the tolerance for stoping the linear solvers (RELATIVE or ABSOLUTE). diff --git a/Common/include/option_structure.hpp b/Common/include/option_structure.hpp index 73266c7dacdb..72c7ebc31ab7 100644 --- a/Common/include/option_structure.hpp +++ b/Common/include/option_structure.hpp @@ -989,18 +989,19 @@ inline TURB_FAMILY TurbModelFamily(TURB_MODEL model) { * \brief SST Options */ enum class SST_OPTIONS { - NONE, /*!< \brief No SST Turb model. */ - V1994, /*!< \brief 1994 Menter k-w SST model. */ - V2003, /*!< \brief 2003 Menter k-w SST model. */ - V1994m, /*!< \brief 1994m Menter k-w SST model. */ - V2003m, /*!< \brief 2003m Menter k-w SST model. */ - SUST, /*!< \brief Menter k-w SST model with sustaining terms. */ - V, /*!< \brief Menter k-w SST model with vorticity production terms. */ - KL, /*!< \brief Menter k-w SST model with Kato-Launder production terms. */ - UQ, /*!< \brief Menter k-w SST model with uncertainty quantification modifications. */ - COMP_Wilcox, /*!< \brief Menter k-w SST model with Compressibility correction of Wilcox. */ - COMP_Sarkar, /*!< \brief Menter k-w SST model with Compressibility correction of Sarkar. */ - DLL, /*!< \brief Menter k-w SST model with dimensionless lower limit clipping of turbulence variables. */ + NONE, /*!< \brief No SST Turb model. */ + V1994, /*!< \brief 1994 Menter k-w SST model. */ + V2003, /*!< \brief 2003 Menter k-w SST model. */ + V1994m, /*!< \brief 1994m Menter k-w SST model. */ + V2003m, /*!< \brief 2003m Menter k-w SST model. */ + SUST, /*!< \brief Menter k-w SST model with sustaining terms. */ + V, /*!< \brief Menter k-w SST model with vorticity production terms. */ + KL, /*!< \brief Menter k-w SST model with Kato-Launder production terms. */ + UQ, /*!< \brief Menter k-w SST model with uncertainty quantification modifications. */ + COMP_Wilcox, /*!< \brief Menter k-w SST model with Compressibility correction of Wilcox. */ + COMP_Sarkar, /*!< \brief Menter k-w SST model with Compressibility correction of Sarkar. */ + COMP_Press_Dil, /*!< \brief Menter k-w SST model with Compressibility correction of pressure-dilatation. */ + DLL, /*!< \brief Menter k-w SST model with dimensionless lower limit clipping of turbulence variables. */ }; static const MapType SST_Options_Map = { MakePair("NONE", SST_OPTIONS::NONE) @@ -1015,6 +1016,7 @@ static const MapType SST_Options_Map = { MakePair("UQ", SST_OPTIONS::UQ) MakePair("COMPRESSIBILITY-WILCOX", SST_OPTIONS::COMP_Wilcox) MakePair("COMPRESSIBILITY-SARKAR", SST_OPTIONS::COMP_Sarkar) + MakePair("COMPRESSIBILITY-PRESS-DIL", SST_OPTIONS::COMP_Press_Dil) MakePair("DIMENSIONLESS_LIMIT", SST_OPTIONS::DLL) }; @@ -1029,6 +1031,7 @@ struct SST_ParsedOptions { bool modified = false; /*!< \brief Bool for modified (m) SST model. */ bool compWilcox = false; /*!< \brief Bool for compressibility correction of Wilcox. */ bool compSarkar = false; /*!< \brief Bool for compressibility correction of Sarkar. */ + bool compPressDil = false; /*!< \brief Bool for compressibility correction of pressure-dilatation. */ bool dll = false; /*!< \brief Bool dimensionless lower limit. */ }; @@ -1067,6 +1070,7 @@ inline SST_ParsedOptions ParseSSTOptions(const SST_OPTIONS *SST_Options, unsigne const bool sst_uq = IsPresent(SST_OPTIONS::UQ); const bool sst_compWilcox = IsPresent(SST_OPTIONS::COMP_Wilcox); const bool sst_compSarkar = IsPresent(SST_OPTIONS::COMP_Sarkar); + const bool sst_compPressDil = IsPresent(SST_OPTIONS::COMP_Press_Dil); const bool sst_dll = IsPresent(SST_OPTIONS::DLL); if (sst_1994 && sst_2003) { @@ -1102,6 +1106,7 @@ inline SST_ParsedOptions ParseSSTOptions(const SST_OPTIONS *SST_Options, unsigne SSTParsedOptions.uq = sst_uq; SSTParsedOptions.compWilcox = sst_compWilcox; SSTParsedOptions.compSarkar = sst_compSarkar; + SSTParsedOptions.compPressDil = sst_compPressDil; SSTParsedOptions.dll = sst_dll; return SSTParsedOptions; @@ -1117,9 +1122,12 @@ struct CMGOptions { std::vector MG_PreSmooth; /*!< \brief Multigrid pre-smoothing iterations per level. */ std::vector MG_PostSmooth; /*!< \brief Multigrid post-smoothing iterations per level. */ std::vector MG_CorrecSmooth; /*!< \brief Multigrid Jacobi correction-smoothing per level. */ + std::vector MG_CflScaling; /*!< \brief Per-level CFL scaling factors relative to the previous (finer) level. Entry [i] scales level i+1 from level i. Size = nMGLevels. */ bool MG_Smooth_EarlyExit{false}; /*!< \brief Enable early exit for MG smoothing iterations. */ bool MG_Smooth_Output{false}; /*!< \brief Output compact per-cycle smoothing summary. */ + su2double MG_Smooth_StagnationTol{0.0}; /*!< \brief Stagnation early exit: stop if current_rms >= prev_rms * tol. 0 = disabled. */ bool MG_Implicit_Lines{false}; /*!< \brief Enable implicit-lines agglomeration from walls. */ + unsigned long MG_Implicit_Lines_MaxLength{20}; /*!< \brief Maximum nodes on a wall-normal implicit line (including wall seed). */ }; /*! @@ -1441,12 +1449,30 @@ static const MapType Flamelet_Init_Map = { MakePair("SPARK", FLAMELET_INIT_TYPE::SPARK) }; +/*! + * \brief Selects the source of wall/inlet enthalpy boundary conditions for the flamelet solver. + * SPECIES_MARKERS (default): inlet H is taken directly from MARKER_INLET_SPECIES; wall enthalpy BC + * is obtained from MARKER_WALL_SPECIES. + * FLOW_MARKERS: inlet H is derived from the MARKER_INLET temperature via a Newton iteration on the + * LUT (reverse lookup using Z,T) from MARKER_ISOTHERMAL or MARKER_HEATFLUX. + */ +enum class FLAMELET_ENTHALPY_BC { + FLOW_MARKERS, /*!< \brief Derive inlet H from MARKER_INLET T (LUT Newton); walls from MARKER_ISOTHERMAL/MARKER_HEATFLUX. */ + SPECIES_MARKERS, /*!< \brief Take inlet H directly from MARKER_INLET_SPECIES; walls from MARKER_WALL_SPECIES (default). */ +}; + +static const MapType Flamelet_Enthalpy_BC_Map = { + MakePair("FLOW_MARKERS", FLAMELET_ENTHALPY_BC::FLOW_MARKERS) + MakePair("SPECIES_MARKERS", FLAMELET_ENTHALPY_BC::SPECIES_MARKERS) +}; + /*! * \brief Structure containing parsed options for flamelet fluid model. */ struct FluidFlamelet_ParsedOptions { ///TODO: Add python wrapper initialization option FLAMELET_INIT_TYPE ignition_method = FLAMELET_INIT_TYPE::NONE; /*!< \brief Method for solution ignition for flamelet problems. */ + FLAMELET_ENTHALPY_BC enthalpy_bc = FLAMELET_ENTHALPY_BC::SPECIES_MARKERS; /*!< \brief Source of enthalpy BCs: species markers (default, backward-compatible) or flow markers. */ unsigned short n_scalars = 0; /*!< \brief Number of transported scalars for flamelet LUT approach. */ unsigned short n_lookups = 0; /*!< \brief Number of lookup variables, for visualization only. */ unsigned short n_table_sources = 0; /*!< \brief Number of transported scalar source terms for LUT. */ diff --git a/Common/include/parallelization/mpi_structure.cpp b/Common/include/parallelization/mpi_structure.cpp index 03152e709e45..e04759b9f952 100644 --- a/Common/include/parallelization/mpi_structure.cpp +++ b/Common/include/parallelization/mpi_structure.cpp @@ -190,7 +190,7 @@ template class CBaseMPIWrapper; #if defined CODI_REVERSE_TYPE template class CBaseMPIWrapper; #endif -#if defined USE_MIXED_PRECISION +#if defined(USE_MIXED_PRECISION) && !defined(USE_SINGLE_PRECISION) template class CBaseMPIWrapper; #endif diff --git a/Common/include/parallelization/mpi_structure.hpp b/Common/include/parallelization/mpi_structure.hpp index afe0c666dcbf..242aa00d7b0f 100644 --- a/Common/include/parallelization/mpi_structure.hpp +++ b/Common/include/parallelization/mpi_structure.hpp @@ -61,6 +61,11 @@ #ifdef HAVE_MPI +#ifdef USE_SINGLE_PRECISION +#undef MPI_DOUBLE +#define MPI_DOUBLE MPI_FLOAT +#endif + /*--- Depending on the datatype used, the correct MPI wrapper class is defined. * For the default (double type) case this results in using the normal MPI routines. ---*/ #if defined CODI_REVERSE_TYPE || defined CODI_FORWARD_TYPE @@ -71,10 +76,10 @@ using namespace medi; #include class CMediMPIWrapper; -typedef CMediMPIWrapper SU2_MPI; +using SU2_MPI = CMediMPIWrapper; -typedef codi::CoDiMpiTypes MediTypes; -typedef MediTypes::Tool MediTool; +using MediTypes = codi::CoDiMpiTypes; +using MediTool = MediTypes::Tool; extern MediTypes* mediTypes; #define AMPI_ADOUBLE ((medi::MpiTypeInterface*)mediTypes->MPI_TYPE) @@ -91,12 +96,12 @@ using SU2_MPI = CBaseMPIWrapper; */ class CBaseMPIWrapper { public: - typedef MPI_Request Request; - typedef MPI_Status Status; - typedef MPI_Datatype Datatype; - typedef MPI_Op Op; - typedef MPI_Comm Comm; - typedef MPI_Win Win; + using Request = MPI_Request; + using Status = MPI_Status; + using Datatype = MPI_Datatype; + using Op = MPI_Op; + using Comm = MPI_Comm; + using Win = MPI_Win; protected: static int Rank, Size, MinRankError; @@ -256,7 +261,7 @@ class CBaseMPIWrapper { static inline passivedouble Wtime(void) { return MPI_Wtime(); } }; -typedef MPI_Comm SU2_Comm; +using SU2_Comm = MPI_Comm; #if defined CODI_REVERSE_TYPE || defined CODI_FORWARD_TYPE @@ -267,8 +272,8 @@ typedef MPI_Comm SU2_Comm; class CMediMPIWrapper : public CBaseMPIWrapper { public: - typedef AMPI_Request Request; - typedef AMPI_Status Status; + using Request = AMPI_Request; + using Status = AMPI_Status; static inline void Init(int* argc, char*** argv) { AMPI_Init(argc, argv); @@ -492,10 +497,10 @@ class CMediMPIWrapper : public CBaseMPIWrapper { template class CBaseMPIWrapper { public: - typedef int Comm; - typedef int Datatype; - typedef int Request; - typedef int Op; + using Comm = int; + using Datatype = int; + using Request = int; + using Op = int; struct Status { int MPI_TAG; @@ -632,7 +637,7 @@ struct SelectMPIWrapper { #endif /*--- Specialize for the low precision type. ---*/ -#if defined(USE_MIXED_PRECISION) +#if defined(USE_MIXED_PRECISION) && !defined(USE_SINGLE_PRECISION) template <> struct SelectMPIWrapper { #if defined HAVE_MPI diff --git a/Common/include/parallelization/vectorization.hpp b/Common/include/parallelization/vectorization.hpp index 34747913843a..b11d19780af9 100644 --- a/Common/include/parallelization/vectorization.hpp +++ b/Common/include/parallelization/vectorization.hpp @@ -35,6 +35,9 @@ #ifdef __SSE2__ #include "x86intrin.h" #endif +#if defined(__ARM_NEON) || defined(__ARM_NEON__) +#include +#endif namespace simd { /// \addtogroup SIMD @@ -47,7 +50,7 @@ using namespace VecExpr; constexpr size_t PREFERRED_SIZE = 64; #elif defined(__AVX__) constexpr size_t PREFERRED_SIZE = 32; -#elif defined(__SSE2__) +#elif defined(__SSE2__) || defined(__ARM_NEON) || defined(__ARM_NEON__) constexpr size_t PREFERRED_SIZE = 16; #else constexpr size_t PREFERRED_SIZE = 8; @@ -200,9 +203,11 @@ struct SIXTEEN {}; /*--- Constants for bitwise implementations. ---*/ /*--- abs forces the sign bit to 0 ("x" & 0b0111...). ---*/ -constexpr auto abs_mask_d = 0x7FFFFFFFFFFFFFFFL; +constexpr uint64_t abs_mask_d = 0x7FFFFFFFFFFFFFFFL; +constexpr uint32_t abs_mask_s = 0x7FFFFFFFU; /*--- negation flips the sign bit ("x" ^ 0b1000...). ---*/ -constexpr auto sign_mask_d = 0x8000000000000000L; +constexpr uint64_t sign_mask_d = 0x8000000000000000L; +constexpr uint32_t sign_mask_s = 0x80000000U; #ifdef __SSE2__ /*! @@ -248,6 +253,46 @@ FORCEINLINE __m128d sign_p(__m128d x) { return _mm_or_pd(ones_2d, _mm_and_pd(x, #include "special_vectorization.hpp" +/*! + * Create specialization for array of 4 floats (this should be always available). + */ +#define ARRAY_T Array +#define SCALAR_T float +#define REGISTER_T __m128 +#define SIZE_TAG SizeTag::FOUR() + +static const __m128 abs_mask_4s = _mm_castsi128_ps(_mm_set1_epi32(abs_mask_s)); +static const __m128 sign_mask_4s = _mm_castsi128_ps(_mm_set1_epi32(sign_mask_s)); +static const __m128 ones_4s = _mm_set1_ps(1); + +FORCEINLINE __m128 set1_p(SizeTag::FOUR, float p) { return _mm_set1_ps(p); } +FORCEINLINE __m128 load_p(SizeTag::FOUR, const float* p) { return _mm_load_ps(p); } +FORCEINLINE __m128 loadu_p(SizeTag::FOUR, const float* p) { return _mm_loadu_ps(p); } +FORCEINLINE void store_p(float* p, __m128 x) { _mm_store_ps(p, x); } +FORCEINLINE void storeu_p(float* p, __m128 x) { _mm_storeu_ps(p, x); } +FORCEINLINE void stream_p(float* p, __m128 x) { _mm_stream_ps(p, x); } + +FORCEINLINE __m128 add_p(__m128 a, __m128 b) { return _mm_add_ps(a, b); } +FORCEINLINE __m128 sub_p(__m128 a, __m128 b) { return _mm_sub_ps(a, b); } +FORCEINLINE __m128 mul_p(__m128 a, __m128 b) { return _mm_mul_ps(a, b); } +FORCEINLINE __m128 div_p(__m128 a, __m128 b) { return _mm_div_ps(a, b); } +FORCEINLINE __m128 max_p(__m128 a, __m128 b) { return _mm_max_ps(a, b); } +FORCEINLINE __m128 min_p(__m128 a, __m128 b) { return _mm_min_ps(a, b); } + +FORCEINLINE __m128 eq_p(__m128 a, __m128 b) { return _mm_and_ps(ones_4s, _mm_cmpeq_ps(a, b)); } +FORCEINLINE __m128 lt_p(__m128 a, __m128 b) { return _mm_and_ps(ones_4s, _mm_cmplt_ps(a, b)); } +FORCEINLINE __m128 le_p(__m128 a, __m128 b) { return _mm_and_ps(ones_4s, _mm_cmple_ps(a, b)); } +FORCEINLINE __m128 ne_p(__m128 a, __m128 b) { return _mm_and_ps(ones_4s, _mm_cmpneq_ps(a, b)); } +FORCEINLINE __m128 ge_p(__m128 a, __m128 b) { return _mm_and_ps(ones_4s, _mm_cmpge_ps(a, b)); } +FORCEINLINE __m128 gt_p(__m128 a, __m128 b) { return _mm_and_ps(ones_4s, _mm_cmpgt_ps(a, b)); } + +FORCEINLINE __m128 sqrt_p(__m128 x) { return _mm_sqrt_ps(x); } +FORCEINLINE __m128 abs_p(__m128 x) { return _mm_and_ps(x, abs_mask_4s); } +FORCEINLINE __m128 neg_p(__m128 x) { return _mm_xor_ps(x, sign_mask_4s); } +FORCEINLINE __m128 sign_p(__m128 x) { return _mm_or_ps(ones_4s, _mm_and_ps(x, sign_mask_4s)); } + +#include "special_vectorization.hpp" + #endif // __SSE2__ #ifdef __AVX__ @@ -291,6 +336,46 @@ FORCEINLINE __m256d sign_p(__m256d x) { return _mm256_or_pd(ones_4d, _mm256_and_ #include "special_vectorization.hpp" +/*! + * Create specialization for array of 8 floats. + */ +#define ARRAY_T Array +#define SCALAR_T float +#define REGISTER_T __m256 +#define SIZE_TAG SizeTag::EIGHT() + +static const __m256 abs_mask_8s = _mm256_castsi256_ps(_mm256_set1_epi32(abs_mask_s)); +static const __m256 sign_mask_8s = _mm256_castsi256_ps(_mm256_set1_epi32(sign_mask_s)); +static const __m256 ones_8s = _mm256_set1_ps(1); + +FORCEINLINE __m256 set1_p(SizeTag::EIGHT, float p) { return _mm256_set1_ps(p); } +FORCEINLINE __m256 load_p(SizeTag::EIGHT, const float* p) { return _mm256_load_ps(p); } +FORCEINLINE __m256 loadu_p(SizeTag::EIGHT, const float* p) { return _mm256_loadu_ps(p); } +FORCEINLINE void store_p(float* p, __m256 x) { _mm256_store_ps(p, x); } +FORCEINLINE void storeu_p(float* p, __m256 x) { _mm256_storeu_ps(p, x); } +FORCEINLINE void stream_p(float* p, __m256 x) { _mm256_stream_ps(p, x); } + +FORCEINLINE __m256 add_p(__m256 a, __m256 b) { return _mm256_add_ps(a, b); } +FORCEINLINE __m256 sub_p(__m256 a, __m256 b) { return _mm256_sub_ps(a, b); } +FORCEINLINE __m256 mul_p(__m256 a, __m256 b) { return _mm256_mul_ps(a, b); } +FORCEINLINE __m256 div_p(__m256 a, __m256 b) { return _mm256_div_ps(a, b); } +FORCEINLINE __m256 max_p(__m256 a, __m256 b) { return _mm256_max_ps(a, b); } +FORCEINLINE __m256 min_p(__m256 a, __m256 b) { return _mm256_min_ps(a, b); } + +FORCEINLINE __m256 eq_p(__m256 a, __m256 b) { return _mm256_and_ps(ones_8s, _mm256_cmp_ps(a, b, 0)); } +FORCEINLINE __m256 lt_p(__m256 a, __m256 b) { return _mm256_and_ps(ones_8s, _mm256_cmp_ps(a, b, 1)); } +FORCEINLINE __m256 le_p(__m256 a, __m256 b) { return _mm256_and_ps(ones_8s, _mm256_cmp_ps(a, b, 2)); } +FORCEINLINE __m256 ne_p(__m256 a, __m256 b) { return _mm256_and_ps(ones_8s, _mm256_cmp_ps(a, b, 4)); } +FORCEINLINE __m256 ge_p(__m256 a, __m256 b) { return _mm256_and_ps(ones_8s, _mm256_cmp_ps(a, b, 13)); } +FORCEINLINE __m256 gt_p(__m256 a, __m256 b) { return _mm256_and_ps(ones_8s, _mm256_cmp_ps(a, b, 14)); } + +FORCEINLINE __m256 sqrt_p(__m256 x) { return _mm256_sqrt_ps(x); } +FORCEINLINE __m256 abs_p(__m256 x) { return _mm256_and_ps(x, abs_mask_8s); } +FORCEINLINE __m256 neg_p(__m256 x) { return _mm256_xor_ps(x, sign_mask_8s); } +FORCEINLINE __m256 sign_p(__m256 x) { return _mm256_or_ps(ones_8s, _mm256_and_ps(x, sign_mask_8s)); } + +#include "special_vectorization.hpp" + #endif // __AVX__ #ifdef __AVX512F__ @@ -338,8 +423,145 @@ FORCEINLINE __m512d sign_p(__m512d x) { return _mm512_or_pd(ones_8d, _mm512_and_ #include "special_vectorization.hpp" +/*! + * Create specialization for array of 16 floats. + */ +#define ARRAY_T Array +#define SCALAR_T float +#define REGISTER_T __m512 +#define SIZE_TAG SizeTag::SIXTEEN() + +static const __m512 abs_mask_16s = _mm512_castsi512_ps(_mm512_set1_epi32(abs_mask_s)); +static const __m512 sign_mask_16s = _mm512_castsi512_ps(_mm512_set1_epi32(sign_mask_s)); +static const __m512 ones_16s = _mm512_set1_ps(1); + +FORCEINLINE __m512 set1_p(SizeTag::SIXTEEN, float p) { return _mm512_set1_ps(p); } +FORCEINLINE __m512 load_p(SizeTag::SIXTEEN, const float* p) { return _mm512_load_ps(p); } +FORCEINLINE __m512 loadu_p(SizeTag::SIXTEEN, const float* p) { return _mm512_loadu_ps(p); } +FORCEINLINE void store_p(float* p, __m512 x) { _mm512_store_ps(p, x); } +FORCEINLINE void storeu_p(float* p, __m512 x) { _mm512_storeu_ps(p, x); } +FORCEINLINE void stream_p(float* p, __m512 x) { _mm512_stream_ps(p, x); } + +FORCEINLINE __m512 add_p(__m512 a, __m512 b) { return _mm512_add_ps(a, b); } +FORCEINLINE __m512 sub_p(__m512 a, __m512 b) { return _mm512_sub_ps(a, b); } +FORCEINLINE __m512 mul_p(__m512 a, __m512 b) { return _mm512_mul_ps(a, b); } +FORCEINLINE __m512 div_p(__m512 a, __m512 b) { return _mm512_div_ps(a, b); } +FORCEINLINE __m512 max_p(__m512 a, __m512 b) { return _mm512_max_ps(a, b); } +FORCEINLINE __m512 min_p(__m512 a, __m512 b) { return _mm512_min_ps(a, b); } + +template +FORCEINLINE __m512 cmp_p(__m512 a, __m512 b) { + return _mm512_mask_blend_ps(_mm512_cmp_ps_mask(a, b, opCode), _mm512_setzero_ps(), ones_16s); +} +FORCEINLINE __m512 eq_p(__m512 a, __m512 b) { return cmp_p<0>(a, b); } +FORCEINLINE __m512 lt_p(__m512 a, __m512 b) { return cmp_p<1>(a, b); } +FORCEINLINE __m512 le_p(__m512 a, __m512 b) { return cmp_p<2>(a, b); } +FORCEINLINE __m512 ne_p(__m512 a, __m512 b) { return cmp_p<4>(a, b); } +FORCEINLINE __m512 ge_p(__m512 a, __m512 b) { return cmp_p<13>(a, b); } +FORCEINLINE __m512 gt_p(__m512 a, __m512 b) { return cmp_p<14>(a, b); } + +FORCEINLINE __m512 sqrt_p(__m512 x) { return _mm512_sqrt_ps(x); } +FORCEINLINE __m512 abs_p(__m512 x) { return _mm512_and_ps(x, abs_mask_16s); } +FORCEINLINE __m512 neg_p(__m512 x) { return _mm512_xor_ps(x, sign_mask_16s); } +FORCEINLINE __m512 sign_p(__m512 x) { return _mm512_or_ps(ones_16s, _mm512_and_ps(x, sign_mask_16s)); } + +#include "special_vectorization.hpp" + #endif // __AVX512F__ +#if defined(__ARM_NEON) || defined(__ARM_NEON__) +/*! + * Create specialization for array of 2 doubles. + */ +#define ARRAY_T Array +#define SCALAR_T double +#define REGISTER_T float64x2_t +#define SIZE_TAG SizeTag::TWO() + +static const uint64x2_t abs_mask_2d_u = vdupq_n_u64(abs_mask_d); +static const uint64x2_t sign_mask_2d_u = vdupq_n_u64(sign_mask_d); +static const uint64x2_t ones_2d_u = vreinterpretq_u64_f64(vdupq_n_f64(1.0)); +static const uint64x2_t ones_2u = vdupq_n_u64(~0ULL); + +FORCEINLINE float64x2_t set1_p(SizeTag::TWO, double p) { return vdupq_n_f64(p); } +FORCEINLINE float64x2_t load_p(SizeTag::TWO, const double* p) { return vld1q_f64(p); } +FORCEINLINE float64x2_t loadu_p(SizeTag::TWO, const double* p) { return vld1q_f64(p); } +FORCEINLINE void store_p(double* p, float64x2_t x) { vst1q_f64(p, x); } +FORCEINLINE void storeu_p(double* p, float64x2_t x) { vst1q_f64(p, x); } +/*--- No direct NEON equivalent to streaming stores. ---*/ +FORCEINLINE void stream_p(double* p, float64x2_t x) { vst1q_f64(p, x); } + +FORCEINLINE float64x2_t add_p(float64x2_t a, float64x2_t b) { return vaddq_f64(a, b); } +FORCEINLINE float64x2_t sub_p(float64x2_t a, float64x2_t b) { return vsubq_f64(a, b); } +FORCEINLINE float64x2_t mul_p(float64x2_t a, float64x2_t b) { return vmulq_f64(a, b); } +FORCEINLINE float64x2_t div_p(float64x2_t a, float64x2_t b) { return vdivq_f64(a, b); } +FORCEINLINE float64x2_t max_p(float64x2_t a, float64x2_t b) { return vmaxq_f64(a, b); } +FORCEINLINE float64x2_t min_p(float64x2_t a, float64x2_t b) { return vminq_f64(a, b); } + +/*--- Comparisons return uint64x2_t masks. Convert to 0.0 / 1.0. ---*/ +FORCEINLINE float64x2_t int2float(uint64x2_t a) { return vreinterpretq_f64_u64(a); } +FORCEINLINE float64x2_t cmp2float(uint64x2_t cmp) { return int2float(vandq_u64(ones_2d_u, cmp)); } +FORCEINLINE float64x2_t eq_p(float64x2_t a, float64x2_t b) { return cmp2float(vceqq_f64(a, b)); } +FORCEINLINE float64x2_t lt_p(float64x2_t a, float64x2_t b) { return cmp2float(vcltq_f64(a, b)); } +FORCEINLINE float64x2_t le_p(float64x2_t a, float64x2_t b) { return cmp2float(vcleq_f64(a, b)); } +FORCEINLINE float64x2_t ne_p(float64x2_t a, float64x2_t b) { return cmp2float(veorq_u64(ones_2u, vceqq_f64(a, b))); } +FORCEINLINE float64x2_t ge_p(float64x2_t a, float64x2_t b) { return cmp2float(vcgeq_f64(a, b)); } +FORCEINLINE float64x2_t gt_p(float64x2_t a, float64x2_t b) { return cmp2float(vcgtq_f64(a, b)); } + +FORCEINLINE float64x2_t sqrt_p(float64x2_t x) { return vsqrtq_f64(x); } +FORCEINLINE float64x2_t abs_p(float64x2_t x) { return int2float(vandq_u64(vreinterpretq_u64_f64(x), abs_mask_2d_u)); } +FORCEINLINE float64x2_t neg_p(float64x2_t x) { return int2float(veorq_u64(vreinterpretq_u64_f64(x), sign_mask_2d_u)); } +FORCEINLINE float64x2_t sign_p(float64x2_t x) { + return int2float(vorrq_u64(ones_2d_u, vandq_u64(vreinterpretq_u64_f64(x), sign_mask_2d_u))); +} + +#include "special_vectorization.hpp" + +/*! + * Create specialization for array of 4 floats. + */ +#define ARRAY_T Array +#define SCALAR_T float +#define REGISTER_T float32x4_t +#define SIZE_TAG SizeTag::FOUR() + +static const uint32x4_t abs_mask_4s_u = vdupq_n_u32(abs_mask_s); +static const uint32x4_t sign_mask_4s_u = vdupq_n_u32(sign_mask_s); +static const uint32x4_t ones_4s_u = vreinterpretq_u32_f32(vdupq_n_f32(1.0f)); + +FORCEINLINE float32x4_t set1_p(SizeTag::FOUR, float p) { return vdupq_n_f32(p); } +FORCEINLINE float32x4_t load_p(SizeTag::FOUR, const float* p) { return vld1q_f32(p); } +FORCEINLINE float32x4_t loadu_p(SizeTag::FOUR, const float* p) { return vld1q_f32(p); } +FORCEINLINE void store_p(float* p, float32x4_t x) { vst1q_f32(p, x); } +FORCEINLINE void storeu_p(float* p, float32x4_t x) { vst1q_f32(p, x); } +FORCEINLINE void stream_p(float* p, float32x4_t x) { vst1q_f32(p, x); } +FORCEINLINE float32x4_t add_p(float32x4_t a, float32x4_t b) { return vaddq_f32(a, b); } +FORCEINLINE float32x4_t sub_p(float32x4_t a, float32x4_t b) { return vsubq_f32(a, b); } +FORCEINLINE float32x4_t mul_p(float32x4_t a, float32x4_t b) { return vmulq_f32(a, b); } +FORCEINLINE float32x4_t div_p(float32x4_t a, float32x4_t b) { return vdivq_f32(a, b); } +FORCEINLINE float32x4_t max_p(float32x4_t a, float32x4_t b) { return vmaxq_f32(a, b); } +FORCEINLINE float32x4_t min_p(float32x4_t a, float32x4_t b) { return vminq_f32(a, b); } + +FORCEINLINE float32x4_t int2float(uint32x4_t a) { return vreinterpretq_f32_u32(a); } +FORCEINLINE float32x4_t cmp2float(uint32x4_t cmp) { return int2float(vandq_u32(ones_4s_u, cmp)); } +FORCEINLINE float32x4_t eq_p(float32x4_t a, float32x4_t b) { return cmp2float(vceqq_f32(a, b)); } +FORCEINLINE float32x4_t lt_p(float32x4_t a, float32x4_t b) { return cmp2float(vcltq_f32(a, b)); } +FORCEINLINE float32x4_t le_p(float32x4_t a, float32x4_t b) { return cmp2float(vcleq_f32(a, b)); } +FORCEINLINE float32x4_t ne_p(float32x4_t a, float32x4_t b) { return cmp2float(vmvnq_u32(vceqq_f32(a, b))); } +FORCEINLINE float32x4_t ge_p(float32x4_t a, float32x4_t b) { return cmp2float(vcgeq_f32(a, b)); } +FORCEINLINE float32x4_t gt_p(float32x4_t a, float32x4_t b) { return cmp2float(vcgtq_f32(a, b)); } + +FORCEINLINE float32x4_t sqrt_p(float32x4_t x) { return vsqrtq_f32(x); } +FORCEINLINE float32x4_t abs_p(float32x4_t x) { return int2float(vandq_u32(vreinterpretq_u32_f32(x), abs_mask_4s_u)); } +FORCEINLINE float32x4_t neg_p(float32x4_t x) { return int2float(veorq_u32(vreinterpretq_u32_f32(x), sign_mask_4s_u)); } +FORCEINLINE float32x4_t sign_p(float32x4_t x) { + return int2float(vorrq_u32(ones_4s_u, vandq_u32(vreinterpretq_u32_f32(x), sign_mask_4s_u))); +} + +#include "special_vectorization.hpp" + +#endif // __ARM_NEON__ + #undef ARRAY_BOILERPLATE /// @} diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index 0f7a5c6821fa..928731422c7d 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -1311,9 +1311,9 @@ void CConfig::SetConfig_Options() { /* DESCRIPTION: Definition of the turbulent thermal conductivity model (CONSTANT_PRANDTL_TURB (default), NONE). */ addEnumOption("TURBULENT_CONDUCTIVITY_MODEL", Kind_ConductivityModel_Turb, TurbConductivityModel_Map, CONDUCTIVITYMODEL_TURB::CONSTANT_PRANDTL); - /*--- Options related to Constant Thermal Conductivity Model ---*/ + /*--- Options related to Constant Thermal Conductivity Model ---*/ - /* DESCRIPTION: default value for AIR */ + /* DESCRIPTION: default value for AIR */ addDoubleListOption("THERMAL_CONDUCTIVITY_CONSTANT", nThermal_Conductivity_Constant , Thermal_Conductivity_Constant); /*--- Options related to temperature polynomial coefficients for fluid models. ---*/ @@ -1410,6 +1410,10 @@ void CConfig::SetConfig_Options() { /*!\brief FLAME_INIT_METHOD \n DESCRIPTION: Ignition method for flamelet solver \n DEFAULT: no ignition; cold flow only. */ addEnumOption("FLAME_INIT_METHOD", flamelet_ParsedOptions.ignition_method, Flamelet_Init_Map, FLAMELET_INIT_TYPE::NONE); + /*!\brief FLAME_ENTHALPY_BC \n DESCRIPTION: enthalpy BC for thermal walls. FLOW_MARKERS (default): enthalpy derived + from MARKER_ISOTHERMAL temperature or MARKER_HEATFLUX via GetEnthFromTemp. SPECIES_MARKERS: enthalpy and all other + scalars taken directly from MARKER_WALL_SPECIES or the Python wrapper (SetMarkerCustomScalar). \n DEFAULT: FLOW_MARKERS \ingroup Config */ + addEnumOption("FLAME_ENTHALPY_BC", flamelet_ParsedOptions.enthalpy_bc, Flamelet_Enthalpy_BC_Map, FLAMELET_ENTHALPY_BC::FLOW_MARKERS); /*!\brief FLAME_INIT \n DESCRIPTION: flame front initialization using the flamelet model \ingroup Config*/ addDoubleArrayOption("FLAME_INIT", flamelet_ParsedOptions.flame_init.size(), false, flamelet_ParsedOptions.flame_init.begin()); @@ -1981,16 +1985,22 @@ void CConfig::SetConfig_Options() { addDoubleOption("MG_DAMP_PROLONGATION", Damp_Correc_Prolong, 0.5); /*!\brief MG_SMOOTH_EARLY_EXIT\n DESCRIPTION: Enable early exit for MG smoothing when RMS drops below threshold. DEFAULT: NO \ingroup Config*/ addBoolOption("MG_SMOOTH_EARLY_EXIT", MGOptions.MG_Smooth_EarlyExit, true); - /*!\brief MG_SMOOTH_RES_THRESHOLD\n DESCRIPTION: Smoothing stops when current_rms < threshold * initial_rms. DEFAULT: 0.1 \ingroup Config*/ - addDoubleOption("MG_SMOOTH_RES_THRESHOLD", MGOptions.MG_Smooth_Res_Threshold, 0.5); + /*!\brief MG_SMOOTH_RES_THRESHOLD\n DESCRIPTION: Early exit smoothing when current_rms drops below threshold * initial_rms. DEFAULT: 0.9 \ingroup Config*/ + addDoubleOption("MG_SMOOTH_RES_THRESHOLD", MGOptions.MG_Smooth_Res_Threshold, 0.9); /*!\brief MG_SMOOTH_OUTPUT\n DESCRIPTION: Print compact per-cycle smoothing iteration summary. DEFAULT: NO \ingroup Config*/ addBoolOption("MG_SMOOTH_OUTPUT", MGOptions.MG_Smooth_Output, false); + /*!\brief MG_SMOOTH_STAGNATION_TOL\n DESCRIPTION: Stop smoothing if current_rms >= previous_rms * this value. Values < 1.0 enable early exit on stagnation, 1.0 only exits on defect growth. DEFAULT: 0.99 \ingroup Config*/ + addDoubleOption("MG_SMOOTH_STAGNATION_TOL", MGOptions.MG_Smooth_StagnationTol, 0.99); /*!\brief MG_SMOOTH_COEFF\n DESCRIPTION: Smoothing coefficient for the correction prolongation Jacobi smoother. DEFAULT: 1.25 \ingroup Config*/ addDoubleOption("MG_SMOOTH_COEFF", MGOptions.MG_Smooth_Coeff, 1.25); /*!\brief MG_MIN_MESHSIZE\n DESCRIPTION: Minimum number of CVs on the coarsest multigrid level. Levels that would produce fewer CVs are not created. DEFAULT: 50 \ingroup Config*/ addUnsignedLongOption("MG_MIN_MESHSIZE", MGOptions.MG_Min_MeshSize, 500); /*!\brief MG_IMPLICIT_LINES\n DESCRIPTION: Enable agglomeration along implicit lines from wall seeds. DEFAULT: NO \ingroup Config*/ addBoolOption("MG_IMPLICIT_LINES", MGOptions.MG_Implicit_Lines, false); + /*!\brief MG_IMPLICIT_LINES_MAX_LENGTH\n DESCRIPTION: Maximum number of nodes on a wall-normal implicit agglomeration line (including the wall seed node). DEFAULT: 20 \ingroup Config*/ + addUnsignedLongOption("MG_IMPLICIT_LINES_MAX_LENGTH", MGOptions.MG_Implicit_Lines_MaxLength, 20); + /*!\brief MG_CFL_SCALING\n DESCRIPTION: Per-level CFL scaling factors for coarse MG levels. Entry i is the ratio CFL(i+1)/CFL(i). If fewer values than nMGLevels are given, the last value is repeated. DEFAULT: 0.25 (i.e., 1/4 per level) \ingroup Config*/ + addDoubleListOption("MG_CFL_SCALING", nMG_CflScaling_p, MG_CflScaling_p); /*!\par CONFIG_CATEGORY: Spatial Discretization \ingroup Config*/ /*--- Options related to the spatial discretization ---*/ @@ -4785,6 +4795,16 @@ void CConfig::SetPostprocessing(SU2_COMPONENT val_software, unsigned short val_i [](unsigned short ) { return (unsigned short)0; }); fillSmooth(nMG_CorrecSmooth_p, MG_CorrecSmooth_p, MGOptions.MG_CorrecSmooth, [](unsigned short ) { return (unsigned short)0; }); + + /*--- Fill MG_CflScaling to size nMGLevels (one entry per coarse level transition). ---*/ + MGOptions.MG_CflScaling.resize(nMGLevels); + if (nMG_CflScaling_p != 0) { + for (unsigned short i = 0; i < nMGLevels; ++i) + MGOptions.MG_CflScaling[i] = (i < nMG_CflScaling_p) ? MG_CflScaling_p[i] : MG_CflScaling_p[nMG_CflScaling_p - 1]; + } else { + for (unsigned short i = 0; i < nMGLevels; ++i) + MGOptions.MG_CflScaling[i] = 0.25; + } } /*--- Override MG Smooth parameters ---*/ @@ -6448,6 +6468,9 @@ void CConfig::SetOutput(SU2_COMPONENT val_software, unsigned short val_izone) { cout << " with no production modification"; break; } + if (sstParsedOptions.production == SST_OPTIONS::COMP_Sarkar || sstParsedOptions.production == SST_OPTIONS::COMP_Wilcox) { + if (sstParsedOptions.compPressDil) cout << " and with pressure dilatation correction (Sarkar Coefficients)"; + } if (sstParsedOptions.dll){ cout << "\nusing non dimensional lower limits relative to infinity values clipping by Coefficients:" ; @@ -7530,10 +7553,12 @@ void CConfig::SetOutput(SU2_COMPONENT val_software, unsigned short val_izone) { MGTable.AddColumn("Presmooth", 10); MGTable.AddColumn("PostSmooth", 10); MGTable.AddColumn("CorrectSmooth", 10); + MGTable.AddColumn("CFL Scaling", 12); MGTable.SetAlign(PrintingToolbox::CTablePrinter::RIGHT); MGTable.PrintHeader(); for (unsigned short iLevel = 0; iLevel < nMGLevels+1; iLevel++) { - MGTable << iLevel << MGOptions.MG_PreSmooth[iLevel] << MGOptions.MG_PostSmooth[iLevel] << MGOptions.MG_CorrecSmooth[iLevel]; + const string cflStr = (iLevel == 0) ? "-" : std::to_string(MGOptions.MG_CflScaling[iLevel-1]).substr(0,6); + MGTable << iLevel << MGOptions.MG_PreSmooth[iLevel] << MGOptions.MG_PostSmooth[iLevel] << MGOptions.MG_CorrecSmooth[iLevel] << cflStr; } MGTable.PrintFooter(); } diff --git a/Common/src/fem/fem_geometry_structure.cpp b/Common/src/fem/fem_geometry_structure.cpp index 4a98ca15cd45..ae71919060a2 100644 --- a/Common/src/fem/fem_geometry_structure.cpp +++ b/Common/src/fem/fem_geometry_structure.cpp @@ -37,8 +37,15 @@ /* Prototypes for Lapack functions, if MKL or LAPACK is used. */ #if defined(HAVE_MKL) || defined(HAVE_LAPACK) -extern "C" void dpotrf_(char*, int*, passivedouble*, int*, int*); -extern "C" void dpotri_(char*, int*, passivedouble*, int*, int*); +#ifdef USE_SINGLE_PRECISION +#define POTRF_IMPL spotrf_ +#define POTRI_IMPL spotri_ +#else +#define POTRF_IMPL dpotrf_ +#define POTRI_IMPL dpotri_ +#endif +extern "C" void POTRF_IMPL(char*, int*, passivedouble*, int*, int*); +extern "C" void POTRI_IMPL(char*, int*, passivedouble*, int*, int*); #endif bool CPointFEM::operator<(const CPointFEM& other) const { @@ -5361,7 +5368,7 @@ void CMeshFEM_DG::MetricTermsVolumeElements(CConfig* config) { than a standard inverse. */ char uplo = 'L'; int NN = nDOFs, errorCode; - dpotrf_(&uplo, &NN, massMat.data(), &NN, &errorCode); + POTRF_IMPL(&uplo, &NN, massMat.data(), &NN, &errorCode); if (errorCode != 0) { ostringstream message; if (errorCode < 0) { @@ -5376,7 +5383,7 @@ void CMeshFEM_DG::MetricTermsVolumeElements(CConfig* config) { SU2_MPI::Error(message.str(), CURRENT_FUNCTION); } - dpotri_(&uplo, &NN, massMat.data(), &NN, &errorCode); + POTRI_IMPL(&uplo, &NN, massMat.data(), &NN, &errorCode); if (errorCode != 0) { ostringstream message; if (errorCode < 0) { diff --git a/Common/src/geometry/CMultiGridGeometry.cpp b/Common/src/geometry/CMultiGridGeometry.cpp index a55c3972cfa3..347a633e2a7b 100644 --- a/Common/src/geometry/CMultiGridGeometry.cpp +++ b/Common/src/geometry/CMultiGridGeometry.cpp @@ -1005,7 +1005,7 @@ void CMultiGridGeometry::SetControlVolume(const CGeometry* fine_grid, unsigned s auto iFinePoint = nodes->GetChildren_CV(iCoarsePoint, iChildren); Coarse_Volume += fine_grid->nodes->GetVolume(iFinePoint); } - nodes->SetVolume(iCoarsePoint, Coarse_Volume); + nodes->SetVolume(iCoarsePoint, max(Coarse_Volume, EPS)); } /*--- Update or not the values of faces at the edge ---*/ @@ -1280,24 +1280,28 @@ su2double CMultiGridGeometry::ComputeLocalCurvature(const CGeometry* fine_grid, void CMultiGridGeometry::AgglomerateImplicitLines(unsigned long& Index_CoarseCV, const CGeometry* fine_grid, const CConfig* config, CMultiGridQueue& MGQueue_InnerCV) { /*--- Parameters ---*/ - const su2double ANGLE_THRESHOLD_DEG = 20.0; /*!< Stop line if direction deviates more than this. */ - constexpr unsigned long MAX_LINE_LENGTH = 20; /*!< Max nodes on implicit line (including wall). */ + const su2double ANGLE_THRESHOLD_DEG = 20.0; /*!< Stop line if direction deviates more than this. */ + const unsigned long MAX_LINE_LENGTH = config->GetMGOptions().MG_Implicit_Lines_MaxLength; const su2double cos_threshold = cos(ANGLE_THRESHOLD_DEG * PI_NUMBER / 180.0); const unsigned long nPointFine = fine_grid->GetnPoint(); - /*--- Collect implicit lines starting at wall vertices. + /*--- Collect implicit lines starting at viscous (no-slip) wall vertices only. + * Seeding from non-wall boundaries (farfield, inlet, outlet, symmetry) would + * claim interior BL cells before the wall lines can reach them, leaving + * wall-seeded lines with length < 3 (discarded). Restricting to viscous walls + * ensures the boundary-layer cells are agglomerated wall-first. * Each line: [wall_node, interior_1, interior_2, ...]. * The wall node (index 0) is already agglomerated by boundary agglomeration; * only interior nodes (index >= 1) are paired into coarse CVs. ---*/ vector> lines; for (auto iMarker = 0u; iMarker < fine_grid->GetnMarker(); iMarker++) { - /*--- Skip non-physical markers ---*/ - if (config->GetMarker_All_KindBC(iMarker) == SEND_RECEIVE || - config->GetMarker_All_KindBC(iMarker) == INTERNAL_BOUNDARY || - config->GetMarker_All_KindBC(iMarker) == NEARFIELD_BOUNDARY) - continue; + /*--- Only seed lines from viscous (no-slip) wall markers. + * Non-wall boundaries (farfield, inlet, outlet, symmetry) must NOT seed + * lines because they would prematurely claim boundary-layer interior nodes. ---*/ + const auto bc = config->GetMarker_All_KindBC(iMarker); + if (bc != HEAT_FLUX && bc != ISOTHERMAL && bc != CHT_WALL_INTERFACE && bc != SMOLUCHOWSKI_MAXWELL) continue; for (auto iVertex = 0ul; iVertex < fine_grid->GetnVertex(iMarker); iVertex++) { const auto iPoint = fine_grid->vertex[iMarker][iVertex]->GetNode(); diff --git a/Common/src/geometry/CPhysicalGeometry.cpp b/Common/src/geometry/CPhysicalGeometry.cpp index 53720985fe26..79421eded3e0 100644 --- a/Common/src/geometry/CPhysicalGeometry.cpp +++ b/Common/src/geometry/CPhysicalGeometry.cpp @@ -7456,10 +7456,8 @@ void CPhysicalGeometry::ComputeMeshQualityStatistics(const CConfig* config) { /*--- Compute the angle between the unit normal associated with the edge and the unit vector pointing from iPoint to jPoint. ---*/ - su2double dotProduct = 0.0; - for (unsigned short iDim = 0; iDim < nDim; iDim++) { - dotProduct += (Normal[iDim] / area) * (edgeVector[iDim] / distance); - } + su2double dotProduct = GeometryToolbox::DotProduct(nDim, Normal, edgeVector.data()); + dotProduct = min(max(-1.0, dotProduct / (area * distance)), 1.0); /*--- The definition of orthogonality is an area-weighted average of 90 degrees minus the angle between the face area unit normal and diff --git a/Common/src/grid_movement/CSurfaceMovement.cpp b/Common/src/grid_movement/CSurfaceMovement.cpp index 77f5110540e9..f43e7f89c593 100644 --- a/Common/src/grid_movement/CSurfaceMovement.cpp +++ b/Common/src/grid_movement/CSurfaceMovement.cpp @@ -3902,7 +3902,7 @@ void CSurfaceMovement::SetAirfoil(CGeometry* boundary, CConfig* config) { su2double *VarCoord, *Coord, NewYCoord, NewXCoord, *Coord_i, *Coord_ip1, yp1, ypn, Airfoil_Coord[2] = {0.0, 0.0}, factor, coeff = 10000, Upper, Lower, Arch = 0.0, TotalArch = 0.0, x_i, x_ip1, y_i, y_ip1; - passivedouble AirfoilScale; + double AirfoilScale; vector Svalue, Xcoord, Ycoord, Xcoord2, Ycoord2, Xcoord_Aux, Ycoord_Aux; bool AddBegin = true, AddEnd = true; char AirfoilFile[256], AirfoilFormat[15], MeshOrientation[15], AirfoilClose[15]; diff --git a/Common/src/interface_interpolation/CRadialBasisFunction.cpp b/Common/src/interface_interpolation/CRadialBasisFunction.cpp index c1d932588f69..3b14674a7866 100644 --- a/Common/src/interface_interpolation/CRadialBasisFunction.cpp +++ b/Common/src/interface_interpolation/CRadialBasisFunction.cpp @@ -37,11 +37,15 @@ #define HAVE_LAPACK #endif #elif defined(HAVE_LAPACK) +#ifdef USE_SINGLE_PRECISION +#define GEMM_IMPL sgemm_ +#else +#define GEMM_IMPL dgemm_ +#endif // dgemm(opA, opB, m, n, k, alpha, A, lda, B, ldb, beta, C, ldc) -extern "C" void dgemm_(const char*, const char*, const int*, const int*, const int*, const passivedouble*, - const passivedouble*, const int*, const passivedouble*, const int*, const passivedouble*, - passivedouble*, const int*); -#define DGEMM dgemm_ +extern "C" void GEMM_IMPL(const char*, const char*, const int*, const int*, const int*, const passivedouble*, + const passivedouble*, const int*, const passivedouble*, const int*, const passivedouble*, + passivedouble*, const int*); #endif CRadialBasisFunction::CRadialBasisFunction(CGeometry**** geometry_container, const CConfig* const* config, @@ -334,7 +338,7 @@ void CRadialBasisFunction::SetTransferCoeff(const CConfig* const* config) { const int M = interpMat.cols(), N = slabSize, K = funcMat.cols(); // lda = C_inv_trunc.cols() = M; ldb = funcMat.cols() = K; ldc = interpMat.cols() = M; const passivedouble alpha = 1.0, beta = 0.0; - DGEMM(&op, &op, &M, &N, &K, &alpha, C_inv_trunc[0], &M, funcMat[0], &K, &beta, interpMat[0], &M); + GEMM_IMPL(&op, &op, &M, &N, &K, &alpha, C_inv_trunc[0], &M, funcMat[0], &K, &beta, interpMat[0], &M); #else /*--- Naive product, loop order considers short-wide * nature of funcMat and interpMat. ---*/ @@ -480,7 +484,7 @@ void CRadialBasisFunction::ComputeGeneratorMatrix(RADIAL_BASIS type, bool usePol const int M = nVertexDonor, N = nVertexDonor, K = nPolynomial + 1; // lda = C_inv_top.cols() = M; ldb = Q.cols() = M; ldc = C_inv_bot.cols() = M; const passivedouble alpha = -1.0, beta = 1.0; - DGEMM(&opa, &opb, &M, &N, &K, &alpha, C_inv_top[0], &M, Q[0], &M, &beta, C_inv_bot[0], &M); + GEMM_IMPL(&opa, &opb, &M, &N, &K, &alpha, C_inv_top[0], &M, Q[0], &M, &beta, C_inv_bot[0], &M); #else // naive product for (int i = 0; i < nVertexDonor; ++i) for (int j = 0; j < nVertexDonor; ++j) diff --git a/Common/src/linear_algebra/CPastixWrapper.cpp b/Common/src/linear_algebra/CPastixWrapper.cpp index 1633a88bbde9..f4db581a879f 100644 --- a/Common/src/linear_algebra/CPastixWrapper.cpp +++ b/Common/src/linear_algebra/CPastixWrapper.cpp @@ -204,8 +204,7 @@ void CPastixWrapper::Initialize(CGeometry* geometry, const CConfig* SU2_MPI::Error("Error analyzing matrix: " + std::to_string(rc), CURRENT_FUNCTION); } - if (mpi_rank == MASTER_NODE && verb > 0) - cout << " +--------------------------------------------------------------------+" << endl; + if (mpi_rank == MASTER_NODE && verb > 0) cout << "+-------------------------------------------------+" << endl; isinitialized = true; } @@ -250,10 +249,8 @@ void CPastixWrapper::Factorize(CGeometry* geometry, const CConfig* c /*--- Yes ---*/ if (mpi_rank == MASTER_NODE && verb > 0) { - cout << endl; - cout << " +--------------------------------------------------------------------+" << endl; - cout << " + PaStiX : Parallel Sparse matriX package +" << endl; - cout << " +--------------------------------------------------------------------+" << endl; + cout << "\n+-------------------------------------------------+"; + cout << "\n+ PaStiX : Parallel Sparse matriX package +" << endl; } const unsigned long szBlk = matrix.nVar * matrix.nVar, nNonZero = values.size(); @@ -297,8 +294,7 @@ void CPastixWrapper::Factorize(CGeometry* geometry, const CConfig* c SU2_MPI::Error("Error factorizing matrix: " + std::to_string(rc), CURRENT_FUNCTION); } - if (mpi_rank == MASTER_NODE && verb > 0) - cout << " +--------------------------------------------------------------------+" << endl << endl; + if (mpi_rank == MASTER_NODE && verb > 0) cout << "+-------------------------------------------------+\n" << endl; isfactorized = true; } @@ -307,7 +303,7 @@ void CPastixWrapper::Factorize(CGeometry* geometry, const CConfig* c template class CPastixWrapper; #else template class CPastixWrapper; -#ifdef USE_MIXED_PRECISION +#if defined(USE_MIXED_PRECISION) && !defined(USE_SINGLE_PRECISION) template class CPastixWrapper; #endif #endif diff --git a/Common/src/linear_algebra/CSysMatrix.cpp b/Common/src/linear_algebra/CSysMatrix.cpp index f9b5d5427321..00ef51c2023a 100644 --- a/Common/src/linear_algebra/CSysMatrix.cpp +++ b/Common/src/linear_algebra/CSysMatrix.cpp @@ -525,8 +525,14 @@ void CSysMatrix::Gauss_Elimination(ScalarType* matrix, ScalarType* v #ifdef USE_MKL_LAPACK // With MKL_DIRECT_CALL enabled, this is significantly faster than native code on Intel Architectures. lapack_int ipiv[MAXNVAR]; - LAPACKE_dgetrf(LAPACK_ROW_MAJOR, nVar, nVar, matrix, nVar, ipiv); - LAPACKE_dgetrs(LAPACK_ROW_MAJOR, 'N', nVar, 1, matrix, nVar, ipiv, vec, 1); + if constexpr (std::is_same_v) { + LAPACKE_dgetrf(LAPACK_ROW_MAJOR, nVar, nVar, matrix, nVar, ipiv); + LAPACKE_dgetrs(LAPACK_ROW_MAJOR, 'N', nVar, 1, matrix, nVar, ipiv, vec, 1); + } else { + static_assert(std::is_same_v, "ScalarType not handled"); + LAPACKE_sgetrf(LAPACK_ROW_MAJOR, nVar, nVar, matrix, nVar, ipiv); + LAPACKE_sgetrs(LAPACK_ROW_MAJOR, 'N', nVar, 1, matrix, nVar, ipiv, vec, 1); + } #else #define A(I, J) matrix[(I)*nVar + (J)] @@ -577,8 +583,14 @@ void CSysMatrix::MatrixInverse(ScalarType* matrix, ScalarType* inver #ifdef USE_MKL_LAPACK // With MKL_DIRECT_CALL enabled, this is significantly faster than native code on Intel Architectures. lapack_int ipiv[MAXNVAR]; - LAPACKE_dgetrf(LAPACK_ROW_MAJOR, nVar, nVar, matrix, nVar, ipiv); - LAPACKE_dgetrs(LAPACK_ROW_MAJOR, 'N', nVar, nVar, matrix, nVar, ipiv, inverse, nVar); + if constexpr (std::is_same_v) { + LAPACKE_dgetrf(LAPACK_ROW_MAJOR, nVar, nVar, matrix, nVar, ipiv); + LAPACKE_dgetrs(LAPACK_ROW_MAJOR, 'N', nVar, nVar, matrix, nVar, ipiv, inverse, nVar); + } else { + static_assert(std::is_same_v, "ScalarType not handled"); + LAPACKE_sgetrf(LAPACK_ROW_MAJOR, nVar, nVar, matrix, nVar, ipiv); + LAPACKE_sgetrs(LAPACK_ROW_MAJOR, 'N', nVar, nVar, matrix, nVar, ipiv, inverse, nVar); + } #else #define A(I, J) matrix[(I)*nVar + (J)] @@ -1364,7 +1376,7 @@ void CSysMatrix::ComputePastixPreconditioner(const CSysVector -__global__ void GPUMatrixVectorProductAdd(matrixType* matrix, vectorType* vec, vectorType* prod, const unsigned long* d_row_ptr, const unsigned long* d_col_ind, unsigned long nPointDomain, unsigned long nVar, unsigned long nEqn) -{ - int row = (blockIdx.x * blockDim.x + threadIdx.x)/32; - int threadNo = threadIdx.x%32; - int activeThreads = nVar * (32/nVar); - - int blockRow = (threadNo/nVar)%nVar; - - if(row +#include +#include + +inline void cusparseAssert(cusparseStatus_t code, const char* file, int line, bool abort = true) { + if (code != CUSPARSE_STATUS_SUCCESS) { + fprintf(stderr, "cuSPARSEassert: %s %s %d\n", cusparseGetErrorString(code), file, line); + if (abort) exit(static_cast(code)); + } +} - for(int index = d_row_ptr[row] * nVar * nEqn + threadNo; index < d_row_ptr[row+1] * nVar * nEqn; index+=activeThreads) - { - int blockCol = index%nEqn; - int blockNo = index/(nVar * nEqn); - res += matrix[index] * vec[(d_col_ind[blockNo])*nVar + blockCol]; - } +#define cusparseErrChk(ans) \ + { \ + cusparseAssert((ans), __FILE__, __LINE__); \ + } + +inline cusparseIndexType_t GetCusparseIndexType() { + if constexpr (sizeof(unsigned long) == 4) { + return CUSPARSE_INDEX_32I; + } else if constexpr (sizeof(unsigned long) == 8) { + return CUSPARSE_INDEX_64I; + } else { + static_assert(sizeof(unsigned long) == 4 || sizeof(unsigned long) == 8, + "cuSPARSE BSR SpMV only supports 32-bit or 64-bit index arrays in this path."); + } +} - atomicAdd(&prod[row * nVar + blockRow], res); - } +template +constexpr cudaDataType GetCudaDataType() { + if constexpr (std::is_same::value) { + return CUDA_R_32F; + } else if constexpr (std::is_same::value) { + return CUDA_R_64F; + } else { + static_assert(std::is_same::value || std::is_same::value, + "cuSPARSE BSR SpMV only supports float and double in this path."); + } } template @@ -62,27 +73,69 @@ void CSysMatrix::HtDTransfer(bool trigger) const if(trigger) gpuErrChk(cudaMemcpy((void*)(d_matrix), (void*)&matrix[0], (sizeof(ScalarType)*nnz*nVar*nEqn), cudaMemcpyHostToDevice)); } -template +template void CSysMatrix::GPUMatrixVectorProduct(const CSysVector& vec, CSysVector& prod, - CGeometry* geometry, const CConfig* config) const - { + CGeometry* geometry, const CConfig* config) const { + if (nVar != nEqn) { + SU2_MPI::Error("CUDA CSysMatrix matvec with cuSPARSE BSR requires square blocks.", CURRENT_FUNCTION); + } - ScalarType* d_vec = vec.GetDevicePointer(); - ScalarType* d_prod = prod.GetDevicePointer(); + ScalarType* d_vec = vec.GetDevicePointer(); + ScalarType* d_prod = prod.GetDevicePointer(); - HtDTransfer(); - vec.HtDTransfer(); - prod.GPUSetVal(0.0); + vec.HtDTransfer(); - dim3 blockDim(KernelParameters::MVP_BLOCK_SIZE,1,1); - int gridx = KernelParameters::round_up_division(KernelParameters::MVP_WARP_SIZE, nPointDomain); - dim3 gridDim(gridx, 1, 1); + const auto indexType = GetCusparseIndexType(); + const auto valueType = GetCudaDataType(); - GPUMatrixVectorProductAdd<<>>(d_matrix, d_vec, d_prod, d_row_ptr, d_col_ind, nPointDomain, nVar, nEqn); - gpuErrChk( cudaPeekAtLastError() ); + const std::int64_t blockSize = static_cast(nVar); - prod.DtHTransfer(); + const std::int64_t brows = static_cast(nPointDomain); + const std::int64_t bcols = static_cast(nPoint); + const std::int64_t bnnz = static_cast(nnz); + + const std::int64_t xSize = static_cast(nPoint) * blockSize; + const std::int64_t ySize = static_cast(nPointDomain) * blockSize; + + const ScalarType alpha = 1.0; + const ScalarType beta = 0.0; + cusparseHandle_t handle = nullptr; + cusparseConstSpMatDescr_t matA = nullptr; + cusparseDnVecDescr_t vecX = nullptr; + cusparseDnVecDescr_t vecY = nullptr; + + cusparseErrChk(cusparseCreate(&handle)); + + cusparseErrChk(cusparseCreateConstBsr(&matA, brows, bcols, bnnz, blockSize, blockSize, d_row_ptr, d_col_ind, d_matrix, + indexType, indexType, CUSPARSE_INDEX_BASE_ZERO, valueType, CUSPARSE_ORDER_ROW)); + + cusparseErrChk(cusparseCreateDnVec(&vecX, xSize, d_vec, valueType)); + cusparseErrChk(cusparseCreateDnVec(&vecY, ySize, d_prod, valueType)); + + size_t bufferSize = 0; + void* dBuffer = nullptr; + + cusparseErrChk(cusparseSpMV_bufferSize(handle, CUSPARSE_OPERATION_NON_TRANSPOSE, &alpha, matA, vecX, &beta, vecY, + valueType, CUSPARSE_SPMV_BSR_ALG1, &bufferSize)); + + if (bufferSize > 0) { + gpuErrChk(cudaMalloc(&dBuffer, bufferSize)); + } + + cusparseErrChk(cusparseSpMV(handle, CUSPARSE_OPERATION_NON_TRANSPOSE, &alpha, matA, vecX, &beta, vecY, valueType, + CUSPARSE_SPMV_BSR_ALG1, dBuffer)); + + if (dBuffer != nullptr) { + gpuErrChk(cudaFree(dBuffer)); + } + + cusparseErrChk(cusparseDestroyDnVec(vecY)); + cusparseErrChk(cusparseDestroyDnVec(vecX)); + cusparseErrChk(cusparseDestroySpMat(matA)); + cusparseErrChk(cusparseDestroy(handle)); + + prod.DtHTransfer(); } template class CSysMatrix; //This is a temporary fix for invalid instantiations due to separating the member function from the header file the class is defined in. Will try to rectify it in coming commits. diff --git a/Common/src/linear_algebra/CSysSolve.cpp b/Common/src/linear_algebra/CSysSolve.cpp index 953bed0ef2af..cd100f311ab0 100644 --- a/Common/src/linear_algebra/CSysSolve.cpp +++ b/Common/src/linear_algebra/CSysSolve.cpp @@ -1728,6 +1728,6 @@ unsigned long CSysSolve::Solve_b(CSysMatrix& Jacobian, c /*--- Explicit instantiations ---*/ template class CSysSolve; -#ifdef USE_MIXED_PRECISION +#if defined(USE_MIXED_PRECISION) && !defined(USE_SINGLE_PRECISION) template class CSysSolve; #endif diff --git a/Common/src/linear_algebra/CSysVector.cpp b/Common/src/linear_algebra/CSysVector.cpp index 61fc3b92a4fc..f7df34633a0e 100644 --- a/Common/src/linear_algebra/CSysVector.cpp +++ b/Common/src/linear_algebra/CSysVector.cpp @@ -144,7 +144,7 @@ CSysVector::~CSysVector() { /*--- Explicit instantiations ---*/ template class CSysVector; -#ifdef USE_MIXED_PRECISION +#if defined(USE_MIXED_PRECISION) && !defined(USE_SINGLE_PRECISION) template class CSysVector; #endif #ifdef CODI_REVERSE_TYPE diff --git a/Common/src/linear_algebra/blas_structure.cpp b/Common/src/linear_algebra/blas_structure.cpp index 2bd87cb378f9..bb85ed9610ad 100644 --- a/Common/src/linear_algebra/blas_structure.cpp +++ b/Common/src/linear_algebra/blas_structure.cpp @@ -34,11 +34,19 @@ #if (defined(HAVE_MKL) || defined(HAVE_BLAS)) && !(defined(CODI_REVERSE_TYPE) || defined(CODI_FORWARD_TYPE)) /* Function prototypes for the BLAS routines used. */ -extern "C" void dgemm_(char*, char*, const int*, const int*, const int*, const passivedouble*, const passivedouble*, - const int*, const passivedouble*, const int*, const passivedouble*, passivedouble*, const int*); +#ifdef USE_SINGLE_PRECISION +#define GEMM_IMPL sgemm_ +#define GEMV_IMPL sgemv_ +#else +#define GEMM_IMPL dgemm_ +#define GEMV_IMPL dgemv_ +#endif +extern "C" void GEMM_IMPL(char*, char*, const int*, const int*, const int*, const passivedouble*, const passivedouble*, + const int*, const passivedouble*, const int*, const passivedouble*, passivedouble*, + const int*); -extern "C" void dgemv_(char*, const int*, const int*, const passivedouble*, const passivedouble*, const int*, - const passivedouble*, const int*, const passivedouble*, passivedouble*, const int*); +extern "C" void GEMV_IMPL(char*, const int*, const int*, const passivedouble*, const passivedouble*, const int*, + const passivedouble*, const int*, const passivedouble*, passivedouble*, const int*); #endif /* Constructor. Initialize the const member variables, if needed. */ @@ -77,7 +85,7 @@ void CBlasStructure::gemm(const int M, const int N, const int K, const su2double su2double beta = 0.0; char trans = 'N'; - dgemm_(&trans, &trans, &N, &M, &K, &alpha, B, &N, A, &K, &beta, C, &N); + GEMM_IMPL(&trans, &trans, &N, &M, &K, &alpha, B, &N, A, &K, &beta, C, &N); #endif @@ -100,7 +108,7 @@ void CBlasStructure::gemv(const int M, const int N, const su2double* A, const su int inc = 1; char trans = 'T'; - dgemv_(&trans, &N, &M, &alpha, A, &N, x, &inc, &beta, y, &inc); + GEMV_IMPL(&trans, &N, &M, &alpha, A, &N, x, &inc, &beta, y, &inc); #else diff --git a/Common/src/toolboxes/CSquareMatrixCM.cpp b/Common/src/toolboxes/CSquareMatrixCM.cpp index 9cbc407cac63..87f6eb356df9 100644 --- a/Common/src/toolboxes/CSquareMatrixCM.cpp +++ b/Common/src/toolboxes/CSquareMatrixCM.cpp @@ -38,11 +38,20 @@ using namespace std; #endif #elif defined(HAVE_LAPACK) /*--- Lapack / Blas routines used in CSquareMatrixCM. ---*/ -extern "C" void dgetrf_(const int*, const int*, passivedouble*, const int*, int*, int*); -extern "C" void dgetri_(const int*, passivedouble*, const int*, int*, passivedouble*, const int*, int*); -extern "C" void dgemm_(char*, char*, const int*, const int*, const int*, const passivedouble*, const passivedouble*, - const int*, const passivedouble*, const int*, const passivedouble*, passivedouble*, const int*); -#define DGEMM dgemm_ +#ifdef USE_SINGLE_PRECISION +#define GEMM_IMPL sgemm_ +#define GETRF_IMPL sgetrf_ +#define GETRI_IMPL sgetri_ +#else +#define GEMM_IMPL dgemm_ +#define GETRF_IMPL dgetrf_ +#define GETRI_IMPL dgetri_ +#endif +extern "C" void GETRF_IMPL(const int*, const int*, passivedouble*, const int*, int*, int*); +extern "C" void GETRI_IMPL(const int*, passivedouble*, const int*, int*, passivedouble*, const int*, int*); +extern "C" void GEMM_IMPL(char*, char*, const int*, const int*, const int*, const passivedouble*, const passivedouble*, + const int*, const passivedouble*, const int*, const passivedouble*, passivedouble*, + const int*); #endif void CSquareMatrixCM::Transpose() { @@ -59,10 +68,10 @@ void CSquareMatrixCM::Invert() { vector ipiv(sz); vector work(sz); - dgetrf_(&sz, &sz, mat.data(), &sz, ipiv.data(), &info); + GETRF_IMPL(&sz, &sz, mat.data(), &sz, ipiv.data(), &info); if (info != 0) SU2_MPI::Error(string("Matrix is singular"), CURRENT_FUNCTION); - dgetri_(&sz, mat.data(), &sz, ipiv.data(), work.data(), &sz, &info); + GETRI_IMPL(&sz, mat.data(), &sz, ipiv.data(), work.data(), &sz, &info); if (info != 0) SU2_MPI::Error(string("Matrix inversion failed"), CURRENT_FUNCTION); #else @@ -88,7 +97,7 @@ void CSquareMatrixCM::MatMatMult(const char side, const ColMajorMatrix(tmp); vector work(query); /*--- Factorize and invert. ---*/ - dsytrf_(&uplo, &sz, mat.data(), &sz, ipiv.data(), work.data(), &query, &info); + SYTRF_IMPL(&uplo, &sz, mat.data(), &sz, ipiv.data(), work.data(), &query, &info); if (info != 0) SU2_MPI::Error("LDLT factorization failed.", CURRENT_FUNCTION); - dsytri_(&uplo, &sz, mat.data(), &sz, ipiv.data(), work.data(), &info); + SYTRI_IMPL(&uplo, &sz, mat.data(), &sz, ipiv.data(), work.data(), &info); if (info != 0) SU2_MPI::Error("Inversion with LDLT factorization failed.", CURRENT_FUNCTION); #endif } @@ -137,9 +150,9 @@ void CSymmetricMatrix::CalcInv_potri() { const int sz = Size(); int info; - dpotrf_(&uplo, &sz, mat.data(), &sz, &info); + POTRF_IMPL(&uplo, &sz, mat.data(), &sz, &info); if (info != 0) SU2_MPI::Error("LLT factorization failed.", CURRENT_FUNCTION); - dpotri_(&uplo, &sz, mat.data(), &sz, &info); + POTRI_IMPL(&uplo, &sz, mat.data(), &sz, &info); if (info != 0) SU2_MPI::Error("Inversion with LLT factorization failed.", CURRENT_FUNCTION); #endif } @@ -167,7 +180,7 @@ void CSymmetricMatrix::MatMatMult(const char side, const su2passivematrix& mat_i /*--- Right and lower because matrices are in row major order. ---*/ const char side = 'R', uplo = 'L'; const passivedouble alpha = 1.0, beta = 0.0; - DSYMM(&side, &uplo, &N, &M, &alpha, mat.data(), &M, mat_in.data(), &N, &beta, mat_out.data(), &N); + SYMM_IMPL(&side, &uplo, &N, &M, &alpha, mat.data(), &M, mat_in.data(), &N, &beta, mat_out.data(), &N); #else // Naive product for (int i = 0; i < M; ++i) for (int j = 0; j < N; ++j) { @@ -187,7 +200,7 @@ void CSymmetricMatrix::MatMatMult(const char side, const su2passivematrix& mat_i /*--- Left and lower because matrices are in row major order. ---*/ const char side = 'L', uplo = 'L'; const passivedouble alpha = 1.0, beta = 0.0; - DSYMM(&side, &uplo, &N, &M, &alpha, mat.data(), &N, mat_in.data(), &N, &beta, mat_out.data(), &N); + SYMM_IMPL(&side, &uplo, &N, &M, &alpha, mat.data(), &N, mat_in.data(), &N, &beta, mat_out.data(), &N); #else // Naive product for (int i = 0; i < M; ++i) for (int j = 0; j < N; ++j) { diff --git a/Common/src/wall_model.cpp b/Common/src/wall_model.cpp index 60c975c43ed5..5c8ea30603cb 100644 --- a/Common/src/wall_model.cpp +++ b/Common/src/wall_model.cpp @@ -31,7 +31,12 @@ /* Prototypes for Lapack functions, if MKL or LAPACK is used. */ #if defined(HAVE_MKL) || defined(HAVE_LAPACK) -extern "C" void dgtsv_(int*, int*, passivedouble*, passivedouble*, passivedouble*, passivedouble*, int*, int*); +#ifdef USE_SINGLE_PRECISION +#define GTSV_IMPL sgtsv_ +#else +#define GTSV_IMPL dgtsv_ +#endif +extern "C" void GTSV_IMPL(int*, int*, passivedouble*, passivedouble*, passivedouble*, passivedouble*, int*, int*); #endif CWallModel::CWallModel(CConfig* config) { @@ -193,7 +198,7 @@ void CWallModel1DEQ::WallShearStressAndHeatFlux(const su2double tExchange, const #if (defined(HAVE_MKL) || defined(HAVE_LAPACK)) && !(defined(CODI_REVERSE_TYPE) || defined(CODI_FORWARD_TYPE)) int info, nrhs = 1; - dgtsv_(&numPoints, &nrhs, lower.data(), diagonal.data(), upper.data(), rhs.data(), &numPoints, &info); + GTSV_IMPL(&numPoints, &nrhs, lower.data(), diagonal.data(), upper.data(), rhs.data(), &numPoints, &info); if (info != 0) SU2_MPI::Error("Unsuccessful call to dgtsv_", CURRENT_FUNCTION); #else SU2_MPI::Error("Not compiled with MKL or LAPACK support", CURRENT_FUNCTION); @@ -273,7 +278,7 @@ void CWallModel1DEQ::WallShearStressAndHeatFlux(const su2double tExchange, const /* Solve the matrix problem to get the Enthalpy field */ #if (defined(HAVE_MKL) || defined(HAVE_LAPACK)) && !(defined(CODI_REVERSE_TYPE) || defined(CODI_FORWARD_TYPE)) - dgtsv_(&numPoints, &nrhs, lower.data(), diagonal.data(), upper.data(), rhs.data(), &numPoints, &info); + GTSV_IMPL(&numPoints, &nrhs, lower.data(), diagonal.data(), upper.data(), rhs.data(), &numPoints, &info); if (info != 0) SU2_MPI::Error("Unsuccessful call to dgtsv_", CURRENT_FUNCTION); #else SU2_MPI::Error("Not compiled with MKL or LAPACK support", CURRENT_FUNCTION); diff --git a/SU2_CFD/flamelet_python_bc.md b/SU2_CFD/flamelet_python_bc.md new file mode 100644 index 000000000000..3aa393cee60b --- /dev/null +++ b/SU2_CFD/flamelet_python_bc.md @@ -0,0 +1,225 @@ +# Flamelet Solver — Python Wrapper Wall Boundary Conditions + +This document explains how to use the Python wrapper (`pysu2`) to set +custom per-vertex boundary conditions for the flamelet (FGM) scalar transport +solver, and how the setup differs between the two `FLAMELET_ENTHALPY_BC` modes. + +--- + +## Background + +The flamelet solver transports `nVar` scalar variables. Their order is: + +| Index | Variable | +|-------|----------| +| 0 | `PROGVAR` (progress variable) | +| 1 | `ENTH` (total enthalpy) | +| 2 … n\_CV−1 | additional control variables (e.g. `MIXFRAC`) | +| n\_CV … nVar−1 | auxiliary / user-defined species | + +Two modes control how the enthalpy boundary condition is derived at thermal +walls (`MARKER_ISOTHERMAL`, `MARKER_HEATFLUX`): + +- **`FLOW_MARKERS`** — enthalpy is derived from the flow thermal field (wall + temperature via `MARKER_ISOTHERMAL`, or wall heat flux via `MARKER_HEATFLUX`). +- **`SPECIES_MARKERS`** (default) — enthalpy and all other scalars are taken + directly from `MARKER_WALL_SPECIES`, or from the Python wrapper when + `MARKER_PYTHON_CUSTOM` is active. + +--- + +## Mode 1: `FLAMELET_ENTHALPY_BC = FLOW_MARKERS` + +### How it works + +The C++ function `BC_HeatFlux_Wall` reads the wall heat flux and applies it as +a Neumann condition on `I_ENTH`. When the marker is also listed in +`MARKER_PYTHON_CUSTOM`, it instead reads a **per-vertex heat flux** set by the +Python wrapper. + +``` +driver.SetMarkerCustomNormalHeatFlux(iMarker, iVertex, q_wall) + → geometry->CustomBoundaryHeatFlux[iMarker][iVertex] + → BC_HeatFlux_Wall reads geometry->GetCustomBoundaryHeatFlux(...) +``` + +> `BC_Isothermal_Wall` in `FLOW_MARKERS` mode always converts the wall +> temperature (from `MARKER_ISOTHERMAL`) to enthalpy via `GetEnthFromTemp`. +> Per-vertex customisation of the enthalpy Dirichlet value is not supported in +> this mode — use `SPECIES_MARKERS` instead. + +### Limitations in this mode + +- Only `I_ENTH` is reachable via the Python wrapper. +- Non-enthalpy scalars (`PROGVAR`, auxiliary species) receive implicit zero + Neumann at the wall and cannot be set via Python. + +### config.cfg + +```cfg +FLAMELET_ENTHALPY_BC = FLOW_MARKERS + +% Flow solver wall BC — sets KindBC and provides the fallback heat flux value +% used when MARKER_PYTHON_CUSTOM is not active. +MARKER_HEATFLUX = ( burner_wall, 0.0 ) + +% Enable the per-vertex Python override path. +MARKER_PYTHON_CUSTOM = ( burner_wall ) +``` + +### run.py + +```python +import pysu2 + +driver = pysu2.CSinglezoneDriver("config.cfg", 1, False) + +marker_name = "burner_wall" +iMarker = list(driver.GetMarkerTags()).index(marker_name) +n_vertex = driver.GetNumberMarkerNodes(iMarker) + +def compute_heat_flux(coord): + """Heat flux [W/m²], positive = into the domain.""" + import math + r = math.sqrt(coord[0]**2 + coord[1]**2) + return -5000.0 * math.exp(-r**2 / 0.01) # Gaussian profile, heat out + +for iteration in range(driver.GetNumberIter()): + + for iVertex in range(n_vertex): + node_id = driver.GetMarkerNode(iMarker, iVertex) + coord = driver.GetInitialMeshCoord(node_id) # [x, y(, z)] + q_wall = compute_heat_flux(coord) + driver.SetMarkerCustomNormalHeatFlux(iMarker, iVertex, q_wall) + + driver.Preprocess(iteration) + driver.Run() + driver.Postprocess() + driver.Monitor(iteration) + driver.Output(iteration) + +driver.Finalize() +``` + +--- + +## Mode 2: `FLAMELET_ENTHALPY_BC = SPECIES_MARKERS` (default) + +### How it works + +Both `BC_HeatFlux_Wall` and `BC_Isothermal_Wall` delegate immediately to +`CSpeciesSolver::BC_Wall_Generic`, which processes **all `nVar` scalars** +independently. When `MARKER_PYTHON_CUSTOM` is active, the value for each +scalar is taken from the array set by `driver.SetMarkerCustomScalar()`. + +``` +driver.SetMarkerCustomScalar(iMarker, iVertex, [val_0, val_1, ..., val_nVar-1]) + → CustomBoundaryScalar[iMarker](iVertex, iVar) + → BC_Wall_Generic reads CustomBoundaryScalar for every iVar +``` + +The **type** of BC for each scalar (Dirichlet `VALUE` or Neumann `FLUX`) is +read from `MARKER_WALL_SPECIES` in the config and cannot be changed from +Python. The Python wrapper only overrides the **magnitude** per vertex. + +### config.cfg + +The example below uses `nVar = 3` (PROGVAR, ENTH, one auxiliary species). +Adjust the number of `BC_TYPE, value` pairs to match the actual number of +scalar variables in your setup. + +```cfg +FLAMELET_ENTHALPY_BC = SPECIES_MARKERS + +% Flow solver wall BC — still required to set KindBC. +% The choice between MARKER_ISOTHERMAL and MARKER_HEATFLUX only affects +% the flow solver; the species solver uses BC_Wall_Generic in both cases. +MARKER_ISOTHERMAL = ( burner_wall, 300.0 ) + +% Per-variable BC types for the species solver. +% Format: (marker_name, BC_TYPE, fallback_value, BC_TYPE, fallback_value, ...) +% One BC_TYPE+value pair per scalar variable, in index order. +% BC_TYPE: FLUX → Neumann (value is normal flux density [unit/m²]) +% VALUE → Dirichlet (value is the scalar value at the wall) +% +% When MARKER_PYTHON_CUSTOM is active, the fallback_value is ignored and +% the Python-supplied value is used instead. The BC_TYPE is always from config. +% +% idx 0 PROGVAR : zero Neumann (no progress variable source at the wall) +% idx 1 ENTH : Dirichlet (enthalpy value set per-vertex by Python) +% idx 2 aux_1 : zero Neumann (no auxiliary species flux at the wall) +MARKER_WALL_SPECIES = ( burner_wall, FLUX, 0.0, VALUE, 0.0, FLUX, 0.0 ) + +% Enable the per-vertex Python override path. +MARKER_PYTHON_CUSTOM = ( burner_wall ) +``` + +### run.py + +```python +import pysu2 + +driver = pysu2.CSinglezoneDriver("config.cfg", 1, False) + +marker_name = "burner_wall" +iMarker = list(driver.GetMarkerTags()).index(marker_name) +n_vertex = driver.GetNumberMarkerNodes(iMarker) + +def compute_wall_enthalpy(coord): + """Return wall enthalpy [J/kg] at this vertex.""" + # Example: uniform value corresponding to T=300 K from your LUT. + return 3.5e5 + +for iteration in range(driver.GetNumberIter()): + + for iVertex in range(n_vertex): + node_id = driver.GetMarkerNode(iMarker, iVertex) + coord = driver.GetInitialMeshCoord(node_id) + + enth_wall = compute_wall_enthalpy(coord) + + # Pass one value per scalar variable (length = nVar). + # PROGVAR (idx 0): 0.0 → applied as FLUX → zero Neumann (BC_TYPE from config) + # ENTH (idx 1): enth_wall → applied as VALUE → Dirichlet + # aux_1 (idx 2): 0.0 → applied as FLUX → zero Neumann + driver.SetMarkerCustomScalar(iMarker, iVertex, [0.0, enth_wall, 0.0]) + + driver.Preprocess(iteration) + driver.Run() + driver.Postprocess() + driver.Monitor(iteration) + driver.Output(iteration) + +driver.Finalize() +``` + +--- + +## Comparison + +| | `FLOW_MARKERS` | `SPECIES_MARKERS` | +|---|---|---| +| **Python API** | `SetMarkerCustomNormalHeatFlux` | `SetMarkerCustomScalar` | +| **Storage** | `geometry->CustomBoundaryHeatFlux` | `CustomBoundaryScalar[iMarker](iVertex, iVar)` | +| **What you set** | Per-vertex heat flux (W/m²) for `I_ENTH` only | Per-vertex values for **all** `nVar` scalars | +| **BC type control** | Hard-coded Neumann in C++ | Per-variable via `MARKER_WALL_SPECIES` in config | +| **`MARKER_ISOTHERMAL` walls** | Enthalpy computed from T via `GetEnthFromTemp`; not overridable by Python | Enthalpy set as Dirichlet `VALUE` from Python | +| **Non-enthalpy scalars** | Not reachable via Python | All controlled via the same `SetMarkerCustomScalar` call | +| **Required config keys** | `MARKER_HEATFLUX`, `MARKER_PYTHON_CUSTOM` | `MARKER_ISOTHERMAL` or `MARKER_HEATFLUX`, `MARKER_WALL_SPECIES`, `MARKER_PYTHON_CUSTOM` | + +--- + +## Notes + +- `MARKER_PYTHON_CUSTOM` is a purely additive flag. A marker can appear in + both `MARKER_HEATFLUX` (or `MARKER_ISOTHERMAL`) and `MARKER_PYTHON_CUSTOM` + simultaneously. +- The fallback values in `MARKER_WALL_SPECIES` are used when `py_custom` is + false (e.g., during a plain SU2\_CFD run without the Python driver). They + allow the same config to be used both ways. +- In `SPECIES_MARKERS` mode, `SetMarkerCustomScalar` must supply a vector of + exactly `nVar` values. Indices that correspond to `FLUX`-type variables + should receive `0.0` unless you intentionally want a non-zero flux there. +- The `CHT` (conjugate heat transfer) path (`BC_ConjugateHeat_Interface`) + always uses `BC_Isothermal_Wall_Generic` and is unaffected by + `FLAMELET_ENTHALPY_BC`. Python custom BCs are not applicable to CHT markers. diff --git a/SU2_CFD/include/drivers/CDiscAdjSinglezoneDriver.hpp b/SU2_CFD/include/drivers/CDiscAdjSinglezoneDriver.hpp index 137c961f1482..6a2f00932ef1 100644 --- a/SU2_CFD/include/drivers/CDiscAdjSinglezoneDriver.hpp +++ b/SU2_CFD/include/drivers/CDiscAdjSinglezoneDriver.hpp @@ -55,6 +55,14 @@ class CDiscAdjSinglezoneDriver : public CSinglezoneDriver { COutput *direct_output; CNumerics ***numerics; /*!< \brief Container vector with all the numerics. */ + /*! + * \brief Returns true if the objective function does not depend on the main variables. In which case, + * the adjoint variables are 0 and the sensitivities can be computed just with the secondary recording. + */ + bool TrivialFunction() const { + return config_container[ZONE_0]->GetnObj() == 1 && config_container[ZONE_0]->GetKind_ObjFunc() == VOLUME_FRACTION; + } + /*! * \brief Record one iteration of a flow iteration in within multiple zones. * \param[in] kind_recording - Type of recording (full list in ENUM_RECORDING, option_structure.hpp) diff --git a/SU2_CFD/include/integration/CMultiGridIntegration.hpp b/SU2_CFD/include/integration/CMultiGridIntegration.hpp index 5f17525cabf5..0672d1ae5ff9 100644 --- a/SU2_CFD/include/integration/CMultiGridIntegration.hpp +++ b/SU2_CFD/include/integration/CMultiGridIntegration.hpp @@ -217,90 +217,64 @@ class CMultiGridIntegration final : public CIntegration { unsigned short RunTime_EqSystem, unsigned long Iteration, unsigned short iZone); /*! - * \brief Compute adaptive CFL for multigrid coarse levels. - * \param[in] config - Problem configuration. - * \param[in] solver_coarse - Coarse grid solver. - * \param[in] geometry_coarse - Coarse grid geometry. - * \param[in] iMesh - Current multigrid level. - * \param[in] CFL_fine - Fine grid CFL value (passive). - * \param[in] CFL_coarse_current - Current coarse grid CFL value (passive). - * \param[in] rms_res_coarse - Coarse-grid RMS residual (already MPI-reduced, from lastPreSmoothRMS). - * \return New CFL value for the coarse grid. - */ - passivedouble computeMultigridCFL(CConfig* config, unsigned short iMesh, - passivedouble CFL_fine, passivedouble CFL_coarse_current, - passivedouble rms_res_coarse); - - /*! - * \brief Adapt the residual restriction damping factor. + * \brief Adapt both restriction and prolongation damping factors from the global-trend signal. * - * Uses \c lastPreSmoothIters[] (filled by the previous multigrid cycle) to assess - * whether the pre-smoother is converging fast or slow on coarse levels, then adjusts - * \c Damp_Res_Restric in \p config accordingly. + * Uses the cross-cycle EMA ratio (crossCycleRatio = fine_d0 / EMA(fine_d0)) to detect + * long-term convergence or divergence, then adjusts both \c Damp_Res_Restric and + * \c Damp_Correc_Prolong with a single shared signal. The EMA filters per-cycle noise; + * no per-level aggregation or floor counter is needed. * - * Signal logic: - * - any coarse level ran its full configured iterations: reduce damping - * - all coarse levels exited early: increase damping - * - mixed (some full, some partial): no change - * - * \param[in,out] config - Problem configuration. + * \param[in,out] config - Problem configuration. + * \param[in] crossCycleRatio - Current fine_d0 divided by the EMA of fine_d0. */ - void adaptRestrictionDamping(CConfig* config); + void adaptDampingFactors(CConfig* config, passivedouble crossCycleRatio); /*! - * \brief Adapt the correction prolongation damping factor. - * - * Uses \c lastCorrecSmoothIters[] (filled by the previous multigrid cycle) to assess - * whether the correction smoother is struggling or converging fast, - * then adjusts \c Damp_Correc_Prolong in \p config accordingly. - * - * Signal logic: - * - any level ran its full correction-smooth iterations: reduce damping - * - all levels exited early: increase damping - * - mixed: no change - * - * \param[in,out] config - Problem configuration; \c SetDamp_Correc_Prolong is called to persist the result. + * \brief Helper function for early-exit logic during pre/post-smoothing. + * \param[in] iSmooth - Current smoothing iteration index. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] defect - Current RMS defect value. + * \param[in] mgOpts - Reference to multigrid options. + * \param[in] stag_tol - Stagnation tolerance value. + * \param[in] early_exit - Whether early exit is enabled. + * \param[out] lastRMS - Array to store RMS values [start, end]. + * \param[out] exitReason - Character for early exit reason ('T', 'S', 'A', or ' '). + * \param[out] worstStepRatio - Worst step-to-step ratio seen. + * \param[out] worstStep - Iteration number of worst step. */ - void adaptProlongationDamping(CConfig* config); + void prePostEarlyExit(unsigned short iSmooth, unsigned short iMesh, + passivedouble defect, const CMGOptions& mgOpts, + passivedouble stag_tol, bool early_exit, + passivedouble lastRMS[2], char& exitReason, + passivedouble& worstStepRatio, unsigned short& worstStep); - /*--- CFL adaptation state variables. - * These must be passivedouble: AD::Reset() clears the tape between adjoint recordings, - * but class members survive. If these were su2double their stale AD indices would - * reference the cleared tape, causing invalid memory access during the backward pass. ---*/ static constexpr int MAX_MG_LEVELS = 10; - passivedouble current_avg[MAX_MG_LEVELS] = {}; - passivedouble prev_avg[MAX_MG_LEVELS] = {}; - passivedouble last_res[MAX_MG_LEVELS] = {}; - bool last_was_increase[MAX_MG_LEVELS] = {}; - int oscillation_count[MAX_MG_LEVELS] = {}; - unsigned long last_check_iter[MAX_MG_LEVELS] = {}; - unsigned long last_update_iter[MAX_MG_LEVELS] = {}; - unsigned long last_reset_iter = std::numeric_limits::max(); /*--- Early-exit smoothing state (shared across OMP threads via master write + barrier). ---*/ - bool mg_early_exit_flag = false; /*!< \brief Shared flag for early exit across OMP threads. */ - passivedouble mg_initial_smooth_rms = 0.0; /*!< \brief Initial RMS before current smoothing phase. */ - passivedouble mg_last_smooth_rms = 0.0; /*!< \brief Last computed RMS; cached to avoid redundant Allreduce. */ + bool mg_early_exit_flag = false; /*!< \brief Shared flag for early exit across OMP threads. */ + passivedouble mg_initial_smooth_rms = 0.0; /*!< \brief Initial RMS residual before current smoothing phase (FAS). */ + passivedouble mg_prev_smooth_rms = 0.0; /*!< \brief RMS residual from previous smoothing step; used for stagnation detection. */ + passivedouble mg_fine_rms_ema = 0.0; /*!< \brief EMA of fine-grid pre-smooth RMS across cycles; cross-cycle trend signal. */ + passivedouble last_crossCycleRatio = 1.0; /*!< \brief crossCycleRatio from the most recent cycle; stored for display only. */ /*--- Actual iteration counts per MG level, filled each cycle for the compact output summary. ---*/ unsigned short lastPreSmoothIters[MAX_MG_LEVELS+1] = {}; unsigned short lastPostSmoothIters[MAX_MG_LEVELS+1] = {}; unsigned short lastCorrecSmoothIters[MAX_MG_LEVELS+1] = {}; + /*--- Early-exit reason per level: 'T'=threshold, 'S'=stagnation, ' '=ran to completion. ---*/ + char lastPreSmoothExitReason[MAX_MG_LEVELS+1] = {}; + char lastPostSmoothExitReason[MAX_MG_LEVELS+1] = {}; - /*--- Per-level residual progress flags: true if the final RMS after that phase was lower - * than the initial RMS. Used by the adaptive damping routines to distinguish - * "hit max iters but still converging" from "hit max iters and stagnated". ---*/ - bool lastPreSmoothProgress[MAX_MG_LEVELS+1] = {}; - bool lastPostSmoothProgress[MAX_MG_LEVELS+1] = {}; - bool lastCorrecSmoothProgress[MAX_MG_LEVELS+1] = {}; - - /*--- Per-level start/end RMS for the compact output summary. - * [0] = initial RMS before smoothing, [1] = final RMS after smoothing. - * Filled unconditionally (early-exit path and exhaustion path). - * Must be passivedouble: class members survive tape resets; su2double would - * carry stale AD indices referencing a cleared tape. ---*/ + /*--- Per-level start/end RMS residual for adaptive damping. ---*/ passivedouble lastPreSmoothRMS[MAX_MG_LEVELS+1][2] = {}; passivedouble lastPostSmoothRMS[MAX_MG_LEVELS+1][2] = {}; passivedouble lastCorrecSmoothRMS[MAX_MG_LEVELS+1][2] = {}; + /*--- Per-level worst step-to-step amplification seen inside a smoothing phase. + * step==0 means no intra-smoother ratio was available (fewer than 2 sweeps). ---*/ + passivedouble lastPreSmoothWorstStepRatio[MAX_MG_LEVELS+1] = {}; + passivedouble lastPostSmoothWorstStepRatio[MAX_MG_LEVELS+1] = {}; + unsigned short lastPreSmoothWorstStep[MAX_MG_LEVELS+1] = {}; + unsigned short lastPostSmoothWorstStep[MAX_MG_LEVELS+1] = {}; + }; diff --git a/SU2_CFD/include/integration/ComputeLinSysResRMS.hpp b/SU2_CFD/include/integration/ComputeLinSysResRMS.hpp deleted file mode 100644 index c773f3fe683d..000000000000 --- a/SU2_CFD/include/integration/ComputeLinSysResRMS.hpp +++ /dev/null @@ -1,63 +0,0 @@ -/*! - * \file ComputeLinSysResRMS.hpp - * \brief Helper to compute the global RMS of LinSysRes across all variables and domain points. - * \author Nijso Beishuizen - * \version 8.5.0 "Harrier" - * - * SU2 Project Website: https://su2code.github.io - * - * The SU2 Project is maintained by the SU2 Foundation - * (http://su2foundation.org) - * - * Copyright 2012-2026, 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/solvers/CSolver.hpp" -#include "../../../Common/include/parallelization/omp_structure.hpp" -#include - -/*! - * \brief Compute the global (MPI-reduced) RMS of LinSysRes over all variables and domain points. - * - * \note Thread-safety: This function MUST be called by ALL threads in the current - * OpenMP parallel region, because squaredNorm() uses parallel for + barriers - * internally. Do NOT call from inside BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS. - * The return value is correct only on the master thread (thread 0). - * - * \param[in] solver - Solver whose LinSysRes is evaluated. - * \return Global RMS value (valid on master thread; other threads return 0). - */ -inline passivedouble ComputeLinSysResRMS(const CSolver* solver) { - - /*--- squaredNorm() -> dot() uses OMP parallel for + barriers internally, - * so all threads must participate. ---*/ - const su2double sqNorm = solver->LinSysRes.squaredNorm(); - - /*--- The MPI reduction for nElmDomain must be single-threaded. ---*/ - passivedouble result = 0.0; - BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS - { - unsigned long nElmDomain = solver->LinSysRes.GetNElmDomain(); - unsigned long globalNElmDomain = 0; - SU2_MPI::Allreduce(&nElmDomain, &globalNElmDomain, 1, MPI_UNSIGNED_LONG, MPI_SUM, SU2_MPI::GetComm()); - if (globalNElmDomain > 0) - result = std::sqrt(SU2_TYPE::GetValue(sqNorm) / static_cast(globalNElmDomain)); - } - END_SU2_OMP_SAFE_GLOBAL_ACCESS - - return result; -} diff --git a/SU2_CFD/include/interfaces/CInterface.hpp b/SU2_CFD/include/interfaces/CInterface.hpp index 7480f970ce4a..23a5621c4929 100644 --- a/SU2_CFD/include/interfaces/CInterface.hpp +++ b/SU2_CFD/include/interfaces/CInterface.hpp @@ -29,6 +29,7 @@ #pragma once #include "../../../Common/include/parallelization/mpi_structure.hpp" +#include "../../../Common/include/option_structure.hpp" #include #include @@ -77,7 +78,7 @@ class CInterface { /*! * \brief Constructor of the class. */ - CInterface(void); + CInterface(); /*! * \overload @@ -89,7 +90,7 @@ class CInterface { /*! * \brief Destructor of the class. */ - virtual ~CInterface(void); + virtual ~CInterface(); /*! * \brief Interpolate data and broadcast it into all processors, for nonmatching meshes. @@ -224,4 +225,11 @@ class CInterface { * \param[in] val_contact_resistance - Contact resistance value in m^2/W */ inline virtual void SetContactResistance(su2double val_contact_resistance) {}; + + /*! + * \brief These can be used to chain interfaces between the same zones but for other variables, + * without having to mix physics in the interface classes. Currently this is used for FSI+CHT. + */ + ENUM_TRANSFER NextInterfaceType = ENUM_TRANSFER::NO_TRANSFER; + CInterface* NextInterface = nullptr; }; diff --git a/SU2_CFD/include/numerics/turbulent/turb_sources.hpp b/SU2_CFD/include/numerics/turbulent/turb_sources.hpp index 2c0cb51a8d21..11f6321282a4 100644 --- a/SU2_CFD/include/numerics/turbulent/turb_sources.hpp +++ b/SU2_CFD/include/numerics/turbulent/turb_sources.hpp @@ -919,8 +919,13 @@ class CSourcePieceWise_TurbSST final : public CNumerics { const su2double VorticityMag = GeometryToolbox::Norm(3, Vorticity_i); su2double P_Base = 0; + + /*--- Compressibility Corrections related variables ---*/ su2double zetaFMt = 0.0; const su2double Mt = sqrt(2.0 * ScalarVar_i[0]) / V_i[idx.SoundSpeed()]; + const su2double alpha2 = 0.4; + const su2double alpha3 = 0.2; + su2double PDTerm = 0.0; /*--- Apply production term modifications ---*/ switch (sstParsedOptions.production) { @@ -947,9 +952,7 @@ class CSourcePieceWise_TurbSST final : public CNumerics { case SST_OPTIONS::COMP_Sarkar: P_Base = StrainMag_i; - if (Mt >= 0.25) { - zetaFMt = 0.5 * (Mt * Mt); - } + zetaFMt=Mt * Mt; break; default: @@ -988,9 +991,10 @@ class CSourcePieceWise_TurbSST final : public CNumerics { pw = max(pw, sust_w); } - if (sstParsedOptions.production == SST_OPTIONS::COMP_Sarkar) { - const su2double Dilatation_Sarkar = -0.15 * pk * Mt + 0.2 * beta_star * (1.0 +zetaFMt) * Density_i * ScalarVar_i[1] * ScalarVar_i[0] * Mt * Mt; - pk += Dilatation_Sarkar; + if (sstParsedOptions.compPressDil) { + /*--- Taken from "Modeling the Pressure-Dilatation Correlation", Sarkar, S. ---*/ + const su2double epsilon = beta_star * ScalarVar_i[1] * ScalarVar_i[0]; + PDTerm = (-alpha2*pk + alpha3*Density_i*epsilon)*Mt*Mt; } /*--- Dissipation ---*/ @@ -1003,6 +1007,10 @@ class CSourcePieceWise_TurbSST final : public CNumerics { pk = pk * eff_intermittency; dk = min(max(eff_intermittency, 0.1), 1.0) * dk; } + + /*--- Include Pressure-Dilatation term if present ---*/ + pk += PDTerm; + pw += (- PDTerm / Eddy_Viscosity_i); /*--- Add the production terms to the residuals. ---*/ diff --git a/SU2_CFD/include/numerics_simd/flow/convection/centered.hpp b/SU2_CFD/include/numerics_simd/flow/convection/centered.hpp index 6647e46825f9..dd010650a47f 100644 --- a/SU2_CFD/include/numerics_simd/flow/convection/centered.hpp +++ b/SU2_CFD/include/numerics_simd/flow/convection/centered.hpp @@ -67,7 +67,7 @@ class CCenteredBase : public Base { * \brief Special treatment needed to fetch integer data. */ template - FORCEINLINE static Double numNeighbor(simd::Array idx, const CGeometry& geometry) { + FORCEINLINE static Double numNeighbor(const simd::Array& idx, const CGeometry& geometry) { Double n; for (size_t k=0; kGetnNeighbor(idx[k]); return n; @@ -80,12 +80,12 @@ class CCenteredBase : public Base { /*! * \brief Implementation of the base centered flux. */ - void ComputeFlux(Int iEdge, + void ComputeFlux(const Int iEdge, const CConfig& config, const CGeometry& geometry, const CVariable& solution_, - UpdateType updateType, - Double updateMask, + const UpdateType updateType, + const Double updateMask, CSysVector& vector, SparseMatrixType& matrix) const final { @@ -220,14 +220,14 @@ class CJSTScheme : public CCenteredBase,Decorator> { FORCEINLINE void finalizeFlux(VectorDbl& flux, MatrixDbl& jac_i, MatrixDbl& jac_j, - bool implicit, - Double area, - Double projVel, + const bool implicit, + const Double& area, + const Double& projVel, const PrimVarType& avgV, const CPair& V, const VectorDbl& diffU, - Int iPoint, - Int jPoint, + const Int& iPoint, + const Int& jPoint, const CGeometry& geometry, const CEulerVariable& solution, Ts&...) const { @@ -301,14 +301,14 @@ class CJSTmatScheme : public CCenteredBase,Decorator> { FORCEINLINE void finalizeFlux(VectorDbl& flux, MatrixDbl& jac_i, MatrixDbl& jac_j, - bool implicit, - Double area, - Double projVel, + const bool implicit, + const Double& area, + const Double& projVel, const PrimVarType& avgV, const CPair& V, const VectorDbl& diffU, - Int iPoint, - Int jPoint, + const Int& iPoint, + const Int& jPoint, const CGeometry& geometry, const CEulerVariable& solution, const VectorDbl& unitNormal, @@ -425,14 +425,14 @@ class CJSTkeScheme : public CCenteredBase,Decorator> { FORCEINLINE void finalizeFlux(VectorDbl& flux, MatrixDbl& jac_i, MatrixDbl& jac_j, - bool implicit, - Double area, - Double projVel, + const bool implicit, + const Double& area, + const Double& projVel, const PrimVarType& avgV, const CPair& V, const VectorDbl& diffU, - Int iPoint, - Int jPoint, + const Int& iPoint, + const Int& jPoint, const CGeometry& geometry, const CEulerVariable& solution, Ts&...) const { @@ -496,14 +496,14 @@ class CLaxScheme : public CCenteredBase,Decorator> { FORCEINLINE void finalizeFlux(VectorDbl& flux, MatrixDbl& jac_i, MatrixDbl& jac_j, - bool implicit, - Double area, - Double projVel, + const bool implicit, + const Double& area, + const Double& projVel, const PrimVarType& avgV, const CPair& V, const VectorDbl& diffU, - Int iPoint, - Int jPoint, + const Int& iPoint, + const Int& jPoint, const CGeometry& geometry, const CEulerVariable& solution, Ts&...) const { diff --git a/SU2_CFD/include/numerics_simd/flow/convection/common.hpp b/SU2_CFD/include/numerics_simd/flow/convection/common.hpp index c2203e1f9841..4796f80ce031 100644 --- a/SU2_CFD/include/numerics_simd/flow/convection/common.hpp +++ b/SU2_CFD/include/numerics_simd/flow/convection/common.hpp @@ -39,9 +39,9 @@ * \param[in] kappa - Blending parameter. * \return Blended difference for reconstruction from point i. */ -FORCEINLINE Double umusclProjection(Double gradProj, - Double delta, - Double kappa) { +FORCEINLINE Double umusclProjection(const Double& gradProj, + const Double& delta, + const Double& kappa) { /*-------------------------------------------------------------------*/ /*--- The MUSCL kappa-scheme reconstruction is typically written: ---*/ /*--- V_L = V_i + 0.25 * dV_ij^kap, where ---*/ @@ -68,10 +68,10 @@ FORCEINLINE Double umusclProjection(Double gradProj, template FORCEINLINE Double musclReconstruction(const GradType& grad, const VectorDbl& vector_ij, - const Double delta, - size_t iVar, - Double kappa, - Double umusclRamp) { + const Double& delta, + const size_t iVar, + const Double& kappa, + const Double& umusclRamp) { const Double proj = dot(grad[iVar], vector_ij); return umusclRamp * umusclProjection(proj, delta, kappa); } @@ -80,13 +80,13 @@ FORCEINLINE Double musclReconstruction(const GradType& grad, * \brief Unlimited reconstruction. */ template -FORCEINLINE void musclUnlimited(Int iPoint, - Int jPoint, +FORCEINLINE void musclUnlimited(const Int& iPoint, + const Int& jPoint, const VectorDbl& vector_ij, const Gradient_t& gradient, CPair& V, - Double kappa, - Double umusclRamp) { + const Double& kappa, + const Double& umusclRamp) { constexpr auto nVarGrad = nVarGrad_ > 0 ? nVarGrad_ : VarType::nVar; auto grad_i = gatherVariables(iPoint, gradient); @@ -110,14 +110,14 @@ FORCEINLINE void musclUnlimited(Int iPoint, * \brief Limited reconstruction with point-based limiter. */ template -FORCEINLINE void musclPointLimited(Int iPoint, - Int jPoint, +FORCEINLINE void musclPointLimited(const Int& iPoint, + const Int& jPoint, const VectorDbl& vector_ij, const Limiter_t& limiter, const Gradient_t& gradient, CPair& V, - Double kappa, - Double umusclRamp) { + const Double& kappa, + const Double& umusclRamp) { constexpr auto nVarGrad = nVarGrad_ > 0 ? nVarGrad_ : VarType::nVar; auto lim_i = gatherVariables(iPoint, limiter); @@ -144,13 +144,13 @@ FORCEINLINE void musclPointLimited(Int iPoint, * \brief Limited reconstruction with edge-based limiter. */ template -FORCEINLINE void musclEdgeLimited(Int iPoint, - Int jPoint, +FORCEINLINE void musclEdgeLimited(const Int& iPoint, + const Int& jPoint, const VectorDbl& vector_ij, const Gradient_t& gradient, CPair& V, - Double kappa, - Double umusclRamp) { + const Double& kappa, + const Double& umusclRamp) { constexpr auto nVarGrad = nVarGrad_ > 0 ? nVarGrad_ : VarType::nVar; auto grad_i = gatherVariables(iPoint, gradient); @@ -191,13 +191,14 @@ FORCEINLINE void musclEdgeLimited(Int iPoint, * \return Pair of primitive variables. */ template -FORCEINLINE CPair reconstructPrimitives(Int iEdge, Int iPoint, Int jPoint, +FORCEINLINE CPair reconstructPrimitives(const Int& iEdge, + const Int& iPoint, const Int& jPoint, const su2double& gamma, const su2double& gasConst, - bool muscl, + const bool muscl, const su2double& kappa, const su2double& umusclRamp, - LIMITER limiterType, + const LIMITER limiterType, const CPair& V1st, const VectorDbl& vector_ij, const VariableType& solution) { @@ -278,8 +279,8 @@ FORCEINLINE CPair reconstructPrimitives(Int iEdge, Int iPoint, Int * \brief Compute and return the P tensor (compressible flow, ideal gas). */ template -FORCEINLINE MatrixDbl pMatrix(Double gamma, Double density, const RandomAccessIterator& velocity, - Double projVel, Double speedSound, const VectorDbl& normal) { +FORCEINLINE MatrixDbl pMatrix(const Double& gamma, const Double& density, const RandomAccessIterator& velocity, + const Double& projVel, const Double& speedSound, const VectorDbl& normal) { MatrixDbl pMat; const Double vel2 = 0.5*squaredNorm(velocity); @@ -340,8 +341,9 @@ FORCEINLINE MatrixDbl pMatrix(Double gamma, Double density, const Random * \brief Compute and return the inverse P tensor (compressible flow, ideal gas). */ template -FORCEINLINE MatrixDbl pMatrixInv(Double gamma, Double density, const RandomAccessIterator& velocity, - Double projVel, Double speedSound, const VectorDbl& normal) { +FORCEINLINE MatrixDbl pMatrixInv(const Double& gamma, const Double& density, + const RandomAccessIterator& velocity, const Double& projVel, + const Double& speedSound, const VectorDbl& normal) { MatrixDbl pMatInv; const Double c2 = pow(speedSound,2); @@ -421,9 +423,9 @@ FORCEINLINE VectorDbl inviscidProjFlux(const PrimVarType& V, * \brief Jacobian of the convective flux (compressible flow, ideal gas). */ template -FORCEINLINE MatrixDbl inviscidProjJac(Double gamma, RandomAccessIterator velocity, - Double energy, const VectorDbl& normal, - Double scale) { +FORCEINLINE MatrixDbl inviscidProjJac(const Double& gamma, RandomAccessIterator velocity, + const Double& energy, const VectorDbl& normal, + const Double& scale) { MatrixDbl jac; Double projVel = dot(velocity, normal); @@ -459,9 +461,9 @@ FORCEINLINE MatrixDbl inviscidProjJac(Double gamma, RandomAccessIterator * \brief (Low) Dissipation coefficient for Roe schemes. */ template -FORCEINLINE Double roeDissipation(Int iPoint, - Int jPoint, - ENUM_ROELOWDISS type, +FORCEINLINE Double roeDissipation(const Int& iPoint, + const Int& jPoint, + const ENUM_ROELOWDISS type, const VariableType& solution) { if (type == NO_ROELOWDISS) { return 1.0; @@ -511,10 +513,10 @@ FORCEINLINE Double roeDissipation(Int iPoint, * \brief Correct spectral radius (avgLambda) for stretching. */ template -FORCEINLINE Double correctedSpectralRadius(Int iPoint, - Int jPoint, - Double avgLambda, - T stretchParam, +FORCEINLINE Double correctedSpectralRadius(const Int& iPoint, + const Int& jPoint, + const Double& avgLambda, + const T& stretchParam, const VariableType& solution) { const auto lambda_i = gatherVariables(iPoint, solution.GetLambda()); @@ -531,7 +533,7 @@ FORCEINLINE Double correctedSpectralRadius(Int iPoint, */ template FORCEINLINE void scalarDissipationJacobian(const VariableType& V, - Double gamma, + const Double& gamma, Double dissipConst, MatrixDbl& jac) { /*--- Diagonal entries. ---*/ diff --git a/SU2_CFD/include/numerics_simd/flow/convection/upwind.hpp b/SU2_CFD/include/numerics_simd/flow/convection/upwind.hpp index 36036d7dc5dc..ad958a7e2f02 100644 --- a/SU2_CFD/include/numerics_simd/flow/convection/upwind.hpp +++ b/SU2_CFD/include/numerics_simd/flow/convection/upwind.hpp @@ -80,12 +80,12 @@ class CUpwindBase : public Base { /*! * \brief Implementation of the base Roe flux. */ - void ComputeFlux(Int iEdge, + void ComputeFlux(const Int iEdge, const CConfig& config, const CGeometry& geometry, const CVariable& solution_, - UpdateType updateType, - Double updateMask, + const UpdateType updateType, + const Double updateMask, CSysVector& vector, SparseMatrixType& matrix) const final { @@ -191,14 +191,14 @@ class CRoeScheme : public CUpwindBase, Decorator> { FORCEINLINE void finalizeFlux(VectorDbl& flux, MatrixDbl& jac_i, MatrixDbl& jac_j, - bool implicit, - Double area, + const bool implicit, + const Double& area, const VectorDbl& unitNormal, const VectorDbl& normal, const CPair& V, const CPair& U, - Int iPoint, - Int jPoint, + const Int& iPoint, + const Int& jPoint, const CEulerVariable& solution, const CGeometry& geometry, Ts&...) const { @@ -340,14 +340,14 @@ class CMSWScheme : public CUpwindBase, Decorator> { FORCEINLINE void finalizeFlux(VectorDbl& flux, MatrixDbl& jac_i, MatrixDbl& jac_j, - bool implicit, - Double area, + const bool implicit, + const Double& area, const VectorDbl& unitNormal, const VectorDbl& normal, const CPair& V, const CPair& U, - Int iPoint, - Int jPoint, + const Int& iPoint, + const Int& jPoint, const CEulerVariable& solution, const CGeometry& geometry, Ts&...) const { diff --git a/SU2_CFD/include/numerics_simd/flow/diffusion/common.hpp b/SU2_CFD/include/numerics_simd/flow/diffusion/common.hpp index 43793d215aaa..0f4fac0d03fd 100644 --- a/SU2_CFD/include/numerics_simd/flow/diffusion/common.hpp +++ b/SU2_CFD/include/numerics_simd/flow/diffusion/common.hpp @@ -36,7 +36,7 @@ * \brief Average gradients at i/j points. */ template -FORCEINLINE MatrixDbl averageGradient(Int iPoint, Int jPoint, +FORCEINLINE MatrixDbl averageGradient(const Int& iPoint, const Int& jPoint, const GradientType& gradient) { auto avgGrad = gatherVariables(iPoint, gradient); auto grad_j = gatherVariables(jPoint, gradient); @@ -55,7 +55,7 @@ FORCEINLINE MatrixDbl averageGradient(Int iPoint, Int jPoint, template FORCEINLINE void correctGradient(const PrimitiveType& V, const VectorDbl& vector_ij, - Double dist2_ij, + const Double& dist2_ij, MatrixDbl& avgGrad) { for (size_t iVar = 0; iVar < nVar; ++iVar) { Double corr = (dot(avgGrad[iVar],vector_ij) - V.j.all(iVar) + V.i.all(iVar)) / dist2_ij; @@ -70,7 +70,7 @@ FORCEINLINE void correctGradient(const PrimitiveType& V, * \note Second viscosity term ignored. */ template -FORCEINLINE MatrixDbl stressTensor(Double viscosity, +FORCEINLINE MatrixDbl stressTensor(const Double& viscosity, const MatrixDbl& grad) { /*--- Hydrostatic term. ---*/ Double velDiv = 0.0; @@ -154,7 +154,7 @@ FORCEINLINE void addQCR(const MatrixType& grad, MatrixDbl& tau) { * wall function) magnitude in the tangential direction. */ template -FORCEINLINE void addTauWall(Int iPoint, Int jPoint, +FORCEINLINE void addTauWall(const Int& iPoint, const Int& jPoint, const Container& tauWall, const VectorDbl& unitNormal, MatrixDbl& tau) { @@ -185,7 +185,7 @@ FORCEINLINE void addTauWall(Int iPoint, Int jPoint, template FORCEINLINE MatrixDbl stressTensorJacobian(const PrimitiveType& V, const VectorDbl& normal, - Double dist_ij) { + const Double& dist_ij) { Double viscosity = V.laminarVisc() + V.eddyVisc(); Double xi = viscosity / (V.density() * dist_ij); MatrixDbl jac; diff --git a/SU2_CFD/include/numerics_simd/flow/diffusion/viscous_fluxes.hpp b/SU2_CFD/include/numerics_simd/flow/diffusion/viscous_fluxes.hpp index 22114093435f..7c3a50052be3 100644 --- a/SU2_CFD/include/numerics_simd/flow/diffusion/viscous_fluxes.hpp +++ b/SU2_CFD/include/numerics_simd/flow/diffusion/viscous_fluxes.hpp @@ -111,16 +111,16 @@ class CCompressibleViscousFluxBase : public CNumericsSIMD { * \brief Add viscous contributions to flux and jacobians. */ template - FORCEINLINE void viscousTerms(Int iEdge, - Int iPoint, - Int jPoint, + FORCEINLINE void viscousTerms(const Int& iEdge, + const Int& iPoint, + const Int& jPoint, const PrimVarType& avgV, const CPair& V, const CVariable& solution_, const VectorDbl& vector_ij, const CGeometry& geometry, const CConfig& config, - Double area, + const Double& area, const VectorDbl& unitNormal, bool implicit, VectorDbl& flux, @@ -210,9 +210,9 @@ class CCompressibleViscousFluxBase : public CNumericsSIMD { * \overload Average primitives if not provided yet. */ template - FORCEINLINE void viscousTerms(Int iEdge, - Int iPoint, - Int jPoint, + FORCEINLINE void viscousTerms(const Int& iEdge, + const Int& iPoint, + const Int& jPoint, const CPair& V, Ts&... args) const { PrimVarType avgV; @@ -228,9 +228,9 @@ class CCompressibleViscousFluxBase : public CNumericsSIMD { * \overload Compute the i-j vector if not provided yet. */ template - FORCEINLINE void viscousTerms(Int iEdge, - Int iPoint, - Int jPoint, + FORCEINLINE void viscousTerms(const Int& iEdge, + const Int& iPoint, + const Int& jPoint, const PrimVarType& avgV, const CPair& V, const CVariable& solution_, @@ -278,9 +278,9 @@ class CCompressibleViscousFlux : public CCompressibleViscousFluxBase FORCEINLINE VectorDbl energyJacobian(const PrimitiveType& V, const MatrixDbl& dtau, - Double thermalCond, - Double area, - Double dist_ij, + const Double& thermalCond, + const Double& area, + const Double& dist_ij, Ts&... args) const { Double vel2 = 0.5 * squaredNorm(V.velocity()); Double phi = (gamma-1) / V.density(); @@ -334,11 +334,11 @@ class CGeneralCompressibleViscousFlux : public CCompressibleViscousFluxBase FORCEINLINE VectorDbl energyJacobian(const PrimitiveType& V, const MatrixDbl& dtau, - Double thermalCond, - Double area, - Double dist_ij, - Int iPoint, - Int jPoint, + const Double& thermalCond, + const Double& area, + const Double& dist_ij, + const Int& iPoint, + const Int& jPoint, const VariableType& solution) const { Double vel2 = squaredNorm(V.velocity()); Double contraction = 0.0; diff --git a/SU2_CFD/include/numerics_simd/flow/variables.hpp b/SU2_CFD/include/numerics_simd/flow/variables.hpp index fa39c7337f2e..4406a06abf7c 100644 --- a/SU2_CFD/include/numerics_simd/flow/variables.hpp +++ b/SU2_CFD/include/numerics_simd/flow/variables.hpp @@ -113,7 +113,7 @@ struct CRoeVariables { * \brief Compute Roe-averaged variables from pair of primitive variables. */ template -FORCEINLINE CRoeVariables roeAveragedVariables(Double gamma, +FORCEINLINE CRoeVariables roeAveragedVariables(const Double& gamma, const CPair& V, const VectorDbl& normal) { CRoeVariables roeAvg; diff --git a/SU2_CFD/include/solvers/CSpeciesFlameletSolver.hpp b/SU2_CFD/include/solvers/CSpeciesFlameletSolver.hpp index 10ccc65cfd36..6b9c45172985 100644 --- a/SU2_CFD/include/solvers/CSpeciesFlameletSolver.hpp +++ b/SU2_CFD/include/solvers/CSpeciesFlameletSolver.hpp @@ -162,6 +162,21 @@ class CSpeciesFlameletSolver final : public CSpeciesSolver { void BC_Isothermal_Wall(CGeometry* geometry, CSolver** solver_container, CNumerics* conv_numerics, CNumerics* visc_numerics, CConfig* config, unsigned short val_marker) override; + /*! + * \brief Impose the heat-flux wall boundary condition on the flamelet enthalpy scalar. + * When FLAMELET_ENTHALPY_BC= FLOW_MARKERS (default), the heat flux value from MARKER_HEATFLUX + * is applied as a Neumann boundary condition on the enthalpy scalar H. + * When FLAMELET_ENTHALPY_BC= SPECIES_MARKERS, use flux/value from MARKER_WALL_SPECIES. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_HeatFlux_Wall(CGeometry* geometry, CSolver** solver_container, CNumerics* conv_numerics, + CNumerics* visc_numerics, CConfig* config, unsigned short val_marker) override; + /*! * \brief Impose the inlet boundary condition. * \param[in] geometry - Geometrical definition of the problem. diff --git a/SU2_CFD/include/variables/CSpeciesFlameletVariable.hpp b/SU2_CFD/include/variables/CSpeciesFlameletVariable.hpp index 63aae6709b1e..fda8056fcd55 100644 --- a/SU2_CFD/include/variables/CSpeciesFlameletVariable.hpp +++ b/SU2_CFD/include/variables/CSpeciesFlameletVariable.hpp @@ -38,6 +38,7 @@ class CSpeciesFlameletVariable final : public CSpeciesVariable { MatrixType source_scalar; /*!< \brief Vector of the source terms from the lookup table for each scalar equation */ MatrixType lookup_scalar; /*!< \brief Vector of the source terms from the lookup table for each scalar equation */ su2vector table_misses; /*!< \brief Vector of lookup table misses. */ + MatrixType source_cons_jac; /*!< \brief Consumption-rate Jacobian dS_aux_i/dY_aux_i = source_cons_i, one column per user scalar. */ public: /*! @@ -87,4 +88,18 @@ class CSpeciesFlameletVariable final : public CSpeciesVariable { inline void SetTableMisses(unsigned long iPoint, unsigned short misses) override { table_misses[iPoint] = misses; } inline unsigned short GetTableMisses(unsigned long iPoint) const override { return table_misses[iPoint]; } + + /*! + * \brief Store the consumption-rate Jacobian dS_aux_i/dY_aux_i = source_cons_i for user scalar i_aux. + */ + inline void SetAuxSourceCons(unsigned long iPoint, unsigned long i_aux, su2double val) { + source_cons_jac(iPoint, i_aux) = val; + } + + /*! + * \brief Get the consumption-rate Jacobian entry for user scalar i_aux at iPoint. + */ + inline su2double GetAuxSourceCons(unsigned long iPoint, unsigned long i_aux) const { + return source_cons_jac(iPoint, i_aux); + } }; diff --git a/SU2_CFD/src/drivers/CDiscAdjMultizoneDriver.cpp b/SU2_CFD/src/drivers/CDiscAdjMultizoneDriver.cpp index 61673bdad1b3..c9529050da06 100644 --- a/SU2_CFD/src/drivers/CDiscAdjMultizoneDriver.cpp +++ b/SU2_CFD/src/drivers/CDiscAdjMultizoneDriver.cpp @@ -719,7 +719,9 @@ void CDiscAdjMultizoneDriver::SetRecording(RECORDING kind_recording, Kind_Tape t switch(kind_recording) { case RECORDING::CLEAR_INDICES: cout << "Clearing the computational graph." << endl; break; case RECORDING::MESH_COORDS: cout << "Storing computational graph wrt MESH COORDINATES." << endl; break; - case RECORDING::SOLUTION_VARIABLES: cout << "Storing computational graph wrt CONSERVATIVE VARIABLES." << endl; break; + case RECORDING::SOLUTION_VARIABLES: + cout << "Storing computational graph wrt CONSERVATIVE VARIABLES.\n"; + cout << "Computing residuals to check the convergence of the direct problem." << endl; break; case RECORDING::TAG_INIT_SOLVER_VARIABLES: cout << "Simulating recording with tag 1 on conservative variables." << endl; AD::SetTag(1); break; case RECORDING::TAG_CHECK_SOLVER_VARIABLES: cout << "Checking first recording with tag 2 on conservative variables." << endl; AD::SetTag(2); break; case RECORDING::TAG_INIT_SOLVER_AND_MESH: cout << "Simulating recording with tag 1 on conservative variables and mesh coordinates." << endl; AD::SetTag(1); break; @@ -850,7 +852,7 @@ void CDiscAdjMultizoneDriver::SetObjFunction(RECORDING kind_recording) { solvers[FLOW_SOL]->Momentum_Forces(geometry, config); solvers[FLOW_SOL]->Friction_Forces(geometry, config); - if(config->GetWeakly_Coupled_Heat()) { + if (config->GetWeakly_Coupled_Heat()) { solvers[HEAT_SOL]->Heat_Fluxes(geometry, solvers, config); } @@ -865,6 +867,9 @@ void CDiscAdjMultizoneDriver::SetObjFunction(RECORDING kind_recording) { break; case MAIN_SOLVER::DISC_ADJ_FEM: + if (config->GetWeakly_Coupled_Heat()) { + solvers[HEAT_SOL]->Heat_Fluxes(geometry, solvers, config); + } solvers[FEA_SOL]->Postprocessing(geometry, config, numerics_container[iZone][INST_0][MESH_0][FEA_SOL], true); direct_output[iZone]->SetHistoryOutput(geometry, solvers, config); ObjFunc += solvers[FEA_SOL]->GetTotal_ComboObj(); @@ -883,7 +888,7 @@ void CDiscAdjMultizoneDriver::SetObjFunction(RECORDING kind_recording) { kind_recording == RECORDING::TAG_CHECK_SOLVER_VARIABLES || kind_recording == RECORDING::TAG_INIT_SOLVER_AND_MESH || kind_recording == RECORDING::TAG_CHECK_SOLVER_AND_MESH) { - cout << " Objective function : " << ObjFunc << endl; + cout << "Objective function value: " << std::setprecision(driver_config->GetOutput_Precision()) << ObjFunc << endl; } } } diff --git a/SU2_CFD/src/drivers/CDiscAdjSinglezoneDriver.cpp b/SU2_CFD/src/drivers/CDiscAdjSinglezoneDriver.cpp index ce6f7d93b10f..5fcd203b84d0 100644 --- a/SU2_CFD/src/drivers/CDiscAdjSinglezoneDriver.cpp +++ b/SU2_CFD/src/drivers/CDiscAdjSinglezoneDriver.cpp @@ -156,6 +156,12 @@ void CDiscAdjSinglezoneDriver::Preprocess(unsigned long TimeIter) { void CDiscAdjSinglezoneDriver::Run() { SU2_ZONE_SCOPED + /*--- No need to solve anything, the tape for the main recording is empty. ---*/ + if (TrivialFunction()) { + SetAllSolutions(ZONE_0, true, [](auto, auto) { return 0; }); + return; + } + CQuasiNewtonInvLeastSquares fixPtCorrector; if (config->GetnQuasiNewtonSamples() > 1) { fixPtCorrector.resize(config->GetnQuasiNewtonSamples(), @@ -273,7 +279,7 @@ void CDiscAdjSinglezoneDriver::SetRecording(RECORDING kind_recording){ case RECORDING::CLEAR_INDICES: cout << "Clearing the computational graph." << endl; break; case RECORDING::MESH_COORDS: cout << "Storing computational graph wrt MESH COORDINATES." << endl; break; case RECORDING::SOLUTION_VARIABLES: - cout << "Direct iteration to store the primal computational graph." << endl; + cout << "Direct iteration to store the primal computational graph.\n"; cout << "Computing residuals to check the convergence of the direct problem." << endl; break; default: break; } @@ -309,6 +315,12 @@ void CDiscAdjSinglezoneDriver::SetRecording(RECORDING kind_recording){ SetObjFunction(); + if (rank == MASTER_NODE && + (kind_recording == RECORDING::SOLUTION_VARIABLES || (TrivialFunction() && kind_recording == RECORDING::MESH_COORDS))) { + cout << "\nObjective function value: " << std::setprecision(config_container[ZONE_0]->GetOutput_Precision()) << ObjFunc; + cout << "\n-------------------------------------------------------------------------\n" << endl; + } + if (kind_recording != RECORDING::CLEAR_INDICES && config_container[ZONE_0]->GetWrt_AD_Statistics()) { AD::PrintStatistics(SU2_MPI::GetComm(), rank == MASTER_NODE); } @@ -410,6 +422,16 @@ void CDiscAdjSinglezoneDriver::DirectRun(RECORDING kind_recording){ void CDiscAdjSinglezoneDriver::MainRecording(){ SU2_ZONE_SCOPED + + /*--- We know this function only depends on the secondary variables, hence skip the main recording. ---*/ + + if (TrivialFunction()) { + if (rank == MASTER_NODE) { + cout << "Trivial objective function, skipping the solution of the adjoint equations." << endl; + } + return; + } + /*--- SetRecording stores the computational graph on one iteration of the direct problem. Calling it with * RECORDING::CLEAR_INDICES as argument ensures that all information from a previous recording is removed. ---*/ diff --git a/SU2_CFD/src/drivers/CDriver.cpp b/SU2_CFD/src/drivers/CDriver.cpp index 5bdeb9ce1af7..63d485900987 100644 --- a/SU2_CFD/src/drivers/CDriver.cpp +++ b/SU2_CFD/src/drivers/CDriver.cpp @@ -813,6 +813,16 @@ void CDriver::InitializeGeometryFVM(CConfig *config, CGeometry **&geometry) { geometry[iMGlevel] = new CMultiGridGeometry(geometry[iMGlevel-1], config, iMGlevel); + /*--- Protect against the situation that we were not able to complete + the agglomeration for this level, i.e., there weren't enough points. + Check immediately so the expensive post-construction steps are skipped. ---*/ + + if (config->GetnMGLevels() != requestedMGlevels) { + delete geometry[iMGlevel]; + geometry[iMGlevel] = nullptr; + break; + } + /*--- Compute points surrounding points. ---*/ geometry[iMGlevel]->SetPoint_Connectivity(geometry[iMGlevel-1]); @@ -836,17 +846,6 @@ void CDriver::InitializeGeometryFVM(CConfig *config, CGeometry **&geometry) { geometry[iMGlevel]->SetMGLevel(iMGlevel); - /*--- Protect against the situation that we were not able to complete - the agglomeration for this level, i.e., there weren't enough points. - We need to check if we changed the total number of levels and delete - the incomplete CMultiGridGeometry object. ---*/ - - if (config->GetnMGLevels() != requestedMGlevels) { - delete geometry[iMGlevel]; - geometry[iMGlevel] = nullptr; - break; - } - } if (config->GetWrt_MultiGrid()) geometry[MESH_0]->ColorMGLevels(config->GetnMGLevels(), geometry); @@ -2443,6 +2442,31 @@ void CDriver::InitializeInterface(CConfig **config, CSolver***** solver, CGeomet interpolation[donor][target] = unique_ptr(CInterpolatorFactory::CreateInterpolator( geometry, config, interpolation[target][donor].get(), donor, target)); + /*--- Helpers with logic to create CHT interfaces. ---*/ + + auto GetChtInterfaceType = [donor, target, config](bool heat_donor, bool heat_target) { + if (heat_donor && heat_target) return CONJUGATE_HEAT_SS; + + const auto fluidZone = heat_target ? donor : target; + if (config[fluidZone]->GetEnergy_Equation() || + config[fluidZone]->GetKind_Regime() == ENUM_REGIME::COMPRESSIBLE || + config[fluidZone]->GetKind_FluidModel() == ENUM_FLUIDMODEL::FLUID_FLAMELET) { + return heat_target ? CONJUGATE_HEAT_FS : CONJUGATE_HEAT_SF; + } else if (config[fluidZone]->GetWeakly_Coupled_Heat()) { + return heat_target ? CONJUGATE_HEAT_WEAKLY_FS : CONJUGATE_HEAT_WEAKLY_SF; + } + return NO_TRANSFER; + }; + + auto MakeChtInterface = [&](const auto type) { + if (type != NO_TRANSFER) { + if (rank == MASTER_NODE) cout << " Conjugate heat variables." << endl; + return new CConjugateHeatInterface(4, 0); + } + if (rank == MASTER_NODE) cout << " NO heat variables." << endl; + return static_cast(nullptr); + }; + /*--- The type of variables transferred depends on the donor/target physics. ---*/ const bool heat_target = config[target]->GetHeatProblem(); @@ -2467,6 +2491,11 @@ void CDriver::InitializeInterface(CConfig **config, CSolver***** solver, CGeomet interface[donor][target] = new CDiscAdjFlowTractionInterface(nDim, nConst, config[donor], conservative); } if (rank == MASTER_NODE) cout << "fluid " << (conservative? "forces." : "tractions.") << endl; + + if (config[target]->GetWeakly_Coupled_Heat()) { + interface[donor][target]->NextInterfaceType = GetChtInterfaceType(false, true); + interface[donor][target]->NextInterface = MakeChtInterface(interface[donor][target]->NextInterfaceType); + } } else if (structural_donor && (fluid_target || heat_target)) { if (solver_container[target][INST_0][MESH_0][MESH_SOL] == nullptr) { @@ -2474,9 +2503,14 @@ void CDriver::InitializeInterface(CConfig **config, CSolver***** solver, CGeomet "Use DEFORM_MESH=YES, and setup MARKER_DEFORM_MESH=(...)", CURRENT_FUNCTION); } interface_type = BOUNDARY_DISPLACEMENTS; - if (!config[donor]->GetTime_Domain()) interface[donor][target] = new CDisplacementsInterface(nDim, 0); - else interface[donor][target] = new CDisplacementsInterface(2*nDim, 0); + const auto nVar = config[donor]->GetTime_Domain() ? 2 * nDim : nDim; + interface[donor][target] = new CDisplacementsInterface(nVar, 0); if (rank == MASTER_NODE) cout << "boundary displacements from the structural solver." << endl; + + if (fluid_target && config[donor]->GetWeakly_Coupled_Heat()) { + interface[donor][target]->NextInterfaceType = GetChtInterfaceType(true, false); + interface[donor][target]->NextInterface = MakeChtInterface(interface[donor][target]->NextInterfaceType); + } } else if (fluid_donor && fluid_target) { /*--- Interface handling for turbomachinery applications. ---*/ @@ -2487,14 +2521,14 @@ void CDriver::InitializeInterface(CConfig **config, CSolver***** solver, CGeomet 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 << "using a mixing-plane interface from donor zone " << donor << " to target zone " << target << "." << endl; + if (rank == MASTER_NODE) cout << " Using a mixing-plane interface from donor zone " << donor << " to target zone " << target << "." << endl; break; } case TURBO_INTERFACE_KIND::FROZEN_ROTOR: { 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 << "using a fluid interface interface from donor zone " << donor << " to target zone " << target << "." << endl; + if (rank == MASTER_NODE) cout << " Using a fluid interface interface from donor zone " << donor << " to target zone " << target << "." << endl; } } } @@ -2502,33 +2536,12 @@ void CDriver::InitializeInterface(CConfig **config, CSolver***** solver, CGeomet 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; + if (rank == MASTER_NODE) cout << " Sliding interface." << endl; } } else if (heat_donor || heat_target) { - if (heat_donor && heat_target){ - interface_type = CONJUGATE_HEAT_SS; - - } else { - - const auto fluidZone = heat_target? donor : target; - if (config[fluidZone]->GetEnergy_Equation() || (config[fluidZone]->GetKind_Regime() == ENUM_REGIME::COMPRESSIBLE) - || (config[fluidZone]->GetKind_FluidModel() == ENUM_FLUIDMODEL::FLUID_FLAMELET)) - interface_type = heat_target? CONJUGATE_HEAT_FS : CONJUGATE_HEAT_SF; - else if (config[fluidZone]->GetWeakly_Coupled_Heat()) - interface_type = heat_target? CONJUGATE_HEAT_WEAKLY_FS : CONJUGATE_HEAT_WEAKLY_SF; - else - interface_type = NO_TRANSFER; - } - - if (interface_type != NO_TRANSFER) { - auto nVar = 4; - interface[donor][target] = new CConjugateHeatInterface(nVar, 0); - if (rank == MASTER_NODE) cout << "conjugate heat variables." << endl; - } - else { - if (rank == MASTER_NODE) cout << "NO heat variables." << endl; - } + interface_type = GetChtInterfaceType(heat_donor, heat_target); + interface[donor][target] = MakeChtInterface(interface_type); } else { if (solver[donor][INST_0][MESH_0][FLOW_SOL] == nullptr) @@ -2537,7 +2550,7 @@ void CDriver::InitializeInterface(CConfig **config, CSolver***** solver, CGeomet auto nVar = solver[donor][INST_0][MESH_0][FLOW_SOL]->GetnVar(); interface_type = CONSERVATIVE_VARIABLES; interface[donor][target] = new CConservativeVarsInterface(nVar, 0); - if (rank == MASTER_NODE) cout << "generic conservative variables." << endl; + if (rank == MASTER_NODE) cout << " Generic conservative variables." << endl; } } @@ -2872,8 +2885,6 @@ void CDriver::PrintDirectResidual(RECORDING kind_recording) { } // for addVals - cout << "\n-------------------------------------------------------------------------\n" << endl; - } diff --git a/SU2_CFD/src/drivers/CMultizoneDriver.cpp b/SU2_CFD/src/drivers/CMultizoneDriver.cpp index d6f68a6682f6..00bdb364a449 100644 --- a/SU2_CFD/src/drivers/CMultizoneDriver.cpp +++ b/SU2_CFD/src/drivers/CMultizoneDriver.cpp @@ -549,19 +549,19 @@ bool CMultizoneDriver::TransferData(unsigned short donorZone, unsigned short tar /*--- Select the transfer method according to the magnitudes being transferred ---*/ - auto BroadcastData = [&](int donorSol, int targetSol) { - interface_container[donorZone][targetZone]->BroadcastData( - *interpolator_container[donorZone][targetZone].get(), - solver_container[donorZone][INST_0][MESH_0][donorSol], - solver_container[targetZone][INST_0][MESH_0][targetSol], - geometry_container[donorZone][INST_0][MESH_0], - geometry_container[targetZone][INST_0][MESH_0], - config_container[donorZone], - config_container[targetZone]); - }; - - switch (interface_types[donorZone][targetZone]) { - + auto HandleInterfaceType = [&] (const auto interface_type, auto* interface) { + auto BroadcastData = [&](int donorSol, int targetSol) { + interface->BroadcastData( + *interpolator_container[donorZone][targetZone], + solver_container[donorZone][INST_0][MESH_0][donorSol], + solver_container[targetZone][INST_0][MESH_0][targetSol], + geometry_container[donorZone][INST_0][MESH_0], + geometry_container[targetZone][INST_0][MESH_0], + config_container[donorZone], + config_container[targetZone]); + }; + + switch (interface_type) { case SLIDING_INTERFACE: BroadcastData(FLOW_SOL, FLOW_SOL); @@ -598,35 +598,49 @@ bool CMultizoneDriver::TransferData(unsigned short donorZone, unsigned short tar case FLOW_TRACTION: BroadcastData(FLOW_SOL, FEA_SOL); break; - case MIXING_PLANE: - { + case MIXING_PLANE: { const auto nMarkerInt = config_container[donorZone]->GetnMarker_MixingPlaneInterface() / 2; - /*--- Transfer the average value from the donorZone to the targetZone ---*/ - /*--- Loops over the mixing planes defined in the config file to find the correct mixing plane for the donor-target combination ---*/ + /*--- Transfer the average value from the donorZone to the targetZone + * Loops over the mixing planes defined in the config file to find the + * correct mixing plane for the donor-target combination ---*/ 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 ); + interface->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); } /*--- Set average value donorZone->targetZone ---*/ - interface_container[donorZone][targetZone]->SetAverageValues(solver_container[donorZone][INST_0][MESH_0][FLOW_SOL],solver_container[targetZone][INST_0][MESH_0][FLOW_SOL], donorZone); + interface->SetAverageValues(solver_container[donorZone][INST_0][MESH_0][FLOW_SOL], + solver_container[targetZone][INST_0][MESH_0][FLOW_SOL], donorZone); /*--- Set average geometrical properties FROM donorZone IN targetZone ---*/ - geometry_container[targetZone][INST_0][MESH_0]->SetAvgTurboGeoValues(config_container[iZone],geometry_container[iZone][INST_0][MESH_0], iZone); - - break; - } + 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: break; default: - if(rank == MASTER_NODE) + if (rank == MASTER_NODE) { cout << "WARNING: One of the intended interface transfer routines is not " << "known to the chosen driver and has not been executed." << endl; + } break; + } + }; + + auto type = interface_types[donorZone][targetZone]; + auto* interface = interface_container[donorZone][targetZone]; + + while (interface != nullptr) { + HandleInterfaceType(type, interface); + type = interface->NextInterfaceType; + interface = interface->NextInterface; } return UpdateMesh; diff --git a/SU2_CFD/src/integration/CMultiGridIntegration.cpp b/SU2_CFD/src/integration/CMultiGridIntegration.cpp index cf1bcd3b1ca5..1c0b35ad53d4 100644 --- a/SU2_CFD/src/integration/CMultiGridIntegration.cpp +++ b/SU2_CFD/src/integration/CMultiGridIntegration.cpp @@ -25,214 +25,54 @@ * License along with SU2. If not, see . */ -#include "../../include/integration/ComputeLinSysResRMS.hpp" #include "../../include/integration/CMultiGridIntegration.hpp" #include "../../../Common/include/parallelization/omp_structure.hpp" #include "../../../Common/include/toolboxes/printing_toolbox.hpp" -/*!\cond PRIVATE Helper: shared logic for adapting a single MG damping factor. - * Inputs: - * performed[] - actual iteration counts per level from this cycle - * progress[] - whether residuals decreased per level - * getConfigured - returns the per-level configured maximum - * levelStart/End - level range to inspect - * getCurrent - returns the current damping factor from config - * setPersist - persists the updated factor back to config +namespace { + +/*!\cond PRIVATE + * Global-trend damping update. Uses the cross-cycle EMA ratio to detect + * long-term divergence or convergence and adjusts both damping factors + * from a single, smooth signal. + * + * crossCycleRatio < LO : SCALE_UP (residual below EMA trend) + * crossCycleRatio >= HI : SCALE_DOWN (residual above EMA trend) + * [LO, HI) : no change (neutral zone) \endcond */ -template -static void adaptMGDampingFactor(const unsigned short* performed, - const bool* progress, - GetCfg getConfigured, - unsigned short levelStart, unsigned short levelEnd, - GetCur getCurrent, SetPersist setPersist) { - int local_any_stagnant = 0; /*--- hit max iters AND residuals did not decrease: scale down. ---*/ - int local_all_early = 1; /*--- all levels exited before max iters: scale up. ---*/ - int local_inspected = 0; - - for (unsigned short lvl = levelStart; lvl <= levelEnd; ++lvl) { - const unsigned short configured = getConfigured(lvl); - if (configured == 0) continue; - ++local_inspected; - const bool hit_max = (performed[lvl] >= configured); - /*--- Scale-down signal: hit the cap AND residuals did not improve. - * Hitting the cap while still converging is not stagnation; no reduction needed. ---*/ - if (hit_max && !progress[lvl]) local_any_stagnant = 1; - /*--- Scale-up signal: requires early exit on every level. - * Making progress at max iters is good, but the damping is already doing useful work; - * do not increase it further until the smoother actually exits early. ---*/ - if (hit_max) local_all_early = 0; - } - if (local_inspected == 0) return; - - /*--- performed[] and progress[] are derived from MPI-reduced ComputeLinSysResRMS values, - * so local_any_stagnant and local_all_early are already identical on every rank. ---*/ - const su2double SCALE_DOWN = 0.99; - const su2double SCALE_UP = 1.01; - const su2double CLAMP_MIN = 0.1; - const su2double CLAMP_MAX = 0.95; - - su2double factor = getCurrent(); - if (local_any_stagnant) factor *= SCALE_DOWN; - else if (local_all_early) factor *= SCALE_UP; - /*--- else: hit max iters but still converging, or mixed — hold factor. ---*/ - factor = max(CLAMP_MIN, min(CLAMP_MAX, factor)); - setPersist(factor); +static su2double applyGlobalTrend(su2double factor, passivedouble crossCycleRatio) { + constexpr passivedouble SCALE_DOWN = 0.92; + constexpr passivedouble SCALE_UP = 1.02; + constexpr passivedouble CLAMP_MIN = 0.10; + constexpr passivedouble CLAMP_MAX = 0.90; + constexpr passivedouble LO = 0.95; // ratio below this: converging, increase damping + constexpr passivedouble HI = 1.05; // ratio above this: diverging, decrease damping + + if (crossCycleRatio >= HI) factor *= SCALE_DOWN; + else if (crossCycleRatio < LO) factor *= SCALE_UP; + return max(su2double{CLAMP_MIN}, min(su2double{CLAMP_MAX}, factor)); } -void CMultiGridIntegration::adaptRestrictionDamping(CConfig* config) { - SU2_ZONE_SCOPED - const auto& mgOpts = config->GetMGOptions(); - const unsigned short nMGLevels = config->GetnMGLevels(); - adaptMGDampingFactor( - lastPreSmoothIters, - lastPreSmoothProgress, - [&mgOpts](unsigned short lvl){ return mgOpts.MG_PreSmooth[lvl]; }, - /*levelStart=*/1, nMGLevels, - [config](){ return config->GetDamp_Res_Restric(); }, - [config](su2double v){ config->SetDamp_Res_Restric(v); }); +inline passivedouble ComputeLinSysResRMS(const CSolver* solver) { + passivedouble result = 0; + for (unsigned short iVar = 0; iVar < solver->GetnVar(); ++iVar) { + result += pow(SU2_TYPE::GetValue(solver->GetRes_RMS(iVar)), 2); + } + return sqrt(result); } -void CMultiGridIntegration::adaptProlongationDamping(CConfig* config) { - SU2_ZONE_SCOPED - /*--- Post-smoothing directly measures whether the corrected fine-grid solution - * is well-behaved after prolongation. If it exits early, increase damping. - * If it stagnates at max iters, decrease damping. ---*/ - const auto& mgOpts = config->GetMGOptions(); - const unsigned short nMGLevels = config->GetnMGLevels(); - if (nMGLevels == 0) return; - adaptMGDampingFactor( - lastPostSmoothIters, - lastPostSmoothProgress, - [&mgOpts](unsigned short lvl){ return mgOpts.MG_PostSmooth[lvl]; }, - /*levelStart=*/0, static_cast(nMGLevels - 1), - [config](){ return config->GetDamp_Correc_Prolong(); }, - [config](su2double v){ config->SetDamp_Correc_Prolong(v); }); -} +} // anonymous namespace -passivedouble CMultiGridIntegration::computeMultigridCFL(CConfig* config, unsigned short iMesh, - passivedouble CFL_fine, passivedouble CFL_coarse_current, - passivedouble rms_res_coarse) { +void CMultiGridIntegration::adaptDampingFactors(CConfig* config, passivedouble crossCycleRatio) { SU2_ZONE_SCOPED - - const bool wasActive = AD::BeginPassive(); - - passivedouble current_coeff = CFL_coarse_current / CFL_fine; - - /*--- Adaptive CFL using Exponential Moving Average (EMA) ---*/ - constexpr int AVG_WINDOW = 5; - - passivedouble CFL_coarse_new = CFL_coarse_current; // Default: keep current value - - /*--- Get global iteration count first ---*/ - unsigned long current_iter; - if (config->GetTime_Domain()) - current_iter = config->GetTimeIter(); - else - current_iter = config->GetInnerIter(); - - /*--- Reset state at the beginning of a new solve (iter 0 or 1) ---*/ - /*--- This ensures deterministic behavior across multiple runs ---*/ - if (current_iter <= 1 && last_reset_iter != current_iter) { - for (int i = 0; i < MAX_MG_LEVELS; i++) { - current_avg[i] = 0.0; - prev_avg[i] = 0.0; - last_res[i] = 0.0; - last_was_increase[i] = false; - oscillation_count[i] = 0; - last_check_iter[i] = 0; - last_update_iter[i] = 0; - } - last_reset_iter = current_iter; - } - - unsigned short lvl = min(iMesh, (unsigned short)(MAX_MG_LEVELS - 1)); - unsigned long iter = current_iter; - - /*--- rms_res_coarse is passed in (from lastPreSmoothRMS, already MPI-reduced). ---*/ - - /*--- Flip-flop detection: detect oscillating residuals (once per outer iteration) ---*/ - bool oscillation_detected = false; - if (iter != last_check_iter[lvl]) { - last_check_iter[lvl] = iter; - - if (last_res[lvl] > EPS) { - bool current_is_increase = (rms_res_coarse > last_res[lvl]); - if (current_is_increase != last_was_increase[lvl]) { - /*--- Direction changed, increment oscillation counter ---*/ - oscillation_count[lvl]++; - if (oscillation_count[lvl] >= 4) { - /*--- Detected 4 consecutive direction changes = oscillation ---*/ - oscillation_detected = true; - oscillation_count[lvl] = 0; // Reset counter after detecting - } - } else { - /*--- Same direction, reset counter ---*/ - oscillation_count[lvl] = 0; - } - last_was_increase[lvl] = current_is_increase; - } - last_res[lvl] = rms_res_coarse; - } - - /*--- Update exponential moving average ---*/ - if (current_avg[lvl] < EPS) { - current_avg[lvl] = rms_res_coarse; // Initialize with first value - } else { - current_avg[lvl] = (current_avg[lvl] * (AVG_WINDOW - 1) + rms_res_coarse) / AVG_WINDOW; - } - - /*--- Check if we should compare and adapt CFL ---*/ - passivedouble new_coeff = current_coeff; - const passivedouble MIN_REDUCTION_FACTOR = 0.98; // Require at least 2% reduction - const int UPDATE_INTERVAL = 5; // Update reference every N iterations - - /*--- Initialize prev_avg on first use ---*/ - if (prev_avg[lvl] < EPS) { - prev_avg[lvl] = current_avg[lvl]; - } - - /*--- Periodically update prev_avg to allow ratio to reflect accumulated decrease ---*/ - bool should_update = (iter - last_update_iter[lvl] >= UPDATE_INTERVAL); - - /*--- Asymmetric adaptation for robustness ---*/ - if (prev_avg[lvl] > EPS) { - passivedouble ratio = current_avg[lvl] / prev_avg[lvl]; - bool sufficient_decrease = (ratio < MIN_REDUCTION_FACTOR); - bool increasing_trend = (ratio >= 1.0); - - if (increasing_trend) { - /*--- Residual increasing: reduce CFL immediately for robustness ---*/ - new_coeff = current_coeff * 0.90; - /*--- Update reference since we're reacting immediately ---*/ - prev_avg[lvl] = current_avg[lvl]; - last_update_iter[lvl] = iter; - } else if (sufficient_decrease && should_update) { - /*--- Residual decreasing sufficiently: increase CFL ---*/ - new_coeff = current_coeff * 1.05; - /*--- Update reference only when we actually increase CFL ---*/ - prev_avg[lvl] = current_avg[lvl]; - last_update_iter[lvl] = iter; - } - } - - /*--- CFL reduction for oscillation detection ---*/ - if (oscillation_detected) { - new_coeff = current_coeff * 0.75; - /*--- Update reference after oscillation response ---*/ - prev_avg[lvl] = current_avg[lvl]; - last_update_iter[lvl] = iter; - } - - /*--- Clamp coefficient between 0.5 and 1.0 ---*/ - new_coeff = max(0.5, min(1.0, new_coeff)); - - /*--- Update coarse grid CFL ---*/ - CFL_coarse_new = max(0.5 * CFL_fine, min(CFL_fine, CFL_fine * new_coeff)); - - config->SetCFL(iMesh+1, CFL_coarse_new); - - AD::EndPassive(wasActive); - return CFL_coarse_new; + if (config->GetnMGLevels() == 0) return; + + /*--- Both factors share the same global-trend signal. The EMA already filters + * per-cycle noise; no per-level aggregation or floor counter needed. ---*/ + config->SetDamp_Res_Restric( + applyGlobalTrend(config->GetDamp_Res_Restric(), crossCycleRatio)); + config->SetDamp_Correc_Prolong( + applyGlobalTrend(config->GetDamp_Correc_Prolong(), crossCycleRatio)); } CMultiGridIntegration::CMultiGridIntegration() : CIntegration() { } @@ -279,7 +119,7 @@ void CMultiGridIntegration::MultiGrid_Iteration(CGeometry ****geometry, su2double monitor = 1.0; bool FullMG = false; - unsigned short RecursiveParam = static_cast(config[iZone]->GetMGCycle()); + auto RecursiveParam = static_cast(config[iZone]->GetMGCycle()); if (config[iZone]->GetMGCycle() == MG_CYCLE::FULL) { RecursiveParam = static_cast(MG_CYCLE::V); @@ -290,22 +130,24 @@ void CMultiGridIntegration::MultiGrid_Iteration(CGeometry ****geometry, unsigned short FinestMesh = config[iZone]->GetFinestMesh(); - /*--- Initialize per-level smoothing iteration counters to the configured maximum. - * If early exit never fires, the output will show actual == max. ---*/ + /*--- Initialize per-level smoothing diagnostics for the current cycle. ---*/ BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { const unsigned short nMGLevels = config[iZone]->GetnMGLevels(); const auto& mgOpts = config[iZone]->GetMGOptions(); for (unsigned short i = 0; i <= nMGLevels; ++i) { - lastPreSmoothIters[i] = mgOpts.MG_PreSmooth[i]; - lastPostSmoothIters[i] = mgOpts.MG_PostSmooth[i]; + lastPreSmoothIters[i] = 0; + lastPostSmoothIters[i] = 0; lastCorrecSmoothIters[i] = mgOpts.MG_CorrecSmooth[i]; - lastPreSmoothProgress[i] = false; - lastPostSmoothProgress[i] = false; - lastCorrecSmoothProgress[i] = false; + lastCorrecSmoothRMS[i][0] = lastCorrecSmoothRMS[i][1] = 0.0; lastPreSmoothRMS[i][0] = lastPreSmoothRMS[i][1] = 0.0; lastPostSmoothRMS[i][0] = lastPostSmoothRMS[i][1] = 0.0; - lastCorrecSmoothRMS[i][0] = lastCorrecSmoothRMS[i][1] = 0.0; + lastPreSmoothWorstStepRatio[i] = 0.0; + lastPostSmoothWorstStepRatio[i] = 0.0; + lastPreSmoothWorstStep[i] = 0; + lastPostSmoothWorstStep[i] = 0; + lastPreSmoothExitReason[i] = ' '; + lastPostSmoothExitReason[i] = ' '; } } END_SU2_OMP_SAFE_GLOBAL_ACCESS @@ -338,16 +180,30 @@ void CMultiGridIntegration::MultiGrid_Iteration(CGeometry ****geometry, MultiGrid_Cycle(geometry, solver_container, numerics_container, config, FinestMesh, RecursiveParam, RunTime_EqSystem, iZone, iInst); - /*--- Adapt coarse-grid CFL once per cycle using smoothing residuals gathered during the cycle. - * lastPreSmoothRMS[iMesh+1][1] is the final RMS after pre-smoothing at the coarse level ---*/ + /*--- Adapt coarse-grid CFL once per cycle using smoothing residuals gathered during the cycle. ---*/ const unsigned short nMGLevels = config[iZone]->GetnMGLevels(); BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { + /*--- Use the current finest-grid CFL as the base for deterministic + * coarse-level scaling. Fall back to config scalar when local CFL + * adaptation is disabled. ---*/ + passivedouble cfl_base = SU2_TYPE::GetValue( + solver_container[iZone][iInst][FinestMesh][Solver_Position]->GetAvg_CFL_Local()); + if (cfl_base < EPS) + cfl_base = SU2_TYPE::GetValue(config[iZone]->GetCFL(FinestMesh)); + + const auto& cflScaling = config[iZone]->GetMGOptions().MG_CflScaling; + + passivedouble CFL_local = cfl_base; for (unsigned short iMesh = FinestMesh; iMesh < nMGLevels; ++iMesh) { - const passivedouble CFL_fine_p = SU2_TYPE::GetValue(config[iZone]->GetCFL(iMesh)); - const passivedouble CFL_coarse_p = SU2_TYPE::GetValue(config[iZone]->GetCFL(iMesh+1)); - computeMultigridCFL(config[iZone], iMesh, CFL_fine_p, CFL_coarse_p, - lastPreSmoothRMS[iMesh+1][1]); + const unsigned short lvl = iMesh + 1; + /*--- Use per-level scaling factor; clamp to (0,1] to prevent coarse CFL from + * exceeding the fine CFL. Index into cflScaling is iMesh (0-based transition). ---*/ + const passivedouble scale = (iMesh < cflScaling.size()) + ? max(passivedouble{1e-6}, min(passivedouble{1.0}, SU2_TYPE::GetValue(cflScaling[iMesh]))) + : passivedouble{0.25}; + CFL_local *= scale; + config[iZone]->SetCFL(lvl, CFL_local); } } END_SU2_OMP_SAFE_GLOBAL_ACCESS @@ -381,10 +237,20 @@ void CMultiGridIntegration::MultiGrid_Iteration(CGeometry ****geometry, * and the signal would always point to "scale down"). ---*/ const auto& mgOptsZone = config[iZone]->GetMGOptions(); if (mgOptsZone.MG_Smooth_EarlyExit) { - BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS - { - adaptRestrictionDamping(config[iZone]); - adaptProlongationDamping(config[iZone]); + BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { + constexpr passivedouble EMA_ALPHA = 0.02; + const passivedouble fine_d0 = lastPreSmoothRMS[FinestMesh][0]; + const bool ema_ready = (mg_fine_rms_ema >= EPS); + if (!ema_ready) + mg_fine_rms_ema = fine_d0; + else + mg_fine_rms_ema = (1.0 - EMA_ALPHA) * mg_fine_rms_ema + EMA_ALPHA * fine_d0; + const passivedouble crossCycleRatio = (mg_fine_rms_ema > EPS) ? fine_d0 / mg_fine_rms_ema : 1.0; + + /*--- Adapt both damping factors from the same global-trend signal. + * Skip on the first cycle while the EMA is still being seeded. ---*/ + if (ema_ready) adaptDampingFactors(config[iZone], crossCycleRatio); + last_crossCycleRatio = crossCycleRatio; } END_SU2_OMP_SAFE_GLOBAL_ACCESS } @@ -392,52 +258,81 @@ void CMultiGridIntegration::MultiGrid_Iteration(CGeometry ****geometry, /*--- Print compact smoothing summary when MG_SMOOTH_OUTPUT= YES. ---*/ if (mgOptsZone.MG_Smooth_Output) { BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS - { - if (SU2_MPI::GetRank() == MASTER_NODE) { - - /*--- Helper: format one cell as "act/max [init->final]". ---*/ - auto cellStr = [](unsigned short act, unsigned short mx, - su2double rms0, su2double rms1) -> std::string { - std::ostringstream ss; - ss << act << "/" << mx << " [" - << std::scientific << std::setprecision(2) - << rms0 << "->" << rms1 << "]"; - return ss.str(); - }; - - PrintingToolbox::CTablePrinter table(&std::cout); - table.AddColumn("Smoother", 13); - for (unsigned short i = 0; i <= nMGLevels; ++i) - table.AddColumn("Level " + std::to_string(i), 26); - table.PrintHeader(); - - /*--- Pre-smooth: defined on all levels 0..nMGLevels. ---*/ - table << "Pre-smooth"; - for (unsigned short i = 0; i <= nMGLevels; ++i) - table << cellStr(lastPreSmoothIters[i], mgOptsZone.MG_PreSmooth[i], - lastPreSmoothRMS[i][0], lastPreSmoothRMS[i][1]); - - /*--- Post-smooth: defined on levels 0..nMGLevels-1; coarsest has none. ---*/ - table << "Post-smooth"; - for (unsigned short i = 0; i < nMGLevels; ++i) - table << cellStr(lastPostSmoothIters[i], mgOptsZone.MG_PostSmooth[i], - lastPostSmoothRMS[i][0], lastPostSmoothRMS[i][1]); - table << "-"; - - /*--- Corr.-smooth: defined on levels 0..nMGLevels-1; coarsest has none. ---*/ - table << "Corr-smooth"; - for (unsigned short i = 0; i < nMGLevels; ++i) - table << cellStr(lastCorrecSmoothIters[i], mgOptsZone.MG_CorrecSmooth[i], - lastCorrecSmoothRMS[i][0], lastCorrecSmoothRMS[i][1]); - table << "-"; - - table.PrintFooter(); - - cout << std::fixed << std::setprecision(4) - << "Damping [restrict | prolong] : " << config[iZone]->GetDamp_Res_Restric() - << " | " << config[iZone]->GetDamp_Correc_Prolong() << "\n" - << std::defaultfloat << std::setprecision(6); + if (SU2_MPI::GetRank() == MASTER_NODE) { + + /*--- Helper: format one cell as "act/max [init->final]". ---*/ + auto cellStr = [](unsigned short act, unsigned short mx, char reason, + su2double d0, su2double d1, + passivedouble worstStepRatio, + unsigned short worstStep) -> std::string { + /*--- Show: steps taken / max + exit reason + initial defect scale + d1/d0 ratio. + * r=d1/d0 < 1 means smoother reduced the defect (good). + * r > 1 means smoother grew the defect. + * Exit reason: T=threshold, S=clean stagnation, A=amplifying stagnation, + * ' '=ran to completion. ---*/ + std::ostringstream ss; + ss << act << "/" << mx; + if (act < mx) ss << reason; /*--- only tag early exits ---*/ + ss << " [" << std::scientific << std::setprecision(2) << d0 << "]"; + if (d0 > 0.0) { + ss << std::fixed << std::setprecision(3) << " r=" << d1 / d0; + } + if (worstStep > 0) { + ss << " rw" << worstStep << "=" << std::fixed << std::setprecision(3) << worstStepRatio; + } + return ss.str(); + }; + + PrintingToolbox::CTablePrinter table(&std::cout); + table.AddColumn("Smoother", 13); + for (unsigned short i = 0; i <= nMGLevels; ++i) + table.AddColumn("Level " + std::to_string(i), 38); + table.PrintHeader(); + + /*--- Pre-smooth: defect [d0->d1] — what early exit and damping adaptation read. ---*/ + table << "Pre-smooth"; + for (unsigned short i = 0; i <= nMGLevels; ++i) + table << cellStr(lastPreSmoothIters[i], mgOptsZone.MG_PreSmooth[i], + lastPreSmoothExitReason[i], + lastPreSmoothRMS[i][0], lastPreSmoothRMS[i][1], + lastPreSmoothWorstStepRatio[i], lastPreSmoothWorstStep[i]); + + /*--- Post-smooth: defect [d0->d1] — what early exit and prolongation-damping read. ---*/ + table << "Post-smooth"; + for (unsigned short i = 0; i < nMGLevels; ++i) + table << cellStr(lastPostSmoothIters[i], mgOptsZone.MG_PostSmooth[i], + lastPostSmoothExitReason[i], + lastPostSmoothRMS[i][0], lastPostSmoothRMS[i][1], + lastPostSmoothWorstStepRatio[i], lastPostSmoothWorstStep[i]); + table << "-"; + + /*--- Corr.-smooth: defined on levels 0..nMGLevels-1; coarsest has none. ---*/ + table << "Corr-smooth"; + for (unsigned short i = 0; i < nMGLevels; ++i) + table << cellStr(lastCorrecSmoothIters[i], mgOptsZone.MG_CorrecSmooth[i], + ' ', lastCorrecSmoothRMS[i][0], lastCorrecSmoothRMS[i][1], + 0.0, 0); + table << "-"; + + table << "CFL"; + for (unsigned short i = 0; i <= nMGLevels; ++i) { + std::ostringstream ss; + ss << std::fixed << std::setprecision(4); + if (i == MESH_0) { + ss << SU2_TYPE::GetValue(solver_container[iZone][iInst][MESH_0][Solver_Position]->GetAvg_CFL_Local()); + } else { + ss << SU2_TYPE::GetValue(config[iZone]->GetCFL(i)); + } + table << ss.str(); } + + table.PrintFooter(); + + cout << std::fixed << std::setprecision(4) + << "Damping [restrict | prolong] : " << config[iZone]->GetDamp_Res_Restric() + << " | " << config[iZone]->GetDamp_Correc_Prolong() + << " cross-cycle: " << std::setprecision(3) << last_crossCycleRatio << "\n" + << std::defaultfloat << std::setprecision(6); } END_SU2_OMP_SAFE_GLOBAL_ACCESS } @@ -502,6 +397,12 @@ void CMultiGridIntegration::MultiGrid_Cycle(CGeometry ****geometry, Space_Integration(geometry_fine, solver_container_fine, numerics_fine, config, iMesh, NO_RK_ITER, RunTime_EqSystem); + /*--- LinSysRes = R(u_N) here, before tau is added by SetResidual_Term. ---*/ + BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { + lastPreSmoothRMS[iMesh][1] = ComputeLinSysResRMS(solver_fine); + } + END_SU2_OMP_SAFE_GLOBAL_ACCESS + SetResidual_Term(geometry_fine, solver_fine); /*--- Compute $r_(k+1) = F_(k+1)(I^(k+1)_k u_k)$ ---*/ @@ -553,6 +454,38 @@ void CMultiGridIntegration::MultiGrid_Cycle(CGeometry ****geometry, } +void CMultiGridIntegration::prePostEarlyExit(unsigned short iSmooth, unsigned short iMesh, + passivedouble defect, const CMGOptions& mgOpts, + passivedouble stag_tol, bool early_exit, + passivedouble lastRMS[2], char& exitReason, + passivedouble& worstStepRatio, unsigned short& worstStep) { + if (iSmooth == 0) { + mg_initial_smooth_rms = defect; + lastRMS[0] = defect; + } else { + if (mg_prev_smooth_rms > EPS) { + const passivedouble step_ratio = defect / mg_prev_smooth_rms; + if (step_ratio > worstStepRatio) { + worstStepRatio = step_ratio; + worstStep = iSmooth + 1; + } + } + + if (early_exit) { + if (defect < mgOpts.MG_Smooth_Res_Threshold * mg_initial_smooth_rms) { + exitReason = 'T'; + mg_early_exit_flag = true; + } else if (defect >= mg_prev_smooth_rms * stag_tol) { + /*--- 'A' = amplifying-stagnation (defect grew vs previous step). + * 'S' = clean stagnation (defect is not improving but also not growing). ---*/ + exitReason = (defect > mg_prev_smooth_rms) ? 'A' : 'S'; + mg_early_exit_flag = true; + } + } + } + mg_prev_smooth_rms = defect; +} + void CMultiGridIntegration::PreSmoothing(unsigned short RunTime_EqSystem, CGeometry**** geometry, CSolver***** solver_container, @@ -572,6 +505,11 @@ void CMultiGridIntegration::PreSmoothing(unsigned short RunTime_EqSystem, const unsigned short nPreSmooth = mgOpts.MG_PreSmooth[iMesh]; const unsigned long timeIter = config->GetTimeIter(); const bool early_exit = mgOpts.MG_Smooth_EarlyExit && (nPreSmooth > 1); + const bool need_per_step_rms = early_exit || mgOpts.MG_Smooth_Output; + /*--- Also capture initial RMS at MESH_0 for the cross-cycle EMA controller, even with nPreSmooth==1. ---*/ + const bool need_initial_rms = need_per_step_rms || (iMesh == MESH_0 && mgOpts.MG_Smooth_EarlyExit); + const passivedouble stag_tol = (mgOpts.MG_Smooth_StagnationTol > 0.0) + ? SU2_TYPE::GetValue(mgOpts.MG_Smooth_StagnationTol) : passivedouble(1.0); /*--- Reset the shared early-exit flag (master only). ---*/ SU2_OMP_SAFE_GLOBAL_ACCESS(mg_early_exit_flag = false;) @@ -596,59 +534,39 @@ void CMultiGridIntegration::PreSmoothing(unsigned short RunTime_EqSystem, /*--- Space integration ---*/ Space_Integration(geometry_fine, solver_container_fine, numerics_fine, config, iMesh, iRKStep, RunTime_EqSystem); - /*--- Capture initial RMS after the very first residual evaluation. - * This is the earliest point where LinSysRes = R(u_current) (not stale). - * ComputeLinSysResRMS must be called by all threads (uses parallel dot). ---*/ - if (iPreSmooth == 0 && iRKStep == 0) { - const passivedouble initial_rms = ComputeLinSysResRMS(solver_fine); - BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS - { - lastPreSmoothRMS[iMesh][0] = initial_rms; - if (early_exit) mg_initial_smooth_rms = initial_rms; + /*--- Time integration, update solution using the old solution plus the solution increment ---*/ + Time_Integration(geometry_fine, solver_container_fine, config, iRKStep, RunTime_EqSystem); + + /*--- At iRKStep==0 LinSysRes = R(u_k). ---*/ + if (iRKStep == 0 && need_initial_rms) { + BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { + const passivedouble defect = ComputeLinSysResRMS(solver_fine); + prePostEarlyExit(iPreSmooth, iMesh, defect, mgOpts, stag_tol, early_exit, + lastPreSmoothRMS[iMesh], lastPreSmoothExitReason[iMesh], + lastPreSmoothWorstStepRatio[iMesh], lastPreSmoothWorstStep[iMesh]); } END_SU2_OMP_SAFE_GLOBAL_ACCESS + if (mg_early_exit_flag) break; } - /*--- Time integration, update solution using the old solution plus the solution increment ---*/ - Time_Integration(geometry_fine, solver_container_fine, config, iRKStep, RunTime_EqSystem); /*--- Send-Receive boundary conditions, and postprocessing ---*/ solver_fine->Postprocessing(geometry_fine, solver_container_fine, config, iMesh); } - - /*--- Early exit: check if RMS has dropped sufficiently. - * ComputeLinSysResRMS must be called by all threads. - * only master uses the result inside the safe block. ---*/ - if (early_exit) { - const passivedouble current_rms = ComputeLinSysResRMS(solver_fine); - BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS - { - mg_last_smooth_rms = current_rms; - if (mg_last_smooth_rms < mgOpts.MG_Smooth_Res_Threshold * mg_initial_smooth_rms) { - lastPreSmoothIters[iMesh] = iPreSmooth + 1; - mg_early_exit_flag = true; - } - } - END_SU2_OMP_SAFE_GLOBAL_ACCESS - if (mg_early_exit_flag) break; - } + SU2_OMP_SAFE_GLOBAL_ACCESS(lastPreSmoothIters[iMesh] = iPreSmooth + 1;) + if (mg_early_exit_flag) break; } - /*--- Record final RMS and progress flag. - * In the early-exit path mg_last_smooth_rms already holds the current value; - * in the normal path we compute it once here. - * The condition is the same for all threads so they all agree on whether to call. ---*/ - passivedouble final_pre_rms = mg_last_smooth_rms; - if (!(early_exit && mg_early_exit_flag)) - final_pre_rms = ComputeLinSysResRMS(solver_fine); - BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS - { - mg_last_smooth_rms = final_pre_rms; - lastPreSmoothRMS[iMesh][1] = final_pre_rms; - lastPreSmoothProgress[iMesh] = mg_early_exit_flag || - (final_pre_rms < lastPreSmoothRMS[iMesh][0]); + /*--- Record d_{N-1} as the final pre-smooth defect (the last value captured inside the loop). + * For non-coarsest levels MultiGrid_Cycle overwrites this with the exact d_N at zero + * additional cost in the restriction block (Space_Integration already runs there). + * Skip when nPreSmooth==0: lastPreSmoothDefect[iMesh] stays {0,0} (initialized). ---*/ + if (nPreSmooth > 0) { + BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { + lastPreSmoothRMS[iMesh][1] = mg_prev_smooth_rms; + } + END_SU2_OMP_SAFE_GLOBAL_ACCESS } - END_SU2_OMP_SAFE_GLOBAL_ACCESS } @@ -667,6 +585,9 @@ void CMultiGridIntegration::PostSmoothing(unsigned short RunTime_EqSystem, const unsigned short nPostSmooth = mgOpts.MG_PostSmooth[iMesh]; const unsigned long timeIter = config->GetTimeIter(); const bool early_exit = mgOpts.MG_Smooth_EarlyExit && (nPostSmooth > 1); + const bool need_per_step_rms = early_exit || mgOpts.MG_Smooth_Output; + const passivedouble stag_tol = (mgOpts.MG_Smooth_StagnationTol > 0.0) + ? SU2_TYPE::GetValue(mgOpts.MG_Smooth_StagnationTol) : passivedouble(1.0); /*--- Reset the shared early-exit flag (master only). ---*/ SU2_OMP_SAFE_GLOBAL_ACCESS(mg_early_exit_flag = false;) @@ -688,77 +609,54 @@ void CMultiGridIntegration::PostSmoothing(unsigned short RunTime_EqSystem, /*--- Space integration ---*/ Space_Integration(geometry_fine, solver_container_fine, numerics_fine, config, iMesh, iRKStep, RunTime_EqSystem); - /*--- Capture initial RMS after the very first residual evaluation. - * Before this point, LinSysRes held the smoothed correction (from SmoothProlongated_Correction), - * NOT the spatial residual R(u). This is the first valid R(u) after applying the correction. - * ComputeLinSysResRMS must be called by all threads (uses parallel dot). ---*/ - if (iPostSmooth == 0 && iRKStep == 0) { - const passivedouble initial_rms = ComputeLinSysResRMS(solver_fine); - BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS - { - lastPostSmoothRMS[iMesh][0] = initial_rms; - if (early_exit) mg_initial_smooth_rms = initial_rms; + /*--- Time integration, update solution using the old solution plus the solution increment ---*/ + Time_Integration(geometry_fine, solver_container_fine, config, iRKStep, RunTime_EqSystem); + + /*--- At iRKStep==0 LinSysRes = R(u_k) ---*/ + if (iRKStep == 0 && need_per_step_rms) { + BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { + const passivedouble defect = ComputeLinSysResRMS(solver_fine); + prePostEarlyExit(iPostSmooth, iMesh, defect, mgOpts, stag_tol, early_exit, + lastPostSmoothRMS[iMesh], lastPostSmoothExitReason[iMesh], + lastPostSmoothWorstStepRatio[iMesh], lastPostSmoothWorstStep[iMesh]); } END_SU2_OMP_SAFE_GLOBAL_ACCESS + if (mg_early_exit_flag) break; } - /*--- Time integration, update solution using the old solution plus the solution increment ---*/ - Time_Integration(geometry_fine, solver_container_fine, config, iRKStep, RunTime_EqSystem); /*--- Send-Receive boundary conditions, and postprocessing ---*/ solver_fine->Postprocessing(geometry_fine, solver_container_fine, config, iMesh); } - - /*--- Early exit: check if RMS has dropped sufficiently. - * ComputeLinSysResRMS must be called by all threads (uses parallel dot). ---*/ - if (early_exit) { - const passivedouble current_rms = ComputeLinSysResRMS(solver_fine); - BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS - { - mg_last_smooth_rms = current_rms; - if (mg_last_smooth_rms < mgOpts.MG_Smooth_Res_Threshold * mg_initial_smooth_rms) { - lastPostSmoothIters[iMesh] = iPostSmooth + 1; - mg_early_exit_flag = true; - } - } - END_SU2_OMP_SAFE_GLOBAL_ACCESS - if (mg_early_exit_flag) break; - } + SU2_OMP_SAFE_GLOBAL_ACCESS(lastPostSmoothIters[iMesh] = iPostSmooth + 1;) + if (mg_early_exit_flag) break; } - /*--- Record final RMS after post-smoothing. - * In the early-exit path mg_last_smooth_rms is already current; otherwise compute once. - * The condition is the same for all threads so they all agree on whether to call. ---*/ - passivedouble final_post_rms = mg_last_smooth_rms; - if (!(early_exit && mg_early_exit_flag)) - final_post_rms = ComputeLinSysResRMS(solver_fine); - BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS - { - mg_last_smooth_rms = final_post_rms; - lastPostSmoothRMS[iMesh][1] = final_post_rms; - lastPostSmoothProgress[iMesh] = mg_early_exit_flag || - (final_post_rms < lastPostSmoothRMS[iMesh][0]); + /*--- Record d_{N-1} as the final post-smooth defect (display only). + * Skip when nPostSmooth==0: lastPostSmoothRMS[iMesh] stays {0,0} (initialized). ---*/ + if (nPostSmooth > 0) { + BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { + lastPostSmoothRMS[iMesh][1] = mg_prev_smooth_rms; + } + END_SU2_OMP_SAFE_GLOBAL_ACCESS } - END_SU2_OMP_SAFE_GLOBAL_ACCESS } void CMultiGridIntegration::GetProlongated_Correction(unsigned short RunTime_EqSystem, CSolver *sol_fine, CSolver *sol_coarse, CGeometry *geo_fine, CGeometry *geo_coarse, CConfig *config) { SU2_ZONE_SCOPED - const su2double *Solution_Fine = nullptr, *Solution_Coarse = nullptr; const unsigned short nVar = sol_coarse->GetnVar(); - - auto *Solution = new su2double[nVar]; + su2activevector Solution(nVar); SU2_OMP_FOR_STAT(roundUpDiv(geo_coarse->GetnPointDomain(), omp_get_num_threads())) for (auto Point_Coarse = 0ul; Point_Coarse < geo_coarse->GetnPointDomain(); Point_Coarse++) { su2double Area_Parent = geo_coarse->nodes->GetVolume(Point_Coarse); - for (auto iVar = 0u; iVar < nVar; iVar++) Solution[iVar] = 0.0; + Solution = su2double(0); /*--- Accumulate children contributions with stable ordering ---*/ /*--- Process all children in sequential order to ensure deterministic FP summation ---*/ @@ -766,24 +664,22 @@ void CMultiGridIntegration::GetProlongated_Correction(unsigned short RunTime_EqS for (auto iChildren = 0u; iChildren < nChildren; iChildren++) { auto Point_Fine = geo_coarse->nodes->GetChildren_CV(Point_Coarse, iChildren); su2double Area_Children = geo_fine->nodes->GetVolume(Point_Fine); - Solution_Fine = sol_fine->GetNodes()->GetSolution(Point_Fine); + const auto* Solution_Fine = sol_fine->GetNodes()->GetSolution(Point_Fine); su2double weight = Area_Children / Area_Parent; for (auto iVar = 0u; iVar < nVar; iVar++) Solution[iVar] -= Solution_Fine[iVar] * weight; } - Solution_Coarse = sol_coarse->GetNodes()->GetSolution(Point_Coarse); + const auto* Solution_Coarse = sol_coarse->GetNodes()->GetSolution(Point_Coarse); for (auto iVar = 0u; iVar < nVar; iVar++) Solution[iVar] += Solution_Coarse[iVar]; for (auto iVar = 0u; iVar < nVar; iVar++) - sol_coarse->GetNodes()->SetSolution_Old(Point_Coarse,Solution); + sol_coarse->GetNodes()->SetSolution_Old(Point_Coarse, Solution.data()); } END_SU2_OMP_FOR - delete [] Solution; - /*--- Enforce Euler wall BC on corrections by projecting to tangent plane ---*/ sol_coarse->MultigridProjectEulerWall(geo_coarse, config, true); @@ -831,24 +727,15 @@ void CMultiGridIntegration::SmoothProlongated_Correction(unsigned short RunTime_ /*--- Check if there is work to do. ---*/ if (val_nSmooth == 0) return; - const su2double *Residual_Old, *Residual_Sum, *Residual_j; - const unsigned short nVar = solver->GetnVar(); SU2_OMP_FOR_STAT(roundUpDiv(geometry->GetnPoint(), omp_get_num_threads())) for (auto iPoint = 0ul; iPoint < geometry->GetnPoint(); iPoint++) { - Residual_Old = solver->LinSysRes.GetBlock(iPoint); - solver->GetNodes()->SetResidual_Old(iPoint,Residual_Old); + const auto* Residual_Old = solver->LinSysRes.GetBlock(iPoint); + solver->GetNodes()->SetResidual_Old(iPoint, Residual_Old); } END_SU2_OMP_FOR - /*--- Record initial correction norm for debugging output. - * ComputeLinSysResRMS must be called by all threads (uses parallel dot). ---*/ - { - const passivedouble initial_corr_rms = ComputeLinSysResRMS(solver); - SU2_OMP_SAFE_GLOBAL_ACCESS(lastCorrecSmoothRMS[iMesh][0] = initial_corr_rms;) - } - /*--- Jacobi iterations (no early exit — Jacobi targets high-frequency modes, * so the global RMS is not a meaningful convergence indicator). ---*/ @@ -863,7 +750,7 @@ void CMultiGridIntegration::SmoothProlongated_Correction(unsigned short RunTime_ for (auto iNeigh = 0u; iNeigh < geometry->nodes->GetnPoint(iPoint); ++iNeigh) { auto jPoint = geometry->nodes->GetPoint(iPoint, iNeigh); - Residual_j = solver->LinSysRes.GetBlock(jPoint); + const auto* Residual_j = solver->LinSysRes.GetBlock(jPoint); solver->GetNodes()->AddResidual_Sum(iPoint, Residual_j); } @@ -877,8 +764,8 @@ void CMultiGridIntegration::SmoothProlongated_Correction(unsigned short RunTime_ su2double factor = 1.0/(1.0+val_smooth_coeff*su2double(geometry->nodes->GetnPoint(iPoint))); - Residual_Sum = solver->GetNodes()->GetResidual_Sum(iPoint); - Residual_Old = solver->GetNodes()->GetResidual_Old(iPoint); + const auto* Residual_Sum = solver->GetNodes()->GetResidual_Sum(iPoint); + const auto* Residual_Old = solver->GetNodes()->GetResidual_Old(iPoint); for (auto iVar = 0u; iVar < nVar; iVar++) solver->LinSysRes(iPoint,iVar) = (Residual_Old[iVar] + val_smooth_coeff*Residual_Sum[iVar])*factor; @@ -895,7 +782,7 @@ void CMultiGridIntegration::SmoothProlongated_Correction(unsigned short RunTime_ SU2_OMP_FOR_STAT(32) for (auto iVertex = 0ul; iVertex < geometry->GetnVertex(iMarker); iVertex++) { auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - Residual_Old = solver->GetNodes()->GetResidual_Old(iPoint); + const auto* Residual_Old = solver->GetNodes()->GetResidual_Old(iPoint); solver->LinSysRes.SetBlock(iPoint, Residual_Old); } END_SU2_OMP_FOR @@ -904,33 +791,26 @@ void CMultiGridIntegration::SmoothProlongated_Correction(unsigned short RunTime_ } - /*--- Record final correction norm for debugging output. - * ComputeLinSysResRMS must be called by all threads (uses parallel dot). ---*/ - const passivedouble final_corr_rms = ComputeLinSysResRMS(solver); - SU2_OMP_SAFE_GLOBAL_ACCESS(lastCorrecSmoothRMS[iMesh][1] = final_corr_rms;) - + /*--- Record final correction norm for debugging output. ---*/ + if (config->GetMGOptions().MG_Smooth_Output) { + const su2double res = sqrt(solver->LinSysRes.squaredNorm() / (nVar * geometry->GetGlobal_nPointDomain())); + SU2_OMP_SAFE_GLOBAL_ACCESS(lastCorrecSmoothRMS[iMesh][1] = SU2_TYPE::GetValue(res);) + } } void CMultiGridIntegration::SetProlongated_Correction(CSolver *sol_fine, CGeometry *geo_fine, CConfig *config, unsigned short iMesh) { SU2_ZONE_SCOPED - su2double *Solution_Fine, *Residual_Fine; const unsigned short nVar = sol_fine->GetnVar(); - /*--- Level-dependent damping: coarser prolongations produce noisier corrections - * due to larger cell-size jumps, so we reduce the factor progressively. - * iMesh=0: factor = base_damp * 1.0 (finest grid, full correction) - * iMesh=1: factor = base_damp * 0.75 - * iMesh=2: factor = base_damp * 0.5625, etc. ---*/ - const su2double base_damp = config->GetDamp_Correc_Prolong(); - const su2double level_factor = pow(0.75, static_cast(iMesh)); - const su2double factor = base_damp * level_factor; + /*--- Use the adaptive damping factor uniformly across all prolongation levels. ---*/ + const su2double factor = config->GetDamp_Correc_Prolong(); SU2_OMP_FOR_STAT(roundUpDiv(geo_fine->GetnPointDomain(), omp_get_num_threads())) for (auto Point_Fine = 0ul; Point_Fine < geo_fine->GetnPointDomain(); Point_Fine++) { - Residual_Fine = sol_fine->LinSysRes.GetBlock(Point_Fine); - Solution_Fine = sol_fine->GetNodes()->GetSolution(Point_Fine); + auto* Residual_Fine = sol_fine->LinSysRes.GetBlock(Point_Fine); + auto* Solution_Fine = sol_fine->GetNodes()->GetSolution(Point_Fine); for (auto iVar = 0u; iVar < nVar; iVar++) { /*--- Prevent a fine grid divergence due to a coarse grid divergence ---*/ if (Residual_Fine[iVar] != Residual_Fine[iVar]) @@ -972,26 +852,24 @@ void CMultiGridIntegration::SetForcing_Term(CSolver *sol_fine, CSolver *sol_coar const unsigned short nVar = sol_coarse->GetnVar(); const su2double factor = config->GetDamp_Res_Restric(); - auto *Residual = new su2double[nVar]; + su2activevector Residual(nVar); SU2_OMP_FOR_STAT(roundUpDiv(geo_coarse->GetnPointDomain(), omp_get_num_threads())) for (auto Point_Coarse = 0ul; Point_Coarse < geo_coarse->GetnPointDomain(); Point_Coarse++) { sol_coarse->GetNodes()->SetRes_TruncErrorZero(Point_Coarse); - for (auto iVar = 0u; iVar < nVar; iVar++) Residual[iVar] = 0.0; + Residual = su2double(0); for (auto iChildren = 0u; iChildren < geo_coarse->nodes->GetnChildren_CV(Point_Coarse); iChildren++) { auto Point_Fine = geo_coarse->nodes->GetChildren_CV(Point_Coarse, iChildren); Residual_Fine = sol_fine->LinSysRes.GetBlock(Point_Fine); for (auto iVar = 0u; iVar < nVar; iVar++) Residual[iVar] += factor * Residual_Fine[iVar]; } - sol_coarse->GetNodes()->AddRes_TruncError(Point_Coarse, Residual); + sol_coarse->GetNodes()->AddRes_TruncError(Point_Coarse, Residual.data()); } END_SU2_OMP_FOR - delete [] Residual; - for (auto iMarker = 0u; iMarker < config->GetnMarker_All(); iMarker++) { if (config->GetViscous_Wall(iMarker)) { SU2_OMP_FOR_STAT(32) diff --git a/SU2_CFD/src/interfaces/CInterface.cpp b/SU2_CFD/src/interfaces/CInterface.cpp index 293141079c49..55537c325279 100644 --- a/SU2_CFD/src/interfaces/CInterface.cpp +++ b/SU2_CFD/src/interfaces/CInterface.cpp @@ -57,6 +57,8 @@ CInterface::~CInterface() { delete[] SpanValueCoeffTarget; delete[] SpanLevelDonor; + + delete NextInterface; } void CInterface::BroadcastData(const CInterpolator& interpolator, diff --git a/SU2_CFD/src/interfaces/fsi/CFlowTractionInterface.cpp b/SU2_CFD/src/interfaces/fsi/CFlowTractionInterface.cpp index e42aabe73358..79e65a2b9614 100644 --- a/SU2_CFD/src/interfaces/fsi/CFlowTractionInterface.cpp +++ b/SU2_CFD/src/interfaces/fsi/CFlowTractionInterface.cpp @@ -158,9 +158,9 @@ void CFlowTractionInterface::GetPhysical_Constants(CSolver *flow_solution, CSolv Physical_Constants[1] = ModAmpl; /*--- For static FSI, we cannot apply the ramp like this ---*/ - if ((!flow_config->GetTime_Domain())){ + if (!flow_config->GetTime_Domain()) { Physical_Constants[1] = 1.0; - if (Ramp_Load){ + if (Ramp_Load) { CurrentTime = static_cast(struct_config->GetOuterIter()); Ramp_Time = static_cast(struct_config->GetnIterFSI_Ramp() - 1); diff --git a/SU2_CFD/src/iteration/CFluidIteration.cpp b/SU2_CFD/src/iteration/CFluidIteration.cpp index 35e2905a7c5e..55aba398ae85 100644 --- a/SU2_CFD/src/iteration/CFluidIteration.cpp +++ b/SU2_CFD/src/iteration/CFluidIteration.cpp @@ -130,9 +130,11 @@ void CFluidIteration::Iterate(COutput* output, CIntegration**** integration, CGe RUNTIME_RADIATION_SYS, val_iZone, val_iInst); } - /*--- Adapt the CFL number using an exponential progression with under-relaxation approach. ---*/ - - if ((config[val_iZone]->GetCFL_Adapt() == YES) && (!disc_adj)) { + /*--- Adapt the CFL number using an exponential progression with under-relaxation approach. + During Full-MG warmup (FinestMesh > MESH_0), skip adaptation entirely until the finest + mesh is active. ---*/ + if ((config[val_iZone]->GetCFL_Adapt() == YES) && (!disc_adj) && + (config[val_iZone]->GetFinestMesh() == MESH_0)) { SU2_OMP_PARALLEL solver[val_iZone][val_iInst][MESH_0][FLOW_SOL]->AdaptCFLNumber(geometry[val_iZone][val_iInst], solver[val_iZone][val_iInst], config[val_iZone]); @@ -245,12 +247,18 @@ bool CFluidIteration::Monitor(COutput* output, CIntegration**** integration, CGe if (config[val_iZone]->GetMUSCLRamp()) UpdateRamp(geometry, config, config[val_iZone]->GetInnerIter(), val_iZone, RAMP_TYPE::MUSCL); - output->SetHistoryOutput(geometry[val_iZone][val_iInst][MESH_0], solver[val_iZone][val_iInst][MESH_0], + /*--- During Full-MG startup FinestMesh > 0: read residuals from the active (coarse) level. ---*/ + const unsigned short finestMesh = config[val_iZone]->GetFinestMesh(); + output->SetHistoryOutput(geometry[val_iZone][val_iInst][finestMesh], solver[val_iZone][val_iInst][finestMesh], config[val_iZone], config[val_iZone]->GetTimeIter(), config[val_iZone]->GetOuterIter(), config[val_iZone]->GetInnerIter()); auto StopCalc = output->GetConvergence(); + /*--- During Full-MG warmup the convergence criterion is evaluated against coarse-mesh residuals. + * Never stop before the fine mesh is active. ---*/ + if (finestMesh != MESH_0) StopCalc = false; + /* --- Checking convergence of Fixed CL mode to target CL, and perform finite differencing if needed --*/ if (config[val_iZone]->GetFixed_CL_Mode()) { diff --git a/SU2_CFD/src/output/CElasticityOutput.cpp b/SU2_CFD/src/output/CElasticityOutput.cpp index 2694b034674d..1a78dbd25e60 100644 --- a/SU2_CFD/src/output/CElasticityOutput.cpp +++ b/SU2_CFD/src/output/CElasticityOutput.cpp @@ -107,10 +107,10 @@ void CElasticityOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CS /*--- Nonlinear analysis: UTOL, RTOL and DTOL (defined in the Postprocessing function) ---*/ if (linear_analysis){ - SetHistoryOutputValue("RMS_DISP_X", log10(fea_solver->GetRes_RMS(0))); - SetHistoryOutputValue("RMS_DISP_Y", log10(fea_solver->GetRes_RMS(1))); + SetHistoryOutputValue("RMS_DISP_X", log10(fea_solver->GetRes_FEM(0))); + SetHistoryOutputValue("RMS_DISP_Y", log10(fea_solver->GetRes_FEM(1))); if (nDim == 3){ - SetHistoryOutputValue("RMS_DISP_Z", log10(fea_solver->GetRes_RMS(2))); + SetHistoryOutputValue("RMS_DISP_Z", log10(fea_solver->GetRes_FEM(2))); } } else if (nonlinear_analysis){ SetHistoryOutputValue("RMS_UTOL", log10(fea_solver->GetRes_FEM(0))); diff --git a/SU2_CFD/src/output/filewriter/CTecplotBinaryFileWriter.cpp b/SU2_CFD/src/output/filewriter/CTecplotBinaryFileWriter.cpp index c933df314ab0..fc34b90d2fd0 100644 --- a/SU2_CFD/src/output/filewriter/CTecplotBinaryFileWriter.cpp +++ b/SU2_CFD/src/output/filewriter/CTecplotBinaryFileWriter.cpp @@ -31,6 +31,12 @@ #endif #include +#ifdef USE_SINGLE_PRECISION +#define TEC_ZONE_WRITE_VALUES tecZoneVarWriteFloatValues +#else +#define TEC_ZONE_WRITE_VALUES tecZoneVarWriteDoubleValues +#endif + const string CTecplotBinaryFileWriter::fileExt = ".szplt"; CTecplotBinaryFileWriter::CTecplotBinaryFileWriter(CParallelDataSorter *valDataSorter, @@ -279,12 +285,12 @@ void CTecplotBinaryFileWriter::WriteData(string val_filename){ for (iVar = 0; err == 0 && iVar < fieldNames.size(); iVar++) { for(unsigned long i = 0; i < dataSorter->GetnPoints(); ++i) values_to_write[i] = dataSorter->GetData(iVar, i); - err = tecZoneVarWriteDoubleValues(file_handle, zone, iVar + 1, rank + 1, dataSorter->GetnPoints(), values_to_write.data()); + err = TEC_ZONE_WRITE_VALUES(file_handle, zone, iVar + 1, rank + 1, dataSorter->GetnPoints(), values_to_write.data()); if (err) cout << rank << ": Error outputting Tecplot variable values." << endl; for (int iRank = 0; err == 0 && iRank < size; ++iRank) { if (num_nodes_to_receive[iRank] > 0) { int var_data_offset = values_to_receive_displacements[iRank] + num_nodes_to_receive[iRank] * iVar; - err = tecZoneVarWriteDoubleValues(file_handle, zone, iVar + 1, rank + 1, static_cast(num_nodes_to_receive[iRank]), &halo_var_data[var_data_offset]); + err = TEC_ZONE_WRITE_VALUES(file_handle, zone, iVar + 1, rank + 1, static_cast(num_nodes_to_receive[iRank]), &halo_var_data[var_data_offset]); if (err) cout << rank << ": Error outputting Tecplot halo values." << endl; } } @@ -306,7 +312,7 @@ void CTecplotBinaryFileWriter::WriteData(string val_filename){ values_to_write.resize(rank_num_points); for(unsigned long i = 0; i < (unsigned long)rank_num_points; ++i) values_to_write[i] = dataSorter->GetData(iVar,i); - err = tecZoneVarWriteDoubleValues(file_handle, zone, iVar + 1, 0, rank_num_points, values_to_write.data()); + err = TEC_ZONE_WRITE_VALUES(file_handle, zone, iVar + 1, 0, rank_num_points, values_to_write.data()); if (err) cout << rank << ": Error outputting Tecplot variable values." << endl; } } @@ -314,7 +320,7 @@ void CTecplotBinaryFileWriter::WriteData(string val_filename){ var_data.resize(max((int64_t)1, (int64_t)fieldNames.size() * rank_num_points)); CBaseMPIWrapper::Recv(var_data.data(), fieldNames.size() * rank_num_points, MPI_DOUBLE, iRank, iRank, SU2_MPI::GetComm(), MPI_STATUS_IGNORE); for (iVar = 0; err == 0 && iVar < fieldNames.size(); iVar++) { - err = tecZoneVarWriteDoubleValues(file_handle, zone, iVar + 1, 0, rank_num_points, &var_data[iVar * rank_num_points]); + err = TEC_ZONE_WRITE_VALUES(file_handle, zone, iVar + 1, 0, rank_num_points, &var_data[iVar * rank_num_points]); if (err) cout << rank << ": Error outputting Tecplot surface variable values." << endl; } } @@ -350,7 +356,7 @@ void CTecplotBinaryFileWriter::WriteData(string val_filename){ for (iVar = 0; err == 0 && iVar < fieldNames.size(); iVar++) { for(unsigned long i = 0; i < dataSorter->GetnPoints(); ++i) var_data.push_back(dataSorter->GetData(iVar,i)); - err = tecZoneVarWriteDoubleValues(file_handle, zone, iVar + 1, 0, dataSorter->GetnPoints(), &var_data[iVar * dataSorter->GetnPoints()]); + err = TEC_ZONE_WRITE_VALUES(file_handle, zone, iVar + 1, 0, dataSorter->GetnPoints(), &var_data[iVar * dataSorter->GetnPoints()]); if (err) cout << rank << ": Error outputting Tecplot variable value." << endl; } diff --git a/SU2_CFD/src/solvers/CDiscAdjFEASolver.cpp b/SU2_CFD/src/solvers/CDiscAdjFEASolver.cpp index 8e1a6499db50..f8e2844d3fd7 100644 --- a/SU2_CFD/src/solvers/CDiscAdjFEASolver.cpp +++ b/SU2_CFD/src/solvers/CDiscAdjFEASolver.cpp @@ -126,16 +126,31 @@ CDiscAdjFEASolver::~CDiscAdjFEASolver() { delete nodes; } void CDiscAdjFEASolver::SetRecording(CGeometry* geometry, CConfig *config){ SU2_ZONE_SCOPED - /*--- Reset the solution to the initial (converged) solution ---*/ + /*--- Under some conditions, linear elasticity problems converge in one iteration. + * This means that the "clear indices" step of the discrete adjoint solver produces a + * converged solution regardless of the primal solution given to the adjoint solver. + * We can take advantage of this for optimization to skip the primal solver. ---*/ + + const bool linear = config->GetGeometricConditions() == STRUCT_DEFORMATION::SMALL; + const bool heat = config->GetWeakly_Coupled_Heat(); + const bool time_domain = config->GetTime_Domain(); + const bool keep_solution = linear && !heat && !time_domain && !std::is_same_v; + + /*--- Restore the solution to the initial (converged) solution or reset AD indices. ---*/ for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { - for (auto iVar = 0u; iVar < nVar; iVar++) - direct_solver->GetNodes()->SetSolution(iPoint, iVar, nodes->GetSolution_Direct(iPoint)[iVar]); + if (keep_solution) { + for (auto iVar = 0u; iVar < nVar; iVar++) + AD::ResetInput(direct_solver->GetNodes()->GetSolution(iPoint)[iVar]); + } else { + for (auto iVar = 0u; iVar < nVar; iVar++) + direct_solver->GetNodes()->SetSolution(iPoint, iVar, nodes->GetSolution_Direct(iPoint)[iVar]); + } } /*--- Reset the input for time n ---*/ - if (config->GetTime_Domain()) { + if (time_domain) { for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) for (auto iVar = 0u; iVar < nVar; iVar++) AD::ResetInput(direct_solver->GetNodes()->GetSolution_time_n(iPoint)[iVar]); diff --git a/SU2_CFD/src/solvers/CEulerSolver.cpp b/SU2_CFD/src/solvers/CEulerSolver.cpp index c58f96c3e4ef..e5737ceebb10 100644 --- a/SU2_CFD/src/solvers/CEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CEulerSolver.cpp @@ -1073,10 +1073,10 @@ void CEulerSolver::SetNondimensionalization(CConfig *config, unsigned short iMes Tke_FreeStreamND = 3.0/2.0*(ModVel_FreeStreamND*ModVel_FreeStreamND*config->GetTurbulenceIntensity_FreeStream()*config->GetTurbulenceIntensity_FreeStream()); config->SetTke_FreeStreamND(Tke_FreeStreamND); - Omega_FreeStream = Density_FreeStream*Tke_FreeStream/(Viscosity_FreeStream*config->GetTurb2LamViscRatio_FreeStream()); + Omega_FreeStream = Density_FreeStream*Tke_FreeStream/max(Viscosity_FreeStream*config->GetTurb2LamViscRatio_FreeStream(), EPS); config->SetOmega_FreeStream(Omega_FreeStream); - Omega_FreeStreamND = Density_FreeStreamND*Tke_FreeStreamND/(Viscosity_FreeStreamND*config->GetTurb2LamViscRatio_FreeStream()); + Omega_FreeStreamND = Density_FreeStreamND*Tke_FreeStreamND/max(Viscosity_FreeStreamND*config->GetTurb2LamViscRatio_FreeStream(), EPS); config->SetOmega_FreeStreamND(Omega_FreeStreamND); if (config->GetTurbulenceIntensity_FreeStream() *100 <= 1.3) { diff --git a/SU2_CFD/src/solvers/CFEASolver.cpp b/SU2_CFD/src/solvers/CFEASolver.cpp index e12f92140a4a..31cb41c52d93 100644 --- a/SU2_CFD/src/solvers/CFEASolver.cpp +++ b/SU2_CFD/src/solvers/CFEASolver.cpp @@ -1833,14 +1833,13 @@ void CFEASolver::Postprocessing(CGeometry *geometry, CConfig *config, CNumerics /*--- RTOL = norm(Residual(k): ABSOLUTE, norm of the residual (T-F) ---*/ /*--- ETOL = Delta_U(k) * Residual(k): ABSOLUTE, energy norm ---*/ - SU2_OMP_PARALLEL - { + SU2_OMP_PARALLEL { + su2double utol = LinSysSol.norm(); su2double rtol = LinSysRes.norm(); su2double etol = fabs(LinSysSol.dot(LinSysRes)); - SU2_OMP_MASTER - { + SU2_OMP_MASTER { Conv_Check[0] = utol; Conv_Check[1] = rtol; Conv_Check[2] = etol; @@ -1872,8 +1871,14 @@ void CFEASolver::Postprocessing(CGeometry *geometry, CConfig *config, CNumerics END_SU2_OMP_FOR /*--- "Add" residuals from all threads to global residual variables. ---*/ - ResidualReductions_FromAllThreads(geometry, config, resRMS,resMax,idxMax); + ResidualReductions_FromAllThreads(geometry, config, resRMS, resMax, idxMax); + SU2_OMP_MASTER { + Conv_Check[0] = Residual_RMS[0]; + Conv_Check[1] = Residual_RMS[1]; + Conv_Check[2] = nDim == 3 ? Residual_RMS[2] : 0; + } + END_SU2_OMP_MASTER } END_SU2_OMP_PARALLEL diff --git a/SU2_CFD/src/solvers/CFEM_DG_EulerSolver.cpp b/SU2_CFD/src/solvers/CFEM_DG_EulerSolver.cpp index b7870f2e64d6..f5177b953534 100644 --- a/SU2_CFD/src/solvers/CFEM_DG_EulerSolver.cpp +++ b/SU2_CFD/src/solvers/CFEM_DG_EulerSolver.cpp @@ -1081,10 +1081,10 @@ void CFEM_DG_EulerSolver::SetNondimensionalization(CConfig *config, Tke_FreeStreamND = 3.0/2.0*(ModVel_FreeStreamND*ModVel_FreeStreamND*config->GetTurbulenceIntensity_FreeStream()*config->GetTurbulenceIntensity_FreeStream()); config->SetTke_FreeStreamND(Tke_FreeStreamND); - Omega_FreeStream = Density_FreeStream*Tke_FreeStream/max((Viscosity_FreeStream*config->GetTurb2LamViscRatio_FreeStream()), 1.e-25); + Omega_FreeStream = Density_FreeStream*Tke_FreeStream/max(Viscosity_FreeStream*config->GetTurb2LamViscRatio_FreeStream(), EPS); config->SetOmega_FreeStream(Omega_FreeStream); - Omega_FreeStreamND = Density_FreeStreamND*Tke_FreeStreamND/max((Viscosity_FreeStreamND*config->GetTurb2LamViscRatio_FreeStream()), 1.e-25); + Omega_FreeStreamND = Density_FreeStreamND*Tke_FreeStreamND/max(Viscosity_FreeStreamND*config->GetTurb2LamViscRatio_FreeStream(), EPS); config->SetOmega_FreeStreamND(Omega_FreeStreamND); /*--- Initialize the dimensionless Fluid Model that will be used to solve the dimensionless problem ---*/ diff --git a/SU2_CFD/src/solvers/CHeatSolver.cpp b/SU2_CFD/src/solvers/CHeatSolver.cpp index 5e9b0b437c27..52b591770ca2 100644 --- a/SU2_CFD/src/solvers/CHeatSolver.cpp +++ b/SU2_CFD/src/solvers/CHeatSolver.cpp @@ -257,6 +257,7 @@ void CHeatSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig * solver[MESH_0][HEAT_SOL]->InitiateComms(geometry[MESH_0], config, MPI_QUANTITIES::SOLUTION); solver[MESH_0][HEAT_SOL]->CompleteComms(geometry[MESH_0], config, MPI_QUANTITIES::SOLUTION); + SU2_OMP_SAFE_GLOBAL_ACCESS(config->SetGlobalParam(MAIN_SOLVER::HEAT_EQUATION, RUNTIME_HEAT_SYS);) solver[MESH_0][HEAT_SOL]->Preprocessing(geometry[MESH_0], solver[MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_HEAT_SYS, false); /*--- Interpolate the solution down to the coarse multigrid levels ---*/ diff --git a/SU2_CFD/src/solvers/CIncEulerSolver.cpp b/SU2_CFD/src/solvers/CIncEulerSolver.cpp index 1cb4a1951bdb..f138422f7ea5 100644 --- a/SU2_CFD/src/solvers/CIncEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CIncEulerSolver.cpp @@ -463,10 +463,10 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i Tke_FreeStreamND = 3.0/2.0*(ModVel_FreeStreamND*ModVel_FreeStreamND*config->GetTurbulenceIntensity_FreeStream()*config->GetTurbulenceIntensity_FreeStream()); config->SetTke_FreeStreamND(Tke_FreeStreamND); - Omega_FreeStream = Density_FreeStream*Tke_FreeStream/(Viscosity_FreeStream*config->GetTurb2LamViscRatio_FreeStream()); + Omega_FreeStream = Density_FreeStream*Tke_FreeStream/max(Viscosity_FreeStream*config->GetTurb2LamViscRatio_FreeStream(), EPS); config->SetOmega_FreeStream(Omega_FreeStream); - Omega_FreeStreamND = Density_FreeStreamND*Tke_FreeStreamND/(Viscosity_FreeStreamND*config->GetTurb2LamViscRatio_FreeStream()); + Omega_FreeStreamND = Density_FreeStreamND*Tke_FreeStreamND/max(Viscosity_FreeStreamND*config->GetTurb2LamViscRatio_FreeStream(), EPS); config->SetOmega_FreeStreamND(Omega_FreeStreamND); const su2double MassDiffusivityND = config->GetDiffusivity_Constant() / (Velocity_Ref * Length_Ref); @@ -1183,7 +1183,7 @@ void CIncEulerSolver::Centered_Residual(CGeometry *geometry, CSolver **solver_co if (LD2_Scheme) { numerics->SetPrimVarGradient(nodes->GetGradient_Primitive(iPoint), nodes->GetGradient_Primitive(jPoint)); - if (!geometry->nodes->GetPeriodicBoundary(iPoint) || (geometry->nodes->GetPeriodicBoundary(iPoint) + if (!geometry->nodes->GetPeriodicBoundary(iPoint) || (geometry->nodes->GetPeriodicBoundary(iPoint) && !geometry->nodes->GetPeriodicBoundary(jPoint))) { numerics->SetCoord(geometry->nodes->GetCoord(iPoint), geometry->nodes->GetCoord(jPoint)); } else { @@ -2535,11 +2535,19 @@ void CIncEulerSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, if (species_model) scalar_inlet = config->GetInlet_SpeciesVal(config->GetMarker_All_TagBound(val_marker)); CFluidModel* auxFluidModel = solver_container[FLOW_SOL]->GetFluidModel(); auxFluidModel->SetTDState_T(V_inlet[prim_idx.Temperature()], scalar_inlet); - V_inlet[prim_idx.Enthalpy()] = auxFluidModel->GetEnthalpy(); + + /*--- For the flamelet model with FLOW_MARKERS enthalpy BC, we obtain the inlet enthalpy + from the flamelet species solver With SPECIES_MARKERS, the enthalpy in MARKER_INLET_SPECIES + is used directly. ---*/ + if (config->GetKind_Species_Model() == SPECIES_MODEL::FLAMELET && + config->GetFlamelet_Enthalpy_BC() == FLAMELET_ENTHALPY_BC::FLOW_MARKERS) + V_inlet[prim_idx.Enthalpy()] = nodes->GetEnthalpy(iPoint); + else + V_inlet[prim_idx.Enthalpy()] = auxFluidModel->GetEnthalpy(); /*--- Access density at the node. This is either constant by - construction, or will be set fixed implicitly by the temperature - and equation of state. ---*/ + construction, or will be set fixed implicitly by the temperature + and equation of state. ---*/ V_inlet[prim_idx.Density()] = nodes->GetDensity(iPoint); diff --git a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp index b86a31b3ba7a..1f3090a67cce 100644 --- a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp @@ -1208,10 +1208,10 @@ void CNEMOEulerSolver::SetNondimensionalization(CConfig *config, unsigned short Tke_FreeStreamND = 3.0/2.0*(ModVel_FreeStreamND*ModVel_FreeStreamND*config->GetTurbulenceIntensity_FreeStream()*config->GetTurbulenceIntensity_FreeStream()); config->SetTke_FreeStreamND(Tke_FreeStreamND); - Omega_FreeStream = Density_FreeStream*Tke_FreeStream/(Viscosity_FreeStream*config->GetTurb2LamViscRatio_FreeStream()); + Omega_FreeStream = Density_FreeStream*Tke_FreeStream/max(Viscosity_FreeStream*config->GetTurb2LamViscRatio_FreeStream(), EPS); config->SetOmega_FreeStream(Omega_FreeStream); - Omega_FreeStreamND = Density_FreeStreamND*Tke_FreeStreamND/(Viscosity_FreeStreamND*config->GetTurb2LamViscRatio_FreeStream()); + Omega_FreeStreamND = Density_FreeStreamND*Tke_FreeStreamND/max(Viscosity_FreeStreamND*config->GetTurb2LamViscRatio_FreeStream(), EPS); config->SetOmega_FreeStreamND(Omega_FreeStreamND); /*--- Initialize the dimensionless Fluid Model that will be used to solve the dimensionless problem ---*/ diff --git a/SU2_CFD/src/solvers/CSolver.cpp b/SU2_CFD/src/solvers/CSolver.cpp index aedacdb90593..36a7d2283f0f 100644 --- a/SU2_CFD/src/solvers/CSolver.cpp +++ b/SU2_CFD/src/solvers/CSolver.cpp @@ -89,7 +89,7 @@ CSolver::CSolver(LINEAR_SOLVER_MODE linear_solver_mode) : System(linear_solver_m Jacobian_jj = nullptr; base_nodes = nullptr; nOutputVariables = 0; - ResLinSolver = 0.0; + ResLinSolver = EPS; /*--- Variable initialization to avoid valgrid warnings when not used. ---*/ @@ -1986,7 +1986,7 @@ void CSolver::AdaptCFLNumber(CGeometry **geometry, void CSolver::SetResidual_RMS(const CGeometry *geometry, const CConfig *config) { SU2_ZONE_SCOPED - if (geometry->GetMGLevel() != MESH_0) return; + if (geometry->GetMGLevel() != MESH_0 && !config->GetMGOptions().MG_Smooth_EarlyExit) return; BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { diff --git a/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp b/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp index 10fb3c49ddb4..8f518e2d9490 100644 --- a/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp +++ b/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp @@ -231,8 +231,9 @@ void CSpeciesFlameletSolver::SetInitialCondition(CGeometry** geometry, CSolver** if (flame_front_ignition) prog_burnt = GetBurntProgressVariable(fluid_model_local, scalar_init, flamelet_config_options.Flame_T_ignition); prog_unburnt = config->GetSpecies_Init()[I_PROGVAR]; + const auto nPoint_iMesh = geometry[i_mesh]->GetnPoint(); SU2_OMP_FOR_STAT(omp_chunk_size) - for (unsigned long i_point = 0; i_point < nPoint; i_point++) { + for (unsigned long i_point = 0; i_point < nPoint_iMesh; i_point++) { auto coords = geometry[i_mesh]->nodes->GetCoord(i_point); if (flame_front_ignition) { @@ -395,11 +396,28 @@ void CSpeciesFlameletSolver::Source_Residual(CGeometry* geometry, CSolver** solv CNumerics** numerics_container, CConfig* config, unsigned short iMesh) { SU2_ZONE_SCOPED + const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); + const auto n_CV = flamelet_config_options.n_control_vars; + const auto n_aux = flamelet_config_options.n_user_scalars; + const auto* fn = static_cast(nodes); + SU2_OMP_FOR_STAT(omp_chunk_size) for (auto i_point = 0u; i_point < nPointDomain; i_point++) { + const su2double volume = geometry->nodes->GetVolume(i_point); + /*--- Add source terms from the lookup table directly to the residual. ---*/ for (auto i_var = 0; i_var < nVar; i_var++) { - LinSysRes(i_point, i_var) -= nodes->GetScalarSources(i_point)[i_var] * geometry->nodes->GetVolume(i_point); + LinSysRes(i_point, i_var) -= nodes->GetScalarSources(i_point)[i_var] * volume; + } + + /*--- Implicit: analytic Jacobian for auxiliary species from the split source form. + * S_aux_i = source_prod_i + source_cons_i * Y_aux_i + * dS_aux_i/dY_aux_i = source_cons_i + * J_ii += -source_cons_i * V ---*/ + if (implicit) { + for (auto i_aux = 0u; i_aux < n_aux; i_aux++) { + Jacobian.AddVal2Diag(i_point, n_CV + i_aux, -fn->GetAuxSourceCons(i_point, i_aux) * volume); + } } } END_SU2_OMP_FOR @@ -409,17 +427,66 @@ void CSpeciesFlameletSolver::Source_Residual(CGeometry* geometry, CSolver** solv } +void CSpeciesFlameletSolver::BC_HeatFlux_Wall(CGeometry* geometry, CSolver** solver_container, + CNumerics* conv_numerics, CNumerics* visc_numerics, + CConfig* config, unsigned short val_marker) { + SU2_ZONE_SCOPED + + /*--- In FLOW_MARKERS mode: read MARKER_HEATFLUX. + In SPECIES_MARKERS mode: read flux/value from MARKER_WALL_SPECIES. ---*/ + + if (config->GetFlamelet_Enthalpy_BC() != FLAMELET_ENTHALPY_BC::FLOW_MARKERS) { + CSpeciesSolver::BC_HeatFlux_Wall(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); + return; + } + + const string Marker_Tag = config->GetMarker_All_TagBound(val_marker); + const bool py_custom = config->GetMarker_All_PyCustom(val_marker); + + su2double Wall_HeatFlux = config->GetWall_HeatFlux(Marker_Tag); + /*--- Integrated heat flux requires area normalization only when using the config value. + When py_custom is active the per-vertex flux density is set directly by the Python wrapper. ---*/ + if (config->GetIntegrated_HeatFlux() && !py_custom) + Wall_HeatFlux /= geometry->GetSurfaceArea(config, val_marker); + + SU2_OMP_FOR_DYN(OMP_MIN_SIZE) + for (auto iVertex = 0ul; iVertex < geometry->nVertex[val_marker]; iVertex++) { + const auto iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); + if (!geometry->nodes->GetDomain(iPoint)) continue; + + const auto Normal = geometry->vertex[val_marker][iVertex]->GetNormal(); + const su2double Area = GeometryToolbox::Norm(nDim, Normal); + + /*--- Override with the per-vertex value set by driver.SetMarkerCustomNormalHeatFlux(). ---*/ + if (py_custom) + Wall_HeatFlux = geometry->GetCustomBoundaryHeatFlux(val_marker, iVertex); + + /*--- Neumann condition: q_wall is the prescribed heat flux (W/m^2, positive into domain). + This adds a source term dH/dn * lambda = q_wall to the enthalpy residual. ---*/ + LinSysRes(iPoint, I_ENTH) -= Wall_HeatFlux * Area; + } + END_SU2_OMP_FOR +} + void CSpeciesFlameletSolver::BC_Inlet(CGeometry* geometry, CSolver** solver_container, CNumerics* conv_numerics, CNumerics* visc_numerics, CConfig* config, unsigned short val_marker) { SU2_ZONE_SCOPED string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - su2double temp_inlet = config->GetInletTtotal(Marker_Tag); - - /*--- We compute inlet enthalpy from the temperature and progress variable. ---*/ su2double enth_inlet; - GetEnthFromTemp(solver_container[FLOW_SOL]->GetFluidModel(), temp_inlet, config->GetInlet_SpeciesVal(Marker_Tag), - &enth_inlet); + if (config->GetFlamelet_Enthalpy_BC() == FLAMELET_ENTHALPY_BC::FLOW_MARKERS) { + /*--- Derive inlet enthalpy from MARKER_INLET temperature via Newton iteration on the LUT. + This ensures the enthalpy is thermodynamically consistent with the prescribed temperature, + regardless of the value given in MARKER_INLET_SPECIES. ---*/ + su2double temp_inlet = config->GetInletTtotal(Marker_Tag); + GetEnthFromTemp(solver_container[FLOW_SOL]->GetFluidModel(), temp_inlet, + config->GetInlet_SpeciesVal(Marker_Tag), &enth_inlet); + } else { + /*--- Use the enthalpy value directly from MARKER_INLET_SPECIES (default). + The user is responsible for providing a thermodynamically consistent value. ---*/ + enth_inlet = config->GetInlet_SpeciesVal(Marker_Tag)[I_ENTH]; + } + SU2_OMP_FOR_STAT(OMP_MIN_SIZE) for (auto iVertex = 0u; iVertex < geometry->nVertex[val_marker]; iVertex++) { Inlet_SpeciesVars[val_marker][iVertex][I_ENTH] = enth_inlet; @@ -519,6 +586,17 @@ void CSpeciesFlameletSolver::BC_Isothermal_Wall(CGeometry* geometry, CSolver** s CNumerics* conv_numerics, CNumerics* visc_numerics, CConfig* config, unsigned short val_marker) { SU2_ZONE_SCOPED + + /*--- In FLOW_MARKERS mode: temperature comes from MARKER_ISOTHERMAL and is + converted to enthalpy via GetEnthFromTemp (thermodynamically consistent). + In SPECIES_MARKERS mode: enthalpy is taken directly from MARKER_WALL_SPECIES, + handled by the base class BC_Wall_Generic. ---*/ + + if (config->GetFlamelet_Enthalpy_BC() != FLAMELET_ENTHALPY_BC::FLOW_MARKERS) { + CSpeciesSolver::BC_Isothermal_Wall(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); + return; + } + BC_Isothermal_Wall_Generic(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); } @@ -539,7 +617,7 @@ unsigned long CSpeciesFlameletSolver::SetScalarSources(const CConfig* config, CF table_sources[I_PROGVAR] = fmax(0, table_sources[I_PROGVAR]); nodes->SetTableMisses(iPoint, misses); - /*--- The source term for progress variable is always positive, we clip from below to makes sure. --- */ + /*--- The source term for progress variable is always positive, we clip from below to make sure. --- */ vector source_scalar(flamelet_config_options.n_scalars); for (auto iCV = 0u; iCV < flamelet_config_options.n_control_vars; iCV++) source_scalar[iCV] = table_sources[iCV]; @@ -552,6 +630,8 @@ unsigned long CSpeciesFlameletSolver::SetScalarSources(const CConfig* config, CF su2double source_prod = table_sources[flamelet_config_options.n_control_vars + 2 * i_aux]; su2double source_cons = table_sources[flamelet_config_options.n_control_vars + 2 * i_aux + 1]; source_scalar[flamelet_config_options.n_control_vars + i_aux] = source_prod + source_cons * y_aux; + /*--- Store the analytic Jacobian dS_aux/dY_aux = source_cons for implicit treatment. ---*/ + static_cast(nodes)->SetAuxSourceCons(iPoint, i_aux, source_cons); } for (auto i_scalar = 0u; i_scalar < nVar; i_scalar++) nodes->SetScalarSource(iPoint, i_scalar, source_scalar[i_scalar]); diff --git a/SU2_CFD/src/solvers/CTurbSASolver.cpp b/SU2_CFD/src/solvers/CTurbSASolver.cpp index fb8d2bf5d484..7bc05787be17 100644 --- a/SU2_CFD/src/solvers/CTurbSASolver.cpp +++ b/SU2_CFD/src/solvers/CTurbSASolver.cpp @@ -506,12 +506,11 @@ void CTurbSASolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_conta } const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); - bool rough_wall = false; string Marker_Tag = config->GetMarker_All_TagBound(val_marker); WALL_TYPE WallType; su2double Roughness_Height; tie(WallType, Roughness_Height) = config->GetWallRoughnessProperties(Marker_Tag); - if (WallType == WALL_TYPE::ROUGH) rough_wall = true; + Roughness_Height = max(Roughness_Height, EPS); /*--- The dirichlet condition is used only without wall function, otherwise the convergence is compromised as we are providing nu tilde values for the @@ -524,47 +523,46 @@ void CTurbSASolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_conta /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ - if (geometry->nodes->GetDomain(iPoint)) { - if (!rough_wall) { - for (auto iVar = 0u; iVar < nVar; iVar++) - nodes->SetSolution_Old(iPoint,iVar,0.0); + if (!geometry->nodes->GetDomain(iPoint)) continue; - LinSysRes.SetBlock_Zero(iPoint); + if (WallType == WALL_TYPE::SMOOTH) { + for (auto iVar = 0u; iVar < nVar; iVar++) + nodes->SetSolution_Old(iPoint,iVar,0.0); - /*--- Includes 1 in the diagonal ---*/ + LinSysRes.SetBlock_Zero(iPoint); - if (implicit) Jacobian.DeleteValsRowi(iPoint, 0); - } else { - /*--- For rough walls, the boundary condition is given by - * (\frac{\partial \nu}{\partial n})_wall = \frac{\nu}{0.03*k_s} - * where \nu is the solution variable, $n$ is the wall normal direction - * and k_s is the equivalent sand grain roughness specified. ---*/ + /*--- Includes 1 in the diagonal ---*/ - /*--- Compute dual-grid area and boundary normal ---*/ - su2double Normal[MAXNDIM] = {0.0}; - for (auto iDim = 0u; iDim < nDim; iDim++) - Normal[iDim] = -geometry->vertex[val_marker][iVertex]->GetNormal(iDim); + if (implicit) Jacobian.DeleteValsRowi(iPoint, 0); + continue; + } - su2double Area = GeometryToolbox::Norm(nDim, Normal); + /*--- For rough walls, the boundary condition is given by + * (\frac{\partial \nu}{\partial n})_wall = \frac{\nu}{0.03*k_s} + * where \nu is the solution variable, $n$ is the wall normal direction + * and k_s is the equivalent sand grain roughness specified. ---*/ + + /*--- Compute dual-grid area and boundary normal ---*/ + su2double Normal[MAXNDIM] = {0.0}; + for (auto iDim = 0u; iDim < nDim; iDim++) + Normal[iDim] = -geometry->vertex[val_marker][iVertex]->GetNormal(iDim); - /*--- Get laminar_viscosity and density ---*/ - su2double sigma = 2.0/3.0; - su2double laminar_viscosity = solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); - su2double density = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + su2double Area = GeometryToolbox::Norm(nDim, Normal); - su2double nu_total = (laminar_viscosity/density + nodes->GetSolution(iPoint,0)); + /*--- Get laminar_viscosity and density ---*/ + su2double sigma = 2.0/3.0; + su2double laminar_viscosity = solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); + su2double density = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + su2double nu_lam = laminar_viscosity / density; - su2double coeff = (nu_total/sigma); - su2double RoughWallBC = nodes->GetSolution(iPoint,0)/(0.03*Roughness_Height); + su2double denom = sigma * 0.03 * Roughness_Height; + su2double coeff = (nu_lam + nodes->GetSolution(iPoint,0)) / denom; - su2double Res_Wall = coeff*RoughWallBC*Area; - LinSysRes(iPoint, 0) -= Res_Wall; + su2double Res_Wall = Area * coeff * nodes->GetSolution(iPoint,0); + LinSysRes(iPoint, 0) -= Res_Wall; - Jacobian_i[0][0] = (laminar_viscosity /density *Area)/(0.03*Roughness_Height*sigma); - Jacobian_i[0][0] += 2.0*RoughWallBC*Area/sigma; - if (implicit) Jacobian.AddVal2Diag(iPoint, 0, -Jacobian_i[0][0]); - } - } + su2double Jac_Wall = Area * (coeff + nodes->GetSolution(iPoint,0) / denom); + if (implicit) Jacobian.AddVal2Diag(iPoint, 0, -Jac_Wall); } END_SU2_OMP_FOR } diff --git a/SU2_CFD/src/variables/CSpeciesFlameletVariable.cpp b/SU2_CFD/src/variables/CSpeciesFlameletVariable.cpp index d5d2f50419bd..a981655b39af 100644 --- a/SU2_CFD/src/variables/CSpeciesFlameletVariable.cpp +++ b/SU2_CFD/src/variables/CSpeciesFlameletVariable.cpp @@ -53,6 +53,7 @@ CSpeciesFlameletVariable::CSpeciesFlameletVariable(const su2double* species_inf, source_scalar.resize(nPoint, flamelet_config_options.n_scalars) = su2double(0.0); lookup_scalar.resize(nPoint, flamelet_config_options.n_lookups) = su2double(0.0); table_misses.resize(nPoint) = 0; + source_cons_jac.resize(nPoint, flamelet_config_options.n_user_scalars) = su2double(0.0); if (flamelet_config_options.preferential_diffusion) { AuxVar.resize(nPoint, FLAMELET_PREF_DIFF_SCALARS::N_BETA_TERMS) = su2double(0.0); diff --git a/TestCases/cont_adj_euler/naca0012/of_grad_cd_disc.dat.ref b/TestCases/cont_adj_euler/naca0012/of_grad_cd_disc.dat.ref index f7e509e5e3cb..6f26c9c89c31 100644 --- a/TestCases/cont_adj_euler/naca0012/of_grad_cd_disc.dat.ref +++ b/TestCases/cont_adj_euler/naca0012/of_grad_cd_disc.dat.ref @@ -1,39 +1,39 @@ VARIABLES="VARIABLE" , "GRADIENT" , "FINDIFF_STEP" - 0 , -7747.74 , 0.001 - 1 , -10948.1 , 0.001 - 2 , -8280.46 , 0.001 - 3 , -3802.21 , 0.001 - 4 , 658.085 , 0.001 - 5 , 4392.72 , 0.001 - 6 , 7268.92 , 0.001 - 7 , 9422.0 , 0.001 - 8 , 11077.6 , 0.001 - 9 , 12447.2 , 0.001 - 10 , 13660.8 , 0.001 - 11 , 14713.0 , 0.001 - 12 , 15397.1 , 0.001 - 13 , 15179.4 , 0.001 - 14 , 12887.9 , 0.001 - 15 , 5922.05 , 0.001 - 16 , -11571.8 , 0.001 - 17 , -51702.7 , 0.001 - 18 , -126889.0 , 0.001 - 19 , -21493.4 , 0.001 - 20 , -22571.2 , 0.001 - 21 , -16492.2 , 0.001 - 22 , -10533.8 , 0.001 - 23 , -6901.19 , 0.001 - 24 , -5763.06 , 0.001 - 25 , -6449.91 , 0.001 - 26 , -8061.2 , 0.001 - 27 , -9790.18 , 0.001 - 28 , -11077.2 , 0.001 - 29 , -11650.8 , 0.001 - 30 , -11500.7 , 0.001 - 31 , -10793.0 , 0.001 - 32 , -9652.1 , 0.001 - 33 , -7555.2 , 0.001 - 34 , -2031.11 , 0.001 - 35 , 12735.8 , 0.001 - 36 , 43905.7 , 0.001 - 37 , 85428.3 , 0.001 + 0 , -9031.62 , 0.001 + 1 , -12012.1 , 0.001 + 2 , -9069.4 , 0.001 + 3 , -4384.1 , 0.001 + 4 , 226.313 , 0.001 + 5 , 4094.64 , 0.001 + 6 , 7135.57 , 0.001 + 7 , 9534.04 , 0.001 + 8 , 11567.7 , 0.001 + 9 , 13502.9 , 0.001 + 10 , 15525.3 , 0.001 + 11 , 17677.6 , 0.001 + 12 , 19774.0 , 0.001 + 13 , 21231.7 , 0.001 + 14 , 20667.9 , 0.001 + 15 , 14910.9 , 0.001 + 16 , -3204.93 , 0.001 + 17 , -47800.8 , 0.001 + 18 , -127342.0 , 0.001 + 19 , -22401.2 , 0.001 + 20 , -22469.9 , 0.001 + 21 , -15796.2 , 0.001 + 22 , -9601.62 , 0.001 + 23 , -5984.92 , 0.001 + 24 , -5040.23 , 0.001 + 25 , -6061.17 , 0.001 + 26 , -8142.27 , 0.001 + 27 , -10495.3 , 0.001 + 28 , -12591.9 , 0.001 + 29 , -14189.4 , 0.001 + 30 , -15280.9 , 0.001 + 31 , -15978.6 , 0.001 + 32 , -16253.9 , 0.001 + 33 , -15289.0 , 0.001 + 34 , -10118.9 , 0.001 + 35 , 5881.72 , 0.001 + 36 , 40595.3 , 0.001 + 37 , 83547.0 , 0.001 diff --git a/TestCases/cont_adj_euler/naca0012/of_grad_directdiff.dat.ref b/TestCases/cont_adj_euler/naca0012/of_grad_directdiff.dat.ref index 0218e98d3169..54b93ba1a831 100644 --- a/TestCases/cont_adj_euler/naca0012/of_grad_directdiff.dat.ref +++ b/TestCases/cont_adj_euler/naca0012/of_grad_directdiff.dat.ref @@ -1,4 +1,4 @@ VARIABLES="VARIABLE" , "DRAG" , "EFFICIENCY" , "FORCE_X" , "FORCE_Y" , "FORCE_Z" , "LIFT" , "MOMENT_X" , "MOMENT_Y" , "MOMENT_Z" , "SIDEFORCE" - 0 , 0.05240962543 , -27.33945591 , 0.08647516198 , -1.560629715 , 0.0 , -1.562144773 , 0.0 , 0.0 , 0.8858124377 , 0.0 - 1 , 0.2008795877 , -41.40890891 , 0.2463424389 , -2.081341632 , 0.0 , -2.086220261 , 0.0 , 0.0 , 0.737429107 , 0.0 - 2 , 0.371975273 , -55.04424867 , 0.4271103196 , -2.522745633 , 0.0 , -2.531462651 , 0.0 , 0.0 , 0.4069664819 , 0.0 + 0 , 0.3283027921 , -23.00124324 , 0.3601048051 , -1.453884254 , 0.0 , -1.461393914 , 0.0 , 0.0 , 0.3837075086 , 0.0 + 1 , 0.5529850442 , -38.57543344 , 0.6062515142 , -2.435135388 , 0.0 , -2.447781199 , 0.0 , 0.0 , 0.1364160306 , 0.0 + 2 , 0.7825703473 , -46.16887385 , 0.8428457563 , -2.753846031 , 0.0 , -2.771577273 , 0.0 , 0.0 , -0.1507632792 , 0.0 diff --git a/TestCases/cont_adj_euler/wedge/of_grad_combo.dat.ref b/TestCases/cont_adj_euler/wedge/of_grad_combo.dat.ref index 88d7794ce033..17f951cf4f58 100644 --- a/TestCases/cont_adj_euler/wedge/of_grad_combo.dat.ref +++ b/TestCases/cont_adj_euler/wedge/of_grad_combo.dat.ref @@ -1,5 +1,5 @@ -VARIABLES="VARIABLE" , "GRADIENT" , "FINDIFF_STEP" - 0 , 0.00701137 , 0.0001 - 1 , 0.00485473 , 0.0001 - 2 , 0.00244467 , 0.0001 - 3 , 0.000872557 , 0.0001 +VARIABLES="VARIABLE" , "GRADIENT" , "FINDIFF_STEP" + 0 , 0.00701908 , 0.0001 + 1 , 0.00485645 , 0.0001 + 2 , 0.002445 , 0.0001 + 3 , 0.000872591 , 0.0001 diff --git a/TestCases/fea_fsi/stat_fsi/config.cfg b/TestCases/fea_fsi/stat_fsi/config.cfg index 029d94ef928c..5faa20853f84 100755 --- a/TestCases/fea_fsi/stat_fsi/config.cfg +++ b/TestCases/fea_fsi/stat_fsi/config.cfg @@ -1,24 +1,32 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % % SU2 configuration file % -% Case description: Fluid structure interaction - Beam in channel - 2D - FEM % -% Author: R.Sanchez % -% Institution: Imperial College London % -% % +% Case description: Aero-thermo-elasticity % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% FSI settings SOLVER= MULTIPHYSICS +MULTIZONE_SOLVER= BLOCK_GAUSS_SEIDEL +RAMP_LOADING= YES +RAMP_FSI_ITER= 5 +BGS_RELAXATION= FIXED_PARAMETER +STAT_RELAX_PARAMETER= 0.9 -CONFIG_LIST = (configFlow.cfg, configFEA.cfg) +CONFIG_LIST= ( configFlow.cfg, configFEA.cfg ) -MULTIZONE_SOLVER = BLOCK_GAUSS_SEIDEL +MARKER_ZONE_INTERFACE= ( wallF, wallS ) -MARKER_ZONE_INTERFACE = (wallF, wallS) +SCREEN_OUTPUT= \ + OUTER_ITER, INNER_ITER[0], AVG_BGS_RES[0], AVG_BGS_RES[1],\ + RMS_DENSITY[0], RMS_UTOL[1], RMS_TEMPERATURE[1], VMS[1],\ + TOTAL_HEATFLUX[1], DEFORM_MIN_VOLUME[0], DEFORM_ITER[0] -MULTIZONE_MESH = NO -SCREEN_OUTPUT=(OUTER_ITER, BGS_DENSITY[0], AVG_BGS_RES[1], DEFORM_MIN_VOLUME[0], DEFORM_ITER[0]) RESTART_SOL= NO -RESTART_ITER = 0 +RESTART_ITER= 0 + +OUTER_ITER= 30 +CONV_RESIDUAL_MINVAL= -5 + +MULTIZONE_MESH= NO +WRT_ZONE_CONV= NO +OUTPUT_WRT_FREQ= 100 -TIME_DOMAIN = NO -OUTER_ITER = 8 diff --git a/TestCases/fea_fsi/stat_fsi/configFEA.cfg b/TestCases/fea_fsi/stat_fsi/configFEA.cfg index 07c2a748f956..a0430a07e717 100755 --- a/TestCases/fea_fsi/stat_fsi/configFEA.cfg +++ b/TestCases/fea_fsi/stat_fsi/configFEA.cfg @@ -1,82 +1,63 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % % SU2 configuration file % -% Case description: Fluid structure interaction - Beam in channel - 2D - FEM % -% Author: R.Sanchez % -% Institution: TU Kaiserslautern % -% % +% Case description: Aero-thermo-elasticity % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% -% +% Nonlinear thermoelasticity SOLVER= ELASTICITY -MATH_PROBLEM= DIRECT - -% ------------------------ PARAMETERS FEM SOLVER ------------------------------% - GEOMETRIC_CONDITIONS= LARGE_DEFORMATIONS MATERIAL_MODEL= NEO_HOOKEAN MATERIAL_COMPRESSIBILITY= COMPRESSIBLE -NONLINEAR_FEM_SOLUTION_METHOD = NEWTON_RAPHSON -INNER_ITER = 10 - -INCREMENTAL_LOAD = NO - -% --------------------------- TIME STEP ISSUES --------------------------------% - -TIME_ITER= 1 -OUTPUT_WRT_FREQ= 1 - -% --------------------------- MESH REFINEMENT ---------------------------------% +FORMULATION_ELASTICITY_2D= PLANE_STRAIN +WEAKLY_COUPLED_HEAT_EQUATION= YES +INC_NONDIM= DIMENSIONAL + +% Material properties +ELASTICITY_MODULUS= 21000 +MATERIAL_DENSITY= 0.8 +POISSON_RATIO= 0.4 + +SPECIFIC_HEAT_CP= 1 +THERMAL_CONDUCTIVITY_CONSTANT= 4 +MATERIAL_REFERENCE_TEMPERATURE= 0.1 +MATERIAL_THERMAL_EXPANSION_COEFF= 1 + +% Boundary conditions +MARKER_CLAMPED= ( clamped ) +MARKER_FLUID_LOAD= ( wallS ) +MARKER_CHT_INTERFACE= ( wallS ) +MARKER_CREATE_COPY= ( clamped, isothermal ) +MARKER_ISOTHERMAL= ( isothermal, 0.1 ) + +MARKER_PLOTTING= ( wallS ) +MARKER_MONITORING= ( wallS ) + +% Initial conditions +FREESTREAM_TEMPERATURE= 0.1 + +% Solver settings +NUM_METHOD_GRAD= GREEN_GAUSS + +TIME_DISCRE_HEAT= EULER_IMPLICIT +CFL_NUMBER= 1e8 +LINEAR_SOLVER= CONJUGATE_GRADIENT +LINEAR_SOLVER_PREC= ILU +LINEAR_SOLVER_ERROR= 1e-4 +LINEAR_SOLVER_ITER= 500 + +% Convergence settings +INNER_ITER= 5 +CONV_FIELD= RMS_UTOL +CONV_RESIDUAL_MINVAL= -10 + +% In/Out +SCREEN_OUTPUT= INNER_ITER, RMS_RES, VMS, TOTAL_HEATFLUX, LINSOL +MESH_FORMAT= SU2 MESH_FILENAME= meshFEA.su2 - -% --------------------------- FSI CONDITIONS ----------------------------------% - -RAMP_LOADING=NO - -STAT_RELAX_PARAMETER= 1.0 -BGS_RELAXATION = FIXED_PARAMETER -PREDICTOR_ORDER = 0 - -CONV_FIELD=RMS_UTOL -CONV_RESIDUAL_MINVAL=-10 - -% ----------------------------- INPUT/OUTPUT ----------------------------------% +TABULAR_FORMAT= CSV VOLUME_FILENAME= result_beam - -BREAKDOWN_FILENAME= forces_breakdown.dat - SOLUTION_FILENAME= solution_beam RESTART_FILENAME= restart_beam -% ------------------------ STRUCTURAL PARAMETERS ------------------------------% - -ELASTICITY_MODULUS=21000 -MATERIAL_DENSITY=0.8 -FORMULATION_ELASTICITY_2D = PLANE_STRAIN -POISSON_RATIO=0.4 - -% -------------------------- DYNAMIC SIMULATION -------------------------------% -TIME_DOMAIN= NO -TIME_DISCRE_FEA= NEWMARK_IMPLICIT - -% -------------------------- STRUCTURAL SOLVER --------------------------------% - -LINEAR_SOLVER = CONJUGATE_GRADIENT -LINEAR_SOLVER_PREC = JACOBI -LINEAR_SOLVER_ERROR = 1E-3 -LINEAR_SOLVER_ITER = 2000 - -% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% - -MARKER_CLAMPED = ( clamped ) -MARKER_PRESSURE= ( wallS, 0.0) - -MARKER_FLUID_LOAD = (wallS) - -% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% - -MESH_FORMAT= SU2 -TABULAR_FORMAT= CSV diff --git a/TestCases/fea_fsi/stat_fsi/configFlow.cfg b/TestCases/fea_fsi/stat_fsi/configFlow.cfg index 2b54ef4d3866..60cc8882a49d 100755 --- a/TestCases/fea_fsi/stat_fsi/configFlow.cfg +++ b/TestCases/fea_fsi/stat_fsi/configFlow.cfg @@ -1,121 +1,81 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % % SU2 configuration file % -% Case description: Fluid structure interaction - Beam in channel - 2D - FEM % -% Author: R.Sanchez % -% Institution: TU Kaiserslautern % -% % +% Case description: Aero-thermo-elasticity % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% -% +% Laminar flow SOLVER= NAVIER_STOKES - KIND_TURB_MODEL= NONE -MATH_PROBLEM= DIRECT - -% --------------------------- MESH DEFORMATION ---------------------------------% - -MESH_FILENAME= meshFlow.su2 - -DEFORM_MESH = YES -MARKER_DEFORM_MESH = (wallF) - -DEFORM_STIFFNESS_TYPE = INVERSE_VOLUME -DEFORM_LINEAR_SOLVER = CONJUGATE_GRADIENT -DEFORM_LINEAR_SOLVER_PREC = LU_SGS -DEFORM_LINEAR_SOLVER_ERROR = 1E-5 -DEFORM_NONLINEAR_ITER= 1 -DEFORM_LINEAR_SOLVER_ITER = 5000 -DEFORM_CONSOLE_OUTPUT = NO - -% -----------------------------------------------------------------------------% - -OUTPUT_WRT_FREQ= 10 +% Material properties +FLUID_MODEL= STANDARD_AIR +VISCOSITY_MODEL= CONSTANT_VISCOSITY +MU_CONSTANT= 1.82E-4 +CONDUCTIVITY_MODEL= CONSTANT_PRANDTL +PRANDTL_LAM= 0.72 -INNER_ITER= 200 - -% ----------------------------- INPUT/OUTPUT ----------------------------------% - -VOLUME_FILENAME= result_flow -CONV_FILENAME= history - -BREAKDOWN_FILENAME= forces_breakdown.dat - -SOLUTION_FILENAME= solution_flow -RESTART_FILENAME= restart_flow - -% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% - -MARKER_HEATFLUX= ( wallF, 0.0) +% Boundary conditions MARKER_INLET= ( inlet, 0.0578070909, 20.1346756866, 1.0, 0.0, 0.0 ) -MARKER_OUTLET= ( outlet, 19.5809057203) +MARKER_OUTLET= ( outlet, 19.5809057203 ) MARKER_EULER= ( upper, lower ) +MARKER_CHT_INTERFACE= ( wallF ) MARKER_PLOTTING= ( wallF ) MARKER_MONITORING= ( wallF ) -% -------------------------- FLUID SIMULATION ---------------------------------% - -TIME_DOMAIN=NO -MAX_TIME= 4.01 - -% ----------- COMPRESSIBLE AND INCOMPRESSIBLE FREE-STREAM DEFINITION ----------% - -MACH_NUMBER= 0.2 -MACH_MOTION= 0.2 -AoA= 0.0 -SIDESLIP_ANGLE= 0.0 - -INIT_OPTION = TD_CONDITIONS -FREESTREAM_OPTION = DENSITY_FS -FREESTREAM_DENSITY = 1.18 -FREESTREAM_PRESSURE = 19.5809057203 -FREESTREAM_TEMPERATURE = 0.0578070909 -VISCOSITY_MODEL = CONSTANT_VISCOSITY -MU_CONSTANT = 1.82E-3 -REYNOLDS_NUMBER= 10 -CFL_NUMBER = 100 - -% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% - -REF_ORIGIN_MOMENT_X = 0.00 -REF_ORIGIN_MOMENT_Y = 0.00 -REF_ORIGIN_MOMENT_Z = 0.00 - -REF_AREA = 0.016 -REYNOLDS_LENGTH = 0.016 - -% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% - -NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES -RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) - -% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% - -LINEAR_SOLVER= FGMRES -LINEAR_SOLVER_PREC= ILU -LINEAR_SOLVER_ERROR= 1E-6 -LINEAR_SOLVER_ITER= 2 - -% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% - +% Initial conditions +MACH_NUMBER= 0.03 +INIT_OPTION= TD_CONDITIONS +FREESTREAM_OPTION= TEMPERATURE_FS +FREESTREAM_PRESSURE= 19.5809057203 +FREESTREAM_TEMPERATURE= 0.0578070909 + +% Mesh deformation +DEFORM_MESH= YES +MARKER_DEFORM_MESH= ( wallF ) +MARKER_DEFORM_MESH_SYM_PLANE= ( upper ) +DEFORM_NONLINEAR_ITER= 1 +DEFORM_STIFFNESS_TYPE= INVERSE_VOLUME +DEFORM_LINEAR_SOLVER= CONJUGATE_GRADIENT +DEFORM_LINEAR_SOLVER_PREC= ILU +DEFORM_LINEAR_SOLVER_ITER= 500 +DEFORM_LINEAR_SOLVER_ERROR= 1E-8 +DEFORM_CONSOLE_OUTPUT= NO + +% Solver settings CONV_NUM_METHOD_FLOW= ROE MUSCL_FLOW= YES +NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES SLOPE_LIMITER_FLOW= VENKATAKRISHNAN VENKAT_LIMITER_COEFF= 1.0 -JST_SENSOR_COEFF=( 0.5, 0.02 ) + TIME_DISCRE_FLOW= EULER_IMPLICIT +CFL_NUMBER= 500 +LINEAR_SOLVER= FGMRES +LINEAR_SOLVER_PREC= ILU +LINEAR_SOLVER_ERROR= 0.1 +LINEAR_SOLVER_ITER= 10 -% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% Convergence settings +INNER_ITER= 100 +CONV_FIELD= RMS_DENSITY +CONV_RESIDUAL_MINVAL= -9 -CONV_RESIDUAL_MINVAL= -10 -CONV_STARTITER= 10 -CONV_CAUCHY_ELEMS= 100 -CONV_CAUCHY_EPS= 1E-5 +% Reference values +REF_ORIGIN_MOMENT_X= 0.0 +REF_ORIGIN_MOMENT_Y= 0.0 +REF_ORIGIN_MOMENT_Z= 0.0 +REF_AREA= 0.016 +REYNOLDS_LENGTH= 0.016 -% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% In/Out +SCREEN_OUTPUT= INNER_ITER, RMS_RES, TOTAL_HEATFLUX, LINSOL MESH_FORMAT= SU2 +MESH_FILENAME= meshFlow.su2 TABULAR_FORMAT= CSV + +VOLUME_FILENAME= result_flow +SOLUTION_FILENAME= solution_flow +RESTART_FILENAME= restart_flow + diff --git a/TestCases/fea_fsi/stat_fsi/config_restart.cfg b/TestCases/fea_fsi/stat_fsi/config_restart.cfg index fa395744db71..b88f64ca143f 100755 --- a/TestCases/fea_fsi/stat_fsi/config_restart.cfg +++ b/TestCases/fea_fsi/stat_fsi/config_restart.cfg @@ -1,23 +1,32 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % % SU2 configuration file % -% Case description: Fluid structure interaction - Beam in channel - 2D - FEM % -% Author: R.Sanchez % -% Institution: Imperial College London % -% % +% Case description: Aero-thermo-elasticity % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% FSI settings SOLVER= MULTIPHYSICS +MULTIZONE_SOLVER= BLOCK_GAUSS_SEIDEL +RAMP_LOADING= NO +RAMP_FSI_ITER= 5 +BGS_RELAXATION= FIXED_PARAMETER +STAT_RELAX_PARAMETER= 0.9 -CONFIG_LIST = (configFlow.cfg, configFEA.cfg) +CONFIG_LIST= ( configFlow.cfg, configFEA.cfg ) -MULTIZONE_SOLVER = BLOCK_GAUSS_SEIDEL +MARKER_ZONE_INTERFACE= ( wallF, wallS ) -MARKER_ZONE_INTERFACE = (wallF, wallS) +SCREEN_OUTPUT= \ + OUTER_ITER, INNER_ITER[0], AVG_BGS_RES[0], AVG_BGS_RES[1],\ + RMS_DENSITY[0], RMS_UTOL[1], RMS_TEMPERATURE[1], VMS[1],\ + TOTAL_HEATFLUX[1], DEFORM_MIN_VOLUME[0], DEFORM_ITER[0] -MULTIZONE_MESH = NO -SCREEN_OUTPUT=(OUTER_ITER, BGS_DENSITY[0], AVG_BGS_RES[1], DEFORM_MIN_VOLUME[0], DEFORM_ITER[0]) RESTART_SOL= YES -RESTART_ITER = 0 -TIME_DOMAIN = NO -OUTER_ITER = 2 +RESTART_ITER= 0 + +OUTER_ITER= 1 +CONV_RESIDUAL_MINVAL= -5 + +MULTIZONE_MESH= NO +WRT_ZONE_CONV= NO +OUTPUT_WRT_FREQ= 100 + diff --git a/TestCases/fea_topology/grad_ref_node.dat.ref b/TestCases/fea_topology/grad_ref_node.dat.ref index 6f3a4d4a6854..15afff813c19 100644 --- a/TestCases/fea_topology/grad_ref_node.dat.ref +++ b/TestCases/fea_topology/grad_ref_node.dat.ref @@ -6157,7 +6157,7 @@ -9.57383e-11 -2.60763e-10 -2.54078e-10 --1.57598e-10 +-1.57599e-10 -8.68931e-12 -4.26927e-13 0 diff --git a/TestCases/hybrid_regression.py b/TestCases/hybrid_regression.py index 57074e8ea998..5f02581eeef1 100644 --- a/TestCases/hybrid_regression.py +++ b/TestCases/hybrid_regression.py @@ -51,7 +51,7 @@ def main(): channel.cfg_dir = "euler/channel" channel.cfg_file = "inv_channel_RK.cfg" channel.test_iter = 20 - channel.test_vals = [-2.318252, 3.226111, 0.133426, 0.150359] + channel.test_vals = [-2.000215, 3.536936, 0.034212, 0.193725] test_list.append(channel) # NACA0012 @@ -59,7 +59,7 @@ def main(): naca0012.cfg_dir = "euler/naca0012" naca0012.cfg_file = "inv_NACA0012_Roe.cfg" naca0012.test_iter = 20 - naca0012.test_vals = [-4.252415, -3.789971, 0.306821, 0.024573] + naca0012.test_vals = [-4.492584, -3.930725, 0.297160, 0.025487] test_list.append(naca0012) # Supersonic wedge @@ -67,7 +67,7 @@ def main(): wedge.cfg_dir = "euler/wedge" wedge.cfg_file = "inv_wedge_HLLC.cfg" wedge.test_iter = 20 - wedge.test_vals = [-3.587150, 2.136260, -0.249533, 0.043953] + wedge.test_vals = [-3.689935, 2.034291, -0.249531, 0.043953] test_list.append(wedge) # ONERA M6 Wing @@ -83,7 +83,7 @@ def main(): fixedCL_naca0012.cfg_dir = "fixed_cl/naca0012" fixedCL_naca0012.cfg_file = "inv_NACA0012.cfg" fixedCL_naca0012.test_iter = 10 - fixedCL_naca0012.test_vals = [-3.936884, 1.574653, 0.300864, 0.019462] + fixedCL_naca0012.test_vals = [-4.017883, 1.513039, 0.300961, 0.019472] test_list.append(fixedCL_naca0012) # HYPERSONIC FLOW PAST BLUNT BODY @@ -103,7 +103,7 @@ def main(): flatplate.cfg_dir = "navierstokes/flatplate" flatplate.cfg_file = "lam_flatplate.cfg" flatplate.test_iter = 100 - flatplate.test_vals = [-6.381351, -0.904240, 0.001313, 0.025285, 2.361500, -2.336300, 0, 0] + flatplate.test_vals = [-6.537258, -1.059050, 0.001198, 0.029303, 2.361500, -2.332200, 0.000000, 0.000000] test_list.append(flatplate) # Laminar cylinder (steady) @@ -111,7 +111,7 @@ def main(): cylinder.cfg_dir = "navierstokes/cylinder" cylinder.cfg_file = "lam_cylinder.cfg" cylinder.test_iter = 25 - cylinder.test_vals = [-8.460419, -2.972300, 0.271000, 1.701198, 0.000000] + cylinder.test_vals = [-8.463699, -2.981890, 0.045839, 1.659615, 0.000000] test_list.append(cylinder) # Laminar cylinder (low Mach correction) @@ -119,7 +119,7 @@ def main(): cylinder_lowmach.cfg_dir = "navierstokes/cylinder" cylinder_lowmach.cfg_file = "cylinder_lowmach.cfg" cylinder_lowmach.test_iter = 25 - cylinder_lowmach.test_vals = [-6.629113, -1.167336, -0.016421, -73.160843, 0.000000] + cylinder_lowmach.test_vals = [-6.473668, -1.011938, 0.275173, 71.130747, 0.000000] cylinder_lowmach.test_vals_aarch64 = [-6.830996, -1.368850, -0.143956, 73.963354, 0] test_list.append(cylinder_lowmach) @@ -136,7 +136,7 @@ def main(): poiseuille_profile.cfg_dir = "navierstokes/poiseuille" poiseuille_profile.cfg_file = "profile_poiseuille.cfg" poiseuille_profile.test_iter = 10 - poiseuille_profile.test_vals = [-12.005211, -7.539073, -0.000000, 2.089953] + poiseuille_profile.test_vals = [-12.005129, -7.581821, -0.000000, 2.089953] poiseuille_profile.test_vals_aarch64 = [-12.009012, -7.262530, -0.000000, 2.089953] test_list.append(poiseuille_profile) @@ -157,7 +157,7 @@ def main(): rae2822_sa.cfg_dir = "rans/rae2822" rae2822_sa.cfg_file = "turb_SA_RAE2822.cfg" rae2822_sa.test_iter = 20 - rae2822_sa.test_vals = [-2.169314, -5.450577, 0.293838, 0.104752, 0.000000] + rae2822_sa.test_vals = [-2.193049, -5.312606, 0.388492, 0.077204, 0.000000] test_list.append(rae2822_sa) # RAE2822 SST @@ -165,7 +165,7 @@ def main(): rae2822_sst.cfg_dir = "rans/rae2822" rae2822_sst.cfg_file = "turb_SST_RAE2822.cfg" rae2822_sst.test_iter = 20 - rae2822_sst.test_vals = [-1.028401, 5.875380, 0.279522, 0.093893, 0.000000] + rae2822_sst.test_vals = [-1.028279, 5.869352, 0.357127, 0.074559, 0.000000] test_list.append(rae2822_sst) # RAE2822 SST_SUST @@ -173,7 +173,7 @@ def main(): rae2822_sst_sust.cfg_dir = "rans/rae2822" rae2822_sst_sust.cfg_file = "turb_SST_SUST_RAE2822.cfg" rae2822_sst_sust.test_iter = 20 - rae2822_sst_sust.test_vals = [-2.540329, 5.875369, 0.279522, 0.093893] + rae2822_sst_sust.test_vals = [-2.479273, 5.869341, 0.357127, 0.074559] test_list.append(rae2822_sst_sust) # Flat plate @@ -181,7 +181,7 @@ def main(): turb_flatplate.cfg_dir = "rans/flatplate" turb_flatplate.cfg_file = "turb_SA_flatplate.cfg" turb_flatplate.test_iter = 20 - turb_flatplate.test_vals = [-4.938980, -7.469368, -0.187651, 0.015894] + turb_flatplate.test_vals = [-4.958138, -7.438030, -0.187473, 0.015060] test_list.append(turb_flatplate) # ONERA M6 Wing @@ -197,7 +197,7 @@ def main(): turb_naca0012_sa.cfg_dir = "rans/naca0012" turb_naca0012_sa.cfg_file = "turb_NACA0012_sa.cfg" turb_naca0012_sa.test_iter = 5 - turb_naca0012_sa.test_vals = [-12.038018, -16.332088, 1.080346, 0.018385, 20, -2.873140, 0, -14.250270, 0] + turb_naca0012_sa.test_vals = [-12.038028, -16.332088, 1.080346, 0.018385, 20, -2.873477, 0, -14.250270, 0] turb_naca0012_sa.test_vals_aarch64 = [-12.038091, -16.332090, 1.080346, 0.018385, 20.000000, -2.873236, 0.000000, -14.250271, 0.000000] test_list.append(turb_naca0012_sa) @@ -206,7 +206,7 @@ def main(): turb_naca0012_sst.cfg_dir = "rans/naca0012" turb_naca0012_sst.cfg_file = "turb_NACA0012_sst.cfg" turb_naca0012_sst.test_iter = 10 - turb_naca0012_sst.test_vals = [-12.093939, -15.251079, -5.906323, 1.070413, 0.015775, -2.854890, 0] + turb_naca0012_sst.test_vals = [-12.093871, -15.251077, -5.906324, 1.070413, 0.015775, -2.855457, 0] turb_naca0012_sst.test_vals_aarch64 = [-12.075928, -15.246732, -5.861249, 1.070036, 0.015841, -2.835263, 0] test_list.append(turb_naca0012_sst) @@ -215,7 +215,7 @@ def main(): turb_naca0012_sst_sust.cfg_dir = "rans/naca0012" turb_naca0012_sst_sust.cfg_file = "turb_NACA0012_sst_sust.cfg" turb_naca0012_sst_sust.test_iter = 10 - turb_naca0012_sst_sust.test_vals = [-12.080826, -14.837176, -5.732918, 1.000893, 0.019109, -2.120233] + turb_naca0012_sst_sust.test_vals = [-12.080828, -14.837176, -5.732906, 1.000893, 0.019109, -2.120116] turb_naca0012_sst_sust.test_vals_aarch64 = [-12.073210, -14.836724, -5.732627, 1.000050, 0.019144, -2.629689] test_list.append(turb_naca0012_sst_sust) @@ -232,7 +232,7 @@ def main(): turb_naca0012_sst_expliciteuler.cfg_dir = "rans/naca0012" turb_naca0012_sst_expliciteuler.cfg_file = "turb_NACA0012_sst_expliciteuler.cfg" turb_naca0012_sst_expliciteuler.test_iter = 10 - turb_naca0012_sst_expliciteuler.test_vals = [-3.532365, -3.157224, 3.743381, 1.124798, 0.501715, -float("inf")] + turb_naca0012_sst_expliciteuler.test_vals = [-3.532365, -3.157224, 3.743381, 1.124798, 0.501715, -16.000000] test_list.append(turb_naca0012_sst_expliciteuler) # PROPELLER @@ -252,7 +252,7 @@ def main(): axi_rans_air_nozzle_restart.cfg_dir = "axisymmetric_rans/air_nozzle" axi_rans_air_nozzle_restart.cfg_file = "air_nozzle_restart.cfg" axi_rans_air_nozzle_restart.test_iter = 10 - axi_rans_air_nozzle_restart.test_vals = [-12.066224, -7.425871, -8.816101, -3.732807, 0] + axi_rans_air_nozzle_restart.test_vals = [-12.066228, -7.425901, -8.815839, -3.732622, 0] axi_rans_air_nozzle_restart.test_vals_aarch64 = [-14.140441, -9.154674, -10.886121, -5.806594, 0.000000] test_list.append(axi_rans_air_nozzle_restart) @@ -266,7 +266,7 @@ def main(): turb_naca0012_sst_restart_mg.cfg_file = "turb_NACA0012_sst_multigrid_restart.cfg" turb_naca0012_sst_restart_mg.test_iter = 20 turb_naca0012_sst_restart_mg.ntest_vals = 5 - turb_naca0012_sst_restart_mg.test_vals = [-6.538814, -5.057150, 0.830240, -0.008813, 0.078177] + turb_naca0012_sst_restart_mg.test_vals = [-6.589114, -5.057151, 0.830239, -0.008808, 0.078150] test_list.append(turb_naca0012_sst_restart_mg) ############################# @@ -347,7 +347,7 @@ def main(): inc_euler_naca0012.cfg_dir = "incomp_euler/naca0012" inc_euler_naca0012.cfg_file = "incomp_NACA0012.cfg" inc_euler_naca0012.test_iter = 20 - inc_euler_naca0012.test_vals = [-5.737092, -4.868827, 0.512333, 0.009264] + inc_euler_naca0012.test_vals = [-5.846118, -4.941076, 0.519913, 0.008955] test_list.append(inc_euler_naca0012) # C-D nozzle with pressure inlet and mass flow outlet @@ -355,7 +355,7 @@ def main(): inc_nozzle.cfg_dir = "incomp_euler/nozzle" inc_nozzle.cfg_file = "inv_nozzle.cfg" inc_nozzle.test_iter = 20 - inc_nozzle.test_vals = [-5.362338, -4.748247, -0.017498, 0.115865] + inc_nozzle.test_vals = [-6.171980, -5.419034, 0.009267, 0.127577] test_list.append(inc_nozzle) ############################# @@ -367,7 +367,7 @@ def main(): inc_lam_cylinder.cfg_dir = "incomp_navierstokes/cylinder" inc_lam_cylinder.cfg_file = "incomp_cylinder.cfg" inc_lam_cylinder.test_iter = 10 - inc_lam_cylinder.test_vals = [-4.168263, -3.611146, 0.013547, 4.538946] + inc_lam_cylinder.test_vals = [-4.159236, -3.569077, 0.017653, 4.934964] test_list.append(inc_lam_cylinder) # Buoyancy-driven cavity @@ -432,7 +432,7 @@ def main(): cavity.cfg_dir = "moving_wall/cavity" cavity.cfg_file = "lam_cavity.cfg" cavity.test_iter = 25 - cavity.test_vals = [-7.325788, -1.861524, 1.097830, 1.028368] + cavity.test_vals = [-7.938907, -2.490199, 0.013042, 0.004995] test_list.append(cavity) # Spinning cylinder @@ -440,7 +440,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.881383, -2.419298, 1.535192, 1.450905] + spinning_cylinder.test_vals = [-7.547526, -2.080576, 1.888705, 1.812327] spinning_cylinder.test_vals_aarch64 = [-8.008023, -2.611064, 1.497308, 1.487483] test_list.append(spinning_cylinder) @@ -462,7 +462,7 @@ def main(): sine_gust.cfg_dir = "gust" sine_gust.cfg_file = "inv_gust_NACA0012.cfg" sine_gust.test_iter = 5 - sine_gust.test_vals = [-1.977498, 3.481817, -0.009878, -0.005086] + sine_gust.test_vals = [-1.977498, 3.481817, -0.009944, -0.004266] sine_gust.unsteady = True test_list.append(sine_gust) @@ -471,7 +471,7 @@ def main(): cosine_gust.cfg_dir = "gust" cosine_gust.cfg_file = "cosine_gust_zdir.cfg" cosine_gust.test_iter = 79 - cosine_gust.test_vals = [-2.418805, 0.001521, -0.001239, 0.000394, -0.000593] + cosine_gust.test_vals = [-2.418805, 0.002211, -0.001258, 0.000438, -0.000592] cosine_gust.unsteady = True cosine_gust.enabled_with_tsan = False test_list.append(cosine_gust) @@ -491,7 +491,7 @@ def main(): aeroelastic.cfg_dir = "aeroelastic" aeroelastic.cfg_file = "aeroelastic_NACA64A010.cfg" aeroelastic.test_iter = 2 - aeroelastic.test_vals = [-1.876630, 4.021077, 0.078661, 0.027698, -0.001639, -0.000129, -1.056256] + aeroelastic.test_vals = [-1.876626, 4.021083, 0.081436, 0.027726, -0.001638, -0.000130, -1.056269] aeroelastic.unsteady = True aeroelastic.enabled_on_cpu_arch = ["x86_64"] # Requires AVX-capable architecture test_list.append(aeroelastic) @@ -519,7 +519,7 @@ def main(): unst_deforming_naca0012.cfg_dir = "disc_adj_euler/naca0012_pitching_def" unst_deforming_naca0012.cfg_file = "inv_NACA0012_pitching_deform.cfg" unst_deforming_naca0012.test_iter = 5 - unst_deforming_naca0012.test_vals = [-3.665243, -3.794042, -3.716822, -3.148495] + unst_deforming_naca0012.test_vals = [-3.665284, -3.794189, -3.716987, -3.148573] unst_deforming_naca0012.unsteady = True unst_deforming_naca0012.enabled_with_tsan = False test_list.append(unst_deforming_naca0012) @@ -532,8 +532,8 @@ def main(): edge_VW = TestCase('edge_VW') edge_VW.cfg_dir = "nicf/edge" edge_VW.cfg_file = "edge_VW.cfg" - edge_VW.test_iter = 40 - edge_VW.test_vals = [-8.895442, -2.694280, -0.000009, 0.000000] + edge_VW.test_iter = 30 + edge_VW.test_vals = [-7.053408, -0.851910, -0.000009, 0.000000] test_list.append(edge_VW) # Rarefaction shock wave edge_PPR @@ -541,7 +541,7 @@ def main(): edge_PPR.cfg_dir = "nicf/edge" edge_PPR.cfg_file = "edge_PPR.cfg" edge_PPR.test_iter = 20 - edge_PPR.test_vals = [-10.594993, -4.431993, -0.000034, 0.000000] + edge_PPR.test_vals = [-12.455039, -6.258168, -0.000034, 0.000000] edge_PPR.test_vals_aarch64 = [ -7.139211, -0.980821, -0.000034, 0.000000] test_list.append(edge_PPR) @@ -654,7 +654,7 @@ def main(): bars_SST_2D.cfg_dir = "sliding_interface/bars_SST_2D" bars_SST_2D.cfg_file = "bars.cfg" bars_SST_2D.test_iter = 13 - bars_SST_2D.test_vals = [13.000000, -0.473801, -1.563681] + bars_SST_2D.test_vals = [13.000000, -0.396746, -1.461254] bars_SST_2D.multizone = True test_list.append(bars_SST_2D) @@ -711,15 +711,14 @@ def main(): dyn_fsi.unsteady = True test_list.append(dyn_fsi) - # FSI, Static, 2D, new mesh solver, restart - stat_fsi_restart = TestCase('stat_fsi_restart') - stat_fsi_restart.cfg_dir = "fea_fsi/stat_fsi" - stat_fsi_restart.cfg_file = "config_restart.cfg" - stat_fsi_restart.test_iter = 1 - stat_fsi_restart.test_vals = [-3.549586, -4.460650, 0.000000, 35.000000] - stat_fsi_restart.test_vals_aarch64 = [-3.549586, -4.460713, 0.000000, 35.000000] - stat_fsi_restart.multizone = True - test_list.append(stat_fsi_restart) + # FSI+CHT, Static, 2D, new mesh solver, restart + fsi_cht_restart = TestCase('fsi_cht_restart') + fsi_cht_restart.cfg_dir = "fea_fsi/stat_fsi" + fsi_cht_restart.cfg_file = "config_restart.cfg" + fsi_cht_restart.test_iter = 0 + fsi_cht_restart.test_vals = [5, 0.006352, -1.960362, -9.327033, -9.599649, -9.318478, 608.38, -0.012974, 0, 20] + fsi_cht_restart.multizone = True + test_list.append(fsi_cht_restart) ############################################## ### Method of Manufactured Solutions (MMS) ### diff --git a/TestCases/hybrid_regression_AD.py b/TestCases/hybrid_regression_AD.py index 4e1aa84e22c2..df801edb10fe 100644 --- a/TestCases/hybrid_regression_AD.py +++ b/TestCases/hybrid_regression_AD.py @@ -99,7 +99,7 @@ def main(): discadj_incomp_NACA0012.cfg_dir = "disc_adj_incomp_euler/naca0012" discadj_incomp_NACA0012.cfg_file = "incomp_NACA0012_disc.cfg" discadj_incomp_NACA0012.test_iter = 20 - discadj_incomp_NACA0012.test_vals = [20.000000, -3.338267, -2.490046, 0.000000] + discadj_incomp_NACA0012.test_vals = [20.000000, -3.122291, -2.287328, 0.000000] test_list.append(discadj_incomp_NACA0012) ##################################### @@ -187,7 +187,7 @@ def main(): discadj_pitchingNACA0012.cfg_dir = "disc_adj_euler/naca0012_pitching" discadj_pitchingNACA0012.cfg_file = "inv_NACA0012_pitching.cfg" discadj_pitchingNACA0012.test_iter = 4 - discadj_pitchingNACA0012.test_vals = [-1.124927, -1.586220, -0.006032, 0.000009] + discadj_pitchingNACA0012.test_vals = [-1.041883, -1.512874, -0.006211, 0.000012] discadj_pitchingNACA0012.tol = 0.01 discadj_pitchingNACA0012.unsteady = True discadj_pitchingNACA0012.enabled_with_tsan = False diff --git a/TestCases/multiple_ffd/naca0012/of_grad_cd.dat.ref b/TestCases/multiple_ffd/naca0012/of_grad_cd.dat.ref index 8ab0b5b0fe70..45622cb6bd5e 100644 --- a/TestCases/multiple_ffd/naca0012/of_grad_cd.dat.ref +++ b/TestCases/multiple_ffd/naca0012/of_grad_cd.dat.ref @@ -1,3 +1,3 @@ VARIABLES="VARIABLE" , "GRADIENT" , "FINDIFF_STEP" - 0 , 0.0456482 , 0.001 - 1 , -0.0881187 , 0.001 + 0 , 0.0525397 , 0.001 + 1 , -0.099502 , 0.001 diff --git a/TestCases/multiple_ffd/naca0012/of_grad_directdiff.dat.ref b/TestCases/multiple_ffd/naca0012/of_grad_directdiff.dat.ref index 9365cd9cd74a..174226e78499 100644 --- a/TestCases/multiple_ffd/naca0012/of_grad_directdiff.dat.ref +++ b/TestCases/multiple_ffd/naca0012/of_grad_directdiff.dat.ref @@ -1,3 +1,3 @@ VARIABLES="VARIABLE" , "DRAG" , "EFFICIENCY" , "FORCE_X" , "FORCE_Y" , "FORCE_Z" , "LIFT" , "MOMENT_X" , "MOMENT_Y" , "MOMENT_Z" , "SIDEFORCE" - 0 , 0.04734305575 , -0.4824482295 , 0.04752721691 , -0.00792353334 , 0.0 , -0.008958448527 , 0.0 , 0.0 , 0.02636591979 , 0.0 - 1 , -0.09189465405 , 0.6527341405 , -0.09165316206 , -0.01206987592 , 0.0 , -0.01006760043 , 0.0 , 0.0 , 0.06097366677 , 0.0 + 0 , 0.05592643623 , -0.4243829941 , 0.05586792439 , 0.003291646374 , 0.0 , 0.002072110703 , 0.0 , 0.0 , 0.02964415677 , 0.0 + 1 , -0.1052916742 , 0.9115770745 , -0.1054405784 , 0.005675584425 , 0.0 , 0.007974407886 , 0.0 , 0.0 , 0.06727760621 , 0.0 diff --git a/TestCases/parallel_regression.py b/TestCases/parallel_regression.py index 7f10753db6e3..a6e777342244 100755 --- a/TestCases/parallel_regression.py +++ b/TestCases/parallel_regression.py @@ -47,7 +47,7 @@ def main(): cfd_flamelet_ch4.cfg_dir = "flamelet/01_laminar_premixed_ch4_flame_cfd" cfd_flamelet_ch4.cfg_file = "lam_prem_ch4_cfd.cfg" cfd_flamelet_ch4.test_iter = 10 - cfd_flamelet_ch4.test_vals = [-14.429718, -15.860038, -8.226686, -16.506667, -19.493283, 87.326000] + cfd_flamelet_ch4.test_vals = [-10.539588, -12.650786, -5.649832, -13.470491, -17.249262, 94.854000] cfd_flamelet_ch4.new_output = True test_list.append(cfd_flamelet_ch4) @@ -56,7 +56,7 @@ def main(): cfd_flamelet_ch4_axi.cfg_dir = "flamelet/05_laminar_premixed_ch4_flame_cfd_axi" cfd_flamelet_ch4_axi.cfg_file = "lam_prem_ch4_cfd_axi.cfg" cfd_flamelet_ch4_axi.test_iter = 10 - cfd_flamelet_ch4_axi.test_vals = [-11.259626, -10.020810, -11.852795, -4.909152, 95.000000] + cfd_flamelet_ch4_axi.test_vals = [-11.255837, -10.017962, -11.850828, -4.916261, 72.669000] cfd_flamelet_ch4_axi.new_output = True test_list.append(cfd_flamelet_ch4_axi) @@ -65,7 +65,7 @@ def main(): cfd_flamelet_ch4_partial_premix.cfg_dir = "flamelet/06_laminar_partial_premixed_ch4_flame_cfd" cfd_flamelet_ch4_partial_premix.cfg_file = "lam_partial_prem_ch4_cfd.cfg" cfd_flamelet_ch4_partial_premix.test_iter = 10 - cfd_flamelet_ch4_partial_premix.test_vals = [-10.482722, -3.621055, -12.938151, -10.154391, 10.000000] + cfd_flamelet_ch4_partial_premix.test_vals = [-10.482722, -3.621055, -12.932224, -10.154391, 10.000000] cfd_flamelet_ch4_partial_premix.new_output = True test_list.append(cfd_flamelet_ch4_partial_premix) @@ -74,7 +74,7 @@ def main(): cfd_flamelet_h2.cfg_dir = "flamelet/07_laminar_premixed_h2_flame_cfd" cfd_flamelet_h2.cfg_file = "laminar_premixed_h2_flame_cfd.cfg" cfd_flamelet_h2.test_iter = 5 - cfd_flamelet_h2.test_vals = [-8.036958, -8.372668, -1.842800, -9.388446] + cfd_flamelet_h2.test_vals = [-8.036794, -8.372668, -1.842800, -9.388446] test_list.append(cfd_flamelet_h2) # Flame ignition methods @@ -228,7 +228,7 @@ def main(): channel.cfg_dir = "euler/channel" channel.cfg_file = "inv_channel_RK.cfg" channel.test_iter = 20 - channel.test_vals = [-2.305051, 3.237256, 0.125006, 0.154077] + channel.test_vals = [-1.988782, 3.546674, 0.032065, 0.194399] test_list.append(channel) # NACA0012 @@ -236,7 +236,7 @@ def main(): naca0012.cfg_dir = "euler/naca0012" naca0012.cfg_file = "inv_NACA0012_Roe.cfg" naca0012.test_iter = 20 - naca0012.test_vals = [-4.314738, -3.845428, 0.307738, 0.024670] + naca0012.test_vals = [-4.442633, -3.913184, 0.295834, 0.024405] test_list.append(naca0012) # Supersonic wedge @@ -244,7 +244,7 @@ def main(): wedge.cfg_dir = "euler/wedge" wedge.cfg_file = "inv_wedge_HLLC.cfg" wedge.test_iter = 20 - wedge.test_vals = [-3.573085, 2.150321, -0.249533, 0.043953] + wedge.test_vals = [-3.681969, 2.042532, -0.249531, 0.043953] test_list.append(wedge) # ONERA M6 Wing @@ -252,7 +252,7 @@ def main(): oneram6.cfg_dir = "euler/oneram6" oneram6.cfg_file = "inv_ONERAM6.cfg" oneram6.test_iter = 10 - oneram6.test_vals = [-11.525271, -10.995902, 0.280800, 0.008623] + oneram6.test_vals = [-11.530230, -11.006685, 0.280800, 0.008623] oneram6.timeout = 3200 test_list.append(oneram6) @@ -261,7 +261,7 @@ def main(): fixedCL_naca0012.cfg_dir = "fixed_cl/naca0012" fixedCL_naca0012.cfg_file = "inv_NACA0012.cfg" fixedCL_naca0012.test_iter = 10 - fixedCL_naca0012.test_vals = [-3.919916, 1.592064, 0.300852, 0.019461] + fixedCL_naca0012.test_vals = [-4.006904, 1.523677, 0.300969, 0.019473] test_list.append(fixedCL_naca0012) # Polar sweep of the inviscid NACA0012 @@ -270,7 +270,7 @@ def main(): polar_naca0012.cfg_file = "inv_NACA0012.cfg" polar_naca0012.polar = True polar_naca0012.test_iter = 10 - polar_naca0012.test_vals = [-1.206973, 4.234604, 0.013410, 0.073285] + polar_naca0012.test_vals = [-1.285568, 4.161371, 0.003627, 0.083095] polar_naca0012.test_vals_aarch64 = [-1.083394, 4.386134, 0.001588, 0.033513] polar_naca0012.command = TestCase.Command(exec = "compute_polar.py", param = "-i 11") # flaky test on arm64 @@ -327,7 +327,7 @@ def main(): flatplate.cfg_dir = "navierstokes/flatplate" flatplate.cfg_file = "lam_flatplate.cfg" flatplate.test_iter = 100 - flatplate.test_vals = [-6.397042, -0.919335, 0.001321, 0.025064, 2.361500, -2.336500, 0.000000, 0.000000] + flatplate.test_vals = [-6.499563, -1.020731, 0.001223, 0.028373, 2.361500, -2.333200, 0.000000, 0.000000] test_list.append(flatplate) # Custom objective function @@ -352,7 +352,7 @@ def main(): cylinder.cfg_dir = "navierstokes/cylinder" cylinder.cfg_file = "lam_cylinder.cfg" cylinder.test_iter = 25 - cylinder.test_vals = [-8.529918, -3.059339, 0.189560, 1.746170, 0.000000] + cylinder.test_vals = [-8.411856, -2.937460, -0.002360, 1.643164, 0.000000] test_list.append(cylinder) # Laminar cylinder (low Mach correction) @@ -360,7 +360,8 @@ def main(): cylinder_lowmach.cfg_dir = "navierstokes/cylinder" cylinder_lowmach.cfg_file = "cylinder_lowmach.cfg" cylinder_lowmach.test_iter = 25 - cylinder_lowmach.test_vals = [-6.603373, -1.141590, -0.715787, -63.545748, 0.000000] + cylinder_lowmach.test_vals = [-6.469910, -1.008163, -0.381561, 78.514909, 0.000000] + test_list.append(cylinder_lowmach) # 2D Poiseuille flow (body force driven with periodic inlet / outlet) @@ -368,7 +369,7 @@ def main(): poiseuille.cfg_dir = "navierstokes/poiseuille" poiseuille.cfg_file = "lam_poiseuille.cfg" poiseuille.test_iter = 10 - poiseuille.test_vals = [-5.050889, 0.648196, 0.000199, 13.639173, 0.000000] + poiseuille.test_vals = [0.648196, 0.000199, 13.639173, 0.000000] poiseuille.tol = 0.001 test_list.append(poiseuille) @@ -377,7 +378,7 @@ def main(): poiseuille_profile.cfg_dir = "navierstokes/poiseuille" poiseuille_profile.cfg_file = "profile_poiseuille.cfg" poiseuille_profile.test_iter = 10 - poiseuille_profile.test_vals = [-12.004334, -7.534404, -0.000000, 2.089953] + poiseuille_profile.test_vals = [-12.004278, -7.578183, -0.000000, 2.089953] poiseuille_profile.test_vals_aarch64 = [-12.007498, -7.226926, -0.000000, 2.089953] poiseuille_profile.tol = [0.001, 0.001, 1e-5, 1e-5, 1e-5] test_list.append(poiseuille_profile) @@ -391,7 +392,7 @@ def main(): rae2822_sa.cfg_dir = "rans/rae2822" rae2822_sa.cfg_file = "turb_SA_RAE2822.cfg" rae2822_sa.test_iter = 20 - rae2822_sa.test_vals = [-2.172705, -5.465982, 0.292927, 0.103369, 0.000000] + rae2822_sa.test_vals = [-2.190821, -5.317349, 0.391922, 0.075544, 0.000000] test_list.append(rae2822_sa) # RAE2822 SST @@ -399,7 +400,7 @@ def main(): rae2822_sst.cfg_dir = "rans/rae2822" rae2822_sst.cfg_file = "turb_SST_RAE2822.cfg" rae2822_sst.test_iter = 20 - rae2822_sst.test_vals = [-1.035662, 5.868036, 0.283073, 0.094756, 0.000000] + rae2822_sst.test_vals = [-1.035574, 5.863601, 0.358893, 0.074724, 0.000000] test_list.append(rae2822_sst) # RAE2822 SST_SUST @@ -407,7 +408,7 @@ def main(): rae2822_sst_sust.cfg_dir = "rans/rae2822" rae2822_sst_sust.cfg_file = "turb_SST_SUST_RAE2822.cfg" rae2822_sst_sust.test_iter = 20 - rae2822_sst_sust.test_vals = [-2.542992, 5.868021, 0.283073, 0.094756] + rae2822_sst_sust.test_vals = [-2.492136, 5.863586, 0.358893, 0.074724] test_list.append(rae2822_sst_sust) # Flat plate @@ -415,7 +416,7 @@ def main(): turb_flatplate.cfg_dir = "rans/flatplate" turb_flatplate.cfg_file = "turb_SA_flatplate.cfg" turb_flatplate.test_iter = 20 - turb_flatplate.test_vals = [-4.879863, -7.464877, -0.187760, 0.016260] + turb_flatplate.test_vals = [-4.926218, -7.441083, -0.187477, 0.015330] test_list.append(turb_flatplate) # Flat plate (compressible) with species inlet @@ -423,7 +424,7 @@ def main(): turb_flatplate_species.cfg_dir = "rans/flatplate" turb_flatplate_species.cfg_file = "turb_SA_flatplate_species.cfg" turb_flatplate_species.test_iter = 20 - turb_flatplate_species.test_vals = [-4.548766, -1.476908, -1.980237, 0.937064, -3.573976, 3.000000, -0.475230, 2.000000, -1.511528, 3.000000, -0.699313, 0.999900, 0.999900] + turb_flatplate_species.test_vals = [-4.728172, -1.517257, -2.296200, 0.801649, -3.574284, 3.000000, -0.964853, 2.000000, -1.529003, 3.000000, -0.705161, 0.999933, 0.999933] test_list.append(turb_flatplate_species) # Flat plate SST compressibility correction Wilcox @@ -491,7 +492,7 @@ def main(): turb_naca0012_sa.cfg_dir = "rans/naca0012" turb_naca0012_sa.cfg_file = "turb_NACA0012_sa.cfg" turb_naca0012_sa.test_iter = 5 - turb_naca0012_sa.test_vals = [-12.037518, -16.376951, 1.080346, 0.018385, 20, -1.564108, 20, -4.180957, 0] + turb_naca0012_sa.test_vals = [-12.037537, -16.376951, 1.080346, 0.018385, 20, -1.564109, 20, -4.180956, 0] turb_naca0012_sa.test_vals_aarch64 = [-12.037489, -16.376949, 1.080346, 0.018385, 20.000000, -1.564143, 20.000000, -4.180945, 0.000000] turb_naca0012_sa.timeout = 3200 test_list.append(turb_naca0012_sa) @@ -501,7 +502,7 @@ def main(): turb_naca0012_sst.cfg_dir = "rans/naca0012" turb_naca0012_sst.cfg_file = "turb_NACA0012_sst.cfg" turb_naca0012_sst.test_iter = 10 - turb_naca0012_sst.test_vals = [-12.094708, -15.251093, -5.906365, 1.070413, 0.015775, -2.376072, 0] + turb_naca0012_sst.test_vals = [-12.094646, -15.251093, -5.906365, 1.070413, 0.015775, -2.376189, 0] turb_naca0012_sst.test_vals_aarch64 = [-12.075620, -15.246688, -5.861276, 1.070036, 0.015841, -1.991001, 0.000000] turb_naca0012_sst.timeout = 3200 test_list.append(turb_naca0012_sst) @@ -511,7 +512,7 @@ def main(): turb_naca0012_sst_sust.cfg_dir = "rans/naca0012" turb_naca0012_sst_sust.cfg_file = "turb_NACA0012_sst_sust.cfg" turb_naca0012_sst_sust.test_iter = 10 - turb_naca0012_sst_sust.test_vals = [-12.082012, -14.837177, -5.733436, 1.000893, 0.019109, -2.241076] + turb_naca0012_sst_sust.test_vals = [-12.082080, -14.837177, -5.733436, 1.000893, 0.019109, -2.241006] turb_naca0012_sst_sust.test_vals_aarch64 = [-12.073964, -14.836726, -5.732390, 1.000050, 0.019144, -2.229074] turb_naca0012_sst_sust.timeout = 3200 test_list.append(turb_naca0012_sst_sust) @@ -521,7 +522,7 @@ def main(): turb_naca0012_sst_2003_Vm.cfg_dir = "rans/naca0012" turb_naca0012_sst_2003_Vm.cfg_file = "turb_NACA0012_sst_2003-Vm.cfg" turb_naca0012_sst_2003_Vm.test_iter = 10 - turb_naca0012_sst_2003_Vm.test_vals = [-7.134118, -10.168739, -3.668709, 1.060563, 0.019147, -2.282800] + turb_naca0012_sst_2003_Vm.test_vals = [-10.168739, -3.668709, 1.060563, 0.019147, -2.282800] turb_naca0012_sst_2003_Vm.timeout = 3200 test_list.append(turb_naca0012_sst_2003_Vm) @@ -530,7 +531,7 @@ def main(): turb_naca0012_sst_1994_KLm.cfg_dir = "rans/naca0012" turb_naca0012_sst_1994_KLm.cfg_file = "turb_NACA0012_sst_1994-KLm.cfg" turb_naca0012_sst_1994_KLm.test_iter = 10 - turb_naca0012_sst_1994_KLm.test_vals = [-7.142696, -10.390871, -3.701584, 1.062164, 0.019076, -2.426123] + turb_naca0012_sst_1994_KLm.test_vals = [-10.390871, -3.701584, 1.062164, 0.019076, -2.426123] turb_naca0012_sst_1994_KLm.timeout = 3200 test_list.append(turb_naca0012_sst_1994_KLm) @@ -539,7 +540,7 @@ def main(): turb_naca0012_sst_fixedvalues.cfg_dir = "rans/naca0012" turb_naca0012_sst_fixedvalues.cfg_file = "turb_NACA0012_sst_fixedvalues.cfg" turb_naca0012_sst_fixedvalues.test_iter = 10 - turb_naca0012_sst_fixedvalues.test_vals = [-5.216551, -10.440018, 0.774146, 1.022363, 0.040546, -3.736444] + turb_naca0012_sst_fixedvalues.test_vals = [-10.440018, 0.774146, 1.022363, 0.040546, -3.736444] turb_naca0012_sst_fixedvalues.timeout = 3200 test_list.append(turb_naca0012_sst_fixedvalues) @@ -548,7 +549,7 @@ def main(): turb_naca0012_sst_expliciteuler.cfg_dir = "rans/naca0012" turb_naca0012_sst_expliciteuler.cfg_file = "turb_NACA0012_sst_expliciteuler.cfg" turb_naca0012_sst_expliciteuler.test_iter = 10 - turb_naca0012_sst_expliciteuler.test_vals = [-3.532365, -3.157224, 3.743381, 1.124798, 0.501715, -float("inf")] + turb_naca0012_sst_expliciteuler.test_vals = [-3.532365, -3.157224, 3.743381, 1.124798, 0.501715, -16.000000] turb_naca0012_sst_expliciteuler.timeout = 3200 test_list.append(turb_naca0012_sst_expliciteuler) @@ -580,7 +581,7 @@ def main(): axi_rans_air_nozzle_restart.cfg_dir = "axisymmetric_rans/air_nozzle" axi_rans_air_nozzle_restart.cfg_file = "air_nozzle_restart.cfg" axi_rans_air_nozzle_restart.test_iter = 10 - axi_rans_air_nozzle_restart.test_vals = [-12.069351, -7.507867, -8.813423, -3.732860, 0] + axi_rans_air_nozzle_restart.test_vals = [-12.069346, -7.508216, -8.813393, -3.732843, 0] axi_rans_air_nozzle_restart.test_vals_aarch64 = [-14.143310, -9.163287, -10.858232, -5.787715, 0.000000] axi_rans_air_nozzle_restart.tol = 0.0001 test_list.append(axi_rans_air_nozzle_restart) @@ -595,7 +596,7 @@ def main(): turb_naca0012_sst_restart_mg.cfg_file = "turb_NACA0012_sst_multigrid_restart.cfg" turb_naca0012_sst_restart_mg.test_iter = 20 turb_naca0012_sst_restart_mg.ntest_vals = 5 - turb_naca0012_sst_restart_mg.test_vals = [-6.538846, -5.057149, 0.830238, -0.008740, 0.078171] + turb_naca0012_sst_restart_mg.test_vals = [-6.566570, -5.057149, 0.830238, -0.008695, 0.078156] turb_naca0012_sst_restart_mg.timeout = 3200 turb_naca0012_sst_restart_mg.tol = 0.000001 test_list.append(turb_naca0012_sst_restart_mg) @@ -609,7 +610,7 @@ def main(): inc_euler_naca0012.cfg_dir = "incomp_euler/naca0012" inc_euler_naca0012.cfg_file = "incomp_NACA0012.cfg" inc_euler_naca0012.test_iter = 20 - inc_euler_naca0012.test_vals = [-5.984413, -5.104039, 0.523625, 0.008885] + inc_euler_naca0012.test_vals = [-6.058441, -5.126560, 0.525681, 0.008778] test_list.append(inc_euler_naca0012) # C-D nozzle with pressure inlet and mass flow outlet @@ -617,7 +618,7 @@ def main(): inc_nozzle.cfg_dir = "incomp_euler/nozzle" inc_nozzle.cfg_file = "inv_nozzle.cfg" inc_nozzle.test_iter = 20 - inc_nozzle.test_vals = [-5.594509, -4.878247, 0.005147, 0.139611] + inc_nozzle.test_vals = [-6.058643, -5.286249, 0.002391, 0.124107] test_list.append(inc_nozzle) # Laminar wall mounted cylinder, Euler walls, cylinder wall diagonally split @@ -637,7 +638,7 @@ def main(): inc_lam_cylinder.cfg_dir = "incomp_navierstokes/cylinder" inc_lam_cylinder.cfg_file = "incomp_cylinder.cfg" inc_lam_cylinder.test_iter = 10 - inc_lam_cylinder.test_vals = [-4.157264, -3.589125, -0.018681, 4.659302] + inc_lam_cylinder.test_vals = [-4.156152, -3.554127, -0.017923, 5.101126] test_list.append(inc_lam_cylinder) # Laminar sphere, Re=1. Last column: Cd=24/Re @@ -645,7 +646,7 @@ def main(): inc_lam_sphere.cfg_dir = "incomp_navierstokes/sphere" inc_lam_sphere.cfg_file = "sphere.cfg" inc_lam_sphere.test_iter = 5 - inc_lam_sphere.test_vals = [-8.166398, -8.947226, 0.121003, 25.782690] + inc_lam_sphere.test_vals = [-8.165744, -8.968003, 0.121003, 25.782691] test_list.append(inc_lam_sphere) # Buoyancy-driven cavity @@ -661,7 +662,7 @@ def main(): inc_poly_cylinder.cfg_dir = "incomp_navierstokes/cylinder" inc_poly_cylinder.cfg_file = "poly_cylinder.cfg" inc_poly_cylinder.test_iter = 20 - inc_poly_cylinder.test_vals = [-8.030976, -2.362995, 0.006829, 1.923532, -172.590000] + inc_poly_cylinder.test_vals = [-2.362995, 0.006829, 1.923532, -172.590000] test_list.append(inc_poly_cylinder) # X-coarse laminar bend as a mixed element CGNS test @@ -783,7 +784,7 @@ def main(): turbmod_sa_bsl_rae2822.cfg_dir = "turbulence_models/sa/rae2822" turbmod_sa_bsl_rae2822.cfg_file = "turb_SA_BSL_RAE2822.cfg" turbmod_sa_bsl_rae2822.test_iter = 20 - turbmod_sa_bsl_rae2822.test_vals = [-2.610446, 0.335724, -0.118510, -5.463071, 0.765741, 0.028251] + turbmod_sa_bsl_rae2822.test_vals = [-2.797759, 0.171338, -0.274795, -5.261510, 0.792586, 0.025577] test_list.append(turbmod_sa_bsl_rae2822) # SA Negative @@ -791,7 +792,7 @@ def main(): turbmod_sa_neg_rae2822.cfg_dir = "turbulence_models/sa/rae2822" turbmod_sa_neg_rae2822.cfg_file = "turb_SA_NEG_RAE2822.cfg" turbmod_sa_neg_rae2822.test_iter = 10 - turbmod_sa_neg_rae2822.test_vals = [-1.345556, 1.448390, 1.208561, -0.846814, 1.273854, 0.498380, 0.000000] + turbmod_sa_neg_rae2822.test_vals = [1.448390, 1.208561, -0.846814, 1.273854, 0.498380, 0.000000] turbmod_sa_neg_rae2822.test_vals_aarch64 = [-1.345593, 1.448310, 1.208721, -0.846597, 1.248410, 0.489117, 0.000000] test_list.append(turbmod_sa_neg_rae2822) @@ -800,7 +801,7 @@ def main(): turbmod_sa_comp_rae2822.cfg_dir = "turbulence_models/sa/rae2822" turbmod_sa_comp_rae2822.cfg_file = "turb_SA_COMP_RAE2822.cfg" turbmod_sa_comp_rae2822.test_iter = 20 - turbmod_sa_comp_rae2822.test_vals = [-2.610449, 0.335720, -0.118515, -5.468848, 0.765768, 0.028257] + turbmod_sa_comp_rae2822.test_vals = [-2.797713, 0.171400, -0.274750, -5.270451, 0.792619, 0.025579] test_list.append(turbmod_sa_comp_rae2822) # SA Edwards @@ -808,7 +809,7 @@ def main(): turbmod_sa_edw_rae2822.cfg_dir = "turbulence_models/sa/rae2822" turbmod_sa_edw_rae2822.cfg_file = "turb_SA_EDW_RAE2822.cfg" turbmod_sa_edw_rae2822.test_iter = 20 - turbmod_sa_edw_rae2822.test_vals = [-2.609968, 0.336105, -0.118179, -6.022707, 0.765928, 0.028192] + turbmod_sa_edw_rae2822.test_vals = [-2.798216, 0.171419, -0.274673, -5.950380, 0.793286, 0.025430] test_list.append(turbmod_sa_edw_rae2822) # SA Compressibility and Edwards @@ -816,7 +817,7 @@ def main(): turbmod_sa_comp_edw_rae2822.cfg_dir = "turbulence_models/sa/rae2822" turbmod_sa_comp_edw_rae2822.cfg_file = "turb_SA_COMP_EDW_RAE2822.cfg" turbmod_sa_comp_edw_rae2822.test_iter = 20 - turbmod_sa_comp_edw_rae2822.test_vals = [-2.610041, 0.336057, -0.118225, -6.023847, 0.765944, 0.028196] + turbmod_sa_comp_edw_rae2822.test_vals = [-2.804013, 0.164355, -0.281124, -5.949769, 0.793596, 0.025415] test_list.append(turbmod_sa_comp_edw_rae2822) # SA QCR @@ -824,7 +825,7 @@ def main(): turbmod_sa_qcr_rae2822.cfg_dir = "turbulence_models/sa/rae2822" turbmod_sa_qcr_rae2822.cfg_file = "turb_SA_QCR_RAE2822.cfg" turbmod_sa_qcr_rae2822.test_iter = 20 - turbmod_sa_qcr_rae2822.test_vals = [-2.320855, 0.512787, 0.108026, -5.449178, 0.770698, 0.026693] + turbmod_sa_qcr_rae2822.test_vals = [-2.818005, 0.149744, -0.284903, -5.229322, 0.793829, 0.025455] test_list.append(turbmod_sa_qcr_rae2822) ############################ @@ -848,7 +849,7 @@ def main(): contadj_naca0012.cfg_dir = "cont_adj_euler/naca0012" contadj_naca0012.cfg_file = "inv_NACA0012.cfg" contadj_naca0012.test_iter = 5 - contadj_naca0012.test_vals = [-9.520784, -15.101278, -0.726250, 0.020280] + contadj_naca0012.test_vals = [-9.526111, -15.089167, -0.726250, 0.020280] contadj_naca0012.test_vals_aarch64 = [-9.662546, -14.998818, -0.726250, 0.020280] test_list.append(contadj_naca0012) @@ -857,7 +858,7 @@ def main(): contadj_oneram6.cfg_dir = "cont_adj_euler/oneram6" contadj_oneram6.cfg_file = "inv_ONERAM6.cfg" contadj_oneram6.test_iter = 10 - contadj_oneram6.test_vals = [-12.069374, -12.632463, -1.086100, 0.007556] + contadj_oneram6.test_vals = [-12.086022, -12.648069, -1.086100, 0.007556] test_list.append(contadj_oneram6) # Inviscid WEDGE: tests averaged outflow total pressure adjoint @@ -873,7 +874,7 @@ def main(): contadj_fixed_CL_naca0012.cfg_dir = "fixed_cl/naca0012" contadj_fixed_CL_naca0012.cfg_file = "inv_NACA0012_ContAdj.cfg" contadj_fixed_CL_naca0012.test_iter = 100 - contadj_fixed_CL_naca0012.test_vals = [1.154889, -4.342907, -0.075177, -0.007496] + contadj_fixed_CL_naca0012.test_vals = [1.382576, -4.042295, -0.008696, 0.003238] test_list.append(contadj_fixed_CL_naca0012) ################################### @@ -885,7 +886,7 @@ def main(): contadj_ns_cylinder.cfg_dir = "cont_adj_navierstokes/cylinder" contadj_ns_cylinder.cfg_file = "lam_cylinder.cfg" contadj_ns_cylinder.test_iter = 20 - contadj_ns_cylinder.test_vals = [-3.589714, -9.027143, 2.056700, -0.000000] + contadj_ns_cylinder.test_vals = [-3.632833, -9.087692, 2.056700, -0.000000] test_list.append(contadj_ns_cylinder) # Adjoint laminar naca0012 subsonic @@ -929,7 +930,7 @@ def main(): contadj_rans_rae2822.cfg_dir = "cont_adj_rans/rae2822" contadj_rans_rae2822.cfg_file = "turb_SA_RAE2822.cfg" contadj_rans_rae2822.test_iter = 20 - contadj_rans_rae2822.test_vals = [-5.399633, -10.904666, -0.212470, 0.005448] + contadj_rans_rae2822.test_vals = [-5.399744, -10.904916, -0.212470, 0.005448] test_list.append(contadj_rans_rae2822) ############################# @@ -1009,7 +1010,7 @@ def main(): rot_naca0012.cfg_dir = "rotating/naca0012" rot_naca0012.cfg_file = "rot_NACA0012.cfg" rot_naca0012.test_iter = 25 - rot_naca0012.test_vals = [-1.302487, 4.220598, -0.002152, 0.124241] + rot_naca0012.test_vals = [-1.289907, 4.246244, -0.000518, 0.112723] test_list.append(rot_naca0012) # Lid-driven cavity @@ -1017,7 +1018,7 @@ def main(): cavity.cfg_dir = "moving_wall/cavity" cavity.cfg_file = "lam_cavity.cfg" cavity.test_iter = 25 - cavity.test_vals = [-8.194578, -2.735580, 0.005612, -0.019805] + cavity.test_vals = [-7.828480, -2.367075, 0.008928, 0.007370] test_list.append(cavity) # Spinning cylinder @@ -1025,7 +1026,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.716789, -2.257294, 2.054821, 1.660858] + spinning_cylinder.test_vals = [-7.383987, -1.919413, 2.601945, 1.976038] test_list.append(spinning_cylinder) ###################################### @@ -1046,7 +1047,7 @@ def main(): sine_gust.cfg_dir = "gust" sine_gust.cfg_file = "inv_gust_NACA0012.cfg" sine_gust.test_iter = 5 - sine_gust.test_vals = [-1.977498, 3.481817, -0.010372, -0.005217] + sine_gust.test_vals = [-1.977498, 3.481817, -0.010337, -0.004460] sine_gust.unsteady = True test_list.append(sine_gust) @@ -1084,7 +1085,7 @@ def main(): flatplate_unsteady.cfg_dir = "navierstokes/flatplate" flatplate_unsteady.cfg_file = "lam_flatplate_unst.cfg" flatplate_unsteady.test_iter = 3 - flatplate_unsteady.test_vals = [-8.875128, -8.250204, -6.305788, -5.469452, -3.398230, 0.002075, -0.325535] + flatplate_unsteady.test_vals = [0.000008, -8.875128, -8.250204, -6.305788, -5.469452, -3.398230, 0.002075, -0.325535] flatplate_unsteady.unsteady = True test_list.append(flatplate_unsteady) @@ -1097,15 +1098,15 @@ def main(): edge_VW.cfg_dir = "nicf/edge" edge_VW.cfg_file = "edge_VW.cfg" edge_VW.test_iter = 25 - edge_VW.test_vals = [-3.178712, 3.023048, -0.000009, 0.000000] + edge_VW.test_vals = [-3.145553, 3.055761, -0.000009, 0.000000] test_list.append(edge_VW) # Rarefaction shock wave edge_PPR edge_PPR = TestCase('edge_PPR') edge_PPR.cfg_dir = "nicf/edge" edge_PPR.cfg_file = "edge_PPR.cfg" - edge_PPR.test_iter = 25 - edge_PPR.test_vals = [-9.020461, -2.870274, -0.000034, 0.000000] + edge_PPR.test_iter = 20 + edge_PPR.test_vals = [-10.311364, -4.158193, -0.000034, 0.000000] test_list.append(edge_PPR) # Rarefaction Q1D nozzle, include CoolProp fluid model @@ -1252,7 +1253,7 @@ def main(): bars_SST_2D.cfg_dir = "sliding_interface/bars_SST_2D" bars_SST_2D.cfg_file = "bars.cfg" bars_SST_2D.test_iter = 13 - bars_SST_2D.test_vals = [13.000000, -0.472766, -1.559919] + bars_SST_2D.test_vals = [13.000000, -0.397743, -1.458724] bars_SST_2D.multizone = True test_list.append(bars_SST_2D) @@ -1357,15 +1358,6 @@ def main(): fsi2d.unsteady = True test_list.append(fsi2d) - # FSI, Static, 2D, new mesh solver - stat_fsi = TestCase('stat_fsi') - stat_fsi.cfg_dir = "fea_fsi/stat_fsi" - stat_fsi.cfg_file = "config.cfg" - stat_fsi.test_iter = 7 - stat_fsi.test_vals = [-3.301938, -4.971986, 0.000000, 11.000000] - stat_fsi.multizone = True - test_list.append(stat_fsi) - # FSI, Dynamic, 2D, new mesh solver dyn_fsi = TestCase('dyn_fsi') dyn_fsi.cfg_dir = "fea_fsi/dyn_fsi" @@ -1376,15 +1368,6 @@ def main(): dyn_fsi.unsteady = True test_list.append(dyn_fsi) - # FSI, Static, 2D, new mesh solver, restart - stat_fsi_restart = TestCase('stat_fsi_restart') - stat_fsi_restart.cfg_dir = "fea_fsi/stat_fsi" - stat_fsi_restart.cfg_file = "config_restart.cfg" - stat_fsi_restart.test_iter = 1 - stat_fsi_restart.test_vals = [-3.486655, -4.425104, 0.000000, 27.000000] - stat_fsi_restart.multizone = True - test_list.append(stat_fsi_restart) - # ############################### # ### Radiative Heat Transfer ### # ############################### @@ -1461,7 +1444,7 @@ def main(): pywrapper_naca0012.cfg_dir = "euler/naca0012" pywrapper_naca0012.cfg_file = "inv_NACA0012_Roe.cfg" pywrapper_naca0012.test_iter = 80 - pywrapper_naca0012.test_vals = [-7.755848, -7.082517, 0.335769, 0.023275] + pywrapper_naca0012.test_vals = [-6.754892, -6.158544, 0.335712, 0.023273] pywrapper_naca0012.command = TestCase.Command("mpirun -np 2", "SU2_CFD.py", "--parallel -f") test_list.append(pywrapper_naca0012) @@ -1470,7 +1453,7 @@ def main(): pywrapper_turb_naca0012_sst.cfg_dir = "rans/naca0012" pywrapper_turb_naca0012_sst.cfg_file = "turb_NACA0012_sst.cfg" pywrapper_turb_naca0012_sst.test_iter = 10 - pywrapper_turb_naca0012_sst.test_vals = [-12.094708, -15.251093, -5.906365, 1.070413, 0.015775, -2.376072, 0] + pywrapper_turb_naca0012_sst.test_vals = [-12.094646, -15.251093, -5.906365, 1.070413, 0.015775, -2.376189, 0] pywrapper_turb_naca0012_sst.test_vals_aarch64 = [-12.075620, -15.246688, -5.861276, 1.070036, 0.015841, -1.991001, 0.000000] pywrapper_turb_naca0012_sst.command = TestCase.Command("mpirun -np 2", "SU2_CFD.py", "--parallel -f") pywrapper_turb_naca0012_sst.timeout = 3200 @@ -1491,7 +1474,7 @@ def main(): pywrapper_aeroelastic.cfg_dir = "aeroelastic" pywrapper_aeroelastic.cfg_file = "aeroelastic_NACA64A010.cfg" pywrapper_aeroelastic.test_iter = 2 - pywrapper_aeroelastic.test_vals = [-1.876634, 4.021068, 0.081002, 0.027610, -0.001642, -0.000127, -0.966944] + pywrapper_aeroelastic.test_vals = [-1.876633, 4.021069, 0.082654, 0.027642, -0.001643, -0.000126, -0.966946] pywrapper_aeroelastic.command = TestCase.Command("mpirun -np 2", "SU2_CFD.py", "--parallel -f") pywrapper_aeroelastic.unsteady = True test_list.append(pywrapper_aeroelastic) @@ -1532,7 +1515,7 @@ def main(): pywrapper_unsteadyCHT.cfg_dir = "py_wrapper/flatPlate_unsteady_CHT" pywrapper_unsteadyCHT.cfg_file = "unsteady_CHT_FlatPlate_Conf.cfg" pywrapper_unsteadyCHT.test_iter = 5 - pywrapper_unsteadyCHT.test_vals = [-1.614168, 2.259984, -0.005601, 0.129785] + pywrapper_unsteadyCHT.test_vals = [-1.614168, 2.259968, -0.010622, 0.171621] pywrapper_unsteadyCHT.command = TestCase.Command("mpirun -np 2", "python", "launch_unsteady_CHT_FlatPlate.py --parallel -f") pywrapper_unsteadyCHT.unsteady = True test_list.append(pywrapper_unsteadyCHT) @@ -1804,7 +1787,7 @@ def main(): cfd_flamelet_ch4_cht.cfg_dir = "flamelet/03_laminar_premixed_ch4_flame_cht_cfd" cfd_flamelet_ch4_cht.cfg_file = "lam_prem_ch4_cht_cfd_master.cfg" cfd_flamelet_ch4_cht.test_iter = 5 - cfd_flamelet_ch4_cht.test_vals = [-9.824525, -8.913124, -9.862973, -11.271228, -3.238372, -10.916614, -12.615134, -6.614396] + cfd_flamelet_ch4_cht.test_vals = [-7.223149, -6.338839, -8.334392, -10.410156, -3.171365, -10.884464, -12.615132, -6.614396] cfd_flamelet_ch4_cht.timeout = 1600 cfd_flamelet_ch4_cht.multizone = True test_list.append(cfd_flamelet_ch4_cht) diff --git a/TestCases/parallel_regression_AD.py b/TestCases/parallel_regression_AD.py index 812c8aeb9dab..cc4b94931bf7 100644 --- a/TestCases/parallel_regression_AD.py +++ b/TestCases/parallel_regression_AD.py @@ -104,7 +104,7 @@ def main(): discadj_incomp_NACA0012.cfg_dir = "disc_adj_incomp_euler/naca0012" discadj_incomp_NACA0012.cfg_file = "incomp_NACA0012_disc.cfg" discadj_incomp_NACA0012.test_iter = 20 - discadj_incomp_NACA0012.test_vals = [20.000000, -3.319959, -2.489110, 0.000000] + discadj_incomp_NACA0012.test_vals = [20.000000, -3.095094, -2.322528, 0.000000] test_list.append(discadj_incomp_NACA0012) ##################################### @@ -217,7 +217,7 @@ def main(): discadj_pitchingNACA0012.cfg_dir = "disc_adj_euler/naca0012_pitching" discadj_pitchingNACA0012.cfg_file = "inv_NACA0012_pitching.cfg" discadj_pitchingNACA0012.test_iter = 4 - discadj_pitchingNACA0012.test_vals = [-1.126077, -1.582787, -0.005904, 0.000009] + discadj_pitchingNACA0012.test_vals = [-1.040215, -1.508864, -0.006076, 0.000012] discadj_pitchingNACA0012.tol = 0.01 discadj_pitchingNACA0012.unsteady = True test_list.append(discadj_pitchingNACA0012) @@ -231,7 +231,7 @@ 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.000000, 2.599441, 2.336307, 2.140979, 0.786891] + discadj_trans_stator.test_vals = [79.000000, 2.555965, 2.327109, 2.115689, 0.745501] discadj_trans_stator.test_vals_aarch64 = [79.000000, 0.696755, 0.485950, 0.569475, -0.990065] test_list.append(discadj_trans_stator) @@ -342,7 +342,7 @@ def main(): discadj_flamelet_ch4_hx.cfg_file = "lam_prem_ch4_hx_ad.cfg" discadj_flamelet_ch4_hx.multizone = False discadj_flamelet_ch4_hx.test_iter = 10 - discadj_flamelet_ch4_hx.test_vals = [-12.782056, -13.049168, -13.441039, -11.710302, -18.821992, -8.887596, -18.882447] + discadj_flamelet_ch4_hx.test_vals = [-9.078706, -9.025745, -9.516205, -8.434002, -15.386905, -8.887596, -18.881167] test_list.append(discadj_flamelet_ch4_hx) # 2D planar laminar premixed flame on isothermal burner with conjugate heat transfer (restart) @@ -351,7 +351,7 @@ def main(): discadj_flamelet_ch4_cht.cfg_file = "lam_prem_ch4_cht_ad_master.cfg" discadj_flamelet_ch4_cht.multizone = True discadj_flamelet_ch4_cht.test_iter = 10 - discadj_flamelet_ch4_cht.test_vals = [-1.543982, 0.628666, -6.533516, -18.651097, -18.648552, -3.794724, -6.561913, 11.000000] + discadj_flamelet_ch4_cht.test_vals = [-1.545058, 0.628666, -6.533534, -18.651078, -18.648552, -3.794724, -6.561913, 11.000000] test_list.append(discadj_flamelet_ch4_cht) ###################################### diff --git a/TestCases/py_wrapper/translating_NACA0012/forces_0.csv.ref b/TestCases/py_wrapper/translating_NACA0012/forces_0.csv.ref index 696f6078c386..5d4e8e3e99e7 100644 --- a/TestCases/py_wrapper/translating_NACA0012/forces_0.csv.ref +++ b/TestCases/py_wrapper/translating_NACA0012/forces_0.csv.ref @@ -1,200 +1,200 @@ -199, -0.97, -0.00, 0.00 +199, -0.96, -0.00, 0.00 0, -2.88, 19.83, 0.00 -1, -4.23, 29.14, 0.00 -2, -5.32, 36.73, 0.00 -3, -6.40, 44.31, 0.00 -4, -7.29, 50.60, 0.00 -5, -8.10, 56.42, 0.00 -6, -8.75, 61.21, 0.00 -7, -9.32, 65.49, 0.00 -8, -9.74, 68.79, 0.00 -9, -10.10, 71.74, 0.00 -10, -10.31, 73.69, 0.00 -11, -10.46, 75.35, 0.00 -12, -10.47, 76.00, 0.00 -13, -10.44, 76.40, 0.00 -14, -10.26, 75.71, 0.00 -15, -10.11, 75.29, 0.00 -16, -9.80, 73.70, 0.00 -17, -9.64, 73.29, 0.00 -18, -9.24, 70.95, 0.00 -19, -8.85, 68.73, 0.00 -20, -8.25, 64.81, 0.00 -21, -7.82, 62.19, 0.00 -22, -7.14, 57.56, 0.00 -23, -6.71, 54.74, 0.00 -24, -5.95, 49.24, 0.00 -25, -5.71, 47.88, 0.00 -26, -4.78, 40.72, 0.00 -27, -4.44, 38.38, 0.00 -28, -3.40, 29.82, 0.00 -29, -2.77, 24.72, 0.00 -30, -1.56, 14.15, 0.00 -31, -0.95, 8.74, 0.00 -32, 0.27, -2.57, 0.00 -33, 1.50, -14.37, 0.00 -34, 2.95, -28.80, 0.00 -35, 4.95, -49.22, 0.00 -36, 6.34, -64.46, 0.00 -37, 8.93, -92.82, 0.00 -38, 10.11, -107.58, 0.00 -39, 12.72, -138.81, 0.00 -40, 13.61, -152.47, 0.00 -41, 17.42, -200.74, 0.00 -42, 18.00, -213.73, 0.00 -43, 20.51, -251.51, 0.00 -44, 20.54, -260.85, 0.00 -45, 22.50, -296.71, 0.00 -46, 22.34, -306.87, 0.00 -47, 23.59, -338.75, 0.00 -48, 23.03, -347.38, 0.00 -49, 23.93, -380.83, 0.00 -50, 22.45, -379.32, 0.00 -51, 20.75, -374.79, 0.00 -52, 18.42, -358.59, 0.00 -53, 15.34, -325.29, 0.00 -54, 13.36, -312.48, 0.00 -55, 10.43, -273.29, 0.00 -56, 9.04, -271.47, 0.00 -57, 6.53, -231.40, 0.00 -58, 6.09, -266.47, 0.00 -59, 5.99, -346.96, 0.00 -60, 4.63, -406.68, 0.00 -61, 2.25, -429.96, 0.00 -62, -0.52, -423.85, 0.00 -63, -3.28, -409.29, 0.00 -64, -6.04, -398.86, 0.00 -65, -8.60, -380.50, 0.00 -66, -11.15, -366.37, 0.00 -67, -13.55, -350.18, 0.00 -68, -15.78, -333.45, 0.00 -69, -17.95, -317.94, 0.00 -70, -19.76, -299.23, 0.00 -71, -21.49, -282.21, 0.00 -72, -22.61, -260.41, 0.00 -73, -24.40, -248.66, 0.00 -74, -25.13, -228.22, 0.00 -75, -25.20, -205.09, 0.00 -76, -24.79, -181.60, 0.00 -77, -24.32, -160.97, 0.00 -78, -23.96, -143.67, 0.00 -79, -21.95, -119.46, 0.00 -80, -20.65, -102.16, 0.00 -81, -20.28, -91.26, 0.00 -82, -19.07, -78.04, 0.00 -83, -17.20, -63.96, 0.00 -84, -13.15, -44.35, 0.00 -85, -6.18, -18.88, 0.00 -86, 1.48, 4.08, 0.00 -87, 4.97, 12.30, 0.00 -88, 13.95, 30.78, 0.00 -89, 13.05, 25.52, 0.00 -90, 39.01, 66.93, 0.00 -91, 34.95, 51.96, 0.00 -92, 10.01, 12.67, 0.00 -93, 12.23, 12.90, 0.00 -94, 14.63, 12.43, 0.00 -95, 3.85, 2.51, 0.00 -96, -58.89, -26.99, 0.00 -97, -58.75, -15.90, 0.00 -98, -114.76, -15.40, 0.00 -99, 44.44, -0.00, 0.00 -100, -6.17, 0.83, 0.00 -101, 92.06, -24.91, 0.00 -102, 144.41, -66.19, 0.00 -103, 183.90, -119.78, 0.00 -104, 81.69, -69.39, 0.00 -105, 58.16, -61.33, 0.00 -106, 54.39, -68.88, 0.00 -107, 20.73, -30.81, 0.00 -108, 15.21, -26.10, 0.00 -109, -5.66, 11.08, 0.00 -110, -10.96, 24.19, 0.00 -111, -22.60, 55.88, 0.00 -112, -24.49, 67.42, 0.00 -113, -35.46, 108.24, 0.00 -114, -39.42, 132.94, 0.00 -115, -44.81, 166.57, 0.00 -116, -45.54, 186.33, 0.00 -117, -47.93, 215.64, 0.00 -118, -48.48, 239.82, 0.00 -119, -49.35, 268.61, 0.00 -120, -49.01, 293.88, 0.00 -121, -48.31, 319.72, 0.00 -122, -46.79, 342.80, 0.00 -123, -45.53, 370.47, 0.00 -124, -43.31, 393.24, 0.00 -125, -41.11, 418.88, 0.00 -126, -38.44, 442.69, 0.00 -127, -35.61, 467.64, 0.00 -128, -32.31, 489.28, 0.00 -129, -28.84, 510.98, 0.00 -130, -25.18, 532.04, 0.00 -131, -21.39, 553.10, 0.00 -132, -17.41, 571.76, 0.00 -133, -13.39, 592.26, 0.00 -134, -9.24, 610.35, 0.00 -135, -5.05, 629.44, 0.00 -136, -0.80, 646.65, 0.00 -137, 3.47, 663.79, 0.00 -138, 7.73, 678.32, 0.00 -139, 11.97, 693.15, 0.00 -140, 16.16, 706.43, 0.00 -141, 20.25, 717.98, 0.00 -142, 24.27, 728.83, 0.00 -143, 28.17, 738.33, 0.00 -144, 31.95, 747.06, 0.00 -145, 35.57, 754.00, 0.00 -146, 39.07, 760.46, 0.00 -147, 42.33, 764.49, 0.00 -148, 45.53, 769.28, 0.00 -149, 48.66, 774.52, 0.00 -150, 51.68, 779.40, 0.00 -151, 55.24, 793.46, 0.00 -152, 57.48, 789.62, 0.00 -153, 55.23, 728.32, 0.00 -154, 58.05, 737.21, 0.00 -155, 70.62, 866.19, 0.00 -156, 62.28, 739.59, 0.00 -157, 53.43, 615.64, 0.00 -158, 50.31, 563.60, 0.00 -159, 35.26, 384.74, 0.00 -160, 38.05, 404.94, 0.00 -161, 10.14, 105.39, 0.00 -162, 5.42, 55.09, 0.00 -163, -5.93, -59.00, 0.00 -164, -8.98, -87.52, 0.00 -165, -4.77, -45.59, 0.00 -166, -4.28, -40.14, 0.00 -167, -4.62, -42.60, 0.00 -168, -5.24, -47.52, 0.00 -169, -5.86, -52.28, 0.00 -170, -6.59, -57.83, 0.00 -171, -6.84, -59.11, 0.00 -172, -7.47, -63.60, 0.00 -173, -7.82, -65.59, 0.00 -174, -8.57, -70.89, 0.00 -175, -9.11, -74.38, 0.00 -176, -9.74, -78.44, 0.00 -177, -9.79, -77.88, 0.00 -178, -10.24, -80.44, 0.00 -179, -10.40, -80.83, 0.00 -180, -10.78, -82.78, 0.00 -181, -10.97, -83.35, 0.00 -182, -11.18, -84.12, 0.00 -183, -11.31, -84.24, 0.00 -184, -11.41, -84.21, 0.00 -185, -11.47, -83.91, 0.00 -186, -11.29, -81.91, 0.00 -187, -11.22, -80.81, 0.00 -188, -11.03, -78.90, 0.00 -189, -10.50, -74.56, 0.00 -190, -10.05, -70.94, 0.00 -191, -9.49, -66.66, 0.00 -192, -8.86, -61.95, 0.00 -193, -8.10, -56.41, 0.00 -194, -7.28, -50.51, 0.00 -195, -6.28, -43.47, 0.00 -196, -5.22, -36.04, 0.00 -197, -3.99, -27.53, 0.00 -198, -2.69, -18.50, 0.00 +1, -4.18, 28.79, 0.00 +2, -5.26, 36.27, 0.00 +3, -6.22, 43.06, 0.00 +4, -7.06, 48.99, 0.00 +5, -7.74, 53.91, 0.00 +6, -8.33, 58.23, 0.00 +7, -8.78, 61.68, 0.00 +8, -9.13, 64.48, 0.00 +9, -9.36, 66.46, 0.00 +10, -9.49, 67.87, 0.00 +11, -9.52, 68.60, 0.00 +12, -9.47, 68.72, 0.00 +13, -9.30, 68.08, 0.00 +14, -9.07, 66.93, 0.00 +15, -8.74, 65.11, 0.00 +16, -8.36, 62.92, 0.00 +17, -7.90, 60.05, 0.00 +18, -7.40, 56.86, 0.00 +19, -6.82, 53.00, 0.00 +20, -6.21, 48.82, 0.00 +21, -5.55, 44.16, 0.00 +22, -4.86, 39.18, 0.00 +23, -4.12, 33.67, 0.00 +24, -3.37, 27.85, 0.00 +25, -2.57, 21.54, 0.00 +26, -1.75, 14.91, 0.00 +27, -0.89, 7.67, 0.00 +28, -0.03, 0.29, 0.00 +29, 0.85, -7.59, 0.00 +30, 1.69, -15.34, 0.00 +31, 2.54, -23.41, 0.00 +32, 3.37, -31.59, 0.00 +33, 4.19, -40.08, 0.00 +34, 5.02, -48.92, 0.00 +35, 5.83, -57.97, 0.00 +36, 6.62, -67.30, 0.00 +37, 7.38, -76.73, 0.00 +38, 8.13, -86.51, 0.00 +39, 8.83, -96.39, 0.00 +40, 9.51, -106.58, 0.00 +41, 10.14, -116.85, 0.00 +42, 10.76, -127.75, 0.00 +43, 11.32, -138.90, 0.00 +44, 11.81, -149.97, 0.00 +45, 12.22, -161.13, 0.00 +46, 12.50, -171.78, 0.00 +47, 12.68, -182.09, 0.00 +48, 12.78, -192.81, 0.00 +49, 12.76, -203.07, 0.00 +50, 12.57, -212.38, 0.00 +51, 12.05, -217.67, 0.00 +52, 11.60, -225.88, 0.00 +53, 11.01, -233.43, 0.00 +54, 10.51, -245.81, 0.00 +55, 9.41, -246.68, 0.00 +56, 7.63, -229.29, 0.00 +57, 6.26, -221.94, 0.00 +58, 6.99, -305.64, 0.00 +59, 6.92, -400.58, 0.00 +60, 4.75, -416.91, 0.00 +61, 2.15, -411.19, 0.00 +62, -0.50, -401.81, 0.00 +63, -3.15, -392.75, 0.00 +64, -5.77, -381.55, 0.00 +65, -8.34, -369.11, 0.00 +66, -10.81, -355.18, 0.00 +67, -13.15, -340.07, 0.00 +68, -15.34, -324.16, 0.00 +69, -17.37, -307.70, 0.00 +70, -19.20, -290.73, 0.00 +71, -20.74, -272.38, 0.00 +72, -22.00, -253.37, 0.00 +73, -22.70, -231.35, 0.00 +74, -23.29, -211.45, 0.00 +75, -23.37, -190.20, 0.00 +76, -23.19, -169.88, 0.00 +77, -22.18, -146.81, 0.00 +78, -20.95, -125.64, 0.00 +79, -19.03, -103.59, 0.00 +80, -16.76, -82.89, 0.00 +81, -13.60, -61.19, 0.00 +82, -9.50, -38.86, 0.00 +83, -4.20, -15.60, 0.00 +84, 2.57, 8.67, 0.00 +85, 10.17, 31.06, 0.00 +86, 18.87, 51.96, 0.00 +87, 28.98, 71.65, 0.00 +88, 41.74, 92.13, 0.00 +89, 54.07, 105.75, 0.00 +90, 70.75, 121.39, 0.00 +91, 96.09, 142.85, 0.00 +92, 93.51, 118.43, 0.00 +93, 120.64, 127.20, 0.00 +94, 136.03, 115.56, 0.00 +95, 169.16, 110.18, 0.00 +96, 186.54, 85.50, 0.00 +97, 143.56, 38.86, 0.00 +98, 66.96, 8.98, 0.00 +99, 44.43, -0.00, 0.00 +100, 87.14, -11.69, 0.00 +101, 145.23, -39.31, 0.00 +102, 142.83, -65.47, 0.00 +103, 105.19, -68.51, 0.00 +104, 88.44, -75.13, 0.00 +105, 63.28, -66.72, 0.00 +106, 48.19, -61.02, 0.00 +107, 25.79, -38.34, 0.00 +108, 13.76, -23.61, 0.00 +109, -0.24, 0.48, 0.00 +110, -9.29, 20.51, 0.00 +111, -20.12, 49.76, 0.00 +112, -27.25, 75.02, 0.00 +113, -34.63, 105.71, 0.00 +114, -39.49, 133.20, 0.00 +115, -42.08, 156.42, 0.00 +116, -43.53, 178.10, 0.00 +117, -45.53, 204.86, 0.00 +118, -46.18, 228.44, 0.00 +119, -46.94, 255.49, 0.00 +120, -46.62, 279.57, 0.00 +121, -46.43, 307.28, 0.00 +122, -45.37, 332.37, 0.00 +123, -44.27, 360.19, 0.00 +124, -42.30, 384.11, 0.00 +125, -40.27, 410.38, 0.00 +126, -37.67, 433.86, 0.00 +127, -34.88, 458.06, 0.00 +128, -31.68, 479.72, 0.00 +129, -28.36, 502.38, 0.00 +130, -24.77, 523.30, 0.00 +131, -21.07, 544.83, 0.00 +132, -17.18, 564.29, 0.00 +133, -13.22, 584.83, 0.00 +134, -9.13, 602.95, 0.00 +135, -4.98, 621.40, 0.00 +136, -0.79, 638.19, 0.00 +137, 3.43, 654.80, 0.00 +138, 7.63, 669.17, 0.00 +139, 11.81, 684.02, 0.00 +140, 15.94, 697.09, 0.00 +141, 20.00, 708.97, 0.00 +142, 23.96, 719.61, 0.00 +143, 27.84, 729.78, 0.00 +144, 31.59, 738.57, 0.00 +145, 35.21, 746.32, 0.00 +146, 38.69, 753.11, 0.00 +147, 42.03, 758.96, 0.00 +148, 45.19, 763.53, 0.00 +149, 48.25, 767.89, 0.00 +150, 51.12, 770.97, 0.00 +151, 53.90, 774.14, 0.00 +152, 56.45, 775.45, 0.00 +153, 58.60, 772.82, 0.00 +154, 60.49, 768.26, 0.00 +155, 61.32, 752.19, 0.00 +156, 66.19, 786.01, 0.00 +157, 51.41, 592.36, 0.00 +158, 2.74, 30.66, 0.00 +159, -1.91, -20.81, 0.00 +160, -1.38, -14.70, 0.00 +161, -2.29, -23.78, 0.00 +162, -2.80, -28.43, 0.00 +163, -2.29, -22.77, 0.00 +164, -2.55, -24.89, 0.00 +165, -2.37, -22.65, 0.00 +166, -2.68, -25.18, 0.00 +167, -2.76, -25.43, 0.00 +168, -3.15, -28.54, 0.00 +169, -3.54, -31.56, 0.00 +170, -4.04, -35.47, 0.00 +171, -4.42, -38.18, 0.00 +172, -4.93, -41.95, 0.00 +173, -5.44, -45.65, 0.00 +174, -6.02, -49.76, 0.00 +175, -6.54, -53.35, 0.00 +176, -7.07, -56.96, 0.00 +177, -7.54, -59.96, 0.00 +178, -8.01, -62.95, 0.00 +179, -8.43, -65.45, 0.00 +180, -8.82, -67.79, 0.00 +181, -9.18, -69.80, 0.00 +182, -9.48, -71.32, 0.00 +183, -9.72, -72.39, 0.00 +184, -9.90, -73.09, 0.00 +185, -10.04, -73.44, 0.00 +186, -10.00, -72.60, 0.00 +187, -10.00, -71.99, 0.00 +188, -9.88, -70.65, 0.00 +189, -9.65, -68.59, 0.00 +190, -9.33, -65.89, 0.00 +191, -8.91, -62.56, 0.00 +192, -8.37, -58.52, 0.00 +193, -7.74, -53.89, 0.00 +194, -7.00, -48.56, 0.00 +195, -6.14, -42.46, 0.00 +196, -5.13, -35.44, 0.00 +197, -4.03, -27.78, 0.00 +198, -2.72, -18.69, 0.00 diff --git a/TestCases/py_wrapper/updated_moving_frame_NACA12/config.cfg b/TestCases/py_wrapper/updated_moving_frame_NACA12/config.cfg index 053828f96eb3..31d503068672 100644 --- a/TestCases/py_wrapper/updated_moving_frame_NACA12/config.cfg +++ b/TestCases/py_wrapper/updated_moving_frame_NACA12/config.cfg @@ -50,7 +50,7 @@ VENKAT_LIMITER_COEFF= 0.1 % SOLUTION ACCELERATION % -CFL_NUMBER= 50 +CFL_NUMBER= 10 CFL_ADAPT= NO % MGLEVEL= 3 diff --git a/TestCases/py_wrapper/updated_moving_frame_NACA12/forces_0.csv.ref b/TestCases/py_wrapper/updated_moving_frame_NACA12/forces_0.csv.ref index 46d649f5175e..e47d7e1ff730 100644 --- a/TestCases/py_wrapper/updated_moving_frame_NACA12/forces_0.csv.ref +++ b/TestCases/py_wrapper/updated_moving_frame_NACA12/forces_0.csv.ref @@ -1,200 +1,200 @@ 199, -0.97, -0.00, 0.00 -0, -2.85, 19.62, 0.00 -1, -4.08, 28.11, 0.00 -2, -5.17, 35.71, 0.00 -3, -6.11, 42.24, 0.00 -4, -6.94, 48.17, 0.00 -5, -7.57, 52.73, 0.00 -6, -8.15, 56.97, 0.00 -7, -8.53, 59.95, 0.00 -8, -8.87, 62.63, 0.00 -9, -8.99, 63.89, 0.00 -10, -9.11, 65.14, 0.00 -11, -9.01, 64.90, 0.00 -12, -8.93, 64.84, 0.00 -13, -8.60, 62.93, 0.00 -14, -8.34, 61.54, 0.00 -15, -7.81, 58.21, 0.00 -16, -7.40, 55.70, 0.00 -17, -6.70, 50.94, 0.00 -18, -6.14, 47.20, 0.00 -19, -5.32, 41.30, 0.00 -20, -4.67, 36.73, 0.00 -21, -3.69, 29.39, 0.00 -22, -2.98, 24.01, 0.00 -23, -1.95, 15.91, 0.00 -24, -1.21, 9.98, 0.00 -25, -0.16, 1.35, 0.00 -26, 0.63, -5.38, 0.00 -27, 1.68, -14.54, 0.00 -28, 2.49, -21.87, 0.00 -29, 3.57, -31.82, 0.00 -30, 4.36, -39.47, 0.00 -31, 5.42, -49.99, 0.00 -32, 6.16, -57.79, 0.00 -33, 7.10, -67.94, 0.00 -34, 7.75, -75.60, 0.00 -35, 8.60, -85.55, 0.00 -36, 9.16, -93.11, 0.00 -37, 9.88, -102.70, 0.00 -38, 10.30, -109.57, 0.00 -39, 10.67, -116.45, 0.00 -40, 10.97, -122.94, 0.00 -41, 10.85, -125.01, 0.00 -42, 10.97, -130.23, 0.00 -43, 10.59, -129.89, 0.00 -44, 10.72, -136.19, 0.00 -45, 10.25, -135.16, 0.00 -46, 10.25, -140.77, 0.00 -47, 9.09, -130.53, 0.00 -48, 8.67, -130.76, 0.00 -49, 6.09, -96.90, 0.00 -50, 5.92, -100.03, 0.00 -51, 5.90, -106.60, 0.00 -52, 6.79, -132.22, 0.00 -53, 20.46, -433.78, 0.00 -54, 27.67, -647.05, 0.00 -55, 21.99, -576.50, 0.00 -56, 18.31, -549.97, 0.00 -57, 15.75, -558.27, 0.00 -58, 12.65, -553.28, 0.00 -59, 9.40, -544.31, 0.00 -60, 6.08, -533.83, 0.00 -61, 2.74, -524.40, 0.00 -62, -0.63, -511.87, 0.00 -63, -4.01, -500.50, 0.00 -64, -7.36, -486.02, 0.00 -65, -10.72, -474.33, 0.00 -66, -13.96, -458.63, 0.00 -67, -17.17, -443.82, 0.00 -68, -20.18, -426.27, 0.00 -69, -23.14, -410.05, 0.00 -70, -25.82, -391.06, 0.00 -71, -28.45, -373.57, 0.00 -72, -30.70, -353.59, 0.00 -73, -33.29, -339.20, 0.00 -74, -35.07, -318.40, 0.00 -75, -36.82, -299.64, 0.00 -76, -37.96, -278.06, 0.00 -77, -39.56, -261.85, 0.00 -78, -40.14, -240.69, 0.00 -79, -41.29, -224.76, 0.00 -80, -41.06, -203.15, 0.00 -81, -42.40, -190.79, 0.00 -82, -41.79, -171.00, 0.00 -83, -42.95, -159.67, 0.00 -84, -42.40, -142.99, 0.00 -85, -45.26, -138.16, 0.00 -86, -45.31, -124.76, 0.00 -87, -48.24, -119.27, 0.00 -88, -50.85, -112.24, 0.00 -89, -59.21, -115.79, 0.00 -90, -58.88, -101.02, 0.00 -91, -81.20, -120.72, 0.00 -92, -82.96, -105.06, 0.00 -93, -107.96, -113.84, 0.00 -94, -139.30, -118.34, 0.00 -95, -41.52, -27.05, 0.00 -96, -37.01, -16.96, 0.00 -97, 39.35, 10.65, 0.00 -98, 37.44, 5.02, 0.00 -99, -65.44, 0.00, 0.00 -100, -86.45, 11.60, 0.00 -101, -161.88, 43.81, 0.00 -102, -143.44, 65.75, 0.00 -103, -113.80, 74.12, 0.00 -104, -114.52, 97.29, 0.00 -105, -107.02, 112.85, 0.00 -106, -135.53, 171.63, 0.00 -107, -84.72, 125.94, 0.00 -108, -68.44, 117.42, 0.00 -109, -43.03, 84.15, 0.00 -110, -50.65, 111.79, 0.00 -111, -47.20, 116.70, 0.00 -112, -49.20, 135.47, 0.00 -113, -45.81, 139.84, 0.00 -114, -49.98, 168.57, 0.00 -115, -49.99, 185.86, 0.00 -116, -51.63, 211.24, 0.00 -117, -50.46, 227.04, 0.00 -118, -51.05, 252.53, 0.00 -119, -49.65, 270.24, 0.00 -120, -49.56, 297.19, 0.00 -121, -47.48, 314.21, 0.00 -122, -46.22, 338.56, 0.00 -123, -44.23, 359.88, 0.00 -124, -42.11, 382.33, 0.00 -125, -39.68, 404.32, 0.00 -126, -37.10, 427.26, 0.00 -127, -34.16, 448.55, 0.00 -128, -31.03, 469.99, 0.00 -129, -27.69, 490.62, 0.00 -130, -24.20, 511.21, 0.00 -131, -20.49, 529.60, 0.00 -132, -16.71, 548.88, 0.00 -133, -12.79, 565.66, 0.00 -134, -8.83, 583.11, 0.00 -135, -4.79, 598.02, 0.00 -136, -0.76, 614.45, 0.00 -137, 3.29, 627.98, 0.00 -138, 7.32, 642.04, 0.00 -139, 11.29, 653.62, 0.00 -140, 15.24, 666.44, 0.00 -141, 19.08, 676.34, 0.00 -142, 22.88, 687.03, 0.00 -143, 26.54, 695.78, 0.00 -144, 30.12, 704.26, 0.00 -145, 33.47, 709.58, 0.00 -146, 36.77, 715.69, 0.00 -147, 39.75, 717.81, 0.00 -148, 42.73, 721.93, 0.00 -149, 45.49, 724.01, 0.00 -150, 48.31, 728.62, 0.00 -151, 51.12, 734.17, 0.00 -152, 55.50, 762.40, 0.00 -153, 39.08, 515.34, 0.00 -154, -2.39, -30.35, 0.00 -155, -1.02, -12.47, 0.00 -156, 3.53, 41.96, 0.00 -157, 4.67, 53.82, 0.00 -158, 4.83, 54.15, 0.00 -159, 5.42, 59.10, 0.00 -160, 5.72, 60.85, 0.00 -161, 5.71, 59.30, 0.00 -162, 5.61, 56.99, 0.00 -163, 5.18, 51.51, 0.00 -164, 4.87, 47.48, 0.00 -165, 4.24, 40.54, 0.00 -166, 3.76, 35.32, 0.00 -167, 3.00, 27.68, 0.00 -168, 2.43, 22.03, 0.00 -169, 1.62, 14.42, 0.00 -170, 0.98, 8.57, 0.00 -171, -0.06, -0.53, 0.00 -172, -0.78, -6.63, 0.00 -173, -1.76, -14.77, 0.00 -174, -2.46, -20.33, 0.00 -175, -3.34, -27.23, 0.00 -176, -4.02, -32.36, 0.00 -177, -4.96, -39.42, 0.00 -178, -5.61, -44.10, 0.00 -179, -6.39, -49.60, 0.00 -180, -6.94, -53.34, 0.00 -181, -7.60, -57.73, 0.00 -182, -8.02, -60.36, 0.00 -183, -8.51, -63.36, 0.00 -184, -8.81, -65.00, 0.00 -185, -9.15, -66.98, 0.00 -186, -9.27, -67.25, 0.00 -187, -9.42, -67.84, 0.00 -188, -9.34, -66.82, 0.00 -189, -9.25, -65.70, 0.00 -190, -8.98, -63.45, 0.00 -191, -8.67, -60.90, 0.00 -192, -8.19, -57.26, 0.00 -193, -7.63, -53.13, 0.00 -194, -6.92, -48.04, 0.00 -195, -6.09, -42.15, 0.00 -196, -5.12, -35.34, 0.00 -197, -4.03, -27.79, 0.00 -198, -2.78, -19.17, 0.00 +0, -2.88, 19.85, 0.00 +1, -4.05, 27.93, 0.00 +2, -5.07, 35.03, 0.00 +3, -5.96, 41.24, 0.00 +4, -6.74, 46.78, 0.00 +5, -7.39, 51.48, 0.00 +6, -7.92, 55.40, 0.00 +7, -8.36, 58.76, 0.00 +8, -8.64, 61.03, 0.00 +9, -8.84, 62.79, 0.00 +10, -8.89, 63.57, 0.00 +11, -8.86, 63.80, 0.00 +12, -8.73, 63.35, 0.00 +13, -8.52, 62.33, 0.00 +14, -8.24, 60.81, 0.00 +15, -7.91, 58.90, 0.00 +16, -7.49, 56.33, 0.00 +17, -7.04, 53.47, 0.00 +18, -6.48, 49.79, 0.00 +19, -5.90, 45.83, 0.00 +20, -5.25, 41.27, 0.00 +21, -4.60, 36.56, 0.00 +22, -3.89, 31.30, 0.00 +23, -3.18, 25.96, 0.00 +24, -2.42, 19.98, 0.00 +25, -1.68, 14.07, 0.00 +26, -0.87, 7.38, 0.00 +27, -0.09, 0.81, 0.00 +28, 0.74, -6.50, 0.00 +29, 1.54, -13.72, 0.00 +30, 2.37, -21.44, 0.00 +31, 3.13, -28.87, 0.00 +32, 3.94, -37.02, 0.00 +33, 4.69, -44.82, 0.00 +34, 5.49, -53.48, 0.00 +35, 6.20, -61.69, 0.00 +36, 6.97, -70.86, 0.00 +37, 7.67, -79.73, 0.00 +38, 8.38, -89.17, 0.00 +39, 9.03, -98.47, 0.00 +40, 9.61, -107.66, 0.00 +41, 10.12, -116.57, 0.00 +42, 10.52, -124.95, 0.00 +43, 10.83, -132.84, 0.00 +44, 11.03, -140.07, 0.00 +45, 11.07, -146.01, 0.00 +46, 10.87, -149.29, 0.00 +47, 10.24, -147.08, 0.00 +48, 9.85, -148.58, 0.00 +49, 9.23, -146.95, 0.00 +50, 8.03, -135.66, 0.00 +51, 5.02, -90.65, 0.00 +52, 8.44, -164.34, 0.00 +53, 24.61, -521.74, 0.00 +54, 25.24, -590.05, 0.00 +55, 21.35, -559.54, 0.00 +56, 18.43, -553.39, 0.00 +57, 15.47, -548.45, 0.00 +58, 12.34, -539.47, 0.00 +59, 9.16, -530.51, 0.00 +60, 5.93, -520.02, 0.00 +61, 2.66, -509.08, 0.00 +62, -0.61, -496.20, 0.00 +63, -3.87, -482.86, 0.00 +64, -7.09, -468.17, 0.00 +65, -10.23, -452.82, 0.00 +66, -13.28, -436.19, 0.00 +67, -16.22, -419.41, 0.00 +68, -19.00, -401.35, 0.00 +69, -21.63, -383.22, 0.00 +70, -24.05, -364.23, 0.00 +71, -26.30, -345.36, 0.00 +72, -28.26, -325.47, 0.00 +73, -30.06, -306.30, 0.00 +74, -31.47, -285.73, 0.00 +75, -32.68, -265.95, 0.00 +76, -33.54, -245.70, 0.00 +77, -34.32, -227.17, 0.00 +78, -34.48, -206.77, 0.00 +79, -34.55, -188.05, 0.00 +80, -33.88, -167.61, 0.00 +81, -33.34, -150.01, 0.00 +82, -31.79, -130.08, 0.00 +83, -30.47, -113.26, 0.00 +84, -27.83, -93.86, 0.00 +85, -26.36, -80.46, 0.00 +86, -22.80, -62.77, 0.00 +87, -20.38, -50.40, 0.00 +88, -16.48, -36.38, 0.00 +89, -13.50, -26.40, 0.00 +90, -8.89, -15.26, 0.00 +91, 2.07, 3.08, 0.00 +92, 9.08, 11.50, 0.00 +93, 13.77, 14.52, 0.00 +94, 20.38, 17.31, 0.00 +95, 38.32, 24.96, 0.00 +96, 51.52, 23.61, 0.00 +97, -11.06, -2.99, 0.00 +98, 9.27, 1.24, 0.00 +99, 56.99, -0.00, 0.00 +100, 121.78, -16.34, 0.00 +101, 216.03, -58.47, 0.00 +102, 204.05, -93.53, 0.00 +103, 153.71, -100.12, 0.00 +104, 131.85, -112.01, 0.00 +105, 83.63, -88.18, 0.00 +106, 65.02, -82.34, 0.00 +107, 36.90, -54.86, 0.00 +108, 24.12, -41.38, 0.00 +109, 3.60, -7.04, 0.00 +110, -5.15, 11.37, 0.00 +111, -17.47, 43.19, 0.00 +112, -23.69, 65.22, 0.00 +113, -32.00, 97.66, 0.00 +114, -36.22, 122.16, 0.00 +115, -40.69, 151.27, 0.00 +116, -42.86, 175.35, 0.00 +117, -45.56, 205.00, 0.00 +118, -46.38, 229.45, 0.00 +119, -47.11, 256.41, 0.00 +120, -46.83, 280.77, 0.00 +121, -46.29, 306.36, 0.00 +122, -45.08, 330.26, 0.00 +123, -43.57, 354.56, 0.00 +124, -41.55, 377.28, 0.00 +125, -39.29, 400.30, 0.00 +126, -36.74, 423.08, 0.00 +127, -33.87, 444.73, 0.00 +128, -30.79, 466.24, 0.00 +129, -27.45, 486.37, 0.00 +130, -23.98, 506.62, 0.00 +131, -20.34, 525.93, 0.00 +132, -16.59, 545.08, 0.00 +133, -12.73, 563.34, 0.00 +134, -8.79, 580.87, 0.00 +135, -4.79, 597.60, 0.00 +136, -0.76, 613.87, 0.00 +137, 3.29, 629.26, 0.00 +138, 7.33, 643.22, 0.00 +139, 11.34, 656.71, 0.00 +140, 15.31, 669.24, 0.00 +141, 19.20, 680.50, 0.00 +142, 23.00, 690.79, 0.00 +143, 26.72, 700.41, 0.00 +144, 30.30, 708.54, 0.00 +145, 33.76, 715.60, 0.00 +146, 37.07, 721.53, 0.00 +147, 40.24, 726.68, 0.00 +148, 43.22, 730.29, 0.00 +149, 46.10, 733.75, 0.00 +150, 48.72, 734.79, 0.00 +151, 51.06, 733.35, 0.00 +152, 54.83, 753.18, 0.00 +153, 51.89, 684.30, 0.00 +154, 8.03, 102.02, 0.00 +155, -1.05, -12.88, 0.00 +156, 3.20, 38.01, 0.00 +157, 3.99, 45.94, 0.00 +158, 4.27, 47.80, 0.00 +159, 4.38, 47.80, 0.00 +160, 4.41, 46.91, 0.00 +161, 4.21, 43.76, 0.00 +162, 3.97, 40.34, 0.00 +163, 3.55, 35.36, 0.00 +164, 3.12, 30.39, 0.00 +165, 2.57, 24.58, 0.00 +166, 2.00, 18.81, 0.00 +167, 1.36, 12.58, 0.00 +168, 0.72, 6.55, 0.00 +169, 0.01, 0.07, 0.00 +170, -0.70, -6.10, 0.00 +171, -1.46, -12.60, 0.00 +172, -2.18, -18.54, 0.00 +173, -2.95, -24.73, 0.00 +174, -3.66, -30.30, 0.00 +175, -4.40, -35.94, 0.00 +176, -5.09, -40.98, 0.00 +177, -5.78, -45.96, 0.00 +178, -6.39, -50.22, 0.00 +179, -7.01, -54.42, 0.00 +180, -7.54, -57.90, 0.00 +181, -8.04, -61.14, 0.00 +182, -8.47, -63.70, 0.00 +183, -8.82, -65.68, 0.00 +184, -9.10, -67.17, 0.00 +185, -9.28, -67.93, 0.00 +186, -9.39, -68.16, 0.00 +187, -9.41, -67.78, 0.00 +188, -9.32, -66.65, 0.00 +189, -9.21, -65.43, 0.00 +190, -8.95, -63.24, 0.00 +191, -8.66, -60.83, 0.00 +192, -8.20, -57.34, 0.00 +193, -7.65, -53.27, 0.00 +194, -6.97, -48.35, 0.00 +195, -6.12, -42.37, 0.00 +196, -5.16, -35.65, 0.00 +197, -4.06, -27.97, 0.00 +198, -2.82, -19.43, 0.00 diff --git a/TestCases/serial_regression.py b/TestCases/serial_regression.py index 279923612d6b..d9968f91b917 100755 --- a/TestCases/serial_regression.py +++ b/TestCases/serial_regression.py @@ -93,7 +93,7 @@ def main(): channel.cfg_dir = "euler/channel" channel.cfg_file = "inv_channel_RK.cfg" channel.test_iter = 10 - channel.test_vals = [-2.215160, 3.327978, 0.064048, 0.163516] + channel.test_vals = [-1.969337, 3.565024, 0.000246, 0.160624] test_list.append(channel) # NACA0012 @@ -101,7 +101,7 @@ def main(): naca0012.cfg_dir = "euler/naca0012" naca0012.cfg_file = "inv_NACA0012_Roe.cfg" naca0012.test_iter = 20 - naca0012.test_vals = [-4.256408, -3.795038, 0.306510, 0.024657] + naca0012.test_vals = [-4.507695, -3.938772, 0.297705, 0.025422] test_list.append(naca0012) # Supersonic wedge @@ -109,7 +109,7 @@ def main(): wedge.cfg_dir = "euler/wedge" wedge.cfg_file = "inv_wedge_HLLC.cfg" wedge.test_iter = 20 - wedge.test_vals = [-3.609826, 2.113544, -0.249533, 0.043953] + wedge.test_vals = [-3.703839, 2.020469, -0.249531, 0.043953] test_list.append(wedge) # ONERA M6 Wing @@ -117,7 +117,7 @@ def main(): oneram6.cfg_dir = "euler/oneram6" oneram6.cfg_file = "inv_ONERAM6.cfg" oneram6.test_iter = 10 - oneram6.test_vals = [-11.512881, -10.980703, 0.280800, 0.008623] + oneram6.test_vals = [-11.513859, -10.984761, 0.280800, 0.008623] oneram6.timeout = 9600 test_list.append(oneram6) @@ -126,7 +126,7 @@ def main(): fixedCL_naca0012.cfg_dir = "fixed_cl/naca0012" fixedCL_naca0012.cfg_file = "inv_NACA0012.cfg" fixedCL_naca0012.test_iter = 10 - fixedCL_naca0012.test_vals = [-3.920501, 1.594999, 0.300907, 0.019465] + fixedCL_naca0012.test_vals = [-3.962510, 1.570618, 0.301016, 0.019477] test_list.append(fixedCL_naca0012) # Polar sweep of the inviscid NACA0012 @@ -135,7 +135,7 @@ def main(): polar_naca0012.cfg_file = "inv_NACA0012.cfg" polar_naca0012.polar = True polar_naca0012.test_iter = 10 - polar_naca0012.test_vals = [-1.196985, 4.245790, 0.010492, 0.070124] + polar_naca0012.test_vals = [-1.278858, 4.165254, 0.004410, 0.083785] polar_naca0012.test_vals_aarch64 = [-1.063447, 4.401847, 0.000291, 0.031696] polar_naca0012.command = TestCase.Command(exec = "compute_polar.py", param = "-n 1 -i 11") # flaky test on arm64 @@ -166,7 +166,7 @@ def main(): flatplate.cfg_dir = "navierstokes/flatplate" flatplate.cfg_file = "lam_flatplate.cfg" flatplate.test_iter = 20 - flatplate.test_vals = [-5.448267, 0.027571, 0.002633, 0.015619, 2.361200, -2.345600, 0.000000, 0.000000] + flatplate.test_vals = [-5.492595, -0.012547, 0.002524, 0.011875, 2.361500, -2.349600, 0.000000, 0.000000] test_list.append(flatplate) # Laminar cylinder (steady) @@ -174,7 +174,7 @@ def main(): cylinder.cfg_dir = "navierstokes/cylinder" cylinder.cfg_file = "lam_cylinder.cfg" cylinder.test_iter = 25 - cylinder.test_vals = [-8.503813, -3.012051, 0.260768, 1.697376, 0.000000] + cylinder.test_vals = [-8.480930, -3.006218, -0.028387, 1.634020, 0.000000] test_list.append(cylinder) # Laminar cylinder (low Mach correction) @@ -182,7 +182,7 @@ def main(): cylinder_lowmach.cfg_dir = "navierstokes/cylinder" cylinder_lowmach.cfg_file = "cylinder_lowmach.cfg" cylinder_lowmach.test_iter = 25 - cylinder_lowmach.test_vals = [-6.604626, -1.142842, -0.080684, -80.137778, 0.000000] + cylinder_lowmach.test_vals = [-6.447834, -0.986069, 0.825992, 65.209800, 0.000000] test_list.append(cylinder_lowmach) # 2D Poiseuille flow (body force driven with periodic inlet / outlet) @@ -198,7 +198,7 @@ def main(): poiseuille_profile.cfg_dir = "navierstokes/poiseuille" poiseuille_profile.cfg_file = "profile_poiseuille.cfg" poiseuille_profile.test_iter = 10 - poiseuille_profile.test_vals = [-12.004416, -7.543897, -0.000000, 2.089953] + poiseuille_profile.test_vals = [-12.003743, -7.573505, -0.000000, 2.089953] poiseuille_profile.test_vals_aarch64 = [-12.009012, -7.262299, -0.000000, 2.089953] #last 4 columns test_list.append(poiseuille_profile) @@ -218,7 +218,7 @@ def main(): rae2822_sa.cfg_dir = "rans/rae2822" rae2822_sa.cfg_file = "turb_SA_RAE2822.cfg" rae2822_sa.test_iter = 20 - rae2822_sa.test_vals = [-2.168944, -5.451519, 0.287676, 0.104861, 0.000000] + rae2822_sa.test_vals = [-2.187684, -5.308480, 0.389353, 0.077079, 0.000000] test_list.append(rae2822_sa) # RAE2822 SST @@ -226,7 +226,7 @@ def main(): rae2822_sst.cfg_dir = "rans/rae2822" rae2822_sst.cfg_file = "turb_SST_RAE2822.cfg" rae2822_sst.test_iter = 20 - rae2822_sst.test_vals = [-1.028398, 5.868068, 0.277703, 0.093381, 0.000000] + rae2822_sst.test_vals = [-1.028239, 5.864396, 0.357218, 0.074732, 0.000000] test_list.append(rae2822_sst) # RAE2822 SST_SUST @@ -234,7 +234,7 @@ def main(): rae2822_sst_sust.cfg_dir = "rans/rae2822" rae2822_sst_sust.cfg_file = "turb_SST_SUST_RAE2822.cfg" rae2822_sst_sust.test_iter = 20 - rae2822_sst_sust.test_vals = [-2.536320, 5.868058, 0.277703, 0.093381] + rae2822_sst_sust.test_vals = [-2.487553, 5.864385, 0.357218, 0.074732] test_list.append(rae2822_sst_sust) # Flat plate @@ -242,7 +242,7 @@ def main(): turb_flatplate.cfg_dir = "rans/flatplate" turb_flatplate.cfg_file = "turb_SA_flatplate.cfg" turb_flatplate.test_iter = 20 - turb_flatplate.test_vals = [-4.939159, -7.469363, -0.187651, 0.015894] + turb_flatplate.test_vals = [-4.958238, -7.438031, -0.187473, 0.015059] test_list.append(turb_flatplate) # FLAT PLATE, WALL FUNCTIONS, COMPRESSIBLE SST @@ -283,7 +283,7 @@ def main(): turb_naca0012_sa.cfg_dir = "rans/naca0012" turb_naca0012_sa.cfg_file = "turb_NACA0012_sa.cfg" turb_naca0012_sa.test_iter = 5 - turb_naca0012_sa.test_vals = [-12.037342, -16.384159, 1.080346, 0.018385, 20, -3.455793, 20, -4.641247, 0] + turb_naca0012_sa.test_vals = [-12.037341, -16.384159, 1.080346, 0.018385, 20, -3.455927, 20, -4.641252, 0] turb_naca0012_sa.test_vals_aarch64 = [-12.037297, -16.384158, 1.080346, 0.018385, 20.000000, -3.455886, 20.000000, -4.641247, 0.000000] turb_naca0012_sa.timeout = 3200 test_list.append(turb_naca0012_sa) @@ -293,7 +293,7 @@ def main(): turb_naca0012_sst.cfg_dir = "rans/naca0012" turb_naca0012_sst.cfg_file = "turb_NACA0012_sst.cfg" turb_naca0012_sst.test_iter = 10 - turb_naca0012_sst.test_vals = [-12.094382, -15.251082, -5.906366, 1.070413, 0.015775, -3.178797, 0] + turb_naca0012_sst.test_vals = [-12.094371, -15.251083, -5.906366, 1.070413, 0.015775, -3.178593, 0] turb_naca0012_sst.test_vals_aarch64 = [-12.076068, -15.246740, -5.861280, 1.070036, 0.015841, -3.297854, 0.000000] turb_naca0012_sst.timeout = 3200 test_list.append(turb_naca0012_sst) @@ -312,7 +312,7 @@ def main(): turb_naca0012_sst_sust_restart.cfg_dir = "rans/naca0012" turb_naca0012_sst_sust_restart.cfg_file = "turb_NACA0012_sst_sust.cfg" turb_naca0012_sst_sust_restart.test_iter = 10 - turb_naca0012_sst_sust_restart.test_vals = [-12.080556, -14.837169, -5.733461, 1.000893, 0.019109, -2.633984] + turb_naca0012_sst_sust_restart.test_vals = [-12.080495, -14.837169, -5.733461, 1.000893, 0.019109, -2.634055] turb_naca0012_sst_sust_restart.test_vals_aarch64 = [-12.074189, -14.836725, -5.732398, 1.000050, 0.019144, -3.315560] turb_naca0012_sst_sust_restart.timeout = 3200 test_list.append(turb_naca0012_sst_sust_restart) @@ -359,7 +359,7 @@ def main(): turb_naca0012_sst_restart_mg.cfg_file = "turb_NACA0012_sst_multigrid_restart.cfg" turb_naca0012_sst_restart_mg.test_iter = 50 turb_naca0012_sst_restart_mg.ntest_vals = 5 - turb_naca0012_sst_restart_mg.test_vals = [-6.575448, -5.081421, 0.810883, -0.008836, 0.077960] + turb_naca0012_sst_restart_mg.test_vals = [-6.610290, -5.081422, 0.810881, -0.008844, 0.077940] turb_naca0012_sst_restart_mg.timeout = 3200 turb_naca0012_sst_restart_mg.tol = 0.000001 test_list.append(turb_naca0012_sst_restart_mg) @@ -380,7 +380,7 @@ def main(): inc_euler_naca0012.cfg_dir = "incomp_euler/naca0012" inc_euler_naca0012.cfg_file = "incomp_NACA0012.cfg" inc_euler_naca0012.test_iter = 20 - inc_euler_naca0012.test_vals = [-5.930469, -4.994452, 0.519589, 0.008977] + inc_euler_naca0012.test_vals = [-5.968755, -5.003709, 0.522550, 0.008867] test_list.append(inc_euler_naca0012) # C-D nozzle with pressure inlet and mass flow outlet @@ -388,7 +388,7 @@ def main(): inc_nozzle.cfg_dir = "incomp_euler/nozzle" inc_nozzle.cfg_file = "inv_nozzle.cfg" inc_nozzle.test_iter = 20 - inc_nozzle.test_vals = [-5.550954, -4.854401, -0.027964, 0.120734] + inc_nozzle.test_vals = [-6.247282, -5.460332, -0.019426, 0.126862] test_list.append(inc_nozzle) ############################# @@ -407,7 +407,7 @@ def main(): inc_lam_cylinder.cfg_dir = "incomp_navierstokes/cylinder" inc_lam_cylinder.cfg_file = "incomp_cylinder.cfg" inc_lam_cylinder.test_iter = 10 - inc_lam_cylinder.test_vals = [-4.168180, -3.611108, 0.007850, 4.539924] + inc_lam_cylinder.test_vals = [-4.159153, -3.569142, 0.011445, 4.936802] test_list.append(inc_lam_cylinder) # Buoyancy-driven cavity @@ -586,7 +586,7 @@ def main(): contadj_naca0012.cfg_dir = "cont_adj_euler/naca0012" contadj_naca0012.cfg_file = "inv_NACA0012.cfg" contadj_naca0012.test_iter = 5 - contadj_naca0012.test_vals = [-9.525042, -15.101716, -0.726250, 0.020280] + contadj_naca0012.test_vals = [-9.531049, -15.087710, -0.726250, 0.020280] contadj_naca0012.tol = 0.001 test_list.append(contadj_naca0012) @@ -595,7 +595,7 @@ def main(): contadj_oneram6.cfg_dir = "cont_adj_euler/oneram6" contadj_oneram6.cfg_file = "inv_ONERAM6.cfg" contadj_oneram6.test_iter = 10 - contadj_oneram6.test_vals = [-12.062243, -12.621811, -1.086100, 0.007556] + contadj_oneram6.test_vals = [-12.080232, -12.641294, -1.086100, 0.007556] test_list.append(contadj_oneram6) # Inviscid WEDGE: tests averaged outflow total pressure adjoint @@ -611,7 +611,7 @@ def main(): contadj_fixedCL_naca0012.cfg_dir = "fixed_cl/naca0012" contadj_fixedCL_naca0012.cfg_file = "inv_NACA0012_ContAdj.cfg" contadj_fixedCL_naca0012.test_iter = 100 - contadj_fixedCL_naca0012.test_vals = [1.165313, -4.338177, -0.068991, -0.007568] + contadj_fixedCL_naca0012.test_vals = [1.381080, -4.043374, -0.033478, 0.003350] test_list.append(contadj_fixedCL_naca0012) ################################### @@ -630,7 +630,7 @@ def main(): contadj_ns_cylinder.cfg_dir = "cont_adj_navierstokes/cylinder" contadj_ns_cylinder.cfg_file = "lam_cylinder.cfg" contadj_ns_cylinder.test_iter = 20 - contadj_ns_cylinder.test_vals = [-3.606048, -9.050787, 2.056700, -0.000000] + contadj_ns_cylinder.test_vals = [-3.628790, -9.082444, 2.056700, -0.000000] test_list.append(contadj_ns_cylinder) # Adjoint laminar naca0012 subsonic @@ -674,7 +674,7 @@ def main(): contadj_rans_rae2822.cfg_dir = "cont_adj_rans/rae2822" contadj_rans_rae2822.cfg_file = "turb_SA_RAE2822.cfg" contadj_rans_rae2822.test_iter = 20 - contadj_rans_rae2822.test_vals = [-5.399739, -10.904778, -0.212470, 0.005448] + contadj_rans_rae2822.test_vals = [-5.399819, -10.904997, -0.212470, 0.005448] test_list.append(contadj_rans_rae2822) ############################# @@ -752,7 +752,7 @@ def main(): rot_naca0012.cfg_dir = "rotating/naca0012" rot_naca0012.cfg_file = "rot_NACA0012.cfg" rot_naca0012.test_iter = 25 - rot_naca0012.test_vals = [-1.313205, 4.208222, -0.001635, 0.121312] + rot_naca0012.test_vals = [-1.290464, 4.245388, -0.000518, 0.112880] test_list.append(rot_naca0012) # Lid-driven cavity @@ -760,7 +760,7 @@ def main(): cavity.cfg_dir = "moving_wall/cavity" cavity.cfg_file = "lam_cavity.cfg" cavity.test_iter = 25 - cavity.test_vals = [-8.327173, -2.944600, 0.017813, 0.009045] + cavity.test_vals = [-8.144051, -2.746565, 0.014954, 0.007011] test_list.append(cavity) # Spinning cylinder @@ -768,7 +768,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.824549, -2.360413, 1.581109, 1.528894] + spinning_cylinder.test_vals = [-7.543538, -2.078580, 1.956630, 1.859963] test_list.append(spinning_cylinder) ###################################### @@ -789,7 +789,7 @@ def main(): sine_gust.cfg_dir = "gust" sine_gust.cfg_file = "inv_gust_NACA0012.cfg" sine_gust.test_iter = 5 - sine_gust.test_vals = [-1.977498, 3.481817, -0.009957, -0.005021] + sine_gust.test_vals = [-1.977498, 3.481817, -0.010134, -0.004283] sine_gust.unsteady = True test_list.append(sine_gust) @@ -798,7 +798,7 @@ def main(): aeroelastic.cfg_dir = "aeroelastic" aeroelastic.cfg_file = "aeroelastic_NACA64A010.cfg" aeroelastic.test_iter = 2 - aeroelastic.test_vals = [-1.876629, 4.021078, 0.079049, 0.027650, -0.001639, -0.000129, -1.140500] + aeroelastic.test_vals = [-1.876626, 4.021083, 0.081596, 0.027684, -0.001638, -0.000130, -1.140510] aeroelastic.unsteady = True test_list.append(aeroelastic) @@ -824,7 +824,7 @@ def main(): unst_pitching_naca64a010_rans.cfg_dir = "unsteady/pitching_naca64a010_rans" unst_pitching_naca64a010_rans.cfg_file = "turb_NACA64A010.cfg" unst_pitching_naca64a010_rans.test_iter = 2 - unst_pitching_naca64a010_rans.test_vals = [-1.299045, -3.951413, 0.012821, 0.008239] + unst_pitching_naca64a010_rans.test_vals = [-1.299045, -3.951366, 0.010128, 0.008245] unst_pitching_naca64a010_rans.unsteady = True test_list.append(unst_pitching_naca64a010_rans) # unsteady pitching NACA64A010, Euler @@ -832,7 +832,7 @@ def main(): unst_pitching_naca64a010_euler.cfg_dir = "unsteady/pitching_naca64a010_euler" unst_pitching_naca64a010_euler.cfg_file = "pitching_NACA64A010.cfg" unst_pitching_naca64a010_euler.test_iter = 2 - unst_pitching_naca64a010_euler.test_vals = [-1.186839, 4.280301, -0.043557, 0.000935] + unst_pitching_naca64a010_euler.test_vals = [-1.186839, 4.280301, -0.039488, 0.000918] unst_pitching_naca64a010_euler.unsteady = True test_list.append(unst_pitching_naca64a010_euler) # unsteady plunging NACA0012, Laminar NS @@ -840,7 +840,7 @@ def main(): unst_plunging_naca0012.cfg_dir = "unsteady/plunging_naca0012" unst_plunging_naca0012.cfg_file = "plunging_NACA0012.cfg" unst_plunging_naca0012.test_iter = 2 - unst_plunging_naca0012.test_vals = [-4.083462, 1.366757, -6.820746, -0.081557] + unst_plunging_naca0012.test_vals = [-4.083462, 1.366757, -6.470859, -0.078768] unst_plunging_naca0012.unsteady = True test_list.append(unst_plunging_naca0012) @@ -849,7 +849,7 @@ def main(): unst_deforming_naca0012.cfg_dir = "disc_adj_euler/naca0012_pitching_def" unst_deforming_naca0012.cfg_file = "inv_NACA0012_pitching_deform.cfg" unst_deforming_naca0012.test_iter = 5 - unst_deforming_naca0012.test_vals = [-3.665254, -3.794011, -3.716829, -3.148509] + unst_deforming_naca0012.test_vals = [-3.665263, -3.794184, -3.716978, -3.148551] unst_deforming_naca0012.unsteady = True test_list.append(unst_deforming_naca0012) @@ -862,7 +862,7 @@ def main(): ls89_sa.cfg_dir = "nicf/LS89" ls89_sa.cfg_file = "turb_SA_PR.cfg" ls89_sa.test_iter = 20 - ls89_sa.test_vals = [-5.241488, -13.580472, 0.188420, 0.414010] + ls89_sa.test_vals = [-5.069399, -13.403603, 0.180485, 0.429457] test_list.append(ls89_sa) # Rarefaction shock wave edge_VW @@ -870,7 +870,7 @@ def main(): edge_VW.cfg_dir = "nicf/edge" edge_VW.cfg_file = "edge_VW.cfg" edge_VW.test_iter = 20 - edge_VW.test_vals = [-2.656646, 3.544572, -0.000020, 0.000000] + edge_VW.test_vals = [-2.851854, 3.349325, -0.000009, 0.000000] test_list.append(edge_VW) # Rarefaction shock wave edge_PPR @@ -878,7 +878,7 @@ def main(): edge_PPR.cfg_dir = "nicf/edge" edge_PPR.cfg_file = "edge_PPR.cfg" edge_PPR.test_iter = 20 - edge_PPR.test_vals = [-12.155248, -5.996433, -0.000034, 0] + edge_PPR.test_vals = [-12.476580, -6.287745, -0.000034, 0.000000] test_list.append(edge_PPR) @@ -892,6 +892,7 @@ def main(): Aachen_3D_restart.cfg_file = "aachen_3D_MP_restart.cfg" Aachen_3D_restart.test_iter = 5 Aachen_3D_restart.test_vals = [-7.701448, -8.512353, -6.014939, -6.468417, -5.801739, -4.607173, -5.550692, -5.300771, -3.804187, -5.256008, -5.765048, -3.609601, -2.229277, -2.883894, -0.563470] + Aachen_3D_restart.enabled_with_asan = False test_list.append(Aachen_3D_restart) # Jones APU Turbocharger restart @@ -972,6 +973,7 @@ def main(): channel_3D.test_vals_aarch64 = [1.000000, 0.000000, 0.611996, 0.798988, 0.702357] channel_3D.unsteady = True channel_3D.multizone = True + channel_3D.enabled_with_asan = False test_list.append(channel_3D) # Pipe @@ -1009,7 +1011,7 @@ def main(): bars_SST_2D.cfg_dir = "sliding_interface/bars_SST_2D" bars_SST_2D.cfg_file = "bars.cfg" bars_SST_2D.test_iter = 13 - bars_SST_2D.test_vals = [13.000000, -0.473009, -1.562179] + bars_SST_2D.test_vals = [13.000000, -0.397243, -1.461873] bars_SST_2D.multizone = True test_list.append(bars_SST_2D) @@ -1072,7 +1074,7 @@ def main(): dynbeam2d.test_vals = [-3.240012, 2.895060, -0.353140, 76220] test_list.append(dynbeam2d) - # # FSI, 2d + # FSI, 2d fsi2d = TestCase('fsi2d') fsi2d.cfg_dir = "fea_fsi/WallChannel_2d" fsi2d.cfg_file = "configFSI.cfg" @@ -1082,30 +1084,21 @@ def main(): fsi2d.unsteady = True test_list.append(fsi2d) - # FSI, Static, 2D, new mesh solver - stat_fsi = TestCase('stat_fsi') - stat_fsi.cfg_dir = "fea_fsi/stat_fsi" - stat_fsi.cfg_file = "config.cfg" - stat_fsi.test_iter = 7 - stat_fsi.test_vals = [-3.336320, -4.991964, 0.000000, 7.000000] - stat_fsi.multizone = True - test_list.append(stat_fsi) - - # FSI, Static, 2D, new mesh solver, restart - stat_fsi_restart = TestCase('stat_fsi_restart') - stat_fsi_restart.cfg_dir = "fea_fsi/stat_fsi" - stat_fsi_restart.cfg_file = "config_restart.cfg" - stat_fsi_restart.test_iter = 1 - stat_fsi_restart.test_vals = [-3.401553, -4.672932, 0.000000, 26.000000] - stat_fsi_restart.multizone = True - test_list.append(stat_fsi_restart) + # FSI+CHT, Static, 2D, new mesh solver + fsi_cht = TestCase('fsi_cht') + fsi_cht.cfg_dir = "fea_fsi/stat_fsi" + fsi_cht.cfg_file = "config.cfg" + fsi_cht.test_iter = 20 + fsi_cht.test_vals = [5, -5.077012, -5.379779, -9.247804, -9.277819, -9.183796, 6.0835e+02, -1.2973e-02, 5.7607e-08, 29] + fsi_cht.multizone = True + test_list.append(fsi_cht) # FSI, Dynamic, 2D, new mesh solver dyn_fsi = TestCase('dyn_fsi') dyn_fsi.cfg_dir = "fea_fsi/dyn_fsi" dyn_fsi.cfg_file = "config.cfg" dyn_fsi.test_iter = 4 - dyn_fsi.test_vals = [-4.330728, -4.152820, 0, 86] + dyn_fsi.test_vals = [-4.330728, -4.152820, 5.3831e-08, 85] dyn_fsi.multizone = True dyn_fsi.unsteady = True test_list.append(dyn_fsi) @@ -1115,7 +1108,7 @@ def main(): airfoilRBF.cfg_dir = "fea_fsi/Airfoil_RBF" airfoilRBF.cfg_file = "config.cfg" airfoilRBF.test_iter = 1 - airfoilRBF.test_vals = [1.000000, 0.184123, -3.375352] + airfoilRBF.test_vals = [1.000000, 0.028165, -3.530075] airfoilRBF.tol = 0.0001 airfoilRBF.multizone = True test_list.append(airfoilRBF) @@ -1522,7 +1515,7 @@ def main(): opt_multiobj1surf_py.cfg_dir = "optimization_euler/multiobjective_wedge" opt_multiobj1surf_py.cfg_file = "inv_wedge_ROE_multiobj_1surf.cfg" opt_multiobj1surf_py.test_iter = 1 - opt_multiobj1surf_py.test_vals = [1.000000, 1.000000, 36.699910, 5.780304] + opt_multiobj1surf_py.test_vals = [1.000000, 1.000000, 36.670510, 5.750360] opt_multiobj1surf_py.command = TestCase.Command(exec = "shape_optimization.py", param = "-g CONTINUOUS_ADJOINT -f") opt_multiobj1surf_py.timeout = 1600 opt_multiobj1surf_py.tol = 0.00001 @@ -1552,7 +1545,7 @@ def main(): pywrapper_naca0012.cfg_dir = "euler/naca0012" pywrapper_naca0012.cfg_file = "inv_NACA0012_Roe.cfg" pywrapper_naca0012.test_iter = 20 - pywrapper_naca0012.test_vals = [-4.256408, -3.795038, 0.306510, 0.024657] + pywrapper_naca0012.test_vals = [-4.507695, -3.938772, 0.297705, 0.025422] pywrapper_naca0012.command = TestCase.Command(exec = "SU2_CFD.py", param = "-f") pywrapper_naca0012.timeout = 1600 pywrapper_naca0012.tol = 0.00001 @@ -1565,7 +1558,7 @@ def main(): pywrapper_turb_naca0012_sst.cfg_dir = "rans/naca0012" pywrapper_turb_naca0012_sst.cfg_file = "turb_NACA0012_sst.cfg" pywrapper_turb_naca0012_sst.test_iter = 10 - pywrapper_turb_naca0012_sst.test_vals = [-12.094382, -15.251082, -5.906366, 1.070413, 0.015775, -3.178797, 0] + pywrapper_turb_naca0012_sst.test_vals = [-12.094371, -15.251083, -5.906366, 1.070413, 0.015775, -3.178593, 0] pywrapper_turb_naca0012_sst.test_vals_aarch64 = [-12.076068, -15.246740, -5.861280, 1.070036, 0.015841, -3.297854, 0.000000] pywrapper_turb_naca0012_sst.command = TestCase.Command(exec = "SU2_CFD.py", param = "-f") pywrapper_turb_naca0012_sst.timeout = 3200 @@ -1608,7 +1601,7 @@ def main(): pywrapper_unsteadyCHT.cfg_dir = "py_wrapper/flatPlate_unsteady_CHT" pywrapper_unsteadyCHT.cfg_file = "unsteady_CHT_FlatPlate_Conf.cfg" pywrapper_unsteadyCHT.test_iter = 5 - pywrapper_unsteadyCHT.test_vals = [-1.614168, 2.259972, 0.000757, 0.113614] + pywrapper_unsteadyCHT.test_vals = [-1.614168, 2.260078, -0.020704, 0.172871] pywrapper_unsteadyCHT.command = TestCase.Command(exec = "python", param = "launch_unsteady_CHT_FlatPlate.py -f") pywrapper_unsteadyCHT.timeout = 1600 pywrapper_unsteadyCHT.tol = 0.00001 diff --git a/TestCases/serial_regression_AD.py b/TestCases/serial_regression_AD.py index 6d0d424251ad..baa6e114700f 100644 --- a/TestCases/serial_regression_AD.py +++ b/TestCases/serial_regression_AD.py @@ -108,7 +108,7 @@ def main(): discadj_incomp_NACA0012.cfg_dir = "disc_adj_incomp_euler/naca0012" discadj_incomp_NACA0012.cfg_file = "incomp_NACA0012_disc.cfg" discadj_incomp_NACA0012.test_iter = 20 - discadj_incomp_NACA0012.test_vals = [20.000000, -3.338269, -2.490047, 0.000000] + discadj_incomp_NACA0012.test_vals = [20.000000, -3.122293, -2.287328, 0.000000] test_list.append(discadj_incomp_NACA0012) ##################################### @@ -158,7 +158,7 @@ def main(): discadj_pitchingNACA0012.cfg_dir = "disc_adj_euler/naca0012_pitching" discadj_pitchingNACA0012.cfg_file = "inv_NACA0012_pitching.cfg" discadj_pitchingNACA0012.test_iter = 4 - discadj_pitchingNACA0012.test_vals = [-1.130532, -1.575494, -0.005113, 0.000007] + discadj_pitchingNACA0012.test_vals = [-1.049761, -1.501951, -0.004853, 0.000013] discadj_pitchingNACA0012.unsteady = True test_list.append(discadj_pitchingNACA0012) @@ -167,7 +167,7 @@ def main(): unst_deforming_naca0012.cfg_dir = "disc_adj_euler/naca0012_pitching_def" unst_deforming_naca0012.cfg_file = "inv_NACA0012_pitching_deform_ad.cfg" unst_deforming_naca0012.test_iter = 4 - unst_deforming_naca0012.test_vals = [-1.885032, -1.775564, 3994.600000, 0.000002] + unst_deforming_naca0012.test_vals = [-1.885816, -1.781193, 3920.300000, 0.000003] unst_deforming_naca0012.unsteady = True test_list.append(unst_deforming_naca0012) diff --git a/TestCases/tutorials.py b/TestCases/tutorials.py index 5d7a226aa005..60680004487d 100644 --- a/TestCases/tutorials.py +++ b/TestCases/tutorials.py @@ -165,7 +165,7 @@ def main(): premixed_hydrogen.cfg_dir = "../Tutorials/incompressible_flow/Inc_Combustion/1__premixed_hydrogen" premixed_hydrogen.cfg_file = "H2_burner.cfg" premixed_hydrogen.test_iter = 10 - premixed_hydrogen.test_vals = [-9.647741, -10.286349, -11.353961, -4.380211, -12.831110] + premixed_hydrogen.test_vals = [-8.772073, -9.721083, -11.354959, -4.381554, -12.832787] test_list.append(premixed_hydrogen) ### Compressible Flow @@ -175,7 +175,7 @@ def main(): tutorial_inv_bump.cfg_dir = "../Tutorials/compressible_flow/Inviscid_Bump" tutorial_inv_bump.cfg_file = "inv_channel.cfg" tutorial_inv_bump.test_iter = 0 - tutorial_inv_bump.test_vals = [-1.437425, 4.075857, 0.043691, 0.034241] + tutorial_inv_bump.test_vals = [-1.437425, 4.075857, 0.080374, 0.012019] test_list.append(tutorial_inv_bump) # Inviscid Wedge @@ -192,7 +192,7 @@ def main(): tutorial_inv_onera.cfg_dir = "../Tutorials/compressible_flow/Inviscid_ONERAM6" tutorial_inv_onera.cfg_file = "inv_ONERAM6.cfg" tutorial_inv_onera.test_iter = 0 - tutorial_inv_onera.test_vals = [-5.204928, -4.597762, 0.255680, 0.087977] + tutorial_inv_onera.test_vals = [-5.204928, -4.597762, 0.261167, 0.084096] tutorial_inv_onera.no_restart = True test_list.append(tutorial_inv_onera) @@ -201,7 +201,7 @@ def main(): tutorial_lam_cylinder.cfg_dir = "../Tutorials/compressible_flow/Laminar_Cylinder" tutorial_lam_cylinder.cfg_file = "lam_cylinder.cfg" tutorial_lam_cylinder.test_iter = 0 - tutorial_lam_cylinder.test_vals = [-6.162141, -0.699617, -0.047729, 43.442977] + tutorial_lam_cylinder.test_vals = [-6.162141, -0.699617, -0.124663, 31.721714] tutorial_lam_cylinder.no_restart = True test_list.append(tutorial_lam_cylinder) @@ -323,7 +323,7 @@ def main(): tutorial_design_inv_naca0012.cfg_dir = "../Tutorials/design/Inviscid_2D_Unconstrained_NACA0012" tutorial_design_inv_naca0012.cfg_file = "inv_NACA0012_basic.cfg" tutorial_design_inv_naca0012.test_iter = 0 - tutorial_design_inv_naca0012.test_vals = [-3.585391, -2.989014, 0.164248, 0.228824] + tutorial_design_inv_naca0012.test_vals = [-3.585391, -2.989014, 0.169747, 0.235619] tutorial_design_inv_naca0012.no_restart = True test_list.append(tutorial_design_inv_naca0012) diff --git a/TestCases/vandv.py b/TestCases/vandv.py index 424b877b216e..b78df50eeb30 100644 --- a/TestCases/vandv.py +++ b/TestCases/vandv.py @@ -63,7 +63,7 @@ def main(): flatplate_sst1994m.cfg_dir = "vandv/rans/flatplate" flatplate_sst1994m.cfg_file = "turb_flatplate_sst.cfg" flatplate_sst1994m.test_iter = 5 - flatplate_sst1994m.test_vals = [-13.040446, -10.136636, -10.945108, -7.983081, -10.323877, -4.733046, 0.002801] + flatplate_sst1994m.test_vals = [-13.040526, -10.136914, -10.942003, -7.980425, -10.323871, -4.732398, 0.002801] flatplate_sst1994m.test_vals_aarch64 = [-13.021715, -9.534786, -10.401912, -7.501836, -9.750800, -4.850665, 0.002807] test_list.append(flatplate_sst1994m) @@ -72,7 +72,7 @@ def main(): bump_sst1994m.cfg_dir = "vandv/rans/bump_in_channel" bump_sst1994m.cfg_file = "turb_bump_sst.cfg" bump_sst1994m.test_iter = 5 - bump_sst1994m.test_vals = [-11.928190, -10.095673, -9.512453, -6.445471, -11.773665, -6.998333, 0.004931] + bump_sst1994m.test_vals = [-11.927868, -10.095409, -9.512544, -6.445154, -11.773530, -6.993606, 0.004931] bump_sst1994m.test_vals_aarch64 = [-13.042689, -10.812982, -10.604523, -7.655547, -10.816257, -5.308083, 0.004911] test_list.append(bump_sst1994m) @@ -99,7 +99,7 @@ def main(): dsma661_sa.cfg_dir = "vandv/rans/dsma661" dsma661_sa.cfg_file = "dsma661_sa_config.cfg" dsma661_sa.test_iter = 5 - dsma661_sa.test_vals = [-11.266227, -8.243175, -9.037538, -5.941643, -10.737679, 0.155687, 0.024232] + dsma661_sa.test_vals = [-11.247169, -8.242321, -9.020952, -5.903807, -10.737679, 0.155687, 0.024232] dsma661_sa.test_vals_aarch64 = [-11.293183, -8.241775, -9.083761, -6.011398, -10.737680, 0.155687, 0.024232] test_list.append(dsma661_sa) @@ -108,7 +108,7 @@ def main(): dsma661_sst.cfg_dir = "vandv/rans/dsma661" dsma661_sst.cfg_file = "dsma661_sst_config.cfg" dsma661_sst.test_iter = 5 - dsma661_sst.test_vals = [-11.020377, -8.157152, -8.998182, -5.917729, -10.650155, -7.856100, 0.155882, 0.023344] + dsma661_sst.test_vals = [-11.023206, -8.157128, -8.995930, -5.936029, -10.650466, -7.864550, 0.155882, 0.023344] dsma661_sst.test_vals_aarch64 = [-10.977195, -8.403731, -8.747068, -5.808899, -10.522786, -7.369851, 0.155875, 0.023353] test_list.append(dsma661_sst) diff --git a/config_template.cfg b/config_template.cfg index b801ef95fd32..889abb9f6b1f 100644 --- a/config_template.cfg +++ b/config_template.cfg @@ -1,6 +1,6 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % -% SU2 configuration file % +% SU2 configuration file config_template.cfg % % Case description: _________________________________________________________ % % Author: ___________________________________________________________________ % % Institution: ______________________________________________________________ % @@ -943,7 +943,12 @@ SPECIES_CLIPPING_MIN= 0.0 % for definition of the flamelet manifold. Either LUT or MLP can be used as options. % If the terms "Beta_ProgVar", "Beta_Enth_Thermal", "Beta_Enth", and "Beta_Mixfrac" are % found in the variables list of the manifold, preferential diffusion is assumed. +% The flamelet method uses the same boundary conditions as species transport. +% FLOW_MARKERS: flamelet method uses temperature BC from MARKER_INLET and MARKER_HEATFLUX/MARKER_ISOTHERMAL. +% It then does a reverse lookup for the enthalpy. +% SPECIES_MARKERS: flamelet method uses enthalpy from MARKER_INLET_SPECIES and MARKER_WALL_SPECIES. +FLAME_ENTHALPY_BC= SPECIES_MARKERS % % Names of the user defined (auxiliary) transport equations. USER_SCALAR_NAMES= (Y-CO) @@ -1677,10 +1682,10 @@ MG_POST_SMOOTH= ( 4, 4, 4, 4 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) % % Damping factor for the residual restriction -MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_RESTRICTION= 0.5 % % Damping factor for the correction prolongation -MG_DAMP_PROLONGATION= 0.75 +MG_DAMP_PROLONGATION= 0.5 % % Enable early exit from multigrid smoothing when the residual RMS drops % below MG_SMOOTH_RES_THRESHOLD * initial_rms (NO, YES) @@ -1688,7 +1693,7 @@ MG_SMOOTH_EARLY_EXIT= YES % % Relative RMS reduction threshold for the multigrid smoothing early exit. % Smoothing stops when current_rms < threshold * initial_rms (default 0.5) -MG_SMOOTH_RES_THRESHOLD= 0.5 +MG_SMOOTH_RES_THRESHOLD= 0.9 % % Smoothing coefficient for the Jacobi correction-prolongation smoother (default 1.25) MG_SMOOTH_COEFF= 1.25 @@ -1702,6 +1707,10 @@ MG_MIN_MESHSIZE= 500 % % Enable agglomeration along implicit lines seeded from viscous walls (NO, YES) MG_IMPLICIT_LINES= NO +% +% Maximum nodes on a wall-normal implicit agglomeration line, including the wall seed. +% Increase to extend the line deeper into the boundary layer (default 20). +MG_IMPLICIT_LINES_MAX_LENGTH= 20 % -------------------------- MESH SMOOTHING -----------------------------% % diff --git a/meson.build b/meson.build index 0620578a1636..d43e2b031d88 100644 --- a/meson.build +++ b/meson.build @@ -20,10 +20,13 @@ python = pymod.find_installation() if get_option('enable-cuda') add_languages('cuda') add_global_arguments('-arch=sm_86', language : 'cuda') + cuda_deps = [meson.get_compiler('cuda').find_library('cusparse', required : true)] +else + cuda_deps = [] endif su2_cpp_args = [] -su2_deps = [declare_dependency(include_directories: 'externals/CLI11')] +su2_deps = [declare_dependency(include_directories: 'externals/CLI11')] + cuda_deps default_warning_flags = [] if build_machine.system() != 'windows' @@ -153,9 +156,12 @@ if get_option('enable-cgns') endif # check for mixed precision floating point arithmetic -if get_option('enable-mixedprec') +if get_option('enable-mixedprec') or get_option('enable-singleprec') su2_cpp_args += '-DUSE_MIXED_PRECISION' endif +if get_option('enable-singleprec') + su2_cpp_args += '-DUSE_SINGLE_PRECISION' +endif # check if MPI dependencies are found and add them if mpi diff --git a/meson_options.txt b/meson_options.txt index 4eba410a0013..6adad19386b7 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -16,6 +16,7 @@ option('enable-pastix', type : 'boolean', value : false, description: 'enable Pa option('custom-mpi', type : 'boolean', value : false, description: 'enable MPI assuming the compiler and/or env vars give the correct include dirs and linker args.') option('enable-tests', type : 'boolean', value : false, description: 'compile Unit Tests') option('enable-mixedprec', type : 'boolean', value : false, description: 'use single precision floating point arithmetic for sparse algebra') +option('enable-singleprec', type : 'boolean', value : false, description: 'use single precision floating point arithmetic for everything') option('extra-deps', type : 'string', value : '', description: 'comma-separated list of extra (custom) dependencies to add for compilation') option('enable-mpp', type : 'boolean', value : false, description: 'enable Mutation++ support') option('install-mpp', type : 'boolean', value : false, description: 'install Mutation++ in the directory defined with --prefix')