diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml index c1bebd3928ff..31aaed6f6930 100644 --- a/.github/workflows/regression.yml +++ b/.github/workflows/regression.yml @@ -26,25 +26,25 @@ jobs: config_set: [BaseMPI, ReverseMPI, ForwardMPI, BaseNoMPI, ReverseNoMPI, ForwardNoMPI, ReverseTagNoMPI, BaseOMP, ReverseOMP, ForwardOMP] include: - config_set: BaseMPI - flags: '-Denable-pywrapper=true -Denable-coolprop=true -Denable-mpp=true -Dinstall-mpp=true -Denable-mlpcpp=true -Denable-tests=true --warnlevel=2' + flags: '-Dcpu-arch=skylake -Denable-pywrapper=true -Denable-coolprop=true -Denable-mpp=true -Dinstall-mpp=true -Denable-mlpcpp=true -Denable-tests=true --warnlevel=2' - config_set: ReverseMPI - flags: '-Denable-autodiff=true -Denable-normal=false -Denable-pywrapper=true -Denable-tests=true --warnlevel=3 --werror' + flags: '-Dcpu-arch=skylake -Denable-autodiff=true -Denable-normal=false -Denable-pywrapper=true -Denable-tests=true -Denable-mlpcpp=true --warnlevel=3 --werror' - config_set: ForwardMPI - flags: '-Denable-directdiff=true -Denable-normal=false -Denable-tests=true -Denable-mlpcpp=true --warnlevel=3 --werror' + flags: '-Dcpu-arch=skylake -Denable-directdiff=true -Denable-normal=false -Denable-tests=true -Denable-mlpcpp=true --warnlevel=3 --werror' - config_set: BaseNoMPI - flags: '-Denable-pywrapper=true -Denable-openblas=true -Dwith-mpi=disabled -Denable-mlpcpp=true -Denable-tests=true --warnlevel=3 --werror' + flags: '-Dcpu-arch=skylake -Denable-pywrapper=true -Denable-openblas=true -Dwith-mpi=disabled -Denable-mlpcpp=true -Denable-tests=true --warnlevel=3 --werror' - config_set: ReverseNoMPI - flags: '-Denable-autodiff=true -Denable-normal=false -Dwith-mpi=disabled -Denable-pywrapper=true -Denable-tests=true --warnlevel=3 --werror' + flags: '-Dcpu-arch=skylake -Denable-autodiff=true -Denable-normal=false -Dwith-mpi=disabled -Denable-pywrapper=true -Denable-tests=true --warnlevel=3 --werror' - config_set: ForwardNoMPI - flags: '-Denable-directdiff=true -Denable-normal=false -Dwith-mpi=disabled -Denable-tests=true --warnlevel=3 --werror' + flags: '-Dcpu-arch=skylake -Denable-directdiff=true -Denable-normal=false -Dwith-mpi=disabled -Denable-tests=true --warnlevel=3 --werror' - config_set: ReverseTagNoMPI - flags: '-Denable-autodiff=true -Denable-normal=false -Dwith-mpi=disabled -Denable-pywrapper=true -Denable-tests=true --warnlevel=3 --werror -Dcodi-tape=Tag' + flags: '-Dcpu-arch=skylake -Denable-autodiff=true -Denable-normal=false -Dwith-mpi=disabled -Denable-pywrapper=true -Denable-tests=true --warnlevel=3 --werror -Dcodi-tape=Tag' - config_set: BaseOMP - flags: '-Dwith-omp=true -Denable-mixedprec=true -Denable-pywrapper=true -Denable-tecio=false --warnlevel=3 --werror' + flags: '-Dcpu-arch=skylake -Dwith-omp=true -Denable-mixedprec=true -Denable-pywrapper=true -Denable-tecio=false --warnlevel=3 --werror' - config_set: ReverseOMP - flags: '-Denable-autodiff=true -Denable-normal=false -Dwith-omp=true -Denable-mixedprec=true -Denable-pywrapper=true -Denable-tecio=false --warnlevel=3 --werror' + flags: '-Dcpu-arch=skylake -Denable-autodiff=true -Denable-normal=false -Dwith-omp=true -Denable-mixedprec=true -Denable-pywrapper=true -Denable-tecio=false --warnlevel=3 --werror' - config_set: ForwardOMP - flags: '-Denable-directdiff=true -Denable-normal=false -Dwith-omp=true -Denable-mixedprec=true -Denable-pywrapper=true -Denable-tecio=false --warnlevel=3 --werror' + flags: '-Dcpu-arch=skylake -Denable-directdiff=true -Denable-normal=false -Dwith-omp=true -Denable-mixedprec=true -Denable-pywrapper=true -Denable-tecio=false --warnlevel=3 --werror' runs-on: ${{ inputs.runner || 'ubuntu-latest' }} steps: - name: Cache Object Files @@ -54,12 +54,12 @@ jobs: key: ${{ matrix.config_set }}-${{ github.sha }} restore-keys: ${{ matrix.config_set }} - name: Pre Cleanup - uses: docker://ghcr.io/su2code/su2/build-su2:250717-1402 + uses: docker://ghcr.io/su2code/su2/build-su2:260405-0054 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} - name: Build - uses: docker://ghcr.io/su2code/su2/build-su2:250717-1402 + uses: docker://ghcr.io/su2code/su2/build-su2:260405-0054 with: args: -b ${{github.ref}} -f "${{matrix.flags}}" - name: Compress binaries @@ -70,7 +70,7 @@ jobs: name: ${{ matrix.config_set }} path: install_bin.tgz - name: Post Cleanup - uses: docker://ghcr.io/su2code/su2/build-su2:250717-1402 + uses: docker://ghcr.io/su2code/su2/build-su2:260405-0054 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} @@ -83,11 +83,11 @@ jobs: config_set: [BaseOMP-tsan, ReverseOMP-tsan] #ForwardOMP-tsan include: - config_set: BaseOMP-tsan - flags: '--buildtype=debugoptimized -Dwith-omp=true -Denable-mixedprec=true -Denable-tecio=false --warnlevel=3' + flags: '--buildtype=debugoptimized -Dcpu-arch=skylake -Dwith-omp=true -Denable-mixedprec=true -Denable-tecio=false --warnlevel=3' - config_set: ReverseOMP-tsan - flags: '--buildtype=debugoptimized -Denable-autodiff=true -Denable-normal=false -Dwith-omp=true -Denable-mixedprec=true -Denable-tecio=false --warnlevel=3' + flags: '--buildtype=debugoptimized -Dcpu-arch=skylake -Denable-autodiff=true -Denable-normal=false -Dwith-omp=true -Denable-mixedprec=true -Denable-tecio=false --warnlevel=3' #- config_set: ForwardOMP-tsan - # flags: '--buildtype=debug -Denable-directdiff=true -Denable-normal=false -Dwith-omp=true -Denable-mixedprec=true -Denable-pywrapper=true -Denable-tecio=false --warnlevel=3 --werror' + # flags: '--buildtype=debug -Dcpu-arch=skylake -Denable-directdiff=true -Denable-normal=false -Dwith-omp=true -Denable-mixedprec=true -Denable-pywrapper=true -Denable-tecio=false --warnlevel=3 --werror' runs-on: ${{ inputs.runner || 'ubuntu-latest' }} steps: - name: Cache Object Files @@ -97,12 +97,12 @@ jobs: key: ${{ matrix.config_set }}-${{ github.sha }} restore-keys: ${{ matrix.config_set }} - name: Pre Cleanup - uses: docker://ghcr.io/su2code/su2/build-su2-tsan:250717-1402 + uses: docker://ghcr.io/su2code/su2/build-su2-tsan:260405-0054 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} - name: Build - uses: docker://ghcr.io/su2code/su2/build-su2-tsan:250717-1402 + uses: docker://ghcr.io/su2code/su2/build-su2-tsan:260405-0054 with: args: -b ${{github.ref}} -f "${{matrix.flags}}" - name: Compress binaries @@ -113,7 +113,7 @@ jobs: name: ${{ matrix.config_set }} path: install_bin.tgz - name: Post Cleanup - uses: docker://ghcr.io/su2code/su2/build-su2-tsan:250717-1402 + uses: docker://ghcr.io/su2code/su2/build-su2-tsan:260405-0054 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} @@ -125,9 +125,9 @@ jobs: config_set: [BaseNoMPI-asan, ReverseNoMPI-asan] include: - config_set: BaseNoMPI-asan - flags: '--buildtype=debugoptimized -Denable-openblas=true -Dwith-mpi=disabled -Denable-mlpcpp=true --warnlevel=3 --werror' + flags: '--buildtype=debugoptimized -Dcpu-arch=skylake -Denable-openblas=true -Dwith-mpi=disabled -Denable-mlpcpp=true --warnlevel=3 --werror' - config_set: ReverseNoMPI-asan - flags: '--buildtype=debugoptimized --optimization=1 -Denable-autodiff=true -Denable-normal=false -Dwith-mpi=disabled --warnlevel=3 --werror' + flags: '--buildtype=debugoptimized -Dcpu-arch=skylake --optimization=1 -Denable-autodiff=true -Denable-normal=false -Dwith-mpi=disabled --warnlevel=3 --werror' runs-on: ${{ inputs.runner || 'ubuntu-latest' }} steps: - name: Cache Object Files @@ -137,12 +137,12 @@ jobs: key: ${{ matrix.config_set }}-${{ github.sha }} restore-keys: ${{ matrix.config_set }} - name: Pre Cleanup - uses: docker://ghcr.io/su2code/su2/build-su2-asan:250717-1402 + uses: docker://ghcr.io/su2code/su2/build-su2-asan:260405-0054 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} - name: Build - run: docker run --rm --cap-add SYS_PTRACE -v $(pwd):${{ github.workspace }} -w ${{ github.workspace }} ghcr.io/su2code/su2/build-su2-asan:250717-1402 -b ${{github.ref}} -f "${{matrix.flags}}" + run: docker run --rm --cap-add SYS_PTRACE -v $(pwd):${{ github.workspace }} -w ${{ github.workspace }} ghcr.io/su2code/su2/build-su2-asan:260405-0054 -b ${{github.ref}} -f "${{matrix.flags}}" - name: Compress binaries run: tar -zcvf install_bin.tgz install/* - name: Upload Binaries @@ -151,7 +151,7 @@ jobs: name: ${{ matrix.config_set }} path: install_bin.tgz - name: Post Cleanup - uses: docker://ghcr.io/su2code/su2/build-su2-asan:250717-1402 + uses: docker://ghcr.io/su2code/su2/build-su2-asan:260405-0054 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} @@ -182,7 +182,7 @@ jobs: tag: OMP steps: - name: Pre Cleanup - uses: docker://ghcr.io/su2code/su2/test-su2:250717-1402 + uses: docker://ghcr.io/su2code/su2/test-su2:260405-0054 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} @@ -208,12 +208,12 @@ jobs: chmod a+x $BIN_FOLDER/* ls -lahR $BIN_FOLDER - name: Run Tests in Container - uses: docker://ghcr.io/su2code/su2/test-su2:250717-1402 + uses: docker://ghcr.io/su2code/su2/test-su2:260405-0054 with: # -t -c args: -b ${{github.ref}} -t develop -c develop -s ${{matrix.testscript}} - name: Cleanup - uses: docker://ghcr.io/su2code/su2/test-su2:250717-1402 + uses: docker://ghcr.io/su2code/su2/test-su2:260405-0054 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} @@ -231,7 +231,7 @@ jobs: tag: TagNoMPI steps: - name: Pre Cleanup - uses: docker://ghcr.io/su2code/su2/test-su2:250717-1402 + uses: docker://ghcr.io/su2code/su2/test-su2:260405-0054 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} @@ -257,12 +257,12 @@ jobs: chmod a+x $BIN_FOLDER/* ls -lahR $BIN_FOLDER - name: Run Tests in Container - uses: docker://ghcr.io/su2code/su2/test-su2:250717-1402 + uses: docker://ghcr.io/su2code/su2/test-su2:260405-0054 with: # -t -c args: -b ${{github.ref}} -t develop -c develop -s ${{matrix.testscript}} -a "--tapetests" - name: Cleanup - uses: docker://ghcr.io/su2code/su2/test-su2:250717-1402 + uses: docker://ghcr.io/su2code/su2/test-su2:260405-0054 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} @@ -277,7 +277,7 @@ jobs: testscript: ['hybrid_regression.py', 'hybrid_regression_AD.py'] steps: - name: Pre Cleanup - uses: docker://ghcr.io/su2code/su2/test-su2-tsan:250717-1402 + uses: docker://ghcr.io/su2code/su2/test-su2-tsan:260405-0054 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} @@ -303,12 +303,14 @@ jobs: chmod a+x $BIN_FOLDER/* ls -lahR $BIN_FOLDER - name: Run Tests in Container - uses: docker://ghcr.io/su2code/su2/test-su2-tsan:250717-1402 + uses: docker://ghcr.io/su2code/su2/test-su2-tsan:260405-0054 + env: + PMIX_MCA_gds: hash with: # -t -c args: -b ${{github.ref}} -t develop -c develop -s ${{matrix.testscript}} -a "--tsan" - name: Cleanup - uses: docker://ghcr.io/su2code/su2/test-su2-tsan:250717-1402 + uses: docker://ghcr.io/su2code/su2/test-su2-tsan:260405-0054 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} @@ -322,7 +324,7 @@ jobs: testscript: ['serial_regression.py', 'serial_regression_AD.py'] steps: - name: Pre Cleanup - uses: docker://ghcr.io/su2code/su2/test-su2-asan:250717-1402 + uses: docker://ghcr.io/su2code/su2/test-su2-asan:260405-0054 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} @@ -348,12 +350,12 @@ jobs: chmod a+x $BIN_FOLDER/* ls -lahR $BIN_FOLDER - name: Run Tests in Container - uses: docker://ghcr.io/su2code/su2/test-su2-asan:250717-1402 + uses: docker://ghcr.io/su2code/su2/test-su2-asan:260405-0054 with: # -t -c args: -b ${{github.ref}} -t develop -c develop -s ${{matrix.testscript}} -a "--asan" - name: Cleanup - uses: docker://ghcr.io/su2code/su2/test-su2-asan:250717-1402 + uses: docker://ghcr.io/su2code/su2/test-su2-asan:260405-0054 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} @@ -374,7 +376,7 @@ jobs: tag: MPI steps: - name: Pre Cleanup - uses: docker://ghcr.io/su2code/su2/test-su2:250717-1402 + uses: docker://ghcr.io/su2code/su2/test-su2:260405-0054 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} @@ -435,11 +437,13 @@ jobs: echo $PWD ls -lahR - name: Run Unit Tests - uses: docker://ghcr.io/su2code/su2/test-su2:250717-1402 + uses: docker://ghcr.io/su2code/su2/test-su2:260405-0054 + env: + OMPI_MCA_osc: pt2pt with: entrypoint: install/bin/${{matrix.testdriver}} - name: Post Cleanup - uses: docker://ghcr.io/su2code/su2/test-su2:250717-1402 + uses: docker://ghcr.io/su2code/su2/test-su2:260405-0054 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} diff --git a/.github/workflows/release-management.yml b/.github/workflows/release-management.yml index b018716a3697..cb9dd60b98e0 100644 --- a/.github/workflows/release-management.yml +++ b/.github/workflows/release-management.yml @@ -12,20 +12,20 @@ jobs: strategy: fail-fast: false matrix: - os_bin: [macos64, macos64-mpi, linux64, linux64-mpi, win64, win64-mpi] + os_bin: [macos64, macos64-mpi, linux64-omp, linux64-mpi, win64-omp, win64-mpi] include: - - os_bin: win64 - flags: '-Dwith-mpi=disabled --cross-file=/hostfiles/hostfile_windows' + - os_bin: win64-omp + flags: '-Dcpu-arch=haswell -Dwith-omp=true -Dwith-mpi=disabled --cross-file=/hostfiles/hostfile_windows' - os_bin: win64-mpi - flags: '-Dcustom-mpi=true --cross-file=/hostfiles/hostfile_windows_mpi' + flags: '-Dcpu-arch=haswell -Dcustom-mpi=true --cross-file=/hostfiles/hostfile_windows_mpi' - os_bin: macos64 - flags: '-Dwith-mpi=disabled --cross-file=/hostfiles/hostfile_darwin' + flags: '-Dcpu-arch= -Dwith-mpi=disabled --cross-file=/hostfiles/hostfile_darwin' - os_bin: macos64-mpi - flags: '-Dcustom-mpi=true --cross-file=/hostfiles/hostfile_darwin_mpi' - - os_bin: linux64 - flags: '-Dwith-mpi=disabled -Dstatic-cgns-deps=true --cross-file=/hostfiles/hostfile_linux' + flags: '-Dcpu-arch= -Dcustom-mpi=true --cross-file=/hostfiles/hostfile_darwin_mpi' + - os_bin: linux64-omp + flags: '-Dcpu-arch=haswell -Dwith-omp=true -Dwith-mpi=disabled -Dstatic-cgns-deps=true --cross-file=/hostfiles/hostfile_linux' - os_bin: linux64-mpi - flags: '-Dcustom-mpi=true --cross-file=/hostfiles/hostfile_linux_mpi' + flags: '-Dcpu-arch=haswell -Dcustom-mpi=true --cross-file=/hostfiles/hostfile_linux_mpi' runs-on: ubuntu-latest steps: - name: Cache Object Files @@ -35,7 +35,7 @@ jobs: key: ${{ matrix.os_bin }}-${{ github.sha }} restore-keys: ${{ matrix.os_bin }} - name: Build - uses: docker://ghcr.io/su2code/su2/build-su2-cross:250717-1402 + uses: docker://ghcr.io/su2code/su2/build-su2-cross:260405-0054 with: args: -b ${{ github.sha }} -f "${{matrix.flags}}" - name: Create Archive diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index f198df434761..7405a527eac7 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -488,7 +488,7 @@ class CConfig { unsigned short **DegreeFFDBox; /*!< \brief Degree of the FFD boxes. */ string *FFDTag; /*!< \brief Parameters of the design variable. */ string *TagFFDBox; /*!< \brief Tag of the FFD box. */ - unsigned short GeometryMode; /*!< \brief Gemoetry mode (analysis or gradient computation). */ + unsigned short GeometryMode; /*!< \brief Geometry mode (analysis or gradient computation). */ unsigned short MGCycle; /*!< \brief Kind of multigrid cycle. */ unsigned short FinestMesh; /*!< \brief Finest mesh for the full multigrid approach. */ unsigned short nFFD_Fix_IDir, @@ -651,6 +651,7 @@ class CConfig { unsigned long Linear_Solver_Prec_Threads; /*!< \brief Number of threads per rank for ILU and LU_SGS preconditioners. */ unsigned short Linear_Solver_ILU_n; /*!< \brief ILU fill=in level. */ su2double SemiSpan; /*!< \brief Wing Semi span. */ + su2double MSW_Alpha; /*!< \brief Coefficient for blending states in the MSW scheme. */ su2double Roe_Kappa; /*!< \brief Relaxation of the Roe scheme. */ su2double Relaxation_Factor_Adjoint; /*!< \brief Relaxation coefficient for variable updates of adjoint solvers. */ su2double Relaxation_Factor_CHT; /*!< \brief Relaxation coefficient for the update of conjugate heat variables. */ @@ -739,6 +740,7 @@ class CConfig { nMarker_ZoneInterface, /*!< \brief Number of markers in the zone interface. */ nMarker_Plotting, /*!< \brief Number of markers to plot. */ nMarker_Analyze, /*!< \brief Number of markers to analyze. */ + nMarker_Create_Copy, /*!< \brief Number of markers to duplicate. */ nMarker_Moving, /*!< \brief Number of markers in motion (DEFORMING, MOVING_WALL). */ nMarker_PyCustom, /*!< \brief Number of markers that are customizable in Python. */ nMarker_DV, /*!< \brief Number of markers affected by the design variables. */ @@ -750,6 +752,7 @@ class CConfig { *Marker_GeoEval, /*!< \brief Markers to evaluate geometry. */ *Marker_Plotting, /*!< \brief Markers to plot. */ *Marker_Analyze, /*!< \brief Markers to analyze. */ + *Marker_Create_Copy, /*!< \brief Markers to duplicate. */ *Marker_ZoneInterface, /*!< \brief Markers in the FSI interface. */ *Marker_Moving, /*!< \brief Markers in motion (DEFORMING, MOVING_WALL). */ *Marker_PyCustom, /*!< \brief Markers that are customizable in Python. */ @@ -929,6 +932,7 @@ class CConfig { Pressure_Thermodynamic, /*!< \brief Thermodynamic pressure of the fluid. */ Temperature_FreeStream, /*!< \brief Total temperature of the fluid. */ Temperature_ve_FreeStream; /*!< \brief Total vibrational-electronic temperature of the fluid. */ + bool out2in_mdot_engine; /*!< \brief Flag to use engine outlet mass flow as engine inlet mass flow. */ unsigned short wallModel_MaxIter; /*!< \brief maximum number of iterations for the Newton method for the wall model */ su2double wallModel_Kappa, /*!< \brief von Karman constant kappa for turbulence wall modeling */ wallModel_B, /*!< \brief constant B for turbulence wall modeling */ @@ -2115,6 +2119,12 @@ class CConfig { */ su2double GetNuFactor_Engine(void) const { return NuFactor_Engine; } + /*! + * \brief Get the flag to use exhaust mass flow as inlet mass flow. + * \return TRUE if exhaust mass flow is used as inlet mass flow. + */ + bool GetExhaustToInlet_Engine(void) const { return out2in_mdot_engine; } + /*! * \brief Get the value of the non-dimensionalized actuator disk turbulence intensity. * \return Non-dimensionalized actuator disk intensity. @@ -2911,7 +2921,7 @@ class CConfig { unsigned short GetFinestMesh(void) const { return FinestMesh; } /*! - * \brief Get the kind of multigrid (V or W). + * \brief Get the kind of multigrid (V, W or FULLMG). * \note This variable is used in a recursive way to perform the different kind of cycles * \return 0 or 1 depending of we are dealing with a V or W cycle. */ @@ -3054,7 +3064,27 @@ class CConfig { * \brief Get the number of Runge-Kutta steps. * \return Number of Runge-Kutta steps. */ - unsigned short GetnRKStep(void) const { return nRKStep; } + unsigned short GetnRKStep(void) const { + + unsigned short iRKLimit = 1; + + switch (GetKind_TimeIntScheme()) { + case RUNGE_KUTTA_EXPLICIT: + iRKLimit = nRKStep; + break; + case CLASSICAL_RK4_EXPLICIT: + iRKLimit = 4; + break; + case EULER_EXPLICIT: + case EULER_IMPLICIT: + iRKLimit = 1; + break; + default: + iRKLimit = 1; + break; + } + return iRKLimit; + } /*! * \brief Get the number of time levels for time accurate local time stepping. @@ -3450,13 +3480,20 @@ class CConfig { */ string GetMarker_HeatFlux_TagBound(unsigned short val_marker) const { return Marker_HeatFlux[val_marker]; } + /*! + * \brief Get the list of markers for which to create copies. + */ + std::vector GetMarkerCreateCopy() const { + return { Marker_Create_Copy, Marker_Create_Copy + nMarker_Create_Copy }; + } + /*! * \brief Get the tag if the iMarker defined in the geometry file. * \param[in] val_tag - Value of the tag in which we are interested. * \return Value of the marker val_marker that is in the geometry file * for the surface that has the tag. */ - short GetMarker_All_TagBound(string val_tag) { + short GetMarker_All_TagBound(const string& val_tag) { for (unsigned short iMarker = 0; iMarker < nMarker_All; iMarker++) { if (val_tag == Marker_All_TagBound[iMarker]) return iMarker; } @@ -4432,6 +4469,11 @@ class CConfig { */ void SetNewtonKrylovRelaxation(const su2double& relaxation) { NK_Relaxation = relaxation; } + /*! + * \brief Returns the MSW alpha (coefficient of the state blending weight). + */ + su2double GetMSW_Alpha(void) const { return MSW_Alpha; } + /*! * \brief Returns the Roe kappa (multipler of the dissipation term). */ diff --git a/Common/include/code_config.hpp b/Common/include/code_config.hpp index eafaa844d8f9..2585283d34d7 100644 --- a/Common/include/code_config.hpp +++ b/Common/include/code_config.hpp @@ -28,6 +28,12 @@ #include +#if defined(_MSC_VER) +#define PRAGMIZE(X) __pragma(X) +#else +#define PRAGMIZE(X) _Pragma(#X) +#endif + #if defined(_MSC_VER) #define FORCEINLINE __forceinline #elif defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER) @@ -151,3 +157,13 @@ using su2mixedfloat = passivedouble; #define HAVE_OMPT #endif #endif + +#ifdef __GNUC__ +#define SU2_IGNORE_WARNING(WARNING) \ + PRAGMIZE(GCC diagnostic push) \ + PRAGMIZE(GCC diagnostic ignored WARNING) +#define SU2_RESTORE_WARNING PRAGMIZE(GCC diagnostic pop) +#else +#define SU2_IGNORE_WARNING(WARNING) +#define SU2_RESTORE_WARNING +#endif diff --git a/Common/include/containers/C2DContainer.hpp b/Common/include/containers/C2DContainer.hpp index 24d2609bece3..b7489f767d7c 100644 --- a/Common/include/containers/C2DContainer.hpp +++ b/Common/include/containers/C2DContainer.hpp @@ -421,7 +421,7 @@ class C2DContainer template class CInnerIterGather { private: - static_assert(std::is_integral::value, ""); + static_assert(std::is_integral::value); enum { Size = IndexSIMD_t::Size }; IndexSIMD_t m_offsets; const Index m_increment; @@ -545,7 +545,10 @@ class C2DContainer * \brief Set value of all entries to "value". */ void setConstant(const Scalar_t& value) noexcept { + // GCC 13 has a false-positive about overflow of memcpy due to size being uint64_t, and its memcpy just int64_t. + SU2_IGNORE_WARNING("-Wstringop-overflow") for (size_t i = 0; i < size(); ++i) m_data[i] = value; + SU2_RESTORE_WARNING } /*! diff --git a/Common/include/containers/CPyWrapperMatrixView.hpp b/Common/include/containers/CPyWrapperMatrixView.hpp index 86836f3a30fd..1b9ef2223fc2 100644 --- a/Common/include/containers/CPyWrapperMatrixView.hpp +++ b/Common/include/containers/CPyWrapperMatrixView.hpp @@ -84,7 +84,7 @@ */ class CPyWrapperMatrixView { protected: - static_assert(su2activematrix::IsRowMajor, ""); + static_assert(su2activematrix::IsRowMajor); su2double* data_ = nullptr; unsigned long rows_ = 0, cols_ = 0; std::string name_; @@ -124,7 +124,7 @@ class CPyWrapperMatrixView { */ class CPyWrapperMarkerMatrixView { private: - static_assert(su2activematrix::IsRowMajor, ""); + static_assert(su2activematrix::IsRowMajor); su2double* data_ = nullptr; const CVertex* const* vertices_ = nullptr; unsigned long rows_ = 0, cols_ = 0; @@ -175,7 +175,7 @@ class CPyWrapperMarkerMatrixView { */ class CPyWrapper3DMatrixView { protected: - static_assert(su2activematrix::IsRowMajor, ""); + static_assert(su2activematrix::IsRowMajor); su2double* data_ = nullptr; unsigned long rows_ = 0, cols_ = 0, dims_ = 0; std::string name_; diff --git a/Common/include/geometry/CMultiGridGeometry.hpp b/Common/include/geometry/CMultiGridGeometry.hpp index 00faa8126c6f..f6036be227f8 100644 --- a/Common/include/geometry/CMultiGridGeometry.hpp +++ b/Common/include/geometry/CMultiGridGeometry.hpp @@ -31,25 +31,25 @@ /*! * \class CMultiGridGeometry - * \brief Class for defining the multigrid geometry, the main delicated part is the + * \brief Class for defining the multigrid geometry, the main dedicated part is the * agglomeration stage, which is done in the declaration. * \author F. Palacios */ class CMultiGridGeometry final : public CGeometry { private: /*! - * \brief Determine if a CVPoint van be agglomerated, if it have the same marker point as the seed. + * \brief Determine if a CVPoint can be agglomerated, if it has the same marker point as the seed. * \param[in] CVPoint - Control volume to be agglomerated. * \param[in] marker_seed - Marker of the seed. * \param[in] fine_grid - Geometrical definition of the problem. * \param[in] config - Definition of the particular problem. * \return TRUE or FALSE depending if the control volume can be agglomerated. */ - bool SetBoundAgglomeration(unsigned long CVPoint, short marker_seed, const CGeometry* fine_grid, + bool SetBoundAgglomeration(unsigned long CVPoint, vector marker_seed, const CGeometry* fine_grid, const CConfig* config) const; /*! - * \brief Determine if a can be agglomerated using geometrical criteria. + * \brief Determine if a Point can be agglomerated using geometrical criteria. * \param[in] iPoint - Seed point. * \param[in] fine_grid - Geometrical definition of the problem. * \param[in] config - Definition of the particular problem. @@ -57,7 +57,7 @@ class CMultiGridGeometry final : public CGeometry { bool GeometricalCheck(unsigned long iPoint, const CGeometry* fine_grid, const CConfig* config) const; /*! - * \brief Determine if a CVPoint van be agglomerated, if it have the same marker point as the seed. + * \brief Determine if a CVPoint can be agglomerated, if it has the same marker point as the seed. * \param[out] Suitable_Indirect_Neighbors - List of Indirect Neighbours that can be agglomerated. * \param[in] iPoint - Seed point. * \param[in] Index_CoarseCV - Index of agglomerated point. @@ -66,6 +66,15 @@ class CMultiGridGeometry final : public CGeometry { void SetSuitableNeighbors(vector& Suitable_Indirect_Neighbors, unsigned long iPoint, unsigned long Index_CoarseCV, const CGeometry* fine_grid) const; + /*! + * \brief Compute local curvature at a boundary vertex on Euler wall. + * \param[in] fine_grid - Fine grid geometry. + * \param[in] iPoint - Point index. + * \param[in] iMarker - Marker index. + * \return Maximum angle (in degrees) between this vertex normal and adjacent vertex normals. + */ + su2double ComputeLocalCurvature(const CGeometry* fine_grid, unsigned long iPoint, unsigned short iMarker) const; + public: /*--- This is to suppress Woverloaded-virtual, omitting it has no negative impact. ---*/ using CGeometry::SetBoundControlVolume; diff --git a/Common/include/geometry/CMultiGridQueue.hpp b/Common/include/geometry/CMultiGridQueue.hpp index 296d4e8f73d8..c16e23520e48 100644 --- a/Common/include/geometry/CMultiGridQueue.hpp +++ b/Common/include/geometry/CMultiGridQueue.hpp @@ -93,7 +93,7 @@ class CMultiGridQueue { void IncrPriorityCV(unsigned long incrPoint); /*! - * \brief Increase the priority of the CV. + * \brief Reduce the priority of the CV. * \param[in] redPoint - Index of the control volume. */ void RedPriorityCV(unsigned long redPoint); diff --git a/Common/include/geometry/elements/CElement.hpp b/Common/include/geometry/elements/CElement.hpp index 2d04c90ed719..e2e436f8169c 100644 --- a/Common/include/geometry/elements/CElement.hpp +++ b/Common/include/geometry/elements/CElement.hpp @@ -249,7 +249,8 @@ class CElement { * \param[in] nodeB - index of Node b. * \param[in] val_Kab - value of the matrix K. */ - inline void Add_Kab(unsigned short nodeA, unsigned short nodeB, su2double** val_Kab) { + template + inline void Add_Kab(unsigned short nodeA, unsigned short nodeB, Matrix& val_Kab) { for (unsigned short iDim = 0; iDim < nDim; iDim++) for (unsigned short jDim = 0; jDim < nDim; jDim++) Kab[nodeA](nodeB, iDim * nDim + jDim) += val_Kab[iDim][jDim]; } @@ -259,7 +260,8 @@ class CElement { * transpose) \param[in] nodeA - index of Node a. \param[in] nodeB - index of Node b. \param[in] val_Kab - value of * the matrix K. */ - inline void Add_Kab_T(unsigned short nodeA, unsigned short nodeB, su2double** val_Kab) { + template + inline void Add_Kab_T(unsigned short nodeA, unsigned short nodeB, Matrix& val_Kab) { for (unsigned short iDim = 0; iDim < nDim; iDim++) for (unsigned short jDim = 0; jDim < nDim; jDim++) Kab[nodeA](nodeB, iDim * nDim + jDim) += val_Kab[jDim][iDim]; } diff --git a/Common/include/geometry/meshreader/CMeshReaderBase.hpp b/Common/include/geometry/meshreader/CMeshReaderBase.hpp index f8cdc2799b06..74fdffb22f24 100644 --- a/Common/include/geometry/meshreader/CMeshReaderBase.hpp +++ b/Common/include/geometry/meshreader/CMeshReaderBase.hpp @@ -89,6 +89,12 @@ class CMeshReaderBase { void GetCornerPointsAllFaces(const unsigned long* elemInfo, unsigned short& numFaces, unsigned short nPointsPerFace[], unsigned long faceConn[6][4]); + /*! + * \brief Creates copies of some markers. + * \param[in] srcDstMarkers - List of marker names [src_1, dst_1, ..., src_n, dst_n]. + */ + void CopyMarkers(const std::vector& srcDstMarkers); + public: /*! * \brief Constructor of the CMeshReaderBase class. diff --git a/Common/include/linear_algebra/CPastixWrapper.hpp b/Common/include/linear_algebra/CPastixWrapper.hpp index 8b22a15cd4a3..b3dfc4714ca9 100644 --- a/Common/include/linear_algebra/CPastixWrapper.hpp +++ b/Common/include/linear_algebra/CPastixWrapper.hpp @@ -34,11 +34,8 @@ #error Cannot use PaStiX with forward mode AD #endif -namespace PaStiX { -extern "C" { #include -} -} // namespace PaStiX +#include #include using namespace std; @@ -55,17 +52,18 @@ class CGeometry; template class CPastixWrapper { private: - PaStiX::pastix_data_t* state; /*!< \brief Internal state of the solver. */ - PaStiX::pastix_int_t nCols; /*!< \brief Local number of columns. */ - vector colptr; /*!< \brief Equiv. to our "row_ptr". */ - vector rowidx; /*!< \brief Equiv. to our "col_ind". */ - vector values; /*!< \brief Equiv. to our "matrix". */ - vector loc2glb; /*!< \brief Global index of the columns held by this rank. */ - vector perm; /*!< \brief Ordering computed by PaStiX. */ - vector workvec; /*!< \brief RHS vector which then becomes the solution. */ - - PaStiX::pastix_int_t iparm[PaStiX::IPARM_SIZE]; /*!< \brief Integer parameters for PaStiX. */ - passivedouble dparm[PaStiX::DPARM_SIZE]; /*!< \brief Floating point parameters for PaStiX. */ + pastix_data_t* state{}; /*!< \brief Internal state of the solver. */ + spmatrix_t spm; /*!< \brief Matrix format used by the solver. */ + pastix_int_t nCols; /*!< \brief Local number of columns. */ + vector colptr; /*!< \brief Equiv. to our "row_ptr". */ + vector rowidx; /*!< \brief Equiv. to our "col_ind". */ + vector values; /*!< \brief Equiv. to our "matrix". */ + vector loc2glb; /*!< \brief Global index of the columns held by this rank. */ + 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. */ struct { unsigned long nVar = 0; @@ -78,35 +76,32 @@ class CPastixWrapper { unsigned long size_rhs() const { return nPointDomain * nVar; } } matrix; /*!< \brief Pointers and sizes of the input matrix. */ - bool issetup; /*!< \brief Signals that the matrix data has been provided. */ - bool isinitialized; /*!< \brief Signals that the sparsity pattern has been set. */ - bool isfactorized; /*!< \brief Signals that a factorization has been computed. */ - unsigned long iter; /*!< \brief Number of times a factorization has been requested. */ - unsigned short verb; /*!< \brief Verbosity level. */ - const int mpi_size, mpi_rank; + bool issetup{}; /*!< \brief Signals that the matrix data has been provided. */ + bool isinitialized{}; /*!< \brief Signals that the sparsity pattern has been set. */ + bool isfactorized{}; /*!< \brief Signals that a factorization has been computed. */ + bool transpose{}; /*!< \brief Solve A^T x = b instead of A x = b. */ + unsigned long iter{}; /*!< \brief Number of times a factorization has been requested. */ + unsigned short verb{}; /*!< \brief Verbosity level. */ + const int mpi_size = SU2_MPI::GetSize(); + const int mpi_rank = SU2_MPI::GetRank(); - vector sort_rows; /*!< \brief List of rows with halo points. */ - vector > sort_order; /*!< \brief How each of those rows needs to be sorted. */ - - /*! - * \brief Run the external solver for the task it is currently setup to execute. - */ - void Run() { - dpastix(&state, SU2_MPI::GetComm(), nCols, colptr.data(), rowidx.data(), values.data(), loc2glb.data(), perm.data(), - NULL, workvec.data(), 1, iparm, dparm); - } + vector sort_rows; /*!< \brief List of rows with halo points. */ + vector> sort_order; /*!< \brief How each of those rows needs to be sorted. */ /*! * \brief Run the "clean" task, releases all memory, leaves object in unusable state. */ void Clean() { - using namespace PaStiX; - if (isfactorized) { - iparm[IPARM_VERBOSE] = (verb > 0) ? API_VERBOSE_NO : API_VERBOSE_NOT; - iparm[IPARM_START_TASK] = API_TASK_CLEAN; - iparm[IPARM_END_TASK] = API_TASK_CLEAN; - Run(); + if (isinitialized) { + iparm[IPARM_VERBOSE] = (verb > 0) ? PastixVerboseNo : PastixVerboseNot; + pastixFinalize(&state); + spm.colptr = nullptr; + spm.rowptr = nullptr; + spm.values = nullptr; + if (mpi_size > 1) spm.loc2glob = nullptr; + spmExit(&spm); isfactorized = false; + isinitialized = false; } } @@ -116,18 +111,7 @@ class CPastixWrapper { void Initialize(CGeometry* geometry, const CConfig* config); public: - /*! - * \brief Class constructor. - */ - CPastixWrapper() - : state(nullptr), - issetup(false), - isinitialized(false), - isfactorized(false), - iter(0), - verb(0), - mpi_size(SU2_MPI::GetSize()), - mpi_rank(SU2_MPI::GetRank()) {} + CPastixWrapper() = default; /*--- Move or copy is not allowed. ---*/ CPastixWrapper(CPastixWrapper&&) = delete; @@ -173,11 +157,7 @@ class CPastixWrapper { * \brief Request solves with the transposed matrix. * \param[in] transposed - Yes or no. */ - void SetTransposedSolve(bool transposed = true) { - using namespace PaStiX; - if (iparm[IPARM_SYM] == API_SYM_NO) - iparm[IPARM_TRANSPOSE_SOLVE] = pastix_int_t(!transposed); // negated due to CSR to CSC copy - } + void SetTransposedSolve(bool transposed = true) { transpose = transposed; } /*! * \brief Runs the "solve" task for any rhs/sol with operator [] @@ -186,20 +166,21 @@ class CPastixWrapper { */ template void Solve(const T& rhs, T& sol) { - using namespace PaStiX; - if (!isfactorized) SU2_MPI::Error("The factorization has not been computed yet.", CURRENT_FUNCTION); - unsigned long i; - - for (i = 0; i < matrix.size_rhs(); ++i) workvec[i] = rhs[i]; - - iparm[IPARM_VERBOSE] = API_VERBOSE_NOT; - iparm[IPARM_START_TASK] = API_TASK_SOLVE; - iparm[IPARM_END_TASK] = API_TASK_SOLVE; - Run(); + /*--- Inverted logic due to CSR to CSC direct copy (PaStiX's A is our A^T). ---*/ + if (iparm[IPARM_FACTORIZATION] == PastixFactLDLT || transpose) { + iparm[IPARM_TRANSPOSE_SOLVE] = PastixNoTrans; + } else { + iparm[IPARM_TRANSPOSE_SOLVE] = PastixTrans; + } + iparm[IPARM_VERBOSE] = PastixVerboseNot; - for (i = 0; i < matrix.size_rhs(); ++i) sol[i] = workvec[i]; + for (auto i = 0ul; i < matrix.size_rhs(); ++i) workvec[i] = rhs[i]; + if (pastix_task_solve(state, matrix.size_rhs(), 1, workvec.data(), matrix.size_rhs()) != PASTIX_SUCCESS) { + SU2_MPI::Error("Error solving linear system.", CURRENT_FUNCTION); + } + for (auto i = 0ul; i < matrix.size_rhs(); ++i) sol[i] = workvec[i]; } }; #endif diff --git a/Common/include/linear_algebra/CSysMatrix.hpp b/Common/include/linear_algebra/CSysMatrix.hpp index 73ca2d5f568d..823f15a51fcf 100644 --- a/Common/include/linear_algebra/CSysMatrix.hpp +++ b/Common/include/linear_algebra/CSysMatrix.hpp @@ -148,7 +148,7 @@ class CSysMatrix { ScalarType* d_matrix; /*!< \brief Device Pointer to store the matrix values on the GPU. */ const unsigned long* d_row_ptr; /*!< \brief Device Pointers to the first element in each row. */ const unsigned long* d_col_ind; /*!< \brief Device Column index for each of the elements in val(). */ - bool useCuda; /*!< \brief Boolean that indicates whether user has enabled CUDA or not. + bool useCuda = false; /*!< \brief Boolean that indicates whether user has enabled CUDA or not. Mainly used to conditionally free GPU memory in the class destructor. */ ScalarType* ILU_matrix; /*!< \brief Entries of the ILU sparse matrix. */ @@ -816,10 +816,11 @@ class CSysMatrix { } /*! - * \brief Deletes the values of the row i of the sparse matrix. - * \param[in] i - Index of the row. + * \brief Deletes the values of a row of the sparse matrix. + * \param[in] block_i - Index of the block. + * \param[in] row - Row within the block. */ - void DeleteValsRowi(unsigned long i); + void DeleteValsRowi(unsigned long block_i, unsigned long row); /*! * \brief Modifies this matrix (A) and a rhs vector (b) such that (A^-1 * b)_i = x_i. diff --git a/Common/include/linear_algebra/CSysVector.hpp b/Common/include/linear_algebra/CSysVector.hpp index 4d7768971be9..f300c01e091b 100644 --- a/Common/include/linear_algebra/CSysVector.hpp +++ b/Common/include/linear_algebra/CSysVector.hpp @@ -28,6 +28,8 @@ #pragma once +#include + #include "../parallelization/mpi_structure.hpp" #include "../parallelization/omp_structure.hpp" #include "../parallelization/vectorization.hpp" @@ -75,6 +77,13 @@ class CSysVector : public VecExpr::CVecExpr, ScalarType> ScalarType* d_vec_val = nullptr; /*!< \brief Device Pointer to store the vector values on the GPU. */ +#ifdef HAVE_OMP + mutable std::unique_ptr + dot_scratch; /*!< \brief Stores partial sums for ordered reduction over OMP threads. */ +#else + mutable std::array dot_scratch; +#endif + /*! * \brief Generic initialization from a scalar or array. * \note If val==nullptr vec_val is not initialized, only allocated. @@ -166,6 +175,7 @@ class CSysVector : public VecExpr::CVecExpr, ScalarType> std::swap(nElm, other.nElm); std::swap(nElmDomain, other.nElmDomain); std::swap(nVar, other.nVar); + std::swap(dot_scratch, other.dot_scratch); } /*! @@ -333,9 +343,8 @@ class CSysVector : public VecExpr::CVecExpr, ScalarType> */ template ScalarType dot(const VecExpr::CVecExpr& expr) const { - static ScalarType dotRes; - /*--- All threads get the same "view" of the vectors and shared variable. ---*/ - SU2_OMP_SAFE_GLOBAL_ACCESS(dotRes = 0.0;) + /*--- All threads get the same "view" of the vectors. ---*/ + SU2_OMP_BARRIER /*--- Local dot product for each thread. ---*/ ScalarType sum = 0.0; @@ -346,23 +355,20 @@ class CSysVector : public VecExpr::CVecExpr, ScalarType> } END_CSYSVEC_PARFOR - /*--- Update shared variable with "our" partial sum. ---*/ - atomicAdd(sum, dotRes); + dot_scratch[omp_get_thread_num()] = sum; -#ifdef HAVE_MPI - /*--- Reduce across all mpi ranks, only master thread communicates. ---*/ BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { - sum = dotRes; + /*--- Reduce over all threads in an ordered way to ensure a deterministic result. ---*/ + for (int i = 1; i < omp_get_num_threads(); ++i) sum += dot_scratch[i]; + + /*--- Reduce across all mpi ranks, only the master thread communicates. ---*/ const auto mpi_type = (sizeof(ScalarType) < sizeof(double)) ? MPI_FLOAT : MPI_DOUBLE; - SelectMPIWrapper::W::Allreduce(&sum, &dotRes, 1, mpi_type, MPI_SUM, SU2_MPI::GetComm()); + SelectMPIWrapper::W::Allreduce(&sum, &dot_scratch[0], 1, mpi_type, MPI_SUM, SU2_MPI::GetComm()); } - END_SU2_OMP_SAFE_GLOBAL_ACCESS -#else /*--- Make view of result consistent across threads. ---*/ - SU2_OMP_BARRIER -#endif + END_SU2_OMP_SAFE_GLOBAL_ACCESS - return dotRes; + return dot_scratch[0]; } /*! diff --git a/Common/include/linear_algebra/vector_expressions.hpp b/Common/include/linear_algebra/vector_expressions.hpp index 75ac69bf7b38..aa240d433dea 100644 --- a/Common/include/linear_algebra/vector_expressions.hpp +++ b/Common/include/linear_algebra/vector_expressions.hpp @@ -138,6 +138,7 @@ namespace math = ::std; #define sign_impl(x) Scalar(1 - 2 * (x < 0)) MAKE_UNARY_FUN(operator-, minus_, -) MAKE_UNARY_FUN(abs, abs_, math::abs) +MAKE_UNARY_FUN(exp, exp_, math::exp) MAKE_UNARY_FUN(sqrt, sqrt_, math::sqrt) MAKE_UNARY_FUN(sign, sign_, sign_impl) #undef sign_impl diff --git a/Common/include/option_structure.hpp b/Common/include/option_structure.hpp index 690350fae050..1361a12072da 100644 --- a/Common/include/option_structure.hpp +++ b/Common/include/option_structure.hpp @@ -1345,8 +1345,6 @@ inline LM_ParsedOptions ParseLMOptions(const LM_OPTIONS *LM_Options, unsigned sh * \brief Structure containing parsed options for data-driven fluid model. */ struct DataDrivenFluid_ParsedOptions { - su2double rho_init_custom = -1; /*!< \brief Optional initial guess for density in inverse look-up operations. */ - su2double e_init_custom = -1; /*!< \brief Optional initial guess for static energy in inverse look-up operations.*/ su2double Newton_relaxation = 1.0; /*!< \brief Relaxation factor for Newton solvers in data-driven fluid models. */ bool use_PINN = false; /*!< \brief Use physics-informed method for data-driven fluid modeling. */ ENUM_DATADRIVEN_METHOD interp_algorithm_type = ENUM_DATADRIVEN_METHOD::MLP; /*!< \brief Interpolation algorithm used for data-driven fluid model. */ diff --git a/Common/include/parallelization/mpi_structure.cpp b/Common/include/parallelization/mpi_structure.cpp index d491e6a77a3a..ae9a0ee25aef 100644 --- a/Common/include/parallelization/mpi_structure.cpp +++ b/Common/include/parallelization/mpi_structure.cpp @@ -28,15 +28,20 @@ #include "mpi_structure.hpp" #include // memcpy -/* Initialise the MPI Communicator Rank and Size */ +/* Initialise the MPI Communicator Rank, Size, and default MPI Communicator */ +#ifdef HAVE_MPI int CBaseMPIWrapper::Rank = 0; int CBaseMPIWrapper::Size = 1; - -/* Set the default MPI Communicator */ -#ifdef HAVE_MPI CBaseMPIWrapper::Comm CBaseMPIWrapper::currentComm = MPI_COMM_WORLD; #else -CBaseMPIWrapper::Comm CBaseMPIWrapper::currentComm = 0; // dummy value +template +int CBaseMPIWrapper::Rank = 0; + +template +int CBaseMPIWrapper::Size = 1; + +template +typename CBaseMPIWrapper::Comm CBaseMPIWrapper::currentComm = 0; // dummy value #endif #ifdef HAVE_MPI @@ -122,7 +127,8 @@ void CBaseMPIWrapper::CopyData(const void* sendbuf, void* recvbuf, int size, Dat } #else // HAVE_MPI -void CBaseMPIWrapper::Error(std::string ErrorMsg, std::string FunctionName) { +template +void CBaseMPIWrapper::Error(const std::string& ErrorMsg, const std::string& FunctionName) { if (Rank == 0) { std::cout << std::endl << std::endl; std::cout << "Error in \"" << FunctionName << "\": " << std::endl; @@ -134,12 +140,13 @@ void CBaseMPIWrapper::Error(std::string ErrorMsg, std::string FunctionName) { Abort(currentComm, 0); } -void CBaseMPIWrapper::CopyData(const void* sendbuf, void* recvbuf, int size, Datatype datatype, int recvshift, - int sendshift) { +template +void CBaseMPIWrapper::CopyData(const void* sendbuf, void* recvbuf, int size, Datatype datatype, + int recvshift, int sendshift) { switch (datatype) { case MPI_DOUBLE: for (int i = 0; i < size; i++) { - static_cast(recvbuf)[i + recvshift] = static_cast(sendbuf)[i + sendshift]; + static_cast(recvbuf)[i + recvshift] = static_cast(sendbuf)[i + sendshift]; } break; case MPI_UNSIGNED_LONG: @@ -178,8 +185,17 @@ void CBaseMPIWrapper::CopyData(const void* sendbuf, void* recvbuf, int size, Dat break; }; } + +template class CBaseMPIWrapper; +#if defined CODI_REVERSE_TYPE +template class CBaseMPIWrapper; +#endif +#if defined USE_MIXED_PRECISION +template class CBaseMPIWrapper; #endif +#endif // HAVE_MPI + #ifdef HAVE_MPI #if defined CODI_REVERSE_TYPE || defined CODI_FORWARD_TYPE MediTypes* mediTypes; diff --git a/Common/include/parallelization/mpi_structure.hpp b/Common/include/parallelization/mpi_structure.hpp index f6d09423daee..d19cfe8c2372 100644 --- a/Common/include/parallelization/mpi_structure.hpp +++ b/Common/include/parallelization/mpi_structure.hpp @@ -489,6 +489,7 @@ class CMediMPIWrapper : public CBaseMPIWrapper { * \class CMPIWrapper * \brief Version for when there is no MPI. */ +template class CBaseMPIWrapper { public: typedef int Comm; @@ -510,7 +511,7 @@ class CBaseMPIWrapper { static void CopyData(const void* sendbuf, void* recvbuf, int size, Datatype datatype, int recvshift = 0, int sendshift = 0); - static void Error(std::string ErrorMsg, std::string FunctionName); + static void Error(const std::string& ErrorMsg, const std::string& FunctionName); static inline int GetRank() { return Rank; } @@ -607,27 +608,37 @@ class CBaseMPIWrapper { static inline passivedouble Wtime(void) { return omp_get_wtime(); } }; -typedef int SU2_Comm; -typedef CBaseMPIWrapper SU2_MPI; +using SU2_Comm = int; +using SU2_MPI = CBaseMPIWrapper; #endif /*--- Select the appropriate MPI wrapper based on datatype, to use in templated classes. ---*/ template struct SelectMPIWrapper { - typedef SU2_MPI W; + using W = SU2_MPI; }; /*--- In AD we specialize for the passive wrapper. ---*/ #if defined CODI_REVERSE_TYPE template <> struct SelectMPIWrapper { - typedef CBaseMPIWrapper W; +#if defined HAVE_MPI + using W = CBaseMPIWrapper; +#else + using W = CBaseMPIWrapper; +#endif }; +#endif + +/*--- Specialize for the low precision type. ---*/ #if defined USE_MIXED_PRECISION template <> struct SelectMPIWrapper { - typedef CBaseMPIWrapper W; -}; +#if defined HAVE_MPI + using W = CBaseMPIWrapper; +#else + using W = CBaseMPIWrapper; #endif +}; #endif diff --git a/Common/include/parallelization/omp_structure.hpp b/Common/include/parallelization/omp_structure.hpp index 9b4f1461419c..3c9e5bca9816 100644 --- a/Common/include/parallelization/omp_structure.hpp +++ b/Common/include/parallelization/omp_structure.hpp @@ -39,15 +39,10 @@ #pragma once #include +#include #include "../code_config.hpp" -#if defined(_MSC_VER) -#define PRAGMIZE(X) __pragma(X) -#else -#define PRAGMIZE(X) _Pragma(#X) -#endif - #if defined(HAVE_OMP) #include @@ -274,3 +269,55 @@ inline void atomicAdd(T rhs, T& lhs) { SU2_OMP_ATOMIC lhs += rhs; } + +/*--- GCC supported atomic compare (for min/max) before it was fully 5.1 compliant. ---*/ +#define ATOMIC_COMPARE_SINCE 202011 +#ifdef __GNUC__ +#if __GNUC__ > 11 +#undef ATOMIC_COMPARE_SINCE +#define ATOMIC_COMPARE_SINCE 201511 +#endif +#endif + +/*--- By default the min/max fallback to critical is required for all types. ---*/ +#define ATOMIC_COMPARE_FALLBACK + +/*--- Atomic max, shared = max(shared, local). ---*/ +#ifdef _OPENMP +#if _OPENMP >= ATOMIC_COMPARE_SINCE +/*--- Atomic min/max are supported for arithmetic types. ---*/ +template ::value> = 0> +inline void atomicMax(const T& local, T& shared) { +#pragma omp atomic compare + shared = shared < local ? local : shared; +} + +/*--- Redefine the fallback for non arithmetic types. ---*/ +#undef ATOMIC_COMPARE_FALLBACK +#define ATOMIC_COMPARE_FALLBACK , su2enable_if::value> = 0 +#endif +#endif +template +inline void atomicMax(const T& local, T& shared) { + SU2_OMP_CRITICAL + shared = std::max(local, shared); + END_SU2_OMP_CRITICAL +} + +/*--- Atomic min, shared = min(shared, local). ---*/ +#ifdef _OPENMP +#if _OPENMP >= ATOMIC_COMPARE_SINCE +template ::value> = 0> +inline void atomicMin(const T& local, T& shared) { +#pragma omp atomic compare + shared = shared > local ? local : shared; +} +#endif +#endif +template +inline void atomicMin(const T& local, T& shared) { + SU2_OMP_CRITICAL + shared = std::min(local, shared); + END_SU2_OMP_CRITICAL +} +#undef ATOMIC_COMPARE_FALLBACK diff --git a/Common/include/parallelization/special_vectorization.hpp b/Common/include/parallelization/special_vectorization.hpp index f44c5a0cdcbe..b4435b6c9f42 100644 --- a/Common/include/parallelization/special_vectorization.hpp +++ b/Common/include/parallelization/special_vectorization.hpp @@ -153,6 +153,8 @@ MAKE_BINARY_FUN(fmin, min_p) return res; \ } +MAKE_UNARY_FUN(exp, ::exp) + #undef MAKE_UNARY_FUN /*--- Functions of two arguments, with arrays and scalars. ---*/ diff --git a/Common/include/toolboxes/graph_toolbox.hpp b/Common/include/toolboxes/graph_toolbox.hpp index f6ec27861a6f..accfa9431ae8 100644 --- a/Common/include/toolboxes/graph_toolbox.hpp +++ b/Common/include/toolboxes/graph_toolbox.hpp @@ -56,7 +56,7 @@ enum class ConnectivityType { FiniteVolume = 0, FiniteElement = 1 }; */ template class CCompressedSparsePattern { - static_assert(std::is_integral::value, ""); + static_assert(std::is_integral::value); private: su2vector m_outerPtr; /*!< \brief Start positions of the inner indices for each outer index. */ @@ -490,8 +490,8 @@ T createNaturalColoring(Index_t numInnerIndexes) { template T colorSparsePattern(const T& pattern, size_t groupSize = 1, bool includeOuterIdx = false, bool balanceColors = false, std::vector* indexColor = nullptr) { - static_assert(std::is_integral::value, ""); - static_assert(std::numeric_limits::max() >= MaxColors, ""); + static_assert(std::is_integral::value); + static_assert(std::numeric_limits::max() >= MaxColors); using Index_t = typename T::IndexType; @@ -607,7 +607,7 @@ T colorSparsePattern(const T& pattern, size_t groupSize = 1, bool includeOuterId */ template struct GridColor { - static_assert(std::is_integral::value, ""); + static_assert(std::is_integral::value); const T size; T groupSize; @@ -625,7 +625,7 @@ struct GridColor { */ template struct DummyGridColor { - static_assert(std::is_integral::value, ""); + static_assert(std::is_integral::value); T size; struct { diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index a9ecb3a94b24..79fe6d6aab1e 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -869,7 +869,7 @@ void CConfig::SetPointersNull() { Marker_Designing = nullptr; Marker_GeoEval = nullptr; Marker_Plotting = nullptr; Marker_Analyze = nullptr; Marker_PyCustom = nullptr; Marker_WallFunctions = nullptr; Marker_CfgFile_KindBC = nullptr; Marker_All_KindBC = nullptr; Marker_SobolevBC = nullptr; - Marker_StrongBC = nullptr; + Marker_StrongBC = nullptr; Marker_Create_Copy = nullptr; Kind_WallFunctions = nullptr; IntInfo_WallFunctions = nullptr; @@ -1229,10 +1229,6 @@ void CConfig::SetConfig_Options() { addStringListOption("FILENAMES_INTERPOLATOR", datadriven_ParsedOptions.n_filenames, datadriven_ParsedOptions.datadriven_filenames); /*!\brief DATADRIVEN_NEWTON_RELAXATION \n DESCRIPTION: Relaxation factor for Newton solvers in data-driven fluid model. \n \ingroup Config*/ addDoubleOption("DATADRIVEN_NEWTON_RELAXATION", datadriven_ParsedOptions.Newton_relaxation, 1.0); - /*!\brief DATADRIVEN_INITIAL_DENSITY \n DESCRIPTION: Optional initial value for fluid density used for the Newton solver processes in the data-driven fluid model. */ - addDoubleOption("DATADRIVEN_INITIAL_DENSITY", datadriven_ParsedOptions.rho_init_custom, -1.0); - /*!\brief DATADRIVEN_INITIAL_ENERGY \n DESCRIPTION: Optional initial value for fluid static energy used for the Newton solver processes in the data-driven fluid model. */ - addDoubleOption("DATADRIVEN_INITIAL_ENERGY", datadriven_ParsedOptions.e_init_custom, -1.0); /*!\biref USE_PINN \n DESCRIPTION: Use physics-informed approach for the entropy-based fluid model. \n \ingroup Config*/ addBoolOption("USE_PINN",datadriven_ParsedOptions.use_PINN, false); @@ -1529,6 +1525,9 @@ void CConfig::SetConfig_Options() { /*!\brief MARKER_MONITORING\n DESCRIPTION: Marker(s) of the surface where evaluate the non-dimensional coefficients \ingroup Config*/ addStringListOption("MARKER_MONITORING", nMarker_Monitoring, Marker_Monitoring); + /*!\brief MARKER_CREATE_COPY\n DESCRIPTION: Marker(s) for which to create copies when reading the mesh \ingroup Config*/ + addStringListOption("MARKER_CREATE_COPY", nMarker_Create_Copy, Marker_Create_Copy); + /*!\brief MARKER_CONTROL_VOLUME\n DESCRIPTION: Marker(s) of the surface in the surface flow solution file \ingroup Config*/ addStringListOption("MARKER_ANALYZE", nMarker_Analyze, Marker_Analyze); /*!\brief MARKER_DESIGNING\n DESCRIPTION: Marker(s) of the surface where objective function (design problem) will be evaluated \ingroup Config*/ @@ -1794,6 +1793,8 @@ void CConfig::SetConfig_Options() { addEnumOption("ENGINE_INFLOW_TYPE", Kind_Engine_Inflow, Engine_Inflow_Map, FAN_FACE_MACH); /* DESCRIPTION: Evaluate a problem with engines */ addBoolOption("ENGINE", Engine, false); + /* DESCRIPTION: Use exhaust mass flow as inlet mass flow. */ + addBoolOption("ENGINE_EXHAUST_TO_INLET", out2in_mdot_engine, false); /* DESCRIPTION: Sharpness coefficient for the buffet sensor */ addDoubleOption("BUFFET_K", Buffet_k, 10.0); @@ -1916,6 +1917,8 @@ void CConfig::SetConfig_Options() { addDoubleOption("RELAXATION_FACTOR_ADJOINT", Relaxation_Factor_Adjoint, 1.0); /* DESCRIPTION: Relaxation of the CHT coupling */ addDoubleOption("RELAXATION_FACTOR_CHT", Relaxation_Factor_CHT, 1.0); + /* DESCRIPTION: MSW alpha coefficient */ + addDoubleOption("MSW_ALPHA", MSW_Alpha, 5.0); /* DESCRIPTION: Roe coefficient */ addDoubleOption("ROE_KAPPA", Roe_Kappa, 0.5); /* DESCRIPTION: Roe-Turkel preconditioning for low Mach number flows */ @@ -1992,7 +1995,7 @@ void CConfig::SetConfig_Options() { * \n DESCRIPTION: Numerical method for spatial gradients used only for upwind reconstruction \n OPTIONS: See \link Gradient_Map \endlink. \n DEFAULT: NO_GRADIENT. \ingroup Config*/ addEnumOption("NUM_METHOD_GRAD_RECON", Kind_Gradient_Method_Recon, Gradient_Map, NO_GRADIENT); /*!\brief VENKAT_LIMITER_COEFF - * \n DESCRIPTION: Coefficient for the limiter. DEFAULT value 0.5. Larger values decrease the extent of limiting, values approaching zero cause lower-order approximation to the solution. \ingroup Config */ + * \n DESCRIPTION: Coefficient for the limiter. DEFAULT value 0.05. Larger values decrease the extent of limiting, values approaching zero cause lower-order approximation to the solution. \ingroup Config */ addDoubleOption("VENKAT_LIMITER_COEFF", Venkat_LimiterCoeff, 0.05); /*!\brief ADJ_SHARP_LIMITER_COEFF * \n DESCRIPTION: Coefficient for detecting the limit of the sharp edges. DEFAULT value 3.0. Use with sharp edges limiter. \ingroup Config*/ @@ -3171,6 +3174,8 @@ void CConfig::SetConfig_Parsing(istream& config_buffer){ newString.append("RAMP_ROTATION_FRAME_COEFF is deprectaed. Use RAMP_MOTION_FRAME_COEFF instead"); else if (!option_name.compare("INC_INLET_USENORMAL")) newString.append("INC_INLET_USENORMAL is deprecated. Use INLET_USE_NORMAL instead (compatible with all solvers).\n\n"); + else if (!option_name.compare("DATADRIVEN_INITIAL_ENERGY") || !option_name.compare("DATADRIVEN_INITIAL_DENSITY")) + newString.append("DATADRIVEN_INITIAL_ENERGY and DATADRIVEN_INITIAL_DENSITY are deprecated, there are no replacements.\n\n"); else { /*--- Find the most likely candidate for the unrecognized option, based on the length of start and end character sequences shared by candidates and the option. ---*/ @@ -3998,12 +4003,7 @@ void CConfig::SetPostprocessing(SU2_COMPONENT val_software, unsigned short val_i /*--- Set the number of external iterations to 1 for the steady state problem ---*/ - if (Kind_Solver == MAIN_SOLVER::FEM_ELASTICITY) { - nMGLevels = 0; - if (Kind_Struct_Solver == STRUCT_DEFORMATION::SMALL){ - MinLogResidual = log10(Linear_Solver_Error); - } - } + if (Kind_Solver == MAIN_SOLVER::FEM_ELASTICITY) nMGLevels = 0; Radiation = (Kind_Radiation != RADIATION_MODEL::NONE); diff --git a/Common/src/geometry/CGeometry.cpp b/Common/src/geometry/CGeometry.cpp index db26d86930a8..770c68f6066a 100644 --- a/Common/src/geometry/CGeometry.cpp +++ b/Common/src/geometry/CGeometry.cpp @@ -2468,6 +2468,9 @@ su2double CGeometry::GetSurfaceArea(const CConfig* config, unsigned short val_ma } void CGeometry::ComputeModifiedSymmetryNormals(const CConfig* config) { + const su2double MIN_AREA = 1e-12; // minimum area to consider a normal valid + const su2double PARALLEL_TOLERANCE = 0.001; // min. angle between symm. planes to consider them non-parallel. + /* Check how many symmetry planes there are and use the first (lowest ID) as the basis to orthogonalize against. * All nodes that are shared by multiple symmetries have to get a corrected normal. */ @@ -2558,6 +2561,8 @@ void CGeometry::ComputeModifiedSymmetryNormals(const CConfig* config) { /*--- Loop over previous symmetries and if this point shares them, make this normal orthogonal to them. * It's ok if we normalize merged normals against themselves, we get 0 area and this becomes a no-op. ---*/ + std::vector parallelMarkers; // Track markers with nearly-parallel normals + for (size_t j = 0; j < i; ++j) { const auto jMarker = symMarkers[j]; const auto jVertex = nodes->GetVertex(iPoint, jMarker); @@ -2567,14 +2572,48 @@ void CGeometry::ComputeModifiedSymmetryNormals(const CConfig* config) { GetNormal(jMarker, jVertex, jNormal); const su2double proj = GeometryToolbox::DotProduct(int(MAXNDIM), jNormal.data(), iNormal.data()); + const su2double angleDiff = std::abs(1.0 - std::abs(proj)); + + // Check if normals are nearly parallel (within ~2.5 degrees) + // cos(2.5°) ≈ 0.999, so (1 - cos(2.5°)) ≈ 0.001 + if (angleDiff < PARALLEL_TOLERANCE) { + // These normals are nearly parallel - average them instead of orthogonalizing + parallelMarkers.push_back(j); + for (auto iDim = 0ul; iDim < MAXNDIM; ++iDim) iNormal[iDim] += jNormal[iDim]; + continue; + } + for (auto iDim = 0ul; iDim < MAXNDIM; ++iDim) iNormal[iDim] -= proj * jNormal[iDim]; } + /*--- If we found parallel markers, average and store the result for all involved markers ---*/ + if (!parallelMarkers.empty()) { + // Normalize the averaged normal + const su2double avgArea = GeometryToolbox::Norm(int(MAXNDIM), iNormal.data()); + if (avgArea > MIN_AREA) { + for (auto iDim = 0ul; iDim < MAXNDIM; ++iDim) iNormal[iDim] /= avgArea; + + // Store the averaged normal for the current marker + symmetryNormals[iMarker][iVertex] = iNormal; + + // Also update all parallel markers with the same averaged normal + for (const auto j : parallelMarkers) { + const auto jMarker = symMarkers[j]; + const auto jVertex = nodes->GetVertex(iPoint, jMarker); + if (jVertex >= 0) { + symmetryNormals[jMarker][jVertex] = iNormal; + } + } + } + continue; // Skip the normal orthogonalization path below + } + /*--- Normalize. If the norm is close to zero it means the normal is a linear combination of previous * normals, in this case we don't need to store the corrected normal, using the original in the gradient * correction will have no effect since previous corrections will remove components in this direction). ---*/ const su2double area = GeometryToolbox::Norm(int(MAXNDIM), iNormal.data()); - if (area > 1e-12) { + + if (area > MIN_AREA) { for (auto iDim = 0ul; iDim < MAXNDIM; ++iDim) iNormal[iDim] /= area; symmetryNormals[iMarker][iVertex] = iNormal; } @@ -2591,16 +2630,14 @@ void CGeometry::ComputeSurfStraightness(const CConfig* config, bool print_on_scr string Local_TagBound, Global_TagBound; vector Normal(nDim), UnitNormal(nDim), RefUnitNormal(nDim); - /*--- Assume now that this boundary marker is straight. As soon as one - AreaElement is found that is not aligend with a Reference then it is - certain that the boundary marker is not straight and one can stop - searching. Another possibility is that this process doesn't own + AreaElement is found that is not aligned with a Reference then it + is certain that the boundary marker is not straight and one can + stop searching. Another possibility is that this process doesn't own any nodes of that boundary, in that case we also have to assume the - boundary is straight. - Any boundary type other than SYMMETRY_PLANE or EULER_WALL gets - the value false (or see cases specified in the conditional below) - which could be wrong. ---*/ + boundary is straight. Any boundary type other than SYMMETRY_PLANE or + EULER_WALL gets the value false (or see cases specified in the + conditional below) which could be wrong. ---*/ boundIsStraight.resize(nMarker); fill(boundIsStraight.begin(), boundIsStraight.end(), true); @@ -3902,11 +3939,13 @@ void CGeometry::ColorMGLevels(unsigned short nMGLevels, const CGeometry* const* for (auto step = 0u; step < iMesh; ++step) { auto coarseMesh = geometry[iMesh - 1 - step]; if (step) - for (auto iPoint = 0ul; iPoint < coarseMesh->GetnPoint(); ++iPoint) + for (auto iPoint = 0ul; iPoint < coarseMesh->GetnPoint(); ++iPoint) { CoarseGridColor_(iPoint, step) = CoarseGridColor_(coarseMesh->nodes->GetParent_CV(iPoint), step - 1); + } else - for (auto iPoint = 0ul; iPoint < coarseMesh->GetnPoint(); ++iPoint) + for (auto iPoint = 0ul; iPoint < coarseMesh->GetnPoint(); ++iPoint) { CoarseGridColor_(iPoint, step) = color[coarseMesh->nodes->GetParent_CV(iPoint)]; + } } } } diff --git a/Common/src/geometry/CMultiGridGeometry.cpp b/Common/src/geometry/CMultiGridGeometry.cpp index a52d111237cb..6887a4521559 100644 --- a/Common/src/geometry/CMultiGridGeometry.cpp +++ b/Common/src/geometry/CMultiGridGeometry.cpp @@ -33,14 +33,24 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, unsigned short iMesh) : CGeometry() { nDim = fine_grid->GetnDim(); // Write the number of dimensions of the coarse grid. - /*--- Create a queue system to do the agglomeration + /*--- Maximum agglomeration size in 2D is 4 nodes, in 3D is 8 nodes. ---*/ + const short int maxAgglomSize = (nDim == 2) ? 4 : 8; + + /*--- Inherit boundary properties from fine grid ---*/ + boundIsStraight = fine_grid->boundIsStraight; + + /*--- Agglomeration Scheme II (Nishikawa, Diskin, Thomas) + Create a queue system to do the agglomeration 1st) More than two markers ---> Vertices (never agglomerate) 2nd) Two markers ---> Edges (agglomerate if same BC, never agglomerate if different BC) 3rd) One marker ---> Surface (always agglomerate) 4th) No marker ---> Internal Volume (always agglomerate) ---*/ + // Note that for MPI, we introduce interfaces and we can choose to have agglomeration over + // the interface or not. Nishikawa chooses not to agglomerate over interfaces. + /*--- Set a marker to indicate indirect agglomeration, for quads and hexs, - i.e. consider up to neighbors of neighbors of neighbors. + i.e. consider up to neighbors of neighbors. For other levels this information is propagated down during their construction. ---*/ if (iMesh == MESH_1) { @@ -67,15 +77,26 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un unsigned long Index_CoarseCV = 0; - /*--- The first step is the boundary agglomeration. ---*/ + /*--- Statistics for Euler wall agglomeration ---*/ + map euler_wall_agglomerated, euler_wall_rejected_curvature, + euler_wall_rejected_straight; + for (unsigned short iMarker = 0; iMarker < fine_grid->GetnMarker(); iMarker++) { + if (config->GetMarker_All_KindBC(iMarker) == EULER_WALL) { + euler_wall_agglomerated[iMarker] = 0; + euler_wall_rejected_curvature[iMarker] = 0; + euler_wall_rejected_straight[iMarker] = 0; + } + } + /*--- STEP 1: The first step is the boundary agglomeration. ---*/ for (auto iMarker = 0u; iMarker < fine_grid->GetnMarker(); iMarker++) { for (auto iVertex = 0ul; iVertex < fine_grid->GetnVertex(iMarker); iVertex++) { const auto iPoint = fine_grid->vertex[iMarker][iVertex]->GetNode(); /*--- If the element has not been previously agglomerated and it - belongs to this physical domain, and it meets the geometrical - criteria, the agglomeration is studied. ---*/ + belongs to this physical domain, and it meets the geometrical + criteria, the agglomeration is studied. ---*/ + vector marker_seed; if ((!fine_grid->nodes->GetAgglomerate(iPoint)) && (fine_grid->nodes->GetDomain(iPoint)) && (GeometricalCheck(iPoint, fine_grid, config))) { @@ -89,42 +110,94 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un /*--- We add the seed point (child) to the parent control volume ---*/ nodes->SetChildren_CV(Index_CoarseCV, 0, iPoint); - bool agglomerate_seed = true; + bool agglomerate_seed = false; auto counter = 0; unsigned short copy_marker[3] = {}; - const auto marker_seed = iMarker; + marker_seed.push_back(iMarker); /*--- For a particular point in the fine grid we save all the markers that are in that point ---*/ - for (auto jMarker = 0u; jMarker < fine_grid->GetnMarker() && counter < 3; jMarker++) { + for (auto jMarker = 0u; jMarker < fine_grid->GetnMarker(); jMarker++) { + const string Marker_Tag = config->GetMarker_All_TagBound(iMarker); if (fine_grid->nodes->GetVertex(iPoint, jMarker) != -1) { copy_marker[counter] = jMarker; counter++; + + if (jMarker != iMarker) { + marker_seed.push_back(jMarker); + } } } - /*--- To aglomerate a vertex it must have only one physical bc!! - This can be improved. If there is only a marker, it is a good + /*--- To agglomerate a vertex it must have only one physical bc. + This can be improved. If there is only one marker, it is a good candidate for agglomeration ---*/ + /*--- 1 BC, so either an edge in 2D or the interior of a plane in 3D ---*/ + /*--- Valley -> Valley : conditionally allowed when both points are on the same marker. ---*/ + /*--- ! Note that in the case of MPI SEND_RECEIVE markers, we might need other conditions ---*/ if (counter == 1) { + // The seed/parent is one valley, so we set this part to true + // if the child is on the same valley, we set it to true as well. agglomerate_seed = true; - /*--- Euler walls can be curved and agglomerating them leads to difficulties ---*/ - if (config->GetMarker_All_KindBC(marker_seed) == EULER_WALL) agglomerate_seed = false; + /*--- Euler walls: check curvature-based agglomeration criterion ---*/ + if (config->GetMarker_All_KindBC(marker_seed[0]) == EULER_WALL) { + /*--- Allow agglomeration if marker is straight OR local curvature is small ---*/ + if (!boundIsStraight[marker_seed[0]]) { + /*--- Compute local curvature at this point ---*/ + su2double local_curvature = ComputeLocalCurvature(fine_grid, iPoint, marker_seed[0]); + // limit to 45 degrees + if (local_curvature >= 45.0) { + agglomerate_seed = false; // High curvature: do not agglomerate + euler_wall_rejected_curvature[marker_seed[0]]++; + } else { + euler_wall_agglomerated[marker_seed[0]]++; + } + } else { + /*--- Straight wall: agglomerate ---*/ + euler_wall_agglomerated[marker_seed[0]]++; + } + } + + /*--- Note that if the (single) marker is a SEND_RECEIVE, then the node is actually an interior point. + In that case it can only be agglomerated with another interior point. ---*/ + if (config->GetMarker_All_KindBC(marker_seed[0]) == SEND_RECEIVE) { + agglomerate_seed = true; + } } - /*--- If there are two markers, we will agglomerate if any of the - markers is SEND_RECEIVE ---*/ + /*--- Note that in 2D, this is a corner and we do not agglomerate unless one of them is SEND_RECEIVE. ---*/ + /*--- In 3D, we agglomerate if the 2 markers are the same. ---*/ if (counter == 2) { - agglomerate_seed = (config->GetMarker_All_KindBC(copy_marker[0]) == SEND_RECEIVE) || - (config->GetMarker_All_KindBC(copy_marker[1]) == SEND_RECEIVE); - - /* --- Euler walls can also not be agglomerated when the point has 2 markers ---*/ - if ((config->GetMarker_All_KindBC(copy_marker[0]) == EULER_WALL) || - (config->GetMarker_All_KindBC(copy_marker[1]) == EULER_WALL)) { - agglomerate_seed = false; + if (nDim == 2) { + agglomerate_seed = ((config->GetMarker_All_KindBC(copy_marker[0]) == SEND_RECEIVE) || + (config->GetMarker_All_KindBC(copy_marker[1]) == SEND_RECEIVE)); + } + /*--- agglomerate if both markers are the same. ---*/ + if (nDim == 3) agglomerate_seed = (copy_marker[0] == copy_marker[1]); + + /*--- Euler walls: check curvature-based agglomeration criterion for both markers ---*/ + // only in 3d because in 2d it's a corner + bool euler_wall_rejected_here = false; + for (unsigned short i = 0; i < 2; i++) { + if ((nDim == 3) && (config->GetMarker_All_KindBC(copy_marker[i]) == EULER_WALL)) { + if (!boundIsStraight[copy_marker[i]]) { + /*--- Compute local curvature at this point ---*/ + su2double local_curvature = ComputeLocalCurvature(fine_grid, iPoint, copy_marker[i]); + // limit to 45 degrees + if (local_curvature >= 45.0) { + agglomerate_seed = false; // High curvature: do not agglomerate + euler_wall_rejected_curvature[copy_marker[i]]++; + euler_wall_rejected_here = true; + } + } + /*--- Track agglomeration if not rejected ---*/ + if (agglomerate_seed && !euler_wall_rejected_here) { + euler_wall_agglomerated[copy_marker[i]]++; + } + } } } @@ -132,7 +205,8 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un if (counter > 2) agglomerate_seed = false; - /*--- If the seed can be agglomerated, we try to agglomerate more points ---*/ + /*--- If the seed (parent) can be agglomerated, we try to agglomerate connected childs to the parent ---*/ + /*--- Note that in 2D we allow a maximum of 4 nodes to be agglomerated ---*/ if (agglomerate_seed) { /*--- Now we do a sweep over all the nodes that surround the seed point ---*/ @@ -149,34 +223,45 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un nodes->SetChildren_CV(Index_CoarseCV, nChildren, CVPoint); nChildren++; + /*--- In 2D, we agglomerate exactly 2 nodes if the nodes are on the line edge. ---*/ + if ((nDim == 2) && (counter == 1)) break; + /*--- In 3D, we agglomerate exactly 2 nodes if the nodes are on the surface edge. ---*/ + if ((nDim == 3) && (counter == 2)) break; + /*--- Apply maxAgglomSize limit for 3D internal boundary face nodes (counter==1 in 3D). ---*/ + if (nChildren == maxAgglomSize) break; } } - Suitable_Indirect_Neighbors.clear(); + /*--- Only take into account indirect neighbors for 3D faces, not 2D. ---*/ + if (nDim == 3) { + Suitable_Indirect_Neighbors.clear(); - if (fine_grid->nodes->GetAgglomerate_Indirect(iPoint)) - SetSuitableNeighbors(Suitable_Indirect_Neighbors, iPoint, Index_CoarseCV, fine_grid); + if (fine_grid->nodes->GetAgglomerate_Indirect(iPoint)) + SetSuitableNeighbors(Suitable_Indirect_Neighbors, iPoint, Index_CoarseCV, fine_grid); - /*--- Now we do a sweep over all the indirect nodes that can be added ---*/ + /*--- Now we do a sweep over all the indirect nodes that can be added ---*/ - for (auto CVPoint : Suitable_Indirect_Neighbors) { - /*--- The new point can be agglomerated ---*/ + for (auto CVPoint : Suitable_Indirect_Neighbors) { + /*--- The new point can be agglomerated ---*/ - if (SetBoundAgglomeration(CVPoint, marker_seed, fine_grid, config)) { - /*--- We set the value of the parent ---*/ + if (SetBoundAgglomeration(CVPoint, marker_seed, fine_grid, config)) { + /*--- We set the value of the parent ---*/ - fine_grid->nodes->SetParent_CV(CVPoint, Index_CoarseCV); + fine_grid->nodes->SetParent_CV(CVPoint, Index_CoarseCV); - /*--- We set the indirect agglomeration information of the corse point - based on its children in the fine grid. ---*/ + /*--- We set the indirect agglomeration information of the corse point + based on its children in the fine grid. ---*/ - if (fine_grid->nodes->GetAgglomerate_Indirect(CVPoint)) - nodes->SetAgglomerate_Indirect(Index_CoarseCV, true); + if (fine_grid->nodes->GetAgglomerate_Indirect(CVPoint)) + nodes->SetAgglomerate_Indirect(Index_CoarseCV, true); - /*--- We set the value of the child ---*/ + /*--- We set the value of the child ---*/ - nodes->SetChildren_CV(Index_CoarseCV, nChildren, CVPoint); - nChildren++; + nodes->SetChildren_CV(Index_CoarseCV, nChildren, CVPoint); + nChildren++; + /*--- Apply maxAgglomSize limit for 3D internal boundary face nodes. ---*/ + if (nChildren == maxAgglomSize) break; + } } } } @@ -223,7 +308,7 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un } } - /*--- Agglomerate the domain points. ---*/ + /*--- STEP 2: Agglomerate the domain points. ---*/ auto iteration = 0ul; while (!MGQueue_InnerCV.EmptyQueue() && (iteration < fine_grid->GetnPoint())) { @@ -271,6 +356,7 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un MGQueue_InnerCV.Update(CVPoint, fine_grid); } + if (nChildren == maxAgglomSize) break; } /*--- Identify the indirect neighbors ---*/ @@ -282,6 +368,8 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un /*--- Now we do a sweep over all the indirect nodes that can be added ---*/ for (auto CVPoint : Suitable_Indirect_Neighbors) { + // if we have reached the maximum, get out. + if (nChildren == maxAgglomSize) break; /*--- The new point can be agglomerated ---*/ if ((!fine_grid->nodes->GetAgglomerate(CVPoint)) && (fine_grid->nodes->GetDomain(CVPoint))) { @@ -343,13 +431,54 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un const auto iCoarsePoint_Complete = nodes->GetPoint(iCoarsePoint, 0); - /*--- Add the children to the connected control volume (and modify its parent indexing). - Identify the child CV from the finest grid and add it to the correct control volume. - Set the parent CV of iFinePoint. Instead of using the original one - (iCoarsePoint), use the new one (iCoarsePoint_Complete) ---*/ + /*--- Check if merging would exceed the maximum agglomeration size ---*/ + auto nChildren_Target = nodes->GetnChildren_CV(iCoarsePoint_Complete); + auto nChildren_Isolated = nodes->GetnChildren_CV(iCoarsePoint); + auto nChildren_Total = nChildren_Target + nChildren_Isolated; + + /*--- If the total would exceed maxAgglomSize, try to redistribute children to neighbors ---*/ + if (nChildren_Total > maxAgglomSize) { + /*--- Find neighbors of the target coarse point that have room ---*/ + unsigned short nChildrenToRedistribute = nChildren_Total - maxAgglomSize; + + for (auto jCoarsePoint : nodes->GetPoints(iCoarsePoint_Complete)) { + if (nChildrenToRedistribute == 0) break; + + auto nChildren_Neighbor = nodes->GetnChildren_CV(jCoarsePoint); + if (nChildren_Neighbor < maxAgglomSize) { + unsigned short nCanTransfer = + min(nChildrenToRedistribute, static_cast(maxAgglomSize - nChildren_Neighbor)); - auto nChildren = nodes->GetnChildren_CV(iCoarsePoint_Complete); + /*--- Transfer children from target to neighbor ---*/ + for (unsigned short iTransfer = 0; iTransfer < nCanTransfer; iTransfer++) { + /*--- Take from the end of the target's children list ---*/ + auto nChildren_Current = nodes->GetnChildren_CV(iCoarsePoint_Complete); + if (nChildren_Current > 0) { + auto iFinePoint = nodes->GetChildren_CV(iCoarsePoint_Complete, nChildren_Current - 1); + /*--- Add to neighbor ---*/ + auto nChildren_Neighbor_Current = nodes->GetnChildren_CV(jCoarsePoint); + nodes->SetChildren_CV(jCoarsePoint, nChildren_Neighbor_Current, iFinePoint); + nodes->SetnChildren_CV(jCoarsePoint, nChildren_Neighbor_Current + 1); + + /*--- Update parent ---*/ + fine_grid->nodes->SetParent_CV(iFinePoint, jCoarsePoint); + + /*--- Remove from target (by reducing count) ---*/ + nodes->SetnChildren_CV(iCoarsePoint_Complete, nChildren_Current - 1); + + nChildrenToRedistribute--; + } + } + } + } + + /*--- Update the target's child count after redistribution ---*/ + nChildren_Target = nodes->GetnChildren_CV(iCoarsePoint_Complete); + } + + /*--- Add the isolated point's children to the target control volume ---*/ + auto nChildren = nChildren_Target; for (auto iChildren = 0u; iChildren < nodes->GetnChildren_CV(iCoarsePoint); iChildren++) { const auto iFinePoint = nodes->GetChildren_CV(iCoarsePoint, iChildren); nodes->SetChildren_CV(iCoarsePoint_Complete, nChildren, iFinePoint); @@ -369,6 +498,16 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un nodes->ResetPoints(); #ifdef HAVE_MPI + /*--- Reset halo point parents before MPI agglomeration. + When creating level N from level N-1, the fine grid (level N-1) + already has Parent_CV set from when it was created from level N-2. + Those parent indices point to level N, but when creating level N+1, they would be + incorrectly interpreted as level N+1 indices. ---*/ + + for (auto iPoint = fine_grid->GetnPointDomain(); iPoint < fine_grid->GetnPoint(); iPoint++) { + fine_grid->nodes->SetParent_CV(iPoint, std::numeric_limits::max()); + } + /*--- Dealing with MPI parallelization, the objective is that the received nodes must be agglomerated in the same way as the donor (send) nodes. Send the node agglomeration information of the donor (parent and children). The agglomerated halos of this rank are set according to the rank where @@ -376,8 +515,8 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un for (auto iMarker = 0u; iMarker < config->GetnMarker_All(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) == SEND_RECEIVE) && (config->GetMarker_All_SendRecv(iMarker) > 0)) { - const auto MarkerS = iMarker; - const auto MarkerR = iMarker + 1; + const auto MarkerS = iMarker; // sending marker + const auto MarkerR = iMarker + 1; // receiving marker const auto send_to = config->GetMarker_All_SendRecv(MarkerS) - 1; const auto receive_from = abs(config->GetMarker_All_SendRecv(MarkerR)) - 1; @@ -424,38 +563,78 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un vector Parent_Local(nVertexR); vector Children_Local(nVertexR); + /*--- First pass: Determine which parents will actually be used (have non-skipped children). + This prevents creating orphaned halo CVs that have coordinates (0,0,0). ---*/ + vector parent_used(Aux_Parent.size(), false); + vector parent_local_index(Aux_Parent.size(), std::numeric_limits::max()); + for (auto iVertex = 0ul; iVertex < nVertexR; iVertex++) { - /*--- We use the same sorting as in the donor domain, i.e. the local parents - are numbered according to their order in the remote rank. ---*/ + const auto iPoint_Fine = fine_grid->vertex[MarkerR][iVertex]->GetNode(); + auto existing_parent = fine_grid->nodes->GetParent_CV(iPoint_Fine); + + /*--- Skip if already agglomerated (first-wins policy) ---*/ + if (existing_parent != std::numeric_limits::max()) continue; + + /*--- Skip if received parent is invalid (sending rank didn't agglomerate this point) ---*/ + if (Parent_Remote[iVertex] == std::numeric_limits::max()) continue; + /*--- Find which parent this vertex maps to ---*/ for (auto jVertex = 0ul; jVertex < Aux_Parent.size(); jVertex++) { if (Parent_Remote[iVertex] == Aux_Parent[jVertex]) { - Parent_Local[iVertex] = jVertex + Index_CoarseCV; + parent_used[jVertex] = true; break; } } - Children_Local[iVertex] = fine_grid->vertex[MarkerR][iVertex]->GetNode(); } - Index_CoarseCV += Aux_Parent.size(); + /*--- Assign local indices only to used parents ---*/ + unsigned long nUsedParents = 0; + for (auto jVertex = 0ul; jVertex < Aux_Parent.size(); jVertex++) { + if (parent_used[jVertex]) { + parent_local_index[jVertex] = Index_CoarseCV + nUsedParents; + nUsedParents++; + } + } + + /*--- Now map each received vertex to its local parent ---*/ + for (auto iVertex = 0ul; iVertex < nVertexR; iVertex++) { + Parent_Local[iVertex] = std::numeric_limits::max(); + for (auto jVertex = 0ul; jVertex < Aux_Parent.size(); jVertex++) { + if (Parent_Remote[iVertex] == Aux_Parent[jVertex]) { + Parent_Local[iVertex] = parent_local_index[jVertex]; + break; + } + } + + Children_Local[iVertex] = fine_grid->vertex[MarkerR][iVertex]->GetNode(); + } - vector nChildren_MPI(Index_CoarseCV, 0); + /*--- Only increment by the number of parents that will actually be used ---*/ + Index_CoarseCV += nUsedParents; /*--- Create the final structure ---*/ for (auto iVertex = 0ul; iVertex < nVertexR; iVertex++) { - const auto iPoint_Coarse = Parent_Local[iVertex]; const auto iPoint_Fine = Children_Local[iVertex]; - /*--- Be careful, it is possible that a node changes the agglomeration configuration, - the priority is always when receiving the information. ---*/ + /*--- Skip if this halo point was already agglomerated (first-wins policy) ---*/ + auto existing_parent = fine_grid->nodes->GetParent_CV(iPoint_Fine); + if (existing_parent != std::numeric_limits::max()) continue; + + /*--- Skip if parent mapping is invalid (sender didn't agglomerate) ---*/ + const auto iPoint_Coarse = Parent_Local[iVertex]; + if (iPoint_Coarse == std::numeric_limits::max()) continue; + + /*--- Append to existing children, don't overwrite ---*/ + auto existing_children_count = nodes->GetnChildren_CV(iPoint_Coarse); + fine_grid->nodes->SetParent_CV(iPoint_Fine, iPoint_Coarse); - nodes->SetChildren_CV(iPoint_Coarse, nChildren_MPI[iPoint_Coarse], iPoint_Fine); - nChildren_MPI[iPoint_Coarse]++; - nodes->SetnChildren_CV(iPoint_Coarse, nChildren_MPI[iPoint_Coarse]); + nodes->SetChildren_CV(iPoint_Coarse, existing_children_count, iPoint_Fine); + nodes->SetnChildren_CV(iPoint_Coarse, existing_children_count + 1); nodes->SetDomain(iPoint_Coarse, false); } } } + #endif // HAVE_MPI /*--- Update the number of points after the MPI agglomeration ---*/ @@ -463,25 +642,27 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un nPoint = Index_CoarseCV; /*--- Console output with the summary of the agglomeration ---*/ - - unsigned long nPointFine = fine_grid->GetnPoint(); + unsigned long nPointFine = fine_grid->GetnPointDomain(); unsigned long Global_nPointCoarse, Global_nPointFine; - SU2_MPI::Allreduce(&nPoint, &Global_nPointCoarse, 1, MPI_UNSIGNED_LONG, MPI_SUM, SU2_MPI::GetComm()); + SU2_MPI::Allreduce(&nPointDomain, &Global_nPointCoarse, 1, MPI_UNSIGNED_LONG, MPI_SUM, SU2_MPI::GetComm()); SU2_MPI::Allreduce(&nPointFine, &Global_nPointFine, 1, MPI_UNSIGNED_LONG, MPI_SUM, SU2_MPI::GetComm()); SetGlobal_nPointDomain(Global_nPointCoarse); if (iMesh != MESH_0) { - const su2double factor = 1.5; - const su2double Coeff = pow(su2double(Global_nPointFine) / Global_nPointCoarse, 1.0 / nDim); - const su2double CFL = factor * config->GetCFL(iMesh - 1) / Coeff; + /*--- Note: CFL at the coarse levels have a large impact on convergence, + this should be rewritten to use adaptive CFL. ---*/ + const su2double Coeff = 1.5; + const su2double CFL = config->GetCFL(iMesh - 1) / Coeff; config->SetCFL(iMesh, CFL); } const su2double ratio = su2double(Global_nPointFine) / su2double(Global_nPointCoarse); + cout << "********** ratio = " << ratio << endl; + // lower value leads to more levels being accepted. - if (((nDim == 2) && (ratio < 2.5)) || ((nDim == 3) && (ratio < 2.5))) { + if (((nDim == 2) && (ratio < 1.5)) || ((nDim == 3) && (ratio < 1.5))) { config->SetMGLevels(iMesh - 1); } else if (rank == MASTER_NODE) { PrintingToolbox::CTablePrinter MGTable(&std::cout); @@ -503,11 +684,65 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un } } + /*--- Output Euler wall agglomeration statistics ---*/ + if (rank == MASTER_NODE) { + /*--- Gather global statistics for Euler walls ---*/ + bool has_euler_walls = false; + for (unsigned short iMarker = 0; iMarker < fine_grid->GetnMarker(); iMarker++) { + if (config->GetMarker_All_KindBC(iMarker) == EULER_WALL) { + has_euler_walls = true; + break; + } + } + + if (has_euler_walls) { + cout << endl; + cout << "Euler Wall Agglomeration Statistics (45° curvature threshold):" << endl; + cout << "----------------------------------------------------------------" << endl; + + for (unsigned short iMarker = 0; iMarker < fine_grid->GetnMarker(); iMarker++) { + if (config->GetMarker_All_KindBC(iMarker) == EULER_WALL) { + string marker_name = config->GetMarker_All_TagBound(iMarker); + unsigned long agglomerated = euler_wall_agglomerated[iMarker]; + unsigned long rejected = euler_wall_rejected_curvature[iMarker]; + unsigned long total = agglomerated + rejected; + + if (total > 0) { + su2double accept_rate = 100.0 * su2double(agglomerated) / su2double(total); + cout << " Marker: " << marker_name << endl; + cout << " Seeds agglomerated: " << agglomerated << " (" << std::setprecision(1) << std::fixed + << accept_rate << "%)" << endl; + cout << " Seeds rejected (>45° curv): " << rejected << " (" << std::setprecision(1) << std::fixed + << (100.0 - accept_rate) << "%)" << endl; + } + } + } + cout << "----------------------------------------------------------------" << endl; + } + } + edgeColorGroupSize = config->GetEdgeColoringGroupSize(); } -bool CMultiGridGeometry::SetBoundAgglomeration(unsigned long CVPoint, short marker_seed, const CGeometry* fine_grid, - const CConfig* config) const { +bool CMultiGridGeometry::GeometricalCheck(unsigned long iPoint, const CGeometry* fine_grid, + const CConfig* config) const { + su2double max_dimension = 1.2; + + /*--- Evaluate the total size of the element ---*/ + + bool Volume = true; + su2double ratio = pow(fine_grid->nodes->GetVolume(iPoint), 1.0 / su2double(nDim)) * max_dimension; + su2double limit = pow(config->GetDomainVolume(), 1.0 / su2double(nDim)); + if (ratio > limit) { + Volume = false; + cout << "Volume limit reached!" << endl; + } + + return (Volume); +} + +bool CMultiGridGeometry::SetBoundAgglomeration(unsigned long CVPoint, vector marker_seed, + const CGeometry* fine_grid, const CConfig* config) const { bool agglomerate_CV = false; /*--- Basic condition, the point has not been previously agglomerated, it belongs to the domain, @@ -517,12 +752,13 @@ bool CMultiGridGeometry::SetBoundAgglomeration(unsigned long CVPoint, short mark (GeometricalCheck(CVPoint, fine_grid, config))) { /*--- If the point belongs to a boundary, its type must be compatible with the seed marker. ---*/ + int counter = 0; + unsigned short copy_marker[3] = {}; + if (fine_grid->nodes->GetBoundary(CVPoint)) { /*--- Identify the markers of the vertex that we want to agglomerate ---*/ // count number of markers on the agglomeration candidate - int counter = 0; - unsigned short copy_marker[3] = {}; for (auto jMarker = 0u; jMarker < fine_grid->GetnMarker() && counter < 3; jMarker++) { if (fine_grid->nodes->GetVertex(CVPoint, jMarker) != -1) { copy_marker[counter] = jMarker; @@ -530,94 +766,54 @@ bool CMultiGridGeometry::SetBoundAgglomeration(unsigned long CVPoint, short mark } } - /*--- The basic condition is that the aglomerated vertex must have the same physical marker, + /*--- The basic condition is that the agglomerated vertex must have the same physical marker, but eventually a send-receive condition ---*/ - /*--- Only one marker in the vertex that is going to be aglomerated ---*/ + /*--- Only one marker in the vertex that is going to be agglomerated ---*/ + /*--- Valley -> Valley: only if of the same type---*/ if (counter == 1) { /*--- We agglomerate if there is only one marker and it is the same marker as the seed marker ---*/ - // note that this should be the same marker id, not just the same marker type - if (copy_marker[0] == marker_seed) agglomerate_CV = true; - - /*--- If there is only one marker, but the marker is the SEND_RECEIVE ---*/ - - if (config->GetMarker_All_KindBC(copy_marker[0]) == SEND_RECEIVE) { - agglomerate_CV = true; - } - - if ((config->GetMarker_All_KindBC(marker_seed) == SYMMETRY_PLANE) || - (config->GetMarker_All_KindBC(marker_seed) == EULER_WALL)) { - if (config->GetMarker_All_KindBC(copy_marker[0]) == SEND_RECEIVE) { - agglomerate_CV = false; + // So this is the case when in 2D we are on an edge, and in 3D we are in the interior of a surface. + // note that this should be the same marker id, not just the same marker type. + if ((marker_seed.size() == 1) && (copy_marker[0] == marker_seed[0])) agglomerate_CV = true; + + // we also allow agglomeration if the seed has 2 markers, one of them is the same as the candidate, and the + // other is a send-receive marker. + if ((marker_seed.size() == 2) && ((copy_marker[0] == marker_seed[0]) || (copy_marker[0] == marker_seed[1]))) { + // check that the other marker is a send-receive marker + unsigned short other_marker = (copy_marker[0] == marker_seed[0]) ? marker_seed[1] : marker_seed[0]; + if (config->GetMarker_All_KindBC(other_marker) == SEND_RECEIVE) { + agglomerate_CV = true; } } } /*--- If there are two markers in the vertex that is going to be aglomerated ---*/ - if (counter == 2) { - /*--- First we verify that the seed is a physical boundary ---*/ - - if (config->GetMarker_All_KindBC(marker_seed) != SEND_RECEIVE) { - /*--- Then we check that one of the markers is equal to the seed marker, and the other is send/receive ---*/ - - if (((copy_marker[0] == marker_seed) && (config->GetMarker_All_KindBC(copy_marker[1]) == SEND_RECEIVE)) || - ((config->GetMarker_All_KindBC(copy_marker[0]) == SEND_RECEIVE) && (copy_marker[1] == marker_seed))) { + /*--- In 2D this is a corner and we do not agglomerate ---*/ + if (nDim == 2) { + agglomerate_CV = false; + } + /*--- Both markers have to be the same. ---*/ + if (marker_seed.size() == 2) { + if (((copy_marker[0] == marker_seed[0]) && (copy_marker[1] == marker_seed[1])) || + ((copy_marker[0] == marker_seed[1]) && (copy_marker[1] == marker_seed[0]))) { agglomerate_CV = true; } } } } - /*--- If the element belongs to the domain, it is always agglomerated. ---*/ + /*--- If the element belongs to the domain, it is never agglomerated with a boundary node. ---*/ else { - agglomerate_CV = true; - - // actually, for symmetry (and possibly other cells) we only agglomerate cells that are on the marker - // at this point, the seed was on the boundary and the CV was not. so we check if the seed is a symmetry - if ((config->GetMarker_All_KindBC(marker_seed) == SYMMETRY_PLANE) || - (config->GetMarker_All_KindBC(marker_seed) == EULER_WALL)) { - agglomerate_CV = false; - } + agglomerate_CV = false; } } return agglomerate_CV; } -bool CMultiGridGeometry::GeometricalCheck(unsigned long iPoint, const CGeometry* fine_grid, - const CConfig* config) const { - su2double max_dimension = 1.2; - - /*--- Evaluate the total size of the element ---*/ - - bool Volume = true; - su2double ratio = pow(fine_grid->nodes->GetVolume(iPoint), 1.0 / su2double(nDim)) * max_dimension; - su2double limit = pow(config->GetDomainVolume(), 1.0 / su2double(nDim)); - if (ratio > limit) Volume = false; - - /*--- Evaluate the stretching of the element ---*/ - - bool Stretching = true; - - /* unsigned short iNode, iDim; - unsigned long jPoint; - su2double *Coord_i = fine_grid->nodes->GetCoord(iPoint); - su2double max_dist = 0.0 ; su2double min_dist = 1E20; - for (iNode = 0; iNode < fine_grid->nodes->GetnPoint(iPoint); iNode ++) { - jPoint = fine_grid->nodes->GetPoint(iPoint, iNode); - su2double *Coord_j = fine_grid->nodes->GetCoord(jPoint); - su2double distance = 0.0; - for (iDim = 0; iDim < nDim; iDim++) - distance += (Coord_j[iDim]-Coord_i[iDim])*(Coord_j[iDim]-Coord_i[iDim]); - distance = sqrt(distance); - max_dist = max(distance, max_dist); - min_dist = min(distance, min_dist); - } - if ( max_dist/min_dist > 100.0 ) Stretching = false;*/ - - return (Stretching && Volume); -} +/*--- ---*/ void CMultiGridGeometry::SetSuitableNeighbors(vector& Suitable_Indirect_Neighbors, unsigned long iPoint, unsigned long Index_CoarseCV, const CGeometry* fine_grid) const { @@ -637,8 +833,8 @@ void CMultiGridGeometry::SetSuitableNeighbors(vector& Suitable_In auto end = First_Neighbor_Points.end(); if (find(First_Neighbor_Points.begin(), end, kPoint) == end) { - Second_Neighbor_Points.push_back(kPoint); - Second_Origin_Points.push_back(jPoint); + Second_Neighbor_Points.push_back(kPoint); // neighbor of a neighbor, not connected to original ipoint + Second_Origin_Points.push_back(jPoint); // the neighbor that is connected to ipoint } } } @@ -668,53 +864,11 @@ void CMultiGridGeometry::SetSuitableNeighbors(vector& Suitable_In sort(Suitable_Second_Neighbors.begin(), Suitable_Second_Neighbors.end()); auto it1 = unique(Suitable_Second_Neighbors.begin(), Suitable_Second_Neighbors.end()); Suitable_Second_Neighbors.resize(it1 - Suitable_Second_Neighbors.begin()); - - /*--- Create a list with the third neighbors, without first, second, and seed neighbors. ---*/ - - /// TODO: This repeats the process above but I doubt it catches any more points. - - vector Third_Neighbor_Points, Third_Origin_Points; - - for (auto kPoint : Suitable_Second_Neighbors) { - for (auto lPoint : fine_grid->nodes->GetPoints(kPoint)) { - /*--- Check that the third neighbor does not belong to the first neighbors or the seed ---*/ - - auto end1 = First_Neighbor_Points.end(); - if (find(First_Neighbor_Points.begin(), end1, lPoint) != end1) continue; - - /*--- Check that the third neighbor does not belong to the second neighbors ---*/ - - auto end2 = Suitable_Second_Neighbors.end(); - if (find(Suitable_Second_Neighbors.begin(), end2, lPoint) != end2) continue; - - Third_Neighbor_Points.push_back(lPoint); - Third_Origin_Points.push_back(kPoint); - } - } - - /*--- Identify those third neighbors that are repeated (candidate to be added). ---*/ - - for (auto iNeighbor = 0ul; iNeighbor < Third_Neighbor_Points.size(); iNeighbor++) { - for (auto jNeighbor = iNeighbor + 1; jNeighbor < Third_Neighbor_Points.size(); jNeighbor++) { - /*--- Repeated third neighbor with different origin ---*/ - - if ((Third_Neighbor_Points[iNeighbor] == Third_Neighbor_Points[jNeighbor]) && - (Third_Origin_Points[iNeighbor] != Third_Origin_Points[jNeighbor])) { - Suitable_Indirect_Neighbors.push_back(Third_Neighbor_Points[iNeighbor]); - } - } - } - - /*--- Remove duplicates from the final list of Suitable Indirect Neighbors. ---*/ - - sort(Suitable_Indirect_Neighbors.begin(), Suitable_Indirect_Neighbors.end()); - auto it2 = unique(Suitable_Indirect_Neighbors.begin(), Suitable_Indirect_Neighbors.end()); - Suitable_Indirect_Neighbors.resize(it2 - Suitable_Indirect_Neighbors.begin()); } void CMultiGridGeometry::SetPoint_Connectivity(const CGeometry* fine_grid) { /*--- Temporary, CPoint (nodes) then compresses this structure. ---*/ - vector > points(nPoint); + vector> points(nPoint); for (auto iCoarsePoint = 0ul; iCoarsePoint < nPoint; iCoarsePoint++) { /*--- For each child CV (of the fine grid), ---*/ @@ -741,17 +895,14 @@ void CMultiGridGeometry::SetPoint_Connectivity(const CGeometry* fine_grid) { } void CMultiGridGeometry::SetVertex(const CGeometry* fine_grid, const CConfig* config) { - unsigned long iVertex, iFinePoint, iCoarsePoint; - unsigned short iMarker, iMarker_Tag, iChildren; - nMarker = fine_grid->GetnMarker(); unsigned short nMarker_Max = config->GetnMarker_Max(); /*--- If any children node belong to the boundary then the entire control volume will belong to the boundary ---*/ - for (iCoarsePoint = 0; iCoarsePoint < nPoint; iCoarsePoint++) - for (iChildren = 0; iChildren < nodes->GetnChildren_CV(iCoarsePoint); iChildren++) { - iFinePoint = nodes->GetChildren_CV(iCoarsePoint, iChildren); + for (auto iCoarsePoint = 0ul; iCoarsePoint < nPoint; iCoarsePoint++) + for (auto iChildren = 0u; iChildren < nodes->GetnChildren_CV(iCoarsePoint); iChildren++) { + auto iFinePoint = nodes->GetChildren_CV(iCoarsePoint, iChildren); if (fine_grid->nodes->GetBoundary(iFinePoint)) { nodes->SetBoundary(iCoarsePoint, nMarker); break; @@ -762,20 +913,20 @@ void CMultiGridGeometry::SetVertex(const CGeometry* fine_grid, const CConfig* co nVertex = new unsigned long[nMarker]; Tag_to_Marker = new string[nMarker_Max]; - for (iMarker_Tag = 0; iMarker_Tag < nMarker_Max; iMarker_Tag++) + for (auto iMarker_Tag = 0u; iMarker_Tag < nMarker_Max; iMarker_Tag++) Tag_to_Marker[iMarker_Tag] = fine_grid->GetMarker_Tag(iMarker_Tag); /*--- Compute the number of vertices to do the dimensionalization ---*/ - for (iMarker = 0; iMarker < nMarker; iMarker++) nVertex[iMarker] = 0; + for (auto iMarker = 0u; iMarker < nMarker; iMarker++) nVertex[iMarker] = 0; - for (iCoarsePoint = 0; iCoarsePoint < nPoint; iCoarsePoint++) { + for (auto iCoarsePoint = 0ul; iCoarsePoint < nPoint; iCoarsePoint++) { if (nodes->GetBoundary(iCoarsePoint)) { - for (iChildren = 0; iChildren < nodes->GetnChildren_CV(iCoarsePoint); iChildren++) { - iFinePoint = nodes->GetChildren_CV(iCoarsePoint, iChildren); - for (iMarker = 0; iMarker < nMarker; iMarker++) { + for (auto iChildren = 0u; iChildren < nodes->GetnChildren_CV(iCoarsePoint); iChildren++) { + auto iFinePoint = nodes->GetChildren_CV(iCoarsePoint, iChildren); + for (auto iMarker = 0u; iMarker < nMarker; iMarker++) { if ((fine_grid->nodes->GetVertex(iFinePoint, iMarker) != -1) && (nodes->GetVertex(iCoarsePoint, iMarker) == -1)) { - iVertex = nVertex[iMarker]; + auto iVertex = nVertex[iMarker]; nodes->SetVertex(iCoarsePoint, iVertex, iMarker); nVertex[iMarker]++; } @@ -784,25 +935,25 @@ void CMultiGridGeometry::SetVertex(const CGeometry* fine_grid, const CConfig* co } } - for (iMarker = 0; iMarker < nMarker; iMarker++) { + for (auto iMarker = 0u; iMarker < nMarker; iMarker++) { vertex[iMarker] = new CVertex*[fine_grid->GetnVertex(iMarker) + 1]; nVertex[iMarker] = 0; } - for (iCoarsePoint = 0; iCoarsePoint < nPoint; iCoarsePoint++) + for (auto iCoarsePoint = 0ul; iCoarsePoint < nPoint; iCoarsePoint++) if (nodes->GetBoundary(iCoarsePoint)) - for (iMarker = 0; iMarker < nMarker; iMarker++) nodes->SetVertex(iCoarsePoint, -1, iMarker); + for (auto iMarker = 0u; iMarker < nMarker; iMarker++) nodes->SetVertex(iCoarsePoint, -1, iMarker); - for (iMarker = 0; iMarker < nMarker; iMarker++) nVertex[iMarker] = 0; + for (auto iMarker = 0u; iMarker < nMarker; iMarker++) nVertex[iMarker] = 0; - for (iCoarsePoint = 0; iCoarsePoint < nPoint; iCoarsePoint++) { + for (auto iCoarsePoint = 0ul; iCoarsePoint < nPoint; iCoarsePoint++) { if (nodes->GetBoundary(iCoarsePoint)) { - for (iChildren = 0; iChildren < nodes->GetnChildren_CV(iCoarsePoint); iChildren++) { - iFinePoint = nodes->GetChildren_CV(iCoarsePoint, iChildren); - for (iMarker = 0; iMarker < fine_grid->GetnMarker(); iMarker++) { + for (auto iChildren = 0u; iChildren < nodes->GetnChildren_CV(iCoarsePoint); iChildren++) { + auto iFinePoint = nodes->GetChildren_CV(iCoarsePoint, iChildren); + for (auto iMarker = 0u; iMarker < fine_grid->GetnMarker(); iMarker++) { if ((fine_grid->nodes->GetVertex(iFinePoint, iMarker) != -1) && (nodes->GetVertex(iCoarsePoint, iMarker) == -1)) { - iVertex = nVertex[iMarker]; + auto iVertex = nVertex[iMarker]; vertex[iMarker][iVertex] = new CVertex(iCoarsePoint, nDim); nodes->SetVertex(iCoarsePoint, iVertex, iMarker); @@ -819,15 +970,13 @@ void CMultiGridGeometry::SetVertex(const CGeometry* fine_grid, const CConfig* co } void CMultiGridGeometry::MatchActuator_Disk(const CConfig* config) { - unsigned short iMarker; - unsigned long iVertex, iPoint; int iProcessor = size; - for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { + for (auto iMarker = 0u; iMarker < config->GetnMarker_All(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) == ACTDISK_INLET) || (config->GetMarker_All_KindBC(iMarker) == ACTDISK_OUTLET)) { - for (iVertex = 0; iVertex < nVertex[iMarker]; iVertex++) { - iPoint = vertex[iMarker][iVertex]->GetNode(); + for (auto iVertex = 0u; iVertex < nVertex[iMarker]; iVertex++) { + auto iPoint = vertex[iMarker][iVertex]->GetNode(); if (nodes->GetDomain(iPoint)) { vertex[iMarker][iVertex]->SetDonorPoint(iPoint, nodes->GetGlobalIndex(iPoint), iVertex, iMarker, iProcessor); } @@ -837,20 +986,18 @@ void CMultiGridGeometry::MatchActuator_Disk(const CConfig* config) { } void CMultiGridGeometry::MatchPeriodic(const CConfig* config, unsigned short val_periodic) { - unsigned short iMarker, iPeriodic, nPeriodic; - unsigned long iVertex, iPoint; int iProcessor = rank; /*--- Evaluate the number of periodic boundary conditions ---*/ - nPeriodic = config->GetnMarker_Periodic(); + auto nPeriodic = config->GetnMarker_Periodic(); - for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { + for (auto iMarker = 0u; iMarker < config->GetnMarker_All(); iMarker++) { if (config->GetMarker_All_KindBC(iMarker) == PERIODIC_BOUNDARY) { - iPeriodic = config->GetMarker_All_PerBound(iMarker); + auto iPeriodic = config->GetMarker_All_PerBound(iMarker); if ((iPeriodic == val_periodic) || (iPeriodic == val_periodic + nPeriodic / 2)) { - for (iVertex = 0; iVertex < nVertex[iMarker]; iVertex++) { - iPoint = vertex[iMarker][iVertex]->GetNode(); + for (auto iVertex = 0u; iVertex < nVertex[iMarker]; iVertex++) { + auto iPoint = vertex[iMarker][iVertex]->GetNode(); if (nodes->GetDomain(iPoint)) { vertex[iMarker][iVertex]->SetDonorPoint(iPoint, nodes->GetGlobalIndex(iPoint), iVertex, iMarker, iProcessor); @@ -863,18 +1010,12 @@ void CMultiGridGeometry::MatchPeriodic(const CConfig* config, unsigned short val void CMultiGridGeometry::SetControlVolume(const CGeometry* fine_grid, unsigned short action) { BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { - unsigned long iFinePoint, iCoarsePoint, iEdge, iParent; - long FineEdge, CoarseEdge; - unsigned short iChildren; - bool change_face_orientation; - su2double Coarse_Volume, Area; - /*--- Compute the area of the coarse volume ---*/ - for (iCoarsePoint = 0; iCoarsePoint < nPoint; iCoarsePoint++) { + for (auto iCoarsePoint = 0u; iCoarsePoint < nPoint; iCoarsePoint++) { nodes->SetVolume(iCoarsePoint, 0.0); - Coarse_Volume = 0.0; - for (iChildren = 0; iChildren < nodes->GetnChildren_CV(iCoarsePoint); iChildren++) { - iFinePoint = nodes->GetChildren_CV(iCoarsePoint, iChildren); + su2double Coarse_Volume = 0.0; + for (auto iChildren = 0u; iChildren < nodes->GetnChildren_CV(iCoarsePoint); iChildren++) { + auto iFinePoint = nodes->GetChildren_CV(iCoarsePoint, iChildren); Coarse_Volume += fine_grid->nodes->GetVolume(iFinePoint); } nodes->SetVolume(iCoarsePoint, Coarse_Volume); @@ -885,19 +1026,19 @@ void CMultiGridGeometry::SetControlVolume(const CGeometry* fine_grid, unsigned s edges->SetZeroValues(); } - for (iCoarsePoint = 0; iCoarsePoint < nPoint; iCoarsePoint++) - for (iChildren = 0; iChildren < nodes->GetnChildren_CV(iCoarsePoint); iChildren++) { - iFinePoint = nodes->GetChildren_CV(iCoarsePoint, iChildren); + for (auto iCoarsePoint = 0u; iCoarsePoint < nPoint; iCoarsePoint++) + for (auto iChildren = 0u; iChildren < nodes->GetnChildren_CV(iCoarsePoint); iChildren++) { + auto iFinePoint = nodes->GetChildren_CV(iCoarsePoint, iChildren); for (auto iFinePoint_Neighbor : fine_grid->nodes->GetPoints(iFinePoint)) { - iParent = fine_grid->nodes->GetParent_CV(iFinePoint_Neighbor); + auto iParent = fine_grid->nodes->GetParent_CV(iFinePoint_Neighbor); if ((iParent != iCoarsePoint) && (iParent < iCoarsePoint)) { - FineEdge = fine_grid->FindEdge(iFinePoint, iFinePoint_Neighbor); + auto FineEdge = fine_grid->FindEdge(iFinePoint, iFinePoint_Neighbor); - change_face_orientation = false; + bool change_face_orientation = false; if (iFinePoint < iFinePoint_Neighbor) change_face_orientation = true; - CoarseEdge = FindEdge(iParent, iCoarsePoint); + auto CoarseEdge = FindEdge(iParent, iCoarsePoint); const auto Normal = fine_grid->edges->GetNormal(FineEdge); @@ -912,9 +1053,9 @@ void CMultiGridGeometry::SetControlVolume(const CGeometry* fine_grid, unsigned s /*--- Check if there is a normal with null area ---*/ - for (iEdge = 0; iEdge < nEdge; iEdge++) { + for (auto iEdge = 0u; iEdge < nEdge; iEdge++) { const auto NormalFace = edges->GetNormal(iEdge); - Area = GeometryToolbox::Norm(nDim, NormalFace); + su2double Area = GeometryToolbox::Norm(nDim, NormalFace); if (Area == 0.0) { su2double DefaultNormal[3] = {EPS * EPS}; edges->SetNormal(iEdge, DefaultNormal); @@ -926,24 +1067,23 @@ void CMultiGridGeometry::SetControlVolume(const CGeometry* fine_grid, unsigned s void CMultiGridGeometry::SetBoundControlVolume(const CGeometry* fine_grid, const CConfig* config, unsigned short action) { - unsigned long iCoarsePoint, iFinePoint, FineVertex, iVertex; - su2double Normal[MAXNDIM] = {0.0}, Area, *NormalFace = nullptr; + su2double Normal[MAXNDIM] = {0.0}, *NormalFace = nullptr; if (action != ALLOCATE) { SU2_OMP_FOR_DYN(1) - for (auto iMarker = 0; iMarker < nMarker; iMarker++) - for (iVertex = 0; iVertex < nVertex[iMarker]; iVertex++) vertex[iMarker][iVertex]->SetZeroValues(); + for (auto iMarker = 0u; iMarker < nMarker; iMarker++) + for (auto iVertex = 0ul; iVertex < nVertex[iMarker]; iVertex++) vertex[iMarker][iVertex]->SetZeroValues(); END_SU2_OMP_FOR } SU2_OMP_FOR_DYN(1) - for (auto iMarker = 0; iMarker < nMarker; iMarker++) { - for (iVertex = 0; iVertex < nVertex[iMarker]; iVertex++) { - iCoarsePoint = vertex[iMarker][iVertex]->GetNode(); + for (auto iMarker = 0u; iMarker < nMarker; iMarker++) { + for (auto iVertex = 0ul; iVertex < nVertex[iMarker]; iVertex++) { + auto iCoarsePoint = vertex[iMarker][iVertex]->GetNode(); for (auto iChildren = 0; iChildren < nodes->GetnChildren_CV(iCoarsePoint); iChildren++) { - iFinePoint = nodes->GetChildren_CV(iCoarsePoint, iChildren); + auto iFinePoint = nodes->GetChildren_CV(iCoarsePoint, iChildren); if (fine_grid->nodes->GetVertex(iFinePoint, iMarker) != -1) { - FineVertex = fine_grid->nodes->GetVertex(iFinePoint, iMarker); + auto FineVertex = fine_grid->nodes->GetVertex(iFinePoint, iMarker); fine_grid->vertex[iMarker][FineVertex]->GetNormal(Normal); vertex[iMarker][iVertex]->AddNormal(Normal); } @@ -954,10 +1094,10 @@ void CMultiGridGeometry::SetBoundControlVolume(const CGeometry* fine_grid, const /*--- Check if there is a normal with null area ---*/ SU2_OMP_FOR_DYN(1) - for (auto iMarker = 0; iMarker < nMarker; iMarker++) { - for (iVertex = 0; iVertex < nVertex[iMarker]; iVertex++) { + for (auto iMarker = 0u; iMarker < nMarker; iMarker++) { + for (auto iVertex = 0ul; iVertex < nVertex[iMarker]; iVertex++) { NormalFace = vertex[iMarker][iVertex]->GetNormal(); - Area = GeometryToolbox::Norm(nDim, NormalFace); + su2double Area = GeometryToolbox::Norm(nDim, NormalFace); if (Area == 0.0) for (auto iDim = 0; iDim < nDim; iDim++) NormalFace[iDim] = EPS * EPS; } @@ -1046,36 +1186,32 @@ void CMultiGridGeometry::SetRestricted_GridVelocity(const CGeometry* fine_grid) } void CMultiGridGeometry::FindNormal_Neighbor(const CConfig* config) { - unsigned short iMarker, iDim; - unsigned long iPoint, iVertex; - - for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { + for (auto iMarker = 0u; iMarker < config->GetnMarker_All(); iMarker++) { if (config->GetMarker_All_KindBC(iMarker) != SEND_RECEIVE && config->GetMarker_All_KindBC(iMarker) != INTERNAL_BOUNDARY && config->GetMarker_All_KindBC(iMarker) != NEARFIELD_BOUNDARY) { - for (iVertex = 0; iVertex < nVertex[iMarker]; iVertex++) { - iPoint = vertex[iMarker][iVertex]->GetNode(); + for (auto iVertex = 0ul; iVertex < nVertex[iMarker]; iVertex++) { + auto iPoint = vertex[iMarker][iVertex]->GetNode(); /*--- If the node belong to the domain ---*/ if (nodes->GetDomain(iPoint)) { /*--- Compute closest normal neighbor ---*/ - su2double cos_max, scalar_prod, norm_vect, norm_Normal, cos_alpha, diff_coord; unsigned long Point_Normal = 0; su2double* Normal = vertex[iMarker][iVertex]->GetNormal(); - cos_max = -1.0; + su2double cos_max = -1.0; for (auto jPoint : nodes->GetPoints(iPoint)) { - scalar_prod = 0.0; - norm_vect = 0.0; - norm_Normal = 0.0; - for (iDim = 0; iDim < nDim; iDim++) { - diff_coord = nodes->GetCoord(jPoint, iDim) - nodes->GetCoord(iPoint, iDim); + su2double scalar_prod = 0.0; + su2double norm_vect = 0.0; + su2double norm_Normal = 0.0; + for (auto iDim = 0u; iDim < nDim; iDim++) { + su2double diff_coord = nodes->GetCoord(jPoint, iDim) - nodes->GetCoord(iPoint, iDim); scalar_prod += diff_coord * Normal[iDim]; norm_vect += diff_coord * diff_coord; norm_Normal += Normal[iDim] * Normal[iDim]; } norm_vect = sqrt(norm_vect); norm_Normal = sqrt(norm_Normal); - cos_alpha = scalar_prod / (norm_vect * norm_Normal); + su2double cos_alpha = scalar_prod / (norm_vect * norm_Normal); /*--- Get maximum cosine (not minimum because normals are oriented inwards) ---*/ if (cos_alpha >= cos_max) { @@ -1089,3 +1225,67 @@ void CMultiGridGeometry::FindNormal_Neighbor(const CConfig* config) { } } } + +su2double CMultiGridGeometry::ComputeLocalCurvature(const CGeometry* fine_grid, unsigned long iPoint, + unsigned short iMarker) const { + /*--- Compute local curvature (maximum angle between adjacent face normals) at a boundary vertex. + This is used to determine if agglomeration is safe based on a curvature threshold. ---*/ + + /*--- Get the vertex index for this point on this marker ---*/ + long iVertex = fine_grid->nodes->GetVertex(iPoint, iMarker); + if (iVertex < 0) return 0.0; // Point not on this marker + + /*--- Get the normal at this vertex ---*/ + su2double Normal_i[MAXNDIM] = {0.0}; + fine_grid->vertex[iMarker][iVertex]->GetNormal(Normal_i); + su2double Area_i = GeometryToolbox::Norm(int(nDim), Normal_i); + + if (Area_i < EPS) return 0.0; // Skip degenerate vertices + + /*--- Normalize the normal ---*/ + for (unsigned short iDim = 0; iDim < nDim; iDim++) { + Normal_i[iDim] /= Area_i; + } + + /*--- Find maximum angle with neighboring vertices on the same marker ---*/ + su2double max_angle = 0.0; + + /*--- Loop over edges connected to this point ---*/ + for (unsigned short iEdge = 0; iEdge < fine_grid->nodes->GetnPoint(iPoint); iEdge++) { + unsigned long jPoint = fine_grid->nodes->GetPoint(iPoint, iEdge); + + /*--- Check if neighbor is also on this marker ---*/ + long jVertex = fine_grid->nodes->GetVertex(jPoint, iMarker); + if (jVertex < 0) continue; // Not on this marker + + /*--- Get normal at neighbor vertex ---*/ + su2double Normal_j[MAXNDIM] = {0.0}; + fine_grid->vertex[iMarker][jVertex]->GetNormal(Normal_j); + su2double Area_j = GeometryToolbox::Norm(int(nDim), Normal_j); + + if (Area_j < EPS) continue; // Skip degenerate neighbor + + /*--- Normalize the neighbor normal ---*/ + for (unsigned short iDim = 0; iDim < nDim; iDim++) { + Normal_j[iDim] /= Area_j; + } + + /*--- Compute dot product: cos(angle) = n_i · n_j ---*/ + su2double dot_product = 0.0; + for (unsigned short iDim = 0; iDim < nDim; iDim++) { + dot_product += Normal_i[iDim] * Normal_j[iDim]; + } + + /*--- Clamp to [-1, 1] to avoid numerical issues with acos ---*/ + dot_product = max(-1.0, min(1.0, dot_product)); + + /*--- Compute angle in degrees ---*/ + su2double angle_rad = acos(dot_product); + su2double angle_deg = angle_rad * 180.0 / PI_NUMBER; + + /*--- Track maximum angle ---*/ + max_angle = max(max_angle, angle_deg); + } + + return max_angle; +} diff --git a/Common/src/geometry/dual_grid/CPoint.cpp b/Common/src/geometry/dual_grid/CPoint.cpp index 361792eac5ee..410a5c31bfdc 100644 --- a/Common/src/geometry/dual_grid/CPoint.cpp +++ b/Common/src/geometry/dual_grid/CPoint.cpp @@ -25,6 +25,7 @@ * License along with SU2. If not, see . */ +#include #include "../../../include/geometry/dual_grid/CPoint.hpp" #include "../../../include/CConfig.hpp" #include "../../../include/parallelization/omp_structure.hpp" @@ -73,7 +74,7 @@ void CPoint::FullAllocation(unsigned short imesh, const CConfig* config) { /*--- Multigrid structures. ---*/ if (config->GetnMGLevels() > 0) { - Parent_CV.resize(npoint) = 0; + Parent_CV.resize(npoint) = numeric_limits::max(); Agglomerate.resize(npoint) = false; Agglomerate_Indirect.resize(npoint) = false; /*--- The finest grid does not have children CV's. ---*/ diff --git a/Common/src/geometry/meshreader/CBoxMeshReaderFEM.cpp b/Common/src/geometry/meshreader/CBoxMeshReaderFEM.cpp index 1759b21b2b76..93d4921fd38d 100644 --- a/Common/src/geometry/meshreader/CBoxMeshReaderFEM.cpp +++ b/Common/src/geometry/meshreader/CBoxMeshReaderFEM.cpp @@ -61,6 +61,9 @@ CBoxMeshReaderFEM::CBoxMeshReaderFEM(const CConfig* val_config, unsigned short v ComputeBoxVolumeConnectivity(); ComputeBoxPointCoordinates(); ComputeBoxSurfaceConnectivity(); + + /*--- Duplicate some markers if requested. ---*/ + CopyMarkers(val_config->GetMarkerCreateCopy()); } CBoxMeshReaderFEM::~CBoxMeshReaderFEM() = default; diff --git a/Common/src/geometry/meshreader/CBoxMeshReaderFVM.cpp b/Common/src/geometry/meshreader/CBoxMeshReaderFVM.cpp index 6b33705f0ad9..857d9f1eafcb 100644 --- a/Common/src/geometry/meshreader/CBoxMeshReaderFVM.cpp +++ b/Common/src/geometry/meshreader/CBoxMeshReaderFVM.cpp @@ -61,6 +61,9 @@ CBoxMeshReaderFVM::CBoxMeshReaderFVM(const CConfig* val_config, unsigned short v ComputeBoxPointCoordinates(); ComputeBoxVolumeConnectivity(); ComputeBoxSurfaceConnectivity(); + + /*--- Duplicate some markers if requested. ---*/ + CopyMarkers(val_config->GetMarkerCreateCopy()); } CBoxMeshReaderFVM::~CBoxMeshReaderFVM() = default; diff --git a/Common/src/geometry/meshreader/CCGNSMeshReaderFEM.cpp b/Common/src/geometry/meshreader/CCGNSMeshReaderFEM.cpp index 776b2b554f4a..3f2a41de39de 100644 --- a/Common/src/geometry/meshreader/CCGNSMeshReaderFEM.cpp +++ b/Common/src/geometry/meshreader/CCGNSMeshReaderFEM.cpp @@ -58,6 +58,9 @@ CCGNSMeshReaderFEM::CCGNSMeshReaderFEM(const CConfig* val_config, unsigned short /*--- We have extracted all CGNS data. Close the CGNS file. ---*/ if (cg_close(cgnsFileID)) cg_error_exit(); + /*--- Duplicate some markers if requested. ---*/ + CopyMarkers(val_config->GetMarkerCreateCopy()); + #else SU2_MPI::Error(string(" SU2 built without CGNS support. \n") + string(" To use CGNS, build SU2 accordingly."), CURRENT_FUNCTION); diff --git a/Common/src/geometry/meshreader/CCGNSMeshReaderFVM.cpp b/Common/src/geometry/meshreader/CCGNSMeshReaderFVM.cpp index 916b1de4699e..bd21c3976953 100644 --- a/Common/src/geometry/meshreader/CCGNSMeshReaderFVM.cpp +++ b/Common/src/geometry/meshreader/CCGNSMeshReaderFVM.cpp @@ -65,6 +65,9 @@ CCGNSMeshReaderFVM::CCGNSMeshReaderFVM(const CConfig* val_config, unsigned short ReformatCGNSVolumeConnectivity(); ReformatCGNSSurfaceConnectivity(); + /*--- Duplicate some markers if requested. ---*/ + CopyMarkers(val_config->GetMarkerCreateCopy()); + #else SU2_MPI::Error(string(" SU2 built without CGNS support. \n") + string(" To use CGNS, build SU2 accordingly."), CURRENT_FUNCTION); diff --git a/Common/src/geometry/meshreader/CMeshReaderBase.cpp b/Common/src/geometry/meshreader/CMeshReaderBase.cpp index 315ff00ac04e..99025d3e87a8 100644 --- a/Common/src/geometry/meshreader/CMeshReaderBase.cpp +++ b/Common/src/geometry/meshreader/CMeshReaderBase.cpp @@ -93,3 +93,25 @@ void CMeshReaderBase::GetCornerPointsAllFaces(const unsigned long* elemInfo, uns } } } + +void CMeshReaderBase::CopyMarkers(const std::vector& srcDstMarkers) { + for (size_t i = 0; i < srcDstMarkers.size(); i += 2) { + const auto& src = srcDstMarkers[i]; + const auto& dst = srcDstMarkers[i + 1]; + + if (const auto it = std::find(markerNames.begin(), markerNames.end(), src); it != markerNames.end()) { + const auto j = std::distance(markerNames.begin(), it); + + numberOfMarkers += 1; + markerNames.push_back(dst); + surfaceElementConnectivity.push_back(surfaceElementConnectivity[j]); + + /*--- Only the FEM readers populate this vector. ---*/ + if (!numberOfLocalSurfaceElements.empty()) { + numberOfLocalSurfaceElements.push_back(numberOfLocalSurfaceElements[j]); + } + } else if (rank == MASTER_NODE) { + std::cout << "WARNING: Not duplicating marker " << src << " because it was not found.\n"; + } + } +} diff --git a/Common/src/geometry/meshreader/CRectangularMeshReaderFEM.cpp b/Common/src/geometry/meshreader/CRectangularMeshReaderFEM.cpp index fec3284304e5..432894814459 100644 --- a/Common/src/geometry/meshreader/CRectangularMeshReaderFEM.cpp +++ b/Common/src/geometry/meshreader/CRectangularMeshReaderFEM.cpp @@ -59,6 +59,9 @@ CRectangularMeshReaderFEM::CRectangularMeshReaderFEM(const CConfig* val_config, ComputeRectangularVolumeConnectivity(); ComputeRectangularPointCoordinates(); ComputeRectangularSurfaceConnectivity(); + + /*--- Duplicate some markers if requested. ---*/ + CopyMarkers(val_config->GetMarkerCreateCopy()); } CRectangularMeshReaderFEM::~CRectangularMeshReaderFEM() = default; diff --git a/Common/src/geometry/meshreader/CRectangularMeshReaderFVM.cpp b/Common/src/geometry/meshreader/CRectangularMeshReaderFVM.cpp index 308330703974..1b32c0369d90 100644 --- a/Common/src/geometry/meshreader/CRectangularMeshReaderFVM.cpp +++ b/Common/src/geometry/meshreader/CRectangularMeshReaderFVM.cpp @@ -59,6 +59,9 @@ CRectangularMeshReaderFVM::CRectangularMeshReaderFVM(const CConfig* val_config, ComputeRectangularPointCoordinates(); ComputeRectangularVolumeConnectivity(); ComputeRectangularSurfaceConnectivity(); + + /*--- Duplicate some markers if requested. ---*/ + CopyMarkers(val_config->GetMarkerCreateCopy()); } CRectangularMeshReaderFVM::~CRectangularMeshReaderFVM() = default; diff --git a/Common/src/geometry/meshreader/CSU2ASCIIMeshReaderFEM.cpp b/Common/src/geometry/meshreader/CSU2ASCIIMeshReaderFEM.cpp index 3f00eeced979..8a9b66e0ea35 100644 --- a/Common/src/geometry/meshreader/CSU2ASCIIMeshReaderFEM.cpp +++ b/Common/src/geometry/meshreader/CSU2ASCIIMeshReaderFEM.cpp @@ -46,6 +46,9 @@ CSU2ASCIIMeshReaderFEM::CSU2ASCIIMeshReaderFEM(CConfig* val_config, unsigned sho /*--- Read the surface connectivity and store the surface elements whose corresponding volume element is stored on this MPI rank. ---*/ ReadSurfaceElementConnectivity({}); + + /*--- Duplicate some markers if requested. ---*/ + CopyMarkers(val_config->GetMarkerCreateCopy()); } CSU2ASCIIMeshReaderFEM::~CSU2ASCIIMeshReaderFEM() = default; diff --git a/Common/src/geometry/meshreader/CSU2ASCIIMeshReaderFVM.cpp b/Common/src/geometry/meshreader/CSU2ASCIIMeshReaderFVM.cpp index 8daeec4c14df..5857e3ac0a98 100644 --- a/Common/src/geometry/meshreader/CSU2ASCIIMeshReaderFVM.cpp +++ b/Common/src/geometry/meshreader/CSU2ASCIIMeshReaderFVM.cpp @@ -69,6 +69,9 @@ CSU2ASCIIMeshReaderFVM::CSU2ASCIIMeshReaderFVM(CConfig* val_config, unsigned sho } } mesh_file.close(); + + /*--- Duplicate some markers if requested. ---*/ + CopyMarkers(val_config->GetMarkerCreateCopy()); } CSU2ASCIIMeshReaderFVM::~CSU2ASCIIMeshReaderFVM() = default; diff --git a/Common/src/grid_movement/CLinearElasticity.cpp b/Common/src/grid_movement/CLinearElasticity.cpp index 2450cadf0e68..6ce11a65422a 100644 --- a/Common/src/grid_movement/CLinearElasticity.cpp +++ b/Common/src/grid_movement/CLinearElasticity.cpp @@ -164,17 +164,12 @@ particular, the linear elasticity equations hold only for small deformations. -- } void CLinearElasticity::UpdateGridCoord(CGeometry* geometry, CConfig* config) { - unsigned short iDim; - unsigned long iPoint, total_index; - su2double new_coord; - /*--- Update the grid coordinates using the solution of the linear system after grid deformation (LinSysSol contains the x, y, z displacements). ---*/ - for (iPoint = 0; iPoint < nPoint; iPoint++) - for (iDim = 0; iDim < nDim; iDim++) { - total_index = iPoint * nDim + iDim; - new_coord = geometry->nodes->GetCoord(iPoint, iDim) + LinSysSol[total_index]; + for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) + for (auto iDim = 0ul; iDim < nDim; iDim++) { + su2double new_coord = geometry->nodes->GetCoord(iPoint, iDim) + LinSysSol(iPoint, iDim); if (fabs(new_coord) < EPS * EPS) new_coord = 0.0; geometry->nodes->SetCoord(iPoint, iDim, new_coord); } @@ -190,7 +185,7 @@ void CLinearElasticity::UpdateGridCoord(CGeometry* geometry, CConfig* config) { void CLinearElasticity::UpdateGridCoord_Derivatives(CGeometry* geometry, CConfig* config, bool ForwardProjectionDerivative) { unsigned short iDim, iMarker; - unsigned long iPoint, total_index, iVertex; + unsigned long iPoint, iVertex; SU2_COMPONENT Kind_SU2 = config->GetKind_SU2(); @@ -200,9 +195,8 @@ void CLinearElasticity::UpdateGridCoord_Derivatives(CGeometry* geometry, CConfig for (iPoint = 0; iPoint < geometry->GetnPoint(); iPoint++) { su2double new_coord[3] = {}; for (iDim = 0; iDim < nDim; iDim++) { - total_index = iPoint * nDim + iDim; new_coord[iDim] = geometry->nodes->GetCoord(iPoint, iDim); - SU2_TYPE::SetDerivative(new_coord[iDim], SU2_TYPE::GetValue(LinSysSol[total_index])); + SU2_TYPE::SetDerivative(new_coord[iDim], SU2_TYPE::GetValue(LinSysSol(iPoint, iDim))); } geometry->nodes->SetCoord(iPoint, new_coord); } @@ -211,7 +205,6 @@ void CLinearElasticity::UpdateGridCoord_Derivatives(CGeometry* geometry, CConfig if (config->GetSmoothGradient()) { for (iPoint = 0; iPoint < geometry->GetnPoint(); iPoint++) { for (iDim = 0; iDim < nDim; iDim++) { - total_index = iPoint * nDim + iDim; geometry->SetSensitivity(iPoint, iDim, 0.0); } } @@ -222,8 +215,7 @@ void CLinearElasticity::UpdateGridCoord_Derivatives(CGeometry* geometry, CConfig iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); if (geometry->nodes->GetDomain(iPoint)) { for (iDim = 0; iDim < nDim; iDim++) { - total_index = iPoint * nDim + iDim; - geometry->SetSensitivity(iPoint, iDim, LinSysSol[total_index]); + geometry->SetSensitivity(iPoint, iDim, LinSysSol(iPoint, iDim)); } } } @@ -232,8 +224,7 @@ void CLinearElasticity::UpdateGridCoord_Derivatives(CGeometry* geometry, CConfig } else if (config->GetSmoothGradient() && ForwardProjectionDerivative) { for (iPoint = 0; iPoint < geometry->GetnPoint(); iPoint++) { for (iDim = 0; iDim < nDim; iDim++) { - total_index = iPoint * nDim + iDim; - geometry->SetSensitivity(iPoint, iDim, LinSysSol[total_index]); + geometry->SetSensitivity(iPoint, iDim, LinSysSol(iPoint, iDim)); } } } @@ -1247,7 +1238,7 @@ su2double CLinearElasticity::ShapeFunc_Hexa(su2double Xi, su2double Eta, su2doub void CLinearElasticity::SetDomainDisplacements(CGeometry* geometry, CConfig* config) { unsigned short iDim, nDim = geometry->GetnDim(); - unsigned long iPoint, total_index; + unsigned long iPoint; if (config->GetHold_GridFixed()) { auto MinCoordValues = config->GetHold_GridFixed_Coord(); @@ -1260,10 +1251,9 @@ void CLinearElasticity::SetDomainDisplacements(CGeometry* geometry, CConfig* con auto Coord = geometry->nodes->GetCoord(iPoint); for (iDim = 0; iDim < nDim; iDim++) { if ((Coord[iDim] < MinCoordValues[iDim]) || (Coord[iDim] > MaxCoordValues[iDim])) { - total_index = iPoint * nDim + iDim; - LinSysRes[total_index] = 0.0; - LinSysSol[total_index] = 0.0; - StiffMatrix.DeleteValsRowi(total_index); + LinSysRes(iPoint, iDim) = 0.0; + LinSysSol(iPoint, iDim) = 0.0; + StiffMatrix.DeleteValsRowi(iPoint, iDim); } } } @@ -1276,10 +1266,9 @@ void CLinearElasticity::SetDomainDisplacements(CGeometry* geometry, CConfig* con for (iPoint = 0; iPoint < nPoint; iPoint++) { if (geometry->nodes->GetWall_Distance(iPoint) >= config->GetDeform_Limit()) { for (iDim = 0; iDim < nDim; iDim++) { - total_index = iPoint * nDim + iDim; - LinSysRes[total_index] = 0.0; - LinSysSol[total_index] = 0.0; - StiffMatrix.DeleteValsRowi(total_index); + LinSysRes(iPoint, iDim) = 0.0; + LinSysSol(iPoint, iDim) = 0.0; + StiffMatrix.DeleteValsRowi(iPoint, iDim); } } } @@ -1288,7 +1277,7 @@ void CLinearElasticity::SetDomainDisplacements(CGeometry* geometry, CConfig* con void CLinearElasticity::SetBoundaryDisplacements(CGeometry* geometry, CConfig* config) { unsigned short iDim, nDim = geometry->GetnDim(), iMarker, axis = 0; - unsigned long iPoint, total_index, iVertex; + unsigned long iPoint, iVertex; su2double *VarCoord, MeanCoord[3] = {0.0, 0.0, 0.0}, VarIncrement = 1.0; /*--- If requested (no by default) impose the surface deflections in @@ -1307,10 +1296,9 @@ void CLinearElasticity::SetBoundaryDisplacements(CGeometry* geometry, CConfig* c for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); for (iDim = 0; iDim < nDim; iDim++) { - total_index = iPoint * nDim + iDim; - LinSysRes[total_index] = 0.0; - LinSysSol[total_index] = 0.0; - StiffMatrix.DeleteValsRowi(total_index); + LinSysRes(iPoint, iDim) = 0.0; + LinSysSol(iPoint, iDim) = 0.0; + StiffMatrix.DeleteValsRowi(iPoint, iDim); } } } @@ -1327,10 +1315,9 @@ void CLinearElasticity::SetBoundaryDisplacements(CGeometry* geometry, CConfig* c VarCoord = geometry->vertex[iMarker][iVertex]->GetVarCoord(); for (iDim = 0; iDim < nDim; iDim++) { - total_index = iPoint * nDim + iDim; - LinSysRes[total_index] = SU2_TYPE::GetValue(VarCoord[iDim] * VarIncrement); - LinSysSol[total_index] = SU2_TYPE::GetValue(VarCoord[iDim] * VarIncrement); - StiffMatrix.DeleteValsRowi(total_index); + LinSysRes(iPoint, iDim) = SU2_TYPE::GetValue(VarCoord[iDim] * VarIncrement); + LinSysSol(iPoint, iDim) = SU2_TYPE::GetValue(VarCoord[iDim] * VarIncrement); + StiffMatrix.DeleteValsRowi(iPoint, iDim); } } } @@ -1367,10 +1354,9 @@ void CLinearElasticity::SetBoundaryDisplacements(CGeometry* geometry, CConfig* c for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - total_index = iPoint * nDim + axis; - LinSysRes[total_index] = 0.0; - LinSysSol[total_index] = 0.0; - StiffMatrix.DeleteValsRowi(total_index); + LinSysRes(iPoint, axis) = 0.0; + LinSysSol(iPoint, axis) = 0.0; + StiffMatrix.DeleteValsRowi(iPoint, axis); } } } @@ -1382,10 +1368,9 @@ void CLinearElasticity::SetBoundaryDisplacements(CGeometry* geometry, CConfig* c for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); for (iDim = 0; iDim < nDim; iDim++) { - total_index = iPoint * nDim + iDim; - LinSysRes[total_index] = 0.0; - LinSysSol[total_index] = 0.0; - StiffMatrix.DeleteValsRowi(total_index); + LinSysRes(iPoint, axis) = 0.0; + LinSysSol(iPoint, axis) = 0.0; + StiffMatrix.DeleteValsRowi(iPoint, axis); } } } @@ -1399,10 +1384,9 @@ void CLinearElasticity::SetBoundaryDisplacements(CGeometry* geometry, CConfig* c iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); VarCoord = geometry->vertex[iMarker][iVertex]->GetVarCoord(); for (iDim = 0; iDim < nDim; iDim++) { - total_index = iPoint * nDim + iDim; - LinSysRes[total_index] = SU2_TYPE::GetValue(VarCoord[iDim] * VarIncrement); - LinSysSol[total_index] = SU2_TYPE::GetValue(VarCoord[iDim] * VarIncrement); - StiffMatrix.DeleteValsRowi(total_index); + LinSysRes(iPoint, iDim) = SU2_TYPE::GetValue(VarCoord[iDim] * VarIncrement); + LinSysSol(iPoint, iDim) = SU2_TYPE::GetValue(VarCoord[iDim] * VarIncrement); + StiffMatrix.DeleteValsRowi(iPoint, iDim); } } } @@ -1411,7 +1395,7 @@ void CLinearElasticity::SetBoundaryDisplacements(CGeometry* geometry, CConfig* c void CLinearElasticity::SetBoundaryDerivatives(CGeometry* geometry, CConfig* config, bool ForwardProjectionDerivative) { unsigned short iDim, iMarker; - unsigned long iPoint, total_index, iVertex; + unsigned long iPoint, iVertex; su2double* VarCoord; SU2_COMPONENT Kind_SU2 = config->GetKind_SU2(); @@ -1422,9 +1406,8 @@ void CLinearElasticity::SetBoundaryDerivatives(CGeometry* geometry, CConfig* con iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); VarCoord = geometry->vertex[iMarker][iVertex]->GetVarCoord(); for (iDim = 0; iDim < nDim; iDim++) { - total_index = iPoint * nDim + iDim; - LinSysRes[total_index] = SU2_TYPE::GetDerivative(VarCoord[iDim]); - LinSysSol[total_index] = SU2_TYPE::GetDerivative(VarCoord[iDim]); + LinSysRes(iPoint, iDim) = SU2_TYPE::GetDerivative(VarCoord[iDim]); + LinSysSol(iPoint, iDim) = SU2_TYPE::GetDerivative(VarCoord[iDim]); } } } @@ -1433,9 +1416,8 @@ void CLinearElasticity::SetBoundaryDerivatives(CGeometry* geometry, CConfig* con } else if ((Kind_SU2 == SU2_COMPONENT::SU2_DOT) && !ForwardProjectionDerivative) { for (iPoint = 0; iPoint < nPoint; iPoint++) { for (iDim = 0; iDim < nDim; iDim++) { - total_index = iPoint * nDim + iDim; - LinSysRes[total_index] = SU2_TYPE::GetValue(geometry->GetSensitivity(iPoint, iDim)); - LinSysSol[total_index] = SU2_TYPE::GetValue(geometry->GetSensitivity(iPoint, iDim)); + LinSysRes(iPoint, iDim) = SU2_TYPE::GetValue(geometry->GetSensitivity(iPoint, iDim)); + LinSysSol(iPoint, iDim) = SU2_TYPE::GetValue(geometry->GetSensitivity(iPoint, iDim)); } } } else if (config->GetSmoothGradient() && ForwardProjectionDerivative) { @@ -1444,9 +1426,8 @@ void CLinearElasticity::SetBoundaryDerivatives(CGeometry* geometry, CConfig* con for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); for (iDim = 0; iDim < nDim; iDim++) { - total_index = iPoint * nDim + iDim; - LinSysRes[total_index] = SU2_TYPE::GetValue(geometry->GetSensitivity(iPoint, iDim)); - LinSysSol[total_index] = SU2_TYPE::GetValue(geometry->GetSensitivity(iPoint, iDim)); + LinSysRes(iPoint, iDim) = SU2_TYPE::GetValue(geometry->GetSensitivity(iPoint, iDim)); + LinSysSol(iPoint, iDim) = SU2_TYPE::GetValue(geometry->GetSensitivity(iPoint, iDim)); } } } diff --git a/Common/src/interface_interpolation/CIsoparametric.cpp b/Common/src/interface_interpolation/CIsoparametric.cpp index 1874c48abe59..51feca37cb80 100644 --- a/Common/src/interface_interpolation/CIsoparametric.cpp +++ b/Common/src/interface_interpolation/CIsoparametric.cpp @@ -245,12 +245,9 @@ void CIsoparametric::SetTransferCoeff(const CConfig* const* config) { } } END_SU2_OMP_FOR - SU2_OMP_CRITICAL { - MaxDistance = max(MaxDistance, maxDist); - ErrorCounter += errorCount; - nGlobalVertexTarget += totalCount; - } - END_SU2_OMP_CRITICAL + atomicMax(maxDist, MaxDistance); + atomicAdd(errorCount, ErrorCounter); + atomicAdd(totalCount, nGlobalVertexTarget); } END_SU2_OMP_PARALLEL diff --git a/Common/src/interface_interpolation/CNearestNeighbor.cpp b/Common/src/interface_interpolation/CNearestNeighbor.cpp index 20a7aacf3406..302669b1fdb5 100644 --- a/Common/src/interface_interpolation/CNearestNeighbor.cpp +++ b/Common/src/interface_interpolation/CNearestNeighbor.cpp @@ -153,12 +153,9 @@ void CNearestNeighbor::SetTransferCoeff(const CConfig* const* config) { } } END_SU2_OMP_FOR - SU2_OMP_CRITICAL { - totalTargetPoints += numTarget; - AvgDistance += avgDist; - MaxDistance = max(MaxDistance, maxDist); - } - END_SU2_OMP_CRITICAL + atomicAdd(numTarget, totalTargetPoints); + atomicAdd(avgDist, AvgDistance); + atomicMax(maxDist, MaxDistance); } END_SU2_OMP_PARALLEL } diff --git a/Common/src/interface_interpolation/CRadialBasisFunction.cpp b/Common/src/interface_interpolation/CRadialBasisFunction.cpp index a974fe326ddb..219685c5a248 100644 --- a/Common/src/interface_interpolation/CRadialBasisFunction.cpp +++ b/Common/src/interface_interpolation/CRadialBasisFunction.cpp @@ -373,14 +373,11 @@ void CRadialBasisFunction::SetTransferCoeff(const CConfig* const* config) { } } // end target vertex loop END_SU2_OMP_FOR - SU2_OMP_CRITICAL { - totalDonorPoints += totalDonors; - MinDonors = min(MinDonors, minDonors); - MaxDonors = max(MaxDonors, maxDonors); - AvgCorrection += sumCorr; - MaxCorrection = max(MaxCorrection, maxCorr); - } - END_SU2_OMP_CRITICAL + atomicAdd(totalDonors, totalDonorPoints); + atomicMin(minDonors, MinDonors); + atomicMax(maxDonors, MaxDonors); + atomicAdd(sumCorr, AvgCorrection); + atomicMax(maxCorr, MaxCorrection); } END_SU2_OMP_PARALLEL diff --git a/Common/src/linear_algebra/CPastixWrapper.cpp b/Common/src/linear_algebra/CPastixWrapper.cpp index b871ac989771..51325275b5fd 100644 --- a/Common/src/linear_algebra/CPastixWrapper.cpp +++ b/Common/src/linear_algebra/CPastixWrapper.cpp @@ -38,18 +38,15 @@ template void CPastixWrapper::Initialize(CGeometry* geometry, const CConfig* config) { - using namespace PaStiX; - if (isinitialized) return; // only need to do this once - unsigned long nVar = matrix.nVar, nPoint = matrix.nPoint, nPointDomain = matrix.nPointDomain; + const unsigned long nVar = matrix.nVar, nPoint = matrix.nPoint, nPointDomain = matrix.nPointDomain; const unsigned long *row_ptr = matrix.rowptr, *col_ind = matrix.colidx; - - unsigned long iPoint, offset = 0, nNonZero = row_ptr[nPointDomain]; + const unsigned long nNonZero = row_ptr[nPointDomain]; /*--- Allocate ---*/ - nCols = pastix_int_t(nPointDomain); + nCols = static_cast(nPointDomain); colptr.resize(nPointDomain + 1); rowidx.clear(); rowidx.reserve(nNonZero); @@ -60,53 +57,40 @@ void CPastixWrapper::Initialize(CGeometry* geometry, const CConfig* /*--- Set default parameter values ---*/ - pastix_int_t incomplete = iparm[IPARM_INCOMPLETE]; - - iparm[IPARM_MODIFY_PARAMETER] = API_NO; - Run(); + const auto incomplete = iparm[IPARM_INCOMPLETE]; + pastixInitParam(iparm, dparm); /*--- Customize important parameters ---*/ switch (verb) { case 1: - iparm[IPARM_VERBOSE] = API_VERBOSE_NO; + iparm[IPARM_VERBOSE] = PastixVerboseNo; break; case 2: - iparm[IPARM_VERBOSE] = API_VERBOSE_YES; + iparm[IPARM_VERBOSE] = PastixVerboseYes; break; default: - iparm[IPARM_VERBOSE] = API_VERBOSE_NOT; + iparm[IPARM_VERBOSE] = PastixVerboseNot; break; } - iparm[IPARM_DOF_NBR] = pastix_int_t(nVar); - iparm[IPARM_MATRIX_VERIFICATION] = API_NO; - iparm[IPARM_FREE_CSCPASTIX] = API_CSC_FREE; - iparm[IPARM_CSCD_CORRECT] = API_NO; - iparm[IPARM_RHSD_CHECK] = API_NO; - iparm[IPARM_ORDERING] = API_ORDER_PTSCOTCH; + iparm[IPARM_ORDERING] = PastixOrderPtScotch; iparm[IPARM_INCOMPLETE] = incomplete; - iparm[IPARM_LEVEL_OF_FILL] = pastix_int_t(config->GetPastixFillLvl()); + iparm[IPARM_LEVEL_OF_FILL] = static_cast(config->GetPastixFillLvl()); iparm[IPARM_THREAD_NBR] = omp_get_max_threads(); -#if defined(HAVE_MPI) && defined(HAVE_OMP) - int comm_mode = MPI_THREAD_SINGLE; - MPI_Query_thread(&comm_mode); - if (comm_mode == MPI_THREAD_MULTIPLE) - iparm[IPARM_THREAD_COMM_MODE] = API_THREAD_MULTIPLE; - else - iparm[IPARM_THREAD_COMM_MODE] = API_THREAD_FUNNELED; -#endif - /*--- Prepare sparsity structure ---*/ + pastixInit(&state, SU2_MPI::GetComm(), iparm, dparm); - /*--- We need it in global coordinates, i.e. shifted according to the position - of the current rank in the linear partitioning space, and "unpacked" halo part. - The latter forces us to re-sort the column indices of rows with halo points, which - in turn requires blocks to be swapped accordingly. Moreover we need "pointer" and - indices in Fortran-style numbering (start at 1), effectively the matrix is copied. - Here we prepare the pointer and index part, and map the required swaps. ---*/ + /*--- Prepare sparsity structure ---*/ - /*--- 1 - Determine position in the linear partitioning ---*/ + /*--- We need it in global coordinates, i.e. shifted according to the position + of the current rank in the linear partitioning space, and "unpacked" halo part. + The latter forces us to re-sort the column indices of rows with halo points, which + in turn requires blocks to be swapped accordingly. Effectively the matrix is copied. + Here we prepare the pointer and index part, and map the required swaps. ---*/ + /*--- 1 - Determine position in the linear partitioning ---*/ + + unsigned long offset = 0; #ifdef HAVE_MPI vector domain_sizes(mpi_size); MPI_Allgather(&nPointDomain, 1, MPI_UNSIGNED_LONG, domain_sizes.data(), 1, MPI_UNSIGNED_LONG, SU2_MPI::GetComm()); @@ -151,54 +135,74 @@ void CPastixWrapper::Initialize(CGeometry* geometry, const CConfig* /*--- 3 - Copy, map the sparsity, and put it in Fortran numbering ---*/ - for (iPoint = 0; iPoint < nPointDomain; ++iPoint) { - colptr[iPoint] = pastix_int_t(row_ptr[iPoint] + 1); + for (auto iPoint = 0ul; iPoint < nPointDomain; ++iPoint) { + colptr[iPoint] = static_cast(row_ptr[iPoint] + 1); - unsigned long begin = row_ptr[iPoint], end = row_ptr[iPoint + 1], j; + const unsigned long begin = row_ptr[iPoint], end = row_ptr[iPoint + 1]; /*--- If last point of row is halo ---*/ - bool sort_required = (col_ind[end - 1] >= nPointDomain); + const bool sort_required = (col_ind[end - 1] >= nPointDomain); if (sort_required) { - unsigned long nnz_row = end - begin; + const unsigned long nnz_row = end - begin; sort_rows.push_back(iPoint); - sort_order.push_back(vector(nnz_row)); + sort_order.emplace_back(nnz_row); /*--- Sort mapped indices ("first") and keep track of source ("second") for when we later need to swap blocks for these rows. ---*/ vector > aux(nnz_row); - for (j = begin; j < end; ++j) { - if (col_ind[j] < nPointDomain) - aux[j - begin].first = pastix_int_t(offset + col_ind[j] + 1); - else - aux[j - begin].first = pastix_int_t(map[col_ind[j] - nPointDomain] + 1); + for (auto j = begin; j < end; ++j) { + if (col_ind[j] < nPointDomain) { + aux[j - begin].first = static_cast(offset + col_ind[j] + 1); + } else { + aux[j - begin].first = static_cast(map[col_ind[j] - nPointDomain] + 1); + } aux[j - begin].second = j; } sort(aux.begin(), aux.end()); - for (j = 0; j < nnz_row; ++j) { + for (auto j = 0ul; j < nnz_row; ++j) { rowidx.push_back(aux[j].first); sort_order.back()[j] = aux[j].second; } } else { /*--- These are all internal, no need to go through map. ---*/ - for (j = begin; j < end; ++j) rowidx.push_back(pastix_int_t(offset + col_ind[j] + 1)); + for (auto j = begin; j < end; ++j) rowidx.push_back(static_cast(offset + col_ind[j] + 1)); } } - colptr[nPointDomain] = pastix_int_t(nNonZero + 1); + colptr[nPointDomain] = static_cast(nNonZero + 1); if (rowidx.size() != nNonZero) SU2_MPI::Error("Error during preparation of PaStiX data", CURRENT_FUNCTION); /*--- 4 - Perform ordering, symbolic factorization, and analysis steps ---*/ + spmInitDist(&spm, SU2_MPI::GetComm()); + spm.mtxtype = SpmGeneral; // Despite being symmetric, we store the entire matrix. + spm.flttype = std::is_same_v ? SpmDouble : SpmFloat; + spm.fmttype = SpmCSC; + spm.layout = SpmColMajor; + spm.baseval = 1; + + spm.n = nCols; + spm.nnz = nNonZero; + spm.dof = nVar; + + spm.colptr = colptr.data(); + spm.rowptr = rowidx.data(); + spm.values = values.data(); + + spm.replicated = static_cast(mpi_size == 1); + spm.loc2glob = mpi_size > 1 ? loc2glb.data() : nullptr; + spmUpdateComputedFields(&spm); + if (mpi_rank == MASTER_NODE && verb > 0) cout << endl; - iparm[IPARM_START_TASK] = API_TASK_ORDERING; - iparm[IPARM_END_TASK] = API_TASK_ANALYSE; - Run(); + if (const auto rc = pastix_task_analyze(state, &spm); rc != PASTIX_SUCCESS) { + SU2_MPI::Error("Error analyzing matrix: " + std::to_string(rc), CURRENT_FUNCTION); + } if (mpi_rank == MASTER_NODE && verb > 0) cout << " +--------------------------------------------------------------------+" << endl; @@ -208,16 +212,13 @@ void CPastixWrapper::Initialize(CGeometry* geometry, const CConfig* template void CPastixWrapper::Factorize(CGeometry* geometry, const CConfig* config, unsigned short kind_fact) { - using namespace PaStiX; - /*--- Detect a possible change of settings between direct and adjoint that requires a reset ---*/ - if (isinitialized) - if ((kind_fact == PASTIX_ILU) != (iparm[IPARM_INCOMPLETE] == API_YES)) { + if (isinitialized) { + if ((kind_fact == PASTIX_ILU) != (iparm[IPARM_INCOMPLETE] == 1)) { Clean(); - isinitialized = false; iter = 0; } - + } verb = config->GetPastixVerbLvl(); iparm[IPARM_INCOMPLETE] = (kind_fact == PASTIX_ILU); @@ -227,21 +228,16 @@ void CPastixWrapper::Factorize(CGeometry* geometry, const CConfig* c switch (verb) { case 1: - iparm[IPARM_VERBOSE] = API_VERBOSE_NO; + iparm[IPARM_VERBOSE] = PastixVerboseNo; break; case 2: - iparm[IPARM_VERBOSE] = API_VERBOSE_YES; + iparm[IPARM_VERBOSE] = PastixVerboseYes; break; default: - iparm[IPARM_VERBOSE] = API_VERBOSE_NOT; + iparm[IPARM_VERBOSE] = PastixVerboseNot; break; } - if (kind_fact == PASTIX_LDLT || kind_fact == PASTIX_LDLT_P) - iparm[IPARM_TRANSPOSE_SOLVE] = API_NO; // symmetric so no need for slower transp. solve - else - iparm[IPARM_TRANSPOSE_SOLVE] = API_YES; // negated due to CSR to CSC copy - /*--- Is factorizing needed on this iteration? ---*/ bool factorize = false; @@ -260,21 +256,21 @@ void CPastixWrapper::Factorize(CGeometry* geometry, const CConfig* c cout << " +--------------------------------------------------------------------+" << endl; } - unsigned long i, j, k, iRow, begin, target, source, szBlk = matrix.nVar * matrix.nVar, nNonZero = values.size(); + const unsigned long szBlk = matrix.nVar * matrix.nVar, nNonZero = values.size(); /*--- Copy matrix values and swap blocks as required ---*/ - for (i = 0; i < nNonZero; ++i) values[i] = SU2_TYPE::GetValue(matrix.values[i]); + for (auto i = 0ul; i < nNonZero; ++i) values[i] = SU2_TYPE::GetValue(matrix.values[i]); - for (i = 0; i < sort_rows.size(); ++i) { - iRow = sort_rows[i]; - begin = matrix.rowptr[iRow]; + for (auto i = 0ul; i < sort_rows.size(); ++i) { + const auto iRow = sort_rows[i]; + const auto begin = matrix.rowptr[iRow]; - for (j = 0; j < sort_order[i].size(); ++j) { - target = (begin + j) * szBlk; - source = sort_order[i][j] * szBlk; + for (auto j = 0ul; j < sort_order[i].size(); ++j) { + const auto target = (begin + j) * szBlk; + const auto source = sort_order[i][j] * szBlk; - for (k = 0; k < szBlk; ++k) values[target + k] = SU2_TYPE::GetValue(matrix.values[source + k]); + for (auto k = 0ul; k < szBlk; ++k) values[target + k] = SU2_TYPE::GetValue(matrix.values[source + k]); } } @@ -283,14 +279,12 @@ void CPastixWrapper::Factorize(CGeometry* geometry, const CConfig* c switch (kind_fact) { case PASTIX_LDLT: case PASTIX_LDLT_P: - iparm[IPARM_SYM] = API_SYM_YES; - iparm[IPARM_FACTORIZATION] = API_FACT_LDLT; + iparm[IPARM_FACTORIZATION] = PastixFactLDLT; break; case PASTIX_LU: case PASTIX_LU_P: case PASTIX_ILU: - iparm[IPARM_SYM] = API_SYM_NO; - iparm[IPARM_FACTORIZATION] = API_FACT_LU; + iparm[IPARM_FACTORIZATION] = PastixFactLU; break; default: SU2_MPI::Error("Unknown type of PaStiX factorization.", CURRENT_FUNCTION); @@ -299,9 +293,9 @@ void CPastixWrapper::Factorize(CGeometry* geometry, const CConfig* c /*--- Compute factorization ---*/ - iparm[IPARM_START_TASK] = API_TASK_NUMFACT; - iparm[IPARM_END_TASK] = API_TASK_NUMFACT; - Run(); + if (const auto rc = pastix_task_numfact(state, &spm); rc != PASTIX_SUCCESS) { + SU2_MPI::Error("Error factorizing matrix: " + std::to_string(rc), CURRENT_FUNCTION); + } if (mpi_rank == MASTER_NODE && verb > 0) cout << " +--------------------------------------------------------------------+" << endl << endl; diff --git a/Common/src/linear_algebra/CSysMatrix.cpp b/Common/src/linear_algebra/CSysMatrix.cpp index aea87b05cf77..1873128def23 100644 --- a/Common/src/linear_algebra/CSysMatrix.cpp +++ b/Common/src/linear_algebra/CSysMatrix.cpp @@ -601,10 +601,7 @@ void CSysMatrix::MatrixInverse(ScalarType* matrix, ScalarType* inver } template -void CSysMatrix::DeleteValsRowi(unsigned long i) { - const auto block_i = i / nVar; - const auto row = i % nVar; - +void CSysMatrix::DeleteValsRowi(unsigned long block_i, unsigned long row) { for (auto index = row_ptr[block_i]; index < row_ptr[block_i + 1]; index++) { for (auto iVar = 0u; iVar < nVar; iVar++) matrix[index * nVar * nVar + row * nVar + iVar] = 0.0; // Delete row values in the block diff --git a/Common/src/linear_algebra/CSysSolve.cpp b/Common/src/linear_algebra/CSysSolve.cpp index ae01000cf7f2..ce4543265464 100644 --- a/Common/src/linear_algebra/CSysSolve.cpp +++ b/Common/src/linear_algebra/CSysSolve.cpp @@ -25,10 +25,6 @@ * License along with SU2. If not, see . */ -#include "Eigen/Core" -#include "Eigen/Dense" -#include "Eigen/Eigenvalues" - #include "../../include/linear_algebra/CSysSolve.hpp" #include "../../include/linear_algebra/CSysSolve_b.hpp" #include "../../include/parallelization/omp_structure.hpp" @@ -38,6 +34,12 @@ #include "../../include/linear_algebra/CMatrixVectorProduct.hpp" #include "../../include/linear_algebra/CPreconditioner.hpp" +SU2_IGNORE_WARNING("-Wmaybe-uninitialized") +#include "Eigen/Core" +#include "Eigen/Dense" +#include "Eigen/Eigenvalues" +SU2_RESTORE_WARNING + #include #include #include diff --git a/Common/src/linear_algebra/CSysVector.cpp b/Common/src/linear_algebra/CSysVector.cpp index f3f682d54fe5..d14a63b52bf2 100644 --- a/Common/src/linear_algebra/CSysVector.cpp +++ b/Common/src/linear_algebra/CSysVector.cpp @@ -54,6 +54,10 @@ void CSysVector::Initialize(unsigned long numBlk, unsigned long numB d_vec_val = GPUMemoryAllocation::gpu_alloc(nElm * sizeof(ScalarType)); +#ifdef HAVE_OMP + dot_scratch.reset(new ScalarType[omp_get_max_threads()]); +#endif + if (val != nullptr) { if (!valIsArray) { for (auto i = 0ul; i < nElm; i++) vec_val[i] = *val; diff --git a/SU2_CFD/include/fluid/CDataDrivenFluid.hpp b/SU2_CFD/include/fluid/CDataDrivenFluid.hpp index 2298425802d1..47092a51f260 100644 --- a/SU2_CFD/include/fluid/CDataDrivenFluid.hpp +++ b/SU2_CFD/include/fluid/CDataDrivenFluid.hpp @@ -37,6 +37,62 @@ #endif #include "CFluidModel.hpp" +/*! + * \class MiniTable2D + * \brief Simple 2D thermodynamic table used to identify the starting point for the Newton solver. + * \author: E.C.Bunschoten. + */ +class MiniTable2D { + size_t nP{5}, + n_vars; + su2activematrix TD_data; + su2vector TD_data_min,TD_data_max; + public: + MiniTable2D()=default; + + /*! + * \brief Set the number of table nodes + * \param[in] nP_in - Number of table nodes. + */ + void SetNPoints(const size_t nP_in) { nP=nP_in; } + + /*! + * \brief Set the number of thermodynamic variables in the table. + * \param[in] n_vars_in - Number of thermodynamic variables. + */ + void SetNVars(const size_t n_vars_in) { n_vars = n_vars_in; } + + /*! + * \brief Specify the thermodynamic data at a table node. + * \param[in] iVar - Variable index. + * \param[in] iX - Table node index. + * \param[in] val_var - Thermodynamic state value. + */ + void SetTableData(const size_t iVar, const size_t iX, const su2double val_var) { + TD_data[iVar][iX] = val_var; + } + + /*! + * \brief Size table data arrays. + */ + void SizeTable(); + + /*! + * \brief Normalize thermodynamic data for regularization. + */ + void ScaleTableData(); + + /*! + * \brief Find the node in the table closest to the query. + * \param[in] iX - Index of the first thermodynamic variable. + * \param[in] val_x - Query of the first thermodynamic variable. + * \param[in] iY - Index of the second thermodynamic variable. + * \param[in] val_y - Query of the second thermodynamic variable. + * \returns Nearest neighbor index. + */ + size_t FindNode(const size_t iX, const su2double val_x, const size_t iY, const su2double val_y) const; +}; + /*! * \class CDataDrivenFluid * \brief Template class for fluid model definition using multi-layer perceptrons for @@ -51,23 +107,15 @@ class CDataDrivenFluid final : public CFluidModel { string varname_rho, /*!< \brief Controlling variable name for density. */ varname_e; /*!< \brief Controlling variable name for static energy. */ - - size_t idx_rho, /*!< \brief Interpolator index for density input. */ - idx_e; /*!< \brief Interpolator index for energy input. */ su2double Newton_Relaxation, /*!< \brief Relaxation factor for Newton solvers. */ rho_start, /*!< \brief Starting value for the density in Newton solver processes. */ e_start, /*!< \brief Starting value for the energy in Newton solver processes. */ + rho_query, + e_query, Newton_Tolerance, /*!< \brief Normalized tolerance for Newton solvers. */ rho_min, rho_max, /*!< \brief Minimum and maximum density values in data set. */ e_min, e_max; /*!< \brief Minimum and maximum energy values in data set. */ - - bool custom_init_rho{false}, - custom_init_e{false}; - su2double val_custom_init_rho, - val_custom_init_e, - rho_median, - e_median; unsigned long MaxIter_Newton; /*!< \brief Maximum number of iterations for Newton solvers. */ @@ -77,21 +125,11 @@ class CDataDrivenFluid final : public CFluidModel { d2sdedrho, /*!< \brief Entropy second derivative w.r.t. density and static energy. */ d2sdrho2; /*!< \brief Entropy second derivative w.r.t. static density. */ - su2double R_idealgas, /*!< \brief Approximated ideal gas constant. */ - Cp_idealgas, /*!< \brief Approximated ideal gas specific heat at constant pressure. */ - gamma_idealgas, /*!< \brief Approximated ideal gas specific heat ratio. */ - Cv_idealgas, /*!< \brief Approximated ideal gas specific heat at constant volume. */ - P_middle, /*!< \brief Pressure computed from the centre of the data set. */ - T_middle; /*!< \brief Temperature computed from the centre of the data set. */ - su2double Enthalpy, /*!< \brief Fluid enthalpy value [J kg^-1] */ dhdrho_e, /*!< \brief Enthalpy derivative w.r.t. density. */ dhde_rho; /*!< \brief Enthalpy derivative w.r.t. static energy. */ - vector input_names_rhoe, /*!< \brief Data-driven method input variable names of the independent variables - (density, energy). */ - output_names_rhoe; /*!< \brief Output variable names listed in the data-driven method input file name. */ - + vector output_names_rhoe; /*!< \brief Output variable names listed in the data-driven method input file name. */ vector outputs_rhoe; /*!< \brief Pointers to output variables. */ vector> dsdrhoe; /*!< \brief Entropy Jacobian terms. */ @@ -99,13 +137,18 @@ class CDataDrivenFluid final : public CFluidModel { bool use_MLP_derivatives; /*!< \brief Use physics-informed model. */ + bool display_Newton_process{false}; /*--- Class variables for the multi-layer perceptron method ---*/ #ifdef USE_MLPCPP - MLPToolbox::CLookUp_ANN* lookup_mlp; /*!< \brief Multi-layer perceptron collection. */ - MLPToolbox::CIOMap* iomap_rhoe; /*!< \brief Input-output map. */ + MLPToolbox::CLookUp_ANN *lookup_mlp; /*!< \brief Multi-layer perceptron collection. */ + MLPToolbox::CIOMap iomap_rhoe; /*!< \brief Input-output map. */ #endif vector MLP_inputs; /*!< \brief Inputs for the multi-layer perceptron look-up operation. */ + MiniTable2D coarse_TD_table; /*!< \brief Small thermodynamic table used to identify the starting point of the Newton solver processes. */ + const size_t iRho{0},iE{1},iP{2},iT{3}; /*!< Indices of thermodynamic variables in the table. */ + su2vector vals_rho_table, vals_e_table; /*!< Density and static energy values of the table nodes. */ + CLookUpTable* lookup_table; /*!< \brief Look-up table regression object. */ unsigned long LUT_idx_s, LUT_idx_dsde_rho, diff --git a/SU2_CFD/include/integration/CMultiGridIntegration.hpp b/SU2_CFD/include/integration/CMultiGridIntegration.hpp index eb2b7ded797c..eb4ba00afd84 100644 --- a/SU2_CFD/include/integration/CMultiGridIntegration.hpp +++ b/SU2_CFD/include/integration/CMultiGridIntegration.hpp @@ -133,6 +133,42 @@ class CMultiGridIntegration final : public CIntegration { void SetProlongated_Solution(unsigned short RunTime_EqSystem, CSolver *sol_fine, CSolver *sol_coarse, CGeometry *geo_fine, CGeometry *geo_coarse, CConfig *config); + + /*! + * \brief Apply post-smoothing iterations on the fine grid after prolongation. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + * \param[in] solver_fine - Pointer to the solver on the fine grid. + * \param[in] numerics_fine - Description of the numerical method on the fine grid. + * \param[in] geometry_fine - Geometrical definition of the fine grid. + * \param[in] solver_container_fine - Container with all solvers on the fine grid. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKLimit - Number of Runge-Kutta steps. + */ + void PostSmoothing(unsigned short RunTime_EqSystem, CSolver* solver_fine, CNumerics** numerics_fine, + CGeometry* geometry_fine, CSolver** solver_container_fine, CConfig *config, + unsigned short iMesh, unsigned short iRKLimit); + + /*! + * \brief Apply pre-smoothing iterations on the fine grid before restriction. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + * \param[in] geometry - Geometrical definition of the problem (all levels). + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config_container - Definition of the particular problems. + * \param[in] solver_fine - Pointer to the solver on the fine grid. + * \param[in] numerics_fine - Description of the numerical method on the fine grid. + * \param[in] geometry_fine - Geometrical definition of the fine grid. + * \param[in] solver_container_fine - Container with all solvers on the fine grid. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iZone - Index of the zone. + * \param[in] iRKLimit - Number of Runge-Kutta steps. + */ + void PreSmoothing(unsigned short RunTime_EqSystem, CGeometry**** geometry, CSolver***** solver_container, + CConfig **config_container, CSolver* solver_fine, CNumerics** numerics_fine, + CGeometry* geometry_fine, CSolver** solver_container_fine, CConfig *config, + unsigned short iMesh, unsigned short iZone, unsigned short iRKLimit); + /*! * \brief Compute the fine grid correction from the coarse solution. * \param[out] sol_fine - Pointer to the solution on the fine grid. @@ -164,8 +200,6 @@ class CMultiGridIntegration final : public CIntegration { * \param[in] geo_fine - Geometrical definition of the fine grid. * \param[in] geo_coarse - Geometrical definition of the coarse grid. * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] InclSharedDomain - Include the shared domain in the interpolation. */ void SetRestricted_Solution(unsigned short RunTime_EqSystem, CSolver *sol_fine, CSolver *sol_coarse, CGeometry *geo_fine, CGeometry *geo_coarse, CConfig *config); @@ -181,4 +215,31 @@ class CMultiGridIntegration final : public CIntegration { void Adjoint_Setup(CGeometry ****geometry, CSolver *****solver_container, CConfig **config, 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). + * \return New CFL value for the coarse grid. + */ + passivedouble computeMultigridCFL(CConfig* config, CSolver* solver_coarse, CGeometry* geometry_coarse, + unsigned short iMesh, passivedouble CFL_fine, passivedouble CFL_coarse_current); + + /*--- 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(); + }; diff --git a/SU2_CFD/include/iteration/CDiscAdjFEAIteration.hpp b/SU2_CFD/include/iteration/CDiscAdjFEAIteration.hpp index f2246f96cef3..12b4403f77dd 100644 --- a/SU2_CFD/include/iteration/CDiscAdjFEAIteration.hpp +++ b/SU2_CFD/include/iteration/CDiscAdjFEAIteration.hpp @@ -42,6 +42,9 @@ class CDiscAdjFEAIteration final : public CIteration { private: unsigned short CurrentRecording; /*!< \brief Stores the current status of the recording. */ + /*!< \brief Used for thermo elastic problems to avoid duplicating code. */ + CIteration* DiscAdjHeatIteration = nullptr; + /*! * \brief load solution for dynamic problems * \param[in] geometry - Geometrical definition of the problem. @@ -64,7 +67,7 @@ class CDiscAdjFEAIteration final : public CIteration { /*! * \brief Destructor of the class. */ - ~CDiscAdjFEAIteration(void) override; + ~CDiscAdjFEAIteration() override; /*! * \brief Preprocessing to prepare for an iteration of the physics. diff --git a/SU2_CFD/include/limiters/CLimiterDetails.hpp b/SU2_CFD/include/limiters/CLimiterDetails.hpp index 1c0b12db5576..c330e9719cf9 100644 --- a/SU2_CFD/include/limiters/CLimiterDetails.hpp +++ b/SU2_CFD/include/limiters/CLimiterDetails.hpp @@ -369,13 +369,11 @@ struct CLimiterDetails /*--- Per rank reduction. ---*/ - SU2_OMP_CRITICAL for(size_t iVar = varBegin; iVar < varEnd; ++iVar) { - sharedMin(iVar) = min(sharedMin(iVar), localMin(iVar)); - sharedMax(iVar) = max(sharedMax(iVar), localMax(iVar)); + atomicMin(localMin(iVar), sharedMin(iVar)); + atomicMax(localMax(iVar), sharedMax(iVar)); } - END_SU2_OMP_CRITICAL /*--- Global reduction. ---*/ diff --git a/SU2_CFD/include/numerics/CNumerics.hpp b/SU2_CFD/include/numerics/CNumerics.hpp index 11044a241c9d..2531f01317ca 100644 --- a/SU2_CFD/include/numerics/CNumerics.hpp +++ b/SU2_CFD/include/numerics/CNumerics.hpp @@ -35,6 +35,7 @@ #include "../../../Common/include/CConfig.hpp" #include "../../../Common/include/linear_algebra/blas_structure.hpp" +#include "../../../Common/include/toolboxes/geometry_toolbox.hpp" class CElement; class CFluidModel; @@ -46,7 +47,7 @@ class CFluidModel; */ class CNumerics { protected: - enum : size_t {MAXNDIM = 3}; /*!< \brief Max number of space dimensions, used in some static arrays. */ + static constexpr size_t MAXNDIM = 3; /*!< \brief Max number of space dimensions, used in some static arrays. */ unsigned short nDim, nVar; /*!< \brief Number of dimensions and variables. */ su2double Gamma; /*!< \brief Fluid's Gamma constant (ratio of specific heats). */ @@ -562,7 +563,7 @@ class CNumerics { NEVERINLINE static void ComputePerturbedRSM(size_t nDim, size_t uq_eigval_comp, bool uq_permute, su2double uq_delta_b, su2double uq_urlx, const Mat1& velgrad, Scalar density, Scalar viscosity, Scalar turb_ke, Mat2& MeanPerturbedRSM) { - Scalar MeanReynoldsStress[3][3]; + Scalar MeanReynoldsStress[3][3] = {{}}; ComputeStressTensor(nDim, MeanReynoldsStress, velgrad, viscosity, density, turb_ke, true); for (size_t iDim = 0; iDim < 3; iDim++) for (size_t jDim = 0; jDim < 3; jDim++) @@ -1146,15 +1147,77 @@ class CNumerics { /*! * \brief Computation of the matrix P, this matrix diagonalize the conservative Jacobians in * the form $P^{-1}(A.Normal)P=Lambda$. - * \param[in] val_density - Value of the density. - * \param[in] val_velocity - Value of the velocity. - * \param[in] val_soundspeed - Value of the sound speed. - * \param[in] val_normal - Normal vector, the norm of the vector is the area of the face. - * \param[out] val_p_tensor - Pointer to the P matrix. - */ - void GetPMatrix(const su2double *val_density, const su2double *val_velocity, - const su2double *val_soundspeed, const su2double *val_normal, - su2double **val_p_tensor) const; + * \param[in] density - Value of the density. + * \param[in] velocity - Velocity vector. + * \param[in] soundspeed - Value of the sound speed. + * \param[in] normal - Normal vector, the norm of the vector is the area of the face. + * \param[out] p_tensor - P matrix. + */ + template + void GetPMatrix(const su2double& density, const su2double* velocity, + const su2double& soundspeed, const su2double* normal, + Matrix& p_tensor) const { + const su2double rhooc = density / soundspeed; + const su2double rhoxc = density * soundspeed; + + if (nDim == 2) { + const su2double ke = 0.5 * GeometryToolbox::SquaredNorm(2, velocity); + const su2double projvel = GeometryToolbox::DotProduct(2, velocity, normal); + + p_tensor[0][0] = 1.0; + p_tensor[0][1] = 0.0; + p_tensor[0][2] = 0.5 * rhooc; + p_tensor[0][3] = 0.5 * rhooc; + + p_tensor[1][0] = velocity[0]; + p_tensor[1][1] = density * normal[1]; + p_tensor[1][2] = 0.5 * (velocity[0] * rhooc + normal[0] * density); + p_tensor[1][3] = 0.5 * (velocity[0] * rhooc - normal[0] * density); + + p_tensor[2][0] = velocity[1]; + p_tensor[2][1] = -density * normal[0]; + p_tensor[2][2] = 0.5 * (velocity[1] * rhooc + normal[1] * density); + p_tensor[2][3] = 0.5 * (velocity[1] * rhooc - normal[1] * density); + + p_tensor[3][0] = ke; + p_tensor[3][1] = density * (velocity[0] * normal[1] - velocity[1] * normal[0]); + p_tensor[3][2] = 0.5 * (ke * rhooc + density * projvel + rhoxc / Gamma_Minus_One); + p_tensor[3][3] = 0.5 * (ke * rhooc - density * projvel + rhoxc / Gamma_Minus_One); + } else { + const su2double ke = 0.5 * GeometryToolbox::SquaredNorm(3, velocity); + const su2double projvel = GeometryToolbox::DotProduct(3, velocity, normal); + + p_tensor[0][0] = normal[0]; + p_tensor[0][1] = normal[1]; + p_tensor[0][2] = normal[2]; + p_tensor[0][3] = 0.5 * rhooc; + p_tensor[0][4] = 0.5 * rhooc; + + p_tensor[1][0] = velocity[0] * normal[0]; + p_tensor[1][1] = velocity[0] * normal[1] - density * normal[2]; + p_tensor[1][2] = velocity[0] * normal[2] + density * normal[1]; + p_tensor[1][3] = 0.5 * (velocity[0] * rhooc + density * normal[0]); + p_tensor[1][4] = 0.5 * (velocity[0] * rhooc - density * normal[0]); + + p_tensor[2][0] = velocity[1] * normal[0] + density * normal[2]; + p_tensor[2][1] = velocity[1] * normal[1]; + p_tensor[2][2] = velocity[1] * normal[2] - density * normal[0]; + p_tensor[2][3] = 0.5 * (velocity[1] * rhooc + density * normal[1]); + p_tensor[2][4] = 0.5 * (velocity[1] * rhooc - density * normal[1]); + + p_tensor[3][0] = velocity[2] * normal[0] - density * normal[1]; + p_tensor[3][1] = velocity[2] * normal[1] + density * normal[0]; + p_tensor[3][2] = velocity[2] * normal[2]; + p_tensor[3][3] = 0.5 * (velocity[2] * rhooc + density * normal[2]); + p_tensor[3][4] = 0.5 * (velocity[2] * rhooc - density * normal[2]); + + p_tensor[4][0] = ke * normal[0] + density * (velocity[1] * normal[2] - velocity[2] * normal[1]); + p_tensor[4][1] = ke * normal[1] + density * (velocity[2] * normal[0] - velocity[0] * normal[2]); + p_tensor[4][2] = ke * normal[2] + density * (velocity[0] * normal[1] - velocity[1] * normal[0]); + p_tensor[4][3] = 0.5 * (ke * rhooc + density * projvel + rhoxc / Gamma_Minus_One); + p_tensor[4][4] = 0.5 * (ke * rhooc - density * projvel + rhoxc / Gamma_Minus_One); + } + } /*! * \brief Computation of the matrix Rinv*Pe. @@ -1261,15 +1324,83 @@ class CNumerics { /*! * \brief Computation of the matrix P^{-1}, this matrix diagonalize the conservative Jacobians * in the form $P^{-1}(A.Normal)P=Lambda$. - * \param[in] val_density - Value of the density. - * \param[in] val_velocity - Value of the velocity. - * \param[in] val_soundspeed - Value of the sound speed. - * \param[in] val_normal - Normal vector, the norm of the vector is the area of the face. - * \param[out] val_invp_tensor - Pointer to inverse of the P matrix. - */ - void GetPMatrix_inv(const su2double *val_density, const su2double *val_velocity, - const su2double *val_soundspeed, const su2double *val_normal, - su2double **val_invp_tensor) const; + * \param[in] density - Value of the density. + * \param[in] velocity - Velocity vector. + * \param[in] soundspeed - Value of the sound speed. + * \param[in] normal - Normal vector, the norm of the vector is the area of the face. + * \param[out] inv_p_tensor - Pointer to inverse of the P matrix. + */ + template + void GetPMatrix_inv(const su2double& density, const su2double* velocity, + const su2double& soundspeed, const su2double* normal, + Matrix& inv_p_tensor) const { + const su2double rhoxc = density * soundspeed; + const su2double c2 = pow(soundspeed, 2); + const su2double gm1 = Gamma_Minus_One; + const su2double k0orho = normal[0] / density; + const su2double k1orho = normal[1] / density; + const su2double gm1_o_c2 = gm1 / c2; + const su2double gm1_o_rhoxc = gm1 / rhoxc; + + if (nDim == 3) { + const su2double k2orho = normal[2] / density; + const su2double ke = 0.5 * GeometryToolbox::SquaredNorm(3, velocity); + const su2double projvel_o_rho = GeometryToolbox::DotProduct(3, velocity, normal) / density; + + inv_p_tensor[0][0] = normal[0] + k1orho * velocity[2] - k2orho * velocity[1] - normal[0] * gm1_o_c2 * ke; + inv_p_tensor[0][1] = normal[0] * gm1_o_c2 * velocity[0]; + inv_p_tensor[0][2] = k2orho + normal[0] * gm1_o_c2 * velocity[1]; + inv_p_tensor[0][3] = -k1orho + normal[0] * gm1_o_c2 * velocity[2]; + inv_p_tensor[0][4] = -normal[0] * gm1_o_c2; + + inv_p_tensor[1][0] = normal[1] + k2orho * velocity[0] - k0orho * velocity[2] - normal[1] * gm1_o_c2 * ke; + inv_p_tensor[1][1] = -k2orho + normal[1] * gm1_o_c2 * velocity[0]; + inv_p_tensor[1][2] = normal[1] * gm1_o_c2 * velocity[1]; + inv_p_tensor[1][3] = k0orho + normal[1] * gm1_o_c2 * velocity[2]; + inv_p_tensor[1][4] = -normal[1] * gm1_o_c2; + + inv_p_tensor[2][0] = normal[2] + k0orho * velocity[1] - k1orho * velocity[0] - normal[2] * gm1_o_c2 * ke; + inv_p_tensor[2][1] = k1orho + normal[2] * gm1_o_c2 * velocity[0]; + inv_p_tensor[2][2] = -k0orho + normal[2] * gm1_o_c2 * velocity[1]; + inv_p_tensor[2][3] = normal[2] * gm1_o_c2 * velocity[2]; + inv_p_tensor[2][4] = -normal[2] * gm1_o_c2; + + inv_p_tensor[3][0] = -projvel_o_rho + gm1_o_rhoxc * ke; + inv_p_tensor[3][1] = k0orho - gm1_o_rhoxc * velocity[0]; + inv_p_tensor[3][2] = k1orho - gm1_o_rhoxc * velocity[1]; + inv_p_tensor[3][3] = k2orho - gm1_o_rhoxc * velocity[2]; + inv_p_tensor[3][4] = gm1_o_rhoxc; + + inv_p_tensor[4][0] = projvel_o_rho + gm1_o_rhoxc * ke; + inv_p_tensor[4][1] = -k0orho - gm1_o_rhoxc * velocity[0]; + inv_p_tensor[4][2] = -k1orho - gm1_o_rhoxc * velocity[1]; + inv_p_tensor[4][3] = -k2orho - gm1_o_rhoxc * velocity[2]; + inv_p_tensor[4][4] = gm1_o_rhoxc; + } else { + const su2double ke = 0.5 * GeometryToolbox::SquaredNorm(2, velocity); + const su2double projvel_o_rho = GeometryToolbox::DotProduct(2, velocity, normal) / density; + + inv_p_tensor[0][0] = 1 - gm1_o_c2 * ke; + inv_p_tensor[0][1] = gm1_o_c2 * velocity[0]; + inv_p_tensor[0][2] = gm1_o_c2 * velocity[1]; + inv_p_tensor[0][3] = -gm1_o_c2; + + inv_p_tensor[1][0] = -k1orho * velocity[0] + k0orho * velocity[1]; + inv_p_tensor[1][1] = k1orho; + inv_p_tensor[1][2] = -k0orho; + inv_p_tensor[1][3] = 0; + + inv_p_tensor[2][0] = -projvel_o_rho + gm1_o_rhoxc * ke; + inv_p_tensor[2][1] = k0orho - gm1_o_rhoxc * velocity[0]; + inv_p_tensor[2][2] = k1orho - gm1_o_rhoxc * velocity[1]; + inv_p_tensor[2][3] = gm1_o_rhoxc; + + inv_p_tensor[3][0] = projvel_o_rho + gm1_o_rhoxc * ke; + inv_p_tensor[3][1] = -k0orho - gm1_o_rhoxc * velocity[0]; + inv_p_tensor[3][2] = -k1orho - gm1_o_rhoxc * velocity[1]; + inv_p_tensor[3][3] = gm1_o_rhoxc; + } + } /*! * \brief Compute viscous residual and jacobian. diff --git a/SU2_CFD/include/numerics/NEMO/convection/msw.hpp b/SU2_CFD/include/numerics/NEMO/convection/msw.hpp index 28e7b7e839d2..f968e63c17f6 100644 --- a/SU2_CFD/include/numerics/NEMO/convection/msw.hpp +++ b/SU2_CFD/include/numerics/NEMO/convection/msw.hpp @@ -38,6 +38,8 @@ */ class CUpwMSW_NEMO : public CNEMONumerics { private: + const su2double alpha; + su2double *Diff_U; su2double *ust_i, *ust_j; su2double *Fc_i, *Fc_j; diff --git a/SU2_CFD/include/numerics/elasticity/CFEAElasticity.hpp b/SU2_CFD/include/numerics/elasticity/CFEAElasticity.hpp index c3a13b058e4f..7e98680a40bc 100644 --- a/SU2_CFD/include/numerics/elasticity/CFEAElasticity.hpp +++ b/SU2_CFD/include/numerics/elasticity/CFEAElasticity.hpp @@ -27,6 +27,7 @@ #pragma once +#include #include "../CNumerics.hpp" #include "../../../../Common/include/geometry/elements/CElement.hpp" @@ -61,23 +62,17 @@ class CFEAElasticity : public CNumerics { su2double Kappa = 0.0; /*!< \brief Aux. variable, Compressibility constant. */ su2double ThermalStressTerm = 0.0; /*!< \brief Aux. variable, Relationship between stress and delta T. */ - su2double *E_i = nullptr; /*!< \brief Young's modulus of elasticity. */ - su2double *Nu_i = nullptr; /*!< \brief Poisson's ratio. */ - su2double *Rho_s_i = nullptr; /*!< \brief Structural density. */ - su2double *Rho_s_DL_i = nullptr; /*!< \brief Structural density (for dead loads). */ - su2double *Alpha_i = nullptr; /*!< \brief Thermal expansion coefficient. */ + std::unique_ptr E_i; /*!< \brief Young's modulus of elasticity. */ + std::unique_ptr Nu_i; /*!< \brief Poisson's ratio. */ + std::unique_ptr Rho_s_i; /*!< \brief Structural density. */ + std::unique_ptr Rho_s_DL_i; /*!< \brief Structural density (for dead loads). */ + std::unique_ptr Alpha_i; /*!< \brief Thermal expansion coefficient. */ su2double ReferenceTemperature = 0.0; /*!< \brief Reference temperature for thermal expansion. */ - su2double **Ba_Mat = nullptr; /*!< \brief Matrix B for node a - Auxiliary. */ - su2double **Bb_Mat = nullptr; /*!< \brief Matrix B for node b - Auxiliary. */ - su2double *Ni_Vec = nullptr; /*!< \brief Vector of shape functions - Auxiliary. */ - su2double **D_Mat = nullptr; /*!< \brief Constitutive matrix - Auxiliary. */ - su2double **KAux_ab = nullptr; /*!< \brief Node ab stiffness matrix - Auxiliary. */ - su2double **GradNi_Ref_Mat = nullptr; /*!< \brief Gradients of Ni - Auxiliary. */ - su2double **GradNi_Curr_Mat = nullptr; /*!< \brief Gradients of Ni - Auxiliary. */ + su2double D_Mat[DIM_STRAIN_3D][DIM_STRAIN_3D]; /*!< \brief Constitutive matrix - Auxiliary. */ - su2double *DV_Val = nullptr; /*!< \brief For optimization cases, value of the design variables. */ + std::unique_ptr DV_Val; /*!< \brief For optimization cases, value of the design variables. */ unsigned short n_DV = 0; /*!< \brief For optimization cases, number of design variables. */ bool plane_stress = false; /*!< \brief Checks if we are solving a plane stress case. */ @@ -97,11 +92,6 @@ class CFEAElasticity : public CNumerics { */ CFEAElasticity(unsigned short val_nDim, unsigned short val_nVar, const CConfig *config); - /*! - * \brief Destructor of the class. - */ - ~CFEAElasticity(void) override; - /*! * \brief Set elasticity modulus and Poisson ratio. * \param[in] iVal - Index of the property. @@ -245,4 +235,25 @@ class CFEAElasticity : public CNumerics { return static_cast(iVar == jVar); } + template + void FillBMat(unsigned short iNode, const Mat1& GradNi_Mat, Mat2& B_Mat) const { + if (nDim == 2) { + B_Mat[0][0] = GradNi_Mat[iNode][0]; + B_Mat[1][1] = GradNi_Mat[iNode][1]; + B_Mat[2][0] = GradNi_Mat[iNode][1]; + B_Mat[2][1] = GradNi_Mat[iNode][0]; + } + else { + B_Mat[0][0] = GradNi_Mat[iNode][0]; + B_Mat[1][1] = GradNi_Mat[iNode][1]; + B_Mat[2][2] = GradNi_Mat[iNode][2]; + B_Mat[3][0] = GradNi_Mat[iNode][1]; + B_Mat[3][1] = GradNi_Mat[iNode][0]; + B_Mat[4][0] = GradNi_Mat[iNode][2]; + B_Mat[4][2] = GradNi_Mat[iNode][0]; + B_Mat[5][1] = GradNi_Mat[iNode][2]; + B_Mat[5][2] = GradNi_Mat[iNode][1]; + } + } + }; diff --git a/SU2_CFD/include/numerics/elasticity/CFEALinearElasticity.hpp b/SU2_CFD/include/numerics/elasticity/CFEALinearElasticity.hpp index 8eae5ee49e68..62d27a17a87c 100644 --- a/SU2_CFD/include/numerics/elasticity/CFEALinearElasticity.hpp +++ b/SU2_CFD/include/numerics/elasticity/CFEALinearElasticity.hpp @@ -55,11 +55,6 @@ class CFEALinearElasticity : public CFEAElasticity { */ CFEALinearElasticity(unsigned short val_nDim, unsigned short val_nVar, const CConfig *config); - /*! - * \brief Destructor of the class. - */ - ~CFEALinearElasticity(void) override = default; - /*! * \brief Build the tangent stiffness matrix of an element. * \param[in,out] element_container - Element whose tangent matrix is being built. @@ -110,11 +105,6 @@ class CFEAMeshElasticity final : public CFEALinearElasticity { */ CFEAMeshElasticity(unsigned short val_nDim, unsigned short val_nVar, unsigned long val_nElem, const CConfig *config); - /*! - * \brief Destructor of the class. - */ - ~CFEAMeshElasticity(void) override = default; - /*! * \brief Set the element-based local Young's modulus in mesh problems * \param[in] iElem - Element index. diff --git a/SU2_CFD/include/numerics/elasticity/CFEANonlinearElasticity.hpp b/SU2_CFD/include/numerics/elasticity/CFEANonlinearElasticity.hpp index ed97b3e28255..bad33c51b345 100644 --- a/SU2_CFD/include/numerics/elasticity/CFEANonlinearElasticity.hpp +++ b/SU2_CFD/include/numerics/elasticity/CFEANonlinearElasticity.hpp @@ -43,15 +43,9 @@ class CFEANonlinearElasticity : public CFEAElasticity { protected: - su2double **F_Mat; /*!< \brief Deformation gradient. */ - su2double **b_Mat; /*!< \brief Left Cauchy-Green Tensor. */ - su2double **currentCoord; /*!< \brief Current coordinates. */ - su2double **Stress_Tensor; /*!< \brief Cauchy stress tensor */ - - su2double **FmT_Mat; /*!< \brief Deformation gradient inverse and transpose. */ - - su2double **KAux_P_ab; /*!< \brief Auxiliar matrix for the pressure term */ - su2double *KAux_t_a; /*!< \brief Auxiliar matrix for the pressure term */ + su2double F_Mat[MAXNDIM][MAXNDIM]; /*!< \brief Deformation gradient. */ + su2double b_Mat[MAXNDIM][MAXNDIM]; /*!< \brief Left Cauchy-Green Tensor. */ + su2double Stress_Tensor[MAXNDIM][MAXNDIM]; su2double J_F; /*!< \brief Jacobian of the transformation (determinant of F) */ @@ -59,23 +53,19 @@ class CFEANonlinearElasticity : public CFEAElasticity { bool nearly_incompressible; /*!< \brief Boolean to consider nearly_incompressible effects */ - su2double **F_Mat_Iso; /*!< \brief Isocoric component of the deformation gradient. */ - su2double **b_Mat_Iso; /*!< \brief Isocoric component of the left Cauchy-Green tensor. */ - - su2double C10, D1; /*!< \brief C10 = Mu/2. D1 = Kappa/2. */ - su2double J_F_Iso; /*!< \brief J_F_Iso: det(F)^-1/3. */ + su2double b_Mat_Iso[MAXNDIM][MAXNDIM]; /*!< \brief Isocoric component of the left Cauchy-Green tensor. */ su2double cijkl[3][3][3][3]; /*!< \brief Constitutive tensor i,j,k,l (defined only for incompressibility - near inc.). */ bool maxwell_stress; /*!< \brief Consider the effects of the dielectric loads */ - su2double *EField_Ref_Unit, /*!< \brief Electric Field, unitary, in the reference configuration. */ - *EField_Ref_Mod; /*!< \brief Electric Field, modulus, in the reference configuration. */ - su2double *EField_Curr_Unit; /*!< \brief Auxiliary vector for the unitary Electric Field in the current configuration. */ + std::unique_ptr EField_Ref_Unit; /*!< \brief Electric Field, unitary, in the reference configuration. */ + std::unique_ptr EField_Ref_Mod; /*!< \brief Electric Field, modulus, in the reference configuration. */ + std::unique_ptr EField_Curr_Unit; /*!< \brief Auxiliary vector for the unitary Electric Field in the current configuration. */ unsigned short nElectric_Field, nDim_Electric_Field; - su2double *ke_DE_i; /*!< \brief Electric Constant for Dielectric Elastomers. */ + std::unique_ptr ke_DE_i; /*!< \brief Electric Constant for Dielectric Elastomers. */ su2double ke_DE; /*!< \brief Electric Constant for Dielectric Elastomers. */ su2double EFieldMod_Ref; /*!< \brief Modulus of the electric field in the reference configuration. */ @@ -94,11 +84,6 @@ class CFEANonlinearElasticity : public CFEAElasticity { */ CFEANonlinearElasticity(unsigned short val_nDim, unsigned short val_nVar, const CConfig *config); - /*! - * \brief Destructor of the class. - */ - ~CFEANonlinearElasticity(void) override; - /*! * \brief Set element electric field. * \param[in] i_DV - Index of the variable. @@ -161,9 +146,48 @@ class CFEANonlinearElasticity : public CFEAElasticity { void SetElectric_Properties(const CElement *element_container, const CConfig *config); /*! - * \brief TODO: Describe what this does. + * \brief Computes b_Mat. + */ + void ComputeLeftCauchyGreenTensor() { + for (unsigned short iVar = 0; iVar < MAXNDIM; iVar++) { + for (unsigned short jVar = 0; jVar < MAXNDIM; jVar++) { + b_Mat[iVar][jVar] = 0; + for (unsigned short kVar = 0; kVar < MAXNDIM; kVar++) { + b_Mat[iVar][jVar] += F_Mat[iVar][kVar]*F_Mat[jVar][kVar]; + } + } + } + } + + /*! + * \brief Computes the determinant of the deformation gradient. + */ + void ComputeJ_F() { + J_F = F_Mat[0][0]*F_Mat[1][1]*F_Mat[2][2]+ + F_Mat[0][1]*F_Mat[1][2]*F_Mat[2][0]+ + F_Mat[0][2]*F_Mat[1][0]*F_Mat[2][1]- + F_Mat[0][2]*F_Mat[1][1]*F_Mat[2][0]- + F_Mat[1][2]*F_Mat[2][1]*F_Mat[0][0]- + F_Mat[2][2]*F_Mat[0][1]*F_Mat[1][0]; + } + + /*! + * \brief Computes the deformation gradient transpose inverse. */ - void Compute_FmT_Mat(void); + template + void Compute_FmT_Mat(const Mat& F_Mat, const su2double& J_F, Mat& FmT_Mat) const { + FmT_Mat[0][0] = (F_Mat[1][1]*F_Mat[2][2] - F_Mat[1][2]*F_Mat[2][1]) / J_F; + FmT_Mat[0][1] = (F_Mat[1][2]*F_Mat[2][0] - F_Mat[2][2]*F_Mat[1][0]) / J_F; + FmT_Mat[0][2] = (F_Mat[1][0]*F_Mat[2][1] - F_Mat[1][1]*F_Mat[2][0]) / J_F; + + FmT_Mat[1][0] = (F_Mat[0][2]*F_Mat[2][1] - F_Mat[0][1]*F_Mat[2][2]) / J_F; + FmT_Mat[1][1] = (F_Mat[0][0]*F_Mat[2][2] - F_Mat[2][0]*F_Mat[0][2]) / J_F; + FmT_Mat[1][2] = (F_Mat[0][1]*F_Mat[2][1] - F_Mat[0][0]*F_Mat[2][0]) / J_F; + + FmT_Mat[2][0] = (F_Mat[0][1]*F_Mat[1][2] - F_Mat[0][2]*F_Mat[1][1]) / J_F; + FmT_Mat[2][1] = (F_Mat[0][2]*F_Mat[1][0] - F_Mat[0][0]*F_Mat[1][2]) / J_F; + FmT_Mat[2][2] = (F_Mat[0][0]*F_Mat[1][1] - F_Mat[0][1]*F_Mat[1][0]) / J_F; + } /*! * \brief TODO: Describe what this does. diff --git a/SU2_CFD/include/numerics/elasticity/nonlinear_models.hpp b/SU2_CFD/include/numerics/elasticity/nonlinear_models.hpp index e57521cea0f8..3cea87dcac5a 100644 --- a/SU2_CFD/include/numerics/elasticity/nonlinear_models.hpp +++ b/SU2_CFD/include/numerics/elasticity/nonlinear_models.hpp @@ -48,11 +48,6 @@ class CFEM_NeoHookean_Comp final : public CFEANonlinearElasticity { */ CFEM_NeoHookean_Comp(unsigned short val_nDim, unsigned short val_nVar, const CConfig *config); - /*! - * \brief Destructor of the class. - */ - ~CFEM_NeoHookean_Comp(void) override = default; - private: /*! * \brief Compute the plane stress term. @@ -100,11 +95,6 @@ class CFEM_Knowles_NearInc final : public CFEANonlinearElasticity { */ CFEM_Knowles_NearInc(unsigned short val_nDim, unsigned short val_nVar, const CConfig *config); - /*! - * \brief Destructor of the class. - */ - ~CFEM_Knowles_NearInc(void) override = default; - private: /*! * \brief Compute the plane stress term. @@ -150,11 +140,6 @@ class CFEM_DielectricElastomer final : public CFEANonlinearElasticity { */ CFEM_DielectricElastomer(unsigned short val_nDim, unsigned short val_nVar, const CConfig *config); - /*! - * \brief Destructor of the class. - */ - ~CFEM_DielectricElastomer(void) override = default; - private: /*! * \brief Compute the plane stress term. @@ -202,11 +187,6 @@ class CFEM_IdealDE final : public CFEANonlinearElasticity { */ CFEM_IdealDE(unsigned short val_nDim, unsigned short val_nVar, const CConfig *config); - /*! - * \brief Destructor of the class. - */ - ~CFEM_IdealDE(void) override = default; - private: /*! * \brief Compute the plane stress term. diff --git a/SU2_CFD/include/numerics/flow/convection/fvs.hpp b/SU2_CFD/include/numerics/flow/convection/fvs.hpp index 32952ee54fc7..f3afb2dfb55c 100644 --- a/SU2_CFD/include/numerics/flow/convection/fvs.hpp +++ b/SU2_CFD/include/numerics/flow/convection/fvs.hpp @@ -38,15 +38,16 @@ */ class CUpwMSW_Flow final : public CNumerics { private: - bool implicit; - su2double *u_i, *u_j, *ust_i, *ust_j; - su2double *Fc_i, *Fc_j; - su2double *Lambda_i, *Lambda_j; - su2double *Vst_i, *Vst_j, *Velst_i, *Velst_j; - su2double **P_Tensor, **invP_Tensor; + static constexpr auto MAXNVAR = MAXNDIM + 2; - su2double** Jacobian_i; /*!< \brief The Jacobian w.r.t. point i after computation. */ - su2double** Jacobian_j; /*!< \brief The Jacobian w.r.t. point j after computation. */ + const su2double alpha; + const bool dynamic_grid; + + su2double buf_Jacobian_i[MAXNVAR * MAXNVAR], buf_Jacobian_j[MAXNVAR * MAXNVAR]; + su2double* Jacobian_i[MAXNVAR]; /*!< \brief The Jacobian w.r.t. point i after computation. */ + su2double* Jacobian_j[MAXNVAR]; /*!< \brief The Jacobian w.r.t. point j after computation. */ + + su2double Fc[MAXNVAR]; public: /*! @@ -57,11 +58,6 @@ class CUpwMSW_Flow final : public CNumerics { */ CUpwMSW_Flow(unsigned short val_nDim, unsigned short val_nVar, const CConfig* config); - /*! - * \brief Destructor of the class. - */ - ~CUpwMSW_Flow(void) override; - /*! * \brief Compute the Roe's flux between two nodes i and j. * \param[in] config - Definition of the particular problem. diff --git a/SU2_CFD/include/numerics_simd/CNumericsSIMD.cpp b/SU2_CFD/include/numerics_simd/CNumericsSIMD.cpp index 09e71002f8ae..5da61a28279c 100644 --- a/SU2_CFD/include/numerics_simd/CNumericsSIMD.cpp +++ b/SU2_CFD/include/numerics_simd/CNumericsSIMD.cpp @@ -28,7 +28,7 @@ */ #include "CNumericsSIMD.hpp" -#include "flow/convection/roe.hpp" +#include "flow/convection/upwind.hpp" #include "flow/convection/centered.hpp" #include "flow/diffusion/viscous_fluxes.hpp" @@ -44,6 +44,9 @@ CNumericsSIMD* createUpwindIdealNumerics(const CConfig& config, int iMesh, const case UPWIND::ROE: obj = new CRoeScheme(config, iMesh, turbVars); break; + case UPWIND::MSW: + obj = new CMSWScheme(config, iMesh, turbVars); + break; default: break; } diff --git a/SU2_CFD/include/numerics_simd/flow/convection/common.hpp b/SU2_CFD/include/numerics_simd/flow/convection/common.hpp index 951555b734ac..9548414c3218 100644 --- a/SU2_CFD/include/numerics_simd/flow/convection/common.hpp +++ b/SU2_CFD/include/numerics_simd/flow/convection/common.hpp @@ -406,7 +406,7 @@ template FORCEINLINE VectorDbl inviscidProjFlux(const PrimVarType& V, const ConsVarType& U, const VectorDbl& normal) { - static_assert(ConsVarType::nVar == nDim+2,""); + static_assert(ConsVarType::nVar == nDim+2); Double mdot = dot(U.momentum(), normal); VectorDbl flux; flux(0) = mdot; diff --git a/SU2_CFD/include/numerics_simd/flow/convection/roe.hpp b/SU2_CFD/include/numerics_simd/flow/convection/upwind.hpp similarity index 63% rename from SU2_CFD/include/numerics_simd/flow/convection/roe.hpp rename to SU2_CFD/include/numerics_simd/flow/convection/upwind.hpp index 8b2bc64ea1fa..da63d5e8b87e 100644 --- a/SU2_CFD/include/numerics_simd/flow/convection/roe.hpp +++ b/SU2_CFD/include/numerics_simd/flow/convection/upwind.hpp @@ -1,5 +1,5 @@ /*! - * \file roe.hpp + * \file upwind.hpp * \brief Roe-family of convective schemes. * \author P. Gomes, A. Bueno, F. Palacios * \version 8.4.0 "Harrier" @@ -35,29 +35,27 @@ #include "../../../../../Common/include/geometry/CGeometry.hpp" /*! - * \class CRoeBase + * \class CUpwindBase * \ingroup ConvDiscr - * \brief Base class for Roe schemes, derived classes implement - * the dissipation term in a const "finalizeFlux" method. + * \brief Base class for upwind schemes, derived classes implement + * details of the convective flux in a const "finalizeFlux" method. * A base class implementing "viscousTerms" is accepted as template parameter. * Similarly to derived, that method should update the flux and Jacobians, but - * whereas "finalizeFlux" is passed data prepared by CRoeBase, "viscousTerms" + * whereas "finalizeFlux" is passed data prepared by CUpwindBase, "viscousTerms" * takes the same input arguments as "ComputeFlux", i.e. it can fetch more * data from CVariable. Derived is meant to implement small details, * Base is meant to do heavy lifting. */ template -class CRoeBase : public Base { +class CUpwindBase : public Base { protected: using Base::nDim; static constexpr size_t nVar = CCompressibleConservatives::nVar; static constexpr size_t nPrimVarGrad = nDim+4; static constexpr size_t nPrimVar = Max(Base::nPrimVar, nPrimVarGrad); - const su2double kappa; const su2double gamma; const su2double gasConst; - const su2double entropyFix; const bool finestGrid; const bool dynamicGrid; const bool muscl; @@ -68,11 +66,9 @@ class CRoeBase : public Base { * \brief Constructor, store some constants and forward args to base. */ template - CRoeBase(const CConfig& config, unsigned iMesh, Ts&... args) : Base(config, iMesh, args...), - kappa(config.GetRoe_Kappa()), + CUpwindBase(const CConfig& config, unsigned iMesh, Ts&... args) : Base(config, iMesh, args...), gamma(config.GetGamma()), gasConst(config.GetGas_ConstantND()), - entropyFix(config.GetEntropyFix_Coeff()), finestGrid(iMesh == MESH_0), dynamicGrid(config.GetDynamic_Grid()), muscl(finestGrid && config.GetMUSCL_Flow()), @@ -131,14 +127,84 @@ class CRoeBase : public Base { U.i = compressibleConservatives(V.i); U.j = compressibleConservatives(V.j); - /*--- Roe averaged variables. ---*/ + /*--- Finalize in derived class (static polymorphism). ---*/ - auto roeAvg = roeAveragedVariables(gamma, V, unitNormal); + const auto derived = static_cast(this); + VectorDbl flux; + MatrixDbl jac_i, jac_j; + derived->finalizeFlux(flux, jac_i, jac_j, implicit, area, unitNormal, + normal, V, U, iPoint, jPoint, solution, geometry); - /*--- P tensor. ---*/ + /*--- Add the contributions from the base class (static decorator). ---*/ - auto pMat = pMatrix(gamma, roeAvg.density, roeAvg.velocity, - roeAvg.projVel, roeAvg.speedSound, unitNormal); + Base::viscousTerms(iEdge, iPoint, jPoint, V1st, solution_, vector_ij, geometry, + config, area, unitNormal, implicit, flux, jac_i, jac_j); + + /*--- Stop preaccumulation. ---*/ + + stopPreacc(flux); + + /*--- Update the vector and system matrix. ---*/ + + updateLinearSystem(iEdge, iPoint, jPoint, implicit, updateType, + updateMask, flux, jac_i, jac_j, vector, matrix); + } +}; + +/*! + * \class CRoeScheme + * \ingroup ConvDiscr + * \brief Classical Roe scheme. + */ +template +class CRoeScheme : public CUpwindBase, Decorator> { +private: + using Base = CUpwindBase, Decorator>; + using Base::nDim; + using Base::nVar; + using Base::nPrimVarGrad; + using Base::nPrimVar; + + const su2double kappa; + const su2double entropyFix; + const ENUM_ROELOWDISS typeDissip; + using Base::gamma; + using Base::gasConst; + using Base::dynamicGrid; + +public: + /*! + * \brief Constructor, store some constants and forward to base. + */ + template + CRoeScheme(const CConfig& config, Ts&... args) : Base(config, args...), + kappa(config.GetRoe_Kappa()), + entropyFix(config.GetEntropyFix_Coeff()), + typeDissip(static_cast(config.GetKind_RoeLowDiss())) { + } + + /*! + * \brief Updates flux and Jacobians with standard Roe dissipation. + * \note "Ts" is here just in case other schemes in the family need extra args. + */ + template + FORCEINLINE void finalizeFlux(VectorDbl& flux, + MatrixDbl& jac_i, + MatrixDbl& jac_j, + bool implicit, + Double area, + const VectorDbl& unitNormal, + const VectorDbl& normal, + const CPair& V, + const CPair& U, + Int iPoint, + Int jPoint, + const CEulerVariable& solution, + const CGeometry& geometry, + Ts&...) const { + /*--- Roe averaged variables. ---*/ + + auto roeAvg = roeAveragedVariables(gamma, V, unitNormal); /*--- Grid motion. ---*/ @@ -172,12 +238,9 @@ class CRoeBase : public Base { auto flux_i = inviscidProjFlux(V.i, U.i, normal); auto flux_j = inviscidProjFlux(V.j, U.j, normal); - VectorDbl flux; for (size_t iVar = 0; iVar < nVar; ++iVar) { flux(iVar) = 0.5 * (flux_i(iVar) + flux_j(iVar)); } - - MatrixDbl jac_i, jac_j; if (implicit) { jac_i = inviscidProjJac(gamma, V.i.velocity(), U.i.energy(), normal, kappa); jac_j = inviscidProjJac(gamma, V.j.velocity(), U.j.energy(), normal, kappa); @@ -197,56 +260,81 @@ class CRoeBase : public Base { } } - /*--- Finalize in derived class (static polymorphism). ---*/ + /*--- P tensor. ---*/ - const auto derived = static_cast(this); + auto pMat = pMatrix(gamma, roeAvg.density, roeAvg.velocity, + roeAvg.projVel, roeAvg.speedSound, unitNormal); + + /*--- Inverse P tensor. ---*/ - derived->finalizeFlux(flux, jac_i, jac_j, implicit, area, unitNormal, V, - U, roeAvg, lambda, pMat, iPoint, jPoint, solution); + auto pMatInv = pMatrixInv(gamma, roeAvg.density, roeAvg.velocity, + roeAvg.projVel, roeAvg.speedSound, unitNormal); - /*--- Add the contributions from the base class (static decorator). ---*/ + /*--- Diference between conservative variables at jPoint and iPoint. ---*/ - Base::viscousTerms(iEdge, iPoint, jPoint, V1st, solution_, vector_ij, geometry, - config, area, unitNormal, implicit, flux, jac_i, jac_j); + VectorDbl deltaU; + for (size_t iVar = 0; iVar < nVar; ++iVar) { + deltaU(iVar) = U.j.all(iVar) - U.i.all(iVar); + } - /*--- Stop preaccumulation. ---*/ + /*--- Dissipation terms. ---*/ - stopPreacc(flux); + Double dissipation = roeDissipation(iPoint, jPoint, typeDissip, solution); - /*--- Update the vector and system matrix. ---*/ + for (size_t iVar = 0; iVar < nVar; ++iVar) { + for (size_t jVar = 0; jVar < nVar; ++jVar) { + /*--- Compute |projModJacTensor| = P x |Lambda| x P^-1. ---*/ - updateLinearSystem(iEdge, iPoint, jPoint, implicit, updateType, - updateMask, flux, jac_i, jac_j, vector, matrix); + Double projModJacTensor = 0.0; + for (size_t kVar = 0; kVar < nVar; ++kVar) { + projModJacTensor += pMat(iVar,kVar) * lambda(kVar) * pMatInv(kVar,jVar); + } + + Double dDdU = projModJacTensor * (1-kappa) * area * dissipation; + + /*--- Update flux and Jacobians. ---*/ + + flux(iVar) -= dDdU * deltaU(jVar); + + if (implicit) { + jac_i(iVar,jVar) += dDdU; + jac_j(iVar,jVar) -= dDdU; + } + } + } } }; /*! - * \class CRoeScheme + * \class CMSWScheme * \ingroup ConvDiscr - * \brief Classical Roe scheme. + * \brief MSW scheme with switch to SW based on a pressure sensor. */ template -class CRoeScheme : public CRoeBase,Decorator> { -private: - using Base = CRoeBase,Decorator>; +class CMSWScheme : public CUpwindBase, Decorator> { +protected: + using Base = CUpwindBase, Decorator>; using Base::nDim; using Base::nVar; + using Base::nPrimVarGrad; + using Base::nPrimVar; + + const su2double alpha; using Base::gamma; - using Base::kappa; - const ENUM_ROELOWDISS typeDissip; + using Base::gasConst; + using Base::dynamicGrid; public: /*! - * \brief Constructor, store some constants and forward to base. + * \brief Constructor, store some constants and forward args to base. */ template - CRoeScheme(const CConfig& config, Ts&... args) : Base(config, args...), - typeDissip(static_cast(config.GetKind_RoeLowDiss())) { + CMSWScheme(const CConfig& config, unsigned iMesh, Ts&... args) : Base(config, iMesh, args...), + alpha(config.GetMSW_Alpha()) { } /*! - * \brief Updates flux and Jacobians with standard Roe dissipation. - * \note "Ts" is here just in case other schemes in the family need extra args. + * \brief Implementation of the flux. */ template FORCEINLINE void finalizeFlux(VectorDbl& flux, @@ -255,51 +343,87 @@ class CRoeScheme : public CRoeBase,Decorator> { bool implicit, Double area, const VectorDbl& unitNormal, + const VectorDbl& normal, const CPair& V, const CPair& U, - const CRoeVariables& roeAvg, - const VectorDbl& lambda, - const MatrixDbl& pMat, Int iPoint, Int jPoint, const CEulerVariable& solution, + const CGeometry& geometry, Ts&...) const { - /*--- Inverse P tensor. ---*/ - auto pMatInv = pMatrixInv(gamma, roeAvg.density, roeAvg.velocity, - roeAvg.projVel, roeAvg.speedSound, unitNormal); + /*--- Weighted states for flux-vector spliting (see the non-SIMD version in fvs.cpp for notes). ---*/ - /*--- Diference between conservative variables at jPoint and iPoint. ---*/ + const auto si = gatherVariables(iPoint, solution.GetSensor()); + const auto sj = gatherVariables(jPoint, solution.GetSensor()); - VectorDbl deltaU; - for (size_t iVar = 0; iVar < nVar; ++iVar) { - deltaU(iVar) = U.j.all(iVar) - U.i.all(iVar); - } + const Double dp = fmax(si, sj) - alpha * 0.06; + const Double w = 0.25 * (1 - sign(dp)) * (1 - exp(-100 * abs(dp))); + const Double onemw = 1 - w; - /*--- Dissipation terms. ---*/ + CPair> Vweighted; + for (size_t iVar = 0; iVar < nPrimVarGrad; ++iVar) { + Vweighted.i.all(iVar) = onemw * V.i.all(iVar) + w * V.j.all(iVar); + Vweighted.j.all(iVar) = onemw * V.j.all(iVar) + w * V.i.all(iVar); + } + const Double soundSpeed_i = sqrt(gamma * gasConst * Vweighted.i.temperature()); + const Double soundSpeed_j = sqrt(gamma * gasConst * Vweighted.j.temperature()); - Double dissipation = roeDissipation(iPoint, jPoint, typeDissip, solution); + Double projGridVel_i = 0.0, projGridVel_j = 0.0; + if (dynamicGrid) { + const auto& gridVel = geometry.nodes->GetGridVel(); + const Double vn_i = dot(gatherVariables(iPoint, gridVel), unitNormal); + const Double vn_j = dot(gatherVariables(jPoint, gridVel), unitNormal); + projGridVel_i = onemw * vn_i + w * vn_j; + projGridVel_j = onemw * vn_j + w * vn_i; + } + Double projVel_i = dot(Vweighted.i.velocity(), unitNormal) - projGridVel_i; + Double projVel_j = dot(Vweighted.j.velocity(), unitNormal) - projGridVel_j; - for (size_t iVar = 0; iVar < nVar; ++iVar) { - for (size_t jVar = 0; jVar < nVar; ++jVar) { - /*--- Compute |projModJacTensor| = P x |Lambda| x P^-1. ---*/ + /*--- Lambda+ ---*/ - Double projModJacTensor = 0.0; - for (size_t kVar = 0; kVar < nVar; ++kVar) { - projModJacTensor += pMat(iVar,kVar) * lambda(kVar) * pMatInv(kVar,jVar); - } + VectorDbl lambda; + for (size_t iDim = 0; iDim < nDim; ++iDim) { + lambda(iDim) = fmax(projVel_i, 0); + } + lambda(nDim) = fmax(projVel_i + soundSpeed_i, 0); + lambda(nDim+1) = fmax(projVel_i - soundSpeed_i, 0); - Double dDdU = projModJacTensor * (1-kappa) * area * dissipation; + auto pMat = pMatrix(gamma, Vweighted.i.density(), Vweighted.i.velocity(), + projVel_i, soundSpeed_i, unitNormal); + auto pMatInv = pMatrixInv(gamma, Vweighted.i.density(), Vweighted.i.velocity(), + projVel_i, soundSpeed_i, unitNormal); - /*--- Update flux and Jacobians. ---*/ + auto updateFlux = [&](const auto& u, auto& jac) { + for (size_t iVar = 0; iVar < nVar; ++iVar) { + for (size_t jVar = 0; jVar < nVar; ++jVar) { + /*--- Compute |projModJacTensor| = P x |Lambda| x P^-1. ---*/ - flux(iVar) -= dDdU * deltaU(jVar); + Double projModJacTensor = 0.0; + for (size_t kVar = 0; kVar < nVar; ++kVar) { + projModJacTensor += pMat(iVar,kVar) * lambda(kVar) * pMatInv(kVar,jVar); + } + Double dFdU = projModJacTensor * area; - if(implicit) { - jac_i(iVar,jVar) += dDdU; - jac_j(iVar,jVar) -= dDdU; + flux(iVar) += dFdU * u(jVar); + jac(iVar, jVar) = dFdU; } } + }; + updateFlux(U.i.all, jac_i); + + /*--- Lambda- ---*/ + + for (size_t iDim = 0; iDim < nDim; ++iDim) { + lambda(iDim) = fmin(projVel_j, 0); } + lambda(nDim) = fmin(projVel_j + soundSpeed_j, 0); + lambda(nDim+1) = fmin(projVel_j - soundSpeed_j, 0); + + pMat = pMatrix(gamma, Vweighted.j.density(), Vweighted.j.velocity(), + projVel_j, soundSpeed_j, unitNormal); + pMatInv = pMatrixInv(gamma, Vweighted.j.density(), Vweighted.j.velocity(), + projVel_j, soundSpeed_j, unitNormal); + updateFlux(U.j.all, jac_j); } }; 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 62b10487782b..22ea755f9af1 100644 --- a/SU2_CFD/include/numerics_simd/flow/diffusion/viscous_fluxes.hpp +++ b/SU2_CFD/include/numerics_simd/flow/diffusion/viscous_fluxes.hpp @@ -127,7 +127,7 @@ class CCompressibleViscousFluxBase : public CNumericsSIMD { MatrixDbl& jac_i, MatrixDbl& jac_j) const { - static_assert(PrimVarType::nVar <= Derived::nPrimVar,""); + static_assert(PrimVarType::nVar <= Derived::nPrimVar); /*--- Pointer on which to call the "compile-time virtual" methods. ---*/ diff --git a/SU2_CFD/include/output/CAdjElasticityOutput.hpp b/SU2_CFD/include/output/CAdjElasticityOutput.hpp index 8a1d0559ca3e..c6872d5b3e2c 100644 --- a/SU2_CFD/include/output/CAdjElasticityOutput.hpp +++ b/SU2_CFD/include/output/CAdjElasticityOutput.hpp @@ -36,6 +36,7 @@ */ class CAdjElasticityOutput final : public COutput { private: + bool coupled_heat; //!< Boolean indicating a thermoelastic analysis unsigned short nVar_FEM; //!< Number of FEM variables public: diff --git a/SU2_CFD/include/output/CAdjHeatOutput.hpp b/SU2_CFD/include/output/CAdjHeatOutput.hpp index 72f8cffc931d..7c7a5a0bf865 100644 --- a/SU2_CFD/include/output/CAdjHeatOutput.hpp +++ b/SU2_CFD/include/output/CAdjHeatOutput.hpp @@ -46,7 +46,12 @@ class CAdjHeatOutput final: public COutput { /*! * \brief Destructor of the class. */ - ~CAdjHeatOutput(void) override; + ~CAdjHeatOutput() override; + + /*! + * \brief Set the history output field values in another output instance. + */ + static void LoadHistoryDataImpl(CConfig *config, CGeometry *geometry, CSolver **solver, COutput* output); /*! * \brief Load the history output field values @@ -54,6 +59,11 @@ class CAdjHeatOutput final: public COutput { */ void LoadHistoryData(CConfig *config, CGeometry *geometry, CSolver **solver) override; + /*! + * \brief Set the available history output fields in another output instance. + */ + static void SetHistoryOutputFieldsImpl(CConfig *config, COutput* output); + /*! * \brief Set the available history output fields * \param[in] config - Definition of the particular problem. diff --git a/SU2_CFD/include/output/CElasticityOutput.hpp b/SU2_CFD/include/output/CElasticityOutput.hpp index c3c189512b47..ecf054a631a1 100644 --- a/SU2_CFD/include/output/CElasticityOutput.hpp +++ b/SU2_CFD/include/output/CElasticityOutput.hpp @@ -37,7 +37,6 @@ class CElasticityOutput final: public COutput { protected: - unsigned short nVar_FEM; //!< Number of FEM variables bool linear_analysis, //!< Boolean indicating a linear analysis nonlinear_analysis, //!< Boolean indicating a nonlinear analysis coupled_heat, //!< Boolean indicating a thermoelastic analysis diff --git a/SU2_CFD/include/output/COutput.hpp b/SU2_CFD/include/output/COutput.hpp index ce4e29ed2c17..cf12c495e1a4 100644 --- a/SU2_CFD/include/output/COutput.hpp +++ b/SU2_CFD/include/output/COutput.hpp @@ -56,6 +56,7 @@ class CFileWriter; class CParallelDataSorter; class CConfig; class CHeatOutput; +class CAdjHeatOutput; using namespace std; @@ -67,6 +68,7 @@ using namespace std; class COutput { protected: friend class CHeatOutput; + friend class CAdjHeatOutput; /*----------------------------- General ----------------------------*/ @@ -91,10 +93,13 @@ class COutput { curOuterIter, /*!< \brief Current value of the outer iteration index */ curInnerIter; /*!< \brief Current value of the inner iteration index */ + su2double PrevStopTime; /*!< \brief Previous stop time for iteration timing. */ + string historyFilename; /*!< \brief The history filename*/ ofstream histFile; /*!< \brief Output file stream for the history */ bool cauchyTimeConverged; /*! \brief: Flag indicating that solver is already converged. Needed for writing restart files. */ + bool maxTimeDelayActive; /*! \brief: Flag for delaying stop at max_time with 2nd order time stepping. */ /** \brief Enum to identify the screen output format. */ enum class ScreenOutputFormat { diff --git a/SU2_CFD/include/output/filewriter/CTecplotBinaryFileWriter.hpp b/SU2_CFD/include/output/filewriter/CTecplotBinaryFileWriter.hpp index da9d09979c6a..29be9e12d2f0 100644 --- a/SU2_CFD/include/output/filewriter/CTecplotBinaryFileWriter.hpp +++ b/SU2_CFD/include/output/filewriter/CTecplotBinaryFileWriter.hpp @@ -27,9 +27,11 @@ #pragma once +#include +#include + #include "CFileWriter.hpp" -#include class CTecplotBinaryFileWriter final: public CFileWriter{ diff --git a/SU2_CFD/include/solvers/CFEASolver.hpp b/SU2_CFD/include/solvers/CFEASolver.hpp index ce472e585750..631f729b04eb 100644 --- a/SU2_CFD/include/solvers/CFEASolver.hpp +++ b/SU2_CFD/include/solvers/CFEASolver.hpp @@ -550,7 +550,7 @@ class CFEASolver : public CFEASolverBase { * \param[in] config - Definition of the problem. * \param[in] solver - Container vector with all the solutions. */ - void Evaluate_ObjFunc(const CConfig *config, CSolver**) final { + void Evaluate_ObjFunc(const CConfig *config, CSolver** solver) final { Total_ComboObj = 0.0; switch (config->GetKind_ObjFunc()) { case REFERENCE_GEOMETRY: @@ -575,6 +575,10 @@ class CFEASolver : public CFEASolverBase { Total_ComboObj = Total_Custom_ObjFunc; break; } + if (config->GetWeakly_Coupled_Heat()) { + solver[HEAT_SOL]->Evaluate_ObjFunc(config, solver); + Total_ComboObj += solver[HEAT_SOL]->GetTotal_ComboObj(); + } } /*! diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp index b61d3d61f33a..9f04b0cbaf69 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp @@ -524,14 +524,10 @@ class CFVMFlowSolverBase : public CSolver { } } END_SU2_OMP_FOR + /*--- Min/max over threads. ---*/ - SU2_OMP_CRITICAL - { - Min_Delta_Time = min(Min_Delta_Time, minDt); - Max_Delta_Time = max(Max_Delta_Time, maxDt); - Global_Delta_Time = Min_Delta_Time; - } - END_SU2_OMP_CRITICAL + atomicMin(minDt, Min_Delta_Time); + atomicMax(maxDt, Max_Delta_Time); } /*--- Compute the min/max dt (in parallel, now over mpi ranks). ---*/ @@ -545,6 +541,7 @@ class CFVMFlowSolverBase : public CSolver { SU2_MPI::Allreduce(&Max_Delta_Time, &rbuf_time, 1, MPI_DOUBLE, MPI_MAX, SU2_MPI::GetComm()); Max_Delta_Time = rbuf_time; } + Global_Delta_Time = Min_Delta_Time; } END_SU2_OMP_SAFE_GLOBAL_ACCESS /*--- For exact time solution use the minimum delta time of the whole mesh. ---*/ @@ -578,7 +575,7 @@ class CFVMFlowSolverBase : public CSolver { } - /*--- Recompute the unsteady time step for the dual time strategy if the unsteady CFL is diferent from 0. + /*--- Recompute the unsteady time step for the dual time strategy if the unsteady CFL is different from 0. * This is only done once because in dual time the time step cannot be variable. ---*/ if (dual_time && (Iteration == config->GetRestart_Iter()) && (config->GetUnst_CFL() != 0.0) && (iMesh == MESH_0)) { @@ -591,9 +588,7 @@ class CFVMFlowSolverBase : public CSolver { glbDtND = min(glbDtND, config->GetUnst_CFL()*Global_Delta_Time / nodes->GetLocalCFL(iPoint)); } END_SU2_OMP_FOR - SU2_OMP_CRITICAL - Global_Delta_UnstTimeND = min(Global_Delta_UnstTimeND, glbDtND); - END_SU2_OMP_CRITICAL + atomicMin(glbDtND, Global_Delta_UnstTimeND); BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { @@ -728,6 +723,7 @@ class CFVMFlowSolverBase : public CSolver { template FORCEINLINE void SetCentered_Dissipation_Sensor_impl(const SensVarFunc& sensVar, CGeometry *geometry, const CConfig *config) { + const bool msw = config->GetKind_Upwind_Flow() == UPWIND::MSW; /*--- We can access memory more efficiently if there are no periodic boundaries. ---*/ @@ -742,8 +738,8 @@ class CFVMFlowSolverBase : public CSolver { const su2double sensVar_i = sensVar(*nodes, iPoint); /*--- Initialize. ---*/ - iPoint_UndLapl[iPoint] = 0.0; - jPoint_UndLapl[iPoint] = 0.0; + iPoint_UndLapl[iPoint] = 0; + jPoint_UndLapl[iPoint] = msw ? 1 : 0; /*--- Loop over the neighbors of point i. ---*/ for (auto jPoint : geometry->nodes->GetPoints(iPoint)) @@ -755,9 +751,16 @@ class CFVMFlowSolverBase : public CSolver { su2double sensVar_j = sensVar(*nodes, jPoint); - /*--- Dissipation sensor, add variable difference and variable sum. ---*/ - iPoint_UndLapl[iPoint] += sensVar_j - sensVar_i; - jPoint_UndLapl[iPoint] += sensVar_j + sensVar_i; + if (msw) { + /*--- More conservative formulation (triggered by large gradient instead of large laplacian). + * From "Development of an Unstructured Navier-Stokes Solver For Hypersonic Nonequilibrium + * Aerothermodynamics". ---*/ + iPoint_UndLapl[iPoint] = fmax(iPoint_UndLapl[iPoint], fabs(sensVar_j - sensVar_i) / fmin(sensVar_j, sensVar_i)); + } else { + /*--- Jameson dissipation sensor, add variable difference and variable sum. ---*/ + iPoint_UndLapl[iPoint] += sensVar_j - sensVar_i; + jPoint_UndLapl[iPoint] += sensVar_j + sensVar_i; + } } if (!isPeriodic) { @@ -803,7 +806,7 @@ class CFVMFlowSolverBase : public CSolver { static_assert(IntegrationType == CLASSICAL_RK4_EXPLICIT || IntegrationType == RUNGE_KUTTA_EXPLICIT || - IntegrationType == EULER_EXPLICIT, ""); + IntegrationType == EULER_EXPLICIT); const bool adjoint = config->GetContinuous_Adjoint(); @@ -960,12 +963,11 @@ class CFVMFlowSolverBase : public CSolver { } for (unsigned short iVar = 0; iVar < nVar; iVar++) { - unsigned long total_index = iPoint*nVar + iVar; - LinSysRes[total_index] = - (LinSysRes[total_index] + local_Res_TruncError[iVar]); - LinSysSol[total_index] = 0.0; + LinSysRes(iPoint, iVar) = -(LinSysRes(iPoint, iVar) + local_Res_TruncError[iVar]); + LinSysSol(iPoint, iVar) = 0.0; /*--- "Add" residual at (iPoint,iVar) to local residual variables. ---*/ - ResidualReductions_PerThread(iPoint, iVar, LinSysRes[total_index], resRMS, resMax, idxMax); + ResidualReductions_PerThread(iPoint, iVar, LinSysRes(iPoint, iVar), resRMS, resMax, idxMax); } } END_SU2_OMP_FOR @@ -1132,6 +1134,8 @@ class CFVMFlowSolverBase : public CSolver { BC_Sym_Plane(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); } + void MultigridProjectEulerWall(CGeometry* geometry, const CConfig* config, bool use_solution_old) override; + /*! * \author T. Kattmann * \brief Impose the symmetry boundary condition using the residual. diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl index 8e935770a89d..cc2fa9a9e5ab 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl @@ -93,7 +93,8 @@ void CFVMFlowSolverBase::Allocate(const CConfig& config) { /*--- Define some auxiliar vector related with the undivided lapalacian computation ---*/ - if ((config.GetKind_ConvNumScheme_Flow() == SPACE_CENTERED) && (MGLevel == MESH_0)) { + if ((config.GetKind_ConvNumScheme_Flow() == SPACE_CENTERED && MGLevel == MESH_0) || + config.GetKind_Upwind_Flow() == UPWIND::MSW) { iPoint_UndLapl.resize(nPointDomain); jPoint_UndLapl.resize(nPointDomain); } @@ -683,11 +684,8 @@ void CFVMFlowSolverBase::ComputeVorticityAndStrainMag(const CConfig& confi END_SU2_OMP_FOR if ((iMesh == MESH_0) && (config.GetComm_Level() == COMM_FULL)) { - SU2_OMP_CRITICAL { - StrainMag_Max = max(StrainMag_Max, strainMax); - Omega_Max = max(Omega_Max, omegaMax); - } - END_SU2_OMP_CRITICAL + atomicMax(strainMax, StrainMag_Max); + atomicMax(omegaMax, Omega_Max); BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { @@ -1457,7 +1455,7 @@ void CFVMFlowSolverBase::BC_Custom(CGeometry* geometry, CSolver** solver_c if (VerificationSolution) { unsigned short iVar; - unsigned long iVertex, iPoint, total_index; + unsigned long iVertex, iPoint; bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); @@ -1499,8 +1497,7 @@ void CFVMFlowSolverBase::BC_Custom(CGeometry* geometry, CSolver** solver_c if (implicit) { for (iVar = 0; iVar < nVar; iVar++) { - total_index = iPoint * nVar + iVar; - Jacobian.DeleteValsRowi(total_index); + Jacobian.DeleteValsRowi(iPoint, iVar); } } } @@ -3003,3 +3000,58 @@ void CFVMFlowSolverBase::ComputeAxisymmetricAuxGradients(CGeometr SetAuxVar_Gradient_LS(geometry, config); } } + +template +void CFVMFlowSolverBase::MultigridProjectEulerWall(CGeometry* geometry, const CConfig* config, + bool use_solution_old) { + const auto iVel = prim_idx.Velocity(); + const auto nDim = geometry->GetnDim(); + + for (auto iMarker = 0u; iMarker < config->GetnMarker_All(); iMarker++) { + if (config->GetMarker_All_KindBC(iMarker) != EULER_WALL) continue; + + SU2_OMP_FOR_STAT(32) + for (auto iVertex = 0ul; iVertex < geometry->nVertex[iMarker]; iVertex++) { + const auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + if (!geometry->nodes->GetDomain(iPoint)) continue; + + /*--- Use the Gram-Schmidt corrected normal for nodes on intersecting walls, + * consistent with BC_Sym_Plane. Fall back to the raw marker normal otherwise. ---*/ + su2double UnitNormal[MAXNDIM] = {0.0}; + const auto it = geometry->symmetryNormals[iMarker].find(iVertex); + if (it != geometry->symmetryNormals[iMarker].end()) { + for (auto iDim = 0u; iDim < nDim; iDim++) UnitNormal[iDim] = it->second[iDim]; + } else { + su2double Normal[MAXNDIM] = {0.0}; + geometry->vertex[iMarker][iVertex]->GetNormal(Normal); + const su2double Area = GeometryToolbox::Norm(nDim, Normal); + if (Area < EPS) continue; + for (auto iDim = 0u; iDim < nDim; iDim++) UnitNormal[iDim] = Normal[iDim] / Area; + } + + su2double* sol = use_solution_old ? nodes->GetSolution_Old(iPoint) : nodes->GetSolution(iPoint); + + /*--- Compute normal component of the velocity / momentum vector. + * For dynamic grids subtract the grid velocity to enforce (v - v_grid).n = 0, + * multiplying by density for compressible flow (conservative variables). ---*/ + su2double gridVel[MAXNDIM] = {}; + if (dynamic_grid && !use_solution_old) { + for (auto iDim = 0u; iDim < nDim; iDim++) + gridVel[iDim] = geometry->nodes->GetGridVel(iPoint)[iDim]; + if constexpr (FlowRegime == ENUM_REGIME::COMPRESSIBLE) { + for (auto iDim = 0u; iDim < nDim; iDim++) + gridVel[iDim] *= nodes->GetDensity(iPoint); + } + } + + su2double momentum_n = 0.0; + for (auto iDim = 0u; iDim < nDim; iDim++) + momentum_n += (sol[iVel + iDim] - gridVel[iDim]) * UnitNormal[iDim]; + + /*--- Project to tangent plane. ---*/ + for (auto iDim = 0u; iDim < nDim; iDim++) sol[iVel + iDim] -= momentum_n * UnitNormal[iDim]; + } + END_SU2_OMP_FOR + } +} diff --git a/SU2_CFD/include/solvers/CHeatSolver.hpp b/SU2_CFD/include/solvers/CHeatSolver.hpp index 7607114dff4c..077d058b9498 100644 --- a/SU2_CFD/include/solvers/CHeatSolver.hpp +++ b/SU2_CFD/include/solvers/CHeatSolver.hpp @@ -88,8 +88,8 @@ class CHeatSolver final : public CScalarSolver { LinSysRes(iPoint, 0) -= thermal_diffusivity * dTdn * Area; if (implicit) { - su2double Jacobian_i[] = {-thermal_diffusivity / dist_ij * Area}; - Jacobian.SubtractBlock2Diag(iPoint, &Jacobian_i); + su2double Jacobian_i[1][1] = {{-thermal_diffusivity / dist_ij * Area}}; + Jacobian.SubtractBlock2Diag(iPoint, Jacobian_i); } } diff --git a/SU2_CFD/include/solvers/CNEMOEulerSolver.hpp b/SU2_CFD/include/solvers/CNEMOEulerSolver.hpp index 35d2492f0727..75bd963f7563 100644 --- a/SU2_CFD/include/solvers/CNEMOEulerSolver.hpp +++ b/SU2_CFD/include/solvers/CNEMOEulerSolver.hpp @@ -56,9 +56,6 @@ class CNEMOEulerSolver : public CFVMFlowSolverBaseSetScalarVar(nodes->GetSolution(iPoint), nodes->GetSolution(jPoint)); numerics->SetScalarVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(jPoint)); - return numerics->ComputeResidual(config); + return numerics->ComputeResidual(config); }; /*--- Compute fluxes and jacobians i->j ---*/ @@ -241,7 +241,7 @@ class CScalarSolver : public CSolver { } } } - + /*! * \brief Generic implementation of the fluid interface boundary condition for scalar solvers. * \tparam SolverSpecificNumericsFunc - lambda that implements solver specific contributions to viscous numerics. @@ -427,7 +427,7 @@ class CScalarSolver : public CSolver { * a nonlinear iteration for stability. Default value 1.0 set in ctor of CScalarVariable. * \param[in] config - Definition of the particular problem. */ - virtual void ComputeUnderRelaxationFactor(const CConfig* config) {} + virtual void ComputeUnderRelaxationFactor(CSolver** solver_container, const CConfig* config) {} public: /*! diff --git a/SU2_CFD/include/solvers/CScalarSolver.inl b/SU2_CFD/include/solvers/CScalarSolver.inl index bbd83679254f..b02cfacf064c 100644 --- a/SU2_CFD/include/solvers/CScalarSolver.inl +++ b/SU2_CFD/include/solvers/CScalarSolver.inl @@ -481,12 +481,11 @@ void CScalarSolver::PrepareImplicitIteration(CGeometry* geometry, /*--- Right hand side of the system (-Residual) and initial guess (x = 0) ---*/ for (unsigned short iVar = 0; iVar < nVar; iVar++) { - unsigned long total_index = iPoint * nVar + iVar; - LinSysRes[total_index] = -LinSysRes[total_index]; - LinSysSol[total_index] = 0.0; + LinSysRes(iPoint, iVar) = -LinSysRes(iPoint, iVar); + LinSysSol(iPoint, iVar) = 0.0; /*--- "Add" residual at (iPoint,iVar) to local residual variables. ---*/ - ResidualReductions_PerThread(iPoint, iVar, LinSysRes[total_index], resRMS, resMax, idxMax); + ResidualReductions_PerThread(iPoint, iVar, LinSysRes(iPoint, iVar), resRMS, resMax, idxMax); } } END_SU2_OMP_FOR @@ -498,7 +497,7 @@ void CScalarSolver::PrepareImplicitIteration(CGeometry* geometry, template void CScalarSolver::CompleteImplicitIteration(CGeometry* geometry, CSolver** solver_container, CConfig* config) { - ComputeUnderRelaxationFactor(config); + ComputeUnderRelaxationFactor(solver_container, config); /*--- Update solution (system written in terms of increments) ---*/ diff --git a/SU2_CFD/include/solvers/CSolver.hpp b/SU2_CFD/include/solvers/CSolver.hpp index 67a8bb8112c3..eba2e5cc07d7 100644 --- a/SU2_CFD/include/solvers/CSolver.hpp +++ b/SU2_CFD/include/solvers/CSolver.hpp @@ -804,6 +804,16 @@ class CSolver { CConfig *config, unsigned short val_marker) { } + /*! + * \brief Enforce Euler wall BC on a restricted or prolongated multigrid solution by + * projecting the momentum to the tangent plane of the wall. + * \param[in] geometry - Coarse grid geometry. + * \param[in] config - Definition of the particular problem. + * \param[in] use_solution_old - If true, project Solution_Old (corrections); if false, project Solution. + */ + inline virtual void MultigridProjectEulerWall(CGeometry* /*geometry*/, const CConfig* /*config*/, + bool /*use_solution_old*/) {} + /*! * \brief A virtual member. * \param[in] geometry - Geometrical definition of the problem. diff --git a/SU2_CFD/include/solvers/CTurbSASolver.hpp b/SU2_CFD/include/solvers/CTurbSASolver.hpp index dfc1362b003c..d4ebe49c8dab 100644 --- a/SU2_CFD/include/solvers/CTurbSASolver.hpp +++ b/SU2_CFD/include/solvers/CTurbSASolver.hpp @@ -70,7 +70,7 @@ class CTurbSASolver final : public CTurbSolver { * a nonlinear iteration for stability. * \param[in] config - Definition of the particular problem. */ - void ComputeUnderRelaxationFactor(const CConfig *config) final; + void ComputeUnderRelaxationFactor(CSolver** solver_container, const CConfig *config) final; public: /*! diff --git a/SU2_CFD/include/solvers/CTurbSSTSolver.hpp b/SU2_CFD/include/solvers/CTurbSSTSolver.hpp index 5c8d9a0e7eac..8b935aeba994 100644 --- a/SU2_CFD/include/solvers/CTurbSSTSolver.hpp +++ b/SU2_CFD/include/solvers/CTurbSSTSolver.hpp @@ -59,7 +59,7 @@ class CTurbSSTSolver final : public CTurbSolver { * a nonlinear iteration for stability. * \param[in] config - Definition of the particular problem. */ - void ComputeUnderRelaxationFactor(const CConfig *config) override; + void ComputeUnderRelaxationFactor(CSolver** solver_container, const CConfig *config) override; public: /*! diff --git a/SU2_CFD/include/solvers/CTurbSolver.hpp b/SU2_CFD/include/solvers/CTurbSolver.hpp index 56b7b96b3b26..59e83795b4b1 100644 --- a/SU2_CFD/include/solvers/CTurbSolver.hpp +++ b/SU2_CFD/include/solvers/CTurbSolver.hpp @@ -153,5 +153,5 @@ class CTurbSolver : public CScalarSolver { * a nonlinear iteration for stability. * \param[in] allowableRatio - Maximum percentage update in variable per iteration. */ - void ComputeUnderRelaxationFactorHelper(su2double allowableRatio); + void ComputeUnderRelaxationFactorHelper(CSolver** solver_container, su2double allowableRatio); }; diff --git a/SU2_CFD/include/variables/CPrimitiveIndices.hpp b/SU2_CFD/include/variables/CPrimitiveIndices.hpp index 2472fa849c9d..a1951ae02a55 100644 --- a/SU2_CFD/include/variables/CPrimitiveIndices.hpp +++ b/SU2_CFD/include/variables/CPrimitiveIndices.hpp @@ -90,7 +90,7 @@ struct CPrimitiveIndices { template void Construct(IndexType nDim, IndexType nSpecies) { /*--- Build the indices object in the static buffer owned by this class. ---*/ - static_assert(sizeof(ConcreteIndices) <= 2 * sizeof(IndexType), ""); + static_assert(sizeof(ConcreteIndices) <= 2 * sizeof(IndexType)); new(data_) ConcreteIndices(nDim, nSpecies); } diff --git a/SU2_CFD/src/drivers/CDriver.cpp b/SU2_CFD/src/drivers/CDriver.cpp index 961ce04832ff..45042a022b1f 100644 --- a/SU2_CFD/src/drivers/CDriver.cpp +++ b/SU2_CFD/src/drivers/CDriver.cpp @@ -810,7 +810,7 @@ void CDriver::InitializeGeometryFVM(CConfig *config, CGeometry **&geometry) { geometry[MESH_0]->SetMGLevel(MESH_0); if ((config->GetnMGLevels() != 0) && (rank == MASTER_NODE)) - cout << "Setting the multigrid structure." << endl; + cout << "Setting the multigrid structure. NMG="<< config->GetnMGLevels() << endl; /*--- Loop over all the new grid ---*/ @@ -2769,9 +2769,10 @@ void CDriver::PrintDirectResidual(RECORDING kind_recording) { /*--- Helper lambda func to return lenghty [iVar][iZone] string. ---*/ auto iVar_iZone2string = [&](unsigned short ivar, unsigned short izone) { - if (multizone) + if (multizone) { return "[" + std::to_string(ivar) + "][" + std::to_string(izone) + "]"; - return "[" + std::to_string(ivar) + "]"; + } + return "[" + std::to_string(ivar) + "]"; }; /*--- Print residuals in the first iteration ---*/ @@ -2827,37 +2828,33 @@ void CDriver::PrintDirectResidual(RECORDING kind_recording) { if (!addVals) RMSTable.AddColumn("rms_Rad" + iVar_iZone2string(0, iZone), fieldWidth); else RMSTable << log10(solvers[RAD_SOL]->GetRes_RMS(0)); } - - } - else if (configs->GetStructuralProblem()) { - + } else if (configs->GetStructuralProblem()) { if (configs->GetGeometricConditions() == STRUCT_DEFORMATION::LARGE){ if (!addVals) { RMSTable.AddColumn("UTOL-A", fieldWidth); RMSTable.AddColumn("RTOL-A", fieldWidth); RMSTable.AddColumn("ETOL-A", fieldWidth); - } - else { + } else { RMSTable << log10(solvers[FEA_SOL]->GetRes_FEM(0)) << log10(solvers[FEA_SOL]->GetRes_FEM(1)) << log10(solvers[FEA_SOL]->GetRes_FEM(2)); } - } - else{ + } else { if (!addVals) { RMSTable.AddColumn("log10[RMS Ux]", fieldWidth); RMSTable.AddColumn("log10[RMS Uy]", fieldWidth); if (nDim == 3) RMSTable.AddColumn("log10[RMS Uz]", fieldWidth); - } - else { + } else { RMSTable << log10(solvers[FEA_SOL]->GetRes_FEM(0)) << log10(solvers[FEA_SOL]->GetRes_FEM(1)); if (nDim == 3) RMSTable << log10(solvers[FEA_SOL]->GetRes_FEM(2)); } } - - } - else if (configs->GetHeatProblem()) { + if (configs->GetWeakly_Coupled_Heat()){ + if (!addVals) RMSTable.AddColumn("rms_Heat", fieldWidth); + else RMSTable << log10(solvers[HEAT_SOL]->GetRes_RMS(0)); + } + } else if (configs->GetHeatProblem()) { if (!addVals) RMSTable.AddColumn("rms_Heat" + iVar_iZone2string(0, iZone), fieldWidth); else RMSTable << log10(solvers[HEAT_SOL]->GetRes_RMS(0)); diff --git a/SU2_CFD/src/fluid/CDataDrivenFluid.cpp b/SU2_CFD/src/fluid/CDataDrivenFluid.cpp index cea19c47c155..8b4f2c20859f 100644 --- a/SU2_CFD/src/fluid/CDataDrivenFluid.cpp +++ b/SU2_CFD/src/fluid/CDataDrivenFluid.cpp @@ -43,13 +43,6 @@ CDataDrivenFluid::CDataDrivenFluid(const CConfig* config, bool display) : CFluid /*--- Use physics-informed approach ---*/ use_MLP_derivatives = datadriven_fluid_options.use_PINN; - /*--- Retrieve initial density and static energy values from config ---*/ - val_custom_init_e = datadriven_fluid_options.rho_init_custom; - val_custom_init_rho = datadriven_fluid_options.e_init_custom; - custom_init_e = (val_custom_init_e != -1.0); - custom_init_rho = (val_custom_init_rho != -1.0); - - /*--- Set up interpolation algorithm according to data-driven method. Currently only MLP's are supported. ---*/ switch (Kind_DataDriven_Method) { case ENUM_DATADRIVEN_METHOD::MLP: @@ -86,7 +79,6 @@ CDataDrivenFluid::~CDataDrivenFluid() { switch (Kind_DataDriven_Method) { case ENUM_DATADRIVEN_METHOD::MLP: #ifdef USE_MLPCPP - delete iomap_rhoe; delete lookup_mlp; #endif break; @@ -99,82 +91,55 @@ CDataDrivenFluid::~CDataDrivenFluid() { } void CDataDrivenFluid::MapInputs_to_Outputs() { /*--- Inputs of the data-driven method are density and internal energy. ---*/ - input_names_rhoe.resize(2); - idx_rho = 0; - idx_e = 1; - input_names_rhoe[idx_rho] = varname_rho; - input_names_rhoe[idx_e] = varname_e; /*--- Required outputs for the interpolation method are entropy and its partial derivatives with respect to energy and * density. ---*/ - size_t n_outputs, idx_s,idx_dsde_rho = 1, idx_dsdrho_e = 2, idx_d2sde2 = 3, idx_d2sdedrho = 4, idx_d2sdrho2 = 5; - if (use_MLP_derivatives) { - n_outputs = 1; - idx_s = 0; - - outputs_rhoe.resize(n_outputs); - output_names_rhoe.resize(n_outputs); - output_names_rhoe[idx_s] = "s"; - outputs_rhoe[idx_s] = &Entropy; - - dsdrhoe.resize(n_outputs); - d2sdrhoe2.resize(n_outputs); - dsdrhoe[0].resize(2); - dsdrhoe[0][idx_rho] = &dsdrho_e; - dsdrhoe[0][idx_e] = &dsde_rho; - - d2sdrhoe2[0].resize(2); - d2sdrhoe2[0][idx_rho].resize(2); - d2sdrhoe2[0][idx_e].resize(2); - d2sdrhoe2[0][idx_rho][idx_rho] = &d2sdrho2; - d2sdrhoe2[0][idx_rho][idx_e] = &d2sdedrho; - d2sdrhoe2[0][idx_e][idx_rho] = &d2sdedrho; - d2sdrhoe2[0][idx_e][idx_e] = &d2sde2; - } else { - n_outputs = 6; - idx_s = 0; - idx_dsde_rho = 1, idx_dsdrho_e = 2, idx_d2sde2 = 3, idx_d2sdedrho = 4, idx_d2sdrho2 = 5; - - outputs_rhoe.resize(n_outputs); - output_names_rhoe.resize(n_outputs); - output_names_rhoe[idx_s] = "s"; - outputs_rhoe[idx_s] = &Entropy; - output_names_rhoe[idx_dsde_rho] = "dsde_rho"; - outputs_rhoe[idx_dsde_rho] = &dsde_rho; - output_names_rhoe[idx_dsdrho_e] = "dsdrho_e"; - outputs_rhoe[idx_dsdrho_e] = &dsdrho_e; - output_names_rhoe[idx_d2sde2] = "d2sde2"; - outputs_rhoe[idx_d2sde2] = &d2sde2; - output_names_rhoe[idx_d2sdedrho] = "d2sdedrho"; - outputs_rhoe[idx_d2sdedrho] = &d2sdedrho; - output_names_rhoe[idx_d2sdrho2] = "d2sdrho2"; - outputs_rhoe[idx_d2sdrho2] = &d2sdrho2; - } - + const string name_entropy{"s"}, name_dsdrho{"dsdrho_e"}, name_dsde{"dsde"}, name_d2sdrho2{"d2sdrho2"}, name_d2sdedrho{"d2sdedrho"}, name_d2sde2{"d2sde2"}; + - /*--- Further preprocessing of input and output variables. ---*/ if (Kind_DataDriven_Method == ENUM_DATADRIVEN_METHOD::MLP) { -/*--- Map MLP inputs to outputs. ---*/ -#ifdef USE_MLPCPP - iomap_rhoe = new MLPToolbox::CIOMap(input_names_rhoe, output_names_rhoe); - lookup_mlp->PairVariableswithMLPs(*iomap_rhoe); - MLP_inputs.resize(2); -#endif + #ifdef USE_MLPCPP + iomap_rhoe = MLPToolbox::CIOMap(); + iomap_rhoe.AddQueryInput(varname_rho, &rho_query); + iomap_rhoe.AddQueryInput(varname_e, &e_query); + iomap_rhoe.AddQueryOutput(name_entropy, &Entropy); + + if (use_MLP_derivatives) { + iomap_rhoe.AddQueryJacobian(name_entropy, varname_rho, &dsdrho_e); + iomap_rhoe.AddQueryJacobian(name_entropy, varname_e, &dsde_rho); + iomap_rhoe.AddQueryHessian(name_entropy, varname_rho, varname_rho, &d2sdrho2); + iomap_rhoe.AddQueryHessian(name_entropy, varname_e, varname_rho, &d2sdedrho); + iomap_rhoe.AddQueryHessian(name_entropy, varname_e, varname_e, &d2sde2); + } else { + iomap_rhoe.AddQueryOutput(name_dsdrho, &dsdrho_e); + iomap_rhoe.AddQueryOutput(name_dsde, &dsde_rho); + iomap_rhoe.AddQueryOutput(name_d2sdrho2, &d2sdrho2); + iomap_rhoe.AddQueryOutput(name_d2sde2, &d2sde2); + iomap_rhoe.AddQueryOutput(name_d2sdedrho, &d2sdedrho); + } + + lookup_mlp->PairVariableswithMLPs(iomap_rhoe); + #endif } else { - /*--- Retrieve column indices of LUT output variables ---*/ - LUT_idx_s = lookup_table->GetIndexOfVar(output_names_rhoe[idx_s]); - LUT_idx_dsdrho_e = lookup_table->GetIndexOfVar(output_names_rhoe[idx_dsdrho_e]); - LUT_idx_dsde_rho = lookup_table->GetIndexOfVar(output_names_rhoe[idx_dsde_rho]); - LUT_idx_d2sde2 = lookup_table->GetIndexOfVar(output_names_rhoe[idx_d2sde2]); - LUT_idx_d2sdedrho= lookup_table->GetIndexOfVar(output_names_rhoe[idx_d2sdedrho]); - LUT_idx_d2sdrho2 = lookup_table->GetIndexOfVar(output_names_rhoe[idx_d2sdrho2]); + LUT_idx_s = lookup_table->GetIndexOfVar(name_entropy); + LUT_idx_dsdrho_e = lookup_table->GetIndexOfVar(name_dsdrho); + LUT_idx_dsde_rho = lookup_table->GetIndexOfVar(name_dsde); + LUT_idx_d2sde2 = lookup_table->GetIndexOfVar(name_d2sde2); + LUT_idx_d2sdedrho= lookup_table->GetIndexOfVar(name_d2sdedrho); + LUT_idx_d2sdrho2 = lookup_table->GetIndexOfVar(name_d2sdrho2); LUT_lookup_indices.push_back(LUT_idx_s); + outputs_rhoe.push_back(&Entropy); LUT_lookup_indices.push_back(LUT_idx_dsde_rho); + outputs_rhoe.push_back(&dsde_rho); LUT_lookup_indices.push_back(LUT_idx_dsdrho_e); + outputs_rhoe.push_back(&dsdrho_e); LUT_lookup_indices.push_back(LUT_idx_d2sde2); + outputs_rhoe.push_back(&d2sde2); LUT_lookup_indices.push_back(LUT_idx_d2sdedrho); + outputs_rhoe.push_back(&d2sdedrho); LUT_lookup_indices.push_back(LUT_idx_d2sdrho2); + outputs_rhoe.push_back(&d2sdrho2); } } @@ -205,14 +170,11 @@ void CDataDrivenFluid::SetTDState_rhoe(su2double rho, su2double e) { dTdrho_e = -Temperature * Temperature * d2sdedrho; /*--- Compute speed of sound. ---*/ - const su2double blue_term = (dsdrho_e * (2 - Density * Temperature * d2sdedrho) + Density * d2sdrho2); - const su2double green_term = (-Temperature * d2sde2 * dsdrho_e + d2sdedrho); - - SoundSpeed2 = -Density * Temperature * (blue_term - Density * green_term * (dsdrho_e / dsde_rho)); - dPde_rho = -rho_2 * Temperature * (-Temperature * (d2sde2 * dsdrho_e) + d2sdedrho); dPdrho_e = - Density * Temperature * (dsdrho_e * (2 - Density * Temperature * d2sdedrho) + Density * d2sdrho2); + SoundSpeed2 = dPdrho_e - (dsdrho_e / dsde_rho) * dPde_rho; + /*--- Compute enthalpy and entropy derivatives required for Giles boundary conditions. ---*/ dhdrho_e = -Pressure * (1 / rho_2) + dPdrho_e / Density; dhde_rho = 1 + dPde_rho / Density; @@ -243,10 +205,10 @@ void CDataDrivenFluid::SetTDState_rhoe(su2double rho, su2double e) { } void CDataDrivenFluid::SetTDState_PT(su2double P, su2double T) { - - /*--- Approximate density and static energy with ideal gas law. ---*/ - rho_start = P / (R_idealgas * T); - e_start = Cv_idealgas * T; + /*--- Find nearest neighbor on pressure-temperature thermodynamic table ---*/ + const auto iNearest = coarse_TD_table.FindNode(iP, P, iT, T); + e_start = vals_e_table[iNearest]; + rho_start = vals_rho_table[iNearest]; /*--- Run 2D Newton solver for pressure and temperature ---*/ Run_Newton_Solver(P, T, Pressure, Temperature, dPdrho_e, dPde_rho, dTdrho_e, dTde_rho); @@ -258,42 +220,41 @@ void CDataDrivenFluid::SetTDState_Prho(su2double P, su2double rho) { } void CDataDrivenFluid::SetEnergy_Prho(su2double P, su2double rho) { - /*--- Run 1D Newton solver for pressure at constant density. ---*/ + /*--- Find nearest neighbor on pressure-density thermodynamic table ---*/ + const auto iNearest = coarse_TD_table.FindNode(iP, P, iRho, rho); + StaticEnergy = vals_e_table[iNearest]; Density = rho; - /*--- Approximate static energy through ideal gas law. ---*/ - StaticEnergy = Cv_idealgas * (P / (R_idealgas * rho)); - + /*--- Run 1D Newton solver for pressure at constant density. ---*/ Run_Newton_Solver(P, Pressure, StaticEnergy, dPde_rho); } void CDataDrivenFluid::SetTDState_rhoT(su2double rho, su2double T) { - /*--- Run 1D Newton solver for temperature at constant density. ---*/ + /*--- Find nearest neighbor on density-temperature thermodynamic table ---*/ + const auto iNearest = coarse_TD_table.FindNode(iRho, rho, iT, T); + StaticEnergy = vals_e_table[iNearest]; Density = rho; - /*--- Approximate static energy through ideal gas law. ---*/ - StaticEnergy = Cv_idealgas * T; - + /*--- Run 1D Newton solver for temperature at constant density. ---*/ Run_Newton_Solver(T, Temperature, StaticEnergy, dTde_rho); } void CDataDrivenFluid::SetTDState_hs(su2double h, su2double s) { - /*--- Run 2D Newton solver for enthalpy and entropy. ---*/ - + /*--- Initial values for density and static energy from previous thermodynamic call. ---*/ e_start = StaticEnergy; rho_start = Density; + /*--- Run 2D Newton solver for enthalpy and entropy. ---*/ Run_Newton_Solver(h, s, Enthalpy, Entropy, dhdrho_e, dhde_rho, dsdrho_e, dsde_rho); } void CDataDrivenFluid::SetTDState_Ps(su2double P, su2double s) { - /*--- Run 2D Newton solver for pressure and entropy ---*/ - + /*--- Initial values for density and static energy from previous thermodynamic call. ---*/ e_start = StaticEnergy; - rho_start = Density; + rho_start = Density; + /*--- Run 2D Newton solver for pressure and entropy ---*/ Run_Newton_Solver(P, s, Pressure, Entropy, dPdrho_e, dPde_rho, dsdrho_e, dsde_rho); } - void CDataDrivenFluid::ComputeDerivativeNRBC_Prho(su2double P, su2double rho) { SetTDState_Prho(P, rho); @@ -308,13 +269,9 @@ unsigned long CDataDrivenFluid::Predict_MLP(su2double rho, su2double e) { unsigned long exit_code = 0; /*--- Evaluate MLP collection for the given values for density and energy. ---*/ #ifdef USE_MLPCPP - MLP_inputs[idx_rho] = rho; - MLP_inputs[idx_e] = e; - if (use_MLP_derivatives){ - exit_code = lookup_mlp->PredictANN(iomap_rhoe, MLP_inputs, outputs_rhoe, &dsdrhoe, &d2sdrhoe2); - } else { - exit_code = lookup_mlp->PredictANN(iomap_rhoe, MLP_inputs, outputs_rhoe); - } + rho_query = rho; + e_query = e; + if(!lookup_mlp->Predict(iomap_rhoe)) exit_code=1; #endif return exit_code; @@ -354,7 +311,7 @@ void CDataDrivenFluid::Run_Newton_Solver(const su2double Y1_target, const su2dou bool converged = false; unsigned long Iter = 0; - + su2double extra_relaxation{1.0}; /*--- Initiating Newton solver ---*/ while (!converged && (Iter < MaxIter_Newton)) { /*--- Determine thermodynamic state based on current density and energy. ---*/ @@ -363,7 +320,7 @@ void CDataDrivenFluid::Run_Newton_Solver(const su2double Y1_target, const su2dou /*--- Determine residuals. ---*/ const su2double delta_Y1 = Y1 - Y1_target; const su2double delta_Y2 = Y2 - Y2_target; - + /*--- Continue iterative process if residuals are outside tolerances. ---*/ if ((abs(delta_Y1 / Y1) < Newton_Tolerance) && (abs(delta_Y2 / Y2) < Newton_Tolerance)) { converged = true; @@ -373,9 +330,17 @@ void CDataDrivenFluid::Run_Newton_Solver(const su2double Y1_target, const su2dou const su2double delta_rho = (dY2de * delta_Y1 - dY1de * delta_Y2) / determinant; const su2double delta_e = (-dY2drho * delta_Y1 + dY1drho * delta_Y2) / determinant; + extra_relaxation = 1.0; + /*--- Check if updated values exceed the bounds. If so, apply extra relaxation. ---*/ + if (rho - delta_rho <= rho_min) extra_relaxation = min(extra_relaxation, 0.5*(rho - rho_min) / (Newton_Relaxation * delta_rho)); + if (rho - delta_rho >= rho_max) extra_relaxation = min(extra_relaxation, 0.5*(rho - rho_max) / (Newton_Relaxation * delta_rho)); + + if (e - delta_e <= e_min) extra_relaxation = min(extra_relaxation, 0.5*(e - e_min) / (Newton_Relaxation * delta_e)); + if (e - delta_e >= e_max) extra_relaxation = min(extra_relaxation, 0.5*(e - e_max) / (Newton_Relaxation * delta_e)); + /*--- Update density and energy values. ---*/ - rho -= Newton_Relaxation * delta_rho; - e -= Newton_Relaxation * delta_e; + rho -= extra_relaxation * Newton_Relaxation * delta_rho; + e -= extra_relaxation * Newton_Relaxation * delta_e; } Iter++; } @@ -426,9 +391,7 @@ void CDataDrivenFluid::Run_Newton_Solver(const su2double Y_target, const su2doub } void CDataDrivenFluid::ComputeIdealGasQuantities() { - /*--- Compute approximate ideal gas properties from the middle of the reference data set. These properties are used to approximate the initial condition of the Newton solvers using the ideal gas law. ---*/ - su2double rho_average = 1.0, e_average = 1.0; - + /*--- Obtain minimum and maximum density and static energy from data set. ---*/ switch (Kind_DataDriven_Method) { @@ -437,36 +400,75 @@ void CDataDrivenFluid::ComputeIdealGasQuantities() { e_min = *lookup_table->GetTableLimitsY().first; rho_max = *lookup_table->GetTableLimitsX().second; e_max = *lookup_table->GetTableLimitsY().second; - rho_average = 0.5*(*lookup_table->GetTableLimitsX().first + *lookup_table->GetTableLimitsX().second); - e_average = 0.5*(*lookup_table->GetTableLimitsY().first + *lookup_table->GetTableLimitsY().second); break; case ENUM_DATADRIVEN_METHOD::MLP: #ifdef USE_MLPCPP - rho_min = lookup_mlp->GetInputNorm(iomap_rhoe, idx_rho).first; - e_min = lookup_mlp->GetInputNorm(iomap_rhoe, idx_e).first; - rho_max = lookup_mlp->GetInputNorm(iomap_rhoe, idx_rho).second; - e_max = lookup_mlp->GetInputNorm(iomap_rhoe, idx_e).second; - rho_average = lookup_mlp->GetInputOffset(iomap_rhoe, idx_rho); - e_average = lookup_mlp->GetInputOffset(iomap_rhoe, idx_e); + rho_min = iomap_rhoe.GetInputNorm(varname_rho).first; + e_min = iomap_rhoe.GetInputNorm(varname_e).first; + rho_max = iomap_rhoe.GetInputNorm(varname_rho).second; + e_max = iomap_rhoe.GetInputNorm(varname_e).second; #endif break; default: break; } - /*--- Compute thermodynamic state from middle of data set. ---*/ - - su2double rho_init = custom_init_rho ? val_custom_init_rho : rho_average; - su2double e_init = custom_init_e ? val_custom_init_e : e_average; - - SetTDState_rhoe(rho_init, e_init); - rho_median = rho_init; - e_median = e_init; - P_middle = Pressure; - T_middle = Temperature; - - R_idealgas = P_middle / (rho_init * T_middle); - Cv_idealgas = Cv; - Cp_idealgas = Cp; - - gamma_idealgas = (R_idealgas / Cv_idealgas) + 1; -} \ No newline at end of file + /*--- Create a five-by-five thermodynamic table used to provide initial guess for Newton solver ---*/ + coarse_TD_table = MiniTable2D(); + const size_t nTable_coarse{5}, + nP_table = nTable_coarse*nTable_coarse; + /*--- Variables included in table: density, static energy, pressure, temperature ---*/ + coarse_TD_table.SetNVars(4); + coarse_TD_table.SetNPoints(nP_table); + coarse_TD_table.SizeTable(); + /*--- Discretize thermodynamic space in terms of density and static energy ---*/ + vals_rho_table.resize(nP_table); + vals_e_table.resize(nP_table); + const su2double delta_rho = (rho_max - rho_min) / (nTable_coarse-1); + const su2double delta_e = (e_max - e_min) / (nTable_coarse-1); + /*--- Calculate thermodynamic states on the table nodes ---*/ + size_t kNode=0; + for (auto iNode=0u; iNodeCheckForVariables(varnames_PD); - break; - case ENUM_DATADRIVEN_METHOD::MLP: -#ifdef USE_MLPCPP - n_betas = 0; - for (auto iMLP = 0u; iMLP < datadriven_fluid_options.n_filenames; iMLP++) { - auto outputMap = lookup_mlp->FindVariableIndices(iMLP, varnames_PD, false); - n_betas += outputMap.size(); - } - preferential_diffusion = (n_betas == varnames_PD.size()); -#endif - break; - default: - break; - } if (!preferential_diffusion && flamelet_options.preferential_diffusion) SU2_MPI::Error("Preferential diffusion scalars not included in flamelet manifold.", CURRENT_FUNCTION); @@ -252,7 +235,8 @@ void CFluidFlamelet::PreprocessLookUp(CConfig* config) { iomap_LookUp = new MLPToolbox::CIOMap(controlling_variable_names, varnames_LookUp); lookup_mlp->PairVariableswithMLPs(*iomap_TD); lookup_mlp->PairVariableswithMLPs(*iomap_Sources); - lookup_mlp->PairVariableswithMLPs(*iomap_LookUp); + if (n_lookups > 1) + lookup_mlp->PairVariableswithMLPs(*iomap_LookUp); if (preferential_diffusion) { iomap_PD = new MLPToolbox::CIOMap(controlling_variable_names, varnames_PD); lookup_mlp->PairVariableswithMLPs(*iomap_PD); @@ -329,7 +313,7 @@ unsigned long CFluidFlamelet::EvaluateDataSet(const vector& input_sca /*--- Add all quantities and their names to the look up vectors. ---*/ - bool inside; + bool inside{true}; switch (Kind_DataDriven_Method) { case ENUM_DATADRIVEN_METHOD::LUT: if (output_refs.size() != LUT_idx.size()) @@ -339,19 +323,20 @@ unsigned long CFluidFlamelet::EvaluateDataSet(const vector& input_sca } else { inside = look_up_table->LookUp_XY(LUT_idx, output_refs, val_prog, val_enth); } - if (inside) extrapolation = 0; - else extrapolation = 1; + break; case ENUM_DATADRIVEN_METHOD::MLP: refs_vars.resize(output_refs.size()); for (auto iVar = 0u; iVar < output_refs.size(); iVar++) refs_vars[iVar] = &output_refs[iVar]; #ifdef USE_MLPCPP - extrapolation = lookup_mlp->PredictANN(iomap_Current, input_scalar, refs_vars); + inside=lookup_mlp->Predict(*iomap_Current, input_scalar, refs_vars); #endif break; default: break; } + if (inside) extrapolation = 0; + else extrapolation = 1; for (auto iVar = 0u; iVar < output_refs.size(); iVar++) AD::SetPreaccOut(output_refs[iVar]); AD::EndPreacc(); return extrapolation; diff --git a/SU2_CFD/src/integration/CFEM_DG_Integration.cpp b/SU2_CFD/src/integration/CFEM_DG_Integration.cpp index acf9f9552ca4..7236558f5d13 100644 --- a/SU2_CFD/src/integration/CFEM_DG_Integration.cpp +++ b/SU2_CFD/src/integration/CFEM_DG_Integration.cpp @@ -38,7 +38,7 @@ void CFEM_DG_Integration::SingleGrid_Iteration(CGeometry ****geometry, unsigned short iZone, unsigned short iInst) { - unsigned short iMesh, iStep, iLimit = 1; + unsigned short iMesh, iStep; unsigned short SolContainer_Position = config[iZone]->GetContainerPosition(RunTime_EqSystem); unsigned short FinestMesh = config[iZone]->GetFinestMesh(); @@ -60,12 +60,8 @@ void CFEM_DG_Integration::SingleGrid_Iteration(CGeometry ****geometry, complicated algorithm must be used to facilitate time accurate local time stepping. Note that we are currently hard-coding the classical RK4 scheme. ---*/ - bool useADER = false; - switch (config[iZone]->GetKind_TimeIntScheme()) { - case RUNGE_KUTTA_EXPLICIT: iLimit = config[iZone]->GetnRKStep(); break; - case CLASSICAL_RK4_EXPLICIT: iLimit = 4; break; - case ADER_DG: iLimit = 1; useADER = true; break; - case EULER_EXPLICIT: case EULER_IMPLICIT: iLimit = 1; break; } + unsigned short iLimit = config[iZone]->GetnRKStep(); + /*--- In case an unsteady simulation is carried out, it is possible that a synchronization time step is specified. If so, set the boolean @@ -101,7 +97,7 @@ void CFEM_DG_Integration::SingleGrid_Iteration(CGeometry ****geometry, space and time integration are tightly coupled and cannot be treated segregatedly. Therefore a different function is called for ADER to carry out the space and time integration. ---*/ - if( useADER ) { + if( config[iZone]->GetKind_TimeIntScheme() == ADER_DG ) { solver_container[iZone][iInst][iMesh][SolContainer_Position]->ADER_SpaceTimeIntegration(geometry[iZone][iInst][iMesh], solver_container[iZone][iInst][iMesh], numerics_container[iZone][iInst][iMesh][SolContainer_Position], config[iZone], iMesh, RunTime_EqSystem); diff --git a/SU2_CFD/src/integration/CMultiGridIntegration.cpp b/SU2_CFD/src/integration/CMultiGridIntegration.cpp index b616f0e66495..93960cd58f6a 100644 --- a/SU2_CFD/src/integration/CMultiGridIntegration.cpp +++ b/SU2_CFD/src/integration/CMultiGridIntegration.cpp @@ -28,6 +28,142 @@ #include "../../include/integration/CMultiGridIntegration.hpp" #include "../../../Common/include/parallelization/omp_structure.hpp" +passivedouble CMultiGridIntegration::computeMultigridCFL(CConfig* config, CSolver* solver_coarse, CGeometry* geometry_coarse, + unsigned short iMesh, passivedouble CFL_fine, passivedouble CFL_coarse_current) { + + /*--- Must be called from a single-thread context (e.g. inside BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS). ---*/ + 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; + + /*--- Get sum of all RMS residuals for all variables (local to this rank) ---*/ + su2double rms_res_coarse_local = 0.0; + for (unsigned short iVar = 0; iVar < solver_coarse->GetnVar(); iVar++) { + rms_res_coarse_local += SU2_TYPE::GetValue(solver_coarse->GetRes_RMS(iVar)); + } + + /*--- MPI synchronization: ensure all ranks use the same global residual value. ---*/ + /*--- Always reduce across ranks so all subsequent CFL logic is deterministic. ---*/ + su2double rms_global_sum = 0.0; + SU2_MPI::Allreduce(&rms_res_coarse_local, &rms_global_sum, 1, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); + passivedouble rms_res_coarse = SU2_TYPE::GetValue(rms_global_sum) / static_cast(SU2_MPI::GetSize()); + + /*--- 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; +} CMultiGridIntegration::CMultiGridIntegration() : CIntegration() { } @@ -139,7 +275,6 @@ void CMultiGridIntegration::MultiGrid_Cycle(CGeometry ****geometry, CConfig* config = config_container[iZone]; const unsigned short Solver_Position = config->GetContainerPosition(RunTime_EqSystem); - const bool classical_rk4 = (config->GetKind_TimeIntScheme() == CLASSICAL_RK4_EXPLICIT); const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); /*--- Shorter names to refer to fine grid entities. ---*/ @@ -151,67 +286,12 @@ void CMultiGridIntegration::MultiGrid_Cycle(CGeometry ****geometry, /*--- Number of RK steps. ---*/ - unsigned short iRKLimit = 1; - - switch (config->GetKind_TimeIntScheme()) { - case RUNGE_KUTTA_EXPLICIT: - iRKLimit = config->GetnRKStep(); - break; - case CLASSICAL_RK4_EXPLICIT: - iRKLimit = 4; - break; - case EULER_EXPLICIT: - case EULER_IMPLICIT: - iRKLimit = 1; - break; - } + unsigned short iRKLimit = config->GetnRKStep(); /*--- Do a presmoothing on the grid iMesh to be restricted to the grid iMesh+1 ---*/ - for (unsigned short iPreSmooth = 0; iPreSmooth < config->GetMG_PreSmooth(iMesh); iPreSmooth++) { - - /*--- Time and space integration ---*/ - - for (unsigned short iRKStep = 0; iRKStep < iRKLimit; iRKStep++) { - - /*--- Send-Receive boundary conditions, and preprocessing ---*/ - - solver_fine->Preprocessing(geometry_fine, solver_container_fine, config, iMesh, iRKStep, RunTime_EqSystem, false); - - - if (iRKStep == 0) { - - /*--- Set the old solution ---*/ - - solver_fine->Set_OldSolution(); - - if (classical_rk4) solver_fine->Set_NewSolution(); - - /*--- Compute time step, max eigenvalue, and integration scheme (steady and unsteady problems) ---*/ - - solver_fine->SetTime_Step(geometry_fine, solver_container_fine, config, iMesh, config->GetTimeIter()); - - /*--- Restrict the solution and gradient for the adjoint problem ---*/ - - Adjoint_Setup(geometry, solver_container, config_container, RunTime_EqSystem, config->GetTimeIter(), iZone); - - } - - /*--- Space integration ---*/ - - Space_Integration(geometry_fine, solver_container_fine, numerics_fine, config, iMesh, iRKStep, RunTime_EqSystem); - - /*--- 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); - - } - - } + PreSmoothing(RunTime_EqSystem, geometry, solver_container, config_container, solver_fine, numerics_fine, + geometry_fine, solver_container_fine, config, iMesh, iZone, iRKLimit); /*--- Compute Forcing Term $P_(k+1) = I^(k+1)_k(P_k+F_k(u_k))-F_(k+1)(I^(k+1)_k u_k)$ and update solution for multigrid ---*/ @@ -257,6 +337,8 @@ void CMultiGridIntegration::MultiGrid_Cycle(CGeometry ****geometry, } /*--- Recursive call to MultiGrid_Cycle (this routine). ---*/ + /*--- Execute multigrid cycles sequentially to ensure deterministic recursion order ---*/ + /*--- This prevents accumulation of floating-point variations across recursive calls ---*/ for (unsigned short imu = 0; imu <= RecursiveParam; imu++) { @@ -266,50 +348,136 @@ void CMultiGridIntegration::MultiGrid_Cycle(CGeometry ****geometry, MultiGrid_Cycle(geometry, solver_container, numerics_container, config_container, iMesh+1, nextRecurseParam, RunTime_EqSystem, iZone, iInst); + } /*--- Compute prolongated solution, and smooth the correction $u^(new)_k = u_k + Smooth(I^k_(k+1)(u_(k+1)-I^(k+1)_k u_k))$ ---*/ GetProlongated_Correction(RunTime_EqSystem, solver_fine, solver_coarse, geometry_fine, geometry_coarse, config); + /*--- Compute adaptive CFL for coarse grid (master only, with barriers for synchronization) ---*/ + BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS + { + passivedouble CFL_fine_passive = SU2_TYPE::GetValue(config->GetCFL(iMesh)); + passivedouble CFL_coarse_current_passive = SU2_TYPE::GetValue(config->GetCFL(iMesh+1)); + computeMultigridCFL(config, solver_coarse, geometry_coarse, iMesh, CFL_fine_passive, CFL_coarse_current_passive); + } + END_SU2_OMP_SAFE_GLOBAL_ACCESS + + /*--- All threads read the CFL updated by master (safe after trailing barrier above) ---*/ + const passivedouble CFL_coarse_new = SU2_TYPE::GetValue(config->GetCFL(iMesh+1)); + + /*--- Update LocalCFL at each coarse grid point ---*/ + SU2_OMP_FOR_STAT(roundUpDiv(geometry_coarse->GetnPoint(), omp_get_num_threads())) + for (auto iPoint = 0ul; iPoint < geometry_coarse->GetnPoint(); iPoint++) { + solver_coarse->GetNodes()->SetLocalCFL(iPoint, CFL_coarse_new); + } + END_SU2_OMP_FOR + SmoothProlongated_Correction(RunTime_EqSystem, solver_fine, geometry_fine, config->GetMG_CorrecSmooth(iMesh), 1.25, config); SetProlongated_Correction(solver_fine, geometry_fine, config, iMesh); - /*--- Solution post-smoothing in the prolongated grid. ---*/ - for (unsigned short iPostSmooth = 0; iPostSmooth < config->GetMG_PostSmooth(iMesh); iPostSmooth++) { + PostSmoothing(RunTime_EqSystem, solver_fine, numerics_fine, geometry_fine, solver_container_fine, + config, iMesh, iRKLimit); + } - for (unsigned short iRKStep = 0; iRKStep < iRKLimit; iRKStep++) { +} - solver_fine->Preprocessing(geometry_fine, solver_container_fine, config, iMesh, iRKStep, RunTime_EqSystem, false); +void CMultiGridIntegration::PreSmoothing(unsigned short RunTime_EqSystem, + CGeometry**** geometry, + CSolver***** solver_container, + CConfig **config_container, + CSolver* solver_fine, + CNumerics** numerics_fine, + CGeometry* geometry_fine, + CSolver** solver_container_fine, + CConfig *config, + unsigned short iMesh, + unsigned short iZone, + unsigned short iRKLimit) { - if (iRKStep == 0) { - solver_fine->Set_OldSolution(); + const bool classical_rk4 = (config->GetKind_TimeIntScheme() == CLASSICAL_RK4_EXPLICIT); + const unsigned short nPreSmooth = config->GetMG_PreSmooth(iMesh); + const unsigned long timeIter = config->GetTimeIter(); - if (classical_rk4) solver_fine->Set_NewSolution(); + /*--- Do a presmoothing on the grid iMesh to be restricted to the grid iMesh+1 ---*/ + for (unsigned short iPreSmooth = 0; iPreSmooth < nPreSmooth; iPreSmooth++) { - solver_fine->SetTime_Step(geometry_fine, solver_container_fine, config, iMesh, config->GetTimeIter()); - } + /*--- Time and space integration ---*/ + for (unsigned short iRKStep = 0; iRKStep < iRKLimit; iRKStep++) { - Space_Integration(geometry_fine, solver_container_fine, numerics_fine, config, iMesh, iRKStep, RunTime_EqSystem); + /*--- Send-Receive boundary conditions, and preprocessing ---*/ + solver_fine->Preprocessing(geometry_fine, solver_container_fine, config, iMesh, iRKStep, RunTime_EqSystem, false); - Time_Integration(geometry_fine, solver_container_fine, config, iRKStep, RunTime_EqSystem); + if (iRKStep == 0) { - solver_fine->Postprocessing(geometry_fine, solver_container_fine, config, iMesh); + /*--- Set the old solution ---*/ + solver_fine->Set_OldSolution(); + if (classical_rk4) solver_fine->Set_NewSolution(); + solver_fine->SetTime_Step(geometry_fine, solver_container_fine, config, iMesh, timeIter); + Adjoint_Setup(geometry, solver_container, config_container, RunTime_EqSystem, timeIter, iZone); } + + /*--- Space integration ---*/ + Space_Integration(geometry_fine, solver_container_fine, numerics_fine, config, iMesh, iRKStep, RunTime_EqSystem); + + /*--- 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); } } +} + +void CMultiGridIntegration::PostSmoothing(unsigned short RunTime_EqSystem, + CSolver* solver_fine, + CNumerics** numerics_fine, + CGeometry* geometry_fine, + CSolver** solver_container_fine, + CConfig *config, + unsigned short iMesh, + unsigned short iRKLimit) { + + const bool classical_rk4 = (config->GetKind_TimeIntScheme() == CLASSICAL_RK4_EXPLICIT); + const unsigned short nPostSmooth = config->GetMG_PostSmooth(iMesh); + const unsigned long timeIter = config->GetTimeIter(); + + /*--- Do a postsmoothing on the grid iMesh after prolongation from the grid iMesh+1 ---*/ + for (unsigned short iPostSmooth = 0; iPostSmooth < nPostSmooth; iPostSmooth++) { + + for (unsigned short iRKStep = 0; iRKStep < iRKLimit; iRKStep++) { + solver_fine->Preprocessing(geometry_fine, solver_container_fine, config, iMesh, iRKStep, RunTime_EqSystem, false); + if (iRKStep == 0) { + + /*--- Set the old solution ---*/ + solver_fine->Set_OldSolution(); + + if (classical_rk4) solver_fine->Set_NewSolution(); + solver_fine->SetTime_Step(geometry_fine, solver_container_fine, config, iMesh, timeIter); + } + + /*--- Space integration ---*/ + Space_Integration(geometry_fine, solver_container_fine, numerics_fine, config, iMesh, iRKStep, RunTime_EqSystem); + + /*--- 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); + + } + } } + void CMultiGridIntegration::GetProlongated_Correction(unsigned short RunTime_EqSystem, CSolver *sol_fine, CSolver *sol_coarse, CGeometry *geo_fine, CGeometry *geo_coarse, CConfig *config) { - unsigned long Point_Fine, Point_Coarse, iVertex; - unsigned short iMarker, iChildren, iVar; - su2double Area_Parent, Area_Children; const su2double *Solution_Fine = nullptr, *Solution_Coarse = nullptr; const unsigned short nVar = sol_coarse->GetnVar(); @@ -317,41 +485,47 @@ void CMultiGridIntegration::GetProlongated_Correction(unsigned short RunTime_EqS auto *Solution = new su2double[nVar]; SU2_OMP_FOR_STAT(roundUpDiv(geo_coarse->GetnPointDomain(), omp_get_num_threads())) - for (Point_Coarse = 0; Point_Coarse < geo_coarse->GetnPointDomain(); Point_Coarse++) { + for (auto Point_Coarse = 0ul; Point_Coarse < geo_coarse->GetnPointDomain(); Point_Coarse++) { - Area_Parent = geo_coarse->nodes->GetVolume(Point_Coarse); + su2double Area_Parent = geo_coarse->nodes->GetVolume(Point_Coarse); - for (iVar = 0; iVar < nVar; iVar++) Solution[iVar] = 0.0; + for (auto iVar = 0u; iVar < nVar; iVar++) Solution[iVar] = 0.0; - for (iChildren = 0; iChildren < geo_coarse->nodes->GetnChildren_CV(Point_Coarse); iChildren++) { - Point_Fine = geo_coarse->nodes->GetChildren_CV(Point_Coarse, iChildren); - Area_Children = geo_fine->nodes->GetVolume(Point_Fine); + /*--- Accumulate children contributions with stable ordering ---*/ + /*--- Process all children in sequential order to ensure deterministic FP summation ---*/ + auto nChildren = geo_coarse->nodes->GetnChildren_CV(Point_Coarse); + 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); - for (iVar = 0; iVar < nVar; iVar++) - Solution[iVar] -= Solution_Fine[iVar]*Area_Children/Area_Parent; + 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); - for (iVar = 0; iVar < nVar; iVar++) + for (auto iVar = 0u; iVar < nVar; iVar++) Solution[iVar] += Solution_Coarse[iVar]; - for (iVar = 0; iVar < nVar; iVar++) + for (auto iVar = 0u; iVar < nVar; iVar++) sol_coarse->GetNodes()->SetSolution_Old(Point_Coarse,Solution); } END_SU2_OMP_FOR delete [] Solution; + /*--- Enforce Euler wall BC on corrections by projecting to tangent plane ---*/ + sol_coarse->MultigridProjectEulerWall(geo_coarse, config, true); + /*--- Remove any contributions from no-slip walls. ---*/ - for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { + for (auto iMarker = 0u; iMarker < config->GetnMarker_All(); iMarker++) { if (config->GetViscous_Wall(iMarker)) { SU2_OMP_FOR_STAT(32) - for (iVertex = 0; iVertex < geo_coarse->nVertex[iMarker]; iVertex++) { - - Point_Coarse = geo_coarse->vertex[iMarker][iVertex]->GetNode(); + for (auto iVertex = 0ul; iVertex < geo_coarse->nVertex[iMarker]; iVertex++) { + auto Point_Coarse = geo_coarse->vertex[iMarker][iVertex]->GetNode(); /*--- For dirichlet boundary condtions, set the correction to zero. Note that Solution_Old stores the correction not the actual value ---*/ @@ -370,9 +544,9 @@ void CMultiGridIntegration::GetProlongated_Correction(unsigned short RunTime_EqS sol_coarse->CompleteComms(geo_coarse, config, MPI_QUANTITIES::SOLUTION_OLD); SU2_OMP_FOR_STAT(roundUpDiv(geo_coarse->GetnPointDomain(), omp_get_num_threads())) - for (Point_Coarse = 0; Point_Coarse < geo_coarse->GetnPointDomain(); Point_Coarse++) { - for (iChildren = 0; iChildren < geo_coarse->nodes->GetnChildren_CV(Point_Coarse); iChildren++) { - Point_Fine = geo_coarse->nodes->GetChildren_CV(Point_Coarse, iChildren); + for (auto Point_Coarse = 0ul; Point_Coarse < geo_coarse->GetnPointDomain(); Point_Coarse++) { + for (auto iChildren = 0u; iChildren < geo_coarse->nodes->GetnChildren_CV(Point_Coarse); iChildren++) { + auto Point_Fine = geo_coarse->nodes->GetChildren_CV(Point_Coarse, iChildren); sol_fine->LinSysRes.SetBlock(Point_Fine, sol_coarse->GetNodes()->GetSolution_Old(Point_Coarse)); } } @@ -387,13 +561,11 @@ void CMultiGridIntegration::SmoothProlongated_Correction(unsigned short RunTime_ if (val_nSmooth == 0) return; const su2double *Residual_Old, *Residual_Sum, *Residual_j; - unsigned short iVar, iSmooth, iMarker, iNeigh; - unsigned long iPoint, jPoint, iVertex; const unsigned short nVar = solver->GetnVar(); SU2_OMP_FOR_STAT(roundUpDiv(geometry->GetnPoint(), omp_get_num_threads())) - for (iPoint = 0; iPoint < geometry->GetnPoint(); iPoint++) { + for (auto iPoint = 0ul; iPoint < geometry->GetnPoint(); iPoint++) { Residual_Old = solver->LinSysRes.GetBlock(iPoint); solver->GetNodes()->SetResidual_Old(iPoint,Residual_Old); } @@ -401,17 +573,17 @@ void CMultiGridIntegration::SmoothProlongated_Correction(unsigned short RunTime_ /*--- Jacobi iterations. ---*/ - for (iSmooth = 0; iSmooth < val_nSmooth; iSmooth++) { + for (auto iSmooth = 0u; iSmooth < val_nSmooth; iSmooth++) { /*--- Loop over all mesh points (sum the residuals of direct neighbors). ---*/ SU2_OMP_FOR_STAT(roundUpDiv(geometry->GetnPoint(), omp_get_num_threads())) - for (iPoint = 0; iPoint < geometry->GetnPoint(); ++iPoint) { + for (auto iPoint = 0ul; iPoint < geometry->GetnPoint(); ++iPoint) { solver->GetNodes()->SetResidualSumZero(iPoint); - for (iNeigh = 0; iNeigh < geometry->nodes->GetnPoint(iPoint); ++iNeigh) { - jPoint = geometry->nodes->GetPoint(iPoint, iNeigh); + for (auto iNeigh = 0u; iNeigh < geometry->nodes->GetnPoint(iPoint); ++iNeigh) { + auto jPoint = geometry->nodes->GetPoint(iPoint, iNeigh); Residual_j = solver->LinSysRes.GetBlock(jPoint); solver->GetNodes()->AddResidual_Sum(iPoint, Residual_j); } @@ -422,28 +594,28 @@ void CMultiGridIntegration::SmoothProlongated_Correction(unsigned short RunTime_ /*--- Loop over all mesh points (update residuals with the neighbor averages). ---*/ SU2_OMP_FOR_STAT(roundUpDiv(geometry->GetnPoint(), omp_get_num_threads())) - for (iPoint = 0; iPoint < geometry->GetnPoint(); ++iPoint) { + for (auto iPoint = 0ul; iPoint < geometry->GetnPoint(); ++iPoint) { 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); - for (iVar = 0; iVar < nVar; iVar++) + for (auto iVar = 0u; iVar < nVar; iVar++) solver->LinSysRes(iPoint,iVar) = (Residual_Old[iVar] + val_smooth_coeff*Residual_Sum[iVar])*factor; } END_SU2_OMP_FOR /*--- Restore original residuals (without average) at boundary points. ---*/ - for (iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { + for (auto iMarker = 0u; iMarker < geometry->GetnMarker(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) != INTERNAL_BOUNDARY) && (config->GetMarker_All_KindBC(iMarker) != NEARFIELD_BOUNDARY) && (config->GetMarker_All_KindBC(iMarker) != PERIODIC_BOUNDARY)) { SU2_OMP_FOR_STAT(32) - for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { - iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + for (auto iVertex = 0ul; iVertex < geometry->GetnVertex(iMarker); iVertex++) { + auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); Residual_Old = solver->GetNodes()->GetResidual_Old(iPoint); solver->LinSysRes.SetBlock(iPoint, Residual_Old); } @@ -457,22 +629,22 @@ void CMultiGridIntegration::SmoothProlongated_Correction(unsigned short RunTime_ void CMultiGridIntegration::SetProlongated_Correction(CSolver *sol_fine, CGeometry *geo_fine, CConfig *config, unsigned short iMesh) { - unsigned long Point_Fine; - unsigned short iVar; su2double *Solution_Fine, *Residual_Fine; const unsigned short nVar = sol_fine->GetnVar(); const su2double factor = config->GetDamp_Correc_Prolong(); SU2_OMP_FOR_STAT(roundUpDiv(geo_fine->GetnPointDomain(), omp_get_num_threads())) - for (Point_Fine = 0; Point_Fine < geo_fine->GetnPointDomain(); Point_Fine++) { + 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); - for (iVar = 0; iVar < nVar; iVar++) { + 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]) Residual_Fine[iVar] = 0.0; - Solution_Fine[iVar] += factor*Residual_Fine[iVar]; + + su2double correction = factor * Residual_Fine[iVar]; + Solution_Fine[iVar] += correction; } } END_SU2_OMP_FOR @@ -486,13 +658,11 @@ void CMultiGridIntegration::SetProlongated_Correction(CSolver *sol_fine, CGeomet void CMultiGridIntegration::SetProlongated_Solution(unsigned short RunTime_EqSystem, CSolver *sol_fine, CSolver *sol_coarse, CGeometry *geo_fine, CGeometry *geo_coarse, CConfig *config) { - unsigned long Point_Fine, Point_Coarse; - unsigned short iChildren; SU2_OMP_FOR_STAT(roundUpDiv(geo_coarse->GetnPointDomain(), omp_get_num_threads())) - for (Point_Coarse = 0; Point_Coarse < geo_coarse->GetnPointDomain(); Point_Coarse++) { - for (iChildren = 0; iChildren < geo_coarse->nodes->GetnChildren_CV(Point_Coarse); iChildren++) { - Point_Fine = geo_coarse->nodes->GetChildren_CV(Point_Coarse, iChildren); + for (auto Point_Coarse = 0ul; Point_Coarse < geo_coarse->GetnPointDomain(); Point_Coarse++) { + for (auto iChildren = 0u; iChildren < geo_coarse->nodes->GetnChildren_CV(Point_Coarse); iChildren++) { + auto Point_Fine = geo_coarse->nodes->GetChildren_CV(Point_Coarse, iChildren); sol_fine->GetNodes()->SetSolution(Point_Fine, sol_coarse->GetNodes()->GetSolution(Point_Coarse)); } } @@ -502,8 +672,6 @@ void CMultiGridIntegration::SetProlongated_Solution(unsigned short RunTime_EqSys void CMultiGridIntegration::SetForcing_Term(CSolver *sol_fine, CSolver *sol_coarse, CGeometry *geo_fine, CGeometry *geo_coarse, CConfig *config, unsigned short iMesh) { - unsigned long Point_Fine, Point_Coarse, iVertex; - unsigned short iMarker, iVar, iChildren; const su2double *Residual_Fine; const unsigned short nVar = sol_coarse->GetnVar(); @@ -512,16 +680,15 @@ void CMultiGridIntegration::SetForcing_Term(CSolver *sol_fine, CSolver *sol_coar auto *Residual = new su2double[nVar]; SU2_OMP_FOR_STAT(roundUpDiv(geo_coarse->GetnPointDomain(), omp_get_num_threads())) - for (Point_Coarse = 0; Point_Coarse < geo_coarse->GetnPointDomain(); Point_Coarse++) { + for (auto Point_Coarse = 0ul; Point_Coarse < geo_coarse->GetnPointDomain(); Point_Coarse++) { sol_coarse->GetNodes()->SetRes_TruncErrorZero(Point_Coarse); - for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = 0.0; - - for (iChildren = 0; iChildren < geo_coarse->nodes->GetnChildren_CV(Point_Coarse); iChildren++) { - Point_Fine = geo_coarse->nodes->GetChildren_CV(Point_Coarse, iChildren); + for (auto iVar = 0u; iVar < nVar; iVar++) Residual[iVar] = 0.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 (iVar = 0; iVar < nVar; iVar++) + for (auto iVar = 0u; iVar < nVar; iVar++) Residual[iVar] += factor*Residual_Fine[iVar]; } sol_coarse->GetNodes()->AddRes_TruncError(Point_Coarse, Residual); @@ -530,11 +697,11 @@ void CMultiGridIntegration::SetForcing_Term(CSolver *sol_fine, CSolver *sol_coar delete [] Residual; - for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { + for (auto iMarker = 0u; iMarker < config->GetnMarker_All(); iMarker++) { if (config->GetViscous_Wall(iMarker)) { SU2_OMP_FOR_STAT(32) - for (iVertex = 0; iVertex < geo_coarse->nVertex[iMarker]; iVertex++) { - Point_Coarse = geo_coarse->vertex[iMarker][iVertex]->GetNode(); + for (auto iVertex = 0ul; iVertex < geo_coarse->nVertex[iMarker]; iVertex++) { + auto Point_Coarse = geo_coarse->vertex[iMarker][iVertex]->GetNode(); sol_coarse->GetNodes()->SetVel_ResTruncError_Zero(Point_Coarse); } END_SU2_OMP_FOR @@ -542,7 +709,7 @@ void CMultiGridIntegration::SetForcing_Term(CSolver *sol_fine, CSolver *sol_coar } SU2_OMP_FOR_STAT(roundUpDiv(geo_coarse->GetnPointDomain(), omp_get_num_threads())) - for (Point_Coarse = 0; Point_Coarse < geo_coarse->GetnPointDomain(); Point_Coarse++) { + for (auto Point_Coarse = 0ul; Point_Coarse < geo_coarse->GetnPointDomain(); Point_Coarse++) { sol_coarse->GetNodes()->SubtractRes_TruncError(Point_Coarse, sol_coarse->LinSysRes.GetBlock(Point_Coarse)); } END_SU2_OMP_FOR @@ -553,7 +720,7 @@ void CMultiGridIntegration::SetResidual_Term(CGeometry *geometry, CSolver *solve AD::StartNoSharedReading(); SU2_OMP_FOR_STAT(roundUpDiv(geometry->GetnPointDomain(), omp_get_num_threads())) - for (unsigned long iPoint = 0; iPoint < geometry->GetnPointDomain(); iPoint++) + for (auto iPoint = 0ul; iPoint < geometry->GetnPointDomain(); iPoint++) solver->LinSysRes.AddBlock(iPoint, solver->GetNodes()->GetResTruncError(iPoint)); END_SU2_OMP_FOR AD::EndNoSharedReading(); @@ -606,6 +773,9 @@ void CMultiGridIntegration::SetRestricted_Solution(unsigned short RunTime_EqSyst } } + /*--- Enforce Euler wall BC by projecting velocity to tangent plane ---*/ + sol_coarse->MultigridProjectEulerWall(geo_coarse, config, false); + /*--- MPI the new interpolated solution ---*/ sol_coarse->InitiateComms(geo_coarse, config, MPI_QUANTITIES::SOLUTION); @@ -615,39 +785,36 @@ void CMultiGridIntegration::SetRestricted_Solution(unsigned short RunTime_EqSyst void CMultiGridIntegration::SetRestricted_Gradient(unsigned short RunTime_EqSystem, CSolver *sol_fine, CSolver *sol_coarse, CGeometry *geo_fine, CGeometry *geo_coarse, CConfig *config) { - unsigned long Point_Fine, Point_Coarse; - unsigned short iVar, iDim, iChildren; - su2double Area_Parent, Area_Children; const unsigned short nDim = geo_coarse->GetnDim(); const unsigned short nVar = sol_coarse->GetnVar(); auto **Gradient = new su2double* [nVar]; - for (iVar = 0; iVar < nVar; iVar++) + for (auto iVar = 0u; iVar < nVar; iVar++) Gradient[iVar] = new su2double [nDim]; SU2_OMP_FOR_STAT(roundUpDiv(geo_coarse->GetnPoint(), omp_get_num_threads())) - for (Point_Coarse = 0; Point_Coarse < geo_coarse->GetnPoint(); Point_Coarse++) { - Area_Parent = geo_coarse->nodes->GetVolume(Point_Coarse); + for (auto Point_Coarse = 0ul; Point_Coarse < geo_coarse->GetnPoint(); Point_Coarse++) { + su2double Area_Parent = geo_coarse->nodes->GetVolume(Point_Coarse); - for (iVar = 0; iVar < nVar; iVar++) - for (iDim = 0; iDim < nDim; iDim++) + for (auto iVar = 0u; iVar < nVar; iVar++) + for (auto iDim = 0u; iDim < nDim; iDim++) Gradient[iVar][iDim] = 0.0; - for (iChildren = 0; iChildren < geo_coarse->nodes->GetnChildren_CV(Point_Coarse); iChildren++) { - Point_Fine = geo_coarse->nodes->GetChildren_CV(Point_Coarse, iChildren); - Area_Children = geo_fine->nodes->GetVolume(Point_Fine); + for (auto iChildren = 0u; iChildren < geo_coarse->nodes->GetnChildren_CV(Point_Coarse); iChildren++) { + unsigned long Point_Fine = geo_coarse->nodes->GetChildren_CV(Point_Coarse, iChildren); + su2double Area_Children = geo_fine->nodes->GetVolume(Point_Fine); auto Gradient_fine = sol_fine->GetNodes()->GetGradient(Point_Fine); - for (iVar = 0; iVar < nVar; iVar++) - for (iDim = 0; iDim < nDim; iDim++) + for (auto iVar = 0u; iVar < nVar; iVar++) + for (auto iDim = 0u; iDim < nDim; iDim++) Gradient[iVar][iDim] += Gradient_fine[iVar][iDim]*Area_Children/Area_Parent; } sol_coarse->GetNodes()->SetGradient(Point_Coarse,Gradient); } END_SU2_OMP_FOR - for (iVar = 0; iVar < nVar; iVar++) + for (auto iVar = 0u; iVar < nVar; iVar++) delete [] Gradient[iVar]; delete [] Gradient; diff --git a/SU2_CFD/src/interfaces/CInterface.cpp b/SU2_CFD/src/interfaces/CInterface.cpp index dce1ceb66561..299b90a90907 100644 --- a/SU2_CFD/src/interfaces/CInterface.cpp +++ b/SU2_CFD/src/interfaces/CInterface.cpp @@ -63,7 +63,7 @@ void CInterface::BroadcastData(const CInterpolator& interpolator, CSolver *donor_solution, CSolver *target_solution, CGeometry *donor_geometry, CGeometry *target_geometry, const CConfig *donor_config, const CConfig *target_config) { - static_assert(su2activematrix::Storage == StorageType::RowMajor,""); + static_assert(su2activematrix::Storage == StorageType::RowMajor); GetPhysical_Constants(donor_solution, target_solution, donor_geometry, target_geometry, donor_config, target_config); @@ -110,7 +110,7 @@ void CInterface::BroadcastData(const CInterpolator& interpolator, if (markDonor >= 0) { /*--- Apply contact resistance if specified. ---*/ - + SetContactResistance(donor_config->GetContactResistance(iMarkerInt)); for (auto iVertex = 0ul, iSend = 0ul; iVertex < donor_geometry->GetnVertex(markDonor); iVertex++) { @@ -235,7 +235,7 @@ void CInterface::PreprocessAverage(CGeometry *donor_geometry, CGeometry *target_ /*--- If the tag hasn't matched any tag within the donor markers ---*/ Marker_Donor = -1; Donor_Flag = -1; - + } #ifdef HAVE_MPI @@ -423,7 +423,7 @@ void CInterface::AllgatherAverage(CSolver *donor_solution, CSolver *target_solut } /*--- If the tag hasn't matched any tag within the donor markers ---*/ Marker_Donor = -1; - + } /*--- Here we want to make available the quantities for all the processors and collect them in a buffer * for each span of the donor the span-wise height vector also so @@ -538,7 +538,7 @@ void CInterface::AllgatherAverage(CSolver *donor_solution, CSolver *target_solut } /*--- If the tag hasn't matched any tag within the Flow markers ---*/ Marker_Target = -1; - + } diff --git a/SU2_CFD/src/iteration/CDiscAdjFEAIteration.cpp b/SU2_CFD/src/iteration/CDiscAdjFEAIteration.cpp index a6c3bfaa014e..a1425be3b7ff 100644 --- a/SU2_CFD/src/iteration/CDiscAdjFEAIteration.cpp +++ b/SU2_CFD/src/iteration/CDiscAdjFEAIteration.cpp @@ -26,13 +26,20 @@ */ #include "../../include/iteration/CDiscAdjFEAIteration.hpp" +#include "../../include/iteration/CDiscAdjHeatIteration.hpp" #include "../../include/iteration/CFEAIteration.hpp" #include "../../include/solvers/CFEASolver.hpp" #include "../../include/output/COutput.hpp" -CDiscAdjFEAIteration::CDiscAdjFEAIteration(const CConfig *config) : CIteration(config), CurrentRecording(NONE) {} +CDiscAdjFEAIteration::CDiscAdjFEAIteration(const CConfig *config) : CIteration(config), CurrentRecording(NONE) { + if (config->GetWeakly_Coupled_Heat()) { + DiscAdjHeatIteration = new CDiscAdjHeatIteration(config); + } +} -CDiscAdjFEAIteration::~CDiscAdjFEAIteration() {} +CDiscAdjFEAIteration::~CDiscAdjFEAIteration() { + delete DiscAdjHeatIteration; +} void CDiscAdjFEAIteration::Preprocess(COutput* output, CIntegration**** integration, CGeometry**** geometry, CSolver***** solver, CNumerics****** numerics, CConfig** config, @@ -90,6 +97,10 @@ void CDiscAdjFEAIteration::Preprocess(COutput* output, CIntegration**** integrat solvers0[ADJFEA_SOL]->Preprocessing(geometry0, solvers0, config[iZone], MESH_0, 0, RUNTIME_ADJFEA_SYS, false); + if (DiscAdjHeatIteration) { + DiscAdjHeatIteration->Preprocess(output, integration, geometry, solver, numerics, config, surface_movement, + grid_movement, FFDBox, iZone, iInst); + } } void CDiscAdjFEAIteration::LoadDynamic_Solution(CGeometry**** geometry, CSolver***** solver, CConfig** config, @@ -115,23 +126,23 @@ void CDiscAdjFEAIteration::IterateDiscAdj(CGeometry**** geometry, CSolver***** s unsigned short iZone, unsigned short iInst, bool CrossTerm) { /*--- Extract the adjoints of the conservative input variables and store them for the next iteration ---*/ - - solver[iZone][iInst][MESH_0][ADJFEA_SOL]->ExtractAdjoint_Solution(geometry[iZone][iInst][MESH_0], config[iZone], - CrossTerm); - - solver[iZone][iInst][MESH_0][ADJFEA_SOL]->ExtractAdjoint_Variables(geometry[iZone][iInst][MESH_0], config[iZone]); + for (const auto iSol : {ADJFEA_SOL, ADJHEAT_SOL}) { + if (auto* sol = solver[iZone][iInst][MESH_0][iSol]; sol != nullptr) { + sol->ExtractAdjoint_Solution(geometry[iZone][iInst][MESH_0], config[iZone], CrossTerm); + sol->ExtractAdjoint_Variables(geometry[iZone][iInst][MESH_0], config[iZone]); + } + } } void CDiscAdjFEAIteration::RegisterInput(CSolver***** solver, CGeometry**** geometry, CConfig** config, unsigned short iZone, unsigned short iInst, RECORDING kind_recording) { if (kind_recording != RECORDING::MESH_COORDS) { - /*--- Register structural displacements as input ---*/ - - solver[iZone][iInst][MESH_0][ADJFEA_SOL]->RegisterSolution(geometry[iZone][iInst][MESH_0], config[iZone]); - - /*--- Register variables as input ---*/ - - solver[iZone][iInst][MESH_0][ADJFEA_SOL]->RegisterVariables(geometry[iZone][iInst][MESH_0], config[iZone]); + for (const auto iSol : {ADJFEA_SOL, ADJHEAT_SOL}) { + if (auto* sol = solver[iZone][iInst][MESH_0][iSol]; sol != nullptr) { + sol->RegisterSolution(geometry[iZone][iInst][MESH_0], config[iZone]); + sol->RegisterVariables(geometry[iZone][iInst][MESH_0], config[iZone]); + } + } } else { /*--- Register topology optimization densities (note direct solver) ---*/ @@ -146,6 +157,10 @@ void CDiscAdjFEAIteration::RegisterInput(CSolver***** solver, CGeometry**** geom void CDiscAdjFEAIteration::SetDependencies(CSolver***** solver, CGeometry**** geometry, CNumerics****** numerics, CConfig** config, unsigned short iZone, unsigned short iInst, RECORDING kind_recording) { + if (DiscAdjHeatIteration) { + DiscAdjHeatIteration->SetDependencies(solver, geometry, numerics, config, iZone, iInst, kind_recording); + } + auto dir_solver = solver[iZone][iInst][MESH_0][FEA_SOL]; auto adj_solver = solver[iZone][iInst][MESH_0][ADJFEA_SOL]; auto structural_geometry = geometry[iZone][iInst][MESH_0]; @@ -263,18 +278,25 @@ void CDiscAdjFEAIteration::SetDependencies(CSolver***** solver, CGeometry**** ge void CDiscAdjFEAIteration::RegisterOutput(CSolver***** solver, CGeometry**** geometry, CConfig** config, unsigned short iZone, unsigned short iInst) { - /*--- Register conservative variables as output of the iteration ---*/ - - solver[iZone][iInst][MESH_0][ADJFEA_SOL]->RegisterOutput(geometry[iZone][iInst][MESH_0], config[iZone]); + /*--- Register solution variables as output of the iteration. ---*/ + for (const auto iSol : {ADJFEA_SOL, ADJHEAT_SOL}) { + if (auto* sol = solver[iZone][iInst][MESH_0][iSol]; sol != nullptr) { + sol->RegisterOutput(geometry[iZone][iInst][MESH_0], config[iZone]); + } + } } void CDiscAdjFEAIteration::InitializeAdjoint(CSolver***** solver, CGeometry**** geometry, CConfig** config, unsigned short iZone, unsigned short iInst) { - /*--- Initialize the adjoints the conservative variables ---*/ + /*--- Initialize the adjoints of the solution variables. ---*/ AD::ResizeAdjoints(); AD::BeginUseAdjoints(); - solver[iZone][iInst][MESH_0][ADJFEA_SOL]->SetAdjoint_Output(geometry[iZone][iInst][MESH_0], config[iZone]); + for (const auto iSol : {ADJFEA_SOL, ADJHEAT_SOL}) { + if (auto* sol = solver[iZone][iInst][MESH_0][iSol]; sol != nullptr) { + sol->SetAdjoint_Output(geometry[iZone][iInst][MESH_0], config[iZone]); + } + } AD::EndUseAdjoints(); } @@ -285,8 +307,8 @@ bool CDiscAdjFEAIteration::Monitor(COutput* output, CIntegration**** integration /*--- Write the convergence history (only screen output) ---*/ output->SetHistoryOutput(geometry[iZone][INST_0][MESH_0], solver[iZone][INST_0][MESH_0], config[iZone], - config[iZone]->GetTimeIter(), config[iZone]->GetOuterIter(), - config[iZone]->GetInnerIter()); + config[iZone]->GetTimeIter(), config[iZone]->GetOuterIter(), + config[iZone]->GetInnerIter()); return output->GetConvergence(); } diff --git a/SU2_CFD/src/iteration/CFEAIteration.cpp b/SU2_CFD/src/iteration/CFEAIteration.cpp index 13339acbcd37..42e8e485f71e 100644 --- a/SU2_CFD/src/iteration/CFEAIteration.cpp +++ b/SU2_CFD/src/iteration/CFEAIteration.cpp @@ -40,140 +40,160 @@ void CFEAIteration::Iterate(COutput* output, CIntegration**** integration, CGeom const bool nonlinear = (config[val_iZone]->GetGeometricConditions() == STRUCT_DEFORMATION::LARGE); const bool linear = (config[val_iZone]->GetGeometricConditions() == STRUCT_DEFORMATION::SMALL); + const bool heat = config[val_iZone]->GetWeakly_Coupled_Heat(); const bool disc_adj_fem = config[val_iZone]->GetDiscrete_Adjoint(); /*--- Loads applied in steps (not used for discrete adjoint). ---*/ const bool incremental_load = config[val_iZone]->GetIncrementalLoad() && !disc_adj_fem; + /*--- We need to restore the current inner iter in discrete adjoint cases because file output depends on it. ---*/ + const auto CurIter = config[val_iZone]->GetInnerIter(); + + CGeometry** geo = geometry[val_iZone][val_iInst]; CIntegration* feaIntegration = integration[val_iZone][val_iInst][FEA_SOL]; CSolver* feaSolver = solver[val_iZone][val_iInst][MESH_0][FEA_SOL]; - /*--- Add heat solver integration step. ---*/ - if (config[val_iZone]->GetWeakly_Coupled_Heat()) { + const auto nPoint = geo[MESH_0]->GetnPoint(); + const auto nDim = geo[MESH_0]->GetnDim(); + + su2activematrix Coords; + if (nonlinear && heat && Coords.empty()) { + /*--- Save the mesh coordinates to solve the heat equations in the deformed configuration + * and then restore the coordinates for the FEA solver. We could use CoordsOld of CPoint but + * that would require accounting for a lot of physics-specific logic in a geometry class. ---*/ + Coords = geo[MESH_0]->nodes->GetCoord(); + } + + auto IterateHeat = [&]() { + /*--- Update the FVM mesh for the heat solver based on the structural deformations. ---*/ + if (nonlinear) { + SU2_OMP_PARALLEL_(for schedule(static)) + for (auto iPoint = 0ul; iPoint < nPoint; ++iPoint) { + for (auto iDim = 0u; iDim < nDim; ++iDim) { + geo[MESH_0]->nodes->SetCoord(iPoint, iDim, Coords(iPoint, iDim) + feaSolver->GetNodes()->GetSolution(iPoint, iDim)); + } + } + END_SU2_OMP_PARALLEL + + CGeometry::UpdateGeometry(geo, config[val_iZone]); + } + config[val_iZone]->SetGlobalParam(MAIN_SOLVER::HEAT_EQUATION, RUNTIME_HEAT_SYS); integration[val_iZone][val_iInst][HEAT_SOL]->SingleGrid_Iteration(geometry, solver, numerics, config, RUNTIME_HEAT_SYS, val_iZone, val_iInst); - } - /*--- FEA equations ---*/ - config[val_iZone]->SetGlobalParam(MAIN_SOLVER::FEM_ELASTICITY, RUNTIME_FEA_SYS); + /*--- Restore the coordinates for the FEA solver. ---*/ + if (nonlinear) { + SU2_OMP_PARALLEL_(for schedule(static)) + for (auto iPoint = 0ul; iPoint < nPoint; ++iPoint) { + for (auto iDim = 0u; iDim < nDim; ++iDim) { + geo[MESH_0]->nodes->SetCoord(iPoint, iDim, Coords(iPoint, iDim)); + } + } + END_SU2_OMP_PARALLEL + } + }; - if (linear) { - /*--- Run the (one) iteration ---*/ + auto Iterate = [&](unsigned long IntIter) { + config[val_iZone]->SetInnerIter(IntIter); - config[val_iZone]->SetInnerIter(0); + /*--- Heat transfer equations. ---*/ + if (heat) IterateHeat(); + /*--- FEA equations. ---*/ + config[val_iZone]->SetGlobalParam(MAIN_SOLVER::FEM_ELASTICITY, RUNTIME_FEA_SYS); feaIntegration->Structural_Iteration(geometry, solver, numerics, config, RUNTIME_FEA_SYS, val_iZone, val_iInst); if (!disc_adj_fem) { - Monitor(output, integration, geometry, solver, numerics, config, surface_movement, grid_movement, FFDBox, - val_iZone, INST_0); - - /*--- Set the convergence monitor to true, to prevent the solver to stop in intermediate FSI subiterations ---*/ - output->SetConvergence(true); + StopCalc = Monitor(output, integration, geometry, solver, numerics, config, surface_movement, grid_movement, + FFDBox, val_iZone, INST_0); } + }; - } else if (nonlinear && !incremental_load) { - /*--- THIS IS THE DIRECT APPROACH (NO INCREMENTAL LOAD APPLIED) ---*/ - - /*--- Keep the current inner iter, we need to restore it in discrete adjoint cases - * because file output depends on it. ---*/ - const auto CurIter = config[val_iZone]->GetInnerIter(); + if (linear || (nonlinear && !incremental_load)) { + /*--- THIS IS THE DIRECT APPROACH (NO INCREMENTAL LOAD APPLIED) ---*/ /*--- Newton-Raphson subiterations ---*/ for (IntIter = 0; IntIter < config[val_iZone]->GetnInner_Iter(); IntIter++) { - config[val_iZone]->SetInnerIter(IntIter); - - feaIntegration->Structural_Iteration(geometry, solver, numerics, config, RUNTIME_FEA_SYS, val_iZone, val_iInst); + Iterate(IntIter); /*--- Limit to only one iteration for the discrete adjoint recording, restore inner iter (see above) ---*/ if (disc_adj_fem) { config[val_iZone]->SetInnerIter(CurIter); break; } - StopCalc = Monitor(output, integration, geometry, solver, numerics, config, surface_movement, grid_movement, - FFDBox, val_iZone, INST_0); - - if (StopCalc && (IntIter > 0)) break; + /*--- Linear elasticity without thermal effects and double precision only needs one iteration. ---*/ +#ifndef USE_MIXED_PRECISION + if (linear && !heat) { + output->SetConvergence(true); + break; + } +#endif + /*--- Normal stopping criteria. ---*/ + if (StopCalc && IntIter > 0) break; } + return; + } - } else { - /*--- THIS IS THE INCREMENTAL LOAD APPROACH (only makes sense for nonlinear) ---*/ - - /*--- Assume the initial load increment as 1.0 ---*/ + /*--- THIS IS THE INCREMENTAL LOAD APPROACH (only makes sense for nonlinear) ---*/ - feaSolver->SetLoad_Increment(0, 1.0); - feaSolver->SetForceCoeff(1.0); + /*--- Assume the initial load increment as 1.0 ---*/ + feaSolver->SetLoad_Increment(0, 1.0); + feaSolver->SetForceCoeff(1.0); - /*--- Run two nonlinear iterations to check if incremental loading can be skipped ---*/ + /*--- Run two nonlinear iterations to check if incremental loading can be skipped ---*/ + for (IntIter = 0; IntIter < 2; ++IntIter) { + Iterate(IntIter); + } - auto Iterate = [&](unsigned long IntIter) { - config[val_iZone]->SetInnerIter(IntIter); - feaIntegration->Structural_Iteration(geometry, solver, numerics, config, RUNTIME_FEA_SYS, val_iZone, val_iInst); + /*--- Early return if we already meet the convergence criteria. ---*/ + if (StopCalc) return; - StopCalc = Monitor(output, integration, geometry, solver, numerics, config, surface_movement, grid_movement, - FFDBox, val_iZone, INST_0); - }; + /*--- Check user-defined criteria to either increment loads or continue with NR iterations. ---*/ + bool meetCriteria = true; + for (int i = 0; i < 3; ++i) { + meetCriteria &= (log10(feaSolver->GetRes_FEM(i)) < config[val_iZone]->GetIncLoad_Criteria(i)); + } - for (IntIter = 0; IntIter < 2; ++IntIter) { + /*--- If the criteria is met, i.e. the load is not too large, continue the regular calculation. ---*/ + if (meetCriteria) { + for (IntIter = 2; IntIter < config[val_iZone]->GetnInner_Iter(); IntIter++) { Iterate(IntIter); + if (StopCalc) break; } + return; + } - /*--- Early return if we already meet the convergence criteria. ---*/ - if (StopCalc) return; - - /*--- Check user-defined criteria to either increment loads or continue with NR iterations. ---*/ - - bool meetCriteria = true; - for (int i = 0; i < 3; ++i) - meetCriteria &= (log10(feaSolver->GetRes_FEM(i)) < config[val_iZone]->GetIncLoad_Criteria(i)); - - /*--- If the criteria is met, i.e. the load is not too large, continue the regular calculation. ---*/ - - if (meetCriteria) { - /*--- Newton-Raphson subiterations ---*/ - - for (IntIter = 2; IntIter < config[val_iZone]->GetnInner_Iter(); IntIter++) { - Iterate(IntIter); - if (StopCalc) break; - } - - } - - /*--- If the criteria is not met, a whole set of subiterations for the different loads must be done. ---*/ - - else { - /*--- Restore solution to initial. Because we ramp the load from zero, in multizone cases it is not - * adequate to take "old values" as those will be for maximum loading on the previous outer iteration. ---*/ + /*--- If the criteria is not met, a whole set of subiterations for the different loads must be done. + * Restore solution to initial. Because we ramp the load from zero, in multizone cases it is not + * adequate to take "old values" as those will be for maximum loading on the previous outer iteration. ---*/ - feaSolver->SetInitialCondition(geometry[val_iZone][val_iInst], solver[val_iZone][val_iInst], config[val_iZone], - TimeIter); + feaSolver->SetInitialCondition(geometry[val_iZone][val_iInst], solver[val_iZone][val_iInst], config[val_iZone], + TimeIter); - /*--- For the number of increments ---*/ - for (auto iIncrement = 1ul; iIncrement <= nIncrements; iIncrement++) { - /*--- Set the load increment and the initial condition, and output the - * parameters of UTOL, RTOL, ETOL for the previous iteration ---*/ + /*--- For the number of increments ---*/ + for (auto iIncrement = 1ul; iIncrement <= nIncrements; iIncrement++) { + /*--- Set the load increment and the initial condition, and output the + * parameters of UTOL, RTOL, ETOL for the previous iteration ---*/ - su2double loadIncrement = su2double(iIncrement) / nIncrements; - feaSolver->SetLoad_Increment(iIncrement, loadIncrement); + su2double loadIncrement = su2double(iIncrement) / nIncrements; + feaSolver->SetLoad_Increment(iIncrement, loadIncrement); - /*--- Set the convergence monitor to false, to force the solver to converge every subiteration ---*/ - output->SetConvergence(false); + /*--- Set the convergence monitor to false, to force the solver to converge every subiteration. ---*/ + output->SetConvergence(false); - if (rank == MASTER_NODE) cout << "\nIncremental load: increment " << iIncrement << endl; + if (rank == MASTER_NODE) cout << "\nIncremental load: increment " << iIncrement << endl; - /*--- Newton-Raphson subiterations ---*/ + /*--- Newton-Raphson subiterations ---*/ - for (IntIter = 0; IntIter < config[val_iZone]->GetnInner_Iter(); IntIter++) { - Iterate(IntIter); - if (StopCalc && (IntIter > 0)) break; - } - } - /*--- Just to be sure, set default increment settings. ---*/ - feaSolver->SetLoad_Increment(0, 1.0); + for (IntIter = 0; IntIter < config[val_iZone]->GetnInner_Iter(); IntIter++) { + Iterate(IntIter); + if (StopCalc && IntIter > 0) break; } } + /*--- Just to be sure, set default increment settings. ---*/ + feaSolver->SetLoad_Increment(0, 1.0); } void CFEAIteration::Update(COutput* output, CIntegration**** integration, CGeometry**** geometry, CSolver***** solver, diff --git a/SU2_CFD/src/iteration/CFluidIteration.cpp b/SU2_CFD/src/iteration/CFluidIteration.cpp index 399fa59ec7b1..7231e3f4b6cf 100644 --- a/SU2_CFD/src/iteration/CFluidIteration.cpp +++ b/SU2_CFD/src/iteration/CFluidIteration.cpp @@ -340,8 +340,11 @@ void CFluidIteration::UpdateRamp(CGeometry**** geometry_container, CConfig** con const long unsigned updateFreq = RampMUSCLParam.rampMUSCLCoeff[RAMP_COEFF::UPDATE_FREQ]; const long unsigned rampLength = RampMUSCLParam.rampMUSCLCoeff[RAMP_COEFF::FINAL_ITER]; auto iterFrac = (static_cast(iter - startIter)/static_cast((rampLength + startIter) - startIter)); - if (iter < startIter) return; - if ((iter == startIter) && (rank == MASTER_NODE)) cout << "Beginning to ramp MUSCL scheme..." << endl; + if (iter < startIter) { + config->SetMUSCLRampValue(0); + return; + } + if (iter == startIter && rank == MASTER_NODE) cout << "Beginning to ramp MUSCL scheme..." << endl; if ((iter % updateFreq == 0 && iter < (rampLength + startIter)) || (iter == (rampLength + startIter))) { switch (RampMUSCLParam.Kind_MUSCLRamp) { case MUSCL_RAMP_TYPE::ITERATION: diff --git a/SU2_CFD/src/numerics/CNumerics.cpp b/SU2_CFD/src/numerics/CNumerics.cpp index f6dd575355ef..c1efac25a19e 100644 --- a/SU2_CFD/src/numerics/CNumerics.cpp +++ b/SU2_CFD/src/numerics/CNumerics.cpp @@ -249,8 +249,8 @@ void CNumerics::GetInviscidProjJac(const su2double *val_velocity, const su2doubl } void CNumerics::GetInviscidIncProjJac(const su2double *val_density, const su2double *val_velocity, - const su2double *val_betainc2, const su2double *val_enthalpy, - const su2double *val_dRhodh, const su2double *val_normal, + const su2double *val_betainc2, const su2double *val_enthalpy, + const su2double *val_dRhodh, const su2double *val_normal, su2double val_scale, su2double **val_Proj_Jac_Tensor) const { const bool wasActive = AD::BeginPassive(); unsigned short iDim; @@ -319,7 +319,7 @@ void CNumerics::GetInviscidIncProjJac(const su2double *val_density, const su2dou } void CNumerics::GetPreconditioner(const su2double *val_density, const su2double *val_velocity, - const su2double *val_betainc2, const su2double *val_enthalpy, + const su2double *val_betainc2, const su2double *val_enthalpy, const su2double *val_drhodh, su2double **val_Precon) const { unsigned short iDim, jDim; @@ -377,80 +377,6 @@ void CNumerics::GetPreconditionedProjJac(const su2double *val_density, const su2 } -void CNumerics::GetPMatrix(const su2double *val_density, const su2double *val_velocity, - const su2double *val_soundspeed, const su2double *val_normal, - su2double **val_p_tensor) const { - - su2double sqvel, rhooc, rhoxc; - //su2double c2; - - rhooc = *val_density / *val_soundspeed; - rhoxc = *val_density * *val_soundspeed; - //c2 = *val_soundspeed * *val_soundspeed; - - if (nDim == 2) { - - sqvel = val_velocity[0]*val_velocity[0]+val_velocity[1]*val_velocity[1]; - - val_p_tensor[0][0]=1.0; - val_p_tensor[0][1]=0.0; - val_p_tensor[0][2]=0.5*rhooc; - val_p_tensor[0][3]=0.5*rhooc; - - val_p_tensor[1][0]=val_velocity[0]; - val_p_tensor[1][1]=*val_density*val_normal[1]; - val_p_tensor[1][2]=0.5*(val_velocity[0]*rhooc+val_normal[0]**val_density); - val_p_tensor[1][3]=0.5*(val_velocity[0]*rhooc-val_normal[0]**val_density); - - val_p_tensor[2][0]=val_velocity[1]; - val_p_tensor[2][1]=-*val_density*val_normal[0]; - val_p_tensor[2][2]=0.5*(val_velocity[1]*rhooc+val_normal[1]**val_density); - val_p_tensor[2][3]=0.5*(val_velocity[1]*rhooc-val_normal[1]**val_density); - - val_p_tensor[3][0]=0.5*sqvel; - val_p_tensor[3][1]=*val_density*val_velocity[0]*val_normal[1]-*val_density*val_velocity[1]*val_normal[0]; - val_p_tensor[3][2]=0.5*(0.5*sqvel*rhooc+*val_density*val_velocity[0]*val_normal[0]+*val_density*val_velocity[1]*val_normal[1]+rhoxc/Gamma_Minus_One); - val_p_tensor[3][3]=0.5*(0.5*sqvel*rhooc-*val_density*val_velocity[0]*val_normal[0]-*val_density*val_velocity[1]*val_normal[1]+rhoxc/Gamma_Minus_One); - - } - else { - - sqvel = val_velocity[0]*val_velocity[0]+val_velocity[1]*val_velocity[1]+val_velocity[2]*val_velocity[2]; - - val_p_tensor[0][0]=val_normal[0]; - val_p_tensor[0][1]=val_normal[1]; - val_p_tensor[0][2]=val_normal[2]; - val_p_tensor[0][3]=0.5*rhooc; - val_p_tensor[0][4]=0.5*rhooc; - - val_p_tensor[1][0]=val_velocity[0]*val_normal[0]; - val_p_tensor[1][1]=val_velocity[0]*val_normal[1]-*val_density*val_normal[2]; - val_p_tensor[1][2]=val_velocity[0]*val_normal[2]+*val_density*val_normal[1]; - val_p_tensor[1][3]=0.5*(val_velocity[0]*rhooc+*val_density*val_normal[0]); - val_p_tensor[1][4]=0.5*(val_velocity[0]*rhooc-*val_density*val_normal[0]); - - val_p_tensor[2][0]=val_velocity[1]*val_normal[0]+*val_density*val_normal[2]; - val_p_tensor[2][1]=val_velocity[1]*val_normal[1]; - val_p_tensor[2][2]=val_velocity[1]*val_normal[2]-*val_density*val_normal[0]; - val_p_tensor[2][3]=0.5*(val_velocity[1]*rhooc+*val_density*val_normal[1]); - val_p_tensor[2][4]=0.5*(val_velocity[1]*rhooc-*val_density*val_normal[1]); - - val_p_tensor[3][0]=val_velocity[2]*val_normal[0]-*val_density*val_normal[1]; - val_p_tensor[3][1]=val_velocity[2]*val_normal[1]+*val_density*val_normal[0]; - val_p_tensor[3][2]=val_velocity[2]*val_normal[2]; - val_p_tensor[3][3]=0.5*(val_velocity[2]*rhooc+*val_density*val_normal[2]); - val_p_tensor[3][4]=0.5*(val_velocity[2]*rhooc-*val_density*val_normal[2]); - - val_p_tensor[4][0]=0.5*sqvel*val_normal[0]+*val_density*val_velocity[1]*val_normal[2]-*val_density*val_velocity[2]*val_normal[1]; - val_p_tensor[4][1]=0.5*sqvel*val_normal[1]-*val_density*val_velocity[0]*val_normal[2]+*val_density*val_velocity[2]*val_normal[0]; - val_p_tensor[4][2]=0.5*sqvel*val_normal[2]+*val_density*val_velocity[0]*val_normal[1]-*val_density*val_velocity[1]*val_normal[0]; - val_p_tensor[4][3]=0.5*(0.5*sqvel*rhooc+*val_density*(val_velocity[0]*val_normal[0]+val_velocity[1]*val_normal[1]+val_velocity[2]*val_normal[2])+rhoxc/Gamma_Minus_One); - val_p_tensor[4][4]=0.5*(0.5*sqvel*rhooc-*val_density*(val_velocity[0]*val_normal[0]+val_velocity[1]*val_normal[1]+val_velocity[2]*val_normal[2])+rhoxc/Gamma_Minus_One); - - } - -} - void CNumerics::GetPMatrix(const su2double *val_density, const su2double *val_velocity, const su2double *val_soundspeed, const su2double *val_enthalpy, const su2double *val_chi, const su2double *val_kappa, @@ -524,82 +450,6 @@ void CNumerics::GetPMatrix(const su2double *val_density, const su2double *val_ve } -void CNumerics::GetPMatrix_inv(const su2double *val_density, const su2double *val_velocity, - const su2double *val_soundspeed, const su2double *val_normal, - su2double **val_invp_tensor) const { - - su2double rhoxc, c2, gm1, k0orho, k1orho, gm1_o_c2, gm1_o_rhoxc, sqvel; - - rhoxc = *val_density * *val_soundspeed; - c2 = *val_soundspeed * *val_soundspeed; - gm1 = Gamma_Minus_One; - k0orho = val_normal[0] / *val_density; - k1orho = val_normal[1] / *val_density; - gm1_o_c2 = gm1/c2; - gm1_o_rhoxc = gm1/rhoxc; - - if (nDim == 3) { - - sqvel = val_velocity[0]*val_velocity[0]+val_velocity[1]*val_velocity[1]+val_velocity[2]*val_velocity[2]; - - val_invp_tensor[0][0]=val_normal[0]-val_normal[2]*val_velocity[1] / *val_density+val_normal[1]*val_velocity[2] / *val_density-val_normal[0]*0.5*gm1*sqvel/c2; - val_invp_tensor[0][1]=val_normal[0]*gm1*val_velocity[0]/c2; - val_invp_tensor[0][2]=val_normal[2] / *val_density+val_normal[0]*gm1*val_velocity[1]/c2; - val_invp_tensor[0][3]=-val_normal[1] / *val_density+val_normal[0]*gm1*val_velocity[2]/c2; - val_invp_tensor[0][4]=-val_normal[0]*gm1/c2; - - val_invp_tensor[1][0]=val_normal[1]+val_normal[2]*val_velocity[0] / *val_density-val_normal[0]*val_velocity[2] / *val_density-val_normal[1]*0.5*gm1*sqvel/c2; - val_invp_tensor[1][1]=-val_normal[2] / *val_density+val_normal[1]*gm1*val_velocity[0]/c2; - val_invp_tensor[1][2]=val_normal[1]*gm1*val_velocity[1]/c2; - val_invp_tensor[1][3]=val_normal[0] / *val_density+val_normal[1]*gm1*val_velocity[2]/c2; - val_invp_tensor[1][4]=-val_normal[1]*gm1/c2; - - val_invp_tensor[2][0]=val_normal[2]-val_normal[1]*val_velocity[0] / *val_density+val_normal[0]*val_velocity[1] / *val_density-val_normal[2]*0.5*gm1*sqvel/c2; - val_invp_tensor[2][1]=val_normal[1] / *val_density+val_normal[2]*gm1*val_velocity[0]/c2; - val_invp_tensor[2][2]=-val_normal[0] / *val_density+val_normal[2]*gm1*val_velocity[1]/c2; - val_invp_tensor[2][3]=val_normal[2]*gm1*val_velocity[2]/c2; - val_invp_tensor[2][4]=-val_normal[2]*gm1/c2; - - val_invp_tensor[3][0]=-(val_normal[0]*val_velocity[0]+val_normal[1]*val_velocity[1]+val_normal[2]*val_velocity[2]) / *val_density+0.5*gm1*sqvel/rhoxc; - val_invp_tensor[3][1]=val_normal[0] / *val_density-gm1*val_velocity[0]/rhoxc; - val_invp_tensor[3][2]=val_normal[1] / *val_density-gm1*val_velocity[1]/rhoxc; - val_invp_tensor[3][3]=val_normal[2] / *val_density-gm1*val_velocity[2]/rhoxc; - val_invp_tensor[3][4]=Gamma_Minus_One/rhoxc; - - val_invp_tensor[4][0]=(val_normal[0]*val_velocity[0]+val_normal[1]*val_velocity[1]+val_normal[2]*val_velocity[2]) / *val_density+0.5*gm1*sqvel/rhoxc; - val_invp_tensor[4][1]=-val_normal[0] / *val_density-gm1*val_velocity[0]/rhoxc; - val_invp_tensor[4][2]=-val_normal[1] / *val_density-gm1*val_velocity[1]/rhoxc; - val_invp_tensor[4][3]=-val_normal[2] / *val_density-gm1*val_velocity[2]/rhoxc; - val_invp_tensor[4][4]=Gamma_Minus_One/rhoxc; - - } - else { - - sqvel = val_velocity[0]*val_velocity[0]+val_velocity[1]*val_velocity[1]; - - val_invp_tensor[0][0] = 1.0-0.5*gm1_o_c2*sqvel; - val_invp_tensor[0][1]=gm1_o_c2*val_velocity[0]; - val_invp_tensor[0][2]=gm1_o_c2*val_velocity[1]; - val_invp_tensor[0][3]=-gm1_o_c2; - - val_invp_tensor[1][0]=-k1orho*val_velocity[0]+k0orho*val_velocity[1]; - val_invp_tensor[1][1]=k1orho; - val_invp_tensor[1][2]=-k0orho; - val_invp_tensor[1][3]=0.0; - - val_invp_tensor[2][0]=-k0orho*val_velocity[0]-k1orho*val_velocity[1]+0.5*gm1_o_rhoxc*sqvel; - val_invp_tensor[2][1]=k0orho-gm1_o_rhoxc*val_velocity[0]; - val_invp_tensor[2][2]=k1orho-gm1_o_rhoxc*val_velocity[1]; - val_invp_tensor[2][3]=gm1_o_rhoxc; - - val_invp_tensor[3][0]=k0orho*val_velocity[0]+k1orho*val_velocity[1]+0.5*gm1_o_rhoxc*sqvel; - val_invp_tensor[3][1]=-k0orho-gm1_o_rhoxc*val_velocity[0]; - val_invp_tensor[3][2]=-k1orho-gm1_o_rhoxc*val_velocity[1]; - val_invp_tensor[3][3]=gm1_o_rhoxc; - - } -} - void CNumerics::GetPMatrix_inv(su2double **val_invp_tensor, const su2double *val_density, const su2double *val_velocity, const su2double *val_soundspeed, const su2double *val_chi, const su2double *val_kappa, const su2double *val_normal) const { diff --git a/SU2_CFD/src/numerics/NEMO/convection/msw.cpp b/SU2_CFD/src/numerics/NEMO/convection/msw.cpp index 6f7c40eecf06..638ba6947803 100644 --- a/SU2_CFD/src/numerics/NEMO/convection/msw.cpp +++ b/SU2_CFD/src/numerics/NEMO/convection/msw.cpp @@ -30,8 +30,9 @@ CUpwMSW_NEMO::CUpwMSW_NEMO(unsigned short val_nDim, unsigned short val_nVar, unsigned short val_nPrimVar, unsigned short val_nPrimVarGrad, - CConfig *config) : CNEMONumerics(val_nDim, val_nVar, val_nPrimVar, val_nPrimVarGrad, - config) { + CConfig *config) : + CNEMONumerics(val_nDim, val_nVar, val_nPrimVar, val_nPrimVarGrad, config), + alpha(config->GetMSW_Alpha()) { /*--- Allocate arrays ---*/ Diff_U = new su2double [nVar]; @@ -109,7 +110,6 @@ CUpwMSW_NEMO::~CUpwMSW_NEMO() { CNumerics::ResidualType<> CUpwMSW_NEMO::ComputeResidual(const CConfig *config) { /*--- Set parameters in the numerical method ---*/ - const su2double alpha = 5.0; const su2double epsilon = 0.0; /*--- Calculate supporting geometry parameters ---*/ diff --git a/SU2_CFD/src/numerics/continuous_adjoint/adj_convection.cpp b/SU2_CFD/src/numerics/continuous_adjoint/adj_convection.cpp index b7f33705c786..faee679b5cb2 100644 --- a/SU2_CFD/src/numerics/continuous_adjoint/adj_convection.cpp +++ b/SU2_CFD/src/numerics/continuous_adjoint/adj_convection.cpp @@ -705,8 +705,8 @@ void CUpwRoe_AdjFlow::ComputeResidual (su2double *val_residual_i, su2double *val /*--- Compute P, inverse P, and store eigenvalues ---*/ - GetPMatrix_inv(&RoeDensity, RoeVelocity, &RoeSoundSpeed, UnitNormal, invP_Tensor); - GetPMatrix(&RoeDensity, RoeVelocity, &RoeSoundSpeed, UnitNormal, P_Tensor); + GetPMatrix_inv(RoeDensity, RoeVelocity, RoeSoundSpeed, UnitNormal, invP_Tensor); + GetPMatrix(RoeDensity, RoeVelocity, RoeSoundSpeed, UnitNormal, P_Tensor); /*--- Flow eigenvalues ---*/ diff --git a/SU2_CFD/src/numerics/elasticity/CFEAElasticity.cpp b/SU2_CFD/src/numerics/elasticity/CFEAElasticity.cpp index 9b9c6af005fa..51f21633ff48 100644 --- a/SU2_CFD/src/numerics/elasticity/CFEAElasticity.cpp +++ b/SU2_CFD/src/numerics/elasticity/CFEAElasticity.cpp @@ -43,11 +43,11 @@ CFEAElasticity::CFEAElasticity(unsigned short val_nDim, unsigned short val_nVar, /*--- Initialize vector structures for multiple material definition ---*/ const auto nProp = config->GetnElasticityMat(); - E_i = new su2double[nProp]; - Nu_i = new su2double[nProp]; - Rho_s_i = new su2double[nProp]; // For inertial effects - Rho_s_DL_i = new su2double[nProp]; // For dead loads - Alpha_i = new su2double[nProp]; + E_i.reset(new su2double[nProp]); + Nu_i.reset(new su2double[nProp]); + Rho_s_i.reset(new su2double[nProp]); // For inertial effects + Rho_s_DL_i.reset(new su2double[nProp]); // For dead loads + Alpha_i.reset(new su2double[nProp]); for (iVar = 0; iVar < nProp; iVar++) { E_i[iVar] = config->GetElasticyMod(iVar); Nu_i[iVar] = config->GetPoissonRatio(iVar); @@ -69,32 +69,7 @@ CFEAElasticity::CFEAElasticity(unsigned short val_nDim, unsigned short val_nVar, Compute_Lame_Parameters(); - KAux_ab = new su2double* [nDim]; - for (iVar = 0; iVar < nDim; iVar++) { - KAux_ab[iVar] = new su2double[nDim]; - } - - unsigned short nStrain = (nDim==2) ? DIM_STRAIN_2D : DIM_STRAIN_3D; - unsigned short nNodes = (nDim==2) ? NNODES_2D : NNODES_3D; - - Ba_Mat = new su2double* [nStrain]; - Bb_Mat = new su2double* [nStrain]; - D_Mat = new su2double* [nStrain]; - Ni_Vec = new su2double [nNodes]; - GradNi_Ref_Mat = new su2double* [nNodes]; - GradNi_Curr_Mat = new su2double* [nNodes]; - for (iVar = 0; iVar < nStrain; iVar++) { - Ba_Mat[iVar] = new su2double[nDim]; - Bb_Mat[iVar] = new su2double[nDim]; - D_Mat[iVar] = new su2double[nStrain]; - } - for (iVar = 0; iVar < nNodes; iVar++) { - GradNi_Ref_Mat[iVar] = new su2double[nDim]; - GradNi_Curr_Mat[iVar] = new su2double[nDim]; - } - - DV_Val = nullptr; - n_DV = 0; + n_DV = 0; switch (config->GetDV_FEA()) { case YOUNG_MODULUS: case POISSON_RATIO: @@ -131,44 +106,6 @@ CFEAElasticity::CFEAElasticity(unsigned short val_nDim, unsigned short val_nVar, } } -CFEAElasticity::~CFEAElasticity() { - - unsigned short iVar; - unsigned short nStrain = (nDim==2) ? DIM_STRAIN_2D : DIM_STRAIN_3D; - unsigned short nNodes = (nDim==2) ? NNODES_2D : NNODES_3D; - - for (iVar = 0; iVar < nDim; iVar++) { - delete [] KAux_ab[iVar]; - } - - for (iVar = 0; iVar < nStrain; iVar++) { - delete [] Ba_Mat[iVar]; - delete [] Bb_Mat[iVar]; - delete [] D_Mat[iVar]; - } - for (iVar = 0; iVar < nNodes; iVar++) { - delete [] GradNi_Ref_Mat[iVar]; - delete [] GradNi_Curr_Mat[iVar]; - } - - delete [] KAux_ab; - delete [] Ba_Mat; - delete [] Bb_Mat; - delete [] D_Mat; - delete [] GradNi_Ref_Mat; - delete [] GradNi_Curr_Mat; - - delete[] DV_Val; - - delete [] E_i; - delete [] Nu_i; - delete [] Rho_s_i; - delete [] Rho_s_DL_i; - delete [] Alpha_i; - delete [] Ni_Vec; -} - - void CFEAElasticity::Compute_Mass_Matrix(CElement *element, const CConfig *config) { /*--- Initialize values for the material model considered ---*/ @@ -198,6 +135,7 @@ void CFEAElasticity::Compute_Mass_Matrix(CElement *element, const CConfig *confi /*--- Retrieve the values of the shape functions for each node ---*/ /*--- This avoids repeated operations ---*/ + su2double Ni_Vec[NNODES_3D] = {}; for (iNode = 0; iNode < nNode; iNode++) { Ni_Vec[iNode] = element->GetNi(iNode,iGauss); } @@ -383,8 +321,8 @@ void CFEAElasticity::ReadDV(const CConfig *config) { if (master_node) cout << "There is no design variable file." << endl; - n_DV = 1; - DV_Val = new su2double[n_DV]; + n_DV = 1; + DV_Val.reset(new su2double[n_DV]); for (unsigned short iDV = 0; iDV < n_DV; iDV++) DV_Val[iDV] = 1.0; @@ -408,7 +346,7 @@ void CFEAElasticity::ReadDV(const CConfig *config) { properties_file.close(); n_DV = iDV; - DV_Val = new su2double[n_DV]; + DV_Val.reset(new su2double[n_DV]); /*--- Reopen the file (TODO: improve this) ---*/ diff --git a/SU2_CFD/src/numerics/elasticity/CFEALinearElasticity.cpp b/SU2_CFD/src/numerics/elasticity/CFEALinearElasticity.cpp index f9273ba0e43a..1e0bf29e0345 100644 --- a/SU2_CFD/src/numerics/elasticity/CFEALinearElasticity.cpp +++ b/SU2_CFD/src/numerics/elasticity/CFEALinearElasticity.cpp @@ -39,14 +39,12 @@ CFEALinearElasticity::CFEALinearElasticity(unsigned short val_nDim, unsigned sho void CFEALinearElasticity::Compute_Tangent_Matrix(CElement *element, const CConfig *config) { unsigned short iVar, jVar, kVar; - unsigned short iGauss, nGauss; - unsigned short iNode, jNode, nNode; + unsigned short iGauss; + unsigned short iNode, jNode; unsigned short iDim; - unsigned short bDim; - su2double Weight, Jac_X; - - su2double AuxMatrix[3][6], *res_aux = new su2double[nVar]; + su2double AuxMatrix[MAXNDIM][DIM_STRAIN_3D] = {}; + su2double Ba_Mat[DIM_STRAIN_3D][MAXNDIM] = {}, Bb_Mat[DIM_STRAIN_3D][MAXNDIM] = {}; /*--- Set element properties and recompute the constitutive matrix, this is needed for multiple material cases and for correct differentiation ---*/ @@ -62,35 +60,21 @@ void CFEALinearElasticity::Compute_Tangent_Matrix(CElement *element, const CConf Compute_Constitutive_Matrix(element, config); - /*--- Initialize auxiliary matrices ---*/ - - bDim = (nDim == 2) ? DIM_STRAIN_2D : DIM_STRAIN_3D; - - for (iVar = 0; iVar < bDim; iVar++) { - for (jVar = 0; jVar < nDim; jVar++) { - Ba_Mat[iVar][jVar] = 0.0; - Bb_Mat[iVar][jVar] = 0.0; - } - } - - for (iVar = 0; iVar < 3; iVar++) { - for (jVar = 0; jVar < 6; jVar++) { - AuxMatrix[iVar][jVar] = 0.0; - } - } - - element->ClearElement(); /*--- Restarts the element: avoids adding over previous results in other elements --*/ + /*--- Restart the element: avoids adding over previous results in other elements --*/ + element->ClearElement(); element->ComputeGrad_Linear(); - nNode = element->GetnNodes(); - nGauss = element->GetnGaussPoints(); + const auto nNode = element->GetnNodes(); + const auto nGauss = element->GetnGaussPoints(); + const auto bDim = (nDim == 2) ? DIM_STRAIN_2D : DIM_STRAIN_3D; for (iGauss = 0; iGauss < nGauss; iGauss++) { - Weight = element->GetWeight(iGauss); - Jac_X = element->GetJ_X(iGauss); + const su2double Weight = element->GetWeight(iGauss); + const su2double Jac_X = element->GetJ_X(iGauss); /*--- Retrieve the values of the gradients of the shape functions for each node ---*/ /*--- This avoids repeated operations ---*/ + su2double GradNi_Ref_Mat[NNODES_3D][MAXNDIM] = {}; for (iNode = 0; iNode < nNode; iNode++) { for (iDim = 0; iDim < nDim; iDim++) { GradNi_Ref_Mat[iNode][iDim] = element->GetGradNi_X(iNode,iGauss,iDim); @@ -101,29 +85,13 @@ void CFEALinearElasticity::Compute_Tangent_Matrix(CElement *element, const CConf for (iNode = 0; iNode < nNode; iNode++) { - su2double KAux_t_a[3] = {0.0}; + su2double KAux_t_a[MAXNDIM] = {}; for (iVar = 0; iVar < nDim; iVar++) { KAux_t_a[iVar] += Weight * thermalStress * GradNi_Ref_Mat[iNode][iVar] * Jac_X; } element->Add_Kt_a(iNode, KAux_t_a); - if (nDim == 2) { - Ba_Mat[0][0] = GradNi_Ref_Mat[iNode][0]; - Ba_Mat[1][1] = GradNi_Ref_Mat[iNode][1]; - Ba_Mat[2][0] = GradNi_Ref_Mat[iNode][1]; - Ba_Mat[2][1] = GradNi_Ref_Mat[iNode][0]; - } - else { - Ba_Mat[0][0] = GradNi_Ref_Mat[iNode][0]; - Ba_Mat[1][1] = GradNi_Ref_Mat[iNode][1]; - Ba_Mat[2][2] = GradNi_Ref_Mat[iNode][2]; - Ba_Mat[3][0] = GradNi_Ref_Mat[iNode][1]; - Ba_Mat[3][1] = GradNi_Ref_Mat[iNode][0]; - Ba_Mat[4][0] = GradNi_Ref_Mat[iNode][2]; - Ba_Mat[4][2] = GradNi_Ref_Mat[iNode][0]; - Ba_Mat[5][1] = GradNi_Ref_Mat[iNode][2]; - Ba_Mat[5][2] = GradNi_Ref_Mat[iNode][1]; - } + FillBMat(iNode, GradNi_Ref_Mat, Ba_Mat); /*--- Compute the BT.D Matrix ---*/ @@ -138,27 +106,11 @@ void CFEALinearElasticity::Compute_Tangent_Matrix(CElement *element, const CConf /*--- Assumming symmetry ---*/ for (jNode = iNode; jNode < nNode; jNode++) { - if (nDim == 2) { - Bb_Mat[0][0] = GradNi_Ref_Mat[jNode][0]; - Bb_Mat[1][1] = GradNi_Ref_Mat[jNode][1]; - Bb_Mat[2][0] = GradNi_Ref_Mat[jNode][1]; - Bb_Mat[2][1] = GradNi_Ref_Mat[jNode][0]; - } - else { - Bb_Mat[0][0] = GradNi_Ref_Mat[jNode][0]; - Bb_Mat[1][1] = GradNi_Ref_Mat[jNode][1]; - Bb_Mat[2][2] = GradNi_Ref_Mat[jNode][2]; - Bb_Mat[3][0] = GradNi_Ref_Mat[jNode][1]; - Bb_Mat[3][1] = GradNi_Ref_Mat[jNode][0]; - Bb_Mat[4][0] = GradNi_Ref_Mat[jNode][2]; - Bb_Mat[4][2] = GradNi_Ref_Mat[jNode][0]; - Bb_Mat[5][1] = GradNi_Ref_Mat[jNode][2]; - Bb_Mat[5][2] = GradNi_Ref_Mat[jNode][1]; - } + FillBMat(jNode, GradNi_Ref_Mat, Bb_Mat); + su2double KAux_ab[MAXNDIM][MAXNDIM] = {}; for (iVar = 0; iVar < nDim; iVar++) { for (jVar = 0; jVar < nDim; jVar++) { - KAux_ab[iVar][jVar] = 0.0; for (kVar = 0; kVar < bDim; kVar++) { KAux_ab[iVar][jVar] += Weight * AuxMatrix[iVar][kVar] * Bb_Mat[kVar][jVar] * Jac_X; } @@ -178,17 +130,16 @@ void CFEALinearElasticity::Compute_Tangent_Matrix(CElement *element, const CConf } /*--- Compute residual ---*/ - for(iNode = 0; iNodeGet_Kab(iNode,jNode); + su2double res_aux[MAXNDIM] = {}; for (iVar = 0; iVar < nVar; iVar++) { - res_aux[iVar] = 0.0; - for (jVar = 0; jVar < nVar; jVar++) - res_aux[iVar] += Kab[iVar*nVar+jVar]* - (element->GetCurr_Coord(jNode,jVar)-element->GetRef_Coord(jNode,jVar)); + for (jVar = 0; jVar < nVar; jVar++) { + res_aux[iVar] += Kab[iVar*nVar+jVar] * + (element->GetCurr_Coord(jNode,jVar) - element->GetRef_Coord(jNode,jVar)); + } } element->Add_Kt_a(iNode, res_aux); } @@ -197,8 +148,6 @@ void CFEALinearElasticity::Compute_Tangent_Matrix(CElement *element, const CConf /*--- Register the stress residual as preaccumulation output ---*/ element->SetPreaccOut_Kt_a(); AD::EndPreacc(); - - delete[] res_aux; } @@ -234,11 +183,12 @@ void CFEALinearElasticity::Compute_Constitutive_Matrix(CElement *element_contain su2double CFEALinearElasticity::Compute_Averaged_NodalStress(CElement *element, const CConfig *config) { unsigned short iVar, jVar; - unsigned short iGauss, nGauss; - unsigned short iNode, nNode; - unsigned short iDim, bDim; + unsigned short iGauss; + unsigned short iNode; + unsigned short iDim; - su2double avgStress[DIM_STRAIN_3D] = {0.0}; + su2double avgStress[DIM_STRAIN_3D] = {}; + su2double Ba_Mat[DIM_STRAIN_3D][MAXNDIM] = {}; /*--- Set element properties and recompute the constitutive matrix, this is needed for multiple material cases and for correct differentiation ---*/ @@ -254,25 +204,19 @@ su2double CFEALinearElasticity::Compute_Averaged_NodalStress(CElement *element, Compute_Constitutive_Matrix(element, config); - /*--- Initialize auxiliary matrices ---*/ - - bDim = (nDim == 2) ? DIM_STRAIN_2D : DIM_STRAIN_3D; - - for (iVar = 0; iVar < bDim; iVar++) { - for (jVar = 0; jVar < nDim; jVar++) { - Ba_Mat[iVar][jVar] = 0.0; - } - } - - element->ClearStress(); /*--- Clears the stress in the element to avoid adding over previous results. --*/ + /*--- Clears the stress in the element to avoid adding over previous results. --*/ + element->ClearStress(); element->ComputeGrad_Linear(); - nNode = element->GetnNodes(); - nGauss = element->GetnGaussPoints(); + + const auto nNode = element->GetnNodes(); + const auto nGauss = element->GetnGaussPoints(); + const auto bDim = (nDim == 2) ? DIM_STRAIN_2D : DIM_STRAIN_3D; for (iGauss = 0; iGauss < nGauss; iGauss++) { /*--- Retrieve the values of the gradients of the shape functions for each node ---*/ /*--- This avoids repeated operations ---*/ + su2double GradNi_Ref_Mat[NNODES_3D][MAXNDIM] = {}; for (iNode = 0; iNode < nNode; iNode++) { for (iDim = 0; iDim < nDim; iDim++) { GradNi_Ref_Mat[iNode][iDim] = element->GetGradNi_X(iNode,iGauss,iDim); @@ -280,37 +224,17 @@ su2double CFEALinearElasticity::Compute_Averaged_NodalStress(CElement *element, } } - su2double Strain[DIM_STRAIN_3D] = {0.0}; + /*--- Compute the Strain Vector as B*u ---*/ + su2double Strain[DIM_STRAIN_3D] = {}; for (iNode = 0; iNode < nNode; iNode++) { - - /*--- Set matrix B ---*/ - if (nDim == 2) { - Ba_Mat[0][0] = GradNi_Ref_Mat[iNode][0]; - Ba_Mat[1][1] = GradNi_Ref_Mat[iNode][1]; - Ba_Mat[2][0] = GradNi_Ref_Mat[iNode][1]; - Ba_Mat[2][1] = GradNi_Ref_Mat[iNode][0]; - } - else { - Ba_Mat[0][0] = GradNi_Ref_Mat[iNode][0]; - Ba_Mat[1][1] = GradNi_Ref_Mat[iNode][1]; - Ba_Mat[2][2] = GradNi_Ref_Mat[iNode][2]; - Ba_Mat[3][0] = GradNi_Ref_Mat[iNode][1]; - Ba_Mat[3][1] = GradNi_Ref_Mat[iNode][0]; - Ba_Mat[4][0] = GradNi_Ref_Mat[iNode][2]; - Ba_Mat[4][2] = GradNi_Ref_Mat[iNode][0]; - Ba_Mat[5][1] = GradNi_Ref_Mat[iNode][2]; - Ba_Mat[5][2] = GradNi_Ref_Mat[iNode][1]; - } - - /*--- Compute the Strain Vector as B*u ---*/ + FillBMat(iNode, GradNi_Ref_Mat, Ba_Mat); for (iVar = 0; iVar < bDim; iVar++) { for (jVar = 0; jVar < nDim; jVar++) { Strain[iVar] += Ba_Mat[iVar][jVar]*nodalDisplacement[iNode][jVar]; } } - } /*--- Compute the Stress Vector as D*epsilon + thermal stress ---*/ @@ -361,17 +285,9 @@ su2double CFEALinearElasticity::Compute_Averaged_NodalStress(CElement *element, CFEAMeshElasticity::CFEAMeshElasticity(unsigned short val_nDim, unsigned short val_nVar, unsigned long val_nElem, const CConfig *config) : CFEALinearElasticity() { - DV_Val = nullptr; - Rho_s_i = nullptr; - Rho_s_DL_i = nullptr; - Nu_i = nullptr; - Alpha_i = nullptr; - nDim = val_nDim; nVar = val_nVar; - unsigned long iVar; - E = 1.0; Nu = config->GetDeform_PoissonRatio(); Compute_Lame_Parameters(); @@ -386,36 +302,11 @@ CFEAMeshElasticity::CFEAMeshElasticity(unsigned short val_nDim, unsigned short v break; } - E_i = nullptr; if (element_based){ - E_i = new su2double[val_nElem]; - for (iVar = 0; iVar < val_nElem; iVar++){ + E_i.reset(new su2double[val_nElem]); + for (unsigned long iVar = 0; iVar < val_nElem; iVar++){ E_i[iVar] = E; } } - KAux_ab = new su2double* [nDim]; - for (iVar = 0; iVar < nDim; iVar++) { - KAux_ab[iVar] = new su2double[nDim]; - } - - unsigned short nStrain = (nDim==2) ? DIM_STRAIN_2D : DIM_STRAIN_3D; - unsigned short nNodes = (nDim==2) ? NNODES_2D : NNODES_3D; - - Ba_Mat = new su2double* [nStrain]; - Bb_Mat = new su2double* [nStrain]; - D_Mat = new su2double* [nStrain]; - Ni_Vec = new su2double [nNodes]; - GradNi_Ref_Mat = new su2double* [nNodes]; - GradNi_Curr_Mat = new su2double* [nNodes]; - for (iVar = 0; iVar < nStrain; iVar++) { - Ba_Mat[iVar] = new su2double[nDim]; - Bb_Mat[iVar] = new su2double[nDim]; - D_Mat[iVar] = new su2double[nStrain]; - } - for (iVar = 0; iVar < nNodes; iVar++) { - GradNi_Ref_Mat[iVar] = new su2double[nDim]; - GradNi_Curr_Mat[iVar] = new su2double[nDim]; - } - } diff --git a/SU2_CFD/src/numerics/elasticity/CFEANonlinearElasticity.cpp b/SU2_CFD/src/numerics/elasticity/CFEANonlinearElasticity.cpp index ecda59f65d75..783a4522a10b 100644 --- a/SU2_CFD/src/numerics/elasticity/CFEANonlinearElasticity.cpp +++ b/SU2_CFD/src/numerics/elasticity/CFEANonlinearElasticity.cpp @@ -34,58 +34,15 @@ CFEANonlinearElasticity::CFEANonlinearElasticity(unsigned short val_nDim, unsign nearly_incompressible = (config->GetMaterialCompressibility() == STRUCT_COMPRESS::NEARLY_INCOMP); - unsigned short iVar; - - F_Mat = new su2double *[3]; - b_Mat = new su2double *[3]; - FmT_Mat = new su2double *[3]; - Stress_Tensor = new su2double *[3]; - for (iVar = 0; iVar < 3; iVar++) { - F_Mat[iVar] = new su2double [3]; - b_Mat[iVar] = new su2double [3]; - FmT_Mat[iVar] = new su2double [3]; - Stress_Tensor[iVar] = new su2double [3]; - } - - KAux_t_a = new su2double [nDim]; - - KAux_P_ab = new su2double* [nDim]; - for (iVar = 0; iVar < nDim; iVar++) { - KAux_P_ab[iVar] = new su2double[nDim]; - } - - unsigned short nNodes = (nDim==2) ? NNODES_2D : NNODES_3D; - - currentCoord = new su2double* [nNodes]; - for (iVar = 0; iVar < nNodes; iVar++) - currentCoord[iVar] = new su2double[nDim]; - - J_F = 1.0; J_F_Iso = 1.0; + J_F = 1.0; f33 = 1.0; - C10 = Mu/2.0; - D1 = 2.0/Kappa; - - F_Mat_Iso = nullptr; - b_Mat_Iso = nullptr; - - F_Mat_Iso = new su2double *[3]; - b_Mat_Iso = new su2double *[3]; - for (iVar = 0; iVar < 3; iVar++){ - F_Mat_Iso[iVar] = new su2double [3]; - b_Mat_Iso[iVar] = new su2double [3]; - } - maxwell_stress = config->GetDE_Effects(); - ke_DE = 0.0; - nElectric_Field = 0; + ke_DE = 0.0; + nElectric_Field = 0; nDim_Electric_Field = 0; - EField_Ref_Unit = nullptr; - EField_Ref_Mod = nullptr; - EField_Curr_Unit = nullptr; - if (maxwell_stress) { const su2double *Electric_Field_Dir = config->Get_Electric_Field_Dir(); @@ -120,26 +77,26 @@ CFEANonlinearElasticity::CFEANonlinearElasticity(unsigned short val_nDim, unsign } /*--- Initialize pointer for the electric field ---*/ - EField_Ref_Unit = new su2double[nDim_Electric_Field]; + EField_Ref_Unit.reset(new su2double[nDim_Electric_Field]); /*--- Assign values to the auxiliary Electric_Field structure ---*/ for (iDim = 0; iDim < nDim_Electric_Field; iDim++) { EField_Ref_Unit[iDim] = Electric_Field_Dir[iDim]/ref_Efield_mod; } /*--- Auxiliary vector for hosting the electric field modulus in the reference configuration ---*/ - EField_Ref_Mod = new su2double[nElectric_Field]; + EField_Ref_Mod.reset(new su2double[nElectric_Field]); for (iVar = 0; iVar < nElectric_Field; iVar++) EField_Ref_Mod[iVar] = config->Get_Electric_Field_Mod(iVar); /*--- Auxiliary vector for computing the electric field in the current configuration ---*/ - EField_Curr_Unit = new su2double[nDim_Electric_Field]; + EField_Curr_Unit.reset(new su2double[nDim_Electric_Field]); for (iDim = 0; iDim < nDim_Electric_Field; iDim++) { EField_Curr_Unit[iDim] = 0.0; } /*--- Auxiliary vector for storing the electric field constant ---*/ unsigned short nElectric_Constant = config->GetnElectric_Constant(); - ke_DE_i = new su2double[nElectric_Field]; + ke_DE_i.reset(new su2double[nElectric_Field]); if (nElectric_Constant == nElectric_Field) for (iVar = 0; iVar < nElectric_Field; iVar++) ke_DE_i[iVar] = config->GetElectric_Constant(iVar); @@ -163,76 +120,19 @@ CFEANonlinearElasticity::CFEANonlinearElasticity(unsigned short val_nDim, unsign } break; } - } - } -CFEANonlinearElasticity::~CFEANonlinearElasticity() { - - unsigned short iVar; - - for (iVar = 0; iVar < 3; iVar++) { - delete [] F_Mat[iVar]; - delete [] b_Mat[iVar]; - delete [] FmT_Mat[iVar]; - delete [] Stress_Tensor[iVar]; - } - - for (iVar = 0; iVar < nDim; iVar++) { - delete [] KAux_P_ab[iVar]; - } - - unsigned short nNodes = (nDim==2) ? NNODES_2D : NNODES_3D; - - for (iVar = 0; iVar < nNodes; iVar++) { - delete [] currentCoord[iVar]; - } - - delete [] F_Mat; - delete [] b_Mat; - delete [] FmT_Mat; - delete [] Stress_Tensor; - delete [] KAux_t_a; - delete [] KAux_P_ab; - delete [] currentCoord; - - if (F_Mat_Iso != nullptr) { - for (iVar = 0; iVar < 3; iVar++){ - if (F_Mat_Iso[iVar] != nullptr) delete [] F_Mat_Iso[iVar]; - } - delete [] F_Mat_Iso; - } - if (b_Mat_Iso != nullptr){ - for (iVar = 0; iVar < 3; iVar++){ - if (b_Mat_Iso[iVar] != nullptr) delete [] b_Mat_Iso[iVar]; - } - delete [] b_Mat_Iso; - } - - delete [] EField_Ref_Unit; - delete [] EField_Ref_Mod; - delete [] EField_Curr_Unit; - - if (maxwell_stress) { - delete [] ke_DE_i; - } -} - - void CFEANonlinearElasticity::Compute_Tangent_Matrix(CElement *element, const CConfig *config) { unsigned short iVar, jVar, kVar; - unsigned short iGauss, nGauss; - unsigned short iNode, jNode, nNode; - unsigned short iDim, bDim; - - su2double Ks_Aux_ab; - - su2double Weight, Jac_x; + unsigned short iGauss; + unsigned short iNode, jNode; + unsigned short iDim; - su2double AuxMatrixKc[3][6]; - su2double AuxMatrixKs[3]; + su2double AuxMatrixKc[MAXNDIM][DIM_STRAIN_3D] = {}; + su2double AuxMatrixKs[MAXNDIM] = {}; + su2double Ba_Mat[DIM_STRAIN_3D][MAXNDIM] = {}, Bb_Mat[DIM_STRAIN_3D][MAXNDIM] = {}; /*--- TODO: Initialize values for the material model considered ---*/ // cout << "PROPERTY: " << element->Get_iProp() << " and DV " << element->Get_iDV() << endl; @@ -251,55 +151,37 @@ void CFEANonlinearElasticity::Compute_Tangent_Matrix(CElement *element, const CC /*--- Recompute Lame parameters as they depend on the material properties ---*/ Compute_Lame_Parameters(); - /*-----------------------------------------------------------*/ - - /*--- Initialize auxiliary matrices ---*/ - - bDim = (nDim == 2) ? DIM_STRAIN_2D : DIM_STRAIN_3D; - - for (iVar = 0; iVar < bDim; iVar++) { - for (jVar = 0; jVar < nDim; jVar++) { - Ba_Mat[iVar][jVar] = 0.0; - Bb_Mat[iVar][jVar] = 0.0; - } - } - - for (iVar = 0; iVar < 3; iVar++) { - for (jVar = 0; jVar < 6; jVar++) { - AuxMatrixKc[iVar][jVar] = 0.0; - } - } - - for (iVar = 0; iVar < 3; iVar++) { - AuxMatrixKs[iVar] = 0.0; - } - - element->ClearElement(); /*--- Restarts the element to avoid adding over previous results. --*/ + /*--- Restarts the element to avoid adding over previous results. --*/ + element->ClearElement(); element->ComputeGrad_Linear(); element->ComputeGrad_NonLinear(); - nNode = element->GetnNodes(); - nGauss = element->GetnGaussPoints(); + const auto nNode = element->GetnNodes(); + const auto nGauss = element->GetnGaussPoints(); + const auto bDim = (nDim == 2) ? DIM_STRAIN_2D : DIM_STRAIN_3D; /*--- Full integration of the constitutive and stress term ---*/ for (iGauss = 0; iGauss < nGauss; iGauss++) { - Weight = element->GetWeight(iGauss); - Jac_x = element->GetJ_x(iGauss); + const su2double Weight = element->GetWeight(iGauss); + const su2double Jac_x = element->GetJ_x(iGauss); /*--- Initialize the deformation gradient for each Gauss Point ---*/ - for (iVar = 0; iVar < 3; iVar++) { - for (jVar = 0; jVar < 3; jVar++) { - F_Mat[iVar][jVar] = 0.0; - b_Mat[iVar][jVar] = 0.0; + for (iVar = 0; iVar < MAXNDIM; iVar++) { + for (jVar = 0; jVar < MAXNDIM; jVar++) { + F_Mat[iVar][jVar] = 0; } } /*--- Retrieve the values of the gradients of the shape functions for each node ---*/ /*--- This avoids repeated operations ---*/ + su2double GradNi_Ref_Mat[NNODES_3D][MAXNDIM] = {}; + su2double GradNi_Curr_Mat[NNODES_3D][MAXNDIM] = {}; + su2double currentCoord[NNODES_3D][MAXNDIM] = {}; + for (iNode = 0; iNode < nNode; iNode++) { for (iDim = 0; iDim < nDim; iDim++) { @@ -330,22 +212,11 @@ void CFEANonlinearElasticity::Compute_Tangent_Matrix(CElement *element, const CC /*--- Determinant of F --> Jacobian of the transformation ---*/ - J_F = F_Mat[0][0]*F_Mat[1][1]*F_Mat[2][2]+ - F_Mat[0][1]*F_Mat[1][2]*F_Mat[2][0]+ - F_Mat[0][2]*F_Mat[1][0]*F_Mat[2][1]- - F_Mat[0][2]*F_Mat[1][1]*F_Mat[2][0]- - F_Mat[1][2]*F_Mat[2][1]*F_Mat[0][0]- - F_Mat[2][2]*F_Mat[0][1]*F_Mat[1][0]; + ComputeJ_F(); /*--- Compute the left Cauchy deformation tensor ---*/ - for (iVar = 0; iVar < 3; iVar++) { - for (jVar = 0; jVar < 3; jVar++) { - for (kVar = 0; kVar < 3; kVar++) { - b_Mat[iVar][jVar] += F_Mat[iVar][kVar]*F_Mat[jVar][kVar]; - } - } - } + ComputeLeftCauchyGreenTensor(); /*--- Compute the constitutive matrix ---*/ @@ -362,8 +233,8 @@ void CFEANonlinearElasticity::Compute_Tangent_Matrix(CElement *element, const CC /*--- Compute the nodal stress term for each gaussian point and for each node, ---*/ /*--- and add it to the element structure to be retrieved from the solver ---*/ + su2double KAux_t_a[MAXNDIM] = {}; for (iVar = 0; iVar < nDim; iVar++) { - KAux_t_a[iVar] = 0.0; for (jVar = 0; jVar < nDim; jVar++) { KAux_t_a[iVar] += Weight * Stress_Tensor[iVar][jVar] * GradNi_Curr_Mat[iNode][jVar] * Jac_x; } @@ -375,25 +246,9 @@ void CFEANonlinearElasticity::Compute_Tangent_Matrix(CElement *element, const CC /*----------------------- CONSTITUTIVE AND STRESS TERM ---------------------------*/ /*--------------------------------------------------------------------------------*/ - if (nDim == 2) { - Ba_Mat[0][0] = GradNi_Curr_Mat[iNode][0]; - Ba_Mat[1][1] = GradNi_Curr_Mat[iNode][1]; - Ba_Mat[2][0] = GradNi_Curr_Mat[iNode][1]; - Ba_Mat[2][1] = GradNi_Curr_Mat[iNode][0]; - } - else if (nDim ==3) { - Ba_Mat[0][0] = GradNi_Curr_Mat[iNode][0]; - Ba_Mat[1][1] = GradNi_Curr_Mat[iNode][1]; - Ba_Mat[2][2] = GradNi_Curr_Mat[iNode][2]; - Ba_Mat[3][0] = GradNi_Curr_Mat[iNode][1]; - Ba_Mat[3][1] = GradNi_Curr_Mat[iNode][0]; - Ba_Mat[4][0] = GradNi_Curr_Mat[iNode][2]; - Ba_Mat[4][2] = GradNi_Curr_Mat[iNode][0]; - Ba_Mat[5][1] = GradNi_Curr_Mat[iNode][2]; - Ba_Mat[5][2] = GradNi_Curr_Mat[iNode][1]; - } + FillBMat(iNode, GradNi_Curr_Mat, Ba_Mat); - /*--- Compute the BT.D Matrix ---*/ + /*--- Compute the BT.D Matrix ---*/ for (iVar = 0; iVar < nDim; iVar++) { for (jVar = 0; jVar < bDim; jVar++) { @@ -415,28 +270,12 @@ void CFEANonlinearElasticity::Compute_Tangent_Matrix(CElement *element, const CC /*--- Assumming symmetry ---*/ for (jNode = iNode; jNode < nNode; jNode++) { - if (nDim == 2) { - Bb_Mat[0][0] = GradNi_Curr_Mat[jNode][0]; - Bb_Mat[1][1] = GradNi_Curr_Mat[jNode][1]; - Bb_Mat[2][0] = GradNi_Curr_Mat[jNode][1]; - Bb_Mat[2][1] = GradNi_Curr_Mat[jNode][0]; - } - else if (nDim ==3) { - Bb_Mat[0][0] = GradNi_Curr_Mat[jNode][0]; - Bb_Mat[1][1] = GradNi_Curr_Mat[jNode][1]; - Bb_Mat[2][2] = GradNi_Curr_Mat[jNode][2]; - Bb_Mat[3][0] = GradNi_Curr_Mat[jNode][1]; - Bb_Mat[3][1] = GradNi_Curr_Mat[jNode][0]; - Bb_Mat[4][0] = GradNi_Curr_Mat[jNode][2]; - Bb_Mat[4][2] = GradNi_Curr_Mat[jNode][0]; - Bb_Mat[5][1] = GradNi_Curr_Mat[jNode][2]; - Bb_Mat[5][2] = GradNi_Curr_Mat[jNode][1]; - } + FillBMat(jNode, GradNi_Curr_Mat, Bb_Mat); /*--- KAux_ab is the term for the constitutive part of the tangent matrix ---*/ + su2double KAux_ab[MAXNDIM][MAXNDIM] = {}; for (iVar = 0; iVar < nDim; iVar++) { for (jVar = 0; jVar < nDim; jVar++) { - KAux_ab[iVar][jVar] = 0.0; for (kVar = 0; kVar < bDim; kVar++) { KAux_ab[iVar][jVar] += Weight * AuxMatrixKc[iVar][kVar] * Bb_Mat[kVar][jVar] * Jac_x; } @@ -444,7 +283,7 @@ void CFEANonlinearElasticity::Compute_Tangent_Matrix(CElement *element, const CC } /*--- Ks_Aux_ab is the term for the constitutive part of the tangent matrix ---*/ - Ks_Aux_ab = 0.0; + su2double Ks_Aux_ab = 0.0; for (iVar = 0; iVar < nDim; iVar++) { Ks_Aux_ab += Weight * AuxMatrixKs[iVar] * GradNi_Curr_Mat[jNode][iVar] * Jac_x; } @@ -471,9 +310,9 @@ void CFEANonlinearElasticity::Compute_Tangent_Matrix(CElement *element, const CC void CFEANonlinearElasticity::Compute_NodalStress_Term(CElement *element, const CConfig *config) { - unsigned short iVar, jVar, kVar; - unsigned short iGauss, nGauss; - unsigned short iNode, nNode; + unsigned short iVar, jVar; + unsigned short iGauss; + unsigned short iNode; unsigned short iDim; /*--- TODO: Initialize values for the material model considered ---*/ @@ -494,34 +333,35 @@ void CFEANonlinearElasticity::Compute_NodalStress_Term(CElement *element, const /*-----------------------------------------------------------*/ - su2double Weight, Jac_x; - element->ClearElement(); /*--- Restarts the element to avoid adding over previous results. --*/ element->ComputeGrad_Linear(); /*--- TODO: Check if we can take this out so we don't have to do it twice. ---*/ element->ComputeGrad_NonLinear(); - nNode = element->GetnNodes(); - nGauss = element->GetnGaussPoints(); + const auto nNode = element->GetnNodes(); + const auto nGauss = element->GetnGaussPoints(); /*--- Full integration of the nodal stress ---*/ for (iGauss = 0; iGauss < nGauss; iGauss++) { - Weight = element->GetWeight(iGauss); - Jac_x = element->GetJ_x(iGauss); + const su2double Weight = element->GetWeight(iGauss); + const su2double Jac_x = element->GetJ_x(iGauss); /*--- Initialize the deformation gradient for each Gauss Point ---*/ - for (iVar = 0; iVar < 3; iVar++) { - for (jVar = 0; jVar < 3; jVar++) { - F_Mat[iVar][jVar] = 0.0; - b_Mat[iVar][jVar] = 0.0; + for (iVar = 0; iVar < MAXNDIM; iVar++) { + for (jVar = 0; jVar < MAXNDIM; jVar++) { + F_Mat[iVar][jVar] = 0; } } /*--- Retrieve the values of the gradients of the shape functions for each node ---*/ /*--- This avoids repeated operations ---*/ + su2double GradNi_Ref_Mat[NNODES_3D][MAXNDIM] = {}; + su2double GradNi_Curr_Mat[NNODES_3D][MAXNDIM] = {}; + su2double currentCoord[NNODES_3D][MAXNDIM] = {}; + for (iNode = 0; iNode < nNode; iNode++) { for (iDim = 0; iDim < nDim; iDim++) { @@ -552,22 +392,11 @@ void CFEANonlinearElasticity::Compute_NodalStress_Term(CElement *element, const /*--- Determinant of F --> Jacobian of the transformation ---*/ - J_F = F_Mat[0][0]*F_Mat[1][1]*F_Mat[2][2]+ - F_Mat[0][1]*F_Mat[1][2]*F_Mat[2][0]+ - F_Mat[0][2]*F_Mat[1][0]*F_Mat[2][1]- - F_Mat[0][2]*F_Mat[1][1]*F_Mat[2][0]- - F_Mat[1][2]*F_Mat[2][1]*F_Mat[0][0]- - F_Mat[2][2]*F_Mat[0][1]*F_Mat[1][0]; + ComputeJ_F(); /*--- Compute the left Cauchy deformation tensor ---*/ - for (iVar = 0; iVar < 3; iVar++) { - for (jVar = 0; jVar < 3; jVar++) { - for (kVar = 0; kVar < 3; kVar++) { - b_Mat[iVar][jVar] += F_Mat[iVar][kVar]*F_Mat[jVar][kVar]; - } - } - } + ComputeLeftCauchyGreenTensor(); /*--- Compute the stress tensor ---*/ @@ -576,11 +405,11 @@ void CFEANonlinearElasticity::Compute_NodalStress_Term(CElement *element, const for (iNode = 0; iNode < nNode; iNode++) { - /*--- Compute the nodal stress term for each gaussian point and for each node, ---*/ - /*--- and add it to the element structure to be retrieved from the solver ---*/ + /*--- Compute the nodal stress term for each gaussian point and for each node, ---*/ + /*--- and add it to the element structure to be retrieved from the solver ---*/ + su2double KAux_t_a[MAXNDIM] = {}; for (iVar = 0; iVar < nDim; iVar++) { - KAux_t_a[iVar] = 0.0; for (jVar = 0; jVar < nDim; jVar++) { KAux_t_a[iVar] += Weight * Stress_Tensor[iVar][jVar] * GradNi_Curr_Mat[iNode][jVar] * Jac_x; } @@ -600,19 +429,18 @@ void CFEANonlinearElasticity::Compute_NodalStress_Term(CElement *element, const void CFEANonlinearElasticity::Add_MaxwellStress(CElement *element, const CConfig *config) { -// Adds the Maxwell stress to the output of the stress Sxx, Syy, Szz, SVM... - - unsigned short iDim, jDim; + // Adds the Maxwell stress to the output of the stress Sxx, Syy, Szz, SVM... su2double E0 = 0.0, E1 = 0.0, E2 = 0.0; su2double E0_2 = 0.0, E1_2 = 0.0, E2_2 = 0.0; su2double E_2 = 0.0; - Compute_FmT_Mat(); + su2double FmT_Mat[MAXNDIM][MAXNDIM] = {}; + Compute_FmT_Mat(F_Mat, J_F, FmT_Mat); - for (iDim = 0; iDim < nDim; iDim++){ + for (unsigned short iDim = 0; iDim < nDim; iDim++){ EField_Curr_Unit[iDim] = 0.0; - for (jDim = 0; jDim < nDim; jDim++){ + for (unsigned short jDim = 0; jDim < nDim; jDim++){ EField_Curr_Unit[iDim] += FmT_Mat[iDim][jDim] * EField_Ref_Unit[jDim]; } } @@ -645,41 +473,23 @@ void CFEANonlinearElasticity::SetElectric_Properties(const CElement *element, co } -void CFEANonlinearElasticity::Compute_FmT_Mat() { - - FmT_Mat[0][0] = (F_Mat[1][1]*F_Mat[2][2] - F_Mat[1][2]*F_Mat[2][1]) / J_F; - FmT_Mat[0][1] = (F_Mat[1][2]*F_Mat[2][0] - F_Mat[2][2]*F_Mat[1][0]) / J_F; - FmT_Mat[0][2] = (F_Mat[1][0]*F_Mat[2][1] - F_Mat[1][1]*F_Mat[2][0]) / J_F; - - FmT_Mat[1][0] = (F_Mat[0][2]*F_Mat[2][1] - F_Mat[0][1]*F_Mat[2][2]) / J_F; - FmT_Mat[1][1] = (F_Mat[0][0]*F_Mat[2][2] - F_Mat[2][0]*F_Mat[0][2]) / J_F; - FmT_Mat[1][2] = (F_Mat[0][1]*F_Mat[2][1] - F_Mat[0][0]*F_Mat[2][0]) / J_F; - - FmT_Mat[2][0] = (F_Mat[0][1]*F_Mat[1][2] - F_Mat[0][2]*F_Mat[1][1]) / J_F; - FmT_Mat[2][1] = (F_Mat[0][2]*F_Mat[1][0] - F_Mat[0][0]*F_Mat[1][2]) / J_F; - FmT_Mat[2][2] = (F_Mat[0][0]*F_Mat[1][1] - F_Mat[0][1]*F_Mat[1][0]) / J_F; - -} - void CFEANonlinearElasticity::Compute_Isochoric_F_b() { - unsigned short iVar, jVar, kVar; - - J_F_Iso = pow(J_F,-0.333333333333333); + const su2double J_F_Iso = pow(J_F,-0.333333333333333); // Isochoric deformation tensor - for (iVar = 0; iVar < 3; iVar++){ - for (jVar = 0; jVar < 3; jVar++){ + su2double F_Mat_Iso[MAXNDIM][MAXNDIM]; + for (unsigned short iVar = 0; iVar < MAXNDIM; iVar++) { + for (unsigned short jVar = 0; jVar < MAXNDIM; jVar++) { F_Mat_Iso[iVar][jVar] = F_Mat[iVar][jVar] * J_F_Iso; } } // Isochoric left Cauchy-Green tensor - - for (iVar = 0; iVar < 3; iVar++){ - for (jVar = 0; jVar < 3; jVar++){ + for (unsigned short iVar = 0; iVar < MAXNDIM; iVar++) { + for (unsigned short jVar = 0; jVar < MAXNDIM; jVar++) { b_Mat_Iso[iVar][jVar] = 0.0; - for (kVar = 0; kVar < 3; kVar++){ + for (unsigned short kVar = 0; kVar < MAXNDIM; kVar++) { b_Mat_Iso[iVar][jVar] += F_Mat_Iso[iVar][kVar]*F_Mat_Iso[jVar][kVar]; } } @@ -689,9 +499,7 @@ void CFEANonlinearElasticity::Compute_Isochoric_F_b() { void CFEANonlinearElasticity::Assign_cijkl_D_Mat() { - unsigned short iVar, jVar; - - if (nDim == 2){ + if (nDim == 2) { D_Mat[0][0] = cijkl[0][0][0][0]; D_Mat[1][1] = cijkl[1][1][1][1]; @@ -705,8 +513,7 @@ void CFEANonlinearElasticity::Assign_cijkl_D_Mat() { D_Mat[2][1] = cijkl[1][0][1][1]; D_Mat[2][2] = cijkl[0][1][0][1]; - } - else{ + } else { D_Mat[0][0] = cijkl[0][0][0][0]; D_Mat[1][1] = cijkl[1][1][1][1]; D_Mat[2][2] = cijkl[2][2][2][2]; @@ -734,8 +541,8 @@ void CFEANonlinearElasticity::Assign_cijkl_D_Mat() { D_Mat[4][5] = cijkl[0][2][1][2]; - for (jVar = 0; jVar < 6; jVar++){ - for (iVar = 0; iVar < jVar; iVar++){ + for (unsigned short jVar = 0; jVar < 6; jVar++){ + for (unsigned short iVar = 0; iVar < jVar; iVar++){ D_Mat[jVar][iVar] = D_Mat[iVar][jVar]; } } @@ -746,11 +553,11 @@ void CFEANonlinearElasticity::Assign_cijkl_D_Mat() { su2double CFEANonlinearElasticity::Compute_Averaged_NodalStress(CElement *element, const CConfig *config) { - unsigned short iVar, jVar, kVar; - unsigned short iGauss, nGauss; - unsigned short iDim, iNode, nNode; + unsigned short iVar, jVar; + unsigned short iGauss; + unsigned short iDim, iNode; - su2double avgStress[DIM_STRAIN_3D] = {0.0}; + su2double avgStress[DIM_STRAIN_3D] = {}; /*--- TODO: Initialize values for the material model considered ---*/ SetElement_Properties(element, config); @@ -772,35 +579,36 @@ su2double CFEANonlinearElasticity::Compute_Averaged_NodalStress(CElement *elemen /*--- Recompute Lame parameters as they depend on the material properties ---*/ Compute_Lame_Parameters(); - su2double Weight, Jac_x; - element->ClearStress(); element->ClearElement(); /*--- Restarts the element to avoid adding over previous results. ---*/ element->ComputeGrad_Linear(); element->ComputeGrad_NonLinear(); - nNode = element->GetnNodes(); - nGauss = element->GetnGaussPoints(); + const auto nNode = element->GetnNodes(); + const auto nGauss = element->GetnGaussPoints(); /*--- Computation of the deformation gradient ---*/ for (iGauss = 0; iGauss < nGauss; iGauss++) { - Weight = element->GetWeight(iGauss); - Jac_x = element->GetJ_x(iGauss); + const su2double Weight = element->GetWeight(iGauss); + const su2double Jac_x = element->GetJ_x(iGauss); /*--- Initialize the deformation gradient for each Gauss Point ---*/ - for (iVar = 0; iVar < 3; iVar++) { - for (jVar = 0; jVar < 3; jVar++) { - F_Mat[iVar][jVar] = 0.0; - b_Mat[iVar][jVar] = 0.0; + for (iVar = 0; iVar < MAXNDIM; iVar++) { + for (jVar = 0; jVar < MAXNDIM; jVar++) { + F_Mat[iVar][jVar] = 0; } } /*--- Retrieve the values of the gradients of the shape functions for each node ---*/ /*--- This avoids repeated operations ---*/ + su2double GradNi_Ref_Mat[NNODES_3D][MAXNDIM] = {}; + su2double GradNi_Curr_Mat[NNODES_3D][MAXNDIM] = {}; + su2double currentCoord[NNODES_3D][MAXNDIM] = {}; + for (iNode = 0; iNode < nNode; iNode++) { for (iDim = 0; iDim < nDim; iDim++) { @@ -831,22 +639,11 @@ su2double CFEANonlinearElasticity::Compute_Averaged_NodalStress(CElement *elemen /*--- Determinant of F --> Jacobian of the transformation ---*/ - J_F = F_Mat[0][0]*F_Mat[1][1]*F_Mat[2][2]+ - F_Mat[0][1]*F_Mat[1][2]*F_Mat[2][0]+ - F_Mat[0][2]*F_Mat[1][0]*F_Mat[2][1]- - F_Mat[0][2]*F_Mat[1][1]*F_Mat[2][0]- - F_Mat[1][2]*F_Mat[2][1]*F_Mat[0][0]- - F_Mat[2][2]*F_Mat[0][1]*F_Mat[1][0]; + ComputeJ_F(); /*--- Compute the left Cauchy deformation tensor ---*/ - for (iVar = 0; iVar < 3; iVar++) { - for (jVar = 0; jVar < 3; jVar++) { - for (kVar = 0; kVar < 3; kVar++) { - b_Mat[iVar][jVar] += F_Mat[iVar][kVar]*F_Mat[jVar][kVar]; - } - } - } + ComputeLeftCauchyGreenTensor(); /*--- Compute the stress tensor ---*/ @@ -867,8 +664,8 @@ su2double CFEANonlinearElasticity::Compute_Averaged_NodalStress(CElement *elemen /*--- Compute the nodal stress term for each gaussian point and for each node, ---*/ /*--- and add it to the element structure to be retrieved from the solver ---*/ + su2double KAux_t_a[MAXNDIM] = {}; for (iVar = 0; iVar < nDim; iVar++) { - KAux_t_a[iVar] = 0.0; for (jVar = 0; jVar < nDim; jVar++) { KAux_t_a[iVar] += Weight * Stress_Tensor[iVar][jVar] * GradNi_Curr_Mat[iNode][jVar] * Jac_x; } diff --git a/SU2_CFD/src/numerics/elasticity/nonlinear_models.cpp b/SU2_CFD/src/numerics/elasticity/nonlinear_models.cpp index 65bb63418093..90e23c38536d 100644 --- a/SU2_CFD/src/numerics/elasticity/nonlinear_models.cpp +++ b/SU2_CFD/src/numerics/elasticity/nonlinear_models.cpp @@ -181,7 +181,7 @@ void CFEM_Knowles_NearInc::Compute_Constitutive_Matrix(CElement *element, const void CFEM_Knowles_NearInc::Compute_Stress_Tensor(CElement *element, const CConfig *config, unsigned short iGauss) { - /* -- Suchocki (2011) (full reference in class constructor). ---*/ + /*--- Suchocki (2011) (full reference in class constructor). ---*/ unsigned short iVar, jVar; @@ -208,9 +208,7 @@ void CFEM_Knowles_NearInc::Compute_Stress_Tensor(CElement *element, const CConfi } CFEM_DielectricElastomer::CFEM_DielectricElastomer(unsigned short val_nDim, unsigned short val_nVar, const CConfig *config) : - CFEANonlinearElasticity(val_nDim, val_nVar, config) { - -} + CFEANonlinearElasticity(val_nDim, val_nVar, config) {} void CFEM_DielectricElastomer::Compute_Constitutive_Matrix(CElement *element, const CConfig *config) { @@ -230,36 +228,16 @@ void CFEM_DielectricElastomer::Compute_Constitutive_Matrix(CElement *element, co D_Mat[5][0] = 0.0; D_Mat[5][1] = 0.0; D_Mat[5][2] = 0.0; D_Mat[5][3] = 0.0; D_Mat[5][4] = 0.0; D_Mat[5][5] = 0.0; } - } void CFEM_DielectricElastomer::Compute_Stress_Tensor(CElement *element, const CConfig *config, unsigned short iGauss) { - unsigned short iDim, jDim; - - su2double E0 = 0.0, E1 = 0.0, E2 = 0.0; - su2double E0_2 = 0.0, E1_2 = 0.0, E2_2 = 0.0; - su2double E_2 = 0.0; - - Compute_FmT_Mat(); - - for (iDim = 0; iDim < nDim; iDim++){ - EField_Curr_Unit[iDim] = 0.0; - for (jDim = 0; jDim < nDim; jDim++){ - EField_Curr_Unit[iDim] += FmT_Mat[iDim][jDim] * EField_Ref_Unit[jDim]; + for (unsigned short iDim = 0; iDim < MAXNDIM; ++iDim) { + for (unsigned short jDim = 0; jDim < MAXNDIM; ++jDim) { + Stress_Tensor[iDim][jDim] = 0; } } - - E0 = EFieldMod_Ref*EField_Curr_Unit[0]; E0_2 = pow(E0,2); - E1 = EFieldMod_Ref*EField_Curr_Unit[1]; E1_2 = pow(E1,2); - if (nDim == 3) {E2 = EFieldMod_Ref*EField_Curr_Unit[2]; E2_2 = pow(E2,2);} - - E_2 = E0_2+E1_2+E2_2; - - Stress_Tensor[0][0] = ke_DE*(E0_2-0.5*E_2); Stress_Tensor[0][1] = ke_DE*E0*E1; Stress_Tensor[0][2] = ke_DE*E0*E2; - Stress_Tensor[1][0] = ke_DE*E1*E0; Stress_Tensor[1][1] = ke_DE*(E1_2-0.5*E_2); Stress_Tensor[1][2] = ke_DE*E1*E2; - Stress_Tensor[2][0] = ke_DE*E2*E0; Stress_Tensor[2][1] = ke_DE*E2*E1; Stress_Tensor[2][2] = ke_DE*(E2_2-0.5*E_2); - + Add_MaxwellStress(element, config); } CFEM_IdealDE::CFEM_IdealDE(unsigned short val_nDim, unsigned short val_nVar, diff --git a/SU2_CFD/src/numerics/flow/convection/ausm_slau.cpp b/SU2_CFD/src/numerics/flow/convection/ausm_slau.cpp index fb6e88234fc4..a9399a88b5b7 100644 --- a/SU2_CFD/src/numerics/flow/convection/ausm_slau.cpp +++ b/SU2_CFD/src/numerics/flow/convection/ausm_slau.cpp @@ -119,7 +119,7 @@ void CUpwAUSMPLUS_SLAU_Base_Flow::ApproximateJacobian(su2double **val_Jacobian_i /*--- Compute P and Lambda (do it with the Normal) ---*/ - GetPMatrix(&RoeDensity, RoeVelocity, &RoeSoundSpeed, UnitNormal, P_Tensor); + GetPMatrix(RoeDensity, RoeVelocity, RoeSoundSpeed, UnitNormal, P_Tensor); /*--- Flow eigenvalues and Entropy correctors ---*/ @@ -129,7 +129,7 @@ void CUpwAUSMPLUS_SLAU_Base_Flow::ApproximateJacobian(su2double **val_Jacobian_i Lambda[nVar-1] = ProjVelocity - RoeSoundSpeed; /*--- Compute inverse P ---*/ - GetPMatrix_inv(&RoeDensity, RoeVelocity, &RoeSoundSpeed, UnitNormal, invP_Tensor); + GetPMatrix_inv(RoeDensity, RoeVelocity, RoeSoundSpeed, UnitNormal, invP_Tensor); /*--- Jacobians of the inviscid flux, scale = 0.5 because val_residual ~ 0.5*(fc_i+fc_j)*Normal ---*/ GetInviscidProjJac(Velocity_i, &Energy_i, Normal, 0.5, val_Jacobian_i); @@ -928,7 +928,7 @@ CNumerics::ResidualType<> CUpwAUSM_Flow::ComputeResidual(const CConfig* config) RoeSoundSpeed = sqrt(fabs((Gamma-1)*(RoeEnthalpy-0.5*sq_vel))); /*--- Compute P and Lambda (do it with the Normal) ---*/ - GetPMatrix(&RoeDensity, RoeVelocity, &RoeSoundSpeed, UnitNormal, P_Tensor); + GetPMatrix(RoeDensity, RoeVelocity, RoeSoundSpeed, UnitNormal, P_Tensor); ProjVelocity = 0.0; ProjVelocity_i = 0.0; ProjVelocity_j = 0.0; for (iDim = 0; iDim < nDim; iDim++) { @@ -944,7 +944,7 @@ CNumerics::ResidualType<> CUpwAUSM_Flow::ComputeResidual(const CConfig* config) Lambda[nVar-1] = ProjVelocity - RoeSoundSpeed; /*--- Compute inverse P ---*/ - GetPMatrix_inv(&RoeDensity, RoeVelocity, &RoeSoundSpeed, UnitNormal, invP_Tensor); + GetPMatrix_inv(RoeDensity, RoeVelocity, RoeSoundSpeed, UnitNormal, invP_Tensor); /*--- Jacobias of the inviscid flux, scale = 0.5 because val_residual ~ 0.5*(fc_i+fc_j)*Normal ---*/ GetInviscidProjJac(Velocity_i, &Energy_i, Normal, 0.5, Jacobian_i); diff --git a/SU2_CFD/src/numerics/flow/convection/fvs.cpp b/SU2_CFD/src/numerics/flow/convection/fvs.cpp index 110207b9592b..bfa04b5f3509 100644 --- a/SU2_CFD/src/numerics/flow/convection/fvs.cpp +++ b/SU2_CFD/src/numerics/flow/convection/fvs.cpp @@ -28,227 +28,155 @@ #include "../../../../include/numerics/flow/convection/fvs.hpp" #include "../../../../../Common/include/toolboxes/geometry_toolbox.hpp" -CUpwMSW_Flow::CUpwMSW_Flow(unsigned short val_nDim, unsigned short val_nVar, const CConfig* config) : CNumerics(val_nDim, val_nVar, config) { - - if (config->GetDynamic_Grid() && (SU2_MPI::GetRank() == MASTER_NODE)) - cout << "WARNING: Grid velocities are NOT yet considered in the MSW scheme." << endl; - - /*--- Set booleans from CConfig settings ---*/ - implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); +CUpwMSW_Flow::CUpwMSW_Flow(unsigned short val_nDim, unsigned short val_nVar, const CConfig* config) : + CNumerics(val_nDim, val_nVar, config), + alpha(config->GetMSW_Alpha()), + dynamic_grid(config->GetDynamic_Grid()) { /*--- Allocate arrays ---*/ - Fc_i = new su2double [nVar]; - Fc_j = new su2double [nVar]; - Lambda_i = new su2double [nVar]; - Lambda_j = new su2double [nVar]; - - u_i = new su2double [nDim]; - u_j = new su2double [nDim]; - ust_i = new su2double [nDim]; - ust_j = new su2double [nDim]; - Vst_i = new su2double [nDim+5]; - Vst_j = new su2double [nDim+5]; - - Velst_i = new su2double [nDim]; - Velst_j = new su2double [nDim]; - - P_Tensor = new su2double* [nVar]; - invP_Tensor= new su2double* [nVar]; - Jacobian_i = new su2double* [nVar]; - Jacobian_j = new su2double* [nVar]; for (unsigned short iVar = 0; iVar < nVar; iVar++) { - P_Tensor[iVar] = new su2double [nVar]; - invP_Tensor[iVar] = new su2double [nVar]; - Jacobian_i[iVar] = new su2double [nVar]; - Jacobian_j[iVar] = new su2double [nVar]; + Jacobian_i[iVar] = &buf_Jacobian_i[iVar * MAXNVAR]; + Jacobian_j[iVar] = &buf_Jacobian_j[iVar * MAXNVAR]; } - -} - -CUpwMSW_Flow::~CUpwMSW_Flow() { - - delete [] Fc_i; - delete [] Fc_j; - delete [] Lambda_i; - delete [] Lambda_j; - - delete [] u_i; - delete [] u_j; - delete [] ust_i; - delete [] ust_j; - delete [] Vst_i; - delete [] Vst_j; - delete [] Velst_i; - delete [] Velst_j; - - for (unsigned short iVar = 0; iVar < nVar; iVar++) { - delete [] P_Tensor[iVar]; - delete [] invP_Tensor[iVar]; - delete [] Jacobian_i[iVar]; - delete [] Jacobian_j[iVar]; - } - delete [] P_Tensor; - delete [] invP_Tensor; - delete [] Jacobian_i; - delete [] Jacobian_j; - } CNumerics::ResidualType<> CUpwMSW_Flow::ComputeResidual(const CConfig* config) { - implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); - - unsigned short iDim, iVar, jVar, kVar; - su2double rho_i, rho_j, P_i, P_j, H_i, H_j; - su2double ProjVel_i, ProjVel_j, ProjVelst_i, ProjVelst_j; - su2double sqvel_i, sqvel_j; - su2double alpha, w, dp, onemw; - su2double Proj_ModJac_Tensor_i, Proj_ModJac_Tensor_j; - - /*--- Set parameters in the numerical method ---*/ - alpha = 6.0; + AD::StartPreacc(); + AD::SetPreaccIn(V_i, nDim + 4); + AD::SetPreaccIn(V_j, nDim + 4); + AD::SetPreaccIn(Sensor_i, Sensor_j); + AD::SetPreaccIn(Normal, nDim); + if (dynamic_grid) { + AD::SetPreaccIn(GridVel_i, nDim); + AD::SetPreaccIn(GridVel_j, nDim); + } /*--- Calculate supporting geometry parameters ---*/ - Area = GeometryToolbox::Norm(nDim, Normal); - - for (iDim = 0; iDim < nDim; iDim++) - UnitNormal[iDim] = Normal[iDim]/Area; + const su2double Area = GeometryToolbox::Norm(nDim, Normal); - /*--- Initialize flux & Jacobian vectors ---*/ - - for (iVar = 0; iVar < nVar; iVar++) { - Fc_i[iVar] = 0.0; - Fc_j[iVar] = 0.0; - } - if (implicit) { - for (iVar = 0; iVar < nVar; iVar++) { - for (jVar = 0; jVar < nVar; jVar++) { - Jacobian_i[iVar][jVar] = 0.0; - Jacobian_j[iVar][jVar] = 0.0; - } - } + for (auto iDim = 0u; iDim < nDim; ++iDim) { + UnitNormal[iDim] = Normal[iDim] / Area; } /*--- Load variables from nodes i & j ---*/ - for (iDim = 0; iDim < nDim; iDim++) { - u_i[iDim] = V_i[iDim+1]; - u_j[iDim] = V_j[iDim+1]; - } - P_i = V_i[nDim+1]; - P_j = V_j[nDim+1]; - rho_i = V_i[nDim+2]; - rho_j = V_j[nDim+2]; - H_i = V_i[nDim+3]; - H_j = V_j[nDim+3]; + const su2double P_i = V_i[nDim + 1]; + const su2double P_j = V_j[nDim + 1]; + const su2double rho_i = V_i[nDim + 2]; + const su2double rho_j = V_j[nDim + 2]; + const su2double H_i = V_i[nDim + 3]; + const su2double H_j = V_j[nDim + 3]; + /*--- Recompute the speed of sound because it is not MUSCL-reconstructed. ---*/ + const su2double sqvel_i = GeometryToolbox::SquaredNorm(nDim, V_i + 1); + const su2double sqvel_j = GeometryToolbox::SquaredNorm(nDim, V_j + 1); + const su2double c_i = sqrt(fmax((Gamma - 1) * (H_i - 0.5 * sqvel_i), EPS)); + const su2double c_j = sqrt(fmax((Gamma - 1) * (H_j - 0.5 * sqvel_j), EPS)); /*--- Recompute conservatives ---*/ - su2double U_i[5] = {0.0}, U_j[5] = {0.0}; - - U_i[0] = rho_i; U_j[0] = rho_j; - for (iDim = 0; iDim < nDim; iDim++) { - U_i[iDim+1] = rho_i*u_i[iDim]; - U_j[iDim+1] = rho_j*u_j[iDim]; - } - U_i[nDim+1] = rho_i*H_i - P_i; - U_j[nDim+1] = rho_j*H_j - P_j; - - /*--- Calculate supporting quantities ---*/ - - sqvel_i = 0.0; sqvel_j = 0.0; - ProjVel_i = 0.0; ProjVel_j = 0.0; - for (iDim = 0; iDim < nDim; iDim++) { - sqvel_i += u_i[iDim]*u_i[iDim]; - sqvel_j += u_j[iDim]*u_j[iDim]; - ProjVel_i += u_i[iDim]*UnitNormal[iDim]; - ProjVel_j += u_j[iDim]*UnitNormal[iDim]; + su2double U_i[MAXNVAR] = {}, U_j[MAXNVAR] = {}; + U_i[0] = rho_i; + U_j[0] = rho_j; + for (auto iDim = 0u; iDim < nDim; ++iDim) { + U_i[iDim + 1] = rho_i * V_i[iDim + 1]; + U_j[iDim + 1] = rho_j * V_j[iDim + 1]; } + U_i[nDim + 1] = rho_i * H_i - P_i; + U_j[nDim + 1] = rho_j * H_j - P_j; /*--- Calculate the state weighting function ---*/ - dp = fabs(P_j-P_i) / min(P_j, P_i); - w = 0.5 * (1.0/(pow(alpha*dp,2.0) +1.0)); - onemw = 1.0 - w; + /*--- For completeness, the original formulation for the switch to unmodified Steger-Warming is: + * dp = fabs(P_j - P_i) / fmin(P_j, P_i) + * w = 0.5 * (1 / (pow(alpha * dp, 2) + 1)) + * where alpha is a tuning constant to make the scheme switch sooner (large alpha). + * We're using a version of the switch based on the maximum "dp" over neighbors, from + * "Development of an Unstructured Navier-Stokes Solver For Hypersonic Nonequilibrium + * Aerothermodynamics". The 0.06 constant is to match our default alpha (5) to the threshold + * of 0.3 in the paper. ---*/ + const su2double dp = fmax(Sensor_i, Sensor_j) - alpha * 0.06; + const su2double w = 0.25 * (1 - (dp > 0 ? 1 : -1) * (1 - exp(-100 *fabs(dp)))); + const su2double onemw = 1 - w; /*--- Calculate weighted state vector (*) for i & j ---*/ - for (iVar = 0; iVar < nDim+5; iVar++) { - Vst_i[iVar] = onemw*V_i[iVar] + w*V_j[iVar]; - Vst_j[iVar] = onemw*V_j[iVar] + w*V_i[iVar]; + su2double Vst_i[MAXNDIM + 5] = {}, Vst_j[MAXNDIM + 5] = {}; + for (auto iVar = 0; iVar < nDim + 4; ++iVar) { + Vst_i[iVar] = onemw * V_i[iVar] + w * V_j[iVar]; + Vst_j[iVar] = onemw * V_j[iVar] + w * V_i[iVar]; } - ProjVelst_i = onemw*ProjVel_i + w*ProjVel_j; - ProjVelst_j = onemw*ProjVel_j + w*ProjVel_i; + Vst_i[nDim + 4] = onemw * c_i + w * c_j; + Vst_j[nDim + 4] = onemw * c_j + w * c_i; + + su2double Velst_i[MAXNDIM] = {}, Velst_j[MAXNDIM] = {}; + su2double ProjVelst_i{}, ProjVelst_j{}; + for (auto iDim = 0u; iDim < nDim; ++iDim) { + Velst_i[iDim] = Vst_i[iDim + 1]; + Velst_j[iDim] = Vst_j[iDim + 1]; - for (iDim = 0; iDim < nDim; iDim++) { - Velst_i[iDim] = Vst_i[iDim+1]; - Velst_j[iDim] = Vst_j[iDim+1]; + ProjVelst_i += (Velst_i[iDim] - (dynamic_grid ? GridVel_i[iDim] : 0)) * UnitNormal[iDim]; + ProjVelst_j += (Velst_j[iDim] - (dynamic_grid ? GridVel_j[iDim] : 0)) * UnitNormal[iDim]; } /*--- Flow eigenvalues at i (Lambda+) ---*/ - for (iDim = 0; iDim < nDim; iDim++) { - Lambda_i[iDim] = 0.5*(ProjVelst_i + fabs(ProjVelst_i)); + su2double Lambda[MAXNVAR] = {}; + for (auto iDim = 0u; iDim < nDim; ++iDim) { + Lambda[iDim] = fmax(ProjVelst_i, 0); } - - Lambda_i[nDim] = 0.5*( ProjVelst_i + Vst_i[nDim+4] + fabs(ProjVelst_i + Vst_i[nDim+4]) ); - Lambda_i[nDim+1] = 0.5*( ProjVelst_i - Vst_i[nDim+4] + fabs(ProjVelst_i - Vst_i[nDim+4]) ); + Lambda[nDim] = fmax(ProjVelst_i + Vst_i[nDim + 4], 0); + Lambda[nDim + 1] = fmax(ProjVelst_i - Vst_i[nDim + 4], 0); /*--- Compute projected P, invP, and Lambda ---*/ - GetPMatrix(&Vst_i[nDim+2], Velst_i, &Vst_i[nDim+4], UnitNormal, P_Tensor); - GetPMatrix_inv(&Vst_i[nDim+2], Velst_i, &Vst_i[nDim+4], UnitNormal, invP_Tensor); + su2double P_Tensor[MAXNVAR][MAXNVAR], invP_Tensor[MAXNVAR][MAXNVAR]; + GetPMatrix(Vst_i[nDim + 2], Velst_i, Vst_i[nDim + 4], UnitNormal, P_Tensor); + GetPMatrix_inv(Vst_i[nDim + 2], Velst_i, Vst_i[nDim + 4], UnitNormal, invP_Tensor); /*--- Projected flux (f+) at i ---*/ - for (iVar = 0; iVar < nVar; iVar++) { - for (jVar = 0; jVar < nVar; jVar++) { - Proj_ModJac_Tensor_i = 0.0; - - /*--- Compute Proj_ModJac_Tensor = P x Lambda+ x inverse P ---*/ - - for (kVar = 0; kVar < nVar; kVar++) - Proj_ModJac_Tensor_i += P_Tensor[iVar][kVar]*Lambda_i[kVar]*invP_Tensor[kVar][jVar]; - Fc_i[iVar] += Proj_ModJac_Tensor_i*U_i[jVar]*Area; - if (implicit) - Jacobian_i[iVar][jVar] += Proj_ModJac_Tensor_i*Area; - } + for (auto iVar = 0u; iVar < MAXNVAR; ++iVar) { + Fc[iVar] = 0; } + auto UpdateFlux = [&](const auto* U, auto* Jacobian) { + for (auto iVar = 0u; iVar < nVar; ++iVar) { + for (auto jVar = 0u; jVar < nVar; ++jVar) { + su2double Proj_ModJac_Tensor_i = 0.0; + + /*--- Compute Proj_ModJac_Tensor = P x Lambda+ x inverse P ---*/ + + for (auto kVar = 0u; kVar < nVar; ++kVar) { + Proj_ModJac_Tensor_i += P_Tensor[iVar][kVar] * Lambda[kVar] * invP_Tensor[kVar][jVar]; + } + Fc[iVar] += Proj_ModJac_Tensor_i * Area * U[jVar]; + Jacobian[iVar][jVar] = Proj_ModJac_Tensor_i * Area; + } + } + }; + UpdateFlux(U_i, Jacobian_i); /*--- Flow eigenvalues at j (Lambda-) ---*/ - for (iDim = 0; iDim < nDim; iDim++) { - Lambda_j[iDim] = 0.5*(ProjVelst_j - fabs(ProjVelst_j)); + for (auto iDim = 0u; iDim < nDim; ++iDim) { + Lambda[iDim] = fmin(ProjVelst_j, 0); } - Lambda_j[nDim] = 0.5*( ProjVelst_j + Vst_j[nDim+4] - fabs(ProjVelst_j + Vst_j[nDim+4]) ); - Lambda_j[nDim+1] = 0.5*( ProjVelst_j - Vst_j[nDim+4] - fabs(ProjVelst_j - Vst_j[nDim+4]) ); + Lambda[nDim] = fmin(ProjVelst_j + Vst_j[nDim + 4], 0); + Lambda[nDim + 1] = fmin(ProjVelst_j - Vst_j[nDim + 4], 0); /*--- Compute projected P, invP, and Lambda ---*/ - GetPMatrix(&Vst_j[nDim+2], Velst_j, &Vst_j[nDim+4], UnitNormal, P_Tensor); - GetPMatrix_inv(&Vst_j[nDim+2], Velst_j, &Vst_j[nDim+4], UnitNormal, invP_Tensor); + GetPMatrix(Vst_j[nDim + 2], Velst_j, Vst_j[nDim + 4], UnitNormal, P_Tensor); + GetPMatrix_inv(Vst_j[nDim + 2], Velst_j, Vst_j[nDim + 4], UnitNormal, invP_Tensor); /*--- Projected flux (f-) ---*/ - for (iVar = 0; iVar < nVar; iVar++) { - for (jVar = 0; jVar < nVar; jVar++) { - Proj_ModJac_Tensor_j = 0.0; - /*--- Compute Proj_ModJac_Tensor = P x Lambda- x inverse P ---*/ - for (kVar = 0; kVar < nVar; kVar++) - Proj_ModJac_Tensor_j += P_Tensor[iVar][kVar]*Lambda_j[kVar]*invP_Tensor[kVar][jVar]; - Fc_j[iVar] += Proj_ModJac_Tensor_j*U_j[jVar]*Area; - if (implicit) - Jacobian_j[iVar][jVar] += Proj_ModJac_Tensor_j*Area; - } - } + UpdateFlux(U_j, Jacobian_j); - /*--- Flux splitting, use the i flux as final output. ---*/ - - for (iVar = 0; iVar < nVar; iVar++) { - Fc_i[iVar] += Fc_j[iVar]; - } + AD::SetPreaccOut(Fc, nVar); + AD::EndPreacc(); - return ResidualType<>(Fc_i, Jacobian_i, Jacobian_j); + return ResidualType<>(Fc, Jacobian_i, Jacobian_j); } diff --git a/SU2_CFD/src/numerics/flow/convection/roe.cpp b/SU2_CFD/src/numerics/flow/convection/roe.cpp index b8cc3c6923f4..f35b97cd6c50 100644 --- a/SU2_CFD/src/numerics/flow/convection/roe.cpp +++ b/SU2_CFD/src/numerics/flow/convection/roe.cpp @@ -170,7 +170,7 @@ CNumerics::ResidualType<> CUpwRoeBase_Flow::ComputeResidual(const CConfig* confi /*--- P tensor ---*/ - GetPMatrix(&RoeDensity, RoeVelocity, &RoeSoundSpeed, UnitNormal, P_Tensor); + GetPMatrix(RoeDensity, RoeVelocity, RoeSoundSpeed, UnitNormal, P_Tensor); /*--- Projected velocity adjusted for mesh motion ---*/ @@ -259,7 +259,7 @@ void CUpwRoe_Flow::FinalizeResidual(su2double *val_residual, su2double **val_Jac unsigned short iVar, jVar, kVar; /*--- Compute inverse P tensor ---*/ - GetPMatrix_inv(&RoeDensity, RoeVelocity, &RoeSoundSpeed, UnitNormal, invP_Tensor); + GetPMatrix_inv(RoeDensity, RoeVelocity, RoeSoundSpeed, UnitNormal, invP_Tensor); /*--- Diference between conservative variables at jPoint and iPoint ---*/ for (iVar = 0; iVar < nVar; iVar++) @@ -349,7 +349,7 @@ void CUpwL2Roe_Flow::FinalizeResidual(su2double *val_residual, su2double **val_J /*--- If implicit use the Jacobians of the standard Roe scheme as an approximation ---*/ - GetPMatrix_inv(&RoeDensity, RoeVelocity, &RoeSoundSpeed, UnitNormal, invP_Tensor); + GetPMatrix_inv(RoeDensity, RoeVelocity, RoeSoundSpeed, UnitNormal, invP_Tensor); for (iVar = 0; iVar < nVar; iVar++) { for (jVar = 0; jVar < nVar; jVar++) { @@ -422,7 +422,7 @@ void CUpwLMRoe_Flow::FinalizeResidual(su2double *val_residual, su2double **val_J /*--- If implicit use the Jacobians of the standard Roe scheme as an approximation ---*/ - GetPMatrix_inv(&RoeDensity, RoeVelocity, &RoeSoundSpeed, UnitNormal, invP_Tensor); + GetPMatrix_inv(RoeDensity, RoeVelocity, RoeSoundSpeed, UnitNormal, invP_Tensor); for (iVar = 0; iVar < nVar; iVar++) { for (jVar = 0; jVar < nVar; jVar++) { diff --git a/SU2_CFD/src/output/CAdjElasticityOutput.cpp b/SU2_CFD/src/output/CAdjElasticityOutput.cpp index 2320cabf5a53..6fc59bf7384a 100644 --- a/SU2_CFD/src/output/CAdjElasticityOutput.cpp +++ b/SU2_CFD/src/output/CAdjElasticityOutput.cpp @@ -27,6 +27,7 @@ #include "../../include/output/CAdjElasticityOutput.hpp" +#include "../../include/output/CAdjHeatOutput.hpp" #include #include "../../../Common/include/geometry/CGeometry.hpp" @@ -34,6 +35,8 @@ CAdjElasticityOutput::CAdjElasticityOutput(CConfig *config, unsigned short nDim) : COutput(config, nDim, false) { + coupled_heat = config->GetWeakly_Coupled_Heat(); + /*--- Initialize number of variables ---*/ nVar_FEM = nDim; @@ -51,8 +54,10 @@ CAdjElasticityOutput::CAdjElasticityOutput(CConfig *config, unsigned short nDim) requestedScreenFields.emplace_back("INNER_ITER"); requestedScreenFields.emplace_back("ADJOINT_DISP_X"); requestedScreenFields.emplace_back("ADJOINT_DISP_Y"); + if (coupled_heat) requestedScreenFields.emplace_back("RMS_ADJ_TEMPERATURE"); requestedScreenFields.emplace_back("SENS_E_0"); requestedScreenFields.emplace_back("SENS_NU_0"); + if (coupled_heat) requestedScreenFields.emplace_back("SENS_GEO"); nRequestedScreenFields = requestedScreenFields.size(); } @@ -134,6 +139,12 @@ void CAdjElasticityOutput::SetHistoryOutputFields(CConfig *config){ AddHistoryOutput("BGS_ADJ_DISP_Z", "bgs[A_Uz]", ScreenOutputFormat::FIXED, "BGS_RES", "BGS residual of the adjoint Z displacement.", HistoryFieldType::RESIDUAL); } } + + if (coupled_heat) { + CAdjHeatOutput::SetHistoryOutputFieldsImpl(config, this); + AddHistoryOutput("LINSOL_ITER_HEAT", "LinSolIterHeat", ScreenOutputFormat::INTEGER, "LINSOL", "Number of iterations of the linear solver."); + AddHistoryOutput("LINSOL_RESIDUAL_HEAT", "LinSolResHeat", ScreenOutputFormat::FIXED, "LINSOL", "Residual of the linear solver."); + } } inline void CAdjElasticityOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSolver **solver) { @@ -173,6 +184,13 @@ inline void CAdjElasticityOutput::LoadHistoryData(CConfig *config, CGeometry *ge } } + /*--- Add heat solver data if available. ---*/ + if (coupled_heat) { + CAdjHeatOutput::LoadHistoryDataImpl(config, geometry, solver, this); + SetHistoryOutputValue("LINSOL_ITER_HEAT", solver[ADJHEAT_SOL]->GetIterLinSolver()); + SetHistoryOutputValue("LINSOL_RESIDUAL_HEAT", log10(solver[ADJHEAT_SOL]->GetResLinSolver())); + } + ComputeSimpleCustomOutputs(config); } @@ -191,6 +209,11 @@ void CAdjElasticityOutput::LoadVolumeData(CConfig *config, CGeometry *geometry, if (nVar_FEM == 3) SetVolumeOutputValue("ADJOINT-Z", iPoint, Node_Struc->GetSolution(iPoint, 2)); + if (coupled_heat) { + const auto* Node_Heat = solver[ADJHEAT_SOL]->GetNodes(); + SetVolumeOutputValue("ADJ_TEMPERATURE", iPoint, Node_Heat->GetSolution(iPoint, 0)); + } + SetVolumeOutputValue("SENSITIVITY-X", iPoint, Node_Struc->GetSensitivity(iPoint, 0)); SetVolumeOutputValue("SENSITIVITY-Y", iPoint, Node_Struc->GetSensitivity(iPoint, 1)); if (nDim == 3) @@ -212,6 +235,14 @@ void CAdjElasticityOutput::LoadVolumeData(CConfig *config, CGeometry *geometry, SetVolumeOutputValue("SENS_ACCEL-Y", iPoint, Node_Struc->GetSolution_time_n(iPoint, 2 * nDim + 1)); if (nDim == 3) SetVolumeOutputValue("SENS_ACCEL-Z", iPoint, Node_Struc->GetSolution_time_n(iPoint, 8)); + + if (coupled_heat) { + const auto* Node_Heat = solver[ADJHEAT_SOL]->GetNodes(); + SetVolumeOutputValue("SENS_TEMP_N", iPoint, Node_Heat->GetSolution_time_n(iPoint, 0)); + if (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND) { + SetVolumeOutputValue("SENS_TEMP_N1", iPoint, Node_Heat->GetSolution_time_n1(iPoint, 0)); + } + } } void CAdjElasticityOutput::SetVolumeOutputFields(CConfig *config){ @@ -232,6 +263,10 @@ void CAdjElasticityOutput::SetVolumeOutputFields(CConfig *config){ AddVolumeOutput("ADJOINT-Z", "Adjoint_z", "SOLUTION", "adjoint of displacement in the z direction"); /// END_GROUP + if (coupled_heat) { + AddVolumeOutput("ADJ_TEMPERATURE", "Adjoint_Temperature", "SOLUTION", "Adjoint Temperature"); + } + /// BEGIN_GROUP: SENSITIVITY, DESCRIPTION: Geometrical sensitivities of the current objective function. /// DESCRIPTION: Sensitivity x-component. AddVolumeOutput("SENSITIVITY-X", "Sensitivity_x", "SENSITIVITY", "geometric sensitivity in the x direction"); @@ -261,4 +296,10 @@ void CAdjElasticityOutput::SetVolumeOutputFields(CConfig *config){ if (nDim == 3) AddVolumeOutput("SENS_ACCEL-Z", "SensitivityAccelN_z", "SENSITIVITY_N", "sensitivity to the previous z acceleration"); + if (coupled_heat) { + AddVolumeOutput("SENS_TEMP_N", "SensitivityTempN", "SENSITIVITY_N", "sensitivity to the previous temperature"); + if (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND) { + AddVolumeOutput("SENS_TEMP_N1", "SensitivityTempN1", "SENSITIVITY_N", "sensitivity to the previous-1 temperature"); + } + } } diff --git a/SU2_CFD/src/output/CAdjHeatOutput.cpp b/SU2_CFD/src/output/CAdjHeatOutput.cpp index 35875abe825a..66cf5a336f73 100644 --- a/SU2_CFD/src/output/CAdjHeatOutput.cpp +++ b/SU2_CFD/src/output/CAdjHeatOutput.cpp @@ -89,25 +89,30 @@ CAdjHeatOutput::CAdjHeatOutput(CConfig *config, unsigned short nDim) : COutput(c CAdjHeatOutput::~CAdjHeatOutput() = default; -void CAdjHeatOutput::SetHistoryOutputFields(CConfig *config){ +void CAdjHeatOutput::SetHistoryOutputFieldsImpl(CConfig *config, COutput* output) { /// BEGIN_GROUP: RMS_RES, DESCRIPTION: The root-mean-square residuals of the conservative variables. /// DESCRIPTION: Root-mean square residual of the adjoint temperature. - AddHistoryOutput("RMS_ADJ_TEMPERATURE", "rms[A_T]", ScreenOutputFormat::FIXED, "RMS_RES", "Root-mean square residual of the adjoint temperature.", HistoryFieldType::RESIDUAL); + output->AddHistoryOutput("RMS_ADJ_TEMPERATURE", "rms[A_T]", ScreenOutputFormat::FIXED, "RMS_RES", "Root-mean square residual of the adjoint temperature.", HistoryFieldType::RESIDUAL); /// END_GROUP /// BEGIN_GROUP: MAX_RES, DESCRIPTION: The maximum residuals of the conservative variables. /// DESCRIPTION: Maximum residual of the adjoint temperature. - AddHistoryOutput("MAX_ADJ_TEMPERATURE", "max[A_T]", ScreenOutputFormat::FIXED, "MAX_RES", "Maximum residual of the adjoint temperature.", HistoryFieldType::RESIDUAL); + output->AddHistoryOutput("MAX_ADJ_TEMPERATURE", "max[A_T]", ScreenOutputFormat::FIXED, "MAX_RES", "Maximum residual of the adjoint temperature.", HistoryFieldType::RESIDUAL); /// BEGIN_GROUP: MAX_RES, DESCRIPTION: The root-mean-square residuals of the conservative variables. /// DESCRIPTION: Root-mean-square residual of the adjoint temperature. - AddHistoryOutput("BGS_ADJ_TEMPERATURE", "bgs[A_T]", ScreenOutputFormat::FIXED, "BGS_RES", "BGS residual of the adjoint temperature.", HistoryFieldType::RESIDUAL); + output->AddHistoryOutput("BGS_ADJ_TEMPERATURE", "bgs[A_T]", ScreenOutputFormat::FIXED, "BGS_RES", "BGS residual of the adjoint temperature.", HistoryFieldType::RESIDUAL); /// BEGIN_GROUP: SENSITIVITY, DESCRIPTION: Sensitivities of different geometrical or boundary values. /// DESCRIPTION: Sum of the geometrical sensitivities on all markers set in MARKER_MONITORING. - AddHistoryOutput("SENS_GEO", "Sens_Geo", ScreenOutputFormat::SCIENTIFIC, "SENSITIVITY", "Sum of the geometrical sensitivities on all markers set in MARKER_MONITORING.", HistoryFieldType::COEFFICIENT); + output->AddHistoryOutput("SENS_GEO", "Sens_Geo", ScreenOutputFormat::SCIENTIFIC, "SENSITIVITY", "Sum of the geometrical sensitivities on all markers set in MARKER_MONITORING.", HistoryFieldType::COEFFICIENT); /// END_GROUP +} + +void CAdjHeatOutput::SetHistoryOutputFields(CConfig *config){ + + SetHistoryOutputFieldsImpl(config, this); AddHistoryOutput("LINSOL_ITER", "LinSolIter", ScreenOutputFormat::INTEGER, "LINSOL", "Number of iterations of the linear solver."); AddHistoryOutput("LINSOL_RESIDUAL", "LinSolRes", ScreenOutputFormat::FIXED, "LINSOL", "Residual of the linear solver."); @@ -119,19 +124,23 @@ void CAdjHeatOutput::SetHistoryOutputFields(CConfig *config){ } -void CAdjHeatOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSolver **solver) { +void CAdjHeatOutput::LoadHistoryDataImpl(CConfig *config, CGeometry *geometry, CSolver **solver, COutput* output) { CSolver* adjheat_solver = solver[ADJHEAT_SOL]; - SetHistoryOutputValue("RMS_ADJ_TEMPERATURE", log10(adjheat_solver->GetRes_RMS(0))); + output->SetHistoryOutputValue("RMS_ADJ_TEMPERATURE", log10(adjheat_solver->GetRes_RMS(0))); + output->SetHistoryOutputValue("MAX_ADJ_TEMPERATURE", log10(adjheat_solver->GetRes_Max(0))); + if (config->GetMultizone_Problem()) { + output->SetHistoryOutputValue("BGS_ADJ_TEMPERATURE", log10(adjheat_solver->GetRes_BGS(0))); + } + output->SetHistoryOutputValue("SENS_GEO", adjheat_solver->GetTotal_Sens_Geo()); +} - SetHistoryOutputValue("MAX_ADJ_TEMPERATURE", log10(adjheat_solver->GetRes_Max(0))); +void CAdjHeatOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSolver **solver) { - if (multiZone) { - SetHistoryOutputValue("BGS_ADJ_TEMPERATURE", log10(adjheat_solver->GetRes_BGS(0))); - } + CSolver* adjheat_solver = solver[ADJHEAT_SOL]; - SetHistoryOutputValue("SENS_GEO", adjheat_solver->GetTotal_Sens_Geo()); + LoadHistoryDataImpl(config, geometry, solver, this); SetHistoryOutputValue("LINSOL_ITER", adjheat_solver->GetIterLinSolver()); SetHistoryOutputValue("LINSOL_RESIDUAL", log10(adjheat_solver->GetResLinSolver())); diff --git a/SU2_CFD/src/output/CElasticityOutput.cpp b/SU2_CFD/src/output/CElasticityOutput.cpp index cebd509656b0..5bf9bfb4d6ed 100644 --- a/SU2_CFD/src/output/CElasticityOutput.cpp +++ b/SU2_CFD/src/output/CElasticityOutput.cpp @@ -37,10 +37,6 @@ CElasticityOutput::CElasticityOutput(CConfig *config, unsigned short nDim) : COu coupled_heat = config->GetWeakly_Coupled_Heat(); dynamic = config->GetTime_Domain(); - /*--- Initialize number of variables ---*/ - if (linear_analysis) nVar_FEM = nDim; - if (nonlinear_analysis) nVar_FEM = 3; - /*--- Default fields for screen output ---*/ if (nRequestedHistoryFields == 0){ RequestCommonHistory(dynamic); diff --git a/SU2_CFD/src/output/CFlowCompOutput.cpp b/SU2_CFD/src/output/CFlowCompOutput.cpp index 4429cdfd7a05..54a30d1b3a2b 100644 --- a/SU2_CFD/src/output/CFlowCompOutput.cpp +++ b/SU2_CFD/src/output/CFlowCompOutput.cpp @@ -288,6 +288,10 @@ void CFlowCompOutput::SetVolumeOutputFields(CConfig *config){ AddVolumeOutput("LIMITER_ENTHALPY", "Limiter_Enthalpy", "LIMITER", "Limiter value of the enthalpy"); } + if (config->GetKind_Upwind_Flow() == UPWIND::MSW) { + AddVolumeOutput("MSW_SENSOR", "MSW_Sensor", "LIMITER", "Value of sensor used to switch from SW to MSW"); + } + SetVolumeOutputFieldsScalarLimiter(config); SetVolumeOutputFieldsScalarSource(config); @@ -378,6 +382,10 @@ void CFlowCompOutput::LoadVolumeData(CConfig *config, CGeometry *geometry, CSolv } } + if (config->GetKind_Upwind_Flow() == UPWIND::MSW) { + SetVolumeOutputValue("MSW_SENSOR", iPoint, Node_Flow->GetSensor(iPoint)); + } + if (config->GetKind_RoeLowDiss() != NO_ROELOWDISS){ SetVolumeOutputValue("ROE_DISSIPATION", iPoint, Node_Flow->GetRoe_Dissipation(iPoint)); } diff --git a/SU2_CFD/src/output/CFlowOutput.cpp b/SU2_CFD/src/output/CFlowOutput.cpp index d9216b7bdc2f..54bdc18d7830 100644 --- a/SU2_CFD/src/output/CFlowOutput.cpp +++ b/SU2_CFD/src/output/CFlowOutput.cpp @@ -979,12 +979,8 @@ void CFlowOutput::SetCustomOutputs(const CSolver* const* solver, const CGeometry } END_SU2_OMP_FOR } - - SU2_OMP_CRITICAL { - integral[0] += local_integral[0]; - integral[1] += local_integral[1]; - } - END_SU2_OMP_CRITICAL + atomicAdd(local_integral[0], integral[0]); + atomicAdd(local_integral[1], integral[1]); } END_SU2_OMP_PARALLEL @@ -1789,6 +1785,9 @@ void CFlowOutput::AddAerodynamicCoefficients(const CConfig* config) { AddHistoryOutput("AOA", "AoA", ScreenOutputFormat::FIXED, "AOA", "Angle of attack"); AddHistoryOutput("COMBO", "ComboObj", ScreenOutputFormat::SCIENTIFIC, "COMBO", "Combined obj. function value.", HistoryFieldType::COEFFICIENT); + // CUSTOM_OBJFUNC is added here so historyMap.py knows how to get its + // value, the actual output is COMBO. + if (false) AddHistoryOutput("CUSTOM_OBJFUNC", "ComboObj", ScreenOutputFormat::SCIENTIFIC, "COMBO", "Custom obj. function value.", HistoryFieldType::COEFFICIENT); } void CFlowOutput::SetAerodynamicCoefficients(const CConfig* config, const CSolver* flow_solver){ diff --git a/SU2_CFD/src/output/COutput.cpp b/SU2_CFD/src/output/COutput.cpp index 0be8bfb759eb..5702673118ad 100644 --- a/SU2_CFD/src/output/COutput.cpp +++ b/SU2_CFD/src/output/COutput.cpp @@ -70,6 +70,8 @@ COutput::COutput(const CConfig *config, unsigned short ndim, bool fem_output): us_units(config->GetSystemMeasurements() == US) { cauchyTimeConverged = false; + maxTimeDelayActive = false; + PrevStopTime = 0.0; convergenceTable = new PrintingToolbox::CTablePrinter(&std::cout); multiZoneHeaderTable = new PrintingToolbox::CTablePrinter(&std::cout); @@ -793,6 +795,7 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form } bool COutput::GetCauchyCorrectedTimeConvergence(const CConfig *config){ + // Handle Cauchy convergence delay for 2nd order time stepping if(!cauchyTimeConverged && TimeConvergence && config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND){ // Change flags for 2nd order Time stepping: In case of convergence, this iter and next iter gets written out. then solver stops cauchyTimeConverged = TimeConvergence; @@ -801,6 +804,25 @@ bool COutput::GetCauchyCorrectedTimeConvergence(const CConfig *config){ else if(cauchyTimeConverged){ TimeConvergence = cauchyTimeConverged; } + + // Handle max time delay for 2nd order time stepping + // Delay stopping at max_time to ensure both timestep N and N-1 are written for proper restart + if(config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND){ + const su2double cur_time = GetHistoryFieldValue("CUR_TIME"); + const su2double max_time = config->GetMax_Time(); + const bool final_time_reached = (cur_time >= max_time); + + // If max_time is reached on first detection, delay the stop + if(final_time_reached && !maxTimeDelayActive){ + maxTimeDelayActive = true; + TimeConvergence = false; // Delay stop to run one more iteration + } + else if(maxTimeDelayActive){ + TimeConvergence = true; // Now allow stop + maxTimeDelayActive = false; // Reset for next run + } + } + return TimeConvergence; } @@ -2074,8 +2096,12 @@ void COutput::SetCommonHistoryFields() { /// Description: The current time step AddHistoryOutput("TIME_STEP", "Time_Step", ScreenOutputFormat::SCIENTIFIC, "TIME_DOMAIN", "Current time step (s)"); + /// BEGIN_GROUP: WALL_TIME, DESCRIPTION: Wall-clock timing information. + /// DESCRIPTION: The current iteration wall-clock time. + AddHistoryOutput("ITER_TIME", "Time(sec)", ScreenOutputFormat::FIXED, "WALL_TIME", "Time per iteration (s)"); /// DESCRIPTION: Currently used wall-clock time. AddHistoryOutput("WALL_TIME", "Time(sec)", ScreenOutputFormat::SCIENTIFIC, "WALL_TIME", "Average wall-clock time since the start of inner iterations."); + /// END_GROUP AddHistoryOutput("NONPHYSICAL_POINTS", "Nonphysical_Points", ScreenOutputFormat::INTEGER, "NONPHYSICAL_POINTS", "The number of non-physical points in the solution"); @@ -2267,13 +2293,21 @@ void COutput::LoadCommonHistoryData(const CConfig *config) { SetHistoryOutputValue("INNER_ITER", curInnerIter); SetHistoryOutputValue("OUTER_ITER", curOuterIter); - su2double StopTime, UsedTime; + su2double StopTime, UsedTime, IterTime; StopTime = SU2_MPI::Wtime(); UsedTime = (StopTime - config->Get_StartTime())/(curInnerIter+1); + if (curInnerIter == 0) { + IterTime = StopTime - config->Get_StartTime(); // First iteration measured from start + } else { + IterTime = StopTime - PrevStopTime; + } + PrevStopTime = StopTime; + SetHistoryOutputValue("WALL_TIME", UsedTime); + SetHistoryOutputValue("ITER_TIME", IterTime); SetHistoryOutputValue("NONPHYSICAL_POINTS", config->GetNonphysical_Points()); } diff --git a/SU2_CFD/src/solvers/CAdjEulerSolver.cpp b/SU2_CFD/src/solvers/CAdjEulerSolver.cpp index 67ef904d1d4a..a96a131f553f 100644 --- a/SU2_CFD/src/solvers/CAdjEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CAdjEulerSolver.cpp @@ -1422,7 +1422,7 @@ void CAdjEulerSolver::ExplicitEuler_Iteration(CGeometry *geometry, CSolver **sol void CAdjEulerSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { unsigned short iVar; - unsigned long iPoint, total_index; + unsigned long iPoint; su2double Delta, *local_Res_TruncError, Vol; /*--- Set maximum residual to zero ---*/ @@ -1450,8 +1450,7 @@ void CAdjEulerSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **sol else { Jacobian.SetVal2Diag(iPoint, 1.0); for (iVar = 0; iVar < nVar; iVar++) { - total_index = iPoint*nVar + iVar; - LinSysRes[total_index] = 0.0; + LinSysRes(iPoint, iVar) = 0.0; local_Res_TruncError[iVar] = 0.0; } } @@ -1459,11 +1458,10 @@ void CAdjEulerSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **sol /*--- Right hand side of the system (-Residual) and initial guess (x = 0) ---*/ for (iVar = 0; iVar < nVar; iVar++) { - total_index = iPoint*nVar+iVar; - LinSysRes[total_index] = -(LinSysRes[total_index] + local_Res_TruncError[iVar]); - LinSysSol[total_index] = 0.0; - Residual_RMS[iVar] += LinSysRes[total_index]*LinSysRes[total_index]; - AddRes_Max(iVar, fabs(LinSysRes[total_index]), geometry->nodes->GetGlobalIndex(iPoint), geometry->nodes->GetCoord(iPoint)); + LinSysRes(iPoint, iVar) = -(LinSysRes(iPoint, iVar) + local_Res_TruncError[iVar]); + LinSysSol(iPoint, iVar) = 0.0; + Residual_RMS[iVar] += LinSysRes(iPoint, iVar)*LinSysRes(iPoint, iVar); + AddRes_Max(iVar, fabs(LinSysRes(iPoint, iVar)), geometry->nodes->GetGlobalIndex(iPoint), geometry->nodes->GetCoord(iPoint)); } } @@ -1472,9 +1470,8 @@ void CAdjEulerSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **sol for (iPoint = nPointDomain; iPoint < nPoint; iPoint++) { for (iVar = 0; iVar < nVar; iVar++) { - total_index = iPoint*nVar + iVar; - LinSysRes[total_index] = 0.0; - LinSysSol[total_index] = 0.0; + LinSysRes(iPoint, iVar) = 0.0; + LinSysSol(iPoint, iVar) = 0.0; } } diff --git a/SU2_CFD/src/solvers/CAdjNSSolver.cpp b/SU2_CFD/src/solvers/CAdjNSSolver.cpp index f6d9ac366f0b..f2ad14257e46 100644 --- a/SU2_CFD/src/solvers/CAdjNSSolver.cpp +++ b/SU2_CFD/src/solvers/CAdjNSSolver.cpp @@ -1165,7 +1165,7 @@ void CAdjNSSolver::Viscous_Sensitivity(CGeometry *geometry, CSolver **solver_con void CAdjNSSolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { unsigned short iDim, iVar, jVar, jDim; - unsigned long iVertex, iPoint, total_index, Point_Normal; + unsigned long iVertex, iPoint, Point_Normal; su2double *d, l1psi, vartheta, Sigma_5, phi[3] = {}; su2double sq_vel, ProjGridVel, Enthalpy = 0.0, *GridVel; @@ -1501,8 +1501,7 @@ void CAdjNSSolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_contai if (implicit) { Jacobian.SubtractBlock2Diag(iPoint, Jacobian_ii); for (iVar = 1; iVar <= nDim; iVar++) { - total_index = iPoint*nVar+iVar; - Jacobian.DeleteValsRowi(total_index); + Jacobian.DeleteValsRowi(iPoint, iVar); } } @@ -1527,7 +1526,7 @@ void CAdjNSSolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_contai void CAdjNSSolver::BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - unsigned long iVertex, iPoint, total_index; + unsigned long iVertex, iPoint; unsigned short iDim, iVar, jVar, jDim; su2double *d, q, *U, dVisc_T, rho, pressure, div_phi, force_stress, Sigma_5, phi[3] = {0.0,0.0,0.0}; @@ -1632,8 +1631,7 @@ void CAdjNSSolver::BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_cont nodes->SetSolution_Old(iPoint,iDim+1, phi[iDim]); if (implicit) { for (iVar = 1; iVar <= nDim; iVar++) { - total_index = iPoint*nVar+iVar; - Jacobian.DeleteValsRowi(total_index); + Jacobian.DeleteValsRowi(iPoint, iVar); } } @@ -1673,8 +1671,7 @@ void CAdjNSSolver::BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_cont nodes->SetSolution_Old(iPoint,nDim+1, q); if (implicit) { iVar = nDim+1; - total_index = iPoint*nVar+iVar; - Jacobian.DeleteValsRowi(total_index); + Jacobian.DeleteValsRowi(iPoint, iVar); } /*--- Additional contributions to adjoint density (weak imposition) ---*/ diff --git a/SU2_CFD/src/solvers/CAdjTurbSolver.cpp b/SU2_CFD/src/solvers/CAdjTurbSolver.cpp index f680ea1ad6cd..bd5bfe3000ed 100644 --- a/SU2_CFD/src/solvers/CAdjTurbSolver.cpp +++ b/SU2_CFD/src/solvers/CAdjTurbSolver.cpp @@ -184,7 +184,7 @@ void CAdjTurbSolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_cont LinSysRes.SetBlock_Zero(iPoint); /*--- Change rows of the Jacobian (includes 1 in the diagonal) ---*/ - Jacobian.DeleteValsRowi(iPoint); + Jacobian.DeleteValsRowi(iPoint, 0); } } @@ -208,7 +208,7 @@ void CAdjTurbSolver::BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_co LinSysRes.SetBlock_Zero(iPoint); /*--- Change rows of the Jacobian (includes 1 in the diagonal) ---*/ - Jacobian.DeleteValsRowi(iPoint); + Jacobian.DeleteValsRowi(iPoint, 0); } } @@ -455,7 +455,7 @@ void CAdjTurbSolver::Source_Residual(CGeometry *geometry, CSolver **solver_conta void CAdjTurbSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { unsigned short iVar; - unsigned long iPoint, total_index; + unsigned long iPoint; su2double Delta, Vol; /*--- Set maximum residual to zero ---*/ @@ -479,11 +479,10 @@ void CAdjTurbSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solv /*--- Right hand side of the system (-Residual) and initial guess (x = 0) ---*/ for (iVar = 0; iVar < nVar; iVar++) { - total_index = iPoint*nVar+iVar; - LinSysRes[total_index] = -LinSysRes[total_index]; - LinSysSol[total_index] = 0.0; - Residual_RMS[iVar] += LinSysRes[total_index]*LinSysRes[total_index]; - AddRes_Max(iVar, fabs(LinSysRes[total_index]), geometry->nodes->GetGlobalIndex(iPoint), geometry->nodes->GetCoord(iPoint)); + LinSysRes(iPoint, iVar) = -LinSysRes(iPoint, iVar); + LinSysSol(iPoint, iVar) = 0.0; + Residual_RMS[iVar] += LinSysRes(iPoint, iVar)*LinSysRes(iPoint, iVar); + AddRes_Max(iVar, fabs(LinSysRes(iPoint, iVar)), geometry->nodes->GetGlobalIndex(iPoint), geometry->nodes->GetCoord(iPoint)); } } @@ -492,9 +491,8 @@ void CAdjTurbSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solv for (iPoint = nPointDomain; iPoint < nPoint; iPoint++) { for (iVar = 0; iVar < nVar; iVar++) { - total_index = iPoint*nVar + iVar; - LinSysRes[total_index] = 0.0; - LinSysSol[total_index] = 0.0; + LinSysRes(iPoint, iVar) = 0.0; + LinSysSol(iPoint, iVar) = 0.0; } } diff --git a/SU2_CFD/src/solvers/CEulerSolver.cpp b/SU2_CFD/src/solvers/CEulerSolver.cpp index 090024819f26..3f8d642e9c6e 100644 --- a/SU2_CFD/src/solvers/CEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CEulerSolver.cpp @@ -1643,6 +1643,9 @@ void CEulerSolver::CommonPreprocessing(CGeometry *geometry, CSolver **solver_con if (!center_jst_ke) SetUndivided_Laplacian(geometry, config); } } + if (config->GetKind_Upwind_Flow() == UPWIND::MSW && !Output) { + SetCentered_Dissipation_Sensor(geometry, config); + } /*--- Roe Low Dissipation Sensor ---*/ @@ -1656,7 +1659,7 @@ void CEulerSolver::CommonPreprocessing(CGeometry *geometry, CSolver **solver_con /*--- Initialize the Jacobian matrix and residual, not needed for the reducer strategy * as we set blocks (including diagonal ones) and completely overwrite. ---*/ - if(!ReducerStrategy && !Output) { + if (!ReducerStrategy && !Output) { LinSysRes.SetValZero(); if (implicit) Jacobian.SetValZero(); else {SU2_OMP_BARRIER} // because of "nowait" in LinSysRes @@ -1793,13 +1796,16 @@ void CEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_contain const bool low_mach_corr = config->Low_Mach_Correction(); /*--- Use vectorization if the scheme supports it. ---*/ - if (config->GetKind_Upwind_Flow() == UPWIND::ROE && ideal_gas && !low_mach_corr) { - EdgeFluxResidual(geometry, solver_container, config); - return; + if (ideal_gas && !low_mach_corr) { + if (config->GetKind_Upwind_Flow() == UPWIND::ROE || config->GetKind_Upwind_Flow() == UPWIND::MSW) { + EdgeFluxResidual(geometry, solver_container, config); + return; + } } const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); + const bool msw = (config->GetKind_Upwind_Flow() == UPWIND::MSW); const bool roe_turkel = (config->GetKind_Upwind_Flow() == UPWIND::TURKEL); const auto kind_dissipation = config->GetKind_RoeLowDiss(); @@ -1947,17 +1953,15 @@ void CEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_contain /*--- Roe Low Dissipation Scheme ---*/ if (kind_dissipation != NO_ROELOWDISS) { - numerics->SetDissipation(nodes->GetRoe_Dissipation(iPoint), nodes->GetRoe_Dissipation(jPoint)); - - if (kind_dissipation == FD_DUCROS || kind_dissipation == NTS_DUCROS){ - numerics->SetSensor(nodes->GetSensor(iPoint), - nodes->GetSensor(jPoint)); - } - if (kind_dissipation == NTS || kind_dissipation == NTS_DUCROS){ - numerics->SetCoord(Coord_i, Coord_j); - } + } + if (msw || kind_dissipation == FD_DUCROS || kind_dissipation == NTS_DUCROS){ + numerics->SetSensor(nodes->GetSensor(iPoint), + nodes->GetSensor(jPoint)); + } + if (kind_dissipation == NTS || kind_dissipation == NTS_DUCROS){ + numerics->SetCoord(Coord_i, Coord_j); } /*--- Compute the residual ---*/ @@ -7618,6 +7622,17 @@ void CEulerSolver::BC_Engine_Inflow(CGeometry *geometry, CSolver **solver_contai Target_Inflow_MassFlow = config->GetEngineInflow_Target(Marker_Tag) / (config->GetDensity_Ref() * config->GetVelocity_Ref()); + if (config->GetExhaustToInlet_Engine()) { + su2double Outlet_MF = 0.0; + unsigned short nMarker_Global = config->GetnMarker_CfgFile(); + for (unsigned short iMarker_Global = 0; iMarker_Global < nMarker_Global; iMarker_Global++) { + if (config->GetMarker_CfgFile_KindBC(config->GetMarker_CfgFile_TagBound(iMarker_Global)) == ENGINE_EXHAUST) { + Outlet_MF = Outlet_MF + config->GetExhaust_MassFlow(config->GetMarker_CfgFile_TagBound(iMarker_Global)); + } + } + Target_Inflow_MassFlow = Outlet_MF; + } + if (config->GetSystemMeasurements() == US) Target_Inflow_MassFlow /= 32.174; if (Engine_HalfModel) Target_Inflow_MassFlow /= 2.0; diff --git a/SU2_CFD/src/solvers/CFEASolver.cpp b/SU2_CFD/src/solvers/CFEASolver.cpp index bce775187314..eb13264f6225 100644 --- a/SU2_CFD/src/solvers/CFEASolver.cpp +++ b/SU2_CFD/src/solvers/CFEASolver.cpp @@ -1296,9 +1296,7 @@ void CFEASolver::Compute_NodalStress(CGeometry *geometry, CNumerics **numerics, maxVonMises = max(maxVonMises, vms); } END_SU2_OMP_FOR - SU2_OMP_CRITICAL - MaxVonMises_Stress = max(MaxVonMises_Stress, maxVonMises); - END_SU2_OMP_CRITICAL + atomicMax(maxVonMises, MaxVonMises_Stress); AD::EndPassive(wasActive); @@ -3099,7 +3097,7 @@ void CFEASolver::Stiffness_Penalty(CGeometry *geometry, CNumerics **numerics, CC void CFEASolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo) { - const bool dynamic = (config->GetTime_Domain()); + const bool dynamic = config->GetTime_Domain(); const bool fluid_structure = config->GetFSI_Simulation(); const bool discrete_adjoint = config->GetDiscrete_Adjoint(); diff --git a/SU2_CFD/src/solvers/CGradientSmoothingSolver.cpp b/SU2_CFD/src/solvers/CGradientSmoothingSolver.cpp index 44f3bbb59818..644cd029d6e8 100644 --- a/SU2_CFD/src/solvers/CGradientSmoothingSolver.cpp +++ b/SU2_CFD/src/solvers/CGradientSmoothingSolver.cpp @@ -550,8 +550,6 @@ void CGradientSmoothingSolver::Compute_Surface_Residual(CGeometry* geometry, con int EL_KIND = 0; std::array indexNode; std::array indexVertex; - su2double Weight, Jac_X, norm, val_Coord, normalSens = 0.0, Residual=0.0; - su2double normal[MAXNDIM]; for (iElem = 0; iElem < geometry->GetnElem_Bound(val_marker); iElem++) { /*--- Identify the kind of boundary element ---*/ @@ -562,7 +560,7 @@ void CGradientSmoothingSolver::Compute_Surface_Residual(CGeometry* geometry, con indexNode[iNode] = geometry->bound[val_marker][iElem]->GetNode(iNode); for (iDim = 0; iDim < nDim; iDim++) { - val_Coord = Get_ValCoord(geometry, indexNode[iNode], iDim); + const su2double val_Coord = Get_ValCoord(geometry, indexNode[iNode], iDim); element_container[GRAD_TERM][EL_KIND]->SetRef_Coord(iNode, iDim, val_Coord); } } @@ -575,31 +573,27 @@ void CGradientSmoothingSolver::Compute_Surface_Residual(CGeometry* geometry, con } } - element_container[GRAD_TERM][EL_KIND] - ->ClearElement(); /*--- Restarts the element: avoids adding over previous results in other elements --*/ + /*--- Restarts the element: avoids adding over previous results in other elements --*/ + element_container[GRAD_TERM][EL_KIND]->ClearElement(); element_container[GRAD_TERM][EL_KIND]->ComputeGrad_SurfaceEmbedded(); unsigned int nGauss = element_container[GRAD_TERM][EL_KIND]->GetnGaussPoints(); for (unsigned int iGauss = 0; iGauss < nGauss; iGauss++) { - Weight = element_container[GRAD_TERM][EL_KIND]->GetWeight(iGauss); - Jac_X = element_container[GRAD_TERM][EL_KIND]->GetJ_X(iGauss); + const su2double Weight = element_container[GRAD_TERM][EL_KIND]->GetWeight(iGauss); + const su2double Jac_X = element_container[GRAD_TERM][EL_KIND]->GetJ_X(iGauss); for (unsigned int iNode = 0; iNode < nNodes; iNode++) { + su2double normal[MAXNDIM] = {}; geometry->vertex[val_marker][indexVertex[iNode]]->GetNormal(normal); - norm = GeometryToolbox::Norm(nDim, normal); + const su2double norm = GeometryToolbox::Norm(nDim, normal); for (iDim = 0; iDim < nDim; iDim++) { normal[iDim] = normal[iDim] / norm; } - + su2double normalSens = 0; for (iDim = 0; iDim < nDim; iDim++) { normalSens += normal[iDim] * nodes->GetSensitivity(indexNode[iNode], iDim); } - - Residual += Weight * Jac_X * element_container[GRAD_TERM][EL_KIND]->GetNi(iNode, iGauss) * normalSens; - LinSysRes.AddBlock(indexNode[iNode], &Residual); - - Residual = 0; - normalSens = 0; + LinSysRes(indexNode[iNode], 0) += Weight * Jac_X * element_container[GRAD_TERM][EL_KIND]->GetNi(iNode, iGauss) * normalSens; } } } diff --git a/SU2_CFD/src/solvers/CHeatSolver.cpp b/SU2_CFD/src/solvers/CHeatSolver.cpp index 24b2eba6d6a0..6e127a984485 100644 --- a/SU2_CFD/src/solvers/CHeatSolver.cpp +++ b/SU2_CFD/src/solvers/CHeatSolver.cpp @@ -201,6 +201,10 @@ void CHeatSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig * // P, vx, vy (,vz) skipVars += 1 + nDim; } + if (config->GetStructuralProblem() && config->GetWeakly_Coupled_Heat()) { + skipVars += nDim; + if (config->GetTime_Domain()) skipVars += 2 * nDim; + } /*--- Read the restart data from either an ASCII or binary SU2 file. ---*/ @@ -562,7 +566,7 @@ void CHeatSolver::BC_ConjugateHeat_Interface(CGeometry *geometry, CSolver **solv LinSysRes(iPoint, 0) = 0.0; nodes->SetRes_TruncErrorZero(iPoint); - if (implicit) Jacobian.DeleteValsRowi(iPoint); + if (implicit) Jacobian.DeleteValsRowi(iPoint, 0); } } END_SU2_OMP_FOR @@ -590,8 +594,8 @@ void CHeatSolver::BC_ConjugateHeat_Interface(CGeometry *geometry, CSolver **solv HeatFlux = HeatFluxDensity * Area; if (implicit) { - su2double Jacobian_i[] = {-thermal_diffusivity*Area}; - Jacobian.SubtractBlock2Diag(iPoint, &Jacobian_i); + su2double Jacobian_i[1][1] = {{-thermal_diffusivity*Area}}; + Jacobian.SubtractBlock2Diag(iPoint, Jacobian_i); } } else { @@ -844,13 +848,8 @@ void CHeatSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, } END_SU2_OMP_FOR /*--- Min/max over threads. ---*/ - SU2_OMP_CRITICAL - { - Min_Delta_Time = min(Min_Delta_Time, minDt); - Max_Delta_Time = max(Max_Delta_Time, maxDt); - Global_Delta_Time = Min_Delta_Time; - } - END_SU2_OMP_CRITICAL + atomicMin(minDt, Min_Delta_Time); + atomicMax(maxDt, Max_Delta_Time); } /*--- Compute the min/max dt (in parallel, now over mpi ranks). ---*/ @@ -864,6 +863,7 @@ void CHeatSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, SU2_MPI::Allreduce(&Max_Delta_Time, &rbuf_time, 1, MPI_DOUBLE, MPI_MAX, SU2_MPI::GetComm()); Max_Delta_Time = rbuf_time; } + Global_Delta_Time = Min_Delta_Time; } END_SU2_OMP_SAFE_GLOBAL_ACCESS /*--- For exact time solution use the minimum delta time of the whole mesh. ---*/ @@ -910,9 +910,7 @@ void CHeatSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, glbDtND = min(glbDtND, config->GetUnst_CFL()*Global_Delta_Time / nodes->GetLocalCFL(iPoint)); } END_SU2_OMP_FOR - SU2_OMP_CRITICAL - Global_Delta_UnstTimeND = min(Global_Delta_UnstTimeND, glbDtND); - END_SU2_OMP_CRITICAL + atomicMin(glbDtND, Global_Delta_UnstTimeND); BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { diff --git a/SU2_CFD/src/solvers/CIncEulerSolver.cpp b/SU2_CFD/src/solvers/CIncEulerSolver.cpp index c99f87896c2d..5ba375e74896 100644 --- a/SU2_CFD/src/solvers/CIncEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CIncEulerSolver.cpp @@ -2006,9 +2006,7 @@ void CIncEulerSolver::SetBeta_Parameter(CGeometry *geometry, CSolver **solver_co maxVel2 = max(maxVel2, nodes->GetVelocity2(iPoint)); END_SU2_OMP_FOR - SU2_OMP_CRITICAL - MaxVel2 = max(MaxVel2, maxVel2); - END_SU2_OMP_CRITICAL + atomicMax(maxVel2, MaxVel2); BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { @@ -2051,14 +2049,10 @@ void CIncEulerSolver::SetRangePressure(CGeometry *geometry, CSolver **solver_con } END_SU2_OMP_FOR - SU2_OMP_CRITICAL { - MinP = min(MinP, minP); - MaxP = max(MaxP, maxP); - } - END_SU2_OMP_CRITICAL + atomicMin(minP, MinP); + atomicMax(maxP, MaxP); - BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS - { + BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { minP = MinP; SU2_MPI::Allreduce(&minP, &MinP, 1, MPI_DOUBLE, MPI_MAX, SU2_MPI::GetComm()); maxP = MaxP; diff --git a/SU2_CFD/src/solvers/CIncNSSolver.cpp b/SU2_CFD/src/solvers/CIncNSSolver.cpp index 6477fa6f3619..182fb133bb9a 100644 --- a/SU2_CFD/src/solvers/CIncNSSolver.cpp +++ b/SU2_CFD/src/solvers/CIncNSSolver.cpp @@ -492,7 +492,7 @@ void CIncNSSolver::BC_Wall_Generic(const CGeometry *geometry, const CConfig *con if (implicit) { for (unsigned short iVar = 1; iVar <= nDim; iVar++) - Jacobian.DeleteValsRowi(iPoint*nVar+iVar); + Jacobian.DeleteValsRowi(iPoint, iVar); } if (!energy) continue; @@ -644,8 +644,8 @@ void CIncNSSolver::BC_ConjugateHeat_Interface(CGeometry *geometry, CSolver **sol if (implicit) { for (unsigned short iVar = 1; iVar <= nDim; iVar++) - Jacobian.DeleteValsRowi(iPoint*nVar+iVar); - if (energy) Jacobian.DeleteValsRowi(iPoint*nVar+nDim+1); + Jacobian.DeleteValsRowi(iPoint, iVar); + if (energy) Jacobian.DeleteValsRowi(iPoint, nDim + 1); } if (!energy) continue; @@ -739,6 +739,7 @@ void CIncNSSolver::SetTau_Wall_WF(CGeometry *geometry, CSolver **solver_containe const auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); const auto Point_Normal = geometry->vertex[iMarker][iVertex]->GetNormal_Neighbor(); + /*--- On the finest mesh compute also on halo nodes to avoid communication of tau wall. ---*/ if ((!geometry->nodes->GetDomain(iPoint)) && !(MGLevel==MESH_0)) continue; diff --git a/SU2_CFD/src/solvers/CMeshSolver.cpp b/SU2_CFD/src/solvers/CMeshSolver.cpp index 603b2e57d150..94792e9c1831 100644 --- a/SU2_CFD/src/solvers/CMeshSolver.cpp +++ b/SU2_CFD/src/solvers/CMeshSolver.cpp @@ -232,13 +232,9 @@ void CMeshSolver::SetMinMaxVolume(CGeometry *geometry, CConfig *config, bool upd if (ElemVolume <= 0.0) elCount++; } END_SU2_OMP_FOR - SU2_OMP_CRITICAL - { - MaxVolume = max(MaxVolume, maxVol); - MinVolume = min(MinVolume, minVol); - ElemCounter += elCount; - } - END_SU2_OMP_CRITICAL + atomicMax(maxVol, MaxVolume); + atomicMin(minVol, MinVolume); + atomicAdd(elCount, ElemCounter); BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { @@ -367,12 +363,9 @@ void CMeshSolver::SetWallDistance(CGeometry *geometry, CConfig *config) { } END_SU2_OMP_FOR - SU2_OMP_CRITICAL - { - MaxDistance = max(MaxDistance, MaxDistance_Local); - MinDistance = min(MinDistance, MinDistance_Local); - } - END_SU2_OMP_CRITICAL + + atomicMax(MaxDistance_Local, MaxDistance); + atomicMin(MinDistance_Local, MinDistance); BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { diff --git a/SU2_CFD/src/solvers/CNEMONSSolver.cpp b/SU2_CFD/src/solvers/CNEMONSSolver.cpp index ac4619145f52..44ede662420f 100644 --- a/SU2_CFD/src/solvers/CNEMONSSolver.cpp +++ b/SU2_CFD/src/solvers/CNEMONSSolver.cpp @@ -313,8 +313,7 @@ void CNEMONSSolver::BC_HeatFluxNonCatalytic_Wall(CGeometry *geometry, if (implicit) { /*--- Enforce the no-slip boundary condition in a strong way ---*/ for (int iVar = nSpecies; iVar < nSpecies+nDim; iVar++) { - auto total_index = iPoint*nVar+iVar; - Jacobian.DeleteValsRowi(total_index); + Jacobian.DeleteValsRowi(iPoint, iVar); } } @@ -349,7 +348,7 @@ void CNEMONSSolver::BC_HeatFluxCatalytic_Wall(CGeometry *geometry, SU2_MPI::Error("BC_HEATFLUX with catalytic wall: Not operational in NEMO.", CURRENT_FUNCTION); //TODO: SCALE WITH EDDY VISC /*--- Local variables ---*/ - unsigned long iPoint, total_index; + unsigned long iPoint; su2double rho, Ys; su2double *Normal, Area; su2double *Ds, *dYdn, SdYdn; @@ -493,8 +492,7 @@ void CNEMONSSolver::BC_HeatFluxCatalytic_Wall(CGeometry *geometry, if (implicit) { /*--- Enforce the no-slip boundary condition in a strong way ---*/ for (auto iVar = nSpecies; iVar < nSpecies+nDim; iVar++) { - total_index = iPoint*nVar+iVar; - Jacobian.DeleteValsRowi(total_index); + Jacobian.DeleteValsRowi(iPoint, iVar); } } @@ -632,8 +630,7 @@ void CNEMONSSolver::BC_IsothermalNonCatalytic_Wall(CGeometry *geometry, Jacobian.SubtractBlock2Diag(iPoint, Jacobian_i); for (auto iVar = 1u; iVar <= nDim; iVar++) { - auto total_index = iPoint*nVar+iVar; - Jacobian.DeleteValsRowi(total_index); + Jacobian.DeleteValsRowi(iPoint, iVar); } } } diff --git a/SU2_CFD/src/solvers/CNSSolver.cpp b/SU2_CFD/src/solvers/CNSSolver.cpp index 7a1309027a65..bb2dfc268d21 100644 --- a/SU2_CFD/src/solvers/CNSSolver.cpp +++ b/SU2_CFD/src/solvers/CNSSolver.cpp @@ -563,8 +563,7 @@ void CNSSolver::BC_HeatFlux_Wall_Generic(const CGeometry* geometry, const CConfi } for (auto iVar = 1u; iVar <= nDim; iVar++) { - auto total_index = iPoint*nVar+iVar; - Jacobian.DeleteValsRowi(total_index); + Jacobian.DeleteValsRowi(iPoint, iVar); } } } @@ -755,8 +754,7 @@ void CNSSolver::BC_Isothermal_Wall_Generic(CGeometry *geometry, CSolver **solver Jacobian.AddBlock2Diag(iPoint, Jacobian_i); for (auto iVar = 1u; iVar <= nDim; iVar++) { - auto total_index = iPoint*nVar+iVar; - Jacobian.DeleteValsRowi(total_index); + Jacobian.DeleteValsRowi(iPoint, iVar); } } } diff --git a/SU2_CFD/src/solvers/CRadP1Solver.cpp b/SU2_CFD/src/solvers/CRadP1Solver.cpp index 14eac91f2d65..dacf863afc13 100644 --- a/SU2_CFD/src/solvers/CRadP1Solver.cpp +++ b/SU2_CFD/src/solvers/CRadP1Solver.cpp @@ -491,7 +491,7 @@ void CRadP1Solver::BC_Marshak(CGeometry *geometry, CSolver **solver_container, C void CRadP1Solver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { unsigned short iVar; - unsigned long iPoint, total_index, IterLinSol = 0; + unsigned long iPoint, IterLinSol = 0; su2double Vol; su2double Delta; @@ -516,19 +516,17 @@ void CRadP1Solver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver else { Jacobian.SetVal2Diag(iPoint, 1.0); for (iVar = 0; iVar < nVar; iVar++) { - total_index = iPoint*nVar + iVar; - LinSysRes[total_index] = 0.0; + LinSysRes(iPoint, iVar) = 0.0; } } /*--- Right hand side of the system (-Residual) and initial guess (x = 0) ---*/ for (iVar = 0; iVar < nVar; iVar++) { - total_index = iPoint*nVar+iVar; - LinSysRes[total_index] = - (LinSysRes[total_index]); - LinSysSol[total_index] = 0.0; - Residual_RMS[iVar] += LinSysRes[total_index]*LinSysRes[total_index]; - AddRes_Max(iVar, fabs(LinSysRes[total_index]), geometry->nodes->GetGlobalIndex(iPoint), geometry->nodes->GetCoord(iPoint)); + LinSysRes(iPoint, iVar) = -LinSysRes(iPoint, iVar); + LinSysSol(iPoint, iVar) = 0.0; + Residual_RMS[iVar] += LinSysRes(iPoint, iVar)*LinSysRes(iPoint, iVar); + AddRes_Max(iVar, fabs(LinSysRes(iPoint, iVar)), geometry->nodes->GetGlobalIndex(iPoint), geometry->nodes->GetCoord(iPoint)); } } @@ -536,9 +534,8 @@ void CRadP1Solver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver for (iPoint = nPointDomain; iPoint < nPoint; iPoint++) { for (iVar = 0; iVar < nVar; iVar++) { - total_index = iPoint*nVar + iVar; - LinSysRes[total_index] = 0.0; - LinSysSol[total_index] = 0.0; + LinSysRes(iPoint, iVar) = 0.0; + LinSysSol(iPoint, iVar) = 0.0; } } diff --git a/SU2_CFD/src/solvers/CSolver.cpp b/SU2_CFD/src/solvers/CSolver.cpp index f544b694ba82..0ff0f125c1a1 100644 --- a/SU2_CFD/src/solvers/CSolver.cpp +++ b/SU2_CFD/src/solvers/CSolver.cpp @@ -667,44 +667,46 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, break; - case PERIODIC_SENSOR: + case PERIODIC_SENSOR: { + const bool msw = config->GetKind_Upwind_Flow() == UPWIND::MSW; /*--- For the centered schemes, the sensor must be computed consistently using info from the entire control volume on both sides of the periodic face. ---*/ - Sensor_i = 0.0; Sensor_j = 0.0; + Sensor_i = 0; Sensor_j = 0; for (auto jPoint : geometry->nodes->GetPoints(iPoint)) { /*--- Avoid halos and boundary points so that we don't duplicate edges on both sides of the periodic BC. ---*/ - if (!geometry->nodes->GetPeriodicBoundary(jPoint)) { + if (geometry->nodes->GetPeriodicBoundary(jPoint)) continue; - /*--- Use density instead of pressure for incomp. flows. ---*/ + /*--- Use density instead of pressure for incomp. flows. ---*/ - if ((config->GetKind_Regime() == ENUM_REGIME::INCOMPRESSIBLE)) { - Pressure_i = base_nodes->GetDensity(iPoint); - Pressure_j = base_nodes->GetDensity(jPoint); - } else { - Pressure_i = base_nodes->GetPressure(iPoint); - Pressure_j = base_nodes->GetPressure(jPoint); - } + if (config->GetKind_Regime() == ENUM_REGIME::INCOMPRESSIBLE) { + Pressure_i = base_nodes->GetDensity(iPoint); + Pressure_j = base_nodes->GetDensity(jPoint); + } else { + Pressure_i = base_nodes->GetPressure(iPoint); + Pressure_j = base_nodes->GetPressure(jPoint); + } - boundary_i = geometry->nodes->GetPhysicalBoundary(iPoint); - boundary_j = geometry->nodes->GetPhysicalBoundary(jPoint); + boundary_i = geometry->nodes->GetPhysicalBoundary(iPoint); + boundary_j = geometry->nodes->GetPhysicalBoundary(jPoint); - /*--- Both points inside domain, or both on boundary ---*/ - /*--- iPoint inside the domain, jPoint on the boundary ---*/ + /*--- Both points inside domain, or both on boundary ---*/ + /*--- iPoint inside the domain, jPoint on the boundary ---*/ - if (!boundary_i || boundary_j) { - if (geometry->nodes->GetDomain(iPoint)) { - Sensor_i += (Pressure_j - Pressure_i); - Sensor_j += (Pressure_i + Pressure_j); - } + if ((!boundary_i || boundary_j) && geometry->nodes->GetDomain(iPoint)) { + if (msw) { + Sensor_i = fmax(Sensor_i, fabs(Pressure_j - Pressure_i)) / fmin(Pressure_i, Pressure_j); + } else { + Sensor_i += (Pressure_j - Pressure_i); + Sensor_j += (Pressure_i + Pressure_j); } - } + } /*--- Store the sensor increments to buffer. After summing @@ -714,7 +716,7 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, buf_offset++; bufDSend[buf_offset] = Sensor_j; - break; + } break; case PERIODIC_SOL_GG: case PERIODIC_SOL_GG_R: @@ -1012,7 +1014,7 @@ void CSolver::CompletePeriodicComms(CGeometry *geometry, unsigned short nPeriodic = config->GetnMarker_Periodic(); unsigned short iDim, jDim, iVar, jVar, iPeriodic, nNeighbor; - unsigned long iPoint, iRecv, nRecv, msg_offset, buf_offset, total_index; + unsigned long iPoint, iRecv, nRecv, msg_offset, buf_offset; int source, iMessage, jRecv; @@ -1157,8 +1159,7 @@ void CSolver::CompletePeriodicComms(CGeometry *geometry, if (iPeriodic == val_periodic_index + nPeriodic/2) { for (iVar = 0; iVar < nVar; iVar++) { LinSysRes(iPoint, iVar) = 0.0; - total_index = iPoint*nVar+iVar; - Jacobian.DeleteValsRowi(total_index); + Jacobian.DeleteValsRowi(iPoint, iVar); } } @@ -1213,8 +1214,13 @@ void CSolver::CompletePeriodicComms(CGeometry *geometry, /*--- Simple accumulation of the sensors on periodic faces. ---*/ - iPoint_UndLapl[iPoint] += bufDRecv[buf_offset]; buf_offset++; - jPoint_UndLapl[iPoint] += bufDRecv[buf_offset]; + if (config->GetKind_Upwind_Flow() == UPWIND::MSW) { + iPoint_UndLapl[iPoint] = fmax(iPoint_UndLapl[iPoint], bufDRecv[buf_offset++]); + jPoint_UndLapl[iPoint] = 1; + } else { + iPoint_UndLapl[iPoint] += bufDRecv[buf_offset++]; + jPoint_UndLapl[iPoint] += bufDRecv[buf_offset]; + } break; @@ -1925,13 +1931,9 @@ void CSolver::AdaptCFLNumber(CGeometry **geometry, /* Reduce the min/max/avg local CFL numbers. */ if ((iMesh == MESH_0) && fullComms) { - SU2_OMP_CRITICAL - { /* OpenMP reduction. */ - Min_CFL_Local = min(Min_CFL_Local,myCFLMin); - Max_CFL_Local = max(Max_CFL_Local,myCFLMax); - Avg_CFL_Local += myCFLSum; - } - END_SU2_OMP_CRITICAL + atomicMin(myCFLMin, Min_CFL_Local); + atomicMax(myCFLMax, Max_CFL_Local); + atomicAdd(myCFLSum, Avg_CFL_Local); BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { /* MPI reduction. */ @@ -4043,7 +4045,7 @@ void CSolver::ComputeVertexTractions(CGeometry *geometry, const CConfig *config) // Calculate tn in the fluid nodes for the viscous term if (viscous_flow) { const su2double Viscosity = base_nodes->GetLaminarViscosity(iPoint); - su2double Tau[3][3]; + su2double Tau[3][3] = {{}}; CNumerics::ComputeStressTensor(nDim, Tau, base_nodes->GetVelocityGradient(iPoint), Viscosity); for (unsigned short iDim = 0; iDim < nDim; iDim++) { auxForce[iDim] += GeometryToolbox::DotProduct(nDim, Tau[iDim], Normal); diff --git a/SU2_CFD/src/solvers/CSolverFactory.cpp b/SU2_CFD/src/solvers/CSolverFactory.cpp index f6ceda06d84d..31a31495367a 100644 --- a/SU2_CFD/src/solvers/CSolverFactory.cpp +++ b/SU2_CFD/src/solvers/CSolverFactory.cpp @@ -178,8 +178,12 @@ CSolver** CSolverFactory::CreateSolverContainer(MAIN_SOLVER kindMainSolver, CCon } break; case MAIN_SOLVER::DISC_ADJ_FEM: - solver[FEA_SOL] = CreateSubSolver(SUB_SOLVER_TYPE::FEA, solver, geometry, config, iMGLevel); + solver[FEA_SOL] = CreateSubSolver(SUB_SOLVER_TYPE::FEA, solver, geometry, config, iMGLevel); solver[ADJFEA_SOL] = CreateSubSolver(SUB_SOLVER_TYPE::DISC_ADJ_FEA, solver, geometry, config, iMGLevel); + if (config->GetWeakly_Coupled_Heat()) { + solver[HEAT_SOL] = CreateSubSolver(SUB_SOLVER_TYPE::HEAT, solver, geometry, config, iMGLevel); + solver[ADJHEAT_SOL] = CreateSubSolver(SUB_SOLVER_TYPE::DISC_ADJ_HEAT, solver, geometry, config, iMGLevel); + } break; case MAIN_SOLVER::FEM_EULER: solver[FLOW_SOL] = CreateSubSolver(SUB_SOLVER_TYPE::DG_EULER, solver, geometry, config, iMGLevel); diff --git a/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp b/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp index 4247cea840a8..d2143ba8d1d8 100644 --- a/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp +++ b/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp @@ -154,14 +154,16 @@ void CSpeciesFlameletSolver::SetInitialCondition(CGeometry** geometry, CSolver** unsigned long ExtIter) { const bool restart = (config->GetRestart() || config->GetRestart_Flow()); - if ((!restart) && ExtIter == 0) { + bool flame_front_ignition = (flamelet_config_options.ignition_method == FLAMELET_INIT_TYPE::FLAME_FRONT); + + /*--- Also allow flame ignition when restarting. ---*/ + if (((!restart) && ExtIter == 0) || (restart && (flamelet_config_options.ignition_method != FLAMELET_INIT_TYPE::NONE))) { if (rank == MASTER_NODE) { cout << "Initializing progress variable and total enthalpy (using temperature)" << endl; } su2double flame_offset[3] = {0, 0, 0}, flame_normal[3] = {0, 0, 0}, flame_thickness = 0, flame_burnt_thickness = 0, flamenorm = 0; - bool flame_front_ignition = (flamelet_config_options.ignition_method == FLAMELET_INIT_TYPE::FLAME_FRONT); if (flame_front_ignition) { /*--- Collect flame front ignition parameters. ---*/ @@ -211,7 +213,7 @@ void CSpeciesFlameletSolver::SetInitialCondition(CGeometry** geometry, CSolver** for (unsigned long i_mesh = 0; i_mesh <= config->GetnMGLevels(); i_mesh++) { fluid_model_local = solver_container[i_mesh][FLOW_SOL]->GetFluidModel(); - prog_burnt = GetBurntProgressVariable(fluid_model_local, scalar_init); + if (flame_front_ignition) prog_burnt = GetBurntProgressVariable(fluid_model_local, scalar_init); for (auto iVar = 0u; iVar < nVar; iVar++) scalar_init[iVar] = config->GetSpecies_Init()[iVar]; @@ -270,6 +272,7 @@ void CSpeciesFlameletSolver::SetInitialCondition(CGeometry** geometry, CSolver** solver_container[i_mesh][SPECIES_SOL]->GetNodes()->SetSolution(i_point, scalar_init); } + END_SU2_OMP_FOR solver_container[i_mesh][SPECIES_SOL]->InitiateComms(geometry[i_mesh], config, MPI_QUANTITIES::SOLUTION); solver_container[i_mesh][SPECIES_SOL]->CompleteComms(geometry[i_mesh], config, MPI_QUANTITIES::SOLUTION); @@ -279,7 +282,6 @@ void CSpeciesFlameletSolver::SetInitialCondition(CGeometry** geometry, CSolver** solver_container[i_mesh][FLOW_SOL]->Preprocessing(geometry[i_mesh], solver_container[i_mesh], config, i_mesh, NO_RK_ITER, RUNTIME_FLOW_SYS, false); - END_SU2_OMP_FOR } /* --- Sum up some global counters over processes. --- */ @@ -458,8 +460,7 @@ void CSpeciesFlameletSolver::BC_Isothermal_Wall_Generic(CGeometry* geometry, CSo nodes->SetVal_ResTruncError_Zero(iPoint, I_ENTH); if (implicit) { - unsigned long total_index = iPoint * nVar + I_ENTH; - Jacobian.DeleteValsRowi(total_index); + Jacobian.DeleteValsRowi(iPoint, I_ENTH); } } else { /*--- Weak BC formulation. ---*/ @@ -796,7 +797,7 @@ su2double CSpeciesFlameletSolver::GetBurntProgressVariable(CFluidModel* fluid_mo bool outside = false; while (!outside) { fluid_model->SetTDState_T(300, scalars); - if (fluid_model->GetExtrapolation() == 1) outside = true; + if (fluid_model->GetExtrapolation() == 1 || (fluid_model->GetTemperature()>1000.)) outside = true; scalars[I_PROGVAR] += delta; } su2double pv_burnt = scalars[I_PROGVAR] - delta; diff --git a/SU2_CFD/src/solvers/CSpeciesSolver.cpp b/SU2_CFD/src/solvers/CSpeciesSolver.cpp index e1b65c56f823..8966ca3da319 100644 --- a/SU2_CFD/src/solvers/CSpeciesSolver.cpp +++ b/SU2_CFD/src/solvers/CSpeciesSolver.cpp @@ -357,15 +357,14 @@ void CSpeciesSolver::BC_Inlet(CGeometry* geometry, CSolver** solver_container, C if (!geometry->nodes->GetDomain(iPoint)) continue; - if (config->GetMarker_StrongBC(Marker_Tag)==true) { + if (config->GetMarker_StrongBC(Marker_Tag)) { nodes->SetSolution_Old(iPoint, Inlet_SpeciesVars[val_marker][iVertex]); LinSysRes.SetBlock_Zero(iPoint); /*--- Includes 1 in the diagonal ---*/ for (auto iVar = 0u; iVar < nVar; iVar++) { - auto total_index = iPoint * nVar + iVar; - Jacobian.DeleteValsRowi(total_index); + Jacobian.DeleteValsRowi(iPoint, iVar); } } else { // weak BC /*--- Normal vector for this vertex (negate for outward convention) ---*/ @@ -473,8 +472,7 @@ void CSpeciesSolver::BC_Wall_Generic(CGeometry* geometry, CSolver** solver_conta nodes->SetSolution_Old(iPoint, iVar, WallSpecies); LinSysRes(iPoint, iVar) = 0.0; if (implicit) { - unsigned long total_index = iPoint * nVar + iVar; - Jacobian.DeleteValsRowi(total_index); + Jacobian.DeleteValsRowi(iPoint, iVar); } break; } @@ -547,8 +545,7 @@ void CSpeciesSolver::BC_Outlet(CGeometry* geometry, CSolver** solver_container, /*--- Includes 1 on the diagonal ---*/ for (auto iVar = 0u; iVar < nVar; iVar++) { - auto total_index = iPoint * nVar + iVar; - Jacobian.DeleteValsRowi(total_index); + Jacobian.DeleteValsRowi(iPoint, iVar); } } else { // weak BC diff --git a/SU2_CFD/src/solvers/CTurbSASolver.cpp b/SU2_CFD/src/solvers/CTurbSASolver.cpp index 5ea64882b0b7..00d3009faa75 100644 --- a/SU2_CFD/src/solvers/CTurbSASolver.cpp +++ b/SU2_CFD/src/solvers/CTurbSASolver.cpp @@ -301,7 +301,7 @@ void CTurbSASolver::Viscous_Residual(const unsigned long iEdge, const CGeometry* /*--- Roughness heights. ---*/ numerics->SetRoughness(geometry->nodes->GetRoughnessHeight(iPoint), geometry->nodes->GetRoughnessHeight(jPoint)); }; - + /*--- Now instantiate the generic non-conservative implementation with the functor above. ---*/ Viscous_Residual_NonCons(iEdge, geometry, solver_container, numerics, config, SolverSpecificNumerics); @@ -479,7 +479,7 @@ void CTurbSASolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_conta /*--- Includes 1 in the diagonal ---*/ - if (implicit) Jacobian.DeleteValsRowi(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} @@ -503,9 +503,8 @@ void CTurbSASolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_conta su2double coeff = (nu_total/sigma); su2double RoughWallBC = nodes->GetSolution(iPoint,0)/(0.03*Roughness_Height); - su2double Res_Wall;// = new su2double [nVar]; - Res_Wall = coeff*RoughWallBC*Area; - LinSysRes.SubtractBlock(iPoint, &Res_Wall); + su2double Res_Wall = coeff*RoughWallBC*Area; + LinSysRes(iPoint, 0) -= Res_Wall; su2double Jacobian_i = (laminar_viscosity /density *Area)/(0.03*Roughness_Height*sigma); Jacobian_i += 2.0*RoughWallBC*Area/sigma; @@ -1342,7 +1341,7 @@ void CTurbSASolver::SetTurbVars_WF(CGeometry *geometry, CSolver **solver_contain /*--- includes 1 in the diagonal ---*/ - if (implicit) Jacobian.DeleteValsRowi(iPoint_Neighbor); + if (implicit) Jacobian.DeleteValsRowi(iPoint_Neighbor, 0); } } } @@ -1555,7 +1554,7 @@ void CTurbSASolver::SetUniformInlet(const CConfig* config, unsigned short iMarke } } -void CTurbSASolver::ComputeUnderRelaxationFactor(const CConfig *config) { +void CTurbSASolver::ComputeUnderRelaxationFactor(CSolver** solver_container, const CConfig *config) { /* Apply the turbulent under-relaxation to the SA variants. The SA_NEG model is more robust due to allowing for negative nu_tilde, @@ -1568,6 +1567,6 @@ void CTurbSASolver::ComputeUnderRelaxationFactor(const CConfig *config) { const su2double allowableRatio = config->GetMaxUpdateFractionSA(); - ComputeUnderRelaxationFactorHelper(allowableRatio); + ComputeUnderRelaxationFactorHelper(solver_container, allowableRatio); } diff --git a/SU2_CFD/src/solvers/CTurbSSTSolver.cpp b/SU2_CFD/src/solvers/CTurbSSTSolver.cpp index 3ce8b2e300a2..e5e845abf7a0 100644 --- a/SU2_CFD/src/solvers/CTurbSSTSolver.cpp +++ b/SU2_CFD/src/solvers/CTurbSSTSolver.cpp @@ -505,8 +505,8 @@ void CTurbSSTSolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_cont if (implicit) { /*--- Change rows of the Jacobian (includes 1 in the diagonal) ---*/ - Jacobian.DeleteValsRowi(iPoint*nVar); - Jacobian.DeleteValsRowi(iPoint*nVar+1); + Jacobian.DeleteValsRowi(iPoint, 0); + Jacobian.DeleteValsRowi(iPoint, 1); } } END_SU2_OMP_FOR @@ -568,8 +568,8 @@ void CTurbSSTSolver::SetTurbVars_WF(CGeometry *geometry, CSolver **solver_contai if (implicit) { /*--- includes 1 in the diagonal ---*/ - Jacobian.DeleteValsRowi(iPoint_Neighbor*nVar); - Jacobian.DeleteValsRowi(iPoint_Neighbor*nVar+1); + Jacobian.DeleteValsRowi(iPoint_Neighbor, 0); + Jacobian.DeleteValsRowi(iPoint_Neighbor, 1); } } } @@ -1046,9 +1046,9 @@ void CTurbSSTSolver::SetUniformInlet(const CConfig* config, unsigned short iMark } -void CTurbSSTSolver::ComputeUnderRelaxationFactor(const CConfig *config) { +void CTurbSSTSolver::ComputeUnderRelaxationFactor(CSolver** solver_container, const CConfig *config) { const su2double allowableRatio = config->GetMaxUpdateFractionSST(); - ComputeUnderRelaxationFactorHelper(allowableRatio); + ComputeUnderRelaxationFactorHelper(solver_container, allowableRatio); } \ No newline at end of file diff --git a/SU2_CFD/src/solvers/CTurbSolver.cpp b/SU2_CFD/src/solvers/CTurbSolver.cpp index f6aed2de8522..609bc3daaeed 100644 --- a/SU2_CFD/src/solvers/CTurbSolver.cpp +++ b/SU2_CFD/src/solvers/CTurbSolver.cpp @@ -229,7 +229,7 @@ void CTurbSolver::Impose_Fixed_Values(const CGeometry *geometry, const CConfig * if (implicit) { /*--- Change rows of the Jacobian (includes 1 in the diagonal) ---*/ for(unsigned long iVar=0; iVarGetSolution(iPoint, iVar)) + EPS); + + su2double current_sol = nodes->GetSolution(iPoint, iVar); + if (Conservative) { + /* Need to multiply by density if this is a conservative variable */ + current_sol *= solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + } + + su2double ratio = fabs(LinSysSol(iPoint, iVar) / (current_sol + EPS)); /* We impose a limit on the maximum percentage that the turbulence variables can change over a nonlinear iteration. */ if (ratio > allowableRatio) { localUnderRelaxation = min(allowableRatio / ratio, localUnderRelaxation); - } } diff --git a/SU2_CFD/src/variables/CAdjEulerVariable.cpp b/SU2_CFD/src/variables/CAdjEulerVariable.cpp index 565c80f8c774..b2ac36a5b8bb 100644 --- a/SU2_CFD/src/variables/CAdjEulerVariable.cpp +++ b/SU2_CFD/src/variables/CAdjEulerVariable.cpp @@ -95,6 +95,9 @@ CAdjEulerVariable::CAdjEulerVariable(su2double psirho, const su2double *phi, su2 if (config->GetTime_Marching() == TIME_MARCHING::HARMONIC_BALANCE) HB_Source.resize(nPoint,nVar) = su2double(0.0); + /*--- Allocate LocalCFL for multigrid support ---*/ + LocalCFL.resize(nPoint) = su2double(0.0); + if (config->GetMultizone_Problem()) Set_BGSSolution_k(); diff --git a/SU2_CFD/src/variables/CEulerVariable.cpp b/SU2_CFD/src/variables/CEulerVariable.cpp index 4e88c9a467d6..f7b5d71f358d 100644 --- a/SU2_CFD/src/variables/CEulerVariable.cpp +++ b/SU2_CFD/src/variables/CEulerVariable.cpp @@ -34,7 +34,9 @@ unsigned long EulerNPrimVarGrad(const CConfig *config, unsigned long ndim) { const bool ideal_gas = config->GetKind_FluidModel() == STANDARD_AIR || config->GetKind_FluidModel() == IDEAL_GAS; - if (ideal_gas && config->GetKind_Upwind_Flow() == UPWIND::ROE && !config->Low_Mach_Correction()) { + const bool low_mach = config->Low_Mach_Correction(); + if (ideal_gas && !low_mach && + (config->GetKind_Upwind_Flow() == UPWIND::ROE || config->GetKind_Upwind_Flow() == UPWIND::MSW)) { // Based on CRoeBase (numerics_simd). return ndim + 2; } diff --git a/SU2_PY/SU2/io/historyMap.py b/SU2_PY/SU2/io/historyMap.py index 93a49a2ce0f5..57392eb82073 100644 --- a/SU2_PY/SU2/io/historyMap.py +++ b/SU2_PY/SU2/io/historyMap.py @@ -310,6 +310,12 @@ "HEADER": "ComboObj", "TYPE": "COEFFICIENT", }, + "CUSTOM_OBJFUNC": { + "DESCRIPTION": "Custom obj. function value.", + "GROUP": "COMBO", + "HEADER": "CustomObj", + "TYPE": "COEFFICIENT", + }, "DEFORM_ITER": { "DESCRIPTION": "Linear solver iterations for the mesh " "deformation", "GROUP": "DEFORM", diff --git a/SU2_PY/SU2/util/polarSweepLib.py b/SU2_PY/SU2/util/polarSweepLib.py index 72137e58185f..73d2c3a241e8 100755 --- a/SU2_PY/SU2/util/polarSweepLib.py +++ b/SU2_PY/SU2/util/polarSweepLib.py @@ -147,7 +147,6 @@ def readParameter(dataFile, nLines, keyWord, iDoNot, verbose): def setContribution(dataFile, nLines, keyWord, iDoNot, verbose): from numpy import size - import string # # default values @@ -176,7 +175,7 @@ def setContribution(dataFile, nLines, keyWord, iDoNot, verbose): # now find out where the standard text ends iBF = firstPart.lower().index("family") + 6 - nameText = string.join(firstPart[iBF:].split(), "") + nameText = "".join(firstPart[iBF:].split()) # component name located. Now check about its contribution try: diff --git a/SU2_PY/SU2_CFD.py b/SU2_PY/SU2_CFD.py index c652bfb729b4..7de10b7f7a6a 100755 --- a/SU2_PY/SU2_CFD.py +++ b/SU2_PY/SU2_CFD.py @@ -30,7 +30,7 @@ # ---------------------------------------------------------------------- from __future__ import division, print_function, absolute_import -from optparse import OptionParser # use a parser for configuration +import argparse # use a parser for configuration import SU2 # imports SU2 python tools import pysu2 # imports the SU2 wrapped module @@ -42,67 +42,67 @@ def main(): # Command line options - parser = OptionParser() - parser.add_option( + parser = argparse.ArgumentParser() + parser.add_argument( "-f", "--file", dest="filename", help="Read config from FILE", metavar="FILE" ) - parser.add_option( + parser.add_argument( "--nDim", dest="nDim", default=2, help="Define the number of DIMENSIONS", metavar="DIMENSIONS", ) - parser.add_option( + parser.add_argument( "--nZone", dest="nZone", default=1, help="Define the number of ZONES", metavar="NZONE", ) - parser.add_option( + parser.add_argument( "--parallel", action="store_true", help="Specify if we need to initialize MPI", dest="with_MPI", default=False, ) - parser.add_option( + parser.add_argument( "--fsi", dest="fsi", default="False", help="Launch the FSI driver", metavar="FSI", ) - parser.add_option( + parser.add_argument( "--fem", dest="fem", default="False", help="Launch the FEM driver (General driver)", metavar="FEM", ) - parser.add_option( + parser.add_argument( "--harmonic_balance", dest="harmonic_balance", default="False", help="Launch the Harmonic Balance (HB) driver", metavar="HB", ) - parser.add_option( + parser.add_argument( "--poisson_equation", dest="poisson_equation", default="False", help="Launch the poisson equation driver (General driver)", metavar="POIS_EQ", ) - parser.add_option( + parser.add_argument( "--wave_equation", dest="wave_equation", default="False", help="Launch the wave equation driver (General driver)", metavar="WAVE_EQ", ) - parser.add_option( + parser.add_argument( "--heat_equation", dest="heat_equation", default="False", @@ -110,7 +110,7 @@ def main(): metavar="HEAT_EQ", ) - (options, args) = parser.parse_args() + options = parser.parse_args() options.nDim = int(options.nDim) options.nZone = int(options.nZone) options.fsi = options.fsi.upper() == "TRUE" diff --git a/SU2_PY/change_version_number.py b/SU2_PY/change_version_number.py index a868f88205ab..49b82da680d4 100755 --- a/SU2_PY/change_version_number.py +++ b/SU2_PY/change_version_number.py @@ -27,30 +27,30 @@ # make print(*args) function available in PY2.6+, does'nt work on PY < 2.6 from __future__ import print_function -from optparse import OptionParser +import argparse # Run the script from the base directory (ie $SU2HOME). Grep will search directories recursively for matches in version number import os, sys -parser = OptionParser() -parser.add_option( +parser = argparse.ArgumentParser() +parser.add_argument( "-v", "--version", dest="version", help="the new version number", metavar="VERSION" ) -parser.add_option( +parser.add_argument( "-r", "--releasename", dest="releasename", help="Name of the new release", metavar="RELEASENAME", ) -parser.add_option( +parser.add_argument( "-y", action="store_true", dest="yes", help="Answer yes to all questions", metavar="YES", ) -(options, args) = parser.parse_args() +options = parser.parse_args() if not options.version: parser.error("new version number must be provided with -v option") diff --git a/SU2_PY/compute_polar.py b/SU2_PY/compute_polar.py index b7daac33799a..d696c1d5e6ea 100755 --- a/SU2_PY/compute_polar.py +++ b/SU2_PY/compute_polar.py @@ -41,7 +41,7 @@ # imports import os, sys, shutil -from optparse import OptionParser +import argparse sys.path.append(os.environ["SU2_RUN"]) import SU2 @@ -52,8 +52,8 @@ def main(): # Command Line Options - parser = OptionParser() - parser.add_option( + parser = argparse.ArgumentParser() + parser.add_argument( "-c", "--ctrl", dest="ctrlFile", @@ -61,7 +61,7 @@ def main(): metavar="FILE", default="polarCtrl.in", ) - parser.add_option( + parser.add_argument( "-n", "--partitions", dest="partitions", @@ -69,7 +69,7 @@ def main(): help="number of PARTITIONS", metavar="PARTITIONS", ) - parser.add_option( + parser.add_argument( "-i", "--iterations", dest="iterations", @@ -77,7 +77,7 @@ def main(): help="number of ITERATIONS", metavar="ITERATIONS", ) - parser.add_option( + parser.add_argument( "-d", "--dimension", dest="geomDim", @@ -85,7 +85,7 @@ def main(): help="Geometry dimension (2 or 3)", metavar="geomDim", ) - parser.add_option( + parser.add_argument( "-w", "--Wind", action="store_true", @@ -93,7 +93,7 @@ def main(): default=False, help=" Wind system (default is body system)", ) - parser.add_option( + parser.add_argument( "-v", "--Verbose", action="store_true", @@ -102,7 +102,7 @@ def main(): help=" Verbose printout (if activated)", ) - (options, args) = parser.parse_args() + options = parser.parse_args() options.partitions = int(options.partitions) options.iterations = int(options.iterations) options.geomDim = int(options.geomDim) diff --git a/SU2_PY/compute_uncertainty.py b/SU2_PY/compute_uncertainty.py index beac7a3f6d06..845d0f1b96b6 100755 --- a/SU2_PY/compute_uncertainty.py +++ b/SU2_PY/compute_uncertainty.py @@ -26,7 +26,7 @@ # License along with SU2. If not, see . # imports import numpy as np -from optparse import OptionParser +import argparse import os import sys import shutil @@ -39,11 +39,11 @@ def main(): # Command Line Options - parser = OptionParser() - parser.add_option( + parser = argparse.ArgumentParser() + parser.add_argument( "-f", "--file", dest="filename", help="read config from FILE", metavar="FILE" ) - parser.add_option( + parser.add_argument( "-n", "--partitions", dest="partitions", @@ -51,7 +51,7 @@ def main(): help="number of PARTITIONS", metavar="PARTITIONS", ) - parser.add_option( + parser.add_argument( "-u", "--underRelaxation", dest="uq_urlx", @@ -59,7 +59,7 @@ def main(): help="under relaxation factor", metavar="UQ_URLX", ) - parser.add_option( + parser.add_argument( "-b", "--deltaB", dest="uq_delta_b", @@ -68,7 +68,7 @@ def main(): metavar="UQ_DELTA_B", ) - (options, args) = parser.parse_args() + options = parser.parse_args() options.partitions = int(options.partitions) # check the typecasting options.beta_delta = float(options.uq_delta_b) diff --git a/SU2_PY/continuous_adjoint.py b/SU2_PY/continuous_adjoint.py index 9f43034b0d99..26d42039ccca 100755 --- a/SU2_PY/continuous_adjoint.py +++ b/SU2_PY/continuous_adjoint.py @@ -26,7 +26,7 @@ # License along with SU2. If not, see . import os, sys -from optparse import OptionParser +import argparse sys.path.append(os.environ["SU2_RUN"]) import SU2 @@ -39,11 +39,11 @@ def main(): # Command Line Options - parser = OptionParser() - parser.add_option( + parser = argparse.ArgumentParser() + parser.add_argument( "-f", "--file", dest="filename", help="read config from FILE", metavar="FILE" ) - parser.add_option( + parser.add_argument( "-n", "--partitions", dest="partitions", @@ -51,7 +51,7 @@ def main(): help="number of PARTITIONS", metavar="PARTITIONS", ) - parser.add_option( + parser.add_argument( "-c", "--compute", dest="compute", @@ -59,7 +59,7 @@ def main(): help="COMPUTE direct and adjoint problem", metavar="COMPUTE", ) - parser.add_option( + parser.add_argument( "-s", "--step", dest="step", @@ -67,7 +67,7 @@ def main(): help="DOT finite difference STEP", metavar="STEP", ) - parser.add_option( + parser.add_argument( "-z", "--zones", dest="nzones", @@ -76,7 +76,7 @@ def main(): metavar="ZONES", ) - (options, args) = parser.parse_args() + options = parser.parse_args() options.partitions = int(options.partitions) options.step = float(options.step) options.compute = options.compute.upper() == "TRUE" diff --git a/SU2_PY/direct_differentiation.py b/SU2_PY/direct_differentiation.py index 56de022474b4..513ee265067e 100755 --- a/SU2_PY/direct_differentiation.py +++ b/SU2_PY/direct_differentiation.py @@ -27,7 +27,7 @@ from __future__ import division, print_function, absolute_import import os, sys, shutil -from optparse import OptionParser +import argparse sys.path.append(os.environ["SU2_RUN"]) import SU2 @@ -39,11 +39,11 @@ def main(): - parser = OptionParser() - parser.add_option( + parser = argparse.ArgumentParser() + parser.add_argument( "-f", "--file", dest="filename", help="read config from FILE", metavar="FILE" ) - parser.add_option( + parser.add_argument( "-n", "--partitions", dest="partitions", @@ -51,7 +51,7 @@ def main(): help="number of PARTITIONS", metavar="PARTITIONS", ) - parser.add_option( + parser.add_argument( "-q", "--quiet", dest="quiet", @@ -59,7 +59,7 @@ def main(): help="output QUIET to log files", metavar="QUIET", ) - parser.add_option( + parser.add_argument( "-z", "--zones", dest="nzones", @@ -68,7 +68,7 @@ def main(): metavar="ZONES", ) - (options, args) = parser.parse_args() + options = parser.parse_args() options.partitions = int(options.partitions) options.quiet = options.quiet.upper() == "TRUE" options.nzones = int(options.nzones) diff --git a/SU2_PY/discrete_adjoint.py b/SU2_PY/discrete_adjoint.py index 8e274a67ee77..aeb5e40a30da 100755 --- a/SU2_PY/discrete_adjoint.py +++ b/SU2_PY/discrete_adjoint.py @@ -26,7 +26,7 @@ # License along with SU2. If not, see . import os, sys, copy -from optparse import OptionParser +import argparse sys.path.append(os.environ["SU2_RUN"]) import SU2 @@ -39,11 +39,11 @@ def main(): # Command Line Options - parser = OptionParser() - parser.add_option( + parser = argparse.ArgumentParser(description="SU2 discrete adjoint computation.") + parser.add_argument( "-f", "--file", dest="filename", help="read config from FILE", metavar="FILE" ) - parser.add_option( + parser.add_argument( "-n", "--partitions", dest="partitions", @@ -51,7 +51,7 @@ def main(): help="number of PARTITIONS", metavar="PARTITIONS", ) - parser.add_option( + parser.add_argument( "-s", "--step", dest="step", @@ -59,7 +59,7 @@ def main(): help="DOT finite difference STEP", metavar="STEP", ) - parser.add_option( + parser.add_argument( "-v", "--validate", dest="validate", @@ -67,7 +67,7 @@ def main(): help="Validate the gradient using direct diff. mode", metavar="VALIDATION", ) - parser.add_option( + parser.add_argument( "-z", "--zones", dest="nzones", @@ -75,7 +75,7 @@ def main(): help="Number of Zones", metavar="ZONES", ) - parser.add_option( + parser.add_argument( "-m", "--mode", dest="mode", @@ -84,7 +84,7 @@ def main(): metavar="MODE", ) - (options, args) = parser.parse_args() + options = parser.parse_args() options.partitions = int(options.partitions) options.step = float(options.step) options.validate = options.validate.upper() == "TRUE" diff --git a/SU2_PY/finite_differences.py b/SU2_PY/finite_differences.py index 8df97948c9bc..fbca3581fd03 100755 --- a/SU2_PY/finite_differences.py +++ b/SU2_PY/finite_differences.py @@ -26,7 +26,7 @@ # License along with SU2. If not, see . import os, sys -from optparse import OptionParser +import argparse sys.path.append(os.environ["SU2_RUN"]) import SU2 @@ -38,11 +38,11 @@ def main(): - parser = OptionParser() - parser.add_option( + parser = argparse.ArgumentParser(description="SU2 finite differences computation.") + parser.add_argument( "-f", "--file", dest="filename", help="read config from FILE", metavar="FILE" ) - parser.add_option( + parser.add_argument( "-n", "--partitions", dest="partitions", @@ -50,7 +50,7 @@ def main(): help="number of PARTITIONS", metavar="PARTITIONS", ) - parser.add_option( + parser.add_argument( "-q", "--quiet", dest="quiet", @@ -58,7 +58,7 @@ def main(): help="output QUIET to log files", metavar="QUIET", ) - parser.add_option( + parser.add_argument( "-z", "--zones", dest="nzones", @@ -67,7 +67,7 @@ def main(): metavar="ZONES", ) - (options, args) = parser.parse_args() + options = parser.parse_args() options.partitions = int(options.partitions) options.quiet = options.quiet.upper() == "TRUE" options.nzones = int(options.nzones) diff --git a/SU2_PY/fsi_computation.py b/SU2_PY/fsi_computation.py index 9fbb3b212209..49eceeb5c263 100755 --- a/SU2_PY/fsi_computation.py +++ b/SU2_PY/fsi_computation.py @@ -35,7 +35,7 @@ import copy import time as timer from math import * # use mathematical expressions -from optparse import OptionParser # use a parser for configuration +import argparse # use a parser for configuration # imports the CFD (SU2) module for FSI computation import pysu2 @@ -49,11 +49,11 @@ def main(): # --- Get the FSI conig file name form the command line options --- # - parser = OptionParser() - parser.add_option( + parser = argparse.ArgumentParser() + parser.add_argument( "-f", "--file", dest="filename", help="read config from FILE", metavar="FILE" ) - parser.add_option( + parser.add_argument( "--parallel", action="store_true", help="Specify if we need to initialize MPI", @@ -61,7 +61,7 @@ def main(): default=False, ) - (options, args) = parser.parse_args() + options = parser.parse_args() if options.with_MPI: from mpi4py import ( diff --git a/SU2_PY/merge_solution.py b/SU2_PY/merge_solution.py index 2cdc6746cfdd..40a5738a5bf2 100755 --- a/SU2_PY/merge_solution.py +++ b/SU2_PY/merge_solution.py @@ -25,7 +25,7 @@ # You should have received a copy of the GNU Lesser General Public # License along with SU2. If not, see . -from optparse import OptionParser +import argparse import SU2 # ------------------------------------------------------------------- @@ -35,11 +35,11 @@ def main(): - parser = OptionParser() - parser.add_option( + parser = argparse.ArgumentParser() + parser.add_argument( "-f", "--file", dest="filename", help="read config from FILE", metavar="FILE" ) - parser.add_option( + parser.add_argument( "-n", "--partitions", dest="partitions", @@ -48,7 +48,7 @@ def main(): metavar="PARTITIONS", ) - (options, args) = parser.parse_args() + options = parser.parse_args() options.partitions = int(options.partitions) merge_solution(options.filename, options.partitions) diff --git a/SU2_PY/mesh_deformation.py b/SU2_PY/mesh_deformation.py index f92692d12c43..ce4c261ba9a9 100755 --- a/SU2_PY/mesh_deformation.py +++ b/SU2_PY/mesh_deformation.py @@ -26,7 +26,7 @@ # License along with SU2. If not, see . import os, sys -from optparse import OptionParser +import argparse sys.path.append(os.environ["SU2_RUN"]) import SU2 @@ -39,11 +39,11 @@ def main(): # Command Line Options - parser = OptionParser() - parser.add_option( + parser = argparse.ArgumentParser() + parser.add_argument( "-f", "--file", dest="filename", help="read config from FILE", metavar="FILE" ) - parser.add_option( + parser.add_argument( "-n", "--partitions", dest="partitions", @@ -52,7 +52,7 @@ def main(): metavar="PARTITIONS", ) - (options, args) = parser.parse_args() + options = parser.parse_args() options.partitions = int(options.partitions) # Run Parallel Comutation diff --git a/SU2_PY/parallel_computation.py b/SU2_PY/parallel_computation.py index f102fe945664..66cdfffdbcbd 100755 --- a/SU2_PY/parallel_computation.py +++ b/SU2_PY/parallel_computation.py @@ -26,7 +26,7 @@ # License along with SU2. If not, see . import os, sys -from optparse import OptionParser +import argparse sys.path.append(os.environ["SU2_RUN"]) import SU2 @@ -39,11 +39,11 @@ def main(): # Command Line Options - parser = OptionParser() - parser.add_option( + parser = argparse.ArgumentParser() + parser.add_argument( "-f", "--file", dest="filename", help="read config from FILE", metavar="FILE" ) - parser.add_option( + parser.add_argument( "-n", "--partitions", dest="partitions", @@ -51,7 +51,7 @@ def main(): help="number of PARTITIONS", metavar="PARTITIONS", ) - parser.add_option( + parser.add_argument( "-c", "--compute", dest="compute", @@ -60,7 +60,7 @@ def main(): metavar="COMPUTE", ) - (options, args) = parser.parse_args() + options = parser.parse_args() options.partitions = int(options.partitions) options.compute = options.compute.upper() == "TRUE" diff --git a/SU2_PY/parallel_computation_fsi.py b/SU2_PY/parallel_computation_fsi.py index 0fb6b459b696..dab33ad21e40 100755 --- a/SU2_PY/parallel_computation_fsi.py +++ b/SU2_PY/parallel_computation_fsi.py @@ -26,7 +26,7 @@ # License along with SU2. If not, see . import os, sys, shutil, copy -from optparse import OptionParser +import argparse sys.path.append(os.environ["SU2_RUN"]) import SU2 @@ -39,11 +39,11 @@ def main(): # Command Line Options - parser = OptionParser() - parser.add_option( + parser = argparse.ArgumentParser() + parser.add_argument( "-f", "--file", dest="filename", help="read config from FILE", metavar="FILE" ) - parser.add_option( + parser.add_argument( "-n", "--partitions", dest="partitions", @@ -51,7 +51,7 @@ def main(): help="number of PARTITIONS", metavar="PARTITIONS", ) - parser.add_option( + parser.add_argument( "-c", "--compute", dest="compute", @@ -60,7 +60,7 @@ def main(): metavar="COMPUTE", ) - (options, args) = parser.parse_args() + options = parser.parse_args() options.partitions = int(options.partitions) options.compute = options.compute.upper() == "TRUE" diff --git a/SU2_PY/profiling.py b/SU2_PY/profiling.py index 5786bb0e629e..acd22b5494a7 100755 --- a/SU2_PY/profiling.py +++ b/SU2_PY/profiling.py @@ -25,17 +25,17 @@ # You should have received a copy of the GNU Lesser General Public # License along with SU2. If not, see . -from optparse import OptionParser +import argparse from pylab import * from numpy import * from matplotlib import pyplot as plt from matplotlib import mlab -parser = OptionParser() -parser.add_option( +parser = argparse.ArgumentParser() +parser.add_argument( "-f", "--file", dest="file", help="profiling CSV file", metavar="FILE" ) -(options, args) = parser.parse_args() +options = parser.parse_args() # Store the file name filename = options.file diff --git a/SU2_PY/pySU2/install.sh b/SU2_PY/pySU2/install.sh index 67e684487f8a..5da0e3c6db75 100644 --- a/SU2_PY/pySU2/install.sh +++ b/SU2_PY/pySU2/install.sh @@ -1,2 +1,2 @@ #!/bin/sh -cp "$1/$2" "${MESON_INSTALL_PREFIX}/bin/$2" +cp "$1/$2" "${MESON_INSTALL_DESTDIR_PREFIX}/bin/$2" diff --git a/SU2_PY/pySU2/meson.build b/SU2_PY/pySU2/meson.build index 3d9abc747ec5..436eb4b0d56a 100644 --- a/SU2_PY/pySU2/meson.build +++ b/SU2_PY/pySU2/meson.build @@ -19,10 +19,17 @@ else mpi4py_include = '' endif +su2_swig_args = [] +foreach arg : su2_cpp_args + if not arg.startswith('-f') and not arg.startswith('-m') + su2_swig_args += arg + endif +endforeach + swig_gen = generator( swig, output: ['@BASENAME@.cxx'], - arguments: su2_cpp_args + + arguments: su2_swig_args + [ '-c++', '-python', '-I'+mpi4py_include, '-outdir', meson.current_build_dir(), '-o', './@OUTPUT@', '@INPUT@'], depfile: '@BASENAME@.d', ) @@ -43,7 +50,7 @@ if get_option('enable-normal') ], install: true, include_directories : mpi4py_include, - cpp_args : [default_warning_flags,su2_cpp_args], + cpp_args : [default_warning_flags, su2_swig_args], name_prefix : '', install_dir: 'bin' ) @@ -62,7 +69,7 @@ if get_option('enable-autodiff') ], install: true, include_directories : mpi4py_include, - cpp_args : [default_warning_flags, su2_cpp_args, codi_rev_args], + cpp_args : [default_warning_flags, su2_swig_args, codi_rev_args], name_prefix : '', install_dir: 'bin' ) diff --git a/SU2_PY/set_ffd_design_var.py b/SU2_PY/set_ffd_design_var.py index acee5722daf7..bf8d98a6b357 100755 --- a/SU2_PY/set_ffd_design_var.py +++ b/SU2_PY/set_ffd_design_var.py @@ -28,11 +28,11 @@ # make print(*args) function available in PY2.6+, does'nt work on PY < 2.6 from __future__ import print_function -from optparse import OptionParser +import argparse from numpy import * -parser = OptionParser() -parser.add_option( +parser = argparse.ArgumentParser() +parser.add_argument( "-i", "--iDegree", dest="iDegree", @@ -40,7 +40,7 @@ help="i degree of the FFD box", metavar="IDEGREE", ) -parser.add_option( +parser.add_argument( "-j", "--jDegree", dest="jDegree", @@ -48,7 +48,7 @@ help="j degree of the FFD box", metavar="JDEGREE", ) -parser.add_option( +parser.add_argument( "-k", "--kDegree", dest="kDegree", @@ -56,7 +56,7 @@ help="k degree of the FFD box", metavar="KDEGREE", ) -parser.add_option( +parser.add_argument( "-b", "--ffdid", dest="ffd_id", @@ -64,21 +64,21 @@ help="ID of the FFD box", metavar="FFD_ID", ) -parser.add_option( +parser.add_argument( "-m", "--marker", dest="marker", help="marker name of the design surface", metavar="MARKER", ) -parser.add_option( +parser.add_argument( "-a", "--axis", dest="axis", help="axis to define twist 'x_Orig, y_Orig, z_Orig, x_End, y_End, z_End'", metavar="AXIS", ) -parser.add_option( +parser.add_argument( "-s", "--scale", dest="scale", @@ -86,7 +86,7 @@ help="scale factor for the bump functions", metavar="SCALE", ) -parser.add_option( +parser.add_argument( "-d", "--dimension", dest="dimension", @@ -95,7 +95,7 @@ metavar="DIMENSION", ) -(options, args) = parser.parse_args() +options = parser.parse_args() # Process options options.iOrder = int(options.iDegree) + 1 diff --git a/SU2_PY/shape_optimization.py b/SU2_PY/shape_optimization.py index 8a68f0ea61cd..0f29a25c123f 100755 --- a/SU2_PY/shape_optimization.py +++ b/SU2_PY/shape_optimization.py @@ -26,7 +26,7 @@ # License along with SU2. If not, see . import os, sys, shutil -from optparse import OptionParser +import argparse sys.path.append(os.environ["SU2_RUN"]) import SU2 @@ -38,11 +38,11 @@ def main(): - parser = OptionParser() - parser.add_option( + parser = argparse.ArgumentParser(description="SU2 shape optimization.") + parser.add_argument( "-f", "--file", dest="filename", help="read config from FILE", metavar="FILE" ) - parser.add_option( + parser.add_argument( "-r", "--name", dest="projectname", @@ -50,7 +50,7 @@ def main(): help="try to restart from project file NAME", metavar="NAME", ) - parser.add_option( + parser.add_argument( "-n", "--partitions", dest="partitions", @@ -58,7 +58,7 @@ def main(): help="number of PARTITIONS", metavar="PARTITIONS", ) - parser.add_option( + parser.add_argument( "-g", "--gradient", dest="gradient", @@ -66,7 +66,7 @@ def main(): help="Method for computing the GRADIENT (CONTINUOUS_ADJOINT, DISCRETE_ADJOINT, FINDIFF, NONE)", metavar="GRADIENT", ) - parser.add_option( + parser.add_argument( "-o", "--optimization", dest="optimization", @@ -74,7 +74,7 @@ def main(): help="OPTIMIZATION techique (SLSQP, CG, BFGS, POWELL)", metavar="OPTIMIZATION", ) - parser.add_option( + parser.add_argument( "-q", "--quiet", dest="quiet", @@ -82,7 +82,7 @@ def main(): help="True/False Quiet all SU2 output (optimizer output only)", metavar="QUIET", ) - parser.add_option( + parser.add_argument( "-z", "--zones", dest="nzones", @@ -91,7 +91,7 @@ def main(): metavar="ZONES", ) - (options, args) = parser.parse_args() + options = parser.parse_args() # process inputs options.partitions = int(options.partitions) diff --git a/TestCases/TestCase.py b/TestCases/TestCase.py index 006271bea714..651193244522 100644 --- a/TestCases/TestCase.py +++ b/TestCases/TestCase.py @@ -232,9 +232,14 @@ def run_test(self, with_tsan=False, with_asan=False, with_tapetests=False): for j in range(len(data)): sim_vals.append( float(data[j]) ) delta_vals.append( abs(float(data[j])-self.test_vals[j]) ) - if delta_vals[j] > self.tol: - exceed_tol = True - passed = False + if isinstance(self.tol, list): + if delta_vals[j] > self.tol[j]: + exceed_tol = True + passed = False + else: + if delta_vals[j] > self.tol: + exceed_tol = True + passed = False break else: iter_missing = True 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 8b2887947f5d..9a1f6b7d1e71 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 , 292.459 , 0.001 - 1 , -8318.5 , 0.001 - 2 , -16158.4 , 0.001 - 3 , -21277.2 , 0.001 - 4 , -23366.9 , 0.001 - 5 , -22727.6 , 0.001 - 6 , -19872.3 , 0.001 - 7 , -15278.1 , 0.001 - 8 , -9283.99 , 0.001 - 9 , -2179.87 , 0.001 - 10 , 5520.63 , 0.001 - 11 , 12726.0 , 0.001 - 12 , 17538.0 , 0.001 - 13 , 17441.1 , 0.001 - 14 , 10335.6 , 0.001 - 15 , -2686.37 , 0.001 - 16 , -10522.5 , 0.001 - 17 , 24712.2 , 0.001 - 18 , 166438.0 , 0.001 - 19 , -15618.6 , 0.001 - 20 , -14178.7 , 0.001 - 21 , -12765.5 , 0.001 - 22 , -12007.2 , 0.001 - 23 , -13597.5 , 0.001 - 24 , -19002.9 , 0.001 - 25 , -28729.6 , 0.001 - 26 , -41946.6 , 0.001 - 27 , -56289.3 , 0.001 - 28 , -67832.1 , 0.001 - 29 , -71484.0 , 0.001 - 30 , -62334.5 , 0.001 - 31 , -38478.2 , 0.001 - 32 , -4757.34 , 0.001 - 33 , 26448.5 , 0.001 - 34 , 45049.5 , 0.001 - 35 , 60960.9 , 0.001 - 36 , 83515.9 , 0.001 - 37 , 8837.4 , 0.001 + 0 , 17852.4 , 0.001 + 1 , 17762.2 , 0.001 + 2 , 13023.3 , 0.001 + 3 , 7235.23 , 0.001 + 4 , 2025.24 , 0.001 + 5 , -2173.83 , 0.001 + 6 , -5516.67 , 0.001 + 7 , -8317.99 , 0.001 + 8 , -10814.3 , 0.001 + 9 , -13092.8 , 0.001 + 10 , -15126.6 , 0.001 + 11 , -16823.4 , 0.001 + 12 , -17994.0 , 0.001 + 13 , -18196.9 , 0.001 + 14 , -16453.7 , 0.001 + 15 , -10589.4 , 0.001 + 16 , 4413.36 , 0.001 + 17 , 30522.9 , 0.001 + 18 , 5834.86 , 0.001 + 19 , -18131.9 , 0.001 + 20 , -21995.1 , 0.001 + 21 , -20862.7 , 0.001 + 22 , -18622.4 , 0.001 + 23 , -18164.8 , 0.001 + 24 , -20842.9 , 0.001 + 25 , -26432.9 , 0.001 + 26 , -33388.6 , 0.001 + 27 , -39214.0 , 0.001 + 28 , -40910.6 , 0.001 + 29 , -35624.7 , 0.001 + 30 , -21761.1 , 0.001 + 31 , -718.652 , 0.001 + 32 , 21422.9 , 0.001 + 33 , 34942.8 , 0.001 + 34 , 34300.9 , 0.001 + 35 , 28342.4 , 0.001 + 36 , 23237.9 , 0.001 + 37 , -20230.5 , 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 1a899cb06680..366ba74b7047 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.24008251 , -117.3444057 , 0.2742430499 , -1.56293638 , 0.0 , -1.568547024 , 0.0 , 0.0 , 1.189018284 , 0.0 - 1 , 0.4064005433 , -189.77779 , 0.4586830911 , -2.391641926 , 0.0 , -2.401078899 , 0.0 , 0.0 , 1.030793484 , 0.0 - 2 , 0.5421052294 , -249.5397676 , 0.6095878335 , -3.086770277 , 0.0 , -3.099333798 , 0.0 , 0.0 , 0.6218682473 , 0.0 + 0 , 0.1875371398 , -46.4529905 , 0.2229292755 , -1.619952826 , 0.0 , -1.624430497 , 0.0 , 0.0 , 0.9817393925 , 0.0 + 1 , 0.2883063943 , -65.16223458 , 0.3360834125 , -2.186444684 , 0.0 , -2.193255991 , 0.0 , 0.0 , 0.9308579056 , 0.0 + 2 , 0.4016718294 , -81.51255705 , 0.4583979297 , -2.595338639 , 0.0 , -2.604720916 , 0.0 , 0.0 , 0.6566891255 , 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 eca2a7ba1835..c861e4fbd810 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.00765473 , 0.0001 - 1 , 0.00497838 , 0.0001 - 2 , 0.0024697 , 0.0001 - 3 , 0.00090216 , 0.0001 + 0 , 0.00763648 , 0.0001 + 1 , 0.00504898 , 0.0001 + 2 , 0.00249639 , 0.0001 + 3 , 0.000890798 , 0.0001 diff --git a/TestCases/disc_adj_fsi/dyn_fsi/grad_dv.opt.ref b/TestCases/disc_adj_fsi/dyn_fsi/grad_dv.opt.ref index 60e4d2cf956e..aeefa8f67249 100644 --- a/TestCases/disc_adj_fsi/dyn_fsi/grad_dv.opt.ref +++ b/TestCases/disc_adj_fsi/dyn_fsi/grad_dv.opt.ref @@ -1,9 +1,9 @@ INDEX GRAD -0 -4.570880257851463e-04 -1 -2.401474161436175e-04 -2 -9.134742016285272e-05 -3 -1.628103644960537e-05 -4 -1.741046823504659e-05 -5 -9.462481396563234e-05 -6 -2.452469693841206e-04 -7 -4.635498187330369e-04 +0 -4.570880237875418e-04 +1 -2.401474145411196e-04 +2 -9.134741927897237e-05 +3 -1.628103641919142e-05 +4 -1.741046901352254e-05 +5 -9.462481564764888e-05 +6 -2.452469723327466e-04 +7 -4.635498231799566e-04 diff --git a/TestCases/euler/channel/inv_channel_RK.cfg b/TestCases/euler/channel/inv_channel_RK.cfg index a719b413d731..bf374054e770 100644 --- a/TestCases/euler/channel/inv_channel_RK.cfg +++ b/TestCases/euler/channel/inv_channel_RK.cfg @@ -44,24 +44,24 @@ MARKER_MONITORING= ( upper_wall, lower_wall ) % ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% % NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES -CFL_NUMBER= 2.5 +CFL_NUMBER= 1.0 CFL_ADAPT= NO CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) ITER= 110 LINEAR_SOLVER= BCGSTAB -LINEAR_SOLVER_ERROR= 1E-6 -LINEAR_SOLVER_ITER= 5 +LINEAR_SOLVER_ERROR= 1E-1 +LINEAR_SOLVER_ITER= 10 % -------------------------- MULTIGRID PARAMETERS -----------------------------% % MGLEVEL= 3 MGCYCLE= W_CYCLE -MG_PRE_SMOOTH= ( 1, 2, 3, 3 ) -MG_POST_SMOOTH= ( 0, 0, 0, 0 ) -MG_CORRECTION_SMOOTH= ( 0, 0, 0, 0 ) -MG_DAMP_RESTRICTION= 0.9 -MG_DAMP_PROLONGATION= 0.9 +MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) +MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_CORRECTION_SMOOTH= ( 4, 4, 4, 4 ) +MG_DAMP_RESTRICTION= 0.5 +MG_DAMP_PROLONGATION= 0.5 % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % diff --git a/TestCases/euler/ramp/inv_ramp_msw.cfg b/TestCases/euler/ramp/inv_ramp_msw.cfg new file mode 100644 index 000000000000..45c0c769a22e --- /dev/null +++ b/TestCases/euler/ramp/inv_ramp_msw.cfg @@ -0,0 +1,77 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Supersonic flow over a ramp in a channel (regression) % +% Author: Thomas D. Economon, Amit Sachdeva % +% Institution: Stanford University % +% Date: 2023.04.08 % +% File Version 8.4.0 "Harrier" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +SOLVER= EULER +MATH_PROBLEM= DIRECT +RESTART_SOL= NO + +% ----------- COMPRESSIBLE AND INCOMPRESSIBLE FREE-STREAM DEFINITION ----------% +% +MACH_NUMBER= 2.0 +AOA= 0.0 +SIDESLIP_ANGLE= 0.0 +FREESTREAM_PRESSURE= 100000.0 +FREESTREAM_TEMPERATURE= 300.0 + +% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% +% +REF_ORIGIN_MOMENT_X = 0.25 +REF_ORIGIN_MOMENT_Y = 0.00 +REF_ORIGIN_MOMENT_Z = 0.00 +REF_LENGTH= 1.0 +REF_AREA= 1.0 + +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +MARKER_EULER= ( upper, lower ) +MARKER_SUPERSONIC_INLET= ( inlet, 300.0, 100000.0, 695.4290761824674, 0.0, 0.0 ) +MARKER_OUTLET= ( outlet, 10000.0 ) +MARKER_PLOTTING= ( lower ) +MARKER_MONITORING= ( upper, lower ) + +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +NUM_METHOD_GRAD= GREEN_GAUSS +CFL_NUMBER= 4.0 +CFL_ADAPT= YES +CFL_ADAPT_PARAM= ( 0.8, 1.2, 1.0, 250.0, 0.8 ) +ITER= 200 +LINEAR_SOLVER= FGMRES +LINEAR_SOLVER_PREC= ILU +LINEAR_SOLVER_ERROR= 1e-6 +LINEAR_SOLVER_ITER= 3 +NEWTON_KRYLOV= YES +NEWTON_KRYLOV_IPARAM= (0, 0, 1) % n0, np, ft +NEWTON_KRYLOV_DPARAM= (0, 1e-20, -2.0, 1e-5, -1.0) % r0, tp, rf, e, nkr +MGLEVEL= 0 + +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +CONV_NUM_METHOD_FLOW= MSW +MUSCL_FLOW= YES +SLOPE_LIMITER_FLOW= NISHIKAWA_R5 +VENKAT_LIMITER_COEFF= 0.5 +TIME_DISCRE_FLOW= EULER_IMPLICIT + +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +CONV_RESIDUAL_MINVAL= -13 +CONV_STARTITER= 10 + +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +MESH_FILENAME= ramp_unst +VOLUME_FILENAME= flow +OUTPUT_WRT_FREQ= 250 +SCREEN_OUTPUT= (INNER_ITER, RMS_DENSITY, RMS_ENERGY, LIFT, DRAG) + diff --git a/TestCases/euler/turbofan_MFR_coupling/MFR_coupling.cfg b/TestCases/euler/turbofan_MFR_coupling/MFR_coupling.cfg new file mode 100644 index 000000000000..c580bf01003f --- /dev/null +++ b/TestCases/euler/turbofan_MFR_coupling/MFR_coupling.cfg @@ -0,0 +1,106 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Turbofan with outlets-to-inlet mass-flow rate coupling___ % +% Author: Angelo Passariello and Mauro Minervino_____________________________ % +% Institution: Italian Aerospace Research Centre (CIRA)______________________ % +% Date: 16/03/2026 % +% File Version 8.4.0 "Harrier" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +SOLVER= EULER +MATH_PROBLEM= DIRECT +RESTART_SOL= NO +% +% ------------------------------- SOLVER CONTROL ------------------------------% +% +ITER= 10000 +CONV_FIELD= RMS_DENSITY +CONV_RESIDUAL_MINVAL= -15 +CONV_STARTITER= 10 +% +% -------------------- COMPRESSIBLE FREE-STREAM DEFINITION --------------------% +% +MACH_NUMBER= 0.16719966920674 +AOA= 0.0 +INIT_OPTION= TD_CONDITIONS +FREESTREAM_OPTION= DENSITY_FS +FREESTREAM_PRESSURE= 101325.0 +FREESTREAM_TEMPERATURE= 288.15 +REYNOLDS_NUMBER= 3.8951057985067e+6 +FREESTREAM_DENSITY= 1.225 +FREESTREAM_VELOCITY= ( 56.897550640000, 0.0, 0.0 ) +FREESTREAM_VISCOSITY= 1.78938027807758E-05 +REF_DIMENSIONALIZATION= DIMENSIONAL +% +% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% +% +% Reference origin for moment computation (m or in) +REF_ORIGIN_MOMENT_X = 0.00 +REF_ORIGIN_MOMENT_Y = 0.00 +REF_ORIGIN_MOMENT_Z = 0.00 +REF_LENGTH= 1.0 +REF_AREA= 1.0 +SEMI_SPAN= 1.0 +% +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +MARKER_EULER= ( INTAKE, NOZZLE_TE, PLUG_TE, PLUG, NACELLE_TE, SPINNER, LIP, NOZZLE_INNER, NOZZLE, NACELLE_INNER, COWL ) +MARKER_FAR= ( FF ) +ENGINE_INFLOW_TYPE= FAN_FACE_MDOT +ENGINE_EXHAUST_TO_INLET= YES +DAMP_ENGINE_INFLOW= 0.01 +MARKER_ENGINE_INFLOW= ( FAN_IN, 140.0 ) +MARKER_ENGINE_EXHAUST= ( FAN_OUT, 289.761088684333, 103321.726628227, CORE_OUT, 289.761088684333, 103321.726628227 ) +% +% ------------------------ SURFACES IDENTIFICATION ----------------------------% +% +MARKER_PLOTTING = ( NOZZLE_TE, PLUG_TE, PLUG, NACELLE_TE, SPINNER, LIP, INTAKE, NOZZLE_INNER, NOZZLE, NACELLE_INNER, COWL, FAN_IN, FAN_OUT, CORE_OUT ) +MARKER_MONITORING = ( NACELLE_TE, LIP, COWL ) +MARKER_ANALYZE = ( FAN_IN, FAN_OUT, CORE_OUT ) +MARKER_ANALYZE_AVERAGE = MASSFLUX +% +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +NUM_METHOD_GRAD= GREEN_GAUSS +NUM_METHOD_GRAD_RECON = GREEN_GAUSS +CFL_NUMBER= 1.0 +% +% ----------- SLOPE LIMITER AND DISSIPATION SENSOR DEFINITION -----------------% +% +MUSCL_FLOW= NO +MUSCL_TURB= YES +% +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +LINEAR_SOLVER= FGMRES +LINEAR_SOLVER_ITER= 5 +% +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +CONV_NUM_METHOD_FLOW= JST +LOW_MACH_PREC= YES +ENTROPY_FIX_COEFF= 0.001 +% +% ------------------------- SCREEN/HISTORY VOLUME OUTPUT --------------------------% +% +SCREEN_OUTPUT= (INNER_ITER, RMS_DENSITY, LIFT, DRAG, SURFACE_MASSFLOW) +HISTORY_OUTPUT= (ITER, AERO_COEFF, RMS_RES, AOA, NONPHYSICAL_POINTS, SURFACE_MASSFLOW, SURFACE_STATIC_PRESSURE) +VOLUME_OUTPUT= (COORDINATES, SOLUTION, PRIMITIVE) +OUTPUT_WRT_FREQ= 1000 +WRT_FORCES_BREAKDOWN= YES +% +% ------------------------- INPUT/OUTPUT FILE INFORMATION --------------------------% +% +SURFACE_FILENAME= surface_flow +VOLUME_FILENAME= flow +RESTART_FILENAME= restart_flow.dat +MESH_FILENAME= engine-alone.cgns +MESH_FORMAT= CGNS +TABULAR_FORMAT= TECPLOT +OUTPUT_FILES= (RESTART, TECPLOT, SURFACE_TECPLOT) +READ_BINARY_RESTART= YES +REORIENT_ELEMENTS= YES diff --git a/TestCases/fea_fsi/ThermalBeam_3d/configBeamNonlinear_3d.cfg b/TestCases/fea_fsi/ThermalBeam_3d/configBeamNonlinear_3d.cfg new file mode 100644 index 000000000000..d8978b0a2b10 --- /dev/null +++ b/TestCases/fea_fsi/ThermalBeam_3d/configBeamNonlinear_3d.cfg @@ -0,0 +1,54 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% SU2 configuration file % +% Case description: 3D beam with thermal expansion % +% File Version 8.4.0 "Harrier" % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +SOLVER= ELASTICITY +GEOMETRIC_CONDITIONS= LARGE_DEFORMATIONS +MATERIAL_MODEL= NEO_HOOKEAN +MESH_FILENAME= ../StatBeam_3d/meshBeam_3d.su2 +ELASTICITY_MODULUS= 3E7 +POISSON_RATIO= 0.3 +MATERIAL_THERMAL_EXPANSION_COEFF= 2e-5 +MATERIAL_REFERENCE_TEMPERATURE= 288.15 +MATERIAL_DENSITY= 7854 +MARKER_CLAMPED= ( left, right ) +MARKER_PRESSURE= ( lower, 0, symleft, 0, symright, 0 ) +MARKER_LOAD= ( upper, 1, 1000, 0, -1, 0 ) +LINEAR_SOLVER= FGCRODR +LINEAR_SOLVER_PREC= ILU +LINEAR_SOLVER_ERROR= 1E-4 +LINEAR_SOLVER_ITER= 1000 +LINEAR_SOLVER_RESTART_FREQUENCY= 50 +LINEAR_SOLVER_RESTART_DEFLATION= 10 +MESH_FORMAT= SU2 +TABULAR_FORMAT= CSV +CONV_FILENAME= history_beam +VOLUME_FILENAME= beam +RESTART_FILENAME= restart_beam +SOLUTION_FILENAME= restart_beam + +CONV_FIELD= REL_RMS_RTOL, REL_RMS_TEMPERATURE +CONV_STARTITER= 0 +CONV_RESIDUAL_MINVAL= -5 +INNER_ITER= 10 + +% Coupling with heat solver. +WEAKLY_COUPLED_HEAT_EQUATION= YES +FREESTREAM_TEMPERATURE= 300 +SPECIFIC_HEAT_CP= 460 +THERMAL_CONDUCTIVITY_CONSTANT= 45 + +% Copy markers to allow specifying boundary conditions for both solvers on the +% same markers. +MARKER_CREATE_COPY= ( left, left_heat, right, right_heat ) +MARKER_ISOTHERMAL= ( left_heat, 400, right_heat, 300 ) + +NUM_METHOD_GRAD= GREEN_GAUSS +TIME_DISCRE_HEAT= EULER_IMPLICIT +CFL_NUMBER= 1e8 + +MARKER_MONITORING= ( left_heat ) +SCREEN_OUTPUT= INNER_ITER, RMS_RES, LINSOL, VMS, TOTAL_HEATFLUX + diff --git a/TestCases/fea_fsi/ThermalBeam_3d/configBeamNonlinear_3d_ad.cfg b/TestCases/fea_fsi/ThermalBeam_3d/configBeamNonlinear_3d_ad.cfg new file mode 100644 index 000000000000..740729bd8405 --- /dev/null +++ b/TestCases/fea_fsi/ThermalBeam_3d/configBeamNonlinear_3d_ad.cfg @@ -0,0 +1,55 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% SU2 configuration file % +% Case description: 3D beam with thermal expansion % +% File Version 8.4.0 "Harrier" % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +SOLVER= ELASTICITY +GEOMETRIC_CONDITIONS= LARGE_DEFORMATIONS +MATERIAL_MODEL= NEO_HOOKEAN +MESH_FILENAME= ../StatBeam_3d/meshBeam_3d.su2 +ELASTICITY_MODULUS= 3E7 +POISSON_RATIO= 0.3 +MATERIAL_THERMAL_EXPANSION_COEFF= 2e-5 +MATERIAL_REFERENCE_TEMPERATURE= 288.15 +MATERIAL_DENSITY= 7854 +MARKER_CLAMPED= ( left, right ) +MARKER_PRESSURE= ( lower, 0, symleft, 0, symright, 0 ) +MARKER_LOAD= ( upper, 1, 1000, 0, -1, 0 ) +DISCADJ_LIN_SOLVER= FGCRODR +DISCADJ_LIN_PREC= ILU +LINEAR_SOLVER_ERROR= 1E-4 +LINEAR_SOLVER_ITER= 1000 +LINEAR_SOLVER_RESTART_FREQUENCY= 50 +LINEAR_SOLVER_RESTART_DEFLATION= 10 +MESH_FORMAT= SU2 +TABULAR_FORMAT= CSV +CONV_FILENAME= history_beam +VOLUME_FILENAME= beam +RESTART_FILENAME= restart_beam +SOLUTION_FILENAME= restart_beam + +CONV_FIELD= REL_ADJOINT_DISP_X, REL_RMS_ADJ_TEMPERATURE +CONV_STARTITER= 0 +CONV_RESIDUAL_MINVAL= -5 +INNER_ITER= 15 + +% Coupling with heat solver. +WEAKLY_COUPLED_HEAT_EQUATION= YES +FREESTREAM_TEMPERATURE= 300 +SPECIFIC_HEAT_CP= 460 +THERMAL_CONDUCTIVITY_CONSTANT= 45 + +% Copy markers to allow specifying boundary conditions for both solvers on the +% same markers. +MARKER_CREATE_COPY= ( left, left_heat, right, right_heat ) +MARKER_ISOTHERMAL= ( left_heat, 400, right_heat, 300 ) + +NUM_METHOD_GRAD= GREEN_GAUSS +TIME_DISCRE_HEAT= EULER_IMPLICIT +CFL_NUMBER= 1e8 + +MARKER_MONITORING= ( left_heat ) +SCREEN_OUTPUT= INNER_ITER, RMS_RES, LINSOL, SENSITIVITY + +OBJECTIVE_FUNCTION = TOTAL_HEATFLUX diff --git a/TestCases/fea_fsi/ThermalBeam_3d/configBeam_3d.cfg b/TestCases/fea_fsi/ThermalBeam_3d/configBeam_3d.cfg index aad8f94ae7f5..c2f263d2108c 100644 --- a/TestCases/fea_fsi/ThermalBeam_3d/configBeam_3d.cfg +++ b/TestCases/fea_fsi/ThermalBeam_3d/configBeam_3d.cfg @@ -5,22 +5,21 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SOLVER= ELASTICITY -MATH_PROBLEM= DIRECT GEOMETRIC_CONDITIONS= SMALL_DEFORMATIONS MATERIAL_MODEL= LINEAR_ELASTIC -MESH_FILENAME= meshBeam_3d.su2 -ELASTICITY_MODULUS=3E7 -POISSON_RATIO=0.3 +MESH_FILENAME= ../StatBeam_3d/meshBeam_3d.su2 +ELASTICITY_MODULUS= 3E7 +POISSON_RATIO= 0.3 MATERIAL_THERMAL_EXPANSION_COEFF= 2e-5 MATERIAL_REFERENCE_TEMPERATURE= 288.15 -MATERIAL_DENSITY=7854 +MATERIAL_DENSITY= 7854 MARKER_CLAMPED= ( left, right ) MARKER_PRESSURE= ( lower, 0, symleft, 0, symright, 0 ) MARKER_LOAD= ( upper, 1, 1000, 0, -1, 0 ) LINEAR_SOLVER= CONJUGATE_GRADIENT LINEAR_SOLVER_PREC= ILU -LINEAR_SOLVER_ERROR= 1E-8 -LINEAR_SOLVER_ITER= 1000 +LINEAR_SOLVER_ERROR= 1E-4 +LINEAR_SOLVER_ITER= 500 MESH_FORMAT= SU2 TABULAR_FORMAT= CSV CONV_FILENAME= history_beam @@ -28,15 +27,21 @@ VOLUME_FILENAME= beam RESTART_FILENAME= restart_beam SOLUTION_FILENAME= restart_beam OUTPUT_WRT_FREQ= 1 -INNER_ITER=1 + +CONV_FIELD= REL_RMS_DISP_X, REL_RMS_DISP_Y, REL_RMS_DISP_Z, REL_RMS_TEMPERATURE +CONV_STARTITER= 0 +CONV_RESIDUAL_MINVAL= -4 +INNER_ITER= 10 % Coupling with heat solver. WEAKLY_COUPLED_HEAT_EQUATION= YES FREESTREAM_TEMPERATURE= 300 SPECIFIC_HEAT_CP= 460 THERMAL_CONDUCTIVITY_CONSTANT= 45 -% NOTE: These markers a duplicates of "left" and "right" to allow specifying -% boundary conditions for both solvers. This is work in progress. + +% Copy markers to allow specifying boundary conditions for both solvers on the +% same markers. +MARKER_CREATE_COPY= ( left, left_heat, right, right_heat ) MARKER_ISOTHERMAL= ( left_heat, 400, right_heat, 300 ) NUM_METHOD_GRAD= GREEN_GAUSS diff --git a/TestCases/fea_topology/grad_ref_node.dat.ref b/TestCases/fea_topology/grad_ref_node.dat.ref index 15afff813c19..6f3a4d4a6854 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.57599e-10 +-1.57598e-10 -8.68931e-12 -4.26927e-13 0 diff --git a/TestCases/flamelet/07_laminar_premixed_h2_flame_cfd/laminar_premixed_h2_flame_cfd.cfg b/TestCases/flamelet/07_laminar_premixed_h2_flame_cfd/laminar_premixed_h2_flame_cfd.cfg index 93328224dc0b..974505d809bf 100644 --- a/TestCases/flamelet/07_laminar_premixed_h2_flame_cfd/laminar_premixed_h2_flame_cfd.cfg +++ b/TestCases/flamelet/07_laminar_premixed_h2_flame_cfd/laminar_premixed_h2_flame_cfd.cfg @@ -31,7 +31,7 @@ CONDUCTIVITY_MODEL= FLAMELET DIFFUSIVITY_MODEL= FLAMELET KIND_SCALAR_MODEL= FLAMELET INTERPOLATION_METHOD= MLP -FILENAMES_INTERPOLATOR= (MLP_TD.mlp, MLP_PD.mlp, MLP_PPV.mlp, MLP_null.mlp) +FILENAMES_INTERPOLATOR= (MLP_TD.mlp, MLP_PD.mlp, MLP_PPV.mlp) PREFERENTIAL_DIFFUSION= YES % -------------------- SCALAR TRANSPORT ---------------------------------------% diff --git a/TestCases/grad_smooth/oneram6/of_hess.dat.ref b/TestCases/grad_smooth/oneram6/of_hess.dat.ref index 02ba06109cbc..682bd0f2a1e0 100644 --- a/TestCases/grad_smooth/oneram6/of_hess.dat.ref +++ b/TestCases/grad_smooth/oneram6/of_hess.dat.ref @@ -15,7 +15,7 @@ -0.006467631847, 0.01474899148, 0.0307974965, 0.03133667011, 0.02135868557, 0.009195956631, 0.0005679148628, -0.002979438869, -0.002888704019, -0.001484322831, -0.0003805028717, -0.009749017792, 0.01377275078, 0.03561910891, 0.04068759244, 0.0320229057, 0.01832378646, 0.006777110935, 0.0003821410305, -0.001496252596, -0.001086366199, -0.0003216351645, -0.01012802391, 0.007372771691, 0.02569386609, 0.03132552458, 0.02570124608, 0.01539133323, 0.006215280913, 0.0008558831252, -0.0009273533675, -0.0007809529487, -0.0002425068128, -0.007928394398, 0.002070266239, 0.01378665724, 0.01798985944, 0.01513337149, 0.009153182312, 0.003674859753, 0.0004413598218, -0.0006244703773, -0.0005081859495, -0.0001571494848, -0.00493051489, -0.0002396568334, 0.005968682259, 0.008479468465, 0.007312783546, 0.004440065636, 0.001738824884, 0.0001397731457, -0.0003689708236, -0.0002823875978, -8.620744834e-05, -0.002478600059, -0.0006748885187, 0.002066013325, 0.00329433432, 0.002922916564, 0.001777630095, 0.000670671817, 1.535797359e-05, -0.0001827231234, -0.0001317267916, -3.964414261e-05, -0.0009841254633, -0.0004506363067, 0.0005147597333, 0.0009923057147, 0.0009141133046, 0.0005556425743, 0.0001975206881, -1.383923076e-05, -7.288723647e-05, -4.94869802e-05, -1.465635953e-05, -0.0002831321015, -0.0001786709401, 6.58272751e-05, 0.0002003390218, 0.0001961592109, 0.0001186688731, 3.753024261e-05, -9.935156589e-06, -2.138473898e-05, -1.360348147e-05, -3.950343144e-06, -4.554004401e-05, -3.672960965e-05, -3.041622561e-06, 1.799427418e-05, 2.027636727e-05, 1.203767729e-05, 2.649508268e-06, -2.70794393e-06, -3.56862514e-06, -2.10310099e-06, -5.947698304e-07, -0.005601649597, 0.003663315053, 0.008855155937, 0.008270418905, 0.005211846044, 0.002051209138, -0.0001730054338, -0.001205865676, -0.001233422859, -0.0007264792759, -0.0002174226404, -0.007611210873, 0.003301523038, 0.01118961161, 0.01201887408, 0.008994275876, 0.005067326541, 0.001833086624, -9.887411615e-05, -0.0007523705682, -0.0005808730526, -0.0001951220177, -0.007441046689, 0.001266593828, 0.008546193153, 0.009942656219, 0.007784066575, 0.004587745773, 0.001826453307, 0.0001135955779, -0.0005216994588, -0.0004414338999, -0.0001526936251, -0.00566661019, -0.0002874917326, 0.004841980873, 0.006139790065, 0.004941019791, 0.002931034371, 0.001147951918, 3.99276224e-05, -0.0003614638394, -0.0002968331893, -0.0001015819715, -0.003509714631, -0.0007811220973, 0.002197881102, 0.003108937626, 0.002572038857, 0.001525852968, 0.0005747115186, -1.373152539e-05, -0.000217106601, -0.0001698282856, -5.711344335e-05, -0.001781565969, -0.0006509595582, 0.0007793958023, 0.001287368927, 0.001099822422, 0.0006508662134, 0.0002316669047, -2.598766996e-05, -0.0001095788854, -8.151575035e-05, -2.690163744e-05, -0.0007189181431, -0.0003579820769, 0.0001868971594, 0.0004081475535, 0.000364234654, 0.0002142863145, 6.953286088e-05, -1.862504208e-05, -4.465908933e-05, -3.149481547e-05, -1.01801397e-05, -0.0002107020059, -0.0001331894618, 1.56490951e-05, 8.471984511e-05, 8.140117857e-05, 4.72137792e-05, 1.254545578e-05, -8.249903837e-06, -1.340571874e-05, -8.898200035e-06, -2.806655401e-06, -3.452670376e-05, -2.680888144e-05, -4.675239333e-06, 7.211143304e-06, 8.385674347e-06, 4.644500619e-06, 4.785389695e-07, -1.936902476e-06, -2.29051854e-06, -1.412826127e-06, -4.319034967e-07 -0.00418760099, 0.003164939048, 0.01686793413, 0.02679089038, 0.02741825725, 0.01985460031, 0.009261368916, 0.0008577314648, -0.002885697698, -0.002698422059, -0.001034333935, -0.005893646974, 0.001358321342, 0.01786175342, 0.0320229057, 0.03605854345, 0.02956944193, 0.01763318488, 0.006508745883, 1.535739201e-05, -0.001671934291, -0.0008468199082, -0.005842296384, -0.001372995249, 0.01139007538, 0.0233103281, 0.02769196454, 0.02359158545, 0.01466512077, 0.00586859374, 0.0004649327871, -0.001142965089, -0.0006355786285, -0.004443360253, -0.002568527442, 0.004976334012, 0.01255500631, 0.01578204326, 0.01379058138, 0.008663801363, 0.003434228438, 0.0001824184137, -0.000766154093, -0.0004152490589, -0.002720813517, -0.002223407514, 0.001469849657, 0.005458152309, 0.007364170805, 0.006606937245, 0.004173466333, 0.001606282661, 1.302051153e-06, -0.0004428899124, -0.0002300480739, -0.001357785599, -0.00135052352, 0.0001523202354, 0.001901908621, 0.002824336773, 0.002613207731, 0.001656887003, 0.0006101845972, -4.613409803e-05, -0.0002145347863, -0.0001068251748, -0.0005374507601, -0.0006149211624, -0.0001325918779, 0.000480019629, 0.0008346787878, 0.0008052744253, 0.0005117203452, 0.0001753724531, -3.56282835e-05, -8.36777944e-05, -3.988970627e-05, -0.0001544528154, -0.0001985035547, -9.03814922e-05, 6.387161394e-05, 0.0001626042288, 0.0001684732315, 0.0001070018665, 3.161302023e-05, -1.548965707e-05, -2.394938367e-05, -1.087091282e-05, -2.482684585e-05, -3.550562621e-05, -2.321071949e-05, -2.098772021e-06, 1.315056181e-05, 1.639844586e-05, 1.030443163e-05, 1.767206972e-06, -3.477078918e-06, -3.879505205e-06, -1.658464571e-06, -0.002332386684, 0.0001731063128, 0.004156773864, 0.006700696045, 0.006975098395, 0.005319517708, 0.002597905565, -5.337653038e-05, -0.001581482699, -0.001597395865, -0.0006987381646, -0.003217682667, -0.0004937642035, 0.004858098239, 0.008991340113, 0.01035025827, 0.008980809821, 0.005801567361, 0.002223062703, -0.0003254417609, -0.001118357965, -0.0006066660815, -0.003175450391, -0.001311369598, 0.003216991658, 0.007015501908, 0.008527140965, 0.007646060766, 0.005113396083, 0.002135316235, -5.664233672e-05, -0.0008146858677, -0.0004693986212, -0.002443739799, -0.001535685769, 0.001405278873, 0.004041864154, 0.005209590155, 0.004766305172, 0.003193478799, 0.001302274629, -8.810153125e-05, -0.0005534997008, -0.000311742948, -0.001533684497, -0.001219118062, 0.0003620943734, 0.001874099921, 0.002603869995, 0.002434314603, 0.001625550092, 0.0006316182562, -9.413097892e-05, -0.0003222779581, -0.0001752139621, -0.0007904665151, -0.0007365990626, -3.314496397e-05, 0.0006861381042, 0.001061324463, 0.00102003623, 0.0006779220326, 0.0002458588143, -6.713443329e-05, -0.0001574809661, -8.252286937e-05, -0.0003242514253, -0.0003428550827, -9.66628515e-05, 0.0001753122948, 0.0003287895655, 0.0003295666681, 0.0002176299511, 7.045310021e-05, -3.524440465e-05, -6.204457248e-05, -3.124617503e-05, -9.66489852e-05, -0.0001143430224, -5.399518557e-05, 1.974863887e-05, 6.521110548e-05, 7.09006824e-05, 4.629322104e-05, 1.157616121e-05, -1.308835212e-05, -1.794621429e-05, -8.630616542e-06, -1.610454588e-05, -2.121832512e-05, -1.359809775e-05, -2.743865465e-06, 4.722924621e-06, 6.674976952e-06, 4.212310826e-06, 1.286530318e-07, -2.717102838e-06, -2.937567447e-06, -1.333576142e-06 -0.002130269292, -0.0009470248424, 0.006198968944, 0.01650667643, 0.0242776469, 0.02510692083, 0.01866511639, 0.008598949539, 3.066027671e-05, -0.003585882953, -0.002415614232, -0.002873002519, -0.002360072921, 0.005497126651, 0.01832378646, 0.02956944193, 0.03324963907, 0.02771776374, 0.01632591269, 0.005021183573, -0.00136192865, -0.001904990318, -0.002763511045, -0.00326365331, 0.002176842328, 0.01216954461, 0.02163728519, 0.02553859047, 0.02208188166, 0.01355252933, 0.004596807657, -0.0007380980325, -0.001422981608, -0.002058984672, -0.003004041845, -0.0002345506762, 0.005678043385, 0.01168083116, 0.01453075018, 0.01289175512, 0.007990537832, 0.002644759726, -0.0005765236419, -0.0009397935261, -0.001244150507, -0.002064054463, -0.0009529820605, 0.001939655982, 0.005087711266, 0.006762775544, 0.006166774863, 0.003839572126, 0.001202466122, -0.0003930505741, -0.0005271495476, -0.0006155379537, -0.001114242331, -0.0007749195492, 0.0004004800683, 0.001775710074, 0.002583203131, 0.00243322122, 0.0015187114, 0.0004377670186, -0.0002169140172, -0.0002477113511, -0.0002421627681, -0.0004695369247, -0.0004065268476, -3.024935204e-05, 0.0004486222037, 0.0007578387235, 0.0007464496678, 0.0004660052955, 0.0001165863637, -9.453997177e-05, -9.360915074e-05, -6.925851305e-05, -0.0001427748728, -0.0001439851029, -6.003664253e-05, 5.957467067e-05, 0.0001452298563, 0.0001546509558, 9.611782424e-05, 1.722891546e-05, -3.001319127e-05, -2.584398217e-05, -1.108514438e-05, -2.426182197e-05, -2.766914936e-05, -1.822466935e-05, -2.063701419e-06, 1.107754621e-05, 1.463543492e-05, 8.896110651e-06, -1.337865412e-07, -5.394843993e-06, -4.003366888e-06, -0.0008961637852, -0.0006318362772, 0.001265848706, 0.004065775474, 0.006615816591, 0.00772020146, 0.006549029486, 0.003285793928, -0.0005144192803, -0.002619112791, -0.001899826304, -0.001237307202, -0.001144112402, 0.001198131022, 0.00506698014, 0.008983044508, 0.01127134701, 0.01064330558, 0.007030351153, 0.002114940086, -0.001347897805, -0.001590974548, -0.001222654803, -0.001439427558, 0.0003233341816, 0.003555143319, 0.00699087439, 0.009153298412, 0.008891319035, 0.0060806853, 0.002065905007, -0.0008764269721, -0.001218031963, -0.000943828967, -0.001309683533, -0.0003284733114, 0.001723559563, 0.004003074319, 0.005503526376, 0.005443375014, 0.00372535344, 0.001211192105, -0.0006306497244, -0.0008097825114, -0.0005952893392, -0.000922588182, -0.0004887007143, 0.0005894353338, 0.001844725347, 0.002706044331, 0.002731195401, 0.001859718564, 0.0005543160343, -0.0003948358104, -0.0004562345055, -0.0003087129688, -0.0005193158905, -0.0003723620957, 9.625265565e-05, 0.0006720964148, 0.001085047454, 0.001125361861, 0.0007609981511, 0.0001989179733, -0.0002058654276, -0.0002153916015, -0.0001274946781, -0.0002297719152, -0.0001984490251, -3.887294326e-05, 0.0001712579124, 0.0003301061973, 0.0003576340951, 0.0002395963219, 4.923527571e-05, -8.627232957e-05, -8.178924288e-05, -3.826847211e-05, -7.352251721e-05, -7.298808994e-05, -3.539178282e-05, 1.938963243e-05, 6.377702276e-05, 7.55296883e-05, 4.97977011e-05, 4.870135848e-06, -2.660491312e-05, -2.26852285e-05, -6.421053274e-06, -1.314939389e-05, -1.467832248e-05, -1.027237718e-05, -2.604807932e-06, 4.263335781e-06, 6.899978488e-06, 4.341053853e-06, -1.025171358e-06, -4.675195282e-06, -3.528138143e-06 --0.0009194723854, -0.00151188807, 0.0006785118074, 0.006878870864, 0.01548300253, 0.02250961605, 0.02385746086, 0.01795751975, 0.007232852953, -0.002506096839, -0.00492027402, -0.001200449871, -0.002315962107, -0.0003127143132, 0.006777110935, 0.01763318488, 0.02771776374, 0.03167775197, 0.0266401318, 0.01446817599, 0.001660550464, -0.003684116049, -0.001127395713, -0.002499038125, -0.001607517431, 0.003428789439, 0.0119086742, 0.02037223604, 0.0243928221, 0.02127467655, 0.012084934, 0.001848892289, -0.002730733078, -0.0008254641523, -0.002020555424, -0.00197471335, 0.0006677780142, 0.005685548809, 0.01104205114, 0.0139288644, 0.01247441309, 0.007127675556, 0.0009298370812, -0.001829329973, -0.0004926986346, -0.001290382847, -0.001533427374, -0.000426009673, 0.002026914899, 0.004831855958, 0.006510409503, 0.005998181189, 0.003420986136, 0.0003126434026, -0.001042502943, -0.000241579101, -0.0006646142371, -0.0008864110522, -0.000522540032, 0.0004722857031, 0.001695451617, 0.002498205923, 0.002379926524, 0.001349188806, 5.170490287e-05, -0.0004970883464, -9.434934994e-05, -0.0002703361475, -0.0003917160444, -0.0003105960361, 6.614310016e-06, 0.0004313722813, 0.000736591389, 0.0007346404414, 0.000411324883, -1.726046648e-05, -0.0001905630072, -2.680669821e-05, -7.975468264e-05, -0.0001237967997, -0.0001176334718, -4.744790859e-05, 5.814707256e-05, 0.0001420488021, 0.0001534039817, 8.355448033e-05, -1.610533148e-05, -5.343149652e-05, -4.262872608e-06, -1.317446976e-05, -2.178325842e-05, -2.366395623e-05, -1.592339722e-05, -1.780757659e-06, 1.096995205e-05, 1.471970969e-05, 7.362398796e-06, -4.628824149e-06, -8.428700767e-06, -0.0003196345825, -0.0005491602195, -4.420644074e-05, 0.001677068774, 0.004627769947, 0.007988843742, 0.01000450135, 0.008714133733, 0.003623122184, -0.002590835523, -0.004398319472, -0.000439288785, -0.0008433726809, -0.0003316461397, 0.001836300625, 0.005808425866, 0.01064988607, 0.01416111641, 0.01368955308, 0.008141857626, 0.0002286407359, -0.003513205016, -0.0004326969064, -0.0009333805399, -0.0007233874422, 0.0008921528996, 0.004106633202, 0.008190616147, 0.01133153106, 0.01128068905, 0.007001657995, 0.0005751065378, -0.002657191594, -0.0003335522058, -0.0007858047181, -0.0008218277649, 5.996991719e-05, 0.002028620818, 0.004639058756, 0.006728549851, 0.00682914596, 0.004227124212, 0.0002140956921, -0.001774432295, -0.0002104144685, -0.0005279248986, -0.0006465234253, -0.0002655246717, 0.0007315096934, 0.002118491489, 0.003271774969, 0.003392173197, 0.002074949316, -6.185624458e-06, -0.001005734161, -0.0001092319184, -0.0002876395163, -0.0003893507636, -0.0002641123818, 0.0001534241879, 0.0007684123984, 0.001301011896, 0.001386844258, 0.0008341565713, -6.342482166e-05, -0.0004774478702, -4.516803105e-05, -0.0001240015452, -0.0001810210676, -0.0001560350856, -1.974927265e-05, 0.0001971196294, 0.0003944597625, 0.0004390147895, 0.0002574579703, -4.871563613e-05, -0.0001823611564, -1.357247914e-05, -3.876415008e-05, -6.037553359e-05, -6.08599144e-05, -3.058893676e-05, 2.384513571e-05, 7.6846757e-05, 9.312886239e-05, 5.207943827e-05, -2.151376195e-05, -5.095077691e-05, -2.278941453e-06, -6.777500225e-06, -1.121758959e-05, -1.274962751e-05, -9.583457423e-06, -2.325633557e-06, 5.516554517e-06, 8.804223533e-06, 4.267115521e-06, -4.928847632e-06, -8.005343201e-06 +-0.0009194723854, -0.00151188807, 0.0006785118074, 0.006878870864, 0.01548300253, 0.02250961605, 0.02385746086, 0.01795751975, 0.007232852953, -0.002506096839, -0.00492027402, -0.001200449871, -0.002315962107, -0.0003127143132, 0.006777110935, 0.01763318488, 0.02771776374, 0.03167775197, 0.0266401318, 0.01446817599, 0.001660550464, -0.003684116049, -0.001127395713, -0.002499038125, -0.001607517431, 0.003428789439, 0.0119086742, 0.02037223604, 0.0243928221, 0.02127467655, 0.012084934, 0.001848892289, -0.002730733078, -0.0008254641523, -0.002020555424, -0.00197471335, 0.0006677780142, 0.005685548809, 0.01104205114, 0.0139288644, 0.01247441309, 0.007127675556, 0.0009298370812, -0.001829329973, -0.0004926986346, -0.001290382847, -0.001533427374, -0.000426009673, 0.002026914899, 0.004831855958, 0.006510409503, 0.005998181189, 0.003420986136, 0.0003126434026, -0.001042502943, -0.000241579101, -0.0006646142371, -0.0008864110522, -0.000522540032, 0.0004722857031, 0.001695451617, 0.002498205923, 0.002379926524, 0.001349188806, 5.170490287e-05, -0.0004970883464, -9.434934994e-05, -0.0002703361475, -0.0003917160444, -0.0003105960361, 6.614310016e-06, 0.0004313722813, 0.000736591389, 0.0007346404414, 0.000411324883, -1.726046648e-05, -0.0001905630072, -2.680669821e-05, -7.975468264e-05, -0.0001237967997, -0.0001176334718, -4.744790859e-05, 5.814707256e-05, 0.0001420488021, 0.0001534039817, 8.355448033e-05, -1.610533148e-05, -5.343149652e-05, -4.262872608e-06, -1.317446976e-05, -2.178325842e-05, -2.366395623e-05, -1.592339722e-05, -1.780757659e-06, 1.096995205e-05, 1.471970969e-05, 7.362398796e-06, -4.628824149e-06, -8.428700767e-06, -0.0003196345825, -0.0005491602195, -4.420644074e-05, 0.001677068774, 0.004627769947, 0.007988843742, 0.01000450135, 0.008714133733, 0.003623122184, -0.002590835523, -0.004398319472, -0.000439288785, -0.000843372681, -0.0003316461397, 0.001836300625, 0.005808425866, 0.01064988607, 0.01416111641, 0.01368955308, 0.008141857626, 0.0002286407359, -0.003513205016, -0.0004326969064, -0.0009333805399, -0.0007233874422, 0.0008921528996, 0.004106633202, 0.008190616147, 0.01133153106, 0.01128068905, 0.007001657995, 0.0005751065378, -0.002657191594, -0.0003335522058, -0.0007858047181, -0.0008218277649, 5.996991719e-05, 0.002028620818, 0.004639058756, 0.006728549851, 0.00682914596, 0.004227124212, 0.0002140956921, -0.001774432295, -0.0002104144685, -0.0005279248986, -0.0006465234253, -0.0002655246717, 0.0007315096934, 0.002118491489, 0.003271774969, 0.003392173197, 0.002074949316, -6.185624458e-06, -0.001005734161, -0.0001092319184, -0.0002876395163, -0.0003893507636, -0.0002641123818, 0.0001534241879, 0.0007684123984, 0.001301011896, 0.001386844258, 0.0008341565713, -6.342482166e-05, -0.0004774478702, -4.516803105e-05, -0.0001240015452, -0.0001810210676, -0.0001560350856, -1.974927265e-05, 0.0001971196294, 0.0003944597625, 0.0004390147895, 0.0002574579703, -4.871563613e-05, -0.0001823611564, -1.357247914e-05, -3.876415008e-05, -6.037553359e-05, -6.08599144e-05, -3.058893676e-05, 2.384513571e-05, 7.6846757e-05, 9.312886239e-05, 5.207943827e-05, -2.151376195e-05, -5.095077691e-05, -2.278941453e-06, -6.777500225e-06, -1.121758959e-05, -1.274962751e-05, -9.583457423e-06, -2.325633557e-06, 5.516554517e-06, 8.804223533e-06, 4.267115521e-06, -4.928847632e-06, -8.005343201e-06 -0.000332406675, -0.0009751414679, -0.001011325471, 0.00108303197, 0.006354573024, 0.01414496246, 0.02155870137, 0.02414496474, 0.01788009288, 0.003158003625, -0.008088545279, -0.0004228284638, -0.001333515417, -0.00170531222, 0.0003821410305, 0.006508745883, 0.01632591269, 0.0266401318, 0.03193311942, 0.02660943827, 0.009891837894, -0.005394668765, -0.0003893208294, -0.001318292995, -0.002033083352, -0.0009423762749, 0.003425356039, 0.01107661426, 0.01965947857, 0.02470867841, 0.02136901927, 0.00848174129, -0.003901388198, -0.0002808430928, -0.001005284547, -0.001752118178, -0.001500740791, 0.0007914979483, 0.005308045005, 0.01072136847, 0.01423961239, 0.01262986959, 0.004891331195, -0.002684957159, -0.0001658160762, -0.0006179878797, -0.001163699492, -0.001259525423, -0.0003006089289, 0.001900889012, 0.004729031473, 0.006732582414, 0.006128348482, 0.002258750871, -0.001576070467, -8.063434211e-05, -0.000309902587, -0.0006156404184, -0.0007567105896, -0.0004435816409, 0.0004455091174, 0.001676016175, 0.002618783685, 0.002455503175, 0.0008422490177, -0.0007713025575, -3.127235825e-05, -0.0001233880456, -0.0002557888453, -0.0003430295368, -0.0002746454663, 6.839749098e-06, 0.0004328558328, 0.0007861406334, 0.0007668009792, 0.0002339538592, -0.0003031109467, -8.826644306e-06, -3.570742307e-05, -7.690879937e-05, -0.0001106079136, -0.0001062313091, -4.479602684e-05, 6.059049262e-05, 0.000156259558, 0.000162818494, 3.873178304e-05, -8.726800847e-05, -1.394138483e-06, -5.787555166e-06, -1.294200917e-05, -1.980976667e-05, -2.1685802e-05, -1.51250928e-05, -1.136466793e-06, 1.31506817e-05, 1.618315884e-05, 1.168733738e-06, -1.42006883e-05, -0.0001036313013, -0.0003153157545, -0.0004126006321, 0.0001205000102, 0.002006507005, 0.005711108611, 0.01056057453, 0.01391211912, 0.01148885884, 0.001127604191, -0.008005536767, -0.0001410328392, -0.0004524158732, -0.0006621241967, -9.435486086e-05, 0.00223251727, 0.007043195616, 0.0136999121, 0.01907968483, 0.01777234372, 0.006339332434, -0.005807751173, -0.0001378435203, -0.0004704185682, -0.0007938080293, -0.000543537641, 0.001133468381, 0.004920899052, 0.01041011122, 0.01511764382, 0.01454462819, 0.005616446238, -0.004289800734, -0.0001056624185, -0.0003788780062, -0.0007054335704, -0.000720048938, 0.0001525850414, 0.002405187769, 0.005845772812, 0.008932209965, 0.008755207352, 0.003245513982, -0.002904526167, -6.639894632e-05, -0.0002468996939, -0.0004896878735, -0.0005968206007, -0.0002440047602, 0.000861909237, 0.002654252444, 0.004332501487, 0.004327249968, 0.001488532326, -0.001673919072, -3.437113185e-05, -0.0001314852752, -0.0002726636864, -0.0003679897768, -0.0002641965162, 0.0001839265272, 0.0009629686583, 0.001725426381, 0.001763264689, 0.0005444704303, -0.0008066439465, -1.417601938e-05, -5.559678902e-05, -0.0001195497072, -0.0001734005669, -0.0001588999505, -1.81533723e-05, 0.0002508998385, 0.0005282837273, 0.0005583014377, 0.0001437108265, -0.0003127703327, -4.247982583e-06, -1.706808637e-05, -3.794401822e-05, -5.838467352e-05, -6.227748151e-05, -3.268450615e-05, 3.328946692e-05, 0.0001062333226, 0.0001194778658, 1.983134952e-05, -8.892718743e-05, -7.109442177e-07, -2.930206376e-06, -6.735699715e-06, -1.093618079e-05, -1.305622226e-05, -1.029974137e-05, -1.758426815e-06, 8.762700387e-06, 1.174619874e-05, -7.877723272e-07, -1.429114974e-05 -9.573144147e-05, -0.0004193987586, -0.0008874204343, -0.0009222384053, 0.0005899383351, 0.004906653823, 0.01253055361, 0.02168069672, 0.02592343965, 0.01470154691, -0.006718605375, -0.000119182369, -0.0005425621065, -0.001220383624, -0.001496252596, 1.535739201e-05, 0.005021183573, 0.01446817599, 0.02660943827, 0.03397909979, 0.02349575137, -0.001666883827, -0.0001079254225, -0.0005115791315, -0.001233868867, -0.00180054378, -0.001085742141, 0.002410553775, 0.009697381766, 0.01964745624, 0.02634825762, 0.01895339641, -0.0007176117448, -7.686549691e-05, -0.0003767524364, -0.0009594794226, -0.00156848079, -0.001497098699, 0.000272339201, 0.004531796804, 0.01075474221, 0.01527808394, 0.01109357876, -0.0008206071416, -4.495501999e-05, -0.0002260353957, -0.0005983764135, -0.001049881085, -0.001212231479, -0.0005148758468, 0.00153834558, 0.004766063683, 0.00727564042, 0.005302058477, -0.0006900594921, -2.17022937e-05, -0.0001113416768, -0.0003034513204, -0.0005589176745, -0.0007178212346, -0.0005146547716, 0.0003029461894, 0.001696984897, 0.00285115865, 0.002080241431, -0.0004255420333, -8.364115454e-06, -4.367811268e-05, -0.0001220047854, -0.0002335356076, -0.0003229973719, -0.0002917320665, -3.819575833e-05, 0.0004402321068, 0.0008633302375, 0.0006291035303, -0.0001995032275, -2.346509237e-06, -1.246634874e-05, -3.563705758e-05, -7.059996163e-05, -0.0001036876487, -0.0001083519618, -5.500824789e-05, 6.194201633e-05, 0.0001738907321, 0.0001259398364, -6.711078364e-05, -3.682533313e-07, -1.992187764e-06, -5.831179943e-06, -1.194536208e-05, -1.851511546e-05, -2.158957014e-05, -1.636416048e-05, -1.126570534e-06, 1.515105522e-05, 1.068706349e-05, -1.270865963e-05, -2.905262831e-05, -0.0001380988818, -0.000344535128, -0.0004956131234, -5.989779894e-05, 0.001987925967, 0.006796054729, 0.01411467366, 0.01900863273, 0.01080192366, -0.007611802676, -3.890384449e-05, -0.0001890485356, -0.0004852210787, -0.0007489552665, -0.0003173462395, 0.002129003274, 0.008159779044, 0.01778681444, 0.02546414123, 0.01830003941, -0.003100015592, -3.753362749e-05, -0.0001880859778, -0.0005071291456, -0.0008800966145, -0.0007836933603, 0.0008865767082, 0.005522447818, 0.01333070536, 0.01997659391, 0.0149283658, -0.001877634612, -2.847592633e-05, -0.0001463971686, -0.0004104333245, -0.0007725321398, -0.0009154056356, -0.000120663826, 0.002567865214, 0.007401633633, 0.01171233043, 0.008773457375, -0.001502630222, -1.77505325e-05, -9.299649422e-05, -0.0002677872265, -0.0005300567539, -0.0007192575844, -0.0004449457049, 0.0008379171059, 0.003323757749, 0.005638469025, 0.004202398189, -0.001018832025, -9.127237647e-06, -4.852870816e-05, -0.0001424961044, -0.0002918269254, -0.0004286048872, -0.0003750121263, 0.0001279388357, 0.001193432959, 0.002229958508, 0.001647718428, -0.0005571258415, -3.741497216e-06, -2.015698103e-05, -6.017555007e-05, -0.0001266016808, -0.0001966822581, -0.000205455505, -5.41382689e-05, 0.0003081693632, 0.0006790709751, 0.0004948028187, -0.0002411957946, -1.114368204e-06, -6.083887898e-06, -1.845737697e-05, -3.979450246e-05, -6.475095387e-05, -7.614433299e-05, -4.649684091e-05, 4.073345998e-05, 0.0001364149187, 9.667116899e-05, -7.644734189e-05, -1.852919823e-07, -1.026578244e-06, -3.168931561e-06, -7.00315716e-06, -1.188864592e-05, -1.532571722e-05, -1.30435833e-05, -2.017055732e-06, 1.146756318e-05, 7.399052492e-06, -1.380453085e-05 -1.976281487e-05, -0.000119929093, -0.0003832317689, -0.0008193276355, -0.001184576568, -0.000740606229, 0.001961864464, 0.00880360968, 0.01944650149, 0.02479784472, 0.01200569583, -2.41636591e-05, -0.0001498393743, -0.0004910437387, -0.001086366199, -0.001671934291, -0.00136192865, 0.001660550464, 0.009891837894, 0.02349575137, 0.03230169181, 0.01894189611, -2.157285826e-05, -0.0001370104018, -0.0004636476867, -0.001077337876, -0.00182128211, -0.002019958297, -0.0001747726612, 0.005913673255, 0.01679240411, 0.02477770546, 0.01546958561, -1.51959815e-05, -9.853332103e-05, -0.0003427302948, -0.0008290247177, -0.001501974056, -0.001969962858, -0.001274182347, 0.002091133007, 0.008739029065, 0.014170093, 0.009269111611, -8.814446886e-06, -5.810388986e-05, -0.0002064144178, -0.0005141192066, -0.000975399129, -0.001403490265, -0.001288489574, 0.0002223894141, 0.003591394987, 0.00663714058, 0.00457052095, -4.228198699e-06, -2.825019022e-05, -0.0001020603328, -0.0002599601627, -0.0005098159877, -0.0007783998722, -0.0008397601999, -0.0002928267357, 0.001127670534, 0.002547498897, 0.001867767062, -1.620566333e-06, -1.095995703e-05, -4.018747145e-05, -0.0001043462284, -0.0002102637114, -0.0003357718436, -0.0004010398187, -0.0002552688171, 0.000219010407, 0.0007485325543, 0.0005990304751, -4.52176023e-07, -3.094993405e-06, -1.151330776e-05, -3.044287345e-05, -6.288356728e-05, -0.0001043688862, -0.0001346378767, -0.0001125350289, -6.900924322e-07, 0.0001426219445, 0.0001327264159, -7.054494777e-08, -4.890572217e-07, -1.846924846e-06, -4.975286507e-06, -1.05325287e-05, -1.812654831e-05, -2.496375626e-05, -2.480700587e-05, -1.102285939e-05, 1.047560949e-05, 1.445443851e-05, -6.294720089e-06, -4.339846478e-05, -0.0001648983392, -0.0004348211352, -0.000819086322, -0.0009119433482, 0.0005010665138, 0.005548985328, 0.01489762049, 0.02074136497, 0.01020373633, -8.24785923e-06, -5.713853778e-05, -0.0002179637437, -0.0005793094034, -0.001113968774, -0.001338258044, 0.0002456231312, 0.006362574438, 0.01832049119, 0.02752447735, 0.01674280098, -7.81877121e-06, -5.482721266e-05, -0.0002125436378, -0.0005806128242, -0.001181183719, -0.001671938736, -0.0008540754457, 0.003586544332, 0.01306187944, 0.0211768986, 0.01376219692, -5.846614997e-06, -4.143030057e-05, -0.0001628460099, -0.000455112021, -0.0009672305076, -0.00152275495, -0.00137925936, 0.0009948730236, 0.006716564564, 0.01210330506, 0.008257678788, -3.60140989e-06, -2.57079602e-05, -0.0001019878945, -0.0002893732362, -0.0006325919265, -0.001059786331, -0.001187281677, -0.0001710278609, 0.002694728905, 0.005657245287, 0.004074931592, -1.833143152e-06, -1.315671913e-05, -5.2533706e-05, -0.0001506203341, -0.0003356709453, -0.0005854183767, -0.0007340161974, -0.0003929497448, 0.0008012009728, 0.00216127672, 0.001665575678, -7.445226858e-07, -5.370044831e-06, -2.156184434e-05, -6.235365998e-05, -0.0001411081033, -0.0002537120655, -0.0003430243538, -0.0002656238753, 0.0001274185119, 0.0006280902136, 0.0005333980672, -2.197559377e-07, -1.593728528e-06, -6.43714209e-06, -1.877384749e-05, -4.309381387e-05, -7.956706732e-05, -0.0001141411126, -0.0001083557871, -1.766414735e-05, 0.0001161438671, 0.0001175004506, -3.620122712e-08, -2.643286359e-07, -1.075362355e-06, -3.166445643e-06, -7.376669711e-06, -1.397399547e-05, -2.111271192e-05, -2.307371212e-05, -1.235250468e-05, 7.441673776e-06, 1.255415275e-05 diff --git a/TestCases/hybrid_regression.py b/TestCases/hybrid_regression.py index 04c8ccffa1a5..378cf419ff48 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.965642, 2.459171, 0.016012, 0.042270] + channel.test_vals = [-2.356739, 3.185311, 0.135404, 0.143482] 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.766168, -4.287699, 0.326688, 0.022661] + naca0012.test_vals = [-4.968156, -4.396643, 0.331958, 0.023010] 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 = [-1.379426, 4.288828, -0.245341, 0.043244] + wedge.test_vals = [-1.301825, 4.369535, -0.236575, 0.041741] 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.896832, 1.637749, 0.301084, 0.019485] + fixedCL_naca0012.test_vals = [-3.786753, 1.752735, 0.301271, 0.019497] 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 = [-7.680046, -2.207922, 0.001084, 0.036233, 2.361500, -2.325300, 0.000000, 0.000000] + flatplate.test_vals = [-7.466885, -1.982938, 0.001084, 0.036236, 2.361500, -2.325300, 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.266602, -2.784028, -0.019899, 1.615655, 0.000000] + cylinder.test_vals = [-8.433648, -2.945868, -0.009392, 1.603197, 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.830997, -1.368850, -0.143986, 73.963289, 0.000000] + cylinder_lowmach.test_vals = [-6.412671, -0.950845, 0.039507, -134.197077, 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.008997, -7.262292, -0.000000, 2.089953] + poiseuille_profile.test_vals = [-12.012575, -7.696236, -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.020123, -5.269264, 0.807147, 0.060494, 0.000000] + rae2822_sa.test_vals = [-1.846052, -5.109587, 0.571411, 0.040773, 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 = [-0.510339, 5.386831, 0.811983, 0.061600, 0.000000] + rae2822_sst.test_vals = [-0.509927, 5.868873, 0.580652, 0.014294, 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.643406, 5.386831, 0.811983, 0.061600] + rae2822_sst_sust.test_vals = [-2.446013, 5.868873, 0.580652, 0.014294] 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.316127, -6.738720, -0.187461, 0.057469] + turb_flatplate.test_vals = [-4.075879, -6.829935, -0.200296, 0.022692] 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.038066, -16.332090, 1.080346, 0.018385, 20.000000, -2.873343, 0.000000, -14.250271, 0.000000] + turb_naca0012_sa.test_vals = [-12.038153, -16.332090, 1.080346, 0.018385, 20, -2.872824, 0, -14.250271, 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,8 +206,8 @@ 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.093897, -15.251080, -5.906326, 1.070413, 0.015775, -2.855557, 0] - turb_naca0012_sst.test_vals_aarch64 = [-12.075928, -15.246732, -5.861249, 1.070036, 0.015841, -2.835263, 0.000000] + turb_naca0012_sst.test_vals = [-12.093892, -15.251078, -5.906327, 1.070413, 0.015775, -2.855348, 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) # NACA0012 (SST_SUST, FUN3D finest grid results: CL=1.0840, CD=0.01253) @@ -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.080740, -14.837176, -5.732917, 1.000893, 0.019109, -2.120257] + turb_naca0012_sst_sust.test_vals = [-12.080757, -14.837176, -5.732917, 1.000893, 0.019109, -2.120437] 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) @@ -224,7 +224,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.192389, -10.445226, 0.774100, 1.022534, 0.040529, -2.383436] + turb_naca0012_sst_fixedvalues.test_vals = [-5.192389, -10.448080, 0.773965, 1.022534, 0.040529, -2.383403] test_list.append(turb_naca0012_sst_fixedvalues) # NACA0012 (SST, explicit Euler for flow and turbulence equations) @@ -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.066676, -7.446616, -8.813770, -3.730662, 0] + axi_rans_air_nozzle_restart.test_vals = [-12.066224, -7.425808, -8.815859, -3.732773, 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.586046, -5.057159, 0.830274, -0.008747, 0.078023] + turb_naca0012_sst_restart_mg.test_vals = [-6.613316, -5.057159, 0.830274, -0.008869, 0.077835] test_list.append(turb_naca0012_sst_restart_mg) ############################# @@ -278,7 +278,7 @@ def main(): turb_naca0012_1c.cfg_dir = "rans_uq/naca0012" turb_naca0012_1c.cfg_file = "turb_NACA0012_uq_1c.cfg" turb_naca0012_1c.test_iter = 10 - turb_naca0012_1c.test_vals = [-4.979757, 1.345555, 0.450656, -0.030217] + turb_naca0012_1c.test_vals = [-4.976782, 1.343831, 0.443889, -0.029247] turb_naca0012_1c.test_vals_aarch64 = [-4.976620, 1.345983, 0.433171, -0.033685] test_list.append(turb_naca0012_1c) @@ -287,7 +287,7 @@ def main(): turb_naca0012_2c.cfg_dir = "rans_uq/naca0012" turb_naca0012_2c.cfg_file = "turb_NACA0012_uq_2c.cfg" turb_naca0012_2c.test_iter = 10 - turb_naca0012_2c.test_vals = [-5.482860, 1.263778, 0.403145, -0.043182] + turb_naca0012_2c.test_vals = [-5.482862, 1.260869, 0.405097, -0.040169] turb_naca0012_2c.test_vals_aarch64 = [-5.485484, 1.263406, 0.411442, -0.040859] test_list.append(turb_naca0012_2c) @@ -296,7 +296,7 @@ def main(): turb_naca0012_3c.cfg_dir = "rans_uq/naca0012" turb_naca0012_3c.cfg_file = "turb_NACA0012_uq_3c.cfg" turb_naca0012_3c.test_iter = 10 - turb_naca0012_3c.test_vals = [-5.583729, 1.232137, 0.384897, -0.047679] + turb_naca0012_3c.test_vals = [-5.583738, 1.228730, 0.381824, -0.046280] turb_naca0012_3c.test_vals_aarch64 = [-5.583737, 1.232005, 0.390258, -0.046305] test_list.append(turb_naca0012_3c) @@ -305,7 +305,7 @@ def main(): turb_naca0012_p1c1.cfg_dir = "rans_uq/naca0012" turb_naca0012_p1c1.cfg_file = "turb_NACA0012_uq_p1c1.cfg" turb_naca0012_p1c1.test_iter = 10 - turb_naca0012_p1c1.test_vals = [-5.133790, 1.285469, 0.551790, 0.009703] + turb_naca0012_p1c1.test_vals = [-5.133998, 1.283519, 0.548341, 0.010772] turb_naca0012_p1c1.test_vals_aarch64 = [-5.114189, 1.285037, 0.406851, -0.043003] test_list.append(turb_naca0012_p1c1) @@ -314,7 +314,7 @@ def main(): turb_naca0012_p1c2.cfg_dir = "rans_uq/naca0012" turb_naca0012_p1c2.cfg_file = "turb_NACA0012_uq_p1c2.cfg" turb_naca0012_p1c2.test_iter = 10 - turb_naca0012_p1c2.test_vals = [-5.553940, 1.237339, 0.427689, -0.034727] + turb_naca0012_p1c2.test_vals = [-5.553950, 1.234029, 0.424324, -0.033438] turb_naca0012_p1c2.test_vals_aarch64 = [-5.548245, 1.236384, 0.381821, -0.050337] test_list.append(turb_naca0012_p1c2) @@ -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 = [-7.127256, -6.466554, 0.531991, 0.008466] + inc_euler_naca0012.test_vals = [-7.118160, -6.555943, 0.531994, 0.008466] 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 = [-6.593521, -5.830706, -0.009062, 0.126050] + inc_nozzle.test_vals = [-4.177986, -3.716749, 0.151721, 0.152945] 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.004277, -3.227956, 0.003851, 7.626583] + inc_lam_cylinder.test_vals = [-4.059218, -3.311865, 0.006311, 6.172389] test_list.append(inc_lam_cylinder) # Buoyancy-driven cavity @@ -404,7 +404,7 @@ def main(): inc_turb_naca0012.cfg_dir = "incomp_rans/naca0012" inc_turb_naca0012.cfg_file = "naca0012.cfg" inc_turb_naca0012.test_iter = 20 - inc_turb_naca0012.test_vals = [-4.758063, -10.974497, -0.000004, -0.028654, 4, -5.405154, 2, -5.032677] + inc_turb_naca0012.test_vals = [-4.758063, -10.974497, -0.000004, -0.028654, 4, -5.402309, 2, -5.032668] test_list.append(inc_turb_naca0012) # NACA0012, SST_SUST @@ -420,7 +420,7 @@ def main(): inc_weakly_coupled.cfg_dir = "disc_adj_heat" inc_weakly_coupled.cfg_file = "primal.cfg" inc_weakly_coupled.test_iter = 10 - inc_weakly_coupled.test_vals = [-18.204006, -16.304263, -16.482688, -15.007166, -17.858118, -14.025082, 5.609100] + inc_weakly_coupled.test_vals = [-18.121422, -16.304159, -16.482315, -15.007167, -17.858118, -14.024885, 5.609100] test_list.append(inc_weakly_coupled) ###################################### @@ -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 = [-5.627869, -0.164403, 0.054734, 2.545857] + cavity.test_vals = [-5.515304, -0.049093, -0.114942, -7.135967] 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 = [-8.008023, -2.611064, 1.497308, 1.487483] + spinning_cylinder.test_vals = [-7.756180, -2.301600, 1.422425, 1.431645] 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.481818, -0.010484, -0.008178] + sine_gust.test_vals = [-1.977498, 3.481817, -0.010140, -0.007833] 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.001949, -0.001254, 0.000425, -0.000593] + cosine_gust.test_vals = [-2.418805, 0.001919, -0.001262, 0.000418, -0.000592] cosine_gust.unsteady = True cosine_gust.enabled_with_tsan = False test_list.append(cosine_gust) @@ -481,7 +481,7 @@ def main(): gust_mesh_defo.cfg_dir = "gust" gust_mesh_defo.cfg_file = "gust_with_mesh_deformation.cfg" gust_mesh_defo.test_iter = 6 - gust_mesh_defo.test_vals = [-1.844761, 0.001095, -0.000273] + gust_mesh_defo.test_vals = [-1.844761, 0.001077, -0.000263] gust_mesh_defo.unsteady = True gust_mesh_defo.enabled_with_tsan = False test_list.append(gust_mesh_defo) @@ -491,7 +491,7 @@ def main(): aeroelastic.cfg_dir = "aeroelastic" aeroelastic.cfg_file = "aeroelastic_NACA64A010.cfg" aeroelastic.test_iter = 2 - aeroelastic.test_vals = [0.074052, 0.027623, -0.001641, -0.000128] + aeroelastic.test_vals = [0.075093, 0.027559, -0.001640, -0.000129] aeroelastic.test_vals_aarch64 = [0.074170, 0.027590, -0.001579, -0.000160] aeroelastic.unsteady = True aeroelastic.enabled_on_cpu_arch = ["x86_64"] # Requires AVX-capable architecture @@ -521,7 +521,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.665168, -3.793307, -3.716526, -3.148348] + unst_deforming_naca0012.test_vals = [-3.665129, -3.793418, -3.716491, -3.148323] unst_deforming_naca0012.unsteady = True unst_deforming_naca0012.enabled_with_tsan = False test_list.append(unst_deforming_naca0012) @@ -535,7 +535,7 @@ def main(): edge_VW.cfg_dir = "nicf/edge" edge_VW.cfg_file = "edge_VW.cfg" edge_VW.test_iter = 40 - edge_VW.test_vals = [-5.681149, 0.463233, -0.000009, 0.000000] + edge_VW.test_vals = [-2.013020, 4.187730, -0.000009, 0.000000] test_list.append(edge_VW) # Rarefaction shock wave edge_PPR @@ -543,7 +543,7 @@ def main(): edge_PPR.cfg_dir = "nicf/edge" edge_PPR.cfg_file = "edge_PPR.cfg" edge_PPR.test_iter = 40 - edge_PPR.test_vals = [-7.139177, -0.980792, -0.000034, 0.000000] + edge_PPR.test_vals = [-7.126741, -0.965306, -0.000034, 0.000000] edge_PPR.test_vals_aarch64 = [-7.139211, -0.980821, -0.000034, 0.000000] test_list.append(edge_PPR) @@ -564,7 +564,7 @@ def main(): axial_stage2D.cfg_dir = "turbomachinery/axial_stage_2D" axial_stage2D.cfg_file = "Axial_stage2D.cfg" axial_stage2D.test_iter = 20 - axial_stage2D.test_vals = [1.065797, 1.519589, -2.928280, 2.573904, -2.526637, 3.017140, 106370.000000, 106370.000000, 5.726800, 64.383000] + axial_stage2D.test_vals = [1.167176, 1.598838, -2.928275, 2.573906, -2.526637, 3.017140, 106370.000000, 106370.000000, 5.726800, 64.383000] test_list.append(axial_stage2D) # 2D transonic stator restart @@ -572,7 +572,7 @@ def main(): transonic_stator_restart.cfg_dir = "turbomachinery/transonic_stator_2D" transonic_stator_restart.cfg_file = "transonic_stator_restart.cfg" transonic_stator_restart.test_iter = 20 - transonic_stator_restart.test_vals = [-4.442510, -2.561369, -2.165778, 1.652750, -1.355494, 3.172711, -471620.000000, 94.843000, -0.043825] + transonic_stator_restart.test_vals = [-4.367184, -2.487640, -2.079069, 1.728134, -1.464968, 3.224889, -471620.000000, 94.839000, -0.051073] transonic_stator_restart.test_vals_aarch64 = [-4.442510, -2.561369, -2.165778, 1.652750, -1.355494, 3.172712, -471620.000000, 94.843000, -0.043825] test_list.append(transonic_stator_restart) @@ -614,7 +614,7 @@ def main(): channel_3D.cfg_dir = "sliding_interface/channel_3D" channel_3D.cfg_file = "channel_3D_WA.cfg" channel_3D.test_iter = 2 - channel_3D.test_vals = [2.000000, 0.000000, 0.629106, 0.524897, 0.422366] + channel_3D.test_vals = [2.000000, 0.000000, 0.629091, 0.524932, 0.422527] channel_3D.test_vals_aarch64 = [2.000000, 0.000000, 0.629112, 0.524948, 0.422396] channel_3D.unsteady = True channel_3D.multizone = True @@ -656,7 +656,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.621423, -1.660901] + bars_SST_2D.test_vals = [13.000000, -0.623154, -1.660901] bars_SST_2D.multizone = True test_list.append(bars_SST_2D) @@ -679,7 +679,7 @@ def main(): statbeam3d.cfg_dir = "fea_fsi/StatBeam_3d" statbeam3d.cfg_file = "configBeam_3d.cfg" statbeam3d.test_iter = 0 - statbeam3d.test_vals = [-2.787802, -1.721974, -2.438436, 110350] + statbeam3d.test_vals = [-2.777602, -1.710976, -2.445072, 110350] statbeam3d.test_vals_aarch64 = [-2.777602, -1.710976, -2.445072, 110350] test_list.append(statbeam3d) @@ -765,7 +765,7 @@ def main(): pywrapper_translating_naca0012.reference_file = "forces_0.csv.ref" pywrapper_translating_naca0012.reference_file_aarch64 = "forces_0_aarch64.csv.ref" pywrapper_translating_naca0012.test_file = "forces_0.csv" - pywrapper_translating_naca0012.tol_file_percent = 0.1 + pywrapper_translating_naca0012.tol_file_percent = 5.0 pywrapper_translating_naca0012.enabled_on_cpu_arch = ["x86_64"] pywrapper_translating_naca0012.enabled_with_tsan = False file_diff_list.append(pywrapper_translating_naca0012) @@ -779,7 +779,7 @@ def main(): pywrapper_updated_moving_frame_naca0012.reference_file = "forces_0.csv.ref" pywrapper_updated_moving_frame_naca0012.reference_file_aarch64 = "forces_0_aarch64.csv.ref" pywrapper_updated_moving_frame_naca0012.test_file = "forces_0.csv" - pywrapper_updated_moving_frame_naca0012.tol_file_percent = 0.1 + pywrapper_updated_moving_frame_naca0012.tol_file_percent = 5.0 pywrapper_updated_moving_frame_naca0012.enabled_on_cpu_arch = ["x86_64"] pywrapper_updated_moving_frame_naca0012.enabled_with_tsan = False file_diff_list.append(pywrapper_updated_moving_frame_naca0012) diff --git a/TestCases/hybrid_regression_AD.py b/TestCases/hybrid_regression_AD.py index 21f86015e12d..7a6abd83c225 100644 --- a/TestCases/hybrid_regression_AD.py +++ b/TestCases/hybrid_regression_AD.py @@ -66,7 +66,7 @@ def main(): discadj_arina2k.cfg_dir = "disc_adj_euler/arina2k" discadj_arina2k.cfg_file = "Arina2KRS.cfg" discadj_arina2k.test_iter = 20 - discadj_arina2k.test_vals = [-3.254503, -3.495599, 0.052373, 0.000000] + discadj_arina2k.test_vals = [-3.229402, -3.466984, 0.043984, 0.000000] test_list.append(discadj_arina2k) #################################### @@ -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, -4.091640, -2.655563, 0.000000] + discadj_incomp_NACA0012.test_vals = [20.000000, -3.977753, -2.562520, 0.000000] test_list.append(discadj_incomp_NACA0012) ##################################### @@ -187,7 +187,8 @@ 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.220333, -1.646832, -0.007539, 0.000013] + discadj_pitchingNACA0012.test_vals = [-1.224189, -1.654687, -0.004097, -0.000003] + discadj_pitchingNACA0012.tol = 0.01 discadj_pitchingNACA0012.unsteady = True discadj_pitchingNACA0012.enabled_with_tsan = False test_list.append(discadj_pitchingNACA0012) @@ -201,7 +202,7 @@ def main(): discadj_fea.cfg_dir = "disc_adj_fea" discadj_fea.cfg_file = "configAD_fem.cfg" discadj_fea.test_iter = 4 - discadj_fea.test_vals = [1.774569, 1.928023, -0.000364, -8.690300] + discadj_fea.test_vals = [2.149620, 2.014985, -0.000364, -8.767900] discadj_fea.test_vals_aarch64 = [1.794371, 2.005865, -0.000365, -8.718100] test_list.append(discadj_fea) @@ -212,7 +213,8 @@ def main(): for test in test_list: test.command = TestCase.Command(exec = "SU2_CFD_AD", param = "-t 2") test.timeout = 600 - test.tol = 1e-4 + if test.tol == 0.0: + test.tol = 1.0e-4 #end pass_list = [ test.run_test(args.tsan) for test in test_list ] diff --git a/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/of_grad_findiff.csv.ref b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/of_grad_findiff.csv.ref index 3e2b9a6332a8..9246266f98a3 100644 --- a/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/of_grad_findiff.csv.ref +++ b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/of_grad_findiff.csv.ref @@ -1,2 +1,2 @@ "VARIABLE" , "AVG_DENSITY[0]", "AVG_ENTHALPY[0]", "AVG_NORMALVEL[0]", "DRAG[0]" , "EFFICIENCY[0]" , "FORCE_X[0]" , "FORCE_Y[0]" , "FORCE_Z[0]" , "LIFT[0]" , "MOMENT_X[0]" , "MOMENT_Y[0]" , "MOMENT_Z[0]" , "SIDEFORCE[0]" , "SURFACE_MACH[0]", "SURFACE_MASSFLOW[0]", "SURFACE_MOM_DISTORTION[0]", "SURFACE_PRESSURE_DROP[0]", "SURFACE_SECONDARY[0]", "SURFACE_SECOND_OVER_UNIFORM[0]", "SURFACE_STATIC_PRESSURE[0]", "SURFACE_STATIC_TEMPERATURE[0]", "SURFACE_TOTAL_PRESSURE[0]", "SURFACE_TOTAL_TEMPERATURE[0]", "SURFACE_UNIFORMITY[0]", "AVG_TEMPERATURE[1]", "TOTAL_HEATFLUX[1]", "FINDIFF_STEP" -0 , 0.0 , -20000.000949949026, 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , -0.01000000082740371, 1.1100000001884e-08, -0.04000000330961484 , 0.0 , 0.01000000082740371 , 0.059999993862192014 , -9.999999406318238 , 0.0 , -69.99999868639861 , 0.0 , -0.09999998606957661 , -80.0000009348878 , -359.99998999614036, 1e-08 +0 , 0.0 , -850000.0054482371, -7.771600000104802e-08, 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , -0.5900000002445616, -2.4420000000008897e-07, -42.92999999933045 , 0.0 , 54.82000000056608 , 110.76999999470871 , 29899.9999984062 , -239.9999971203215 , 28910.000000337277 , -239.9999971203215 , -35.200000003676735 , -80.0000009348878 , -490.00000217347406, 1e-08 diff --git a/TestCases/multiple_ffd/naca0012/of_grad_cd.dat.ref b/TestCases/multiple_ffd/naca0012/of_grad_cd.dat.ref index fce3c63c6760..dcfbdc3dc263 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.0790825 , 0.001 - 1 , -0.112974 , 0.001 + 0 , 0.0640697 , 0.001 + 1 , -0.117493 , 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 27fc6f627aec..d09e8e3fb047 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.05922508178 , -0.6082054907 , 0.05650610011 , 0.1252552372 , 0.0 , 0.1239927558 , 0.0 , 0.0 , 0.00502894879 , 0.0 - 1 , -0.07750209216 , 8.684127966 , -0.08326907905 , 0.2634518171 , 0.0 , 0.2652056281 , 0.0 , 0.0 , -0.006643227386 , 0.0 + 0 , 0.06254154103 , 0.1373280567 , 0.06005900872 , 0.1144550943 , 0.0 , 0.1131176767 , 0.0 , 0.0 , 0.01961712845 , 0.0 + 1 , -0.1126451148 , 6.126522734 , -0.1183006714 , 0.2579616726 , 0.0 , 0.2604810003 , 0.0 , 0.0 , 0.04918121089 , 0.0 diff --git a/TestCases/parallel_regression.py b/TestCases/parallel_regression.py index 37e3a5756dec..2925725d1eb1 100755 --- a/TestCases/parallel_regression.py +++ b/TestCases/parallel_regression.py @@ -87,7 +87,7 @@ def main(): thermalbath.cfg_dir = "nonequilibrium/thermalbath/finitechemistry" thermalbath.cfg_file = "thermalbath.cfg" thermalbath.test_iter = 10 - thermalbath.test_vals = [0.945997, 0.945997, -12.039262, -12.171767, -32.000000, 10.013239] + thermalbath.test_vals = [0.945997, 0.945997, -11.860991, -11.857906, -32.000000, 10.013239] test_list.append(thermalbath) # Adiabatic thermal bath @@ -95,7 +95,7 @@ def main(): ionized.cfg_dir = "nonequilibrium/thermalbath/finitechemistry" ionized.cfg_file = "weakly_ionized.cfg" ionized.test_iter = 10 - ionized.test_vals = [-29.806157, -11.130797, -11.337264, -17.235059, -17.578729, -15.190274, -25.013626, -32.000000, -5.174887, 0.000000, 0.000000] + ionized.test_vals = [-28.173855, -10.350260, -11.719875, -16.100105, -16.850783, -13.485322, -23.431375, -32.000000, -4.558277, 0.000000, 0.000000] ionized.test_vals_aarch64 = [-29.816386, -10.729986, -11.720016, -17.484469, -18.237891, -15.241605, -24.956918, -32.000000, -5.727244, 0.000000, 0.000000] test_list.append(ionized) @@ -104,7 +104,7 @@ def main(): thermalbath_frozen.cfg_dir = "nonequilibrium/thermalbath/frozen" thermalbath_frozen.cfg_file = "thermalbath_frozen.cfg" thermalbath_frozen.test_iter = 10 - thermalbath_frozen.test_vals = [-32.000000, -32.000000, -11.962477, -11.962477, -32.000000, 10.013545] + thermalbath_frozen.test_vals = [-32.000000, -32.000000, -11.818647, -11.857909, -32.000000, 10.013545] test_list.append(thermalbath_frozen) # Inviscid single wedge, ausm, implicit @@ -112,7 +112,7 @@ def main(): invwedge_a.cfg_dir = "nonequilibrium/invwedge" invwedge_a.cfg_file = "invwedge_ausm.cfg" invwedge_a.test_iter = 10 - invwedge_a.test_vals = [-1.069675, -1.594438, -18.299923, -18.627316, -18.573325, 2.245721, 1.874105, 5.290285, 0.847729] + invwedge_a.test_vals = [-1.069669, -1.594432, -18.299010, -18.626399, -18.572410, 2.245727, 1.874088, 5.290291, 0.847735] invwedge_a.test_vals_aarch64 = [-1.069675, -1.594438, -18.299736, -18.627126, -18.573137, 2.245721, 1.874105, 5.290285, 0.847729] test_list.append(invwedge_a) @@ -130,7 +130,7 @@ def main(): invwedge_msw.cfg_dir = "nonequilibrium/invwedge" invwedge_msw.cfg_file = "invwedge_msw.cfg" invwedge_msw.test_iter = 10 - invwedge_msw.test_vals = [-1.212335, -1.737098, -18.299220, -18.626618, -18.572623, 2.106171, 1.651949, 5.143958, 0.704444] + invwedge_msw.test_vals = [-1.212335, -1.737098, -18.299375, -18.626782, -18.572771, 2.106171, 1.651949, 5.143958, 0.704444] invwedge_msw.test_vals_aarch64 = [-1.212335, -1.737098, -18.299279, -18.626656, -18.572683, 2.106171, 1.651949, 5.143958, 0.704444] test_list.append(invwedge_msw) @@ -139,7 +139,7 @@ def main(): invwedge_roe.cfg_dir = "nonequilibrium/invwedge" invwedge_roe.cfg_file = "invwedge_roe.cfg" invwedge_roe.test_iter = 10 - invwedge_roe.test_vals = [-1.063535, -1.588299, -17.208084, -17.537836, -17.481214, 2.254713, 1.854802, 5.292805, 0.890122] + invwedge_roe.test_vals = [-1.054108, -1.578871, -17.782421, -18.111535, -18.055538, 2.264661, 1.841727, 5.302630, 0.897714] invwedge_roe.test_vals_aarch64 = [-1.052398, -1.577160, -17.794015, -18.122997, -18.067131, 2.266042, 1.849686, 5.304700, 0.899584] test_list.append(invwedge_roe) @@ -175,7 +175,7 @@ def main(): visc_cone.cfg_dir = "nonequilibrium/visc_wedge" visc_cone.cfg_file = "axi_visccone.cfg" visc_cone.test_iter = 10 - visc_cone.test_vals = [-5.222270, -5.746525, -20.560278, -20.510152, -20.409102, 1.255758, -3.208382, -0.016014, 0.093462, 32619.000000] + visc_cone.test_vals = [-5.222269, -5.746523, -20.560216, -20.510119, -20.409089, 1.255762, -3.208384, -0.016011, 0.093461, 32619] visc_cone.test_vals_aarch64 = [-5.222270, -5.746525, -20.560286, -20.510152, -20.409101, 1.255758, -3.208382, -0.016014, 0.093462, 32619.000000] test_list.append(visc_cone) @@ -220,7 +220,7 @@ def main(): channel.cfg_dir = "euler/channel" channel.cfg_file = "inv_channel_RK.cfg" channel.test_iter = 20 - channel.test_vals = [-2.904401, 2.536139, 0.020924, 0.042340] + channel.test_vals = [-2.343552, 3.197189, 0.123534, 0.148052] test_list.append(channel) # NACA0012 @@ -228,7 +228,7 @@ def main(): naca0012.cfg_dir = "euler/naca0012" naca0012.cfg_file = "inv_NACA0012_Roe.cfg" naca0012.test_iter = 20 - naca0012.test_vals = [-4.607257, -4.138750, 0.327682, 0.022685] + naca0012.test_vals = [-4.877597, -4.355615, 0.331699, 0.022976] test_list.append(naca0012) # Supersonic wedge @@ -236,7 +236,7 @@ def main(): wedge.cfg_dir = "euler/wedge" wedge.cfg_file = "inv_wedge_HLLC.cfg" wedge.test_iter = 20 - wedge.test_vals = [-1.387215, 4.281574, -0.245443, 0.043264] + wedge.test_vals = [-1.296189, 4.375714, -0.235637, 0.041589] test_list.append(wedge) # ONERA M6 Wing @@ -244,7 +244,7 @@ def main(): oneram6.cfg_dir = "euler/oneram6" oneram6.cfg_file = "inv_ONERAM6.cfg" oneram6.test_iter = 10 - oneram6.test_vals = [-11.500303, -10.971884, 0.280800, 0.008623] + oneram6.test_vals = [-11.457168, -10.921423, 0.280800, 0.008623] oneram6.timeout = 3200 test_list.append(oneram6) @@ -253,7 +253,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.840915, 1.693979, 0.301144, 0.019489] + fixedCL_naca0012.test_vals = [-3.802419, 1.735767, 0.301252, 0.019495] test_list.append(fixedCL_naca0012) # Polar sweep of the inviscid NACA0012 @@ -262,7 +262,7 @@ def main(): polar_naca0012.cfg_file = "inv_NACA0012.cfg" polar_naca0012.polar = True polar_naca0012.test_iter = 10 - polar_naca0012.test_vals = [-1.096894, 4.372054, 0.002074, 0.031515] + polar_naca0012.test_vals = [-1.107467, 4.365654, 0.006796, 0.025216] 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 @@ -290,10 +290,26 @@ def main(): ramp.cfg_dir = "euler/ramp" ramp.cfg_file = "inv_ramp.cfg" ramp.test_iter = 10 - ramp.test_vals = [-13.649760, -8.012144, -0.076277, 0.054839] + ramp.test_vals = [-13.646937, -8.006398, -0.076277, 0.054839] ramp.test_vals_aarch64 = [-13.648406, -8.014579, -0.076277, 0.054839] test_list.append(ramp) + ramp_msw = TestCase('ramp_msw') + ramp_msw.cfg_dir = "euler/ramp" + ramp_msw.cfg_file = "inv_ramp_msw.cfg" + ramp_msw.test_iter = 100 + ramp_msw.test_vals = [-7.5, -1.765, -0.077520, 0.054427] + ramp_msw.tol = [0.03, 0.03, 0.00001, 0.00001] + test_list.append(ramp_msw) + + # MFR_coupling + MFR_coupling = TestCase('MFR_coupling') + MFR_coupling.cfg_dir = "euler/turbofan_MFR_coupling" + MFR_coupling.cfg_file = "MFR_coupling.cfg" + MFR_coupling.test_iter = 100 + MFR_coupling.test_vals = [-2.1124e+02, 1.5003e+02, 2.0151e+01] + test_list.append(MFR_coupling) + ########################## ### Compressible N-S ### ########################## @@ -303,7 +319,7 @@ def main(): flatplate.cfg_dir = "navierstokes/flatplate" flatplate.cfg_file = "lam_flatplate.cfg" flatplate.test_iter = 100 - flatplate.test_vals = [-7.613292, -2.141207, 0.001084, 0.036230, 2.361500, -2.325300, 0.000000, 0.000000] + flatplate.test_vals = [-7.436411, -1.956557, 0.001084, 0.036232, 2.361500, -2.325300, 0.000000, 0.000000] test_list.append(flatplate) # Custom objective function @@ -311,7 +327,7 @@ def main(): flatplate_udobj.cfg_dir = "user_defined_functions" flatplate_udobj.cfg_file = "lam_flatplate.cfg" flatplate_udobj.test_iter = 20 - flatplate_udobj.test_vals = [-6.760101, -1.283906, -0.745653, 0.000587, -0.000038, 0.000977, -0.001015, 596.450000, 299.550000, 296.900000, 21.318000, 0.586640, 36.553000, 2.188800] + flatplate_udobj.test_vals = [-0.001015, 596.450000, 299.550000, 296.900000, 21.318000, 0.586640, 36.553000, 2.188800] test_list.append(flatplate_udobj) # Probe performance test (11 probes, ADT path) @@ -328,7 +344,7 @@ def main(): cylinder.cfg_dir = "navierstokes/cylinder" cylinder.cfg_file = "lam_cylinder.cfg" cylinder.test_iter = 25 - cylinder.test_vals = [-8.422012, -2.930518, -0.003394, 1.608420, 0.000000] + cylinder.test_vals = [-8.486555, -2.997719, -0.006044, 1.601479, 0.000000] test_list.append(cylinder) # Laminar cylinder (low Mach correction) @@ -336,7 +352,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.841606, -1.379533, -1.266782, 76.118168, 0.000000] + cylinder_lowmach.test_vals = [-6.388898, -0.927029, -0.590968, -132.145318, 0.000000] test_list.append(cylinder_lowmach) # 2D Poiseuille flow (body force driven with periodic inlet / outlet) @@ -353,7 +369,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.007496, -7.227093, -0.000000, 2.089953] + poiseuille_profile.test_vals = [-12.011765, -7.670052, -0.000000, 2.089953] poiseuille_profile.test_vals_aarch64 = [-12.007498, -7.226926, -0.000000, 2.089953] test_list.append(poiseuille_profile) @@ -366,7 +382,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.004689, -5.265730, 0.809462, 0.062011, 0.000000] + rae2822_sa.test_vals = [-1.850422, -5.131788, 0.571589, 0.042386, 0.000000] test_list.append(rae2822_sa) # RAE2822 SST @@ -374,7 +390,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 = [-0.510305, 5.386832, 0.813794, 0.062425, 0.000000] + rae2822_sst.test_vals = [-0.509872, 5.867970, 0.575399, 0.016441, 0.000000] test_list.append(rae2822_sst) # RAE2822 SST_SUST @@ -382,7 +398,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.644127, 5.386832, 0.813793, 0.062425] + rae2822_sst_sust.test_vals = [-2.464677, 5.867970, 0.575399, 0.016441] test_list.append(rae2822_sst_sust) # Flat plate @@ -390,7 +406,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.297192, -6.731227, -0.187632, 0.057700] + turb_flatplate.test_vals = [-3.944613, -6.827069, -0.192592, 0.023549] test_list.append(turb_flatplate) # Flat plate (compressible) with species inlet @@ -398,7 +414,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.249462, -0.634904, -1.716285, 1.223210, -3.307930, 9.000000, -6.633666, 5.000000, -6.986787, 10.000000, -6.255670, 0.999903, 0.9999033] + turb_flatplate_species.test_vals = [-3.901196, -1.030304, -1.390862, 1.596603, -3.294825, 9.000000, -6.033863, 5.000000, -6.604787, 10.000000, -5.749978, 0.999917, 0.999917] test_list.append(turb_flatplate_species) # Flat plate SST compressibility correction Wilcox @@ -406,7 +422,7 @@ def main(): turb_flatplate_CC_Wilcox.cfg_dir = "rans/flatplate" turb_flatplate_CC_Wilcox.cfg_file = "turb_SST_flatplate_compressibility_Wilcox.cfg" turb_flatplate_CC_Wilcox.test_iter = 20 - turb_flatplate_CC_Wilcox.test_vals = [-1.195053, 2.089306, 1.529063, 5.164703, -3.700915, 8.162921] + turb_flatplate_CC_Wilcox.test_vals = [-1.169750, 2.167973, 1.488567, 5.244807, -3.795767, 9.699598] test_list.append(turb_flatplate_CC_Wilcox) # Flat plate SST compressibility correction Sarkar @@ -414,7 +430,7 @@ def main(): turb_flatplate_CC_Sarkar.cfg_dir = "rans/flatplate" turb_flatplate_CC_Sarkar.cfg_file = "turb_SST_flatplate_compressibility_Sarkar.cfg" turb_flatplate_CC_Sarkar.test_iter = 20 - turb_flatplate_CC_Sarkar.test_vals = [-1.195053, 2.089306, 1.529063, 5.164703, -3.700917, 8.162921] + turb_flatplate_CC_Sarkar.test_vals = [-1.169750, 2.167973, 1.488567, 5.244807, -3.795765, 9.699598] test_list.append(turb_flatplate_CC_Sarkar) # FLAT PLATE, ROUGHNESS BC KNOPP SST @@ -430,7 +446,7 @@ def main(): turb_flatplate_sst_roughBCAupoix.cfg_dir = "rans/flatplate/roughness/bc_aupoix" turb_flatplate_sst_roughBCAupoix.cfg_file = "turb_SST_flatplate_roughBCAupoix.cfg" turb_flatplate_sst_roughBCAupoix.test_iter = 10 - turb_flatplate_sst_roughBCAupoix.test_vals = [-5.278097, -2.297701, -2.883899, 0.228298, -1.375945, 3.209449, -0.188736, 0.007201] + turb_flatplate_sst_roughBCAupoix.test_vals = [-5.278728, -2.302982, -2.890419, 0.227585, -1.393786, 3.192601, -0.188729, 0.0071821] test_list.append(turb_flatplate_sst_roughBCAupoix) # ONERA M6 Wing @@ -466,7 +482,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.037442, -16.376949, 1.080346, 0.018385, 20.000000, -1.564214, 20.000000, -4.180956, 0.000000] + turb_naca0012_sa.test_vals = [-12.037476, -16.376950, 1.080346, 0.018385, 20, -1.564171, 20, -4.180937, 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) @@ -476,7 +492,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.094699, -15.251093, -5.906365, 1.070413, 0.015775, -2.376178, 0.000000] + turb_naca0012_sst.test_vals = [-12.094714, -15.251093, -5.906365, 1.070413, 0.015775, -2.376111, 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) @@ -486,7 +502,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.082096, -14.837177, -5.733436, 1.000893, 0.019109, -2.240955] + turb_naca0012_sst_sust.test_vals = [-12.082149, -14.837177, -5.733436, 1.000893, 0.019109, -2.240949] 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) @@ -514,7 +530,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.437140, 0.774285, 1.022363, 0.040546, -3.736455] + turb_naca0012_sst_fixedvalues.test_vals = [-5.216551, -10.440018, 0.774146, 1.022363, 0.040546, -3.736444] turb_naca0012_sst_fixedvalues.timeout = 3200 test_list.append(turb_naca0012_sst_fixedvalues) @@ -555,7 +571,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.069728, -7.537071, -8.812516, -3.731961, 0.000000] + axi_rans_air_nozzle_restart.test_vals = [-12.069349, -7.508309, -8.813361, -3.732852, 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) @@ -570,7 +586,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.574959, -5.057159, 0.830274, -0.009283, 0.078035] + turb_naca0012_sst_restart_mg.test_vals = [-6.605858, -5.057159, 0.830274, -0.008419, 0.077910] turb_naca0012_sst_restart_mg.timeout = 3200 turb_naca0012_sst_restart_mg.tol = 0.000001 test_list.append(turb_naca0012_sst_restart_mg) @@ -584,7 +600,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 = [-7.154146, -6.507095, 0.532001, 0.008466] + inc_euler_naca0012.test_vals = [-7.155691, -6.591881, 0.531999, 0.008466] test_list.append(inc_euler_naca0012) # C-D nozzle with pressure inlet and mass flow outlet @@ -592,7 +608,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 = [-6.407323, -5.715668, -0.003225, 0.126214] + inc_nozzle.test_vals = [-4.867594, -4.435604, -0.006083, 0.131415] test_list.append(inc_nozzle) # Laminar wall mounted cylinder, Euler walls, cylinder wall diagonally split @@ -612,7 +628,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.004072, -3.194881, -0.076553, 7.780048] + inc_lam_cylinder.test_vals = [-3.959383, -3.272502, -0.087725, 6.769520] test_list.append(inc_lam_cylinder) # Laminar sphere, Re=1. Last column: Cd=24/Re @@ -620,7 +636,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.342048, -9.328063, 0.121003, 25.782687] + inc_lam_sphere.test_vals = [-8.377082, -9.393391, 0.121003, 25.782686] test_list.append(inc_lam_sphere) # Buoyancy-driven cavity @@ -758,7 +774,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.004689, 0.742307, 0.497308, -5.265730, 0.809462, 0.062011] + turbmod_sa_bsl_rae2822.test_vals = [-1.850422, 0.801378, 0.576701, -5.131788, 0.571589, 0.042386] test_list.append(turbmod_sa_bsl_rae2822) # SA Negative @@ -766,7 +782,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.345531, 1.448387, 1.208638, -0.846585, 1.271362, 0.497475, 0.000000] + turbmod_sa_neg_rae2822.test_vals = [-1.345560, 1.448328, 1.208614, -0.846773, 1.277698, 0.499718, 0] 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) @@ -775,7 +791,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.004688, 0.742305, 0.497309, -5.266066, 0.809466, 0.062026] + turbmod_sa_comp_rae2822.test_vals = [-1.850425, 0.801375, 0.576699, -5.131880, 0.571592, 0.042388] test_list.append(turbmod_sa_comp_rae2822) # SA Edwards @@ -783,7 +799,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.004687, 0.742306, 0.497310, -5.290787, 0.809485, 0.062034] + turbmod_sa_edw_rae2822.test_vals = [-1.850407, 0.801397, 0.576716, -5.168509, 0.571594, 0.042384] test_list.append(turbmod_sa_edw_rae2822) # SA Compressibility and Edwards @@ -791,7 +807,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.004686, 0.742307, 0.497311, -5.290776, 0.809487, 0.062044] + turbmod_sa_comp_edw_rae2822.test_vals = [-1.850411, 0.801392, 0.576713, -5.168535, 0.571597, 0.042387] test_list.append(turbmod_sa_comp_edw_rae2822) # SA QCR @@ -799,7 +815,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.004794, 0.742354, 0.497315, -5.265910, 0.807835, 0.062022] + turbmod_sa_qcr_rae2822.test_vals = [-1.848614, 0.801975, 0.578549, -5.131053, 0.571093, 0.042439] test_list.append(turbmod_sa_qcr_rae2822) ############################ @@ -823,7 +839,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.662585, -14.998832, -0.726250, 0.020280] + contadj_naca0012.test_vals = [-9.583496, -15.034977, -0.726250, 0.020280] contadj_naca0012.test_vals_aarch64 = [-9.662546, -14.998818, -0.726250, 0.020280] test_list.append(contadj_naca0012) @@ -832,7 +848,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.032190, -12.587083, -1.086100, 0.007556] + contadj_oneram6.test_vals = [-11.981260, -12.515067, -1.086100, 0.007556] test_list.append(contadj_oneram6) # Inviscid WEDGE: tests averaged outflow total pressure adjoint @@ -848,7 +864,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 = [0.748407, -4.810872, -0.520110, -0.000291] + contadj_fixed_CL_naca0012.test_vals = [0.838756, -4.799730, -0.372690, -0.000630] test_list.append(contadj_fixed_CL_naca0012) ################################### @@ -860,7 +876,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.651430, -9.113079, 2.056700, -0.000000] + contadj_ns_cylinder.test_vals = [-3.600450, -9.041799, 2.056700, -0.000000] test_list.append(contadj_ns_cylinder) # Adjoint laminar naca0012 subsonic @@ -904,7 +920,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.372407, -10.874841, -0.212470, 0.005448] + contadj_rans_rae2822.test_vals = [-5.385804, -10.889762, -0.212470, 0.005448] test_list.append(contadj_rans_rae2822) ############################# @@ -916,7 +932,7 @@ def main(): turb_naca0012_1c.cfg_dir = "rans_uq/naca0012" turb_naca0012_1c.cfg_file = "turb_NACA0012_uq_1c.cfg" turb_naca0012_1c.test_iter = 10 - turb_naca0012_1c.test_vals = [-4.975127, 1.346671, 0.677571, 0.011242] + turb_naca0012_1c.test_vals = [-4.982630, 1.343638, 0.664182, 0.009490] turb_naca0012_1c.test_vals_aarch64 = [-4.981036, 1.345868, 0.673232, 0.010091] test_list.append(turb_naca0012_1c) @@ -925,7 +941,7 @@ def main(): turb_naca0012_2c.cfg_dir = "rans_uq/naca0012" turb_naca0012_2c.cfg_file = "turb_NACA0012_uq_2c.cfg" turb_naca0012_2c.test_iter = 10 - turb_naca0012_2c.test_vals = [-5.482703, 1.265040, 0.500982, -0.033411] + turb_naca0012_2c.test_vals = [-5.482693, 1.262634, 0.495712, -0.032734] turb_naca0012_2c.test_vals_aarch64 = [-5.484365, 1.264701, 0.501741, -0.033109] test_list.append(turb_naca0012_2c) @@ -934,7 +950,7 @@ def main(): turb_naca0012_3c.cfg_dir = "rans_uq/naca0012" turb_naca0012_3c.cfg_file = "turb_NACA0012_uq_3c.cfg" turb_naca0012_3c.test_iter = 10 - turb_naca0012_3c.test_vals = [-5.583618, 1.232138, 0.466795, -0.036337] + turb_naca0012_3c.test_vals = [-5.583617, 1.229594, 0.463394, -0.035393] test_list.append(turb_naca0012_3c) # NACA0012 p1c1 @@ -942,7 +958,7 @@ def main(): turb_naca0012_p1c1.cfg_dir = "rans_uq/naca0012" turb_naca0012_p1c1.cfg_file = "turb_NACA0012_uq_p1c1.cfg" turb_naca0012_p1c1.test_iter = 10 - turb_naca0012_p1c1.test_vals = [-5.129515, 1.285213, 0.811512, 0.047455] + turb_naca0012_p1c1.test_vals = [-5.129475, 1.283940, 0.807012, 0.047519] turb_naca0012_p1c1.test_vals_aarch64 = [-5.122100, 1.284478, 0.608744, -0.008593] test_list.append(turb_naca0012_p1c1) @@ -951,7 +967,7 @@ def main(): turb_naca0012_p1c2.cfg_dir = "rans_uq/naca0012" turb_naca0012_p1c2.cfg_file = "turb_NACA0012_uq_p1c2.cfg" turb_naca0012_p1c2.test_iter = 10 - turb_naca0012_p1c2.test_vals = [-5.553988, 1.236535, 0.608219, -0.008951] + turb_naca0012_p1c2.test_vals = [-5.553963, 1.234481, 0.604361, -0.008431] test_list.append(turb_naca0012_p1c2) ###################################### @@ -984,7 +1000,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 = [-2.603551, 2.924633, -0.081272, 0.002162] + rot_naca0012.test_vals = [-1.412607, 4.090722, -0.021973, 0.057457] test_list.append(rot_naca0012) # Lid-driven cavity @@ -992,7 +1008,7 @@ def main(): cavity.cfg_dir = "moving_wall/cavity" cavity.cfg_file = "lam_cavity.cfg" cavity.test_iter = 25 - cavity.test_vals = [-5.610923, -0.146741, 1.115860, 1.490430] + cavity.test_vals = [-5.450215, 0.015635, 0.011950, -9.224629] test_list.append(cavity) # Spinning cylinder @@ -1000,7 +1016,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.806025, -2.364860, 1.685247, 1.518292] + spinning_cylinder.test_vals = [-7.707122, -2.253704, 1.633997, 1.546081] test_list.append(spinning_cylinder) ###################################### @@ -1021,7 +1037,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.010773, -0.008068] + sine_gust.test_vals = [-1.977498, 3.481817, -0.010227, -0.007902] sine_gust.unsteady = True test_list.append(sine_gust) @@ -1030,7 +1046,7 @@ def main(): aeroelastic.cfg_dir = "aeroelastic" aeroelastic.cfg_file = "aeroelastic_NACA64A010.cfg" aeroelastic.test_iter = 2 - aeroelastic.test_vals = [0.075023, 0.027483, -0.001643, -0.000126] + aeroelastic.test_vals = [0.075680, 0.027563, -0.001642, -0.000127] aeroelastic.unsteady = True test_list.append(aeroelastic) @@ -1070,7 +1086,7 @@ def main(): edge_VW.cfg_dir = "nicf/edge" edge_VW.cfg_file = "edge_VW.cfg" edge_VW.test_iter = 50 - edge_VW.test_vals = [-9.057409, -2.833203, -0.000009, 0.000000] + edge_VW.test_vals = [-2.386376, 3.814463, -0.000009, 0.000000] test_list.append(edge_VW) # Rarefaction shock wave edge_PPR @@ -1078,7 +1094,7 @@ def main(): edge_PPR.cfg_dir = "nicf/edge" edge_PPR.cfg_file = "edge_PPR.cfg" edge_PPR.test_iter = 50 - edge_PPR.test_vals = [-9.781896, -3.630892, -0.000034, 0.000000] + edge_PPR.test_vals = [-12.063410, -5.872787, -0.000034, 0.000000] test_list.append(edge_PPR) # Rarefaction Q1D nozzle, include CoolProp fluid model @@ -1086,7 +1102,7 @@ def main(): coolprop_fluidModel.cfg_dir = "nicf/coolprop" coolprop_fluidModel.cfg_file = "fluidModel.cfg" coolprop_fluidModel.test_iter = 5 - coolprop_fluidModel.test_vals = [-4.665443, -0.172865, 4.497973, 0.000000, 0.000000] + coolprop_fluidModel.test_vals = [-4.666146, -0.172864, 4.492817, 0.000000, 0.000000] coolprop_fluidModel.enabled_on_cpu_arch = ["x86_64"] test_list.append(coolprop_fluidModel) @@ -1095,7 +1111,7 @@ def main(): coolprop_transportModel.cfg_dir = "nicf/coolprop" coolprop_transportModel.cfg_file = "transportModel.cfg" coolprop_transportModel.test_iter = 5 - coolprop_transportModel.test_vals = [-4.666163, -0.172865, 5.445413, 0.000000, 0.000000] + coolprop_transportModel.test_vals = [-4.667122, -0.172865, 4.687652, 0.000000, 0.000000] coolprop_transportModel.enabled_on_cpu_arch = ["x86_64"] test_list.append(coolprop_transportModel) @@ -1133,7 +1149,7 @@ def main(): axial_stage2D.cfg_dir = "turbomachinery/axial_stage_2D" axial_stage2D.cfg_file = "Axial_stage2D.cfg" axial_stage2D.test_iter = 20 - axial_stage2D.test_vals = [1.065803, 1.519598, -2.928278, 2.573906, -2.526640, 3.017138, 106370.000000, 106370.000000, 5.726800, 64.383000] + axial_stage2D.test_vals = [1.167155, 1.598851, -2.928273, 2.573908, -2.526641, 3.017138, 106370.000000, 106370.000000, 5.726800, 64.383000] test_list.append(axial_stage2D) # 2D transonic stator restart @@ -1141,7 +1157,7 @@ def main(): transonic_stator_restart.cfg_dir = "turbomachinery/transonic_stator_2D" transonic_stator_restart.cfg_file = "transonic_stator_restart.cfg" transonic_stator_restart.test_iter = 20 - transonic_stator_restart.test_vals = [-4.437809, -2.553049, -2.164729, 1.657542, -1.356823, 3.178788, -471620.000000, 94.842000, -0.040365] + transonic_stator_restart.test_vals = [-4.363703, -2.480017, -2.079311, 1.731709, -1.467573, 3.229965, -471620.000000, 94.838000, -0.046906] transonic_stator_restart.test_vals_aarch64 = [-4.437809, -2.553049, -2.164729, 1.657542, -1.356823, 3.178788, -471620.000000, 94.842000, -0.040365] test_list.append(transonic_stator_restart) @@ -1184,7 +1200,7 @@ def main(): channel_3D.cfg_dir = "sliding_interface/channel_3D" channel_3D.cfg_file = "channel_3D_WA.cfg" channel_3D.test_iter = 2 - channel_3D.test_vals = [2.000000, 0.000000, 0.629113, 0.524906, 0.422425] + channel_3D.test_vals = [2.000000, 0.000000, 0.629098, 0.524941, 0.422526] channel_3D.test_vals_aarch64 = [2.000000, 0.000000, 0.629119, 0.524959, 0.422390] channel_3D.unsteady = True channel_3D.multizone = True @@ -1225,7 +1241,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.621423, -1.660901] + bars_SST_2D.test_vals = [13.000000, -0.623154, -1.660901] bars_SST_2D.multizone = True test_list.append(bars_SST_2D) @@ -1260,21 +1276,26 @@ def main(): statbeam3d.cfg_dir = "fea_fsi/StatBeam_3d" statbeam3d.cfg_file = "configBeam_3d.cfg" statbeam3d.test_iter = 0 - statbeam3d.test_vals = [-6.058758, -5.750933, -5.892188, 110190] + statbeam3d.test_vals = [-6.047457, -5.730708, -5.926093, 110190] statbeam3d.test_vals_aarch64 = [-6.062693, -5.769132, -5.891190, 110190] - statbeam3d.command = TestCase.Command(exec = "parallel_computation_fsi.py", param = "-f") test_list.append(statbeam3d) # Static beam, 3d with coupled temperature thermal_beam_3d = TestCase('thermal_beam_3d') thermal_beam_3d.cfg_dir = "fea_fsi/ThermalBeam_3d" thermal_beam_3d.cfg_file = "configBeam_3d.cfg" - thermal_beam_3d.test_iter = 0 - thermal_beam_3d.test_vals = [-6.140220, -5.842734, -5.972391, -8.091358, 262, -8.246755, 81, -8.298569, 135620, 144.65] - thermal_beam_3d.test_vals_aarch64 = [-6.131860, -5.845164, -5.964084, -8.091358, 262, -8.244325, 81, -8.298569, 135620, 144.65] - thermal_beam_3d.command = TestCase.Command(exec = "parallel_computation_fsi.py", param = "-f") + thermal_beam_3d.test_iter = 4 + thermal_beam_3d.test_vals = [-8.147213, -7.841446, -7.904153, -13.978110, 217, -4.095071, 39, -4.072614, 136760, 75] test_list.append(thermal_beam_3d) + # Static beam, 3d with coupled temperature, nonlinear elasticity + thermal_beam_nl_3d = TestCase('thermal_beam_nl_3d') + thermal_beam_nl_3d.cfg_dir = "fea_fsi/ThermalBeam_3d" + thermal_beam_nl_3d.cfg_file = "configBeamNonlinear_3d.cfg" + thermal_beam_nl_3d.test_iter = 8 + thermal_beam_nl_3d.test_vals = [-7.564309, -2.992893, -12.242503, -14.068322, 57, -4.017665, 24, -4.204804, 138710, 75.233] + test_list.append(thermal_beam_nl_3d) + # Rotating cylinder, 3d rotating_cylinder_fea = TestCase('rotating_cylinder_fea') rotating_cylinder_fea.cfg_dir = "fea_fsi/rotating_cylinder" @@ -1292,7 +1313,7 @@ def main(): linear_plane_strain.cfg_dir = "fea_fsi/VonMissesVerif" linear_plane_strain.cfg_file = "linear_plane_strain_2d.cfg" linear_plane_strain.test_iter = 0 - linear_plane_strain.test_vals = [-6.157686, -6.051735, 0, 120140, 325, -8.105017] + linear_plane_strain.test_vals = [-6.036048, -6.001905, 0, 120140, 325, -8.025024] test_list.append(linear_plane_strain) # 2D beam in plain stress with thermal expansion. This tests fixes to the 2D von Mises stress calculation, @@ -1301,7 +1322,7 @@ def main(): nonlinear_plane_stress.cfg_dir = "fea_fsi/VonMissesVerif" nonlinear_plane_stress.cfg_file = "nonlinear_plane_stress_2d.cfg" nonlinear_plane_stress.test_iter = 19 - nonlinear_plane_stress.test_vals = [-7.433102, -3.355151, -13.983258, 162480, 43, -4.071408] + nonlinear_plane_stress.test_vals = [-7.433449, -3.355607, -13.983863, 162480, 43, -4.070373] test_list.append(nonlinear_plane_stress) # Dynamic beam, 2d @@ -1374,7 +1395,7 @@ def main(): solid_periodic_pins.cfg_dir = "solid_heat_conduction/periodic_pins" solid_periodic_pins.cfg_file = "configSolid.cfg" solid_periodic_pins.test_iter = 750 - solid_periodic_pins.test_vals = [-15.878977, -14.569206, 300.900000, 425.320000, 5.000000, -1.672737] + solid_periodic_pins.test_vals = [-15.878973, -14.569206, 300.900000, 425.320000, 5.000000, -1.672670] solid_periodic_pins.test_vals_aarch64 = [-15.879016, -14.569206, 300.900000, 425.320000, 5.000000, -1.672666] test_list.append(solid_periodic_pins) @@ -1405,7 +1426,7 @@ def main(): sp_pinArray_cht_2d_dp_hf.cfg_dir = "incomp_navierstokes/streamwise_periodic/chtPinArray_2d" sp_pinArray_cht_2d_dp_hf.cfg_file = "configMaster.cfg" sp_pinArray_cht_2d_dp_hf.test_iter = 100 - sp_pinArray_cht_2d_dp_hf.test_vals = [0.353740, 2.436726, -1.270003, -0.615079, 208.023676, 350.100000, -0.000000, -0.615080, 0.615080] + sp_pinArray_cht_2d_dp_hf.test_vals = [0.691407, 2.834803, -1.205148, -0.677171, 208.023676, 350.080000, -0.000000, -0.677170, 0.677170] sp_pinArray_cht_2d_dp_hf.multizone = True test_list.append(sp_pinArray_cht_2d_dp_hf) @@ -1414,7 +1435,7 @@ def main(): sp_pinArray_3d_cht_mf_hf_tp.cfg_dir = "incomp_navierstokes/streamwise_periodic/chtPinArray_3d" sp_pinArray_3d_cht_mf_hf_tp.cfg_file = "configMaster.cfg" sp_pinArray_3d_cht_mf_hf_tp.test_iter = 30 - sp_pinArray_3d_cht_mf_hf_tp.test_vals = [-1.279608, 3.011923, -0.641797, -0.009777, 104.609505, 410.330000, 0.000000] + sp_pinArray_3d_cht_mf_hf_tp.test_vals = [-1.116268, 3.008626, -0.634287, -0.009805, 104.600487, 410.310000, 0.000000] sp_pinArray_3d_cht_mf_hf_tp.multizone = True test_list.append(sp_pinArray_3d_cht_mf_hf_tp) @@ -1427,8 +1448,8 @@ def main(): pywrapper_naca0012 = TestCase('pywrapper_naca0012') pywrapper_naca0012.cfg_dir = "euler/naca0012" pywrapper_naca0012.cfg_file = "inv_NACA0012_Roe.cfg" - pywrapper_naca0012.test_iter = 100 - pywrapper_naca0012.test_vals = [-9.249009, -8.546597, 0.335769, 0.023275] + pywrapper_naca0012.test_iter = 80 + pywrapper_naca0012.test_vals = [-9.980225, -9.402767, 0.335769, 0.023275] pywrapper_naca0012.command = TestCase.Command("mpirun -np 2", "SU2_CFD.py", "--parallel -f") test_list.append(pywrapper_naca0012) @@ -1437,7 +1458,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.094699, -15.251093, -5.906365, 1.070413, 0.015775, -2.376178, 0.000000] + pywrapper_turb_naca0012_sst.test_vals = [-12.094714, -15.251093, -5.906365, 1.070413, 0.015775, -2.376111, 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 @@ -1458,7 +1479,7 @@ def main(): pywrapper_aeroelastic.cfg_dir = "aeroelastic" pywrapper_aeroelastic.cfg_file = "aeroelastic_NACA64A010.cfg" pywrapper_aeroelastic.test_iter = 2 - pywrapper_aeroelastic.test_vals = [0.075023, 0.027483, -0.001643, -0.000126] + pywrapper_aeroelastic.test_vals = [0.075680, 0.027563, -0.001642, -0.000127] pywrapper_aeroelastic.command = TestCase.Command("mpirun -np 2", "SU2_CFD.py", "--parallel -f") pywrapper_aeroelastic.unsteady = True test_list.append(pywrapper_aeroelastic) @@ -1468,7 +1489,7 @@ def main(): pywrapper_custom_fea_load.cfg_dir = "py_wrapper/custom_load_fea" pywrapper_custom_fea_load.cfg_file = "config.cfg" pywrapper_custom_fea_load.test_iter = 13 - pywrapper_custom_fea_load.test_vals = [-7.262040, -4.945686, -14.163208, 34, -6.009642, 362.23] + pywrapper_custom_fea_load.test_vals = [-7.262040, -4.945686, -14.163208, 34, -6.029883, 362.230000] pywrapper_custom_fea_load.command = TestCase.Command("mpirun -np 2", "python", "run.py") test_list.append(pywrapper_custom_fea_load) @@ -1499,7 +1520,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.614167, 2.264219, -0.001386, 0.172978] + pywrapper_unsteadyCHT.test_vals = [-1.614167, 2.260123, -0.002469, 0.100260] 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) @@ -1509,7 +1530,7 @@ def main(): pywrapper_rigidMotion.cfg_dir = "py_wrapper/flatPlate_rigidMotion" pywrapper_rigidMotion.cfg_file = "flatPlate_rigidMotion_Conf.cfg" pywrapper_rigidMotion.test_iter = 5 - pywrapper_rigidMotion.test_vals = [-1.614166, 2.257995, 0.350194, 0.089496] + pywrapper_rigidMotion.test_vals = [-1.614166, 2.255135, 0.350194, 0.089496] pywrapper_rigidMotion.command = TestCase.Command("mpirun -np 2", "python", "launch_flatPlate_rigidMotion.py --parallel -f") pywrapper_rigidMotion.unsteady = True test_list.append(pywrapper_rigidMotion) @@ -1519,7 +1540,7 @@ def main(): pywrapper_deformingBump.cfg_dir = "py_wrapper/deforming_bump_in_channel" pywrapper_deformingBump.cfg_file = "config.cfg" pywrapper_deformingBump.test_iter = 1 - pywrapper_deformingBump.test_vals = [0.500000, 0.000000, -2.811520, -1.603562, -2.074259, 2.424289, 7.616891, -0.205655] + pywrapper_deformingBump.test_vals = [0.500000, 0.000000, -2.556309, -1.270839, -2.350590, 2.606851, 8.002480, -0.300272] pywrapper_deformingBump.command = TestCase.Command("mpirun -np 2", "python", "run.py") pywrapper_deformingBump.unsteady = True test_list.append(pywrapper_deformingBump) @@ -1544,16 +1565,16 @@ def main(): test_list.append(pywrapper_zimont) - # Heat solver unsteady with source - pywrapper_Unst_Heat_Source = TestCase('pywrapper_Unst_Heat_Source') - pywrapper_Unst_Heat_Source.cfg_dir = "py_wrapper/custom_heat_source" - pywrapper_Unst_Heat_Source.cfg_file = "run.py" - pywrapper_Unst_Heat_Source.test_iter = 10 - pywrapper_Unst_Heat_Source.unsteady = True + # Heat solver unsteady with source + pywrapper_Unst_Heat_Source = TestCase('pywrapper_Unst_Heat_Source') + pywrapper_Unst_Heat_Source.cfg_dir = "py_wrapper/custom_heat_source" + pywrapper_Unst_Heat_Source.cfg_file = "run.py" + pywrapper_Unst_Heat_Source.test_iter = 10 + pywrapper_Unst_Heat_Source.unsteady = True pywrapper_Unst_Heat_Source.test_vals = [-5.235402, 300.010000, 300.000000] pywrapper_Unst_Heat_Source.command = TestCase.Command("mpirun -n 2", "python", "run.py") test_list.append(pywrapper_Unst_Heat_Source) - + ############################################## ### Method of Manufactured Solutions (MMS) ### ############################################## @@ -1630,7 +1651,7 @@ def main(): species2_primitiveVenturi_mixingmodel.cfg_dir = "species_transport/venturi_primitive_3species" species2_primitiveVenturi_mixingmodel.cfg_file = "species2_primitiveVenturi_mixingmodel.cfg" species2_primitiveVenturi_mixingmodel.test_iter = 50 - species2_primitiveVenturi_mixingmodel.test_vals = [ -5.737415, -4.566668, -4.671780, -5.777603, -0.066800, -5.583554, 5.000000, -1.373807, 5.000000, -4.869219, 5.000000, -1.453021, 0.000381, 0.000365, 0.000016, 0.000000] + species2_primitiveVenturi_mixingmodel.test_vals = [-5.735589, -4.564867, -4.669647, -5.794093, -0.067124, -5.583396, 5.000000, -1.375324, 5.000000, -4.869799, 5.000000, -1.453419, 0.000381, 0.000366, 0.000016, 0.000000] test_list.append(species2_primitiveVenturi_mixingmodel) # 2 species (1 eq) primitive venturi mixing using mixing model and bounded scalar transport @@ -1638,7 +1659,7 @@ def main(): species2_primitiveVenturi_mixingmodel_boundedscalar.cfg_dir = "species_transport/venturi_primitive_3species" species2_primitiveVenturi_mixingmodel_boundedscalar.cfg_file = "species2_primitiveVenturi_mixingmodel_boundedscalar.cfg" species2_primitiveVenturi_mixingmodel_boundedscalar.test_iter = 50 - species2_primitiveVenturi_mixingmodel_boundedscalar.test_vals = [-5.690396, -4.512158, -4.616488, -5.776093, -0.113176, -5.705291, 5.000000, -1.433234, 5.000000, -4.921121, 5.000000, -1.770744, 0.000318, 0.000318, 0.000000, 0.000000] + species2_primitiveVenturi_mixingmodel_boundedscalar.test_vals = [-5.689670, -4.511504, -4.615493, -5.795204, -0.113336, -5.704986, 5.000000, -1.433752, 5.000000, -4.921373, 5.000000, -1.771016, 0.000318, 0.000318, 0.000000, 0.000000] test_list.append(species2_primitiveVenturi_mixingmodel_boundedscalar) # 2 species (1 eq) primitive venturi mixing using mixing model including viscosity, thermal conductivity and inlet markers for SA turbulence model @@ -1654,7 +1675,7 @@ def main(): species2_primitiveVenturi_mixingmodel_heatcapacity_H2.cfg_dir = "species_transport/venturi_primitive_3species" species2_primitiveVenturi_mixingmodel_heatcapacity_H2.cfg_file = "species2_primitiveVenturi_mixingmodel_heatcapacity_H2.cfg" species2_primitiveVenturi_mixingmodel_heatcapacity_H2.test_iter = 50 - species2_primitiveVenturi_mixingmodel_heatcapacity_H2.test_vals = [-5.824346, -4.632948, -4.560590, -6.765715, 2.076808, -5.480881, 30.000000, -7.315121, 12.000000, -8.059064, 8.000000, -8.896288, 2.092262, 1.000000, 0.600000, 0.492262] + species2_primitiveVenturi_mixingmodel_heatcapacity_H2.test_vals = [-5.815955, -4.624944, -4.555357, -6.656244, 2.075950, -5.479969, 30.000000, -7.342937, 12.000000, -8.030131, 8.000000, -8.931183, 2.092270, 1.000000, 0.600000, 0.492270] test_list.append(species2_primitiveVenturi_mixingmodel_heatcapacity_H2) # 2 species (1 eq) primitive venturi mixing using mixing model including heat capacity and mass diffusivity NonDimensional case @@ -1662,7 +1683,7 @@ def main(): species2_primitiveVenturi_mixingmodel_heatcapacity_H2_ND.cfg_dir = "species_transport/venturi_primitive_3species" species2_primitiveVenturi_mixingmodel_heatcapacity_H2_ND.cfg_file = "species2_primitiveVenturi_mixingmodel_heatcapacity_H2_ND.cfg" species2_primitiveVenturi_mixingmodel_heatcapacity_H2_ND.test_iter = 50 - species2_primitiveVenturi_mixingmodel_heatcapacity_H2_ND.test_vals = [-5.400769, -4.916015, -4.837449, -7.711760, 1.771402, -5.087077, 10.000000, -2.744436, 3.000000, -5.095706, 5.000000, -5.856784, 2.092358, 1.000000, 0.600000, 0.492358] + species2_primitiveVenturi_mixingmodel_heatcapacity_H2_ND.test_vals = [-5.404273, -4.918833, -4.841423, -7.647725, 1.772604, -5.085765, 10.000000, -2.745490, 3.000000, -5.207707, 5.000000, -5.863162, 2.092298, 1.000000, 0.600000, 0.492298] test_list.append(species2_primitiveVenturi_mixingmodel_heatcapacity_H2_ND) # 2 species (1 eq) primitive venturi mixing using mixing model solving enthalpy equation using preconditioning + JST convective scheme @@ -1686,7 +1707,7 @@ def main(): species2_primitiveVenturi.cfg_dir = "species_transport/venturi_primitive_3species" species2_primitiveVenturi.cfg_file = "species2_primitiveVenturi.cfg" species2_primitiveVenturi.test_iter = 50 - species2_primitiveVenturi.test_vals = [-5.557355, -4.528649, -4.567282, -5.392656, -0.920718, -5.677129, 5.000000, -0.597625, 5.000000, -2.601553, 5.000000, -0.550169, 0.000035, 0.000035, 0.000000, 0.000000] + species2_primitiveVenturi.test_vals = [-5.470699, -4.435379, -4.486544, -5.327925, -0.866369, -5.623281, 5.000000, -0.557915, 5.000000, -2.599732, 5.000000, -0.536608, 0.000037, 0.000037, 0.000000, 0.000000] test_list.append(species2_primitiveVenturi) # 2 species (1 eq) primitive venturi mixing with bounded scalar transport @@ -1694,7 +1715,7 @@ def main(): species_primitiveVenturi_boundedscalar.cfg_dir = "species_transport/venturi_primitive_3species" species_primitiveVenturi_boundedscalar.cfg_file = "species2_primitiveVenturi_boundedscalar.cfg" species_primitiveVenturi_boundedscalar.test_iter = 50 - species_primitiveVenturi_boundedscalar.test_vals = [-5.539052, -4.376789, -4.477172, -5.579444, -0.871003, -5.633907, 5.000000, -1.460377, 5.000000, -4.141552, 5.000000, -1.727113, 0.000438, 0.000438, 0.000000, 0.000000] + species_primitiveVenturi_boundedscalar.test_vals = [-5.537734, -4.375388, -4.475128, -5.597904, -0.870563, -5.633513, 5.000000, -1.461524, 5.000000, -4.142508, 5.000000, -1.727874, 0.000438, 0.000438, 0.000000, 0.000000] test_list.append(species_primitiveVenturi_boundedscalar) # 2 species (1 eq) primitive venturi mixing using mixing model including inlet markers for turbulent intensity and viscosity ratios @@ -1702,7 +1723,7 @@ def main(): species2_primitiveVenturi_mixingmodel_TURBULENT_MARKERS.cfg_dir = "species_transport/venturi_primitive_3species" species2_primitiveVenturi_mixingmodel_TURBULENT_MARKERS.cfg_file = "species2_primitiveVenturi_mixingmodel_TURBULENT_MARKERS.cfg" species2_primitiveVenturi_mixingmodel_TURBULENT_MARKERS.test_iter = 50 - species2_primitiveVenturi_mixingmodel_TURBULENT_MARKERS.test_vals = [-4.782077, -1.837073, -1.862970, -0.641171, 1.349304, -3.929006, 21.000000, -5.212393, 9.000000, -5.455072, 4.000000, -5.915343, 2.000000, 1.000000, 0.000000, 1.000000] + species2_primitiveVenturi_mixingmodel_TURBULENT_MARKERS.test_vals = [-4.847447, -1.922191, -1.947568, -0.716575, 1.211626, -3.930420, 21.000000, -5.152536, 9.000000, -5.329555, 4.000000, -5.865224, 2.000000, 1.000000, 0.000000, 1.000000] test_list.append(species2_primitiveVenturi_mixingmodel_TURBULENT_MARKERS) # 3 species (2 eq) primitive venturi mixing with inlet files. @@ -1727,7 +1748,7 @@ def main(): species_passive_val.cfg_dir = "species_transport/passive_transport_validation" species_passive_val.cfg_file = "passive_transport.cfg" species_passive_val.test_iter = 50 - species_passive_val.test_vals = [-16.602539, -16.343775, -16.937083, -4.257599, 10, -4.277976, 8, -5.193350, 0.186610, 0] + species_passive_val.test_vals = [-16.590103, -16.350880, -16.915685, -4.257599, 10, -4.296538, 8, -5.193350, 0.186610, 0] species_passive_val.test_vals_aarch64 = [-16.517744, -16.282420, -16.871663, -4.257599, 10.000000, -4.278151, 8.000000, -5.193350, 0.186610, 0.000000] test_list.append(species_passive_val) diff --git a/TestCases/parallel_regression_AD.py b/TestCases/parallel_regression_AD.py index b3679519a97d..5a6bbef85a62 100644 --- a/TestCases/parallel_regression_AD.py +++ b/TestCases/parallel_regression_AD.py @@ -63,7 +63,7 @@ def main(): discadj_arina2k.cfg_dir = "disc_adj_euler/arina2k" discadj_arina2k.cfg_file = "Arina2KRS.cfg" discadj_arina2k.test_iter = 20 - discadj_arina2k.test_vals = [-3.254894, -3.550776, 0.053099, 0.000000] + discadj_arina2k.test_vals = [-3.259547, -3.544519, 0.044517, 0.000000] test_list.append(discadj_arina2k) # Equivalent area NACA64-206 @@ -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, -4.096681, -2.686537, 0.000000] + discadj_incomp_NACA0012.test_vals = [20.000000, -3.949889, -2.567232, 0.000000] test_list.append(discadj_incomp_NACA0012) ##################################### @@ -217,7 +217,8 @@ 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.226212, -1.647429, -0.007557, 0.000012] + discadj_pitchingNACA0012.test_vals = [-1.226498, -1.653107, -0.003489, -0.000000] + discadj_pitchingNACA0012.tol = 0.01 discadj_pitchingNACA0012.unsteady = True test_list.append(discadj_pitchingNACA0012) @@ -230,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, 0.667037, 0.483920, 0.518405, -1.013536] + discadj_trans_stator.test_vals = [79.000000, 0.697136, 0.459036, 0.536525, -0.995531] discadj_trans_stator.test_vals_aarch64 = [79.000000, 0.696755, 0.485950, 0.569475, -0.990065] test_list.append(discadj_trans_stator) @@ -243,10 +244,19 @@ def main(): discadj_fea.cfg_dir = "disc_adj_fea" discadj_fea.cfg_file = "configAD_fem.cfg" discadj_fea.test_iter = 4 - discadj_fea.test_vals = [-2.849453, -3.238429, -0.000364, -8.708700] #last 4 columns + discadj_fea.test_vals = [-2.849687, -3.238608, -0.000364, -8.708700] #last 4 columns discadj_fea.test_vals_aarch64 = [-2.849646, -3.238577, -0.000364, -8.708700] #last 4 columns test_list.append(discadj_fea) + # Thermoelastic problem + # Derivative of heat flux wrt Poisson's ratio (due to increase in cross section) verified via finite differences. + discadj_thermoelastic = TestCase('discadj_thermoelastic') + discadj_thermoelastic.cfg_dir = "fea_fsi/ThermalBeam_3d" + discadj_thermoelastic.cfg_file = "configBeamNonlinear_3d_ad.cfg" + discadj_thermoelastic.test_iter = 10 + discadj_thermoelastic.test_vals = [-5.355531, -5.293380, -6.164482, -6.433863, 43, -4.049760, 27, -4.164183, 0, 0.192640, 0] + test_list.append(discadj_thermoelastic) + ################################### ### Disc. adj. heat ### ################################### @@ -276,8 +286,8 @@ def main(): discadj_fsi2.cfg_dir = "disc_adj_fsi/Airfoil_2d" discadj_fsi2.cfg_file = "config.cfg" discadj_fsi2.test_iter = 8 - discadj_fsi2.test_vals = [-4.772676, 0.917733, -3.863369, 0.295450, 3.839800] - discadj_fsi2.test_vals_aarch64 = [-4.773008, 0.916312, -3.863369, 0.295450, 3.841200] + discadj_fsi2.test_vals = [-4.773024, 0.915849, -3.863369, 0.295450, 3.839800] + discadj_fsi2.test_vals_aarch64 = [-4.772641, 0.917601, -3.863369, 0.295450, 3.839800] discadj_fsi2.tol = 0.00001 test_list.append(discadj_fsi2) @@ -298,7 +308,7 @@ def main(): da_sp_pinArray_cht_2d_dp_hf.cfg_dir = "incomp_navierstokes/streamwise_periodic/chtPinArray_2d" da_sp_pinArray_cht_2d_dp_hf.cfg_file = "DA_configMaster.cfg" da_sp_pinArray_cht_2d_dp_hf.test_iter = 100 - da_sp_pinArray_cht_2d_dp_hf.test_vals = [-4.697305, -4.335384, -4.726171] + da_sp_pinArray_cht_2d_dp_hf.test_vals = [-2.687303, -3.218852, -2.653738] da_sp_pinArray_cht_2d_dp_hf.multizone = True test_list.append(da_sp_pinArray_cht_2d_dp_hf) @@ -307,7 +317,7 @@ def main(): da_sp_pinArray_cht_2d_mf.cfg_dir = "incomp_navierstokes/streamwise_periodic/dp-adjoint_chtPinArray_2d" da_sp_pinArray_cht_2d_mf.cfg_file = "configMaster.cfg" da_sp_pinArray_cht_2d_mf.test_iter = 100 - da_sp_pinArray_cht_2d_mf.test_vals = [-4.512241, -1.154741, -1.436747, 0.148439, -5.675767, -15.727696, -50.4635702] + da_sp_pinArray_cht_2d_mf.test_vals = [-4.544489, -1.200740, -1.451677, -0.809551, -5.998322, -15.723654, -49.833480] da_sp_pinArray_cht_2d_mf.multizone = True test_list.append(da_sp_pinArray_cht_2d_mf) diff --git a/TestCases/pastix_support/config.cfg b/TestCases/pastix_support/config.cfg index 83b9c95b8a95..b13c1f09e641 100644 --- a/TestCases/pastix_support/config.cfg +++ b/TestCases/pastix_support/config.cfg @@ -1,6 +1,6 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % SU2 configuration file % -% PaStiX options (http://pastix.gforge.inria.fr/files/README-txt.html) % +% PaStiX options (https://solverstack.gitlabpages.inria.fr/pastix/) % % Institution: Imperial College London % % File Version 8.4.0 "Harrier" % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/TestCases/pastix_support/readme.txt b/TestCases/pastix_support/readme.txt index 5b3d30968696..43c195c463c5 100644 --- a/TestCases/pastix_support/readme.txt +++ b/TestCases/pastix_support/readme.txt @@ -5,81 +5,43 @@ % File Version 8.4.0 "Harrier" % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% 1 - Download -% Get PaStiX 5.2.3 from https://gforge.inria.fr/frs/?group_id=186 -% Get Scotch 6.0.6 from https://gforge.inria.fr/projects/scotch -% Note: These two versions were tested on a number of platforms, some -% issues were encountered with more recent version of Scotch, and PaStiX -% 6.0.X is not compatible with SU2 as it does not support MPI yet. -% -% 2 - Build Scotch -% Extract the tarball downloaded in 1 into "externals" -% Rename the directory as "scotch" -% cd scotch/src && cp Make.inc/Makefile.inc.x86-64_pc_linux2.XXXX Makefile.inc -% (choose the XXXX that matches your compiler) -% Edit Makefile.inc and delete the cflag -DSCOTCH_PTHREAD (see why in 3-ii) -% "make ptscotch" -% -% Note: If you build SU2 (7.0.1+) with OpenMP support (-Dwith-omp=true), -% AND your system supports MPI_THREAD_MULTIPLE, you do not need to -% delete the -DSCOTCH_PTHREAD flag (but doing so does no harm). -% -% 3 - Build PaStiX -% Extract the tarball downloaded in 1 into "externals" -% Rename the directory as "pastix" -% cd pastix/src && cp config/LINUX-XXXX.in config.in -% (again choose the XXXX that matches your compiler) -% Edit config.in -% i - Uncomment the lines for "VERSIONINT = _int32" -% ii - Uncomment the lines for "VERSIONSMP = _nosmp", -% SU2 does not currently support MPI+Threads. -% iii - Set SCOTCH_HOME as SCOTCH_HOME ?= ${PWD}/../../scotch/ -% iv - Comment out the lines for "Hardware Locality", this may only be -% important for an MPI+Threads build (usually it is not). -% v - Optionally look at the BLAS section (only required by "make examples") -% "make all" -% -% Note: If you build SU2 (7.0.1+) with OpenMP support (-Dwith-omp=true), -% skip 3-ii, note however that this may not work well with SU2_CFD_AD. -% If you do use MPI+Threads, it is important for good performance that your -% system supports MPI_THREAD_MULTIPLE (SU2_CFD --thread_multiple ...) -% Furthermore, if MPI_THREAD_MULTIPLE is NOT supported, you need to -% uncomment the line with "-DPASTIX_FUNNELED" in config.in. -% Finally, if you just use threads (no MPI) this is not important. +% 1 - Build and install dependencies +% - A BLAS library with LAPACK and LAPACKE support (e.g. OpenBLAS), +% sequential versions are required (threading is managed by the solver). +% - Scotch and PT-Scotch. +% - HWLOC (recommended for PaStiX). +% If you use your OS package manager for these, the PaStiX and SU2 build +% systems should be able to find them automatically. +% If you build them from source and install in a custom location, you will +% need to use CPATH, LIBRARY_PATH, and LD_LIBRARY_PATH for the build +% systems to find them. +% +% 2 - Build PaStiX +% Get PaStiX 6.X.X from https://gitlab.inria.fr/solverstack/pastix.git +% Follow their build instructions, make sure to compile it with support +% for MPI and PT-Scotch (see the cmake flags). +% You may need to adjust the integer type from 64 to 32 bits depending +% on how your version of Scotch was built. % % 4 - Build SU2 % Follow the normal meson build instructions, add -Denable-pastix=true, % this requires you to compile with MKL (-Denable-mkl=true) or OpenBLAS % (-Denable-openblas=true) support in your call to meson.py. -% If you did not build PaStiX and Scotch in the externals folders you must -% use -Dpastix_root="some path" and -Dscotch_root="another path" to -% indicate where they are RELATIVE to the SU2 directory. -% You need sequential versions of BLAS. But when using MPI+Threads beware that -% OpenBLAS needs to have parallel support otherwise the solver will crash, if -% you get poor performance see 5.4 below. -% -% 5 - Common problems and known issues -% - OpenMPI 4 does not work with PaStiX 5, downgrade to 3.1.4. -% - Very early versions of OpenMPI 3 may have problems with MPI types. -% - OpenBLAS build fails when linking executables. Old versions (e.g. -% 0.2.18) did not provide LAPACK support, rebuild or upgrade. -% - Very bad performance with OpenBLAS on some systems (observed on Ubuntu -% 16.04) try "export OMP_NUM_THREADS=1" before running SU2, check that -% you only see N SU2 processes running at 100% (mpirun -n N SU2_XXX). -% - Cannot find BLAS dependency: -% i - On some OS the package has a different name (e.g. Ubuntu 16.04 -% blas-openblas instead of openblas), use -Dblas-name="right name" in -% call to meson.py -% ii - The name is right but meson cannot find it. Set env variable -% PKG_CONFIG_PATH=$PKG_CONFIG_PATH:"directory with someblas.pc file" -% - MKL is not in its standard directory (/opt/intel/mkl), use option -% -Dmkl_root="non standard directory" in call to meson.py (headers are -% expected in "include" and libraries in "lib/intel64"). +% The reliable way for meson to find PaStiX is use PKG_CONFIG_PATH to +% make the pastix.pc.in file discoverable. For the other dependencies, +% see #1. You should build with OpenMP to get the best performance, +% using only MPI with PaStiX is not efficient. +% +% 5 - Running SU2 +% When running with MPI + OpenMP you need to pay attention to core and +% thread binding to get the best performance. For example, to use 2 ranks +% with 8 threads each (effectively) you may need something like: +% mpirun -n 2 --map-by NUMA:PE=8 SU2_CFD -t 8 --thread_multiple config.cfg +% otherwise the MPI implementation may not let each rank use the requested +% threads, or PaStiX/HWLOC may bind the threads of different ranks to the +% same core. Different MPI versions may have other arguments. % % 6 - Tested platforms -% - Ubuntu 18.04, gcc 7.4, ompi 3.1.4, mkl 2017, openblas 0.2.20 and 0.3.2.dev -% - Ubuntu 16.04, gcc 5.4, ompi 3.1.4, mkl 2017 and 2019 -% - CentOS 7.6.1810, gcc 5.4, ompi 3.1.4, mkl 2017 -% - CentOS 7.6.1810, gcc 5.4, impi 2018, mkl 2019 -% - CentOS 7.6.1810, gcc 8.2, impi 2018, mkl 2019 +% - Ubuntu 24.04 (gcc 13), ompi 5.0.6, default OpenBLAS, Scotch, PT-Scotch, +% and HWLOC (i.e. from apt install ...). % diff --git a/TestCases/py_wrapper/translating_NACA0012/forces_0.csv.ref b/TestCases/py_wrapper/translating_NACA0012/forces_0.csv.ref index d9998aced7cb..d715ec6cdcc1 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.95, -0.00, 0.00 -0, -2.89, 19.93, 0.00 -1, -4.16, 28.63, 0.00 -2, -5.19, 35.84, 0.00 -3, -6.11, 42.27, 0.00 -4, -6.89, 47.83, 0.00 -5, -7.53, 52.42, 0.00 -6, -8.06, 56.37, 0.00 -7, -8.47, 59.49, 0.00 -8, -8.76, 61.87, 0.00 -9, -8.94, 63.52, 0.00 -10, -9.02, 64.50, 0.00 -11, -9.01, 64.87, 0.00 -12, -8.90, 64.57, 0.00 -13, -8.70, 63.67, 0.00 -14, -8.42, 62.15, 0.00 -15, -8.06, 60.06, 0.00 -16, -7.64, 57.51, 0.00 -17, -7.16, 54.41, 0.00 -18, -6.62, 50.82, 0.00 -19, -6.02, 46.77, 0.00 -20, -5.38, 42.25, 0.00 -21, -4.69, 37.33, 0.00 -22, -3.97, 31.98, 0.00 -23, -3.21, 26.23, 0.00 -24, -2.43, 20.13, 0.00 -25, -1.63, 13.66, 0.00 -26, -0.80, 6.84, 0.00 -27, 0.03, -0.29, 0.00 -28, 0.88, -7.75, 0.00 -29, 1.74, -15.50, 0.00 -30, 2.60, -23.53, 0.00 -31, 3.45, -31.83, 0.00 -32, 4.31, -40.43, 0.00 -33, 5.15, -49.28, 0.00 -34, 5.98, -58.35, 0.00 -35, 6.80, -67.68, 0.00 -36, 7.60, -77.26, 0.00 -37, 8.37, -87.01, 0.00 -38, 9.12, -97.01, 0.00 -39, 9.83, -107.21, 0.00 -40, 10.49, -117.56, 0.00 -41, 11.11, -128.08, 0.00 -42, 11.69, -138.80, 0.00 -43, 12.20, -149.69, 0.00 -44, 12.65, -160.70, 0.00 -45, 13.03, -171.78, 0.00 -46, 13.32, -182.92, 0.00 -47, 13.52, -194.12, 0.00 -48, 13.61, -205.31, 0.00 -49, 13.60, -216.52, 0.00 -50, 13.47, -227.51, 0.00 -51, 13.18, -238.10, 0.00 -52, 12.75, -248.28, 0.00 -53, 12.23, -259.17, 0.00 -54, 11.51, -269.17, 0.00 -55, 10.25, -268.73, 0.00 -56, 8.38, -251.80, 0.00 -57, 7.08, -251.06, 0.00 -58, 7.58, -331.40, 0.00 -59, 7.34, -425.09, 0.00 -60, 5.05, -443.58, 0.00 -61, 2.27, -434.14, 0.00 -62, -0.52, -424.59, 0.00 -63, -3.33, -414.88, 0.00 -64, -6.11, -403.87, 0.00 -65, -8.85, -391.44, 0.00 -66, -11.50, -377.71, 0.00 -67, -14.04, -363.05, 0.00 -68, -16.44, -347.37, 0.00 -69, -18.68, -330.91, 0.00 -70, -20.72, -313.80, 0.00 -71, -22.54, -296.04, 0.00 -72, -24.12, -277.82, 0.00 -73, -25.43, -259.16, 0.00 -74, -26.46, -240.22, 0.00 -75, -27.16, -221.02, 0.00 -76, -27.48, -201.33, 0.00 -77, -27.42, -181.48, 0.00 -78, -26.96, -161.64, 0.00 -79, -26.03, -141.69, 0.00 -80, -24.63, -121.84, 0.00 -81, -22.68, -102.06, 0.00 -82, -20.15, -82.45, 0.00 -83, -16.97, -63.10, 0.00 -84, -13.07, -44.09, 0.00 -85, -8.36, -25.53, 0.00 -86, -2.73, -7.52, 0.00 -87, 3.97, 9.81, 0.00 -88, 11.89, 26.25, 0.00 -89, 21.22, 41.51, 0.00 -90, 32.12, 55.12, 0.00 -91, 44.88, 66.72, 0.00 -92, 59.51, 75.37, 0.00 -93, 76.12, 80.27, 0.00 -94, 94.45, 80.24, 0.00 -95, 113.03, 73.62, 0.00 -96, 129.92, 59.55, 0.00 -97, 142.64, 38.61, 0.00 -98, 108.56, 14.57, 0.00 -99, 69.98, -0.00, 0.00 -100, 103.93, -13.95, 0.00 -101, 125.25, -33.90, 0.00 -102, 102.02, -46.76, 0.00 -103, 77.51, -50.49, 0.00 -104, 53.83, -45.73, 0.00 -105, 32.59, -34.37, 0.00 -106, 14.60, -18.48, 0.00 -107, -0.30, 0.44, 0.00 -108, -12.53, 21.51, 0.00 -109, -22.47, 43.94, 0.00 -110, -30.49, 67.29, 0.00 -111, -36.85, 91.11, 0.00 -112, -41.91, 115.39, 0.00 -113, -45.81, 139.82, 0.00 -114, -48.77, 164.48, 0.00 -115, -50.93, 189.36, 0.00 -116, -52.38, 214.32, 0.00 -117, -53.20, 239.37, 0.00 -118, -53.43, 264.32, 0.00 -119, -53.12, 289.11, 0.00 -120, -52.35, 313.88, 0.00 -121, -51.12, 338.31, 0.00 -122, -49.52, 362.75, 0.00 -123, -47.56, 387.00, 0.00 -124, -45.22, 410.58, 0.00 -125, -42.59, 434.00, 0.00 -126, -39.71, 457.30, 0.00 -127, -36.56, 480.08, 0.00 -128, -33.16, 502.25, 0.00 -129, -29.56, 523.72, 0.00 -130, -25.78, 544.66, 0.00 -131, -21.86, 565.07, 0.00 -132, -17.80, 584.72, 0.00 -133, -13.65, 603.83, 0.00 -134, -9.41, 621.93, 0.00 -135, -5.12, 639.20, 0.00 -136, -0.81, 656.06, 0.00 -137, 3.51, 671.80, 0.00 -138, 7.82, 686.38, 0.00 -139, 12.10, 700.45, 0.00 -140, 16.32, 713.56, 0.00 -141, 20.46, 725.19, 0.00 -142, 24.51, 736.06, 0.00 -143, 28.46, 746.15, 0.00 -144, 32.29, 754.94, 0.00 -145, 35.97, 762.42, 0.00 -146, 39.51, 769.08, 0.00 -147, 42.90, 774.72, 0.00 -148, 46.11, 779.11, 0.00 -149, 49.18, 782.75, 0.00 -150, 52.06, 785.17, 0.00 -151, 54.77, 786.61, 0.00 -152, 57.30, 787.12, 0.00 -153, 59.67, 786.85, 0.00 -154, 61.83, 785.26, 0.00 -155, 63.48, 778.68, 0.00 -156, 67.01, 795.78, 0.00 -157, 59.18, 681.93, 0.00 -158, 2.62, 29.33, 0.00 -159, -2.31, -25.18, 0.00 -160, 0.55, 5.86, 0.00 -161, 0.34, 3.53, 0.00 -162, 0.33, 3.30, 0.00 -163, 0.29, 2.87, 0.00 -164, 0.12, 1.20, 0.00 -165, -0.13, -1.27, 0.00 -166, -0.46, -4.36, 0.00 -167, -0.86, -7.92, 0.00 -168, -1.30, -11.82, 0.00 -169, -1.79, -15.99, 0.00 -170, -2.32, -20.31, 0.00 -171, -2.86, -24.72, 0.00 -172, -3.42, -29.14, 0.00 -173, -4.00, -33.56, 0.00 -174, -4.58, -37.85, 0.00 -175, -5.15, -41.99, 0.00 -176, -5.71, -46.00, 0.00 -177, -6.25, -49.75, 0.00 -178, -6.77, -53.23, 0.00 -179, -7.26, -56.43, 0.00 -180, -7.72, -59.27, 0.00 -181, -8.13, -61.77, 0.00 -182, -8.49, -63.87, 0.00 -183, -8.79, -65.51, 0.00 -184, -9.04, -66.76, 0.00 -185, -9.23, -67.51, 0.00 -186, -9.33, -67.71, 0.00 -187, -9.36, -67.37, 0.00 -188, -9.29, -66.42, 0.00 -189, -9.14, -64.91, 0.00 -190, -8.89, -62.78, 0.00 -191, -8.54, -59.98, 0.00 -192, -8.08, -56.48, 0.00 -193, -7.50, -52.21, 0.00 -194, -6.82, -47.34, 0.00 -195, -6.01, -41.55, 0.00 -196, -5.06, -34.95, 0.00 -197, -4.01, -27.61, 0.00 -198, -2.73, -18.81, 0.00 +199, -0.86, -0.00, 0.00 +0, -2.65, 18.23, 0.00 +1, -3.76, 25.89, 0.00 +2, -4.65, 32.09, 0.00 +3, -5.46, 37.74, 0.00 +4, -6.13, 42.56, 0.00 +5, -6.71, 46.69, 0.00 +6, -7.16, 50.07, 0.00 +7, -7.53, 52.90, 0.00 +8, -7.76, 54.82, 0.00 +9, -7.90, 56.13, 0.00 +10, -7.93, 56.70, 0.00 +11, -7.90, 56.91, 0.00 +12, -7.75, 56.22, 0.00 +13, -7.57, 55.39, 0.00 +14, -7.26, 53.59, 0.00 +15, -6.89, 51.30, 0.00 +16, -6.44, 48.47, 0.00 +17, -5.99, 45.51, 0.00 +18, -5.40, 41.51, 0.00 +19, -4.79, 37.20, 0.00 +20, -4.13, 32.43, 0.00 +21, -3.45, 27.41, 0.00 +22, -2.67, 21.54, 0.00 +23, -1.89, 15.41, 0.00 +24, -1.09, 9.05, 0.00 +25, -0.31, 2.56, 0.00 +26, 0.57, -4.88, 0.00 +27, 1.43, -12.39, 0.00 +28, 2.29, -20.08, 0.00 +29, 3.06, -27.24, 0.00 +30, 3.89, -35.25, 0.00 +31, 4.75, -43.77, 0.00 +32, 5.63, -52.86, 0.00 +33, 6.43, -61.46, 0.00 +34, 7.32, -71.39, 0.00 +35, 8.22, -81.78, 0.00 +36, 9.08, -92.31, 0.00 +37, 9.89, -102.78, 0.00 +38, 10.69, -113.72, 0.00 +39, 11.47, -125.13, 0.00 +40, 12.18, -136.48, 0.00 +41, 12.94, -149.09, 0.00 +42, 13.63, -161.87, 0.00 +43, 14.33, -175.75, 0.00 +44, 14.84, -188.45, 0.00 +45, 15.37, -202.73, 0.00 +46, 15.64, -214.91, 0.00 +47, 16.02, -230.07, 0.00 +48, 16.07, -242.38, 0.00 +49, 16.04, -255.31, 0.00 +50, 15.75, -266.07, 0.00 +51, 15.41, -278.35, 0.00 +52, 14.99, -291.85, 0.00 +53, 14.69, -311.51, 0.00 +54, 14.03, -328.05, 0.00 +55, 13.22, -346.63, 0.00 +56, 11.58, -347.88, 0.00 +57, 9.48, -336.06, 0.00 +58, 7.63, -333.70, 0.00 +59, 6.69, -387.45, 0.00 +60, 5.25, -460.90, 0.00 +61, 2.49, -475.82, 0.00 +62, -0.58, -468.44, 0.00 +63, -3.64, -454.65, 0.00 +64, -6.73, -444.52, 0.00 +65, -9.62, -425.48, 0.00 +66, -12.57, -412.95, 0.00 +67, -15.42, -398.58, 0.00 +68, -18.20, -384.41, 0.00 +69, -20.74, -367.51, 0.00 +70, -23.30, -352.80, 0.00 +71, -25.57, -335.76, 0.00 +72, -27.15, -312.68, 0.00 +73, -28.23, -287.64, 0.00 +74, -30.47, -276.68, 0.00 +75, -32.56, -264.93, 0.00 +76, -32.95, -241.41, 0.00 +77, -33.96, -224.77, 0.00 +78, -35.35, -211.94, 0.00 +79, -35.57, -193.60, 0.00 +80, -33.74, -166.92, 0.00 +81, -37.96, -170.78, 0.00 +82, -35.41, -144.86, 0.00 +83, -35.53, -132.10, 0.00 +84, -30.07, -101.42, 0.00 +85, -26.51, -80.93, 0.00 +86, -20.60, -56.73, 0.00 +87, -16.53, -40.87, 0.00 +88, -10.32, -22.78, 0.00 +89, -1.78, -3.49, 0.00 +90, 5.56, 9.54, 0.00 +91, 13.08, 19.45, 0.00 +92, 20.82, 26.37, 0.00 +93, 41.34, 43.59, 0.00 +94, 56.70, 48.17, 0.00 +95, 86.67, 56.45, 0.00 +96, 94.24, 43.20, 0.00 +97, 124.52, 33.70, 0.00 +98, 95.89, 12.87, 0.00 +99, 56.96, -0.00, 0.00 +100, 87.55, -11.75, 0.00 +101, 76.99, -20.84, 0.00 +102, 46.64, -21.38, 0.00 +103, 27.47, -17.89, 0.00 +104, 9.68, -8.22, 0.00 +105, -19.36, 20.42, 0.00 +106, -24.54, 31.07, 0.00 +107, -36.12, 53.70, 0.00 +108, -39.92, 68.49, 0.00 +109, -46.04, 90.04, 0.00 +110, -50.48, 111.42, 0.00 +111, -53.58, 132.47, 0.00 +112, -55.98, 154.13, 0.00 +113, -58.11, 177.39, 0.00 +114, -61.20, 206.40, 0.00 +115, -62.47, 232.26, 0.00 +116, -62.39, 255.28, 0.00 +117, -62.07, 279.29, 0.00 +118, -61.73, 305.38, 0.00 +119, -60.90, 331.50, 0.00 +120, -59.52, 356.86, 0.00 +121, -57.20, 378.58, 0.00 +122, -54.90, 402.16, 0.00 +123, -52.07, 423.70, 0.00 +124, -49.20, 446.69, 0.00 +125, -45.88, 467.53, 0.00 +126, -42.63, 490.92, 0.00 +127, -39.04, 512.69, 0.00 +128, -35.26, 534.03, 0.00 +129, -31.36, 555.63, 0.00 +130, -27.27, 576.05, 0.00 +131, -23.01, 594.86, 0.00 +132, -18.68, 613.47, 0.00 +133, -14.28, 631.83, 0.00 +134, -9.82, 648.99, 0.00 +135, -5.33, 665.19, 0.00 +136, -0.84, 680.91, 0.00 +137, 3.65, 697.90, 0.00 +138, 8.11, 711.95, 0.00 +139, 12.54, 725.96, 0.00 +140, 16.89, 738.46, 0.00 +141, 21.14, 749.55, 0.00 +142, 25.30, 759.68, 0.00 +143, 29.32, 768.68, 0.00 +144, 33.23, 776.92, 0.00 +145, 37.07, 785.93, 0.00 +146, 40.69, 791.99, 0.00 +147, 44.12, 796.75, 0.00 +148, 47.39, 800.59, 0.00 +149, 50.60, 805.39, 0.00 +150, 53.53, 807.33, 0.00 +151, 56.24, 807.80, 0.00 +152, 58.72, 806.69, 0.00 +153, 61.82, 815.20, 0.00 +154, 64.19, 815.25, 0.00 +155, 67.21, 824.40, 0.00 +156, 71.43, 848.24, 0.00 +157, 39.92, 460.00, 0.00 +158, 4.29, 48.09, 0.00 +159, 17.77, 193.92, 0.00 +160, 21.23, 225.97, 0.00 +161, 10.74, 111.65, 0.00 +162, 9.33, 94.79, 0.00 +163, 6.98, 69.42, 0.00 +164, 6.08, 59.32, 0.00 +165, 4.35, 41.60, 0.00 +166, 3.64, 34.13, 0.00 +167, 2.62, 24.13, 0.00 +168, 1.95, 17.64, 0.00 +169, 1.16, 10.32, 0.00 +170, 0.46, 4.05, 0.00 +171, -0.36, -3.14, 0.00 +172, -1.08, -9.18, 0.00 +173, -1.74, -14.63, 0.00 +174, -2.38, -19.72, 0.00 +175, -3.04, -24.84, 0.00 +176, -3.71, -29.86, 0.00 +177, -4.30, -34.19, 0.00 +178, -4.90, -38.47, 0.00 +179, -5.43, -42.17, 0.00 +180, -5.99, -46.01, 0.00 +181, -6.42, -48.81, 0.00 +182, -6.86, -51.59, 0.00 +183, -7.19, -53.60, 0.00 +184, -7.54, -55.68, 0.00 +185, -7.71, -56.39, 0.00 +186, -7.94, -57.63, 0.00 +187, -7.98, -57.50, 0.00 +188, -8.00, -57.19, 0.00 +189, -7.94, -56.41, 0.00 +190, -7.77, -54.88, 0.00 +191, -7.47, -52.50, 0.00 +192, -7.09, -49.57, 0.00 +193, -6.59, -45.88, 0.00 +194, -6.01, -41.72, 0.00 +195, -5.29, -36.63, 0.00 +196, -4.48, -30.94, 0.00 +197, -3.58, -24.65, 0.00 +198, -2.49, -17.12, 0.00 diff --git a/TestCases/py_wrapper/translating_NACA0012/run_su2.py b/TestCases/py_wrapper/translating_NACA0012/run_su2.py index f6fffc21c550..27ea2b880fcb 100644 --- a/TestCases/py_wrapper/translating_NACA0012/run_su2.py +++ b/TestCases/py_wrapper/translating_NACA0012/run_su2.py @@ -27,10 +27,14 @@ def run_solver(self): self.comm.barrier() # run solver self.FluidSolver.Preprocess(0) + self.comm.barrier() self.FluidSolver.Run() + self.comm.barrier() self.FluidSolver.Postprocess() + self.comm.barrier() # write outputs self.FluidSolver.Monitor(0) + self.comm.barrier() self.FluidSolver.Output(0) self.comm.barrier() diff --git a/TestCases/py_wrapper/updated_moving_frame_NACA12/config.cfg b/TestCases/py_wrapper/updated_moving_frame_NACA12/config.cfg index 7417a173e403..5806f25e7d0a 100644 --- a/TestCases/py_wrapper/updated_moving_frame_NACA12/config.cfg +++ b/TestCases/py_wrapper/updated_moving_frame_NACA12/config.cfg @@ -50,16 +50,16 @@ VENKAT_LIMITER_COEFF= 0.1 % SOLUTION ACCELERATION % -CFL_NUMBER= 1e3 +CFL_NUMBER= 100 CFL_ADAPT= NO % MGLEVEL= 3 MGCYCLE= V_CYCLE MG_PRE_SMOOTH= ( 1, 2, 3, 3 ) -MG_POST_SMOOTH= ( 0, 0, 0, 0 ) -MG_CORRECTION_SMOOTH= ( 0, 0, 0, 0 ) -MG_DAMP_RESTRICTION= 0.7 -MG_DAMP_PROLONGATION= 0.7 +MG_POST_SMOOTH= ( 1, 1, 1, 1 ) +MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) +MG_DAMP_RESTRICTION= 0.5 +MG_DAMP_PROLONGATION= 0.5 % LINEAR_SOLVER= FGMRES LINEAR_SOLVER_PREC= ILU 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 4eacedc90eff..4e95fa24a0e5 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.96, -0.00, 0.00 -0, -2.92, 20.12, 0.00 -1, -4.12, 28.38, 0.00 -2, -5.19, 35.79, 0.00 -3, -6.11, 42.26, 0.00 -4, -6.91, 47.93, 0.00 -5, -7.55, 52.59, 0.00 -6, -8.09, 56.59, 0.00 -7, -8.51, 59.77, 0.00 -8, -8.81, 62.19, 0.00 -9, -8.99, 63.88, 0.00 -10, -9.08, 64.90, 0.00 -11, -9.07, 65.31, 0.00 -12, -8.96, 65.04, 0.00 -13, -8.77, 64.16, 0.00 -14, -8.49, 62.66, 0.00 -15, -8.13, 60.58, 0.00 -16, -7.71, 58.02, 0.00 -17, -7.23, 54.91, 0.00 -18, -6.68, 51.30, 0.00 -19, -6.08, 47.23, 0.00 -20, -5.43, 42.67, 0.00 -21, -4.74, 37.69, 0.00 -22, -4.01, 32.30, 0.00 -23, -3.24, 26.47, 0.00 -24, -2.46, 20.31, 0.00 -25, -1.64, 13.76, 0.00 -26, -0.81, 6.86, 0.00 -27, 0.04, -0.35, 0.00 -28, 0.90, -7.89, 0.00 -29, 1.76, -15.72, 0.00 -30, 2.63, -23.81, 0.00 -31, 3.49, -32.17, 0.00 -32, 4.35, -40.81, 0.00 -33, 5.19, -49.67, 0.00 -34, 6.02, -58.71, 0.00 -35, 6.83, -67.98, 0.00 -36, 7.62, -77.42, 0.00 -37, 8.37, -86.96, 0.00 -38, 9.08, -96.64, 0.00 -39, 9.75, -106.37, 0.00 -40, 10.36, -116.07, 0.00 -41, 10.91, -125.70, 0.00 -42, 11.38, -135.20, 0.00 -43, 11.77, -144.41, 0.00 -44, 12.06, -153.14, 0.00 -45, 12.22, -161.12, 0.00 -46, 12.23, -168.00, 0.00 -47, 12.04, -172.93, 0.00 -48, 11.64, -175.62, 0.00 -49, 11.16, -177.56, 0.00 -50, 10.14, -171.34, 0.00 -51, 7.30, -131.80, 0.00 -52, 6.53, -127.05, 0.00 -53, 19.34, -410.00, 0.00 -54, 25.58, -598.18, 0.00 -55, 21.94, -575.15, 0.00 -56, 18.63, -559.59, 0.00 -57, 15.63, -554.21, 0.00 -58, 12.51, -546.77, 0.00 -59, 9.28, -537.48, 0.00 -60, 6.01, -527.06, 0.00 -61, 2.70, -515.82, 0.00 -62, -0.62, -503.27, 0.00 -63, -3.92, -489.49, 0.00 -64, -7.19, -475.06, 0.00 -65, -10.39, -459.70, 0.00 -66, -13.50, -443.27, 0.00 -67, -16.48, -426.16, 0.00 -68, -19.32, -408.24, 0.00 -69, -22.00, -389.76, 0.00 -70, -24.49, -370.83, 0.00 -71, -26.76, -351.38, 0.00 -72, -28.78, -331.47, 0.00 -73, -30.53, -311.04, 0.00 -74, -31.98, -290.35, 0.00 -75, -33.11, -269.46, 0.00 -76, -33.87, -248.14, 0.00 -77, -34.25, -226.70, 0.00 -78, -34.24, -205.31, 0.00 -79, -33.76, -183.76, 0.00 -80, -32.81, -162.32, 0.00 -81, -31.32, -140.93, 0.00 -82, -29.24, -119.65, 0.00 -83, -26.52, -98.60, 0.00 -84, -23.07, -77.82, 0.00 -85, -18.81, -57.42, 0.00 -86, -13.61, -37.46, 0.00 -87, -7.31, -18.07, 0.00 -88, 0.25, 0.55, 0.00 -89, 9.28, 18.15, 0.00 -90, 20.00, 34.31, 0.00 -91, 32.69, 48.60, 0.00 -92, 47.51, 60.17, 0.00 -93, 64.67, 68.19, 0.00 -94, 84.00, 71.35, 0.00 -95, 104.26, 67.91, 0.00 -96, 123.59, 56.65, 0.00 -97, 139.79, 37.83, 0.00 -98, 109.03, 14.63, 0.00 -99, 71.37, -0.00, 0.00 -100, 106.71, -14.32, 0.00 -101, 131.85, -35.68, 0.00 -102, 110.88, -50.82, 0.00 -103, 88.07, -57.36, 0.00 -104, 65.47, -55.62, 0.00 -105, 44.83, -47.26, 0.00 -106, 27.03, -34.23, 0.00 -107, 12.07, -17.95, 0.00 -108, -0.39, 0.67, 0.00 -109, -10.68, 20.88, 0.00 -110, -19.12, 42.19, 0.00 -111, -25.97, 64.20, 0.00 -112, -31.53, 86.81, 0.00 -113, -35.96, 109.75, 0.00 -114, -39.44, 133.01, 0.00 -115, -42.10, 156.51, 0.00 -116, -44.03, 180.14, 0.00 -117, -45.33, 203.94, 0.00 -118, -46.04, 227.76, 0.00 -119, -46.21, 251.54, 0.00 -120, -45.93, 275.39, 0.00 -121, -45.17, 298.97, 0.00 -122, -44.03, 322.56, 0.00 -123, -42.51, 345.93, 0.00 -124, -40.61, 368.71, 0.00 -125, -38.41, 391.41, 0.00 -126, -35.95, 414.07, 0.00 -127, -33.22, 436.26, 0.00 -128, -30.23, 457.86, 0.00 -129, -27.02, 478.79, 0.00 -130, -23.63, 499.23, 0.00 -131, -20.08, 519.16, 0.00 -132, -16.39, 538.35, 0.00 -133, -12.59, 557.00, 0.00 -134, -8.70, 574.66, 0.00 -135, -4.74, 591.49, 0.00 -136, -0.75, 607.88, 0.00 -137, 3.26, 623.17, 0.00 -138, 7.26, 637.30, 0.00 -139, 11.24, 650.91, 0.00 -140, 15.18, 663.54, 0.00 -141, 19.03, 674.74, 0.00 -142, 22.82, 685.17, 0.00 -143, 26.50, 694.80, 0.00 -144, 30.07, 703.15, 0.00 -145, 33.50, 710.22, 0.00 -146, 36.80, 716.44, 0.00 -147, 39.96, 721.63, 0.00 -148, 42.95, 725.58, 0.00 -149, 45.78, 728.71, 0.00 -150, 48.38, 729.69, 0.00 -151, 50.59, 726.67, 0.00 -152, 54.68, 751.14, 0.00 -153, 51.25, 675.81, 0.00 -154, 6.97, 88.47, 0.00 -155, -0.21, -2.53, 0.00 -156, 3.40, 40.39, 0.00 -157, 3.83, 44.10, 0.00 -158, 4.05, 45.38, 0.00 -159, 4.28, 46.69, 0.00 -160, 4.30, 45.78, 0.00 -161, 4.17, 43.39, 0.00 -162, 3.93, 39.96, 0.00 -163, 3.59, 35.69, 0.00 -164, 3.16, 30.80, 0.00 -165, 2.66, 25.45, 0.00 -166, 2.10, 19.75, 0.00 -167, 1.50, 13.82, 0.00 -168, 0.86, 7.76, 0.00 -169, 0.18, 1.63, 0.00 -170, -0.51, -4.49, 0.00 -171, -1.22, -10.54, 0.00 -172, -1.93, -16.46, 0.00 -173, -2.65, -22.24, 0.00 -174, -3.36, -27.80, 0.00 -175, -4.05, -33.09, 0.00 -176, -4.73, -38.14, 0.00 -177, -5.39, -42.85, 0.00 -178, -6.01, -47.20, 0.00 -179, -6.59, -51.20, 0.00 -180, -7.13, -54.76, 0.00 -181, -7.62, -57.91, 0.00 -182, -8.06, -60.60, 0.00 -183, -8.43, -62.77, 0.00 -184, -8.74, -64.50, 0.00 -185, -8.98, -65.68, 0.00 -186, -9.13, -66.26, 0.00 -187, -9.20, -66.26, 0.00 -188, -9.17, -65.60, 0.00 -189, -9.06, -64.36, 0.00 -190, -8.84, -62.46, 0.00 -191, -8.52, -59.85, 0.00 -192, -8.08, -56.52, 0.00 -193, -7.52, -52.37, 0.00 -194, -6.86, -47.59, 0.00 -195, -6.05, -41.82, 0.00 -196, -5.11, -35.27, 0.00 -197, -4.04, -27.82, 0.00 -198, -2.82, -19.44, 0.00 +199, -0.86, -0.00, 0.00 +0, -2.63, 18.11, 0.00 +1, -3.63, 25.00, 0.00 +2, -4.49, 31.01, 0.00 +3, -5.27, 36.45, 0.00 +4, -5.94, 41.20, 0.00 +5, -6.49, 45.19, 0.00 +6, -6.94, 48.51, 0.00 +7, -7.30, 51.25, 0.00 +8, -7.53, 53.19, 0.00 +9, -7.69, 54.61, 0.00 +10, -7.73, 55.29, 0.00 +11, -7.72, 55.60, 0.00 +12, -7.59, 55.07, 0.00 +13, -7.40, 54.17, 0.00 +14, -7.11, 52.49, 0.00 +15, -6.79, 50.55, 0.00 +16, -6.37, 47.90, 0.00 +17, -5.91, 44.92, 0.00 +18, -5.36, 41.14, 0.00 +19, -4.80, 37.28, 0.00 +20, -4.15, 32.62, 0.00 +21, -3.50, 27.86, 0.00 +22, -2.78, 22.37, 0.00 +23, -2.06, 16.81, 0.00 +24, -1.27, 10.52, 0.00 +25, -0.50, 4.21, 0.00 +26, 0.33, -2.80, 0.00 +27, 1.15, -9.97, 0.00 +28, 2.04, -17.86, 0.00 +29, 2.85, -25.42, 0.00 +30, 3.69, -33.44, 0.00 +31, 4.48, -41.33, 0.00 +32, 5.36, -50.31, 0.00 +33, 6.18, -59.06, 0.00 +34, 7.05, -68.72, 0.00 +35, 7.84, -78.03, 0.00 +36, 8.69, -88.33, 0.00 +37, 9.43, -98.01, 0.00 +38, 10.23, -108.84, 0.00 +39, 10.92, -119.14, 0.00 +40, 11.63, -130.32, 0.00 +41, 12.28, -141.50, 0.00 +42, 12.91, -153.33, 0.00 +43, 13.43, -164.72, 0.00 +44, 13.81, -175.34, 0.00 +45, 14.01, -184.69, 0.00 +46, 14.17, -194.64, 0.00 +47, 14.35, -206.11, 0.00 +48, 14.35, -216.45, 0.00 +49, 14.66, -233.35, 0.00 +50, 14.44, -243.91, 0.00 +51, 13.23, -239.01, 0.00 +52, 9.28, -180.73, 0.00 +53, 10.93, -231.67, 0.00 +54, 22.42, -524.14, 0.00 +55, 23.41, -613.61, 0.00 +56, 19.80, -594.50, 0.00 +57, 16.27, -576.89, 0.00 +58, 13.02, -569.14, 0.00 +59, 9.66, -559.58, 0.00 +60, 6.26, -549.57, 0.00 +61, 2.81, -536.89, 0.00 +62, -0.65, -524.68, 0.00 +63, -4.08, -509.47, 0.00 +64, -7.50, -495.51, 0.00 +65, -10.82, -478.63, 0.00 +66, -14.09, -462.77, 0.00 +67, -17.20, -444.59, 0.00 +68, -20.22, -427.15, 0.00 +69, -22.98, -407.10, 0.00 +70, -25.67, -388.75, 0.00 +71, -27.98, -367.48, 0.00 +72, -30.23, -348.11, 0.00 +73, -31.93, -325.35, 0.00 +74, -33.71, -306.06, 0.00 +75, -34.92, -284.17, 0.00 +76, -36.03, -263.97, 0.00 +77, -36.59, -242.17, 0.00 +78, -37.19, -222.97, 0.00 +79, -36.76, -200.07, 0.00 +80, -36.54, -180.76, 0.00 +81, -35.69, -160.58, 0.00 +82, -34.73, -142.08, 0.00 +83, -32.59, -121.17, 0.00 +84, -30.29, -102.16, 0.00 +85, -26.60, -81.19, 0.00 +86, -22.96, -63.22, 0.00 +87, -15.77, -38.98, 0.00 +88, -10.68, -23.57, 0.00 +89, -2.62, -5.11, 0.00 +90, 2.96, 5.08, 0.00 +91, 10.30, 15.31, 0.00 +92, 19.77, 25.04, 0.00 +93, 17.81, 18.78, 0.00 +94, 23.65, 20.09, 0.00 +95, 12.09, 7.87, 0.00 +96, 11.10, 5.09, 0.00 +97, 33.12, 8.96, 0.00 +98, 30.07, 4.03, 0.00 +99, 6.42, -0.00, 0.00 +100, 26.15, -3.51, 0.00 +101, 36.45, -9.86, 0.00 +102, 30.00, -13.75, 0.00 +103, 31.67, -20.63, 0.00 +104, 13.92, -11.83, 0.00 +105, 11.86, -12.50, 0.00 +106, -3.05, 3.86, 0.00 +107, -9.48, 14.09, 0.00 +108, -15.43, 26.47, 0.00 +109, -23.77, 46.48, 0.00 +110, -29.37, 64.83, 0.00 +111, -36.14, 89.36, 0.00 +112, -39.14, 107.77, 0.00 +113, -43.76, 133.57, 0.00 +114, -46.73, 157.62, 0.00 +115, -48.66, 180.91, 0.00 +116, -49.42, 202.21, 0.00 +117, -50.43, 226.88, 0.00 +118, -50.47, 249.70, 0.00 +119, -50.38, 274.24, 0.00 +120, -49.39, 296.15, 0.00 +121, -48.36, 320.09, 0.00 +122, -46.69, 342.06, 0.00 +123, -44.98, 365.99, 0.00 +124, -42.69, 387.65, 0.00 +125, -40.38, 411.42, 0.00 +126, -37.70, 434.15, 0.00 +127, -34.80, 457.05, 0.00 +128, -31.59, 478.33, 0.00 +129, -28.21, 499.82, 0.00 +130, -24.60, 519.72, 0.00 +131, -20.90, 540.34, 0.00 +132, -17.01, 558.78, 0.00 +133, -13.08, 578.82, 0.00 +134, -9.02, 595.64, 0.00 +135, -4.92, 613.62, 0.00 +136, -0.78, 629.39, 0.00 +137, 3.38, 645.30, 0.00 +138, 7.51, 658.91, 0.00 +139, 11.63, 673.17, 0.00 +140, 15.67, 685.03, 0.00 +141, 19.64, 696.34, 0.00 +142, 23.51, 705.94, 0.00 +143, 27.29, 715.50, 0.00 +144, 30.93, 723.09, 0.00 +145, 34.51, 731.63, 0.00 +146, 37.87, 737.15, 0.00 +147, 41.12, 742.64, 0.00 +148, 44.13, 745.57, 0.00 +149, 47.11, 749.74, 0.00 +150, 49.67, 749.17, 0.00 +151, 52.81, 758.54, 0.00 +152, 56.11, 770.82, 0.00 +153, 31.65, 417.42, 0.00 +154, 3.15, 40.06, 0.00 +155, 10.66, 130.75, 0.00 +156, 12.98, 154.17, 0.00 +157, 9.56, 110.13, 0.00 +158, 8.57, 96.03, 0.00 +159, 7.81, 85.17, 0.00 +160, 7.42, 78.98, 0.00 +161, 6.93, 72.03, 0.00 +162, 6.41, 65.19, 0.00 +163, 5.87, 58.43, 0.00 +164, 5.27, 51.40, 0.00 +165, 4.67, 44.62, 0.00 +166, 3.99, 37.44, 0.00 +167, 3.31, 30.56, 0.00 +168, 2.58, 23.38, 0.00 +169, 1.85, 16.52, 0.00 +170, 1.09, 9.54, 0.00 +171, 0.38, 3.32, 0.00 +172, -0.36, -3.08, 0.00 +173, -1.06, -8.86, 0.00 +174, -1.80, -14.86, 0.00 +175, -2.49, -20.35, 0.00 +176, -3.20, -25.78, 0.00 +177, -3.83, -30.43, 0.00 +178, -4.46, -35.04, 0.00 +179, -5.01, -38.95, 0.00 +180, -5.56, -42.75, 0.00 +181, -6.03, -45.86, 0.00 +182, -6.49, -48.84, 0.00 +183, -6.85, -51.00, 0.00 +184, -7.19, -53.04, 0.00 +185, -7.40, -54.18, 0.00 +186, -7.60, -55.14, 0.00 +187, -7.66, -55.16, 0.00 +188, -7.69, -54.99, 0.00 +189, -7.63, -54.19, 0.00 +190, -7.48, -52.85, 0.00 +191, -7.21, -50.64, 0.00 +192, -6.86, -47.97, 0.00 +193, -6.39, -44.48, 0.00 +194, -5.85, -40.57, 0.00 +195, -5.16, -35.70, 0.00 +196, -4.39, -30.33, 0.00 +197, -3.53, -24.31, 0.00 +198, -2.53, -17.43, 0.00 diff --git a/TestCases/py_wrapper/updated_moving_frame_NACA12/run_su2.py b/TestCases/py_wrapper/updated_moving_frame_NACA12/run_su2.py index bb0e5379830c..cd4c2b2bae55 100644 --- a/TestCases/py_wrapper/updated_moving_frame_NACA12/run_su2.py +++ b/TestCases/py_wrapper/updated_moving_frame_NACA12/run_su2.py @@ -40,10 +40,14 @@ def run_solver(self): self.comm.barrier() # run solver self.FluidSolver.Preprocess(0) + self.comm.barrier() self.FluidSolver.Run() + self.comm.barrier() self.FluidSolver.Postprocess() + self.comm.barrier() # write outputs self.FluidSolver.Monitor(0) + self.comm.barrier() self.FluidSolver.Output(0) self.comm.barrier() diff --git a/TestCases/rotating/naca0012/rot_NACA0012.cfg b/TestCases/rotating/naca0012/rot_NACA0012.cfg index 847ac151b32e..fec91316e14b 100644 --- a/TestCases/rotating/naca0012/rot_NACA0012.cfg +++ b/TestCases/rotating/naca0012/rot_NACA0012.cfg @@ -52,7 +52,7 @@ MARKER_DESIGNING = ( airfoil ) % ------------- COMMON PARAMETERS TO DEFINE THE NUMERICAL METHOD --------------% % NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES -CFL_NUMBER= 100 +CFL_NUMBER= 5 CFL_ADAPT= NO CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) @@ -62,7 +62,7 @@ ITER= 9999 % LINEAR_SOLVER= FGMRES LINEAR_SOLVER_PREC= LU_SGS -LINEAR_SOLVER_ERROR= 1E-6 +LINEAR_SOLVER_ERROR= 1E-1 LINEAR_SOLVER_ITER= 5 % -------------------------- MULTIGRID PARAMETERS -----------------------------% @@ -72,8 +72,9 @@ MGCYCLE= W_CYCLE MG_PRE_SMOOTH= ( 1, 2, 3, 3 ) MG_POST_SMOOTH= ( 0, 0, 0, 0 ) MG_CORRECTION_SMOOTH= ( 0, 0, 0, 0 ) -MG_DAMP_RESTRICTION= 0.95 -MG_DAMP_PROLONGATION= 0.95 +MG_DAMP_RESTRICTION= 0.5 +% lower damping, to keep from fast oscillations in residuals +MG_DAMP_PROLONGATION= 0.5 % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % diff --git a/TestCases/serial_regression.py b/TestCases/serial_regression.py index d648bb852c76..ca83cca21ef4 100755 --- a/TestCases/serial_regression.py +++ b/TestCases/serial_regression.py @@ -48,7 +48,7 @@ def main(): thermalbath.cfg_dir = "nonequilibrium/thermalbath/finitechemistry" thermalbath.cfg_file = "thermalbath.cfg" thermalbath.test_iter = 10 - thermalbath.test_vals = [0.945997, 0.945997, -12.018025, -12.217291, -32.000000, 10.013239] + thermalbath.test_vals = [0.945997, 0.945997, -11.897761, -11.867806, -32.000000, 10.013239] test_list.append(thermalbath) # Adiabatic frozen thermal bath @@ -56,7 +56,7 @@ def main(): thermalbath_frozen.cfg_dir = "nonequilibrium/thermalbath/frozen" thermalbath_frozen.cfg_file = "thermalbath_frozen.cfg" thermalbath_frozen.test_iter = 10 - thermalbath_frozen.test_vals = [-32.000000, -32.000000, -12.018022, -11.978730, -32.000000, 10.013545] + thermalbath_frozen.test_vals = [-32.000000, -32.000000, -11.810719, -11.867806, -32.000000, 10.013545] test_list.append(thermalbath_frozen) # Inviscid single wedge, implicit @@ -64,7 +64,7 @@ def main(): invwedge.cfg_dir = "nonequilibrium/invwedge" invwedge.cfg_file = "invwedge_ausm.cfg" invwedge.test_iter = 10 - invwedge.test_vals = [-1.073699, -1.598462, -18.299911, -18.627322, -18.573334, 2.241760, 1.868575, 5.286072, 0.843741] + invwedge.test_vals = [-1.073693, -1.598456, -18.298997, -18.626405, -18.572419, 2.241766, 1.868557, 5.286079, 0.843747] invwedge.test_vals_aarch64 = [-1.073699, -1.598462, -18.299723, -18.627132, -18.573146, 2.241760, 1.868575, 5.286072, 0.843741] test_list.append(invwedge) @@ -73,7 +73,7 @@ def main(): visc_cone.cfg_dir = "nonequilibrium/visc_wedge" visc_cone.cfg_file = "axi_visccone.cfg" visc_cone.test_iter = 10 - visc_cone.test_vals = [-5.215239, -5.739373, -20.560910, -20.517094, -20.406632, 1.262779, -3.205484, -0.015695, 0.093205, 32641.000000] + visc_cone.test_vals = [-5.215230, -5.739367, -20.560781, -20.516922, -20.406516, 1.262782, -3.205476, -0.015696, 0.093206, 32641] visc_cone.test_vals_aarch64 = [-5.215250, -5.739384, -20.560917, -20.517096, -20.406630, 1.262772, -3.205492, -0.015695, 0.093205, 32641.000000] test_list.append(visc_cone) @@ -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.691660, 2.781413, -0.009401, 0.011862] + channel.test_vals = [-2.244274, 3.300113, 0.075814, 0.159961] 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.766184, -4.287722, 0.326688, 0.022661] + naca0012.test_vals = [-4.968082, -4.396602, 0.331959, 0.023010] 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 = [-1.379426, 4.288828, -0.245341, 0.043244] + wedge.test_vals = [-1.301825, 4.369535, -0.236575, 0.041741] 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.498143, -10.969216, 0.280800, 0.008623] + oneram6.test_vals = [-11.428634, -10.889247, 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.837516, 1.700577, 0.301169, 0.019490] + fixedCL_naca0012.test_vals = [-3.751251, 1.788794, 0.301332, 0.019499] 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.077848, 4.386916, -0.000333, 0.029678] + polar_naca0012.test_vals = [-1.119642, 4.342860, 0.002338, 0.020591] 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.097199, 0.382306, 0.001326, 0.027904, 2.361500, -2.333600, 0.000000, 0.000000] + flatplate.test_vals = [-5.099346, 0.381614, 0.001277, 0.024994, 2.361500, -2.336500, 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.363897, -2.882485, -0.017777, 1.607978, 0.000000] + cylinder.test_vals = [-8.631691, -3.138513, -0.003331, 1.602087, 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.830989, -1.368842, -0.143868, 73.962350, 0.000000] + cylinder_lowmach.test_vals = [-6.412653, -0.950827, 0.038557, -134.198785, 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.009004, -7.262034, -0.000000, 2.089953] + poiseuille_profile.test_vals = [-12.012556, -7.696221, -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.020123, -5.269264, 0.807147, 0.060494, 0.000000] + rae2822_sa.test_vals = [-1.846052, -5.109587, 0.571411, 0.040773, 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 = [-0.510321, 5.387978, 0.812737, 0.061080, 0.000000] + rae2822_sst.test_vals = [-0.509931, 5.862083, 0.583382, 0.013958, 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.645780, 5.387978, 0.812737, 0.061080] + rae2822_sst_sust.test_vals = [-2.446759, 5.862083, 0.583382, 0.013958] 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.316128, -6.738720, -0.187461, 0.057469] + turb_flatplate.test_vals = [-4.075879, -6.829935, -0.200296, 0.022692] 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.037386, -16.384158, 1.080346, 0.018385, 20.000000, -3.455861, 20.000000, -4.641245, 0.000000] + turb_naca0012_sa.test_vals = [-12.037240, -16.384159, 1.080346, 0.018385, 20, -3.455187, 20, -4.641267, 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.094423, -15.251083, -5.906366, 1.070413, 0.015775, -3.178803, 0.000000] + turb_naca0012_sst.test_vals = [-12.094475, -15.251083, -5.906366, 1.070413, 0.015775, -3.178930, 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.080463, -14.837169, -5.733461, 1.000893, 0.019109, -2.634206] + turb_naca0012_sst_sust_restart.test_vals = [-12.080392, -14.837169, -5.733461, 1.000893, 0.019109, -2.634226] 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) @@ -322,7 +322,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.206619, -10.433888, 0.774232, 1.021995, 0.040553, -3.477598] + turb_naca0012_sst_fixedvalues.test_vals = [-5.206619, -10.436764, 0.774095, 1.021995, 0.040553, -3.477596] turb_naca0012_sst_fixedvalues.timeout = 3200 test_list.append(turb_naca0012_sst_fixedvalues) @@ -344,7 +344,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.067967, -7.554256, -8.815999, -3.734660, 0.000000] + axi_rans_air_nozzle_restart.test_vals = [-12.067609, -7.525629, -8.817136, -3.735731, 0] axi_rans_air_nozzle_restart.test_vals_aarch64 = [-14.143715, -9.170705, -10.848554, -5.776746, 0.000000] axi_rans_air_nozzle_restart.tol = 0.0001 test_list.append(axi_rans_air_nozzle_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.576830, -5.081440, 0.810957, -0.008626, 0.077900] + turb_naca0012_sst_restart_mg.test_vals = [-6.606238, -5.081439, 0.810958, -0.008789, 0.077730] 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 = [-7.140809, -6.485990, 0.531993, 0.008466] + inc_euler_naca0012.test_vals = [-7.126959, -6.573716, 0.531996, 0.008466] 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.394788, -4.869896, -0.021578, 0.125704] + inc_nozzle.test_vals = [-3.936023, -3.470470, -0.012281, 0.120981] 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.004277, -3.227956, 0.003852, 7.626578] + inc_lam_cylinder.test_vals = [-4.059218, -3.311865, 0.006311, 6.172388] 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.748339, -15.067997, -0.726250, 0.020280] + contadj_naca0012.test_vals = [-9.578867, -15.048458, -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.034680, -12.592674, -1.086100, 0.007556] + contadj_oneram6.test_vals = [-11.969828, -12.503366, -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 = [0.754936, -4.793625, -0.524550, -0.000227] + contadj_fixedCL_naca0012.test_vals = [0.887003, -4.740585, -0.358290, -0.000626] 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.665842, -9.132048, 2.056700, -0.000000] + contadj_ns_cylinder.test_vals = [-3.600653, -9.043319, 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.369688, -10.872211, -0.212470, 0.005448] + contadj_rans_rae2822.test_vals = [-5.387481, -10.891118, -0.212470, 0.005448] test_list.append(contadj_rans_rae2822) ############################# @@ -686,7 +686,7 @@ def main(): turb_naca0012_1c.cfg_dir = "rans_uq/naca0012" turb_naca0012_1c.cfg_file = "turb_NACA0012_uq_1c.cfg" turb_naca0012_1c.test_iter = 10 - turb_naca0012_1c.test_vals = [-4.985486, 1.344249, 0.601107, 0.015762] + turb_naca0012_1c.test_vals = [-4.979967, 1.343850, 0.597508, 0.017311] turb_naca0012_1c.test_vals_aarch64 = [-4.992791, 1.342873, 0.557941, 0.003269] test_list.append(turb_naca0012_1c) @@ -695,7 +695,7 @@ def main(): turb_naca0012_2c.cfg_dir = "rans_uq/naca0012" turb_naca0012_2c.cfg_file = "turb_NACA0012_uq_2c.cfg" turb_naca0012_2c.test_iter = 10 - turb_naca0012_2c.test_vals = [-5.482877, 1.263877, 0.444556, -0.031131] + turb_naca0012_2c.test_vals = [-5.482898, 1.261918, 0.440874, -0.029636] test_list.append(turb_naca0012_2c) # NACA0012 3c @@ -703,7 +703,7 @@ def main(): turb_naca0012_3c.cfg_dir = "rans_uq/naca0012" turb_naca0012_3c.cfg_file = "turb_NACA0012_uq_3c.cfg" turb_naca0012_3c.test_iter = 10 - turb_naca0012_3c.test_vals = [-5.583759, 1.231949, 0.428507, -0.034739] + turb_naca0012_3c.test_vals = [-5.583768, 1.229824, 0.426251, -0.033154] test_list.append(turb_naca0012_3c) # NACA0012 p1c1 @@ -711,7 +711,7 @@ def main(): turb_naca0012_p1c1.cfg_dir = "rans_uq/naca0012" turb_naca0012_p1c1.cfg_file = "turb_NACA0012_uq_p1c1.cfg" turb_naca0012_p1c1.test_iter = 10 - turb_naca0012_p1c1.test_vals = [-5.127653, 1.286134, 0.782715, 0.085312] + turb_naca0012_p1c1.test_vals = [-5.127708, 1.284871, 0.779462, 0.086168] turb_naca0012_p1c1.test_vals_aarch64 = [-5.119942, 1.283920, 0.486264, -0.021518] test_list.append(turb_naca0012_p1c1) @@ -720,7 +720,7 @@ def main(): turb_naca0012_p1c2.cfg_dir = "rans_uq/naca0012" turb_naca0012_p1c2.cfg_file = "turb_NACA0012_uq_p1c2.cfg" turb_naca0012_p1c2.test_iter = 10 - turb_naca0012_p1c2.test_vals = [-5.553991, 1.237006, 0.523311, -0.006088] + turb_naca0012_p1c2.test_vals = [-5.554059, 1.235065, 0.521498, -0.004382] test_list.append(turb_naca0012_p1c2) ###################################### @@ -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 = [-2.610126, 2.922809, -0.080488, 0.002170] + rot_naca0012.test_vals = [-1.413477, 4.090702, -0.024889, 0.056654] 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 = [-5.627870, -0.164404, 0.054706, 2.545833] + cavity.test_vals = [-5.515303, -0.049093, -0.114925, -7.135945] 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.894513, -2.469083, 1.703823, 1.670412] + spinning_cylinder.test_vals = [-7.699257, -2.240779, 1.471969, 1.496512] 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.010657, -0.007976] + sine_gust.test_vals = [-1.977498, 3.481817, -0.010233, -0.007786] 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 = [0.074208, 0.027599, -0.001641, -0.000128] + aeroelastic.test_vals = [0.075274, 0.027537, -0.001640, -0.000129] aeroelastic.unsteady = True test_list.append(aeroelastic) @@ -819,13 +819,37 @@ def main(): unst_inc_turb_naca0015_sa.test_vals = [-3.007635, -6.879816, 1.445300, 0.419281] unst_inc_turb_naca0015_sa.unsteady = True test_list.append(unst_inc_turb_naca0015_sa) + # unsteady pitching NACA64A010, RANS, SA + unst_pitching_naca64a010_rans = TestCase('unst_pitching_naca64a010_rans') + 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.951372, 0.010139, 0.008244] + unst_pitching_naca64a010_rans.unsteady = True + test_list.append(unst_pitching_naca64a010_rans) + # unsteady pitching NACA64A010, Euler + unst_pitching_naca64a010_euler = TestCase('unst_pitching_naca64a010_euler') + 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.038811, 0.000913] + unst_pitching_naca64a010_euler.unsteady = True + test_list.append(unst_pitching_naca64a010_euler) + # unsteady plunging NACA0012, Laminar NS + unst_plunging_naca0012 = TestCase('unst_plunging_naca0012') + 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, -3.718481, -0.066605] + unst_plunging_naca0012.unsteady = True + test_list.append(unst_plunging_naca0012) # unsteady pitching NACA0012, Euler, Deforming unst_deforming_naca0012 = TestCase('unst_deforming_naca0012') 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.665152, -3.793306, -3.716483, -3.148336] + unst_deforming_naca0012.test_vals = [-3.665164, -3.793367, -3.716518, -3.148356] unst_deforming_naca0012.unsteady = True test_list.append(unst_deforming_naca0012) @@ -846,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 = [-0.772250, 5.429879, -0.000470, 0.000000] + edge_VW.test_vals = [-0.577419, 5.624333, -0.016050, 0.000000] test_list.append(edge_VW) # Rarefaction shock wave edge_PPR @@ -854,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 = [-2.126694, 4.066051, -0.000013, 0.000000] + edge_PPR.test_vals = [-1.542990, 4.650149, 0.001487, 0.000000] test_list.append(edge_PPR) @@ -883,7 +907,7 @@ def main(): axial_stage2D.cfg_dir = "turbomachinery/axial_stage_2D" axial_stage2D.cfg_file = "Axial_stage2D.cfg" axial_stage2D.test_iter = 20 - axial_stage2D.test_vals = [1.065801, 1.519596, -2.928281, 2.573903, -2.526639, 3.017139, 106370.000000, 106370.000000, 5.726800, 64.383000] + axial_stage2D.test_vals = [1.167176, 1.598840, -2.928275, 2.573906, -2.526639, 3.017139, 106370.000000, 106370.000000, 5.726800, 64.383000] test_list.append(axial_stage2D) # 2D transonic stator restart @@ -891,7 +915,7 @@ def main(): transonic_stator_restart.cfg_dir = "turbomachinery/transonic_stator_2D" transonic_stator_restart.cfg_file = "transonic_stator_restart.cfg" transonic_stator_restart.test_iter = 20 - transonic_stator_restart.test_vals = [-4.443401, -2.566759, -2.169302, 1.651815, -1.356398, 3.172527, -471620.000000, 94.843000, -0.044669] + transonic_stator_restart.test_vals = [-4.367851, -2.492866, -2.082422, 1.727424, -1.466963, 3.224518, -471620.000000, 94.839000, -0.052025] transonic_stator_restart.test_vals_aarch64 = [-4.443401, -2.566759, -2.169302, 1.651815, -1.356398, 3.172527, -471620.000000, 94.843000, -0.044669] test_list.append(transonic_stator_restart) @@ -921,7 +945,7 @@ def main(): uniform_flow.cfg_dir = "sliding_interface/uniform_flow" uniform_flow.cfg_file = "uniform_NN.cfg" uniform_flow.test_iter = 2 - uniform_flow.test_vals = [2.000000, 0.000000, -0.230641, -13.245776] + uniform_flow.test_vals = [2.000000, 0.000000, -0.230641, -13.250662] uniform_flow.test_vals_aarch64 = [2.000000, 0.000000, -0.230641, -13.249000] uniform_flow.tol = 0.000001 uniform_flow.unsteady = True @@ -944,7 +968,7 @@ def main(): channel_3D.cfg_dir = "sliding_interface/channel_3D" channel_3D.cfg_file = "channel_3D_WA.cfg" channel_3D.test_iter = 1 - channel_3D.test_vals = [1.000000, 0.000000, 0.611989, 0.798999, 0.702438] + channel_3D.test_vals = [1.000000, 0.000000, 0.611998, 0.798899, 0.702676] channel_3D.test_vals_aarch64 = [1.000000, 0.000000, 0.611996, 0.798988, 0.702357] channel_3D.unsteady = True channel_3D.multizone = True @@ -985,7 +1009,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.621423, -1.660901] + bars_SST_2D.test_vals = [13.000000, -0.623154, -1.660901] bars_SST_2D.multizone = True test_list.append(bars_SST_2D) @@ -1025,7 +1049,7 @@ def main(): statbeam3d.cfg_dir = "fea_fsi/StatBeam_3d" statbeam3d.cfg_file = "configBeam_3d.cfg" statbeam3d.test_iter = 0 - statbeam3d.test_vals = [-6.168640, -5.939035, -6.071159, 110190] + statbeam3d.test_vals = [-6.175086, -5.939313, -6.084188, 110190] statbeam3d.test_vals_aarch64 = [-6.166287, -5.938291, -6.069768, 110190] #last 4 columns test_list.append(statbeam3d) @@ -1034,7 +1058,7 @@ def main(): knowlesbeam.cfg_dir = "fea_fsi/MixElemsKnowles" knowlesbeam.cfg_file = "config.cfg" knowlesbeam.test_iter = 0 - knowlesbeam.test_vals = [-14.513598, -13.577350, -28.126416, 0.445030, 9.730600] + knowlesbeam.test_vals = [-14.472698, -13.540078, -28.049079, 0.445030, 9.730600] knowlesbeam.test_vals_aarch64 = [-14.475326, -13.54641, -28.057487, 0.44503, 9.7306] #last 5 columns knowlesbeam.tol = 0.0001 test_list.append(knowlesbeam) @@ -1092,7 +1116,7 @@ def main(): airfoilRBF.cfg_file = "config.cfg" airfoilRBF.test_iter = 1 - airfoilRBF.test_vals = [1.000000, 0.086004, -3.365759] + airfoilRBF.test_vals = [1.000000, 0.112689, -3.382129] airfoilRBF.tol = 0.0001 airfoilRBF.multizone = True test_list.append(airfoilRBF) @@ -1499,7 +1523,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.122920, 4.611743] + opt_multiobj1surf_py.test_vals = [1.000000, 1.000000, 36.178490, 3.891506] 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 @@ -1512,7 +1536,7 @@ def main(): opt_2surf1obj_py.cfg_dir = "optimization_euler/multiobjective_wedge" opt_2surf1obj_py.cfg_file = "inv_wedge_ROE_2surf_1obj.cfg" opt_2surf1obj_py.test_iter = 1 - opt_2surf1obj_py.test_vals = [1.000000, 1.000000, 2.005099, 0.000383] + opt_2surf1obj_py.test_vals = [1.000000, 1.000000, 2.005074, 0.000323] opt_2surf1obj_py.command = TestCase.Command(exec = "shape_optimization.py", param = "-g CONTINUOUS_ADJOINT -f") opt_2surf1obj_py.timeout = 1600 opt_2surf1obj_py.tol = 0.00001 @@ -1529,7 +1553,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.766184, -4.287722, 0.326688, 0.022661] + pywrapper_naca0012.test_vals = [-4.968082, -4.396602, 0.331959, 0.023010] pywrapper_naca0012.command = TestCase.Command(exec = "SU2_CFD.py", param = "-f") pywrapper_naca0012.timeout = 1600 pywrapper_naca0012.tol = 0.00001 @@ -1542,7 +1566,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.094423, -15.251083, -5.906366, 1.070413, 0.015775, -3.178803, 0.000000] + pywrapper_turb_naca0012_sst.test_vals = [-12.094475, -15.251083, -5.906366, 1.070413, 0.015775, -3.178930, 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 @@ -1570,10 +1594,10 @@ def main(): pywrapper_aeroelastic.cfg_dir = "aeroelastic" pywrapper_aeroelastic.cfg_file = "aeroelastic_NACA64A010.cfg" pywrapper_aeroelastic.test_iter = 2 - pywrapper_aeroelastic.test_vals = [0.074208, 0.027599, -0.001641, -0.000128] + pywrapper_aeroelastic.test_vals = [0.075274, 0.027537, -0.001640, -0.000129] pywrapper_aeroelastic.command = TestCase.Command(exec = "SU2_CFD.py", param = "-f") pywrapper_aeroelastic.timeout = 1600 - pywrapper_aeroelastic.tol = 0.00001 + pywrapper_aeroelastic.tol = 0.01 pywrapper_aeroelastic.unsteady = True pywrapper_aeroelastic.enabled_with_asan = False test_list.append(pywrapper_aeroelastic) @@ -1599,7 +1623,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.614167, 2.264215, 0.000771, 0.172980] + pywrapper_unsteadyCHT.test_vals = [-1.614167, 2.260153, -0.003880, 0.099289] pywrapper_unsteadyCHT.command = TestCase.Command(exec = "python", param = "launch_unsteady_CHT_FlatPlate.py -f") pywrapper_unsteadyCHT.timeout = 1600 pywrapper_unsteadyCHT.tol = 0.00001 @@ -1613,7 +1637,7 @@ def main(): pywrapper_rigidMotion.cfg_dir = "py_wrapper/flatPlate_rigidMotion" pywrapper_rigidMotion.cfg_file = "flatPlate_rigidMotion_Conf.cfg" pywrapper_rigidMotion.test_iter = 5 - pywrapper_rigidMotion.test_vals = [-1.614166, 2.257995, 0.350208, 0.089496] + pywrapper_rigidMotion.test_vals = [-1.614166, 2.255135, 0.350208, 0.089496] pywrapper_rigidMotion.command = TestCase.Command(exec = "python", param = "launch_flatPlate_rigidMotion.py -f") pywrapper_rigidMotion.timeout = 1600 pywrapper_rigidMotion.tol = 0.00001 @@ -1627,7 +1651,7 @@ def main(): pywrapper_custom_inlet.cfg_dir = "py_wrapper/custom_inlet" pywrapper_custom_inlet.cfg_file = "lam_flatplate.cfg" pywrapper_custom_inlet.test_iter = 20 - pywrapper_custom_inlet.test_vals = [-4.123206, -1.543215, -3.735006, 1.339481, -0.793478, 0.161210, -0.007009, 0.513560, -0.520570] + pywrapper_custom_inlet.test_vals = [-4.122866, -1.542850, -3.664440, 1.339854, -0.793567, 0.159301, -0.007466, 0.514290, -0.521750] pywrapper_custom_inlet.command = TestCase.Command(exec = "python", param = "run.py") pywrapper_custom_inlet.timeout = 1600 pywrapper_custom_inlet.tol = 0.0001 diff --git a/TestCases/serial_regression_AD.py b/TestCases/serial_regression_AD.py index 9826e95cd1f4..13b7984ab1d7 100644 --- a/TestCases/serial_regression_AD.py +++ b/TestCases/serial_regression_AD.py @@ -76,7 +76,7 @@ def main(): discadj_arina2k.cfg_dir = "disc_adj_euler/arina2k" discadj_arina2k.cfg_file = "Arina2KRS.cfg" discadj_arina2k.test_iter = 20 - discadj_arina2k.test_vals = [-3.254490, -3.495569, 0.052370, 0.000000] + discadj_arina2k.test_vals = [-3.229386, -3.466956, 0.043983, 0.000000] test_list.append(discadj_arina2k) ####################################################### @@ -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, -4.091644, -2.655563, 0.000000] + discadj_incomp_NACA0012.test_vals = [20.000000, -3.977751, -2.562520, 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.219518, -1.646199, -0.007607, 0.000013] + discadj_pitchingNACA0012.test_vals = [-1.223517, -1.653450, -0.004178, -0.000004] 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.960419, -1.844186, 2970.700000, 0.000004] + unst_deforming_naca0012.test_vals = [-1.965747, -1.848881, 2961.700000, 0.000000] unst_deforming_naca0012.unsteady = True test_list.append(unst_deforming_naca0012) @@ -180,7 +180,7 @@ def main(): discadj_fea.cfg_dir = "disc_adj_fea" discadj_fea.cfg_file = "configAD_fem.cfg" discadj_fea.test_iter = 4 - discadj_fea.test_vals = [-2.849844, -3.238713, -0.000364, -8.708700] + discadj_fea.test_vals = [-2.849719, -3.238637, -0.000364, -8.708700] discadj_fea.test_vals_aarch64 = [-2.849588, -3.238523, -0.000364, -8.708700] discadj_fea.tol = 0.00007 test_list.append(discadj_fea) @@ -206,8 +206,8 @@ def main(): discadj_fsi.cfg_dir = "disc_adj_fsi" discadj_fsi.cfg_file = "config.cfg" discadj_fsi.test_iter = 6 - discadj_fsi.test_vals = [6, -8.932959, -10.054580, 3.1054e-11, -1.7612e-06] - discadj_fsi.test_vals_aarch64 = [6, -8.928861, -10.122430, 3.0979e-11, -1.7585e-06] + discadj_fsi.test_vals = [6, -8.929655, -10.097091, 3.0939e-11, -1.7573e-06] + discadj_fsi.test_vals_aarch64 = [6, -8.928820, -10.067497, 3.0979e-11, -1.7585e-06] test_list.append(discadj_fsi) ################################### diff --git a/TestCases/tutorials.py b/TestCases/tutorials.py index dcfbc0a0f44c..cf0968e2a9de 100644 --- a/TestCases/tutorials.py +++ b/TestCases/tutorials.py @@ -80,7 +80,7 @@ def main(): sp_pinArray_2d_mf_hf.cfg_dir = "../Tutorials/incompressible_flow/Inc_Streamwise_Periodic" sp_pinArray_2d_mf_hf.cfg_file = "sp_pinArray_2d_mf_hf.cfg" sp_pinArray_2d_mf_hf.test_iter = 25 - sp_pinArray_2d_mf_hf.test_vals = [-4.683630, 0.844679, -0.755570, 241.872160] + sp_pinArray_2d_mf_hf.test_vals = [-4.674156, 0.512176, -0.756308, 241.767693] sp_pinArray_2d_mf_hf.test_vals_aarch64 = [-4.683630, -0.755570, 241.872160] test_list.append(sp_pinArray_2d_mf_hf) @@ -89,7 +89,7 @@ def main(): sp_pinArray_2d_dp_hf_tp.cfg_dir = "../Tutorials/incompressible_flow/Inc_Streamwise_Periodic" sp_pinArray_2d_dp_hf_tp.cfg_file = "sp_pinArray_2d_dp_hf_tp.cfg" sp_pinArray_2d_dp_hf_tp.test_iter = 25 - sp_pinArray_2d_dp_hf_tp.test_vals = [-4.739709, 0.520033, -0.713547, 208.023676] + sp_pinArray_2d_dp_hf_tp.test_vals = [-4.727583, 0.453505, -0.714476, 208.023676] sp_pinArray_2d_dp_hf_tp.test_vals_aarch64 = [-4.739709, 0.520033, -0.713547, 208.023676] test_list.append(sp_pinArray_2d_dp_hf_tp) @@ -153,7 +153,7 @@ def main(): kenics_mixer_tutorial.cfg_dir = "../Tutorials/incompressible_flow/Inc_Species_Transport_Composition_Dependent_Model" kenics_mixer_tutorial.cfg_file = "kenics_mixer_tutorial.cfg" kenics_mixer_tutorial.test_iter = 10 - kenics_mixer_tutorial.test_vals = [-7.490472, -6.823803, -6.838373, -6.383764, -7.907928, -3.062404, -7.452184, 5.000000, -1.858094, 4.000000, -5.318066, 3.000000, -6.371967, 0.025661, 0.000000, 0.025661, 0.000000, 62.736000, 8.470600, 46.738000, 7.527900] + kenics_mixer_tutorial.test_vals = [-7.490438, -6.823937, -6.838581, -6.383852, -7.879414, -3.004710, -7.452189, 5.000000, -1.857319, 4.000000, -5.336948, 3.000000, -6.369478, 0.025670, 0.000000, 0.025670, 0.000000, 62.718000, 8.462700, 46.726000, 7.529400] kenics_mixer_tutorial.command = TestCase.Command("mpirun -n 2", "SU2_CFD") test_list.append(kenics_mixer_tutorial) @@ -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.035200, 0.019230] + tutorial_inv_bump.test_vals = [-1.437425, 4.075857, 0.060602, -0.001097] test_list.append(tutorial_inv_bump) # Inviscid Wedge @@ -183,7 +183,7 @@ def main(): tutorial_inv_wedge.cfg_dir = "../Tutorials/compressible_flow/Inviscid_Wedge" tutorial_inv_wedge.cfg_file = "inv_wedge_HLLC.cfg" tutorial_inv_wedge.test_iter = 0 - tutorial_inv_wedge.test_vals = [-0.481460, 5.253008, -0.281099, 0.049535] + tutorial_inv_wedge.test_vals = [-0.481460, 5.253008, -0.290816, 0.051445] tutorial_inv_wedge.no_restart = True test_list.append(tutorial_inv_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.294332, 0.115223] + tutorial_inv_onera.test_vals = [-5.204928, -4.597762, 0.262596, 0.084044] 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.126007, 69.619462] + 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) @@ -237,7 +237,7 @@ def main(): tutorial_trans_flatplate_T3A.cfg_dir = "../Tutorials/compressible_flow/Transitional_Flat_Plate/Langtry_and_Menter/T3A" tutorial_trans_flatplate_T3A.cfg_file = "transitional_LM_model_ConfigFile.cfg" tutorial_trans_flatplate_T3A.test_iter = 20 - tutorial_trans_flatplate_T3A.test_vals = [-5.808996, -2.070606, -3.969765, -0.277943, -1.953093, 1.708472, -3.514943, 0.357411] + tutorial_trans_flatplate_T3A.test_vals = [-5.790137, -2.054834, -3.894661, -0.255074, -1.747007, 5.119341, -3.493237, 0.393262] tutorial_trans_flatplate_T3A.test_vals_aarch64 = [-5.808996, -2.070606, -3.969765, -0.277943, -1.953289, 1.708472, -3.514943, 0.357411] tutorial_trans_flatplate_T3A.no_restart = True test_list.append(tutorial_trans_flatplate_T3A) @@ -247,7 +247,7 @@ def main(): tutorial_trans_flatplate_T3Am.cfg_dir = "../Tutorials/compressible_flow/Transitional_Flat_Plate/Langtry_and_Menter/T3A-" tutorial_trans_flatplate_T3Am.cfg_file = "transitional_LM_model_ConfigFile.cfg" tutorial_trans_flatplate_T3Am.test_iter = 20 - tutorial_trans_flatplate_T3Am.test_vals = [-5.538098, -1.681627, -2.877016, -0.055689, -3.695534, 3.413620, -2.385344, 1.103633] + tutorial_trans_flatplate_T3Am.test_vals = [-5.591088, -1.700867, -3.100341, -0.106090, -3.750523, 3.287643, -2.394576, 1.119623] tutorial_trans_flatplate_T3Am.test_vals_aarch64 = [-5.540938, -1.681627, -2.878831, -0.058224, -3.695533, 3.413628, -2.385345, 1.103633] tutorial_trans_flatplate_T3Am.no_restart = True test_list.append(tutorial_trans_flatplate_T3Am) @@ -283,7 +283,7 @@ def main(): tutorial_nicfd_nozzle.cfg_dir = "../Tutorials/compressible_flow/NICFD_nozzle" tutorial_nicfd_nozzle.cfg_file = "NICFD_nozzle.cfg" tutorial_nicfd_nozzle.test_iter = 20 - tutorial_nicfd_nozzle.test_vals = [-1.799262, -11.343263, 4.631692, 0.000000, 0.000000] + tutorial_nicfd_nozzle.test_vals = [-1.799850, -6.002739, 4.635400, 0.000000, 0.000000] tutorial_nicfd_nozzle.no_restart = True test_list.append(tutorial_nicfd_nozzle) @@ -292,7 +292,7 @@ def main(): tutorial_nicfd_nozzle_pinn.cfg_dir = "../Tutorials/compressible_flow/NICFD_nozzle/PhysicsInformed" tutorial_nicfd_nozzle_pinn.cfg_file = "config_NICFD_PINN.cfg" tutorial_nicfd_nozzle_pinn.test_iter = 20 - tutorial_nicfd_nozzle_pinn.test_vals = [-3.181747, -1.638856, -1.277037, 2.445964, -11.759632] + tutorial_nicfd_nozzle_pinn.test_vals = [-2.728179, -0.849337, -1.224542, 2.898995, -11.420290] tutorial_nicfd_nozzle_pinn.no_restart = True test_list.append(tutorial_nicfd_nozzle_pinn) @@ -302,7 +302,7 @@ def main(): tutorial_unst_naca0012.cfg_dir = "../Tutorials/compressible_flow/Unsteady_NACA0012" tutorial_unst_naca0012.cfg_file = "unsteady_naca0012.cfg" tutorial_unst_naca0012.test_iter = 520 - tutorial_unst_naca0012.test_vals = [520, 0, -5.298821, 0, 0.269405, 0.724098, 0.002630, 0.015827] + tutorial_unst_naca0012.test_vals = [520, 0, -5.293168, 0, 0.301651, 0.772998, 0.002171, 0.012763] tutorial_unst_naca0012.test_vals_aarch64 = [520, 0, -5.292359, 0, 0.284720, 0.766329, 0.000954, 0.007565] tutorial_unst_naca0012.unsteady = True test_list.append(tutorial_unst_naca0012) @@ -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.169337, 0.235131] + tutorial_design_inv_naca0012.test_vals = [-3.585391, -2.989014, 0.165195, 0.238368] tutorial_design_inv_naca0012.no_restart = True test_list.append(tutorial_design_inv_naca0012) @@ -345,6 +345,34 @@ def main(): tutorial_design_multiobj.no_restart = True test_list.append(tutorial_design_multiobj) + # custom source: turbulent flamespeed closure (Zimont model) for PSI testcase + pywrapper_psi = TestCase('psi_adiabatic') + pywrapper_psi.cfg_dir = "../Tutorials/multiphysics/TFC_python/adiabatic" + pywrapper_psi.cfg_file = "psi.cfg" + pywrapper_psi.test_iter = 0 + pywrapper_psi.test_vals = [-2.682653, -0.994981, -2.221252, -2.401462, 3.597559, -3.369865] + pywrapper_psi.command = TestCase.Command("mpirun -np 2", "python", "run.py") + test_list.append(pywrapper_psi) + + # custom source: including source term for enthalpy equations + pywrapper_psi_hl = TestCase('psi_enthalpy') + pywrapper_psi_hl.cfg_dir = "../Tutorials/multiphysics/TFC_python/enthalpy" + pywrapper_psi_hl.cfg_file = "psi.cfg" + pywrapper_psi_hl.test_iter = 0 + pywrapper_psi_hl.test_vals = [-6.211126, -4.025898, -5.405635, -3.743101, -1.314498, -3.948690] + pywrapper_psi_hl.command = TestCase.Command("mpirun -np 2", "python", "run.py") + test_list.append(pywrapper_psi_hl) + + # custom source: including custom BC and source term + pywrapper_psi_quench = TestCase('psi_quench') + pywrapper_psi_quench.cfg_dir = "../Tutorials/multiphysics/TFC_python/quench" + pywrapper_psi_quench.cfg_file = "psi.cfg" + pywrapper_psi_quench.test_iter = 0 + pywrapper_psi_quench.test_vals = [-7.370108, -6.688806, -7.839519, -4.086479, -1.223314, -4.022876] + pywrapper_psi_quench.command = TestCase.Command("mpirun -np 2", "python", "run.py") + test_list.append(pywrapper_psi_quench) + + ###################################### ### RUN TESTS ### ###################################### diff --git a/TestCases/unsteady/pitching_naca64a010_euler/pitching_NACA64A010.cfg b/TestCases/unsteady/pitching_naca64a010_euler/pitching_NACA64A010.cfg index 3db0541e9a88..6b1e3e7192b5 100644 --- a/TestCases/unsteady/pitching_naca64a010_euler/pitching_NACA64A010.cfg +++ b/TestCases/unsteady/pitching_naca64a010_euler/pitching_NACA64A010.cfg @@ -14,7 +14,7 @@ SOLVER= EULER KIND_TURB_MODEL= NONE MATH_PROBLEM= DIRECT -RESTART_SOL= NO +RESTART_SOL= YES % ------------------------- UNSTEADY SIMULATION -------------------------------% % @@ -26,7 +26,9 @@ TIME_STEP= 0.0023555025613149587 MAX_TIME= 0.59 % 10 periods: 0.5888756403287397 % -INNER_ITER= 110 +TIME_DOMAIN= YES +TIME_ITER= 100 +INNER_ITER= 20 UNST_ADJOINT_ITER= 251 % ----------------------- DYNAMIC MESH DEFINITION -----------------------------% @@ -67,16 +69,15 @@ MARKER_DESIGNING = ( airfoil ) % ------------- COMMON PARAMETERS TO DEFINE THE NUMERICAL METHOD --------------% % NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES -CFL_NUMBER= 10.0 +CFL_NUMBER= 200.0 CFL_ADAPT= NO CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) -EXT_ITER= 99999 % ------------------------ LINEAR SOLVER DEFINITION ---------------------------% % LINEAR_SOLVER= FGMRES -LINEAR_SOLVER_PREC= LU_SGS +LINEAR_SOLVER_PREC= ILU LINEAR_SOLVER_ERROR= 1E-6 LINEAR_SOLVER_ITER= 5 @@ -131,7 +132,7 @@ CONV_CAUCHY_EPS= 1E-6 MESH_FILENAME= mesh_NACA64A010_inv.su2 MESH_FORMAT= SU2 MESH_OUT_FILENAME= mesh_out -SOLUTION_FILENAME= restart_flow +SOLUTION_FILENAME= solution_flow SOLUTION_ADJ_FILENAME= solution_adj TABULAR_FORMAT= CSV CONV_FILENAME= history @@ -142,6 +143,7 @@ VOLUME_ADJ_FILENAME= adjoint GRAD_OBJFUNC_FILENAME= of_grad SURFACE_FILENAME= surface_flow SURFACE_ADJ_FILENAME= surface_adjoint +SCREEN_OUTPUT= (TIME_ITER, INNER_ITER, RMS_DENSITY, RMS_ENERGY, LIFT, DRAG) OUTPUT_WRT_FREQ= 250 % --------------------- OPTIMAL SHAPE DESIGN DEFINITION -----------------------% @@ -149,3 +151,5 @@ OUTPUT_WRT_FREQ= 250 OPT_OBJECTIVE= DRAG * 0.001 OPT_CONSTRAINT= ( LIFT = 0.0 ) * 0.001; ( AREA > 0.0660957 ) * 0.001 DEFINITION_DV= ( 30, 1.0 | airfoil | 0, 0.961538461538 ); ( 30, 1.0 | airfoil | 0, 0.923076923077 ); ( 30, 1.0 | airfoil | 0, 0.884615384615 ); ( 30, 1.0 | airfoil | 0, 0.846153846154 ); ( 30, 1.0 | airfoil | 0, 0.807692307692 ); ( 30, 1.0 | airfoil | 0, 0.769230769231 ); ( 30, 1.0 | airfoil | 0, 0.730769230769 ); ( 30, 1.0 | airfoil | 0, 0.692307692308 ); ( 30, 1.0 | airfoil | 0, 0.653846153846 ); ( 30, 1.0 | airfoil | 0, 0.615384615385 ); ( 30, 1.0 | airfoil | 0, 0.576923076923 ); ( 30, 1.0 | airfoil | 0, 0.538461538462 ); ( 30, 1.0 | airfoil | 0, 0.5 ); ( 30, 1.0 | airfoil | 0, 0.461538461538 ); ( 30, 1.0 | airfoil | 0, 0.423076923077 ); ( 30, 1.0 | airfoil | 0, 0.384615384615 ); ( 30, 1.0 | airfoil | 0, 0.346153846154 ); ( 30, 1.0 | airfoil | 0, 0.307692307692 ); ( 30, 1.0 | airfoil | 0, 0.269230769231 ); ( 30, 1.0 | airfoil | 0, 0.230769230769 ); ( 30, 1.0 | airfoil | 0, 0.192307692308 ); ( 30, 1.0 | airfoil | 0, 0.153846153846 ); ( 30, 1.0 | airfoil | 0, 0.115384615385 ); ( 30, 1.0 | airfoil | 0, 0.0769230769231 ); ( 30, 1.0 | airfoil | 0, 0.0384615384615 ); ( 30, 1.0 | airfoil | 1, 0.0384615384615 ); ( 30, 1.0 | airfoil | 1, 0.0769230769231 ); ( 30, 1.0 | airfoil | 1, 0.115384615385 ); ( 30, 1.0 | airfoil | 1, 0.153846153846 ); ( 30, 1.0 | airfoil | 1, 0.192307692308 ); ( 30, 1.0 | airfoil | 1, 0.230769230769 ); ( 30, 1.0 | airfoil | 1, 0.269230769231 ); ( 30, 1.0 | airfoil | 1, 0.307692307692 ); ( 30, 1.0 | airfoil | 1, 0.346153846154 ); ( 30, 1.0 | airfoil | 1, 0.384615384615 ); ( 30, 1.0 | airfoil | 1, 0.423076923077 ); ( 30, 1.0 | airfoil | 1, 0.461538461538 ); ( 30, 1.0 | airfoil | 1, 0.5 ); ( 30, 1.0 | airfoil | 1, 0.538461538462 ); ( 30, 1.0 | airfoil | 1, 0.576923076923 ); ( 30, 1.0 | airfoil | 1, 0.615384615385 ); ( 30, 1.0 | airfoil | 1, 0.653846153846 ); ( 30, 1.0 | airfoil | 1, 0.692307692308 ); ( 30, 1.0 | airfoil | 1, 0.730769230769 ); ( 30, 1.0 | airfoil | 1, 0.769230769231 ); ( 30, 1.0 | airfoil | 1, 0.807692307692 ); ( 30, 1.0 | airfoil | 1, 0.846153846154 ); ( 30, 1.0 | airfoil | 1, 0.884615384615 ); ( 30, 1.0 | airfoil | 1, 0.923076923077 ); ( 30, 1.0 | airfoil | 1, 0.961538461538 ) +READ_BINARY_RESTART= NO +RESTART_ITER= 2 diff --git a/TestCases/unsteady/pitching_naca64a010_rans/turb_NACA64A010.cfg b/TestCases/unsteady/pitching_naca64a010_rans/turb_NACA64A010.cfg index ae230679efdd..8a4e536d4eb0 100644 --- a/TestCases/unsteady/pitching_naca64a010_rans/turb_NACA64A010.cfg +++ b/TestCases/unsteady/pitching_naca64a010_rans/turb_NACA64A010.cfg @@ -11,10 +11,10 @@ % ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% % -SOLVER= NAVIER_STOKES +SOLVER= RANS KIND_TURB_MODEL= SA MATH_PROBLEM= DIRECT -RESTART_SOL= NO +RESTART_SOL= YES % ------------------------- UNSTEADY SIMULATION -------------------------------% % @@ -27,7 +27,9 @@ TIME_STEP= 0.0023555025613149587 MAX_TIME= 0.59 % 10 periods: 0.5888756403287397 % -INNER_ITER= 2000 +TIME_DOMAIN= YES +TIME_ITER= 100 +INNER_ITER= 30 UNST_ADJOINT_ITER= 251 GRID_MOVEMENT= RIGID_MOTION MACH_MOTION= 0.796 @@ -65,16 +67,15 @@ MARKER_DESIGNING = ( airfoil ) % ------------- COMMON PARAMETERS TO DEFINE THE NUMERICAL METHOD --------------% % NUM_METHOD_GRAD= GREEN_GAUSS -CFL_NUMBER= 4.0 +CFL_NUMBER= 200.0 CFL_ADAPT= NO CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) -EXT_ITER= 99999 % ------------------------ LINEAR SOLVER DEFINITION ---------------------------% % LINEAR_SOLVER= FGMRES -LINEAR_SOLVER_PREC= LU_SGS +LINEAR_SOLVER_PREC= ILU LINEAR_SOLVER_ERROR= 1E-6 LINEAR_SOLVER_ITER= 5 @@ -139,7 +140,7 @@ CONV_CAUCHY_EPS= 1E-5 MESH_FILENAME= mesh_NACA64A010_turb.su2 MESH_FORMAT= SU2 MESH_OUT_FILENAME= mesh_out -SOLUTION_FILENAME= restart_flow +SOLUTION_FILENAME= solution_flow SOLUTION_ADJ_FILENAME= restart_adj TABULAR_FORMAT= CSV CONV_FILENAME= history @@ -150,6 +151,7 @@ VOLUME_ADJ_FILENAME= adjoint GRAD_OBJFUNC_FILENAME= of_grad SURFACE_FILENAME= surface_flow SURFACE_ADJ_FILENAME= surface_adjoint +SCREEN_OUTPUT= (TIME_ITER, INNER_ITER, RMS_DENSITY, RMS_NU_TILDE, LIFT, DRAG) OUTPUT_WRT_FREQ= 1 % --------------------- OPTIMAL SHAPE DESIGN DEFINITION -----------------------% @@ -157,3 +159,5 @@ OUTPUT_WRT_FREQ= 1 OPT_OBJECTIVE= DRAG * 0.001 OPT_CONSTRAINT= ( AREA > 0.0661121 ) * 0.001 DEFINITION_DV= ( 30, 1.0 | airfoil | 0, 0.961538461538 ); ( 30, 1.0 | airfoil | 0, 0.923076923077 ); ( 30, 1.0 | airfoil | 0, 0.884615384615 ); ( 30, 1.0 | airfoil | 0, 0.846153846154 ); ( 30, 1.0 | airfoil | 0, 0.807692307692 ); ( 30, 1.0 | airfoil | 0, 0.769230769231 ); ( 30, 1.0 | airfoil | 0, 0.730769230769 ); ( 30, 1.0 | airfoil | 0, 0.692307692308 ); ( 30, 1.0 | airfoil | 0, 0.653846153846 ); ( 30, 1.0 | airfoil | 0, 0.615384615385 ); ( 30, 1.0 | airfoil | 0, 0.576923076923 ); ( 30, 1.0 | airfoil | 0, 0.538461538462 ); ( 30, 1.0 | airfoil | 0, 0.5 ); ( 30, 1.0 | airfoil | 0, 0.461538461538 ); ( 30, 1.0 | airfoil | 0, 0.423076923077 ); ( 30, 1.0 | airfoil | 0, 0.384615384615 ); ( 30, 1.0 | airfoil | 0, 0.346153846154 ); ( 30, 1.0 | airfoil | 0, 0.307692307692 ); ( 30, 1.0 | airfoil | 0, 0.269230769231 ); ( 30, 1.0 | airfoil | 0, 0.230769230769 ); ( 30, 1.0 | airfoil | 0, 0.192307692308 ); ( 30, 1.0 | airfoil | 0, 0.153846153846 ); ( 30, 1.0 | airfoil | 0, 0.115384615385 ); ( 30, 1.0 | airfoil | 0, 0.0769230769231 ); ( 30, 1.0 | airfoil | 0, 0.0384615384615 ); ( 30, 1.0 | airfoil | 1, 0.0384615384615 ); ( 30, 1.0 | airfoil | 1, 0.0769230769231 ); ( 30, 1.0 | airfoil | 1, 0.115384615385 ); ( 30, 1.0 | airfoil | 1, 0.153846153846 ); ( 30, 1.0 | airfoil | 1, 0.192307692308 ); ( 30, 1.0 | airfoil | 1, 0.230769230769 ); ( 30, 1.0 | airfoil | 1, 0.269230769231 ); ( 30, 1.0 | airfoil | 1, 0.307692307692 ); ( 30, 1.0 | airfoil | 1, 0.346153846154 ); ( 30, 1.0 | airfoil | 1, 0.384615384615 ); ( 30, 1.0 | airfoil | 1, 0.423076923077 ); ( 30, 1.0 | airfoil | 1, 0.461538461538 ); ( 30, 1.0 | airfoil | 1, 0.5 ); ( 30, 1.0 | airfoil | 1, 0.538461538462 ); ( 30, 1.0 | airfoil | 1, 0.576923076923 ); ( 30, 1.0 | airfoil | 1, 0.615384615385 ); ( 30, 1.0 | airfoil | 1, 0.653846153846 ); ( 30, 1.0 | airfoil | 1, 0.692307692308 ); ( 30, 1.0 | airfoil | 1, 0.730769230769 ); ( 30, 1.0 | airfoil | 1, 0.769230769231 ); ( 30, 1.0 | airfoil | 1, 0.807692307692 ); ( 30, 1.0 | airfoil | 1, 0.846153846154 ); ( 30, 1.0 | airfoil | 1, 0.884615384615 ); ( 30, 1.0 | airfoil | 1, 0.923076923077 ); ( 30, 1.0 | airfoil | 1, 0.961538461538 ) +READ_BINARY_RESTART= NO +RESTART_ITER= 2 diff --git a/TestCases/unsteady/plunging_naca0012/plunging_NACA0012.cfg b/TestCases/unsteady/plunging_naca0012/plunging_NACA0012.cfg index 6e4bc39ea5dd..b1ce80b506fe 100644 --- a/TestCases/unsteady/plunging_naca0012/plunging_NACA0012.cfg +++ b/TestCases/unsteady/plunging_naca0012/plunging_NACA0012.cfg @@ -14,19 +14,21 @@ SOLVER= NAVIER_STOKES KIND_TURB_MODEL= NONE MATH_PROBLEM= DIRECT -RESTART_SOL= NO +RESTART_SOL= YES % ------------------------- UNSTEADY SIMULATION -------------------------------% % TIME_MARCHING= DUAL_TIME_STEPPING-2ND_ORDER TIME_STEP= 0.0023555025613149587 +TIME_DOMAIN= YES +TIME_ITER= 100 % 24 steps per period: 0.0024536485013697488 % 25 steps per period: 0.0023555025613149587 % MAX_TIME= 0.5888756403287397 % 10 periods: 0.5888756403287397 % -INNER_ITER= 1000 +INNER_ITER= 50 % ----------------------- DYNAMIC MESH DEFINITION -----------------------------% % @@ -62,7 +64,6 @@ CFL_NUMBER= 1.0 CFL_ADAPT= NO CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) -EXT_ITER= 99999 % ----------------------- SLOPE LIMITER DEFINITION ----------------------------% % @@ -118,4 +119,7 @@ VOLUME_ADJ_FILENAME= adjoint GRAD_OBJFUNC_FILENAME= of_grad SURFACE_FILENAME= surface_flow SURFACE_ADJ_FILENAME= surface_adjoint +SCREEN_OUTPUT= (TIME_ITER, INNER_ITER, RMS_DENSITY, RMS_ENERGY, LIFT, DRAG) OUTPUT_WRT_FREQ= 1 +READ_BINARY_RESTART= NO +RESTART_ITER= 2 diff --git a/TestCases/vandv.py b/TestCases/vandv.py index b5a0ebdc3d78..d207912bbfa9 100644 --- a/TestCases/vandv.py +++ b/TestCases/vandv.py @@ -53,7 +53,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.041770, -10.137183, -10.939993, -7.992281, -10.323862, -4.732832, 0.002801] + flatplate_sst1994m.test_vals = [-13.040613, -10.136941, -10.940824, -7.982363, -10.323879, -4.732619, 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) @@ -62,7 +62,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 = [-13.025922, -11.014048, -10.634022, -7.540700, -11.769195, -6.978039, 0.004931] + bump_sst1994m.test_vals = [-11.928363, -10.095978, -9.513649, -6.445700, -11.773659, -6.990340, 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) @@ -81,7 +81,7 @@ def main(): swbli_sst.cfg_dir = "vandv/rans/swbli" swbli_sst.cfg_file = "config_sst.cfg" swbli_sst.test_iter = 5 - swbli_sst.test_vals = [-11.569218, -10.909085, -11.607979, -10.431162, -11.407582, -2.637788, 0.001816, -1.305819, -3.514509, 13.399000] + swbli_sst.test_vals = [-11.569218, -10.909086, -11.607984, -10.431163, -11.407588, -2.637660, 0.001816, -1.305818, -3.514590, 13.399000] test_list.append(swbli_sst) # DSMA661 - SA @@ -89,7 +89,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.230903, -8.242025, -9.022553, -5.871551, -10.737683, 0.155687, 0.024232] + dsma661_sa.test_vals = [-11.230865, -8.242970, -8.982056, -5.877960, -10.737687, 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) @@ -98,7 +98,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.017795, -8.156464, -9.007731, -5.893887, -10.650405, -7.860166, 0.155882, 0.023344] + dsma661_sst.test_vals = [-11.017110, -8.156868, -9.048400, -5.895204, -10.649930, -7.839740, 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/UnitTests/Common/toolboxes/multilayer_perceptron/CLookUp_ANN_tests.cpp b/UnitTests/Common/toolboxes/multilayer_perceptron/CLookUp_ANN_tests.cpp index 2d255f8ca5cb..7f6dc38ad614 100644 --- a/UnitTests/Common/toolboxes/multilayer_perceptron/CLookUp_ANN_tests.cpp +++ b/UnitTests/Common/toolboxes/multilayer_perceptron/CLookUp_ANN_tests.cpp @@ -28,6 +28,7 @@ #include "catch.hpp" #include "../../../../Common/include/CConfig.hpp" #if defined(HAVE_MLPCPP) +#define MLP_CUSTOM_TYPE su2double #include "../../../../subprojects/MLPCpp/include/CLookUp_ANN.hpp" #define USE_MLPCPP #endif @@ -35,43 +36,59 @@ #ifdef USE_MLPCPP TEST_CASE("LookUp ANN test", "[LookUpANN]") { - std::string MLP_input_files[] = {"src/SU2/UnitTests/Common/toolboxes/multilayer_perceptron/simple_mlp.mlp"}; - unsigned short n_MLPs = 1; - MLPToolbox::CLookUp_ANN ANN(n_MLPs, MLP_input_files); - std::vector MLP_input_names, MLP_output_names; - std::vector MLP_inputs; - std::vector MLP_outputs; - su2double x, y, z; + MLPToolbox::CLookUp_ANN ANN; + MLPToolbox::CNeuralNetwork mlp = + MLPToolbox::CNeuralNetwork("src/SU2/UnitTests/Common/toolboxes/multilayer_perceptron/simple_mlp.mlp"); - /*--- Define MLP inputs and outputs ---*/ - MLP_input_names.resize(2); - MLP_input_names[0] = "x"; - MLP_input_names[1] = "y"; - MLP_inputs.resize(2); + ANN.AddNetwork(&mlp); + su2double x, y, z, z_alt; - MLP_outputs.resize(1); - MLP_output_names.resize(1); - MLP_output_names[0] = "z"; - MLP_outputs[0] = &z; + /*--- Create a query where the value of z is calculated from x and y ---*/ + MLPToolbox::CIOMap iomap_ref; + iomap_ref.AddQueryInput("x", &x); + iomap_ref.AddQueryInput("y", &y); + iomap_ref.AddQueryOutput("z", &z); - /*--- Generate input-output map ---*/ - MLPToolbox::CIOMap iomap(MLP_input_names, MLP_output_names); - ANN.PairVariableswithMLPs(iomap); - /*--- MLP evaluation on point in the middle of the training data range ---*/ + ANN.PairVariableswithMLPs(iomap_ref); + + MLPToolbox::CIOMap iomap_vec; + std::vector input_names = {"x", "y"}, output_names = {"z"}; + std::vector output_refs = {&z_alt}; + std::vector mlp_inputs; + + iomap_vec.SetQueryInput(input_names); + iomap_vec.SetQueryOutput(output_names); + ANN.PairVariableswithMLPs(iomap_vec); + + /*--- MLP evaluation on two points in the middle of the training data range ---*/ x = 1.0; y = -0.5; - MLP_inputs[0] = x; - MLP_inputs[1] = y; - ANN.PredictANN(&iomap, MLP_inputs, MLP_outputs); + bool inside = ANN.Predict(iomap_ref); CHECK(z == Approx(0.344829)); + CHECK(inside); + + mlp_inputs.resize(2); + mlp_inputs[0] = x; + mlp_inputs[1] = y; + ANN.Predict(iomap_vec, mlp_inputs, output_refs); + CHECK(z == z_alt); + + x = 0.5; + y = -0.23; + inside = ANN.Predict(iomap_ref); + + CHECK(z == Approx(0.224986)); + CHECK(inside); + + mlp_inputs[0] = x; + mlp_inputs[1] = y; + ANN.Predict(iomap_vec, mlp_inputs, output_refs); - /*--- MLP evaluation on point outside the training data range ---*/ - x = 3.0; - y = -10; - MLP_inputs[0] = x; - MLP_inputs[1] = y; - ANN.PredictANN(&iomap, MLP_inputs, MLP_outputs); - CHECK(z == Approx(0.012737)); + /*--- */ + x = 10.0; + y = -20.0; + inside = ANN.Predict(iomap_ref); + CHECK(!inside); } #endif diff --git a/UnitTests/Common/toolboxes/multilayer_perceptron/MLP_Jacobian_tests.cpp b/UnitTests/Common/toolboxes/multilayer_perceptron/MLP_Jacobian_tests.cpp new file mode 100644 index 000000000000..b2277d7d1b5b --- /dev/null +++ b/UnitTests/Common/toolboxes/multilayer_perceptron/MLP_Jacobian_tests.cpp @@ -0,0 +1,119 @@ +/*! + * \file MLP_Jacobian_tests.cpp + * \brief Check if MLP is differentiable + * \author E.C.Bunschoten + * \version 8.4.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 . + */ + +#include "catch.hpp" +#include "../../../../Common/include/CConfig.hpp" +#if defined(HAVE_MLPCPP) +#define MLP_CUSTOM_TYPE su2double +#include "../../../../subprojects/MLPCpp/include/CLookUp_ANN.hpp" +#define USE_MLPCPP +#endif +#include + +#ifdef USE_MLPCPP +TEST_CASE("MLP Jacobian test", "[LookUpANN]") { + /* Create network with random weights */ + std::vector NN = {3, 10, 10, 1}; + MLPToolbox::CNeuralNetwork mlp = MLPToolbox::CNeuralNetwork(NN); + mlp.SetActivationFunction("gelu"); + mlp.RandomWeights(); + + /* Enable Jacobian and Hessian computation */ + mlp.CalcJacobian(true); + mlp.CalcHessian(true); + + /* Network input values */ + su2double val_in_1, val_in_2, val_in_3; + val_in_1 = 0.2; + val_in_2 = 0.3; + val_in_3 = 0.9; + + /* Calculate Jacobians with AD */ + AD::Reset(); + AD::StartRecording(); + AD::RegisterInput(val_in_1); + AD::RegisterInput(val_in_2); + AD::RegisterInput(val_in_3); + + mlp.SetInput(0, val_in_1); + mlp.SetInput(1, val_in_2); + mlp.SetInput(2, val_in_3); + mlp.Predict(); + + su2double val_out = mlp.GetOutput(0); + + AD::RegisterOutput(val_out); + AD::StopRecording(); + SU2_TYPE::SetDerivative(val_out, 1.0); + AD::ComputeAdjoint(); + const su2double jacobian_AD_1 = SU2_TYPE::GetDerivative(val_in_1); + const su2double jacobian_AD_2 = SU2_TYPE::GetDerivative(val_in_2); + const su2double jacobian_AD_3 = SU2_TYPE::GetDerivative(val_in_3); + + /* Retrieve analytical Jacobians */ + const su2double jacobian_ref_1 = mlp.GetJacobian(0, 0); + const su2double jacobian_ref_2 = mlp.GetJacobian(0, 1); + const su2double jacobian_ref_3 = mlp.GetJacobian(0, 2); + + /* Unit tests for Jacobians */ + CHECK(SU2_TYPE::GetValue(jacobian_AD_1) == Approx(SU2_TYPE::GetValue(jacobian_ref_1))); + CHECK(SU2_TYPE::GetValue(jacobian_AD_2) == Approx(SU2_TYPE::GetValue(jacobian_ref_2))); + CHECK(SU2_TYPE::GetValue(jacobian_AD_3) == Approx(SU2_TYPE::GetValue(jacobian_ref_3))); + + /* Calculate Hessians with AD */ + AD::Reset(); + AD::StartRecording(); + AD::RegisterInput(val_in_1); + AD::RegisterInput(val_in_2); + AD::RegisterInput(val_in_3); + + mlp.SetInput(0, val_in_1); + mlp.SetInput(1, val_in_2); + mlp.SetInput(2, val_in_3); + mlp.Predict(); + + su2double jacobian_analytical = mlp.GetJacobian(0, 0); + + AD::RegisterOutput(jacobian_analytical); + AD::StopRecording(); + SU2_TYPE::SetDerivative(jacobian_analytical, 1.0); + AD::ComputeAdjoint(); + const su2double hessian_AD_1 = SU2_TYPE::GetDerivative(val_in_1); + const su2double hessian_AD_2 = SU2_TYPE::GetDerivative(val_in_2); + const su2double hessian_AD_3 = SU2_TYPE::GetDerivative(val_in_3); + + /* Retrieve analytical Hessians */ + const su2double hessian_ref_1 = mlp.GetHessian(0, 0, 0); + const su2double hessian_ref_2 = mlp.GetHessian(0, 0, 1); + const su2double hessian_ref_3 = mlp.GetHessian(0, 0, 2); + + /* Unit tests on Hessians */ + CHECK(SU2_TYPE::GetValue(hessian_AD_1) == Approx(SU2_TYPE::GetValue(hessian_ref_1))); + CHECK(SU2_TYPE::GetValue(hessian_AD_2) == Approx(SU2_TYPE::GetValue(hessian_ref_2))); + CHECK(SU2_TYPE::GetValue(hessian_AD_3) == Approx(SU2_TYPE::GetValue(hessian_ref_3))); +} +#endif diff --git a/UnitTests/meson.build b/UnitTests/meson.build index 3e64cfb9aa3d..40b54cf69717 100644 --- a/UnitTests/meson.build +++ b/UnitTests/meson.build @@ -19,10 +19,9 @@ su2_cfd_tests = files(['Common/geometry/primal_grid/CPrimalGrid_tests.cpp', 'SU2_CFD/windowing.cpp']) # Reverse-mode (algorithmic differentiation) tests: -su2_cfd_tests_ad = files(['Common/simple_ad_test.cpp']) -if get_option('enable-mlpcpp') - su2_cfd_tests_ad = su2_cfd_tests_ad + files(['SU2_CFD/fluid/CFluidModel_tests_AD.cpp']) -endif +su2_cfd_tests_ad = files(['Common/simple_ad_test.cpp', + 'SU2_CFD/fluid/CFluidModel_tests_AD.cpp', + 'Common/toolboxes/multilayer_perceptron/MLP_Jacobian_tests.cpp']) # Forward-mode (direct differentiation) tests: su2_cfd_tests_dd = files(['Common/simple_directdiff_test.cpp']) diff --git a/config_template.cfg b/config_template.cfg index e519f5971aaf..47b1ee28375a 100644 --- a/config_template.cfg +++ b/config_template.cfg @@ -459,11 +459,6 @@ DATADRIVEN_NEWTON_RELAXATION= 0.8 % Use physics-informed neural network for calculation of the fluid caloric properties. USE_PINN= YES -% Optional initial guess for fluid density and static energy in data-driven fluid analysis. -DATADRIVEN_INITIAL_DENSITY= -1 -DATADRIVEN_INITIAL_ENERGY= -1 - - % Specify if there is ionization IONIZATION= NO % @@ -1188,6 +1183,9 @@ MARKER_ENGINE_INFLOW= ( NONE ) % Format: (engine exhaust marker, total nozzle temp, total nozzle pressure, ... ) MARKER_ENGINE_EXHAUST= ( NONE ) % +% Flag to allow mass-flow rate coupling between all exhaust surfaces and the engine inlet (YES, NO) +ENGINE_EXHAUST_TO_INLET= NO +% % Displacement boundary marker(s) (NONE = no marker) % Format: ( displacement marker, displacement value normal to the surface, ... ) MARKER_NORMAL_DISPL= ( NONE ) @@ -1416,6 +1414,10 @@ MARKER_ANALYZE = ( airfoil ) % % Method to compute the average value in MARKER_ANALYZE (AREA, MASSFLUX). MARKER_ANALYZE_AVERAGE = MASSFLUX +% +% Duplicate markers while reading the mesh. Currently this is only used for thermoelastic simulations +% to allow specifying two boundary conditions (thermal and structural) on the same boundary. +MARKER_CREATE_COPY= ( original_1, copy_1, ..., original_n, copy_n ) % ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% % @@ -1674,6 +1676,10 @@ USE_VECTORIZATION= YES % artificial dissipation) ENTROPY_FIX_COEFF= 0.0 % +% MSW coefficient for blending states based on pressure jump. +% Using 0 makes the scheme average left and right regardless of pressure. +MSW_ALPHA= 5.0 +% % Higher values than 1 (3 to 4) make the global Jacobian of central schemes (compressible flow % only) more diagonal dominant (but mathematically incorrect) so that higher CFL can be used. CENTRAL_JACOBIAN_FIX_FACTOR= 4.0 @@ -2360,7 +2366,7 @@ GRAD_LINEAR_SOLVER_ERROR= 1E-14 % ------------------------- SCREEN/HISTORY VOLUME OUTPUT --------------------------% % % Screen output fields (use 'SU2_CFD -d ' to view list of available fields) -SCREEN_OUTPUT= (INNER_ITER, RMS_DENSITY, RMS_MOMENTUM-X, RMS_MOMENTUM-Y, RMS_ENERGY) +SCREEN_OUTPUT= (INNER_ITER, ITER_TIME, RMS_DENSITY, RMS_MOMENTUM-X, RMS_MOMENTUM-Y, RMS_ENERGY) % % History output groups (use 'SU2_CFD -d ' to view list of available fields) HISTORY_OUTPUT= (ITER, RMS_RES) diff --git a/externals/CLI11/CLI11.hpp b/externals/CLI11/CLI11.hpp index 5c880875042b..2b859cc3999c 100644 --- a/externals/CLI11/CLI11.hpp +++ b/externals/CLI11/CLI11.hpp @@ -62,6 +62,7 @@ #include #include #include +#include // Verbatim copy from CLI/Version.hpp: diff --git a/externals/cgns/hdf5/meson.build b/externals/cgns/hdf5/meson.build index 782e1771a289..8b34eeebe708 100644 --- a/externals/cgns/hdf5/meson.build +++ b/externals/cgns/hdf5/meson.build @@ -16,7 +16,9 @@ if target_machine.system() != 'windows' and cc.get_id() != 'intel' '-Wno-pedantic', '-Wno-error=stringop-truncation', '-Wno-error=cast-function-type', - '-Wno-stringop-truncation'] + '-Wno-stringop-truncation', + '-Wno-dangling-pointer', + '-Wno-format-truncation'] foreach flag : desired_warnings if cc.has_argument(flag) hdf5_default_warnings += flag diff --git a/externals/cgns/meson.build b/externals/cgns/meson.build index 6444e810eb78..47885e893d7b 100644 --- a/externals/cgns/meson.build +++ b/externals/cgns/meson.build @@ -11,7 +11,13 @@ if build_machine.system() != 'windows' and meson.get_compiler('c').get_id() != ' '-Wno-error=stringop-truncation', '-Wno-stringop-truncation', '-Wno-error=absolute-value', - '-Wno-error=class-memaccess'] + '-Wno-error=class-memaccess', + '-Wno-dangling-pointer', + '-Wno-format-truncation', + '-Wno-maybe-uninitialized', + '-Wno-array-bounds', + '-Wno-array-parameter', + '-Wno-stringop-overflow'] foreach flag : desired_warnings if meson.get_compiler('c').has_argument(flag) cgns_default_warnings += flag diff --git a/externals/tecio/boost.tar.gz b/externals/tecio/boost.tar.gz index 9943d19de426..1c1d78fc2d3d 100644 Binary files a/externals/tecio/boost.tar.gz and b/externals/tecio/boost.tar.gz differ diff --git a/externals/tecio/meson.build b/externals/tecio/meson.build index 3ff0218ff039..693984be4d2d 100644 --- a/externals/tecio/meson.build +++ b/externals/tecio/meson.build @@ -1,11 +1,11 @@ -check_dir = run_command(python, +check_dir = run_command(python, script_path / 'check_dir.py', 'boost') if check_dir.returncode() != 0 message('Extracting boost ...') - extract_boost = run_command(python, + extract_boost = run_command(python, script_path / 'extract_file.py', - 'boost.tar.gz', + 'boost.tar.gz', meson.current_source_dir(), check: true) else message('Boost sources found.') diff --git a/externals/tecio/teciompisrc/meson.build b/externals/tecio/teciompisrc/meson.build index 420447098369..2598f078b8a3 100644 --- a/externals/tecio/teciompisrc/meson.build +++ b/externals/tecio/teciompisrc/meson.build @@ -22,7 +22,10 @@ if build_machine.system() != 'windows' and meson.get_compiler('cpp').get_id() != '-Wno-error=deprecated-copy', '-Wno-deprecated-copy', '-Wno-error=cast-function-type', - '-Wno-cast-function-type'] + '-Wno-cast-function-type', + '-Wno-free-nonheap-object', + '-Wno-deprecated-copy', + '-Wno-array-bounds'] foreach flag : desired_warnings if meson.get_compiler('cpp').has_argument(flag) tec_cxx_flags += flag @@ -103,9 +106,9 @@ teciompi = static_library('teciompi', 'TecioSZL.cpp', 'exportSubzonePlt.cpp', install : false, - dependencies: [mpi_dep], + dependencies: [mpi_dep], cpp_args: [default_warning_flags, tec_cxx_flags], - include_directories: + include_directories: teciompi_include) teciompi_dep = declare_dependency(link_with: teciompi, diff --git a/externals/tecio/teciosrc/meson.build b/externals/tecio/teciosrc/meson.build index ab7e985549bf..caed8227519c 100644 --- a/externals/tecio/teciosrc/meson.build +++ b/externals/tecio/teciosrc/meson.build @@ -17,7 +17,10 @@ if build_machine.system() != 'windows' and meson.get_compiler('cpp').get_id() != '-Wno-uninitialized', '-Wno-placement-new', '-Wno-pedantic', - '-Wno-error=deprecated-copy'] + '-Wno-error=deprecated-copy', + '-Wno-free-nonheap-object', + '-Wno-deprecated-copy', + '-Wno-array-bounds'] foreach flag : desired_warnings if meson.get_compiler('cpp').has_argument(flag) tecio_cpp_flags += flag diff --git a/meson.build b/meson.build index 8ceab579b765..5a46b12431f5 100644 --- a/meson.build +++ b/meson.build @@ -27,10 +27,8 @@ su2_deps = [declare_dependency(include_directories: 'externals/CLI11')] default_warning_flags = [] if build_machine.system() != 'windows' - if meson.get_compiler('cpp').get_id() != 'intel' - default_warning_flags += ['-Wno-empty-body'] - endif - desired_warnings = ['-Wno-ignored-qualifiers', + desired_warnings = ['-Wno-empty-body', + '-Wno-ignored-qualifiers', '-Wno-unused-parameter', '-Wno-deprecated-declarations', '-Wno-error=cast-function-type', @@ -40,7 +38,10 @@ if build_machine.system() != 'windows' '-Wno-error=missing-field-initializers', '-Wno-missing-field-initializers', '-Wno-error=class-memaccess', - '-Wno-class-memaccess'] + '-Wno-class-memaccess', + '-Wno-overloaded-virtual', + '-Wno-array-bounds', + '-Wno-dangling-pointer'] foreach flag : desired_warnings if meson.get_compiler('cpp').has_argument(flag) default_warning_flags += flag @@ -52,6 +53,15 @@ if build_machine.system() != 'windows' endif endif +if get_option('cpu-arch') != '' + su2_cpp_args += ['-march=' + get_option('cpu-arch')] +endif + +# Fast math to allow pow(x, 2) -> x * x. +if meson.get_compiler('cpp').has_argument('-fno-finite-math-only') + su2_cpp_args += ['-ffast-math', '-fno-finite-math-only'] +endif + # Handle assertions: default is b_ndebug=true (assertions disabled) # but for debug builds, we want to enable assertions if get_option('buildtype') == 'debug' @@ -208,18 +218,10 @@ if get_option('enable-pastix') 'PaStiX support requires either mkl or openblas') su2_cpp_args += '-DHAVE_PASTIX' - - pastix_dep = dependency('pastix', required: false) - - if not pastix_dep.found() - pastix_root = get_option('pastix_root')+'/install' - scotch_root = get_option('scotch_root')+'/lib' - pastix_dep = declare_dependency(include_directories: pastix_root, - link_args: [ '-L../'+pastix_root, '-L../'+scotch_root, - '-lpastix', '-lscotch', '-lptscotch', '-lptscotcherr', - '-lm', '-lrt', '-lpthread']) - endif - su2_deps += pastix_dep + su2_deps += dependency('pastix') + su2_deps += meson.get_compiler('cpp').find_library('scotch', required: true) + su2_deps += meson.get_compiler('cpp').find_library('scotcherr', required: true) + su2_deps += meson.get_compiler('cpp').find_library('ptscotch', required: true) endif # CUDA dependencies @@ -250,9 +252,11 @@ elif get_option('enable-openblas') su2_cpp_args += '-DHAVE_BLAS' su2_cpp_args += '-DHAVE_LAPACK' - blas_dep = dependency(get_option('blas-name')) - su2_deps += blas_dep - + su2_deps += dependency(get_option('blas-name')) + su2_deps += dependency('lapack') + if get_option('enable-pastix') + su2_deps += dependency('lapacke') + endif endif if get_option('enable-librom') @@ -309,6 +313,11 @@ if get_option('enable-coolprop') if build_machine.cpu_family() == 'x86' or build_machine.cpu_family() == 'x86_64' cmake = import('cmake') cmake_opts = cmake.subproject_options() + if get_option('cpu-arch') != '' + cmake_opts.add_cmake_defines({ + 'CMAKE_CXX_FLAGS': '-march=' + get_option('cpu-arch') + }) + endif cmake_opts.set_override_option('warning_level', '0') cmake_opts.add_cmake_defines({ 'COOLPROP_STATIC_LIBRARY': true, diff --git a/meson_options.txt b/meson_options.txt index dcecd404204a..f460f6b1e139 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,26 +1,25 @@ -option('with-mpi', type : 'feature', value : 'auto', description: 'enable MPI support') -option('with-omp', type : 'boolean', value : false, description: 'enable OpenMP support') +option('with-mpi', type : 'feature', value : 'auto', description: 'enable MPI support') +option('with-omp', type : 'boolean', value : false, description: 'enable OpenMP support') +option('cpu-arch', type : 'string', value : 'native', description: 'CPU architecture optimization, important for vectorization') option('enable-tecio', type : 'boolean', value : true, description: 'enable TECIO support') -option('enable-cgns', type : 'boolean', value : true, description: 'enable CGNS support') -option('enable-autodiff', type : 'boolean', value : false, description: 'enable AD (reverse) support') -option('enable-directdiff', type : 'boolean', value : false, description: 'enable AD (forward) support') -option('enable-pywrapper', type : 'boolean', value : false, description: 'enable Python wrapper support') -option('enable-normal', type : 'boolean', value : true, description: 'enable normal build') +option('enable-cgns', type : 'boolean', value : true, description: 'enable CGNS support') +option('enable-autodiff', type : 'boolean', value : false, description: 'enable AD (reverse) support') +option('enable-directdiff', type : 'boolean', value : false, description: 'enable AD (forward) support') +option('enable-pywrapper', type : 'boolean', value : false, description: 'enable Python wrapper support') +option('enable-normal', type : 'boolean', value : true, description: 'enable normal build') option('enable-mkl', type : 'boolean', value : false, description: 'enable Intel-MKL support') option('mkl_root', type : 'string', value : '/opt/intel/mkl', description: 'root of Intel-MKL installation (only for non-intel compilers)') option('enable-openblas', type : 'boolean', value : false, description: 'enable BLAS and LAPACK support via OpenBLAS') option('enable-cuda', type : 'boolean', value : false, description: 'enable GPU acceleration using CUDA') option('blas-name', type : 'string', value : 'openblas', description: 'name of the BLAS/LAPACK dependency') option('enable-pastix', type : 'boolean', value : false, description: 'enable PaStiX support') -option('pastix_root', type : 'string', value : 'externals/pastix/', description: 'PaStiX base directory') -option('scotch_root', type : 'string', value : 'externals/scotch/', description: 'Scotch base directory') 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('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('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') -option('enable-coolprop', type : 'boolean', value : false, description: 'enable CoolProp support') +option('enable-coolprop', type : 'boolean', value : false, description: 'enable CoolProp support') option('enable-mlpcpp', type : 'boolean', value : false, description: 'enable MLPCpp support') option('enable-gprof', type : 'boolean', value : false, description: 'enable profiling through gprof') option('opdi-backend', type : 'combo', choices : ['auto', 'macro', 'ompt'], value : 'auto', description: 'OpDiLib backend choice') diff --git a/meson_scripts/init.py b/meson_scripts/init.py index 334c1950024d..858456015f13 100755 --- a/meson_scripts/init.py +++ b/meson_scripts/init.py @@ -68,16 +68,21 @@ def init_submodules( github_repo_ninja = "https://github.com/ninja-build/ninja" sha_version_mpp = "5ff579f43781cae07411e5ab46291c9971536be6" github_repo_mpp = "https://github.com/mutationpp/Mutationpp" - sha_version_coolprop = "bafdea1f39ee873a6bb9833e3a21fe41f90b85e8" + sha_version_coolprop = "98b3523d5daa98454618d381d2ae53f7471d216b" github_repo_coolprop = "https://github.com/CoolProp/CoolProp" sha_version_mel = "46205ab019e5224559091375a6d71aabae6bc5b9" github_repo_mel = "https://github.com/pcarruscag/MEL" sha_version_fado = "ce7ee018e4e699af5028d69baa1939fea290e18a" github_repo_fado = "https://github.com/pcarruscag/FADO" - sha_version_mlpcpp = "ff57e0cf9e60127196d3f1be71e711d47ff646ef" + sha_version_mlpcpp = "02f2cb9dde791074858e11ac091f7c4df9c6af65" github_repo_mlpcpp = "https://github.com/EvertBunschoten/MLPCpp" sha_version_eigen = "d71c30c47858effcbd39967097a2d99ee48db464" github_repo_eigen = "https://gitlab.com/libeigen/eigen.git" + # The download paths for gitlab are different than github so we need this ad-hoc fix. + # NOTE: Update the Eigen version in download_module when changing this. + download_eigen = ( + "https://gitlab.com/libeigen/eigen/-/archive/3.4/eigen-3.4.zip?ref_type=heads" + ) medi_name = "MeDiPack" codi_name = "CoDiPack" @@ -180,7 +185,11 @@ def init_submodules( ) if own_eigen: download_module( - eigen_name, alt_name_eigen, github_repo_eigen, sha_version_eigen + eigen_name, + alt_name_eigen, + github_repo_eigen, + sha_version_eigen, + download_eigen, ) @@ -260,7 +269,7 @@ def submodule_status(path, sha_commit): ) -def download_module(name, alt_name, git_repo, commit_sha): +def download_module(name, alt_name, git_repo, commit_sha, download_url=None): # ZipFile does not preserve file permissions. # This is a workaround for that problem: # https://stackoverflow.com/questions/39296101/python-zipfile-removes-execute-permissions-from-binaries @@ -296,7 +305,7 @@ def _extract_member(self, member, targetpath, pwd): alt_filename = name + "-" + filename alt_filepath = os.path.join(sys.path[0], alt_filename) - url = git_repo + "/archive/" + filename + url = download_url or (git_repo + "/archive/" + filename) if not os.path.exists(filepath) and not os.path.exists(alt_filepath): try: @@ -321,7 +330,13 @@ def _extract_member(self, member, targetpath, pwd): if os.path.exists(alt_name): os.rmdir(alt_name) - os.rename(os.path.join(target_dir, name + "-" + commit_sha), alt_name) + try: + os.rename(os.path.join(target_dir, name + "-" + commit_sha), alt_name) + except FileNotFoundError: + if "eigen" in url: + os.rename(os.path.join(target_dir, "eigen-3.4"), alt_name) + else: + raise # Delete zip file remove_file(filepath) diff --git a/subprojects/CoolProp b/subprojects/CoolProp index bafdea1f39ee..98b3523d5daa 160000 --- a/subprojects/CoolProp +++ b/subprojects/CoolProp @@ -1 +1 @@ -Subproject commit bafdea1f39ee873a6bb9833e3a21fe41f90b85e8 +Subproject commit 98b3523d5daa98454618d381d2ae53f7471d216b diff --git a/subprojects/MLPCpp b/subprojects/MLPCpp index e19ca0cafb28..02f2cb9dde79 160000 --- a/subprojects/MLPCpp +++ b/subprojects/MLPCpp @@ -1 +1 @@ -Subproject commit e19ca0cafb28c4b7ba5b8cffef42883259b00dc0 +Subproject commit 02f2cb9dde791074858e11ac091f7c4df9c6af65