diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml index d0c9b6519ef..cd916ffcfe5 100644 --- a/.github/workflows/regression.yml +++ b/.github/workflows/regression.yml @@ -52,12 +52,12 @@ jobs: key: ${{ matrix.config_set }}-${{ github.sha }} restore-keys: ${{ matrix.config_set }} - name: Pre Cleanup - uses: docker://ghcr.io/su2code/su2/build-su2:230813-0103 + uses: docker://ghcr.io/su2code/su2/build-su2:240320-1536 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:230813-0103 + uses: docker://ghcr.io/su2code/su2/build-su2:240320-1536 with: args: -b ${{github.ref}} -f "${{matrix.flags}}" - name: Compress binaries @@ -68,7 +68,7 @@ jobs: name: ${{ matrix.config_set }} path: install_bin.tgz - name: Post Cleanup - uses: docker://ghcr.io/su2code/su2/build-su2:230813-0103 + uses: docker://ghcr.io/su2code/su2/build-su2:240320-1536 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} @@ -95,12 +95,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:230813-0103 + uses: docker://ghcr.io/su2code/su2/build-su2-tsan:240320-1536 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:230813-0103 + uses: docker://ghcr.io/su2code/su2/build-su2-tsan:240320-1536 with: args: -b ${{github.ref}} -f "${{matrix.flags}}" - name: Compress binaries @@ -111,7 +111,45 @@ jobs: name: ${{ matrix.config_set }} path: install_bin.tgz - name: Post Cleanup - uses: docker://ghcr.io/su2code/su2/build-su2-tsan:230813-0103 + uses: docker://ghcr.io/su2code/su2/build-su2-tsan:240320-1536 + with: + entrypoint: /bin/rm + args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} + build_asan: + name: Build SU2 (asan) + strategy: + fail-fast: false + matrix: + 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' + - config_set: ReverseNoMPI-asan + flags: '--buildtype=debugoptimized -Denable-autodiff=true -Denable-normal=false -Dwith-mpi=disabled --warnlevel=3 --werror' + runs-on: ${{ inputs.runner || 'ubuntu-latest' }} + steps: + - name: Cache Object Files + uses: actions/cache@v4 + with: + path: ccache + key: ${{ matrix.config_set }}-${{ github.sha }} + restore-keys: ${{ matrix.config_set }} + - name: Pre Cleanup + uses: docker://ghcr.io/su2code/su2/build-su2-asan:240320-1536 + 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:240320-1536 -b ${{github.ref}} -f "${{matrix.flags}}" + - name: Compress binaries + run: tar -zcvf install_bin.tgz install/* + - name: Upload Binaries + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.config_set }} + path: install_bin.tgz + - name: Post Cleanup + uses: docker://ghcr.io/su2code/su2/build-su2-asan:240320-1536 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} @@ -142,7 +180,7 @@ jobs: tag: OMP steps: - name: Pre Cleanup - uses: docker://ghcr.io/su2code/su2/test-su2:230813-0103 + uses: docker://ghcr.io/su2code/su2/test-su2:240320-1536 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} @@ -168,12 +206,12 @@ jobs: chmod a+x $BIN_FOLDER/* ls -lahR $BIN_FOLDER - name: Run Tests in Container - uses: docker://ghcr.io/su2code/su2/test-su2:230813-0103 + uses: docker://ghcr.io/su2code/su2/test-su2:240320-1536 with: # -t -c - args: -b ${{github.ref}} -t develop -c develop -s ${{matrix.testscript}} + args: -b ${{github.ref}} -t feature_solid-solid_cht -c develop -s ${{matrix.testscript}} - name: Cleanup - uses: docker://ghcr.io/su2code/su2/test-su2:230813-0103 + uses: docker://ghcr.io/su2code/su2/test-su2:240320-1536 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} @@ -188,7 +226,7 @@ jobs: testscript: ['hybrid_regression.py', 'hybrid_regression_AD.py'] steps: - name: Pre Cleanup - uses: docker://ghcr.io/su2code/su2/test-su2-tsan:230813-0103 + uses: docker://ghcr.io/su2code/su2/test-su2-tsan:240320-1536 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} @@ -214,12 +252,57 @@ jobs: chmod a+x $BIN_FOLDER/* ls -lahR $BIN_FOLDER - name: Run Tests in Container - uses: docker://ghcr.io/su2code/su2/test-su2-tsan:230813-0103 + uses: docker://ghcr.io/su2code/su2/test-su2-tsan:240320-1536 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:230813-0103 + uses: docker://ghcr.io/su2code/su2/test-su2-tsan:240320-1536 + with: + entrypoint: /bin/rm + args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} + address_sanitizer_tests: + runs-on: ${{ inputs.runner || 'ubuntu-latest' }} + name: Address Sanitizer Tests + needs: build_asan + strategy: + fail-fast: false + matrix: + testscript: ['serial_regression.py', 'serial_regression_AD.py'] + steps: + - name: Pre Cleanup + uses: docker://ghcr.io/su2code/su2/test-su2-asan:240320-1536 + with: + entrypoint: /bin/rm + args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} + - name: Download All artifacts + uses: actions/download-artifact@v4 + - name: Uncompress and Move Binaries + run: | + BIN_FOLDER="$PWD/install/bin" + mkdir -p $BIN_FOLDER + ls -lah $BIN_FOLDER + for type in Base Reverse Forward; do + TYPE_FOLDER="${type}NoMPI-asan" + echo "Processing '$TYPE_FOLDER' ..." + if [ -d $TYPE_FOLDER ]; then + pushd $TYPE_FOLDER + ls -lah + tar -zxvf install_bin.tgz + ls -lah install/bin/ + cp -r install/* $BIN_FOLDER/../ + popd; + fi + done + chmod a+x $BIN_FOLDER/* + ls -lahR $BIN_FOLDER + - name: Run Tests in Container + uses: docker://ghcr.io/su2code/su2/test-su2-asan:240320-1536 + 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:240320-1536 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} @@ -240,7 +323,7 @@ jobs: tag: MPI steps: - name: Pre Cleanup - uses: docker://ghcr.io/su2code/su2/test-su2:230813-0103 + uses: docker://ghcr.io/su2code/su2/test-su2:240320-1536 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} @@ -301,11 +384,11 @@ jobs: echo $PWD ls -lahR - name: Run Unit Tests - uses: docker://ghcr.io/su2code/su2/test-su2:230813-0103 + uses: docker://ghcr.io/su2code/su2/test-su2:240320-1536 with: entrypoint: install/bin/${{matrix.testdriver}} - name: Post Cleanup - uses: docker://ghcr.io/su2code/su2/test-su2:230813-0103 + uses: docker://ghcr.io/su2code/su2/test-su2:240320-1536 with: entrypoint: /bin/rm args: -rf install install_bin.tgz src ccache ${{ matrix.config_set }} diff --git a/AUTHORS.md b/AUTHORS.md index f8c364f411b..511ebcf4b33 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -69,6 +69,7 @@ Daumantas Kavolis Dave Taflin Eduardo Molina Edwin van der Weide +Eitan Aberman Ethan Alan Hereth Florian Dittmann Filip Hahs @@ -108,6 +109,7 @@ Max Sagebaum Michele Gaffuri Mickael Philit Mladen Banovic +Mor Nat-1 Nicola Fonzi Nijso Beishuizen @@ -137,6 +139,7 @@ Trent Lukaczyk Vinzenz Götz VivaanKhatri Wally Maier +Yair Mor-Yossef Y. Chandukrishna Zan Xu Zcaic diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index c28c3aaef54..0bec4282207 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -192,6 +192,7 @@ class CConfig { nMarker_Fluid_Load, /*!< \brief Number of markers in which the flow load is computed/employed. */ nMarker_Fluid_InterfaceBound, /*!< \brief Number of fluid interface markers. */ nMarker_CHTInterface, /*!< \brief Number of conjugate heat transfer interface markers. */ + nMarker_ContactResistance, /*!< \brief Number of CHT interfaces with contact resistance. */ nMarker_Inlet, /*!< \brief Number of inlet flow markers. */ nMarker_Inlet_Species, /*!< \brief Number of inlet species markers. */ nSpecies_per_Inlet, /*!< \brief Number of species defined per inlet markers. */ @@ -235,6 +236,7 @@ class CConfig { *Marker_MixingPlaneInterface, /*!< \brief MixingPlane interface boundary markers. */ *Marker_TurboBoundIn, /*!< \brief Turbomachinery performance boundary markers. */ *Marker_TurboBoundOut, /*!< \brief Turbomachinery performance boundary donor markers. */ + *Marker_Turbomachinery, /*!< \breif Turbomachinery markers */ *Marker_NearFieldBound, /*!< \brief Near Field boundaries markers. */ *Marker_Deform_Mesh, /*!< \brief Deformable markers at the boundary. */ *Marker_Deform_Mesh_Sym_Plane, /*!< \brief Marker with symmetric deformation. */ @@ -396,6 +398,7 @@ class CConfig { su2double **Periodic_RotCenter; /*!< \brief Rotational center for each periodic boundary. */ su2double **Periodic_RotAngles; /*!< \brief Rotation angles for each periodic boundary. */ su2double **Periodic_Translation; /*!< \brief Translation vector for each periodic boundary. */ + su2double *CHT_ContactResistance; /*!< \brief Contact resistance values for each solid-solid CHT interface. */ string *Marker_CfgFile_TagBound; /*!< \brief Global index for markers using config file. */ unsigned short *Marker_All_KindBC, /*!< \brief Global index for boundaries using grid information. */ *Marker_CfgFile_KindBC; /*!< \brief Global index for boundaries using config file. */ @@ -440,6 +443,7 @@ class CConfig { TURBO_PERF_KIND *Kind_TurboPerf; /*!< \brief Kind of turbomachynery architecture.*/ TURBOMACHINERY_TYPE *Kind_TurboMachinery; + su2vector Kind_TurboInterface; /* Gradient smoothing options */ su2double SmoothingEps1; /*!< \brief Parameter for the identity part in gradient smoothing. */ @@ -463,6 +467,7 @@ class CConfig { unsigned short* nDV_Value; /*!< \brief Number of values for each design variable (might be different than 1 if we allow arbitrary movement). */ unsigned short nFFDBox; /*!< \brief Number of ffd boxes. */ unsigned short nTurboMachineryKind; /*!< \brief Number turbomachinery types specified. */ + unsigned short nTurboInterfaces; /*!< \brief Number of turbomachiery interfaces */ unsigned short nParamDV; /*!< \brief Number of parameters of the design variable. */ string DV_Filename; /*!< \brief Filename for providing surface positions from an external parameterization. */ string DV_Unordered_Sens_Filename; /*!< \brief Filename of volume sensitivities in an unordered ASCII format. */ @@ -589,6 +594,7 @@ class CConfig { bool EulerPersson; /*!< \brief Boolean to determine whether this is an Euler simulation with Persson shock capturing. */ bool FSI_Problem = false,/*!< \brief Boolean to determine whether the simulation is FSI or not. */ Multizone_Problem; /*!< \brief Boolean to determine whether we are solving a multizone problem. */ + //bool ContactResistance = false; /*!< \brief Apply contact resistance for conjugate heat transfer. */ unsigned short nID_DV; /*!< \brief ID for the region of FEM when computed using direct differentiation. */ bool AD_Mode; /*!< \brief Algorithmic Differentiation support. */ @@ -1224,7 +1230,13 @@ class CConfig { unsigned short nSpecies_Init; /*!< \brief Number of entries of SPECIES_INIT */ /*--- Additional flamelet solver options ---*/ - su2double flame_init[8]; /*!< \brief Initial solution parameters for flamelet solver.*/ + ///TODO: Add python wrapper initialization option + FLAMELET_INIT_TYPE flame_init_type = FLAMELET_INIT_TYPE::NONE; /*!< \brief Method for solution ignition for flamelet problems. */ + std::array flame_init; /*!< \brief Flame front initialization parameters. */ + std::array spark_init; /*!< \brief Spark ignition initialization parameters. */ + su2double* spark_reaction_rates; /*!< \brief Source terms for flamelet spark ignition option. */ + unsigned short nspark; /*!< \brief Number of source terms for spark initialization. */ + bool preferential_diffusion = false; /*!< \brief Preferential diffusion physics for flamelet solver.*/ /*--- lookup table ---*/ unsigned short n_scalars = 0; /*!< \brief Number of transported scalars for flamelet LUT approach. */ @@ -1363,7 +1375,7 @@ class CConfig { su2double** & RotCenter, su2double** & RotAngles, su2double** & Translation); void addTurboPerfOption(const string & name, unsigned short & nMarker_TurboPerf, - string* & Marker_TurboBoundIn, string* & Marker_TurboBoundOut); + string* & Marker_TurboBoundIn, string* & Marker_TurboBoundOut, string* & Marker_Turbomachinery); void addActDiskOption(const string & name, unsigned short & nMarker_ActDiskInlet, unsigned short & nMarker_ActDiskOutlet, string* & Marker_ActDiskInlet, string* & Marker_ActDiskOutlet, @@ -2138,13 +2150,44 @@ class CConfig { /*! * \brief Get the flame initialization. - * (x1,x2,x3) = flame offset. - * (x4,x5,x6) = flame normal, separating unburnt from burnt. + * (x1,x2,x3) = flame offset/spark center location. + * (x4,x5,x6) = flame normal, separating unburnt from burnt or + * spark radius, spark start iteration, spark duration. * (x7) = flame thickness, the length from unburnt to burnt conditions. * (x8) = flame burnt thickness, the length to stay at burnt conditions. - * \return Flame initialization for the flamelet model. + * \return Ignition initialization parameters for the flamelet model. + */ + const su2double* GetFlameInit() const { + switch (flame_init_type) + { + case FLAMELET_INIT_TYPE::FLAME_FRONT: + return flame_init.data(); + break; + case FLAMELET_INIT_TYPE::SPARK: + return spark_init.data(); + break; + default: + return nullptr; + break; + } + } + + /*! + * \brief Get species net reaction rates applied during spark ignition. */ - const su2double* GetFlameInit() const { return flame_init; } + const su2double* GetSpark() const { + return spark_reaction_rates; + } + + /*! + * \brief Preferential diffusion combustion problem. + */ + bool GetPreferentialDiffusion() const { return preferential_diffusion; } + + /*! + * \brief Define preferential diffusion combustion problem. + */ + inline void SetPreferentialDiffusion(bool input) { preferential_diffusion = input; } /*! * \brief Get the number of control variables for flamelet model. @@ -2190,6 +2233,11 @@ class CConfig { if (n_user_sources > 0) return user_source_names[i_user_source]; else return none; } + /*! + * \brief Get the ignition method used for combustion problems. + */ + FLAMELET_INIT_TYPE GetFlameletInitType() const { return flame_init_type; } + /*! * \brief Get the number of transported scalars for combustion. */ @@ -2904,7 +2952,10 @@ class CConfig { * \brief Get the number of design variables. * \return Number of the design variables. */ - unsigned short GetnDV_Value(unsigned short iDV) const { return nDV_Value[iDV]; } + unsigned short GetnDV_Value(unsigned short iDV) const { + if (!nDV_Value) return 0; + return nDV_Value[iDV]; + } /*! * \brief Get the total number of design variables. @@ -3603,6 +3654,13 @@ class CConfig { */ unsigned short GetMarker_n_ZoneInterface(void) const { return nMarker_ZoneInterface; } + /*! + * \brief Get the contact resistance value of a specified interface. + * \param[in] val_interface interface index. + * \return Contact resistance value (zero by default). + */ + su2double GetContactResistance(unsigned short val_interface) const { return (nMarker_ContactResistance > 0) ? CHT_ContactResistance[val_interface] : 0.0; } + /*! * \brief Get the DV information for a marker val_marker. * \param[in] val_marker - 0 or 1 depending if the the marker is going to be affected by design variables. @@ -5088,7 +5146,7 @@ class CConfig { /*! * \brief Set Monitor Outlet Pressure value for the ramp. */ - void SetMonitotOutletPressure(su2double newMonPres) { MonitorOutletPressure = newMonPres;} + void SetMonitorOutletPressure(su2double newMonPres) { MonitorOutletPressure = newMonPres;} /*! * \brief Get Outlet Pressure Ramp option. @@ -5266,6 +5324,17 @@ class CConfig { */ TURBO_PERF_KIND GetKind_TurboPerf(unsigned short val_iZone) const { return Kind_TurboPerf[val_iZone]; }; + /*! + * \brief gets interface kind for an interface marker in turbomachinery problem + * \return interface kind + */ + TURBO_INTERFACE_KIND GetKind_TurboInterface(unsigned short interfaceIndex) const { return Kind_TurboInterface[interfaceIndex]; } + + /*! + * \brief Sets marker kind for an interface marker in turbomachinery problem + */ + void SetKind_TurboInterface(unsigned short interfaceIndex, TURBO_INTERFACE_KIND TurboInterfaceKind) {Kind_TurboInterface[interfaceIndex] = TurboInterfaceKind ;} + /*! * \brief get outlet bounds name for Turbomachinery performance calculation. * \return name of the bound. @@ -6796,7 +6865,7 @@ class CConfig { * \param[in] val_index - Index corresponding to the inlet boundary. * \return The total temperature. */ - su2double GetInlet_Ttotal(const string& val_index) const; + su2double GetInletTtotal(const string& val_index) const; /*! * \brief Get the temperature at a supersonic inlet boundary. @@ -6838,14 +6907,14 @@ class CConfig { * \param[in] val_index - Index corresponding to the inlet boundary. * \return The total pressure. */ - su2double GetInlet_Ptotal(const string& val_index) const; + su2double GetInletPtotal(const string& val_index) const; /*! * \brief Set the total pressure at an inlet boundary. * \param[in] val_pressure - Pressure value at the inlet boundary. * \param[in] val_index - Index corresponding to the inlet boundary. */ - void SetInlet_Ptotal(su2double val_pressure, const string& val_marker); + void SetInletPtotal(su2double val_pressure, const string& val_marker); /*! * \brief Get the species values at an inlet boundary @@ -6885,7 +6954,7 @@ class CConfig { * \param[in] val_index - Index corresponding to the inlet boundary. * \return The flow direction vector. */ - const su2double* GetInlet_FlowDir(const string& val_index) const; + const su2double* GetInletFlowDir(const string& val_index) const; /*! * \brief Get the back pressure (static) at an outlet boundary. diff --git a/Common/include/basic_types/ad_structure.hpp b/Common/include/basic_types/ad_structure.hpp index bdb13365056..c44374f7eb7 100644 --- a/Common/include/basic_types/ad_structure.hpp +++ b/Common/include/basic_types/ad_structure.hpp @@ -58,8 +58,13 @@ inline bool TapeActive() { return false; } /*! * \brief Prints out tape statistics. + * + * Tape statistics are aggregated across OpenMP threads and MPI processes, if applicable. + * With MPI, the given communicator is used to reduce data across MPI processes, and the printing behaviour can be set + * per rank (usually, only the master rank prints). */ -inline void PrintStatistics() {} +template +inline void PrintStatistics(Comm communicator, bool printingRank) {} /*! * \brief Registers the variable as an input. I.e. as a leaf of the computational graph. @@ -348,7 +353,77 @@ FORCEINLINE void StopRecording() { AD::getTape().setPassive(); } FORCEINLINE bool TapeActive() { return AD::getTape().isActive(); } -FORCEINLINE void PrintStatistics() { AD::getTape().printStatistics(); } +template +FORCEINLINE void PrintStatistics(Comm communicator, bool printingRank) { + if (printingRank) { + std::cout << "-------------------------------------------------------\n"; + std::cout << " Serial parts of the tape\n"; +#ifdef HAVE_MPI + std::cout << " (aggregated across MPI processes)\n"; +#endif + std::cout << "-------------------------------------------------------\n"; + } + + codi::TapeValues serialTapeValues = AD::getTape().getTapeValues(); + serialTapeValues.combineDataMPI(communicator); + + if (printingRank) { + serialTapeValues.formatDefault(std::cout); + } + + double totalMemoryUsed = serialTapeValues.getUsedMemorySize(); + double totalMemoryAllocated = serialTapeValues.getAllocatedMemorySize(); + +#ifdef HAVE_OPDI + + if (printingRank) { + std::cout << "-------------------------------------------------------\n"; + std::cout << " OpenMP parallel parts of the tape\n"; + std::cout << " (aggregated across OpenMP threads)\n"; +#ifdef HAVE_MPI + std::cout << " (aggregated across MPI processes)\n"; +#endif + std::cout << "-------------------------------------------------------\n"; + } + + codi::TapeValues* aggregatedOpenMPTapeValues = nullptr; + + // clang-format off + + SU2_OMP_PARALLEL { + if (omp_get_thread_num() == 0) { // master thread + codi::TapeValues masterTapeValues = AD::getTape().getTapeValues(); + aggregatedOpenMPTapeValues = &masterTapeValues; + + SU2_OMP_BARRIER // master completes initialization + SU2_OMP_BARRIER // other threads complete adding their data + + aggregatedOpenMPTapeValues->combineDataMPI(communicator); + totalMemoryUsed += aggregatedOpenMPTapeValues->getUsedMemorySize(); + totalMemoryAllocated += aggregatedOpenMPTapeValues->getAllocatedMemorySize(); + if (printingRank) { + aggregatedOpenMPTapeValues->formatDefault(std::cout); + } + aggregatedOpenMPTapeValues = nullptr; + } else { // other threads + SU2_OMP_BARRIER // master completes initialization + SU2_OMP_CRITICAL { + aggregatedOpenMPTapeValues->combineData(AD::getTape().getTapeValues()); + } END_SU2_OMP_CRITICAL + SU2_OMP_BARRIER // other threads complete adding their data + } + } END_SU2_OMP_PARALLEL + +// clang-format on +#endif + + if (printingRank) { + std::cout << "-------------------------------------------------------\n"; + std::cout << " Total memory used : " << totalMemoryUsed / 1024.0 / 1024.0 << " MB\n"; + std::cout << " Total memory allocated : " << totalMemoryAllocated / 1024.0 / 1024.0 << " MB\n"; + std::cout << "-------------------------------------------------------\n"; + } +} FORCEINLINE void ClearAdjoints() { AD::getTape().clearAdjoints(); } diff --git a/Common/include/containers/CLookUpTable.hpp b/Common/include/containers/CLookUpTable.hpp index 50add943c1f..230b009fc92 100644 --- a/Common/include/containers/CLookUpTable.hpp +++ b/Common/include/containers/CLookUpTable.hpp @@ -48,7 +48,11 @@ class CLookUpTable { version_lut, /*!< \brief LUT version as specified in LUT file.*/ version_reader, /*!< \brief Reader version (should be equal or above LUT version).*/ name_CV1, /*!< \brief Name of controlling variable 1.*/ - name_CV2; /*!< \brief Name of xontrolling variable 2.*/ + name_CV2; /*!< \brief Name of controlling variable 2.*/ + + unsigned long idx_CV1, /*!< \brief Table variable index of controlling variable 1.*/ + idx_CV2, /*!< \brief Table variable index of controlling variable 2.*/ + idx_null; /*!< \brief Variable index corresponding to NULL variable. */ su2vector n_points, /*!< \brief Number of data poins per table level.*/ n_triangles, /*!< \brief Number of triangles per table level.*/ @@ -56,7 +60,7 @@ class CLookUpTable { unsigned long n_variables, n_table_levels = 1; - su2vector z_values_levels; /*!< \brief Constant z-values of each table level.*/ + std::vector z_values_levels; /*!< \brief Constant z-values of each table level.*/ unsigned short table_dim = 2; /*!< \brief Table dimension.*/ /*! @@ -105,21 +109,6 @@ class CLookUpTable { */ su2vector> interp_mat_inv_x_y; - /*! \brief - * Returns the index to the variable in the lookup table. - */ - inline unsigned int GetIndexOfVar(const std::string& nameVar) const { - int index = find(names_var.begin(), names_var.end(), nameVar) - names_var.begin(); - if (index == int(names_var.size())) { - index = -1; - std::string error_msg = "Variable '"; - error_msg.append(nameVar); - error_msg.append("' is not in the lookup table."); - SU2_MPI::Error(error_msg, CURRENT_FUNCTION); - } - return index; - } - /*! \brief * Returns true if the string is null or zero (ignores case). */ @@ -182,8 +171,8 @@ class CLookUpTable { * \param[in] interp_mat_inv - Inverse matrix for interpolation. * \param[out] interp_coeffs - Interpolation coefficients. */ - void GetInterpCoeffs(su2double val_CV1, su2double val_CV2, su2activematrix& interp_mat_inv, - std::array& interp_coeffs); + void GetInterpCoeffs(su2double val_CV1, su2double val_CV2, const su2activematrix& interp_mat_inv, + std::array& interp_coeffs) const; /*! * \brief Compute interpolated value of a point P in the triangle. @@ -239,6 +228,28 @@ class CLookUpTable { const std::vector& names_var, std::vector& var_vals, const unsigned long i_level = 0); + /*! + * \brief Interpolate data based on distance-weighted averaging on the nearest two table nodes. + * \param[in] val_CV1 - First coordinate of point P(val_CV1,val_CV2) to check. + * \param[in] val_CV2 - Second coordinate of point P(val_CV1,val_CV2) to check. + * \param[in] idx_var - Vector of table variable indices to be looked up. + * \param[out] val_vars - Pointer to the vector of stored values of the variables to look up. + */ + void InterpolateToNearestNeighbors(const su2double val_CV1, const su2double val_CV2, + const std::vector& idx_var, std::vector& var_vals, + const unsigned long i_level = 0); + + /*! + * \brief Interpolate data based on distance-weighted averaging on the nearest two table nodes. + * \param[in] val_CV1 - First coordinate of point P(val_CV1,val_CV2) to check. + * \param[in] val_CV2 - Second coordinate of point P(val_CV1,val_CV2) to check. + * \param[in] idx_var - Vector of table variable indices to be looked up. + * \param[out] val_vars - Pointer to the vector of stored values of the variables to look up. + */ + void InterpolateToNearestNeighbors(const su2double val_CV1, const su2double val_CV2, + const std::vector& idx_var, std::vector& var_vals, + const unsigned long i_level = 0); + /*! * \brief Interpolate data based on distance-weighted averaging on the nearest two table nodes for a single variable. * \param[in] val_CV1 - First coordinate of point P(val_CV1,val_CV2) to check. @@ -284,6 +295,27 @@ class CLookUpTable { const su2double val_CV1, const su2double val_CV2, const su2double val_CV3); + /*! + * \brief Find the triangle within which the query point (val_CV1, val_CV2) is located. + * \param[in] val_CV1 - First controlling variable value. + * \param[in] val_CV2 - Second controlling variable value. + * \param[in] id_triangle - Reference to inclusion triangle index. + * \param[in] iLevel - Table level index. + * \returns if query point is within data set. + */ + bool FindInclusionTriangle(const su2double val_CV1, const su2double val_CV2, unsigned long& id_triangle, + const unsigned long iLevel = 0); + + /*! + * \brief Identify the nearest second nearest hull nodes w.r.t. the query point (val_CV1, val_CV2). + * \param[in] val_CV1 - First controlling variable value. + * \param[in] val_CV2 - Second controlling variable value. + * \param[in] iLevel - Table level index. + * \returns pair with nearest node index(first) and second nearest node(second). + */ + std::pair FindNearestNeighbors(const su2double val_CV1, const su2double val_CV2, + const unsigned long iLevel = 0); + public: CLookUpTable(const std::string& file_name_lut, std::string name_CV1_in, std::string name_CV2_in); @@ -293,67 +325,70 @@ class CLookUpTable { void PrintTableInfo(); /*! - * \brief Lookup 1 value of the single variable "val_name_var" using controlling variable values(val_CV1,val_CV2). - * \param[in] val_name_var - String name of the variable to look up. + * \brief Lookup value of variable stored under idx_var using controlling variable values(val_CV1,val_CV2). + * \param[in] idx_var - Column index corresponding to look-up data. * \param[out] val_var - The stored value of the variable to look up. * \param[in] val_CV1 - Value of controlling variable 1. * \param[in] val_CV2 - Value of controlling variable 2. - * \returns 1 if the lookup and subsequent interpolation was a success, 0 if not. + * \returns whether query is inside (true) or outside (false) data set. */ - unsigned long LookUp_XY(const std::string& val_name_var, su2double* val_var, su2double val_CV1, su2double val_CV2, - unsigned long i_level = 0); + bool LookUp_XY(const unsigned long idx_var, su2double* val_var, const su2double val_CV1, const su2double val_CV2, + const unsigned long i_level = 0); /*! - * \brief Lookup 1 value for each of the variables in "val_name_var" using controlling variable - * values(val_CV1,val_CV2). - * \param[in] val_names_var - vector of string names of the variables to look up. - * \param[out] val_vars - pointer to the vector of stored values of the variables to look up. - * \param[in] val_CV1 - value of controlling variable 1. - * \param[in] val_CV2 - value of controlling variable 2. - * \returns 1 if the lookup and subsequent interpolation was a success, 0 if not. - */ - unsigned long LookUp_XY(const std::vector& val_names_var, std::vector& val_vars, - su2double val_CV1, su2double val_CV2, unsigned long i_level = 0); - - /*! - * \brief Lookup the value of the variable "val_name_var" using controlling variable values(val_CV1,val_CV2). - * \param[in] val_name_var - String name of the variable to look up. + * \brief Lookup the value of the variable stored under idx_var using controlling variable values(val_CV1,val_CV2). + * \param[in] idx_var - Table data column indices corresponding to look-up variables. * \param[out] val_var - The stored value of the variable to look up. * \param[in] val_CV1 - Value of controlling variable 1. * \param[in] val_CV2 - Value of controlling variable 2. - * \returns 1 if the lookup and subsequent interpolation was a success, 0 if not. + * \returns whether query is inside (true) or outside (false) data set. */ - unsigned long LookUp_XY(const std::vector& val_names_var, std::vector& val_vars, - su2double val_CV1, su2double val_CV2, unsigned long i_level = 0); + bool LookUp_XY(const std::vector& idx_var, std::vector& val_vars, const su2double val_CV1, + const su2double val_CV2, const unsigned long i_level = 0); /*! - * \brief Lookup the value of the variable "val_name_var" using controlling variable values(val_CV1,val_CV2,val_z). - * \param[in] val_name_var - String name of the variable to look up. + * \brief Lookup the values of the variables stored under idx_var using controlling variable values(val_CV1,val_CV2). + * \param[in] idx_var - Table data column indices corresponding to look-up variables. * \param[out] val_var - The stored value of the variable to look up. * \param[in] val_CV1 - Value of controlling variable 1. * \param[in] val_CV2 - Value of controlling variable 2. - * \param[in] val_CV3 - Value of controlling variable 3. - * \returns 1 if the lookup and subsequent interpolation was a success, 0 if not. + * \returns whether query is inside (true) or outside (false) data set. */ - unsigned long LookUp_XYZ(const std::string& val_name_var, su2double* val_var, su2double val_CV1, su2double val_CV2, - su2double val_CV3); + bool LookUp_XY(const std::vector& idx_var, std::vector& val_vars, const su2double val_CV1, + su2double val_CV2, const unsigned long i_level = 0); + /*! + * \brief Lookup the value of the variable stored under idx_var using controlling variable values(val_CV1,val_CV2, + * val_CV3). \param[in] val_name_var - String name of the variable to look up. \param[out] val_var - The stored value + * of the variable to look up. \param[in] val_CV1 - Value of controlling variable 1. \param[in] val_CV2 - Value of + * controlling variable 2. \param[in] val_CV3 - Value of controlling variable 3. \returns whether query is inside + * (true) or outside (false) data set. + */ + bool LookUp_XYZ(const unsigned long idx_var, su2double* val_var, const su2double val_CV1, const su2double val_CV2, + const su2double val_CV3); /*! - * \brief Lookup the value of the variable "val_name_var" using controlling variable values(val_CV1,val_CV2,val_z). - * \param[in] val_name_var - String name of the variable to look up. - * \param[out] val_var - The stored value of the variable to look up. - * \param[in] val_CV1 - Value of controlling variable 1. - * \param[in] val_CV2 - Value of controlling variable 2. - * \param[in] val_CV3 - Value of controlling variable 3. - * \returns 1 if the lookup and subsequent interpolation was a success, 0 if not. + * \brief Lookup the values of the variables stored under idx_var using controlling variable values + * (val_CV1,val_CV2,val_z). \param[in] idx_var - Table variable index to look up. \param[out] val_var - The stored + * value of the variable to look up. \param[in] val_CV1 - Value of controlling variable 1. \param[in] val_CV2 - Value + * of controlling variable 2. \param[in] val_CV3 - Value of controlling variable 3. \returns whether query is inside + * (true) or outside (false) data set. */ - unsigned long LookUp_XYZ(const std::vector& val_names_var, std::vector& val_vars, - su2double val_CV1, su2double val_CV2, su2double val_CV3 = 0); + bool LookUp_XYZ(const std::vector& idx_var, std::vector& val_vars, const su2double val_CV1, + const su2double val_CV2, const su2double val_CV3 = 0); + + /*! + * \brief Lookup the values of the variables stored under idx_var using controlling variable values + * (val_CV1,val_CV2,val_z). \param[in] idx_var - Table variable index to look up. \param[out] val_var - The stored + * value of the variable to look up. \param[in] val_CV1 - Value of controlling variable 1. \param[in] val_CV2 - Value + * of controlling variable 2. \param[in] val_CV3 - Value of controlling variable 3. \returns whether query is inside + * (true) or outside (false) data set. + */ + bool LookUp_XYZ(const std::vector& idx_var, std::vector& val_vars, const su2double val_CV1, + const su2double val_CV2, const su2double val_CV3 = 0); /*! * \brief Find the table levels with constant z-values directly above and below query val_z. * \param[in] val_CV3 - Value of controlling variable 3. - * \param[in] within_limits - Whether query point lies within table bounds. * \returns Pair of inclusion level indices (first = lower level index, second = upper level index). */ std::pair FindInclusionLevels(const su2double val_CV3); @@ -362,7 +397,7 @@ class CLookUpTable { * \brief Determine the minimum and maximum value of the second controlling variable. * \returns Pair of minimum and maximum value of controlling variable 2. */ - inline std::pair GetTableLimitsY(unsigned long i_level = 0) const { + inline std::pair GetTableLimitsY(const unsigned long i_level = 0) const { return limits_table_y[i_level]; } @@ -370,7 +405,34 @@ class CLookUpTable { * \brief Determine the minimum and maximum value of the first controlling variable. * \returns Pair of minimum and maximum value of controlling variable 1. */ - inline std::pair GetTableLimitsX(unsigned long i_level = 0) const { + inline std::pair GetTableLimitsX(const unsigned long i_level = 0) const { return limits_table_x[i_level]; } + + /*! + * \brief Check whether requested set of variables are included in the table. + */ + bool CheckForVariables(const std::vector& vars_to_check) const; + + /*! + * \brief Returns the index to the variable in the lookup table. + * \param[in] nameVar - Variable name for which to retrieve the column index. + * \returns Table data column index corresponding to variable. + */ + inline unsigned int GetIndexOfVar(const std::string& nameVar) const { + int index = find(names_var.begin(), names_var.end(), nameVar) - names_var.begin(); + if (index == int(names_var.size())) { + index = -1; + std::string error_msg = "Variable '"; + error_msg.append(nameVar); + error_msg.append("' is not in the lookup table."); + SU2_MPI::Error(error_msg, CURRENT_FUNCTION); + } + return index; + } + + /*! \brief + * Returns the table variable index which will always return zero when looked up. + */ + unsigned long GetNullIndex() const { return idx_null; } }; diff --git a/Common/include/containers/CTrapezoidalMap.hpp b/Common/include/containers/CTrapezoidalMap.hpp index c82d0281a2c..2225a9b718c 100644 --- a/Common/include/containers/CTrapezoidalMap.hpp +++ b/Common/include/containers/CTrapezoidalMap.hpp @@ -69,7 +69,7 @@ class CTrapezoidalMap { * \param[in] val_y - y-coordinate or second independent variable * \param[out] val_index - index to the triangle */ - unsigned long GetTriangle(su2double val_x, su2double val_y); + unsigned long GetTriangle(const su2double val_x, const su2double val_y); /*! * \brief get the indices of the vertical coordinate band (xmin,xmax) in the 2D search space @@ -78,7 +78,7 @@ class CTrapezoidalMap { * \param[out] val_band - a pair(i_low,i_up) , the lower index and upper index between which the value val_x * can be found */ - std::pair GetBand(su2double val_x); + std::pair GetBand(const su2double val_x); /*! * \brief for a given coordinate (val_x,value), known to be in the band (xmin,xmax) with band index (i_low,i_up), diff --git a/Common/include/geometry/CGeometry.hpp b/Common/include/geometry/CGeometry.hpp index 15a726cabec..582679ca6af 100644 --- a/Common/include/geometry/CGeometry.hpp +++ b/Common/include/geometry/CGeometry.hpp @@ -426,7 +426,7 @@ class CGeometry { * \param[out] COUNT_PER_POINT - Number of communicated variables per point. * \param[out] MPI_TYPE - Enumerated type for the datatype of the quantity to be communicated. */ - void GetCommCountAndType(const CConfig* config, unsigned short commType, unsigned short& COUNT_PER_POINT, + void GetCommCountAndType(const CConfig* config, MPI_QUANTITIES commType, unsigned short& COUNT_PER_POINT, unsigned short& MPI_TYPE) const; /*! @@ -436,14 +436,14 @@ class CGeometry { * \param[in] config - Definition of the particular problem. * \param[in] commType - Enumerated type for the quantity to be communicated. */ - void InitiateComms(CGeometry* geometry, const CConfig* config, unsigned short commType) const; + void InitiateComms(CGeometry* geometry, const CConfig* config, MPI_QUANTITIES commType) const; /*! * \brief Routine to complete the set of non-blocking communications launched by InitiateComms() and unpacking of the * data into the geometry class. \param[in] geometry - Geometrical definition of the problem. \param[in] config - * Definition of the particular problem. \param[in] commType - Enumerated type for the quantity to be unpacked. */ - void CompleteComms(CGeometry* geometry, const CConfig* config, unsigned short commType); + void CompleteComms(CGeometry* geometry, const CConfig* config, MPI_QUANTITIES commType); /*! * \brief Get number of coordinates. @@ -1639,6 +1639,50 @@ class CGeometry { CustomBoundaryHeatFlux[val_marker][val_vertex] = val_customBoundaryHeatFlux; } + /*! + * \brief Set a representative wall value of the agglomerated control volumes on a particular boundary marker. + * \param[in] fine_grid - Geometrical definition of the problem. + * \param[in] val_marker - Index of the boundary marker. + * \param[in] wall_quantity - Object with methods Get(iVertex_fine) and Set(iVertex_coarse, val). + */ + template + void SetMultiGridMarkerQuantity(const CGeometry* fine_grid, unsigned short val_marker, T& wall_quantity) { + for (auto iVertex = 0ul; iVertex < nVertex[val_marker]; iVertex++) { + const auto Point_Coarse = vertex[val_marker][iVertex]->GetNode(); + + if (!nodes->GetDomain(Point_Coarse)) continue; + + su2double Area_Parent = 0.0; + + /*--- Compute area parent by taking into account only volumes that are on the marker. ---*/ + for (auto iChildren = 0u; iChildren < nodes->GetnChildren_CV(Point_Coarse); iChildren++) { + const auto Point_Fine = nodes->GetChildren_CV(Point_Coarse, iChildren); + const auto isVertex = + fine_grid->nodes->GetDomain(Point_Fine) && (fine_grid->nodes->GetVertex(Point_Fine, val_marker) != -1); + if (isVertex) { + Area_Parent += fine_grid->nodes->GetVolume(Point_Fine); + } + } + + su2double Quantity_Coarse = 0.0; + + /*--- Loop again to average coarser value. ---*/ + for (auto iChildren = 0u; iChildren < nodes->GetnChildren_CV(Point_Coarse); iChildren++) { + const auto Point_Fine = nodes->GetChildren_CV(Point_Coarse, iChildren); + const auto isVertex = + fine_grid->nodes->GetDomain(Point_Fine) && (fine_grid->nodes->GetVertex(Point_Fine, val_marker) != -1); + if (isVertex) { + const auto Vertex_Fine = fine_grid->nodes->GetVertex(Point_Fine, val_marker); + const auto Area_Children = fine_grid->nodes->GetVolume(Point_Fine); + Quantity_Coarse += wall_quantity.Get(Vertex_Fine) * Area_Children / Area_Parent; + } + } + + /*--- Set the value at the coarse level. ---*/ + wall_quantity.Set(iVertex, Quantity_Coarse); + } + } + /*! * \brief Filter values given at the element CG by performing a weighted average over a radial neighbourhood. * \param[in] filter_radius - Parameter defining the size of the neighbourhood. diff --git a/Common/include/geometry/CMultiGridGeometry.hpp b/Common/include/geometry/CMultiGridGeometry.hpp index 6669db4b019..1a7f7f9ab58 100644 --- a/Common/include/geometry/CMultiGridGeometry.hpp +++ b/Common/include/geometry/CMultiGridGeometry.hpp @@ -66,50 +66,6 @@ class CMultiGridGeometry final : public CGeometry { void SetSuitableNeighbors(vector& Suitable_Indirect_Neighbors, unsigned long iPoint, unsigned long Index_CoarseCV, const CGeometry* fine_grid) const; - /*! - * \brief Set a representative wall value of the agglomerated control volumes on a particular boundary marker. - * \param[in] fine_grid - Geometrical definition of the problem. - * \param[in] val_marker - Index of the boundary marker. - * \param[in] wall_quantity - Object with methods Get(iVertex_fine) and Set(iVertex_coarse, val). - */ - template - void SetMultiGridWallQuantity(const CGeometry* fine_grid, unsigned short val_marker, T& wall_quantity) { - for (auto iVertex = 0ul; iVertex < nVertex[val_marker]; iVertex++) { - const auto Point_Coarse = vertex[val_marker][iVertex]->GetNode(); - - if (!nodes->GetDomain(Point_Coarse)) continue; - - su2double Area_Parent = 0.0; - - /*--- Compute area parent by taking into account only volumes that are on the marker. ---*/ - for (auto iChildren = 0u; iChildren < nodes->GetnChildren_CV(Point_Coarse); iChildren++) { - const auto Point_Fine = nodes->GetChildren_CV(Point_Coarse, iChildren); - const auto isVertex = - fine_grid->nodes->GetDomain(Point_Fine) && (fine_grid->nodes->GetVertex(Point_Fine, val_marker) != -1); - if (isVertex) { - Area_Parent += fine_grid->nodes->GetVolume(Point_Fine); - } - } - - su2double Quantity_Coarse = 0.0; - - /*--- Loop again to average coarser value. ---*/ - for (auto iChildren = 0u; iChildren < nodes->GetnChildren_CV(Point_Coarse); iChildren++) { - const auto Point_Fine = nodes->GetChildren_CV(Point_Coarse, iChildren); - const auto isVertex = - fine_grid->nodes->GetDomain(Point_Fine) && (fine_grid->nodes->GetVertex(Point_Fine, val_marker) != -1); - if (isVertex) { - const auto Vertex_Fine = fine_grid->nodes->GetVertex(Point_Fine, val_marker); - const auto Area_Children = fine_grid->nodes->GetVolume(Point_Fine); - Quantity_Coarse += wall_quantity.Get(Vertex_Fine) * Area_Children / Area_Parent; - } - } - - /*--- Set the value at the coarse level. ---*/ - wall_quantity.Set(iVertex, Quantity_Coarse); - } - } - public: /*--- This is to suppress Woverloaded-virtual, omitting it has no negative impact. ---*/ using CGeometry::SetBoundControlVolume; diff --git a/Common/include/linear_algebra/CSysMatrix.hpp b/Common/include/linear_algebra/CSysMatrix.hpp index 573e6217d93..02747f8be07 100644 --- a/Common/include/linear_algebra/CSysMatrix.hpp +++ b/Common/include/linear_algebra/CSysMatrix.hpp @@ -92,7 +92,7 @@ struct CSysMatrixComms { */ template static void Initiate(const CSysVector& x, CGeometry* geometry, const CConfig* config, - unsigned short commType = SOLUTION_MATRIX); + MPI_QUANTITIES commType = MPI_QUANTITIES::SOLUTION_MATRIX); /*! * \brief Routine to complete the set of non-blocking communications launched by @@ -104,7 +104,7 @@ struct CSysMatrixComms { */ template static void Complete(CSysVector& x, CGeometry* geometry, const CConfig* config, - unsigned short commType = SOLUTION_MATRIX); + MPI_QUANTITIES commType = MPI_QUANTITIES::SOLUTION_MATRIX); }; /*! diff --git a/Common/include/option_structure.hpp b/Common/include/option_structure.hpp index 7199a310193..ab32f398e76 100644 --- a/Common/include/option_structure.hpp +++ b/Common/include/option_structure.hpp @@ -409,6 +409,7 @@ enum ENUM_TRANSFER { CONJUGATE_HEAT_WEAKLY_FS = 17, /*!< \brief Conjugate heat transfer (between incompressible fluids and solids). */ CONJUGATE_HEAT_SF = 18, /*!< \brief Conjugate heat transfer (between solids and compressible fluids). */ CONJUGATE_HEAT_WEAKLY_SF = 19, /*!< \brief Conjugate heat transfer (between solids and incompressible fluids). */ + CONJUGATE_HEAT_SS = 20, /*!< \brief Conjugate heat transfer (between two solids). */ }; /*! @@ -1333,11 +1334,38 @@ enum FLAMELET_SCALAR_SOURCES { * \brief Look-up operations for the flamelet scalar solver. */ enum FLAMELET_LOOKUP_OPS { - TD, /*!< \brief Thermochemical properties (temperature, density, diffusivity, etc.). */ + THERMO, /*!< \brief Thermochemical properties (temperature, density, diffusivity, etc.). */ + PREFDIF, /*!< \brief Preferential diffusion scalars. */ SOURCES, /*!< \brief Scalar source terms (controlling variables, passive species).*/ LOOKUP, /*!< \brief Passive look-up variables specified in config. */ }; +/*! + * \brief The preferential diffusion scalar indices for the preferential diffusion model. + */ +enum FLAMELET_PREF_DIFF_SCALARS { + I_BETA_PROGVAR, /*!< \brief Preferential diffusion scalar for the progress variable. */ + I_BETA_ENTH_THERMAL, /*!< \brief Preferential diffusion scalar for temperature. */ + I_BETA_ENTH, /*!< \brief Preferential diffusion scalar for total enthalpy. */ + I_BETA_MIXFRAC, /*!< \brief Preferential diffusion scalar for mixture fraction. */ + N_BETA_TERMS, /*!< \brief Total number of preferential diffusion scalars. */ +}; + +/*! + * \brief Flame initialization options for the flamelet solver. + */ +enum class FLAMELET_INIT_TYPE { + FLAME_FRONT, /*!< \brief Straight flame front. */ + SPARK, /*!< \brief Species reaction rate in a set location. */ + NONE, /*!< \brief No ignition, cold flow only. */ +}; + +static const MapType Flamelet_Init_Map = { + MakePair("NONE", FLAMELET_INIT_TYPE::NONE) + MakePair("FLAME_FRONT", FLAMELET_INIT_TYPE::FLAME_FRONT) + MakePair("SPARK", FLAMELET_INIT_TYPE::SPARK) +}; + /*! * \brief Types of subgrid scale models */ @@ -1569,6 +1597,7 @@ enum BC_TYPE { FLUID_INTERFACE = 39, /*!< \brief Domain interface definition. */ DISP_DIR_BOUNDARY = 40, /*!< \brief Boundary displacement definition. */ DAMPER_BOUNDARY = 41, /*!< \brief Damper. */ + MIXING_PLANE_INTERFACE = 42, /*< \breif Mxing plane */ CHT_WALL_INTERFACE = 50, /*!< \brief Domain interface definition. */ SMOLUCHOWSKI_MAXWELL = 55, /*!< \brief Smoluchoski/Maxwell wall boundary condition. */ SEND_RECEIVE = 99, /*!< \brief Boundary send-receive definition. */ @@ -1699,7 +1728,8 @@ enum RIEMANN_TYPE { TOTAL_CONDITIONS_PT_1D = 11, STATIC_PRESSURE_1D = 12, MIXING_IN_1D = 13, - MIXING_OUT_1D =14 + MIXING_OUT_1D = 14, + MASS_FLOW_OUTLET = 15 }; static const MapType Riemann_Map = { MakePair("TOTAL_CONDITIONS_PT", TOTAL_CONDITIONS_PT) @@ -1716,6 +1746,7 @@ static const MapType Riemann_Map = { MakePair("RADIAL_EQUILIBRIUM", RADIAL_EQUILIBRIUM) MakePair("TOTAL_CONDITIONS_PT_1D", TOTAL_CONDITIONS_PT_1D) MakePair("STATIC_PRESSURE_1D", STATIC_PRESSURE_1D) + MakePair("MASS_FLOW_OUTLET", MASS_FLOW_OUTLET) }; static const MapType Giles_Map = { @@ -1733,6 +1764,7 @@ static const MapType Giles_Map = { MakePair("RADIAL_EQUILIBRIUM", RADIAL_EQUILIBRIUM) MakePair("TOTAL_CONDITIONS_PT_1D", TOTAL_CONDITIONS_PT_1D) MakePair("STATIC_PRESSURE_1D", STATIC_PRESSURE_1D) + MakePair("MASS_FLOW_OUTLET", MASS_FLOW_OUTLET) }; /*! @@ -1809,6 +1841,18 @@ static const MapType TurboPerfKind_Map = { MakePair("PROPELLOR", TURBO_PERF_KIND::PROPELLOR) }; +/*! + * \brief Types onf Turbomachinery interfaces + */ +enum class TURBO_INTERFACE_KIND{ + MIXING_PLANE = ENUM_TRANSFER::MIXING_PLANE, + FROZEN_ROTOR = ENUM_TRANSFER::SLIDING_INTERFACE, +}; +static const MapType TurboInterfaceKind_Map = { + MakePair("MIXING_PLANE", TURBO_INTERFACE_KIND::MIXING_PLANE) + MakePair("FROZEN_ROTOR", TURBO_INTERFACE_KIND::FROZEN_ROTOR) +}; + /*! * \brief Types of Turbomachinery performance flag. */ @@ -2471,7 +2515,7 @@ enum PERIODIC_QUANTITIES { /*! * \brief Vertex-based quantities exchanged in MPI point-to-point communications. */ -enum MPI_QUANTITIES { +enum class MPI_QUANTITIES { SOLUTION , /*!< \brief Conservative solution communication. */ SOLUTION_OLD , /*!< \brief Conservative solution old communication. */ SOLUTION_GRADIENT , /*!< \brief Conservative solution gradient communication. */ diff --git a/Common/include/option_structure.inl b/Common/include/option_structure.inl index 955d1531482..01ed6de9bf9 100644 --- a/Common/include/option_structure.inl +++ b/Common/include/option_structure.inl @@ -1606,11 +1606,15 @@ class COptionTurboPerformance : public COptionBase { unsigned short& size; string*& marker_turboIn; string*& marker_turboOut; + string*& markers; public: COptionTurboPerformance(const string option_field_name, unsigned short& nMarker_TurboPerf, - string*& Marker_TurboBoundIn, string*& Marker_TurboBoundOut) - : size(nMarker_TurboPerf), marker_turboIn(Marker_TurboBoundIn), marker_turboOut(Marker_TurboBoundOut) { + string*& Marker_TurboBoundIn, string*& Marker_TurboBoundOut, string*& Marker_Turbomachinery) + : size(nMarker_TurboPerf), + marker_turboIn(Marker_TurboBoundIn), + marker_turboOut(Marker_TurboBoundOut), + markers(Marker_Turbomachinery) { this->name = option_field_name; } @@ -1624,6 +1628,7 @@ class COptionTurboPerformance : public COptionBase { this->size = 0; this->marker_turboIn = nullptr; this->marker_turboOut = nullptr; + this->markers = nullptr; return ""; } @@ -1634,10 +1639,16 @@ class COptionTurboPerformance : public COptionBase { this->size = 0; this->marker_turboIn = nullptr; this->marker_turboOut = nullptr; + this->markers = nullptr; ; return newstring; } + this->markers = new string[totalVals]; + for (unsigned long i = 0; i < totalVals; i++) { + this->markers[i].assign(option_value[i]); + } + unsigned long nVals = totalVals / mod_num; this->size = nVals; this->marker_turboIn = new string[nVals]; @@ -1654,6 +1665,7 @@ class COptionTurboPerformance : public COptionBase { this->size = 0; this->marker_turboIn = nullptr; this->marker_turboOut = nullptr; + this->markers = nullptr; } }; diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index 18da76556c4..c90b6b79518 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -539,10 +539,10 @@ void CConfig::addPeriodicOption(const string & name, unsigned short & nMarker_Pe } void CConfig::addTurboPerfOption(const string & name, unsigned short & nMarker_TurboPerf, - string* & Marker_TurboBoundIn, string* & Marker_TurboBoundOut) { + string* & Marker_TurboBoundIn, string* & Marker_TurboBoundOut, string* & Marker_Turbomachinery) { assert(option_map.find(name) == option_map.end()); all_options.insert(pair(name, true)); - COptionBase* val = new COptionTurboPerformance(name, nMarker_TurboPerf, Marker_TurboBoundIn, Marker_TurboBoundOut); + COptionBase* val = new COptionTurboPerformance(name, nMarker_TurboPerf, Marker_TurboBoundIn, Marker_TurboBoundOut, Marker_Turbomachinery); option_map.insert(pair(name, val)); } @@ -987,6 +987,7 @@ void CConfig::SetPointersNull() { Species_Init = nullptr; Species_Clipping_Min = nullptr; Species_Clipping_Max = nullptr; + spark_reaction_rates = nullptr; /*--- Moving mesh pointers ---*/ @@ -1036,6 +1037,7 @@ void CConfig::SetPointersNull() { Marker_MixingPlaneInterface = nullptr; Marker_TurboBoundIn = nullptr; Marker_TurboBoundOut = nullptr; + Marker_Turbomachinery = nullptr; Marker_Giles = nullptr; Marker_Shroud = nullptr; @@ -1376,14 +1378,23 @@ void CConfig::SetConfig_Options() { /*!\brief SPECIES_CLIPPING_MIN \n DESCRIPTION: Minimum values for scalar clipping \ingroup Config*/ addDoubleListOption("SPECIES_CLIPPING_MIN", nSpecies_Clipping_Min, Species_Clipping_Min); - /*!\brief FLAME_INIT \n DESCRIPTION: flame initialization using the flamelet model \ingroup Config*/ + /*!\brief FLAME_INIT_METHOD \n DESCRIPTION: Ignition method for flamelet solver \n DEFAULT: no ignition; cold flow only. */ + addEnumOption("FLAME_INIT_METHOD", flame_init_type, Flamelet_Init_Map, FLAMELET_INIT_TYPE::NONE); + /*!\brief FLAME_INIT \n DESCRIPTION: flame front initialization using the flamelet model \ingroup Config*/ /*--- flame offset (x,y,z) ---*/ flame_init[0] = 0.0; flame_init[1] = 0.0; flame_init[2] = 0.0; /*--- flame normal (nx, ny, nz) ---*/ flame_init[3] = 1.0; flame_init[4] = 0.0; flame_init[5] = 0.0; /*--- flame thickness (x) and flame burnt thickness (after this thickness, we have unburnt conditions again) ---*/ flame_init[6] = 0.5e-3; flame_init[7] = 1.0; - addDoubleArrayOption("FLAME_INIT", 8,flame_init); + addDoubleArrayOption("FLAME_INIT", 8,flame_init.begin()); + + /*!\brief SPARK_INIT \n DESCRIPTION: spark initialization using the flamelet model \ingroup Config*/ + for (auto iSpark=0u; iSpark<6; ++iSpark) spark_init[iSpark]=0; + addDoubleArrayOption("SPARK_INIT", 6, spark_init.begin()); + + /*!\brief SPARK_REACTION_RATES \n DESCRIPTION: Net source term values applied to species within spark area during spark ignition. \ingroup Config*/ + addDoubleListOption("SPARK_REACTION_RATES", nspark, spark_reaction_rates); /*--- Options related to mass diffusivity and thereby the species solver. ---*/ @@ -1503,6 +1514,8 @@ void CConfig::SetConfig_Options() { addStringListOption("MARKER_ZONE_INTERFACE", nMarker_ZoneInterface, Marker_ZoneInterface); /*!\brief MARKER_CHT_INTERFACE \n DESCRIPTION: CHT interface boundary marker(s) \ingroup Config*/ addStringListOption("MARKER_CHT_INTERFACE", nMarker_CHTInterface, Marker_CHTInterface); + /*!\brief CHT_INTERFACE_CONTACT_RESISTANCE: Thermal contact resistance values for each CHT inerface. \ingroup Config*/ + addDoubleListOption("CHT_INTERFACE_CONTACT_RESISTANCE", nMarker_ContactResistance, CHT_ContactResistance); /* DESCRIPTION: Internal boundary marker(s) */ addStringListOption("MARKER_INTERNAL", nMarker_Internal, Marker_Internal); /* DESCRIPTION: Custom boundary marker(s) */ @@ -1617,8 +1630,8 @@ void CConfig::SetConfig_Options() { addStringListOption("MARKER_MIXINGPLANE_INTERFACE", nMarker_MixingPlaneInterface, Marker_MixingPlaneInterface); /*!\brief TURBULENT_MIXINGPLANE \n DESCRIPTION: Activate mixing plane also for turbulent quantities \ingroup Config*/ addBoolOption("TURBULENT_MIXINGPLANE", turbMixingPlane, false); - /*!\brief MARKER_TURBOMACHINERY \n DESCRIPTION: Identify the inflow and outflow boundaries in which the turbomachinery settings are applied. \ingroup Config*/ - addTurboPerfOption("MARKER_TURBOMACHINERY", nMarker_Turbomachinery, Marker_TurboBoundIn, Marker_TurboBoundOut); + /*!\brief MARKER_TURBOMACHINERY \n DESCRIPTION: Identify the boundaries for which the turbomachinery settings are applied. \ingroup Config*/ + addTurboPerfOption("MARKER_TURBOMACHINERY", nMarker_Turbomachinery, Marker_TurboBoundIn, Marker_TurboBoundOut, Marker_Turbomachinery); /*!\brief NUM_SPANWISE_SECTIONS \n DESCRIPTION: Integer number of spanwise sections to compute 3D turbo BC and Performance for turbomachinery */ addUnsignedShortOption("NUM_SPANWISE_SECTIONS", nSpanWiseSections_User, 1); /*!\brief SPANWISE_KIND \n DESCRIPTION: type of algorithm to identify the span-wise sections at the turbo boundaries. @@ -2136,6 +2149,9 @@ void CConfig::SetConfig_Options() { /* DESCRIPTION: Names of the user scalar source terms. */ addStringListOption("USER_SOURCE_NAMES", n_user_sources, user_source_names); + /* DESCRIPTION: Enable preferential diffusion for FGM simulations. \n DEFAULT: false */ + addBoolOption("PREFERENTIAL_DIFFUSION", preferential_diffusion, false); + /*!\brief CONV_FILENAME \n DESCRIPTION: Output file convergence history (w/o extension) \n DEFAULT: history \ingroup Config*/ addStringOption("CONV_FILENAME", Conv_FileName, string("history")); /*!\brief BREAKDOWN_FILENAME \n DESCRIPTION: Output file forces breakdown \ingroup Config*/ @@ -3540,6 +3556,25 @@ void CConfig::SetPostprocessing(SU2_COMPONENT val_software, unsigned short val_i SU2_MPI::Error(string("You probably want to set INC_ENERGY_EQUATION= YES for the fluid solver. \n"), CURRENT_FUNCTION); } + /*--- Check correctness and consistency of contact resistance options. ---*/ + if (nMarker_ContactResistance > 0) { + + /*--- Set constant contact resistance across CHT interfaces if a single value is provided. ---*/ + if (nMarker_ContactResistance == 1) { + auto val_CHTInterface = CHT_ContactResistance[0]; + delete [] CHT_ContactResistance; + CHT_ContactResistance = new su2double[nMarker_CHTInterface]; + for (auto iCHTMarker=0u; iCHTMarker < nMarker_CHTInterface; iCHTMarker++) + CHT_ContactResistance[iCHTMarker] = val_CHTInterface; + }else if((nMarker_CHTInterface/2) != nMarker_ContactResistance){ + SU2_MPI::Error("Number of CHT interfaces does not match number of contact resistances.", CURRENT_FUNCTION); + } + for (auto iCHTMarker=0u; iCHTMarker < nMarker_ContactResistance; iCHTMarker++){ + if (CHT_ContactResistance[iCHTMarker] < 0) + SU2_MPI::Error("Contact resistance value should be positive.", CURRENT_FUNCTION); + } + } + /*--- By default, in 2D we should use TWOD_AIRFOIL (independenly from the input file) ---*/ if (val_nDim == 2) Geo_Description = TWOD_AIRFOIL; @@ -3900,6 +3935,13 @@ void CConfig::SetPostprocessing(SU2_COMPONENT val_software, unsigned short val_i SU2_MPI::Error("The use of FLUID_MIXTURE requires the INC_DENSITY_MODEL option to be VARIABLE", CURRENT_FUNCTION); } + /*--- Check whether the Kind scalar model used is correct, in the case of FLUID_MIXTURE the kind scalar model must + be SPECIES_TRANSPORT. Otherwise, if the scalar model is NONE, the species transport equations will not be solved. + --- */ + if (Kind_Species_Model != SPECIES_MODEL::SPECIES_TRANSPORT) { + SU2_MPI::Error("The use of FLUID_MIXTURE requires the KIND_SCALAR_MODEL option to be SPECIES_TRANSPORT", + CURRENT_FUNCTION); + } switch (Kind_ViscosityModel) { case VISCOSITYMODEL::CONSTANT: @@ -5758,7 +5800,7 @@ void CConfig::SetMarkers(SU2_COMPONENT val_software) { for (iMarker_Fluid_InterfaceBound = 0; iMarker_Fluid_InterfaceBound < nMarker_Fluid_InterfaceBound; iMarker_Fluid_InterfaceBound++) { Marker_CfgFile_TagBound[iMarker_CfgFile] = Marker_Fluid_InterfaceBound[iMarker_Fluid_InterfaceBound]; - Marker_CfgFile_KindBC[iMarker_CfgFile] = FLUID_INTERFACE; + Marker_CfgFile_KindBC[iMarker_CfgFile] = BC_TYPE::FLUID_INTERFACE; iMarker_CfgFile++; } @@ -5995,6 +6037,37 @@ void CConfig::SetMarkers(SU2_COMPONENT val_software) { Marker_CfgFile_MixingPlaneInterface[iMarker_CfgFile] = indexMarker; } + /*--- Once we have identified the MixingPlane and Turbomachinery markers + * we next need to determine what type of interface between zones is + * used. It is convenient to do this here as it tidies up the interface + * preproccesing in CDriver ---*/ + if (nMarker_Turbomachinery != 0) { + nTurboInterfaces = (nMarker_Turbomachinery - 1)*2; //Two markers per zone minus inlet & outlet + Kind_TurboInterface.resize(nTurboInterfaces); + /*--- Loop over all markers ---*/ + for (iMarker_CfgFile = 0; iMarker_CfgFile < nMarker_CfgFile; iMarker_CfgFile++) { + /*--- Identify mixing plane markers ---*/ + if (Marker_MixingPlaneInterface != nullptr){ // Necessary in cases where no mixing plane interfaces are defined + if (Marker_CfgFile_MixingPlaneInterface[iMarker_CfgFile] != 0) { //Is a mixing plane + /*--- Find which list position this marker is in turbomachinery markers ---*/ + const auto* target = std::find(&Marker_Turbomachinery[0], &Marker_Turbomachinery[nMarker_Turbomachinery*2-1], Marker_CfgFile_TagBound[iMarker_CfgFile]); + const auto target_index = target - Marker_Turbomachinery; + /*--- Assert that we find the marker within the turbomachienry markers ---*/ + assert(target != &Marker_Turbomachinery[nMarker_Turbomachinery*2-1]); + /*--- Assign the correct interface ---*/ + SetKind_TurboInterface(target_index - 1, TURBO_INTERFACE_KIND::MIXING_PLANE); // Need to subtract 1 from index as to not consider the inlet an interface + } + } + if (Marker_Fluid_InterfaceBound != nullptr){ // No fluid interfaces are defined in the config file (nullptr if no interfaces defined) + if (Marker_CfgFile_KindBC[iMarker_CfgFile] == BC_TYPE::FLUID_INTERFACE) { // iMarker_CfgFile is a fluid interface + const auto* target = std::find(&Marker_Turbomachinery[0], &Marker_Turbomachinery[nMarker_Turbomachinery*2-1], Marker_CfgFile_TagBound[iMarker_CfgFile]); + const auto target_index = target - Marker_Turbomachinery; + SetKind_TurboInterface(target_index-1, TURBO_INTERFACE_KIND::FROZEN_ROTOR); + } + } + } + } + for (iMarker_CfgFile = 0; iMarker_CfgFile < nMarker_CfgFile; iMarker_CfgFile++) { Marker_CfgFile_DV[iMarker_CfgFile] = NO; for (iMarker_DV = 0; iMarker_DV < nMarker_DV; iMarker_DV++) @@ -8200,6 +8273,7 @@ CConfig::~CConfig() { delete [] RelaxFactorFourier; delete [] nSpan_iZones; + delete [] Marker_Turbomachinery; delete [] Marker_TurboBoundIn; delete [] Marker_TurboBoundOut; delete [] Marker_Riemann; @@ -8887,28 +8961,28 @@ INC_OUTLET_TYPE CConfig::GetKind_Inc_Outlet(const string& val_marker) const { return Kind_Inc_Outlet[iMarker_Outlet]; } -su2double CConfig::GetInlet_Ttotal(const string& val_marker) const { +su2double CConfig::GetInletTtotal(const string& val_marker) const { unsigned short iMarker_Inlet; for (iMarker_Inlet = 0; iMarker_Inlet < nMarker_Inlet; iMarker_Inlet++) if (Marker_Inlet[iMarker_Inlet] == val_marker) break; return Inlet_Ttotal[iMarker_Inlet]; } -su2double CConfig::GetInlet_Ptotal(const string& val_marker) const { +su2double CConfig::GetInletPtotal(const string& val_marker) const { unsigned short iMarker_Inlet; for (iMarker_Inlet = 0; iMarker_Inlet < nMarker_Inlet; iMarker_Inlet++) if (Marker_Inlet[iMarker_Inlet] == val_marker) break; return Inlet_Ptotal[iMarker_Inlet]; } -void CConfig::SetInlet_Ptotal(su2double val_pressure, const string& val_marker) { +void CConfig::SetInletPtotal(su2double val_pressure, const string& val_marker) { unsigned short iMarker_Inlet; for (iMarker_Inlet = 0; iMarker_Inlet < nMarker_Inlet; iMarker_Inlet++) if (Marker_Inlet[iMarker_Inlet] == val_marker) Inlet_Ptotal[iMarker_Inlet] = val_pressure; } -const su2double* CConfig::GetInlet_FlowDir(const string& val_marker) const { +const su2double* CConfig::GetInletFlowDir(const string& val_marker) const { unsigned short iMarker_Inlet; for (iMarker_Inlet = 0; iMarker_Inlet < nMarker_Inlet; iMarker_Inlet++) if (Marker_Inlet[iMarker_Inlet] == val_marker) break; diff --git a/Common/src/containers/CLookUpTable.cpp b/Common/src/containers/CLookUpTable.cpp index 206ea2ff648..16c042efba7 100644 --- a/Common/src/containers/CLookUpTable.cpp +++ b/Common/src/containers/CLookUpTable.cpp @@ -40,6 +40,10 @@ CLookUpTable::CLookUpTable(const string& var_file_name_lut, string name_CV1_in, LoadTableRaw(var_file_name_lut); + /* Store indices of controlling variables. */ + idx_CV1 = GetIndexOfVar(name_CV1); + idx_CV2 = GetIndexOfVar(name_CV2); + FindTableLimits(name_CV1, name_CV2); if (rank == MASTER_NODE) @@ -53,6 +57,9 @@ CLookUpTable::CLookUpTable(const string& var_file_name_lut, string name_CV1_in, PrintTableInfo(); + /* Add additional variable index which will always result in zero when looked up. */ + idx_null = names_var.size(); + if (rank == MASTER_NODE) switch (table_dim) { case 2: cout << "Building a trapezoidal map for the (" + name_CV1 + ", " + name_CV2 + @@ -158,8 +165,6 @@ void CLookUpTable::LoadTableRaw(const string& var_file_name_lut) { } void CLookUpTable::FindTableLimits(const string& name_cv1, const string& name_cv2) { - int idx_CV1 = GetIndexOfVar(name_cv1); - int idx_CV2 = GetIndexOfVar(name_cv2); limits_table_x.resize(n_table_levels); limits_table_y.resize(n_table_levels); @@ -214,7 +219,7 @@ void CLookUpTable::PrintTableInfo() { cout << "| Variable names: |" << endl; cout << "| |" << endl; - for (unsigned long i_var = 0; i_var < names_var.size(); i_var++) + for (auto i_var = 0u; i_var < names_var.size(); i_var++) cout << "| " << right << setw(3) << i_var << ": " << left << setw(59) << names_var[i_var] << " |" << endl; cout << "+------------------------------------------------------------------+" << endl; @@ -238,7 +243,7 @@ void CLookUpTable::PrintTableInfo() { cout << "| Variable names: |" << endl; cout << "| |" << endl; - for (unsigned long i_var = 0; i_var < names_var.size(); i_var++) + for (auto i_var = 0u; i_var < names_var.size(); i_var++) cout << "| " << right << setw(3) << i_var << ": " << left << setw(59) << names_var[i_var] << " |" << endl; cout << "+------------------------------------------------------------------+" << endl; @@ -257,11 +262,11 @@ void CLookUpTable::IdentifyUniqueEdges() { vector > neighborElemsOfPoint; neighborElemsOfPoint.resize(n_points[i_level]); - for (unsigned long iElem = 0; iElem < n_triangles[i_level]; iElem++) { + for (auto iElem = 0u; iElem < n_triangles[i_level]; iElem++) { /* loop over 3 points per triangle */ - for (unsigned long iPoint = 0; iPoint < N_POINTS_TRIANGLE; iPoint++) { + for (auto iPoint = 0u; iPoint < N_POINTS_TRIANGLE; iPoint++) { /* get the global ID of the current point */ - const unsigned long GlobalIndex = triangles[i_level][iElem][iPoint]; + const auto GlobalIndex = triangles[i_level][iElem][iPoint]; /* add the current element ID to the neighbor list for this point */ neighborElemsOfPoint[GlobalIndex].push_back(iElem); @@ -270,7 +275,7 @@ void CLookUpTable::IdentifyUniqueEdges() { /* remove duplicates from the neighboring element lists*/ vector::iterator vecIt; - for (unsigned long iPoint = 0; iPoint < n_points[i_level]; iPoint++) { + for (auto iPoint = 0u; iPoint < n_points[i_level]; iPoint++) { /* sort neighboring elements for each point */ sort(neighborElemsOfPoint[iPoint].begin(), neighborElemsOfPoint[iPoint].end()); @@ -285,12 +290,12 @@ void CLookUpTable::IdentifyUniqueEdges() { the point IDs that are neighboring points */ vector > neighborPointsOfPoint; neighborPointsOfPoint.resize(n_points[i_level]); - for (unsigned long iPoint = 0; iPoint < n_points[i_level]; iPoint++) { - for (unsigned long iElem = 0; iElem < neighborElemsOfPoint[iPoint].size(); iElem++) { + for (auto iPoint = 0u; iPoint < n_points[i_level]; iPoint++) { + for (auto iElem = 0u; iElem < neighborElemsOfPoint[iPoint].size(); iElem++) { /* loop over element points */ - for (unsigned long jPoint = 0; jPoint < N_POINTS_TRIANGLE; jPoint++) { + for (auto jPoint = 0u; jPoint < N_POINTS_TRIANGLE; jPoint++) { /* get the global ID of the current point */ - const unsigned long GlobalIndex = triangles[i_level][neighborElemsOfPoint[iPoint][iElem]][jPoint]; + const auto GlobalIndex = triangles[i_level][neighborElemsOfPoint[iPoint][iElem]][jPoint]; /* add the current element ID to the neighbor list for this point */ if (GlobalIndex != iPoint) neighborPointsOfPoint[iPoint].push_back(GlobalIndex); @@ -299,7 +304,7 @@ void CLookUpTable::IdentifyUniqueEdges() { } /* remove duplicates from the neighboring points lists */ - for (unsigned long iPoint = 0; iPoint < n_points[i_level]; iPoint++) { + for (auto iPoint = 0u; iPoint < n_points[i_level]; iPoint++) { /* sort neighboring points for each point */ sort(neighborPointsOfPoint[iPoint].begin(), neighborPointsOfPoint[iPoint].end()); @@ -315,10 +320,10 @@ void CLookUpTable::IdentifyUniqueEdges() { that the smaller global index is in the first position and the larger is in the second to make for a unique set, so there's no need to remove duplicates. */ - for (unsigned long iPoint = 0; iPoint < n_points[i_level]; iPoint++) { - for (unsigned long jPoint = 0; jPoint < neighborPointsOfPoint[iPoint].size(); jPoint++) { + for (auto iPoint = 0u; iPoint < n_points[i_level]; iPoint++) { + for (auto jPoint = 0u; jPoint < neighborPointsOfPoint[iPoint].size(); jPoint++) { /* Store the neighbor index more clearly. */ - const unsigned long GlobalIndex = neighborPointsOfPoint[iPoint][jPoint]; + const auto GlobalIndex = neighborPointsOfPoint[iPoint][jPoint]; /* Store the edge so that the lower index of the pair is always first. */ if (iPoint < GlobalIndex) { @@ -334,17 +339,17 @@ void CLookUpTable::IdentifyUniqueEdges() { pair, loop through the neighboring elements and store the two elements that contain the second point in the edge ('left' and 'right' of the edge). */ edge_to_triangle[i_level].resize(edges[i_level].size()); - for (unsigned long iEdge = 0; iEdge < edges[i_level].size(); iEdge++) { + for (auto iEdge = 0u; iEdge < edges[i_level].size(); iEdge++) { /* Store the two points of the edge more clearly. */ - const unsigned long iPoint = edges[i_level][iEdge][0]; - const unsigned long jPoint = edges[i_level][iEdge][1]; + const auto iPoint = edges[i_level][iEdge][0]; + const auto jPoint = edges[i_level][iEdge][1]; /* Loop over all neighboring elements to iPoint. */ - for (unsigned long iElem = 0; iElem < neighborElemsOfPoint[iPoint].size(); iElem++) { + for (auto iElem = 0u; iElem < neighborElemsOfPoint[iPoint].size(); iElem++) { /* loop over 3 points per triangle */ - for (unsigned long kPoint = 0; kPoint < N_POINTS_TRIANGLE; kPoint++) { + for (auto kPoint = 0u; kPoint < N_POINTS_TRIANGLE; kPoint++) { /* Get the global ID of the current point. */ - const unsigned long GlobalIndex = triangles[i_level][neighborElemsOfPoint[iPoint][iElem]][kPoint]; + const auto GlobalIndex = triangles[i_level][neighborElemsOfPoint[iPoint][iElem]][kPoint]; /* Add the current element ID to the neighbor list for this point. */ if (GlobalIndex == jPoint) edge_to_triangle[i_level][iEdge].push_back(neighborElemsOfPoint[iPoint][iElem]); @@ -360,18 +365,18 @@ void CLookUpTable::ComputeInterpCoeffs() { std::array next_triangle; - const su2double* val_CV1 = GetDataP(name_CV1, i_level); - const su2double* val_CV2 = GetDataP(name_CV2, i_level); + const su2double* val_CV1 = table_data[i_level][idx_CV1]; + const su2double* val_CV2 = table_data[i_level][idx_CV2]; /* calculate weights for each triangle (basically a distance function) and * build inverse interpolation matrices */ interp_mat_inv_x_y[i_level].resize(n_triangles[i_level]); - for (unsigned long i_triangle = 0; i_triangle < n_triangles[i_level]; i_triangle++) { - for (int p = 0; p < 3; p++) { + for (auto i_triangle = 0u; i_triangle < n_triangles[i_level]; i_triangle++) { + for (auto p = 0u; p < N_POINTS_TRIANGLE; p++) { next_triangle[p] = triangles[i_level][i_triangle][p]; } - su2activematrix x_interp_mat_inv(3, 3); + su2activematrix x_interp_mat_inv(N_POINTS_TRIANGLE, N_POINTS_TRIANGLE); GetInterpMatInv(val_CV1, val_CV2, next_triangle, x_interp_mat_inv); interp_mat_inv_x_y[i_level][i_triangle] = x_interp_mat_inv; } @@ -380,24 +385,23 @@ void CLookUpTable::ComputeInterpCoeffs() { void CLookUpTable::GetInterpMatInv(const su2double* vec_x, const su2double* vec_y, std::array& point_ids, su2activematrix& interp_mat_inv) { - const unsigned int M = 3; - CSquareMatrixCM global_M(3); + CSquareMatrixCM global_M(N_POINTS_TRIANGLE); /* setup LHM matrix for the interpolation */ - for (unsigned int i_point = 0; i_point < M; i_point++) { - su2double x = vec_x[point_ids[i_point]]; - su2double y = vec_y[point_ids[i_point]]; + for (auto i_vertex = 0u; i_vertex < N_POINTS_TRIANGLE; i_vertex++) { + su2double x = vec_x[point_ids[i_vertex]]; + su2double y = vec_y[point_ids[i_vertex]]; - global_M(i_point, 0) = SU2_TYPE::GetValue(1.0); - global_M(i_point, 1) = SU2_TYPE::GetValue(x); - global_M(i_point, 2) = SU2_TYPE::GetValue(y); + global_M(i_vertex, 0) = SU2_TYPE::GetValue(1.0); + global_M(i_vertex, 1) = SU2_TYPE::GetValue(x); + global_M(i_vertex, 2) = SU2_TYPE::GetValue(y); } global_M.Invert(); global_M.Transpose(); - for (unsigned int i = 0; i < M; i++) { - for (unsigned int j = 0; j < M; j++) { + for (auto i = 0u; i < N_POINTS_TRIANGLE; i++) { + for (auto j = 0u; j < N_POINTS_TRIANGLE; j++) { interp_mat_inv[i][j] = global_M(i, j); } } @@ -406,61 +410,47 @@ void CLookUpTable::GetInterpMatInv(const su2double* vec_x, const su2double* vec_ std::pair CLookUpTable::FindInclusionLevels(const su2double val_CV3) { /*--- Find the table levels with constant z-values directly below and above the query value val_CV3 ---*/ + su2double val_z = val_CV3; + unsigned long i_up{0}, i_low{0}; /* Check if val_CV3 lies outside table bounds */ - if (val_CV3 >= *limits_table_z.second) { - return std::make_pair(n_table_levels - 1, n_table_levels - 1); - } else if (val_CV3 <= *limits_table_z.first) { - return std::make_pair(0, 0); - } else { - std::pair inclusion_levels; - /* Loop over table levels to find the levels directly above and below the query value */ - for (auto i_level = 0ul; i_level < n_table_levels - 1; i_level++) { - if ((val_CV3 >= z_values_levels[i_level]) && (val_CV3 < z_values_levels[i_level + 1])) { - inclusion_levels = std::make_pair(i_level, i_level + 1); - } - } - return inclusion_levels; + if (val_z < z_values_levels.front()) { + val_z = z_values_levels.front(); + return make_pair(i_low, i_up); } -} - -unsigned long CLookUpTable::LookUp_XYZ(const std::string& val_name_var, su2double* val_var, su2double val_CV1, - su2double val_CV2, su2double val_CV3) { - /*--- Perform quasi-3D interpolation for a single variable named val_name_var on a query point - with coordinates val_CV1, val_CV2, and val_CV3 ---*/ - - /* 1: Find table levels directly above and below the query point (the levels that sandwhich val_CV3) */ - std::pair inclusion_levels = FindInclusionLevels(val_CV3); - bool within_z_limits = (inclusion_levels.first != inclusion_levels.second); - - if (within_z_limits) { - /* 2: Determine val_CV1 and val_CV2 for the inclusion table levels. */ - std::array, 2> lower_upper_CV1_2 = - ComputeNormalizedXY(inclusion_levels, val_CV1, val_CV2, val_CV3); - su2double val_CV1_lower = lower_upper_CV1_2[0][0], val_CV2_lower = lower_upper_CV1_2[0][1], - val_CV1_upper = lower_upper_CV1_2[1][0], val_CV2_upper = lower_upper_CV1_2[1][1]; + if (val_z > z_values_levels.back()) { + val_z = z_values_levels.back(); + i_low = n_table_levels - 1; + i_up = n_table_levels - 1; + return make_pair(i_low, i_up); + } + std::pair::iterator, std::vector::iterator> bounds; + bounds = std::equal_range(z_values_levels.begin(), z_values_levels.end(), val_z); - /* 3: Perform 2D interpolations on upper and lower inclusion levels */ - unsigned long lower_level = inclusion_levels.first; - unsigned long upper_level = inclusion_levels.second; + /*--- if upper bound = 0, then use the range [0,1] ---*/ + i_up = max(1, bounds.first - z_values_levels.begin()); + i_low = i_up - 1; + return make_pair(i_low, i_up); +} - su2double val_var_lower, val_var_upper; - unsigned long exit_code_lower = LookUp_XY(val_name_var, &val_var_lower, val_CV1_lower, val_CV2_lower, lower_level); - unsigned long exit_code_upper = LookUp_XY(val_name_var, &val_var_upper, val_CV1_upper, val_CV2_upper, upper_level); +bool CLookUpTable::LookUp_XYZ(const unsigned long idx_var, su2double* val_var, const su2double val_CV1, + const su2double val_CV2, const su2double val_CV3) { + vector vec_idx_var = {idx_var}; + vector vec_val_var = {val_var}; + return LookUp_XYZ(vec_idx_var, vec_val_var, val_CV1, val_CV2, val_CV3); +} - /* 4: Perform linear interpolation along the z-direction using the x-y interpolation results - from upper and lower trapezoidal maps */ - Linear_Interpolation(val_CV3, lower_level, upper_level, val_var_lower, val_var_upper, val_var); +bool CLookUpTable::LookUp_XYZ(const std::vector& idx_var, std::vector& val_vars, + const su2double val_CV1, const su2double val_CV2, const su2double val_CV3) { + vector var_vals_output; + var_vals_output.resize(val_vars.size()); + bool inside = LookUp_XYZ(idx_var, var_vals_output, val_CV1, val_CV2, val_CV3); + for (auto iVar = 0u; iVar < val_vars.size(); iVar++) *val_vars[iVar] = var_vals_output[iVar]; - return max(exit_code_lower, exit_code_upper); - } else { - /* Perform single, 2D interpolation when val_CV3 lies outside table bounds */ - unsigned long bound_level = inclusion_levels.first; - LookUp_XY(val_name_var, val_var, val_CV1, val_CV2, bound_level); - return 1; - } + return inside; } -unsigned long CLookUpTable::LookUp_XYZ(const std::vector& val_names_var, std::vector& val_vars, - su2double val_CV1, su2double val_CV2, su2double val_CV3) { + +bool CLookUpTable::LookUp_XYZ(const std::vector& idx_var, std::vector& val_vars, + const su2double val_CV1, const su2double val_CV2, const su2double val_CV3) { /*--- Perform quasi-3D interpolation for a vector of variables with names val_names_var on a query point with coordinates val_CV1, val_CV2, and val_CV3 ---*/ @@ -482,19 +472,19 @@ unsigned long CLookUpTable::LookUp_XYZ(const std::vector& val_names std::vector val_vars_lower, val_vars_upper; val_vars_lower.resize(val_vars.size()); val_vars_upper.resize(val_vars.size()); - unsigned long exit_code_lower = LookUp_XY(val_names_var, val_vars_lower, val_CV1_lower, val_CV2_lower, lower_level); - unsigned long exit_code_upper = LookUp_XY(val_names_var, val_vars_upper, val_CV1_upper, val_CV2_upper, upper_level); + auto inside_lower = LookUp_XY(idx_var, val_vars_lower, val_CV1_lower, val_CV2_lower, lower_level); + auto inside_upper = LookUp_XY(idx_var, val_vars_upper, val_CV1_upper, val_CV2_upper, upper_level); /* 4: Perform linear interpolation along the z-direction using the x-y interpolation results from upper and lower trapezoidal maps */ Linear_Interpolation(val_CV3, lower_level, upper_level, val_vars_lower, val_vars_upper, val_vars); - return max(exit_code_lower, exit_code_upper); + return (inside_upper && inside_lower); } else { /* Perform single, 2D interpolation when val_CV3 lies outside table bounds */ unsigned long bound_level = inclusion_levels.first; - LookUp_XY(val_names_var, val_vars, val_CV1, val_CV2, bound_level); - return 1; + LookUp_XY(idx_var, val_vars, val_CV1, val_CV2, bound_level); + return false; } } @@ -579,105 +569,76 @@ std::array, 2> CLookUpTable::ComputeNormalizedXY( return lower_upper_CVs; } -unsigned long CLookUpTable::LookUp_XY(const string& val_name_var, su2double* val_var, su2double val_CV1, - su2double val_CV2, unsigned long i_level) { - unsigned long exit_code = 1; +bool CLookUpTable::LookUp_XY(const vector& idx_var, vector& val_vars, const su2double val_CV1, + const su2double val_CV2, unsigned long i_level) { + unsigned long id_triangle; + bool inside = FindInclusionTriangle(val_CV1, val_CV2, id_triangle, i_level); - if (noSource(val_name_var)) { - *val_var = 0.0; - exit_code = 0; - return exit_code; - } - - /* check if x and y value is in table range */ - if ((val_CV1 >= *limits_table_x[i_level].first && val_CV1 <= *limits_table_x[i_level].second) && - (val_CV2 >= *limits_table_y[i_level].first && val_CV2 <= *limits_table_y[i_level].second)) { - /* find the triangle that holds the (x, y) point */ - unsigned long id_triangle = trap_map_x_y[i_level].GetTriangle(val_CV1, val_CV2); - - if (IsInTriangle(val_CV1, val_CV2, id_triangle, i_level)) { - /* get interpolation coefficients for point on triangle */ - std::array interp_coeffs{0}; - GetInterpCoeffs(val_CV1, val_CV2, interp_mat_inv_x_y[i_level][id_triangle], interp_coeffs); + /* loop over variable names and interpolate / get values */ + if (inside) { + std::array interp_coeffs{0}; + std::array triangle{0}; + for (auto iVertex = 0u; iVertex < N_POINTS_TRIANGLE; iVertex++) + triangle[iVertex] = triangles[i_level][id_triangle][iVertex]; - /* first, copy the single triangle from the large triangle list*/ - std::array triangle{0}; - for (int p = 0; p < 3; p++) triangle[p] = triangles[i_level][id_triangle][p]; + GetInterpCoeffs(val_CV1, val_CV2, interp_mat_inv_x_y[i_level][id_triangle], interp_coeffs); - *val_var = Interpolate(GetDataP(val_name_var, i_level), triangle, interp_coeffs); - exit_code = 0; + for (auto iVar = 0u; iVar < idx_var.size(); iVar++) { + if (idx_var[iVar] == idx_null) { + val_vars[iVar] = 0; + } else { + su2double interp_var = Interpolate(table_data[i_level][idx_var[iVar]], triangle, interp_coeffs); + val_vars[iVar] = interp_var; + } } - } - if (exit_code == 1) InterpolateToNearestNeighbors(val_CV1, val_CV2, val_name_var, val_var, i_level); + } else + InterpolateToNearestNeighbors(val_CV1, val_CV2, idx_var, val_vars, i_level); - return exit_code; + return inside; } -unsigned long CLookUpTable::LookUp_XY(const vector& val_names_var, vector& val_vars, - su2double val_CV1, su2double val_CV2, unsigned long i_level) { - vector look_up_data(val_names_var.size()); +bool CLookUpTable::LookUp_XY(const unsigned long idx_var, su2double* val_var, const su2double val_CV1, + const su2double val_CV2, const unsigned long i_level) { + vector vec_idx_var = {idx_var}; + vector val_vars = {val_var}; + return LookUp_XY(vec_idx_var, val_vars, val_CV1, val_CV2, i_level); +} - for (long unsigned int i_var = 0; i_var < val_vars.size(); ++i_var) { - look_up_data[i_var] = &val_vars[i_var]; - } +bool CLookUpTable::LookUp_XY(const vector& idx_var, vector& val_vars, + const su2double val_CV1, const su2double val_CV2, const unsigned long i_level) { + vector output_var_vals; + output_var_vals.resize(val_vars.size()); + bool inside = LookUp_XY(idx_var, output_var_vals, val_CV1, val_CV2, i_level); - unsigned long exit_code = LookUp_XY(val_names_var, look_up_data, val_CV1, val_CV2, i_level); + for (auto iVar = 0u; iVar < val_vars.size(); iVar++) *val_vars[iVar] = output_var_vals[iVar]; - return exit_code; + return inside; } -unsigned long CLookUpTable::LookUp_XY(const vector& val_names_var, vector& val_vars, - su2double val_CV1, su2double val_CV2, unsigned long i_level) { - unsigned long exit_code = 1; - unsigned long id_triangle = 0; - std::array interp_coeffs{0}; - std::array triangle{0}; - +bool CLookUpTable::FindInclusionTriangle(const su2double val_CV1, const su2double val_CV2, unsigned long& id_triangle, + const unsigned long iLevel) { /* check if x value is in table x-dimension range * and if y is in table y-dimension table range */ - if ((val_CV1 >= *limits_table_x[i_level].first && val_CV1 <= *limits_table_x[i_level].second) && - (val_CV2 >= *limits_table_y[i_level].first && val_CV2 <= *limits_table_y[i_level].second)) { + if ((val_CV1 >= *limits_table_x[iLevel].first && val_CV1 <= *limits_table_x[iLevel].second) && + (val_CV2 >= *limits_table_y[iLevel].first && val_CV2 <= *limits_table_y[iLevel].second)) { /* if so, try to find the triangle that holds the (prog, enth) point */ - id_triangle = trap_map_x_y[i_level].GetTriangle(val_CV1, val_CV2); + id_triangle = trap_map_x_y[iLevel].GetTriangle(val_CV1, val_CV2); /* check if point is inside a triangle (if table domain is non-rectangular, * the previous range check might be true but the point could still be outside of the domain) */ - if (IsInTriangle(val_CV1, val_CV2, id_triangle, i_level)) { - /* if so, get interpolation coefficients for point in the triangle */ - GetInterpCoeffs(val_CV1, val_CV2, interp_mat_inv_x_y[i_level][id_triangle], interp_coeffs); - - /* exit_code 0 means point was in triangle */ - exit_code = 0; - } - } - - /* loop over variable names and interpolate / get values */ - for (long unsigned int i_var = 0; i_var < val_names_var.size(); ++i_var) { - if (noSource(val_names_var[i_var])) { - *val_vars[i_var] = 0.0; - exit_code = 0; - } else { - if (exit_code == 0) { - /* first, copy the single triangle from the large triangle list*/ - for (int p = 0; p < 3; p++) triangle[p] = triangles[i_level][id_triangle][p]; - *val_vars[i_var] = Interpolate(GetDataP(val_names_var[i_var], i_level), triangle, interp_coeffs); - } else { - InterpolateToNearestNeighbors(val_CV1, val_CV2, val_names_var[i_var], val_vars[i_var], i_level); - } - } + return IsInTriangle(val_CV1, val_CV2, id_triangle, iLevel); } - - return exit_code; + return false; } -void CLookUpTable::GetInterpCoeffs(su2double val_CV1, su2double val_CV2, su2activematrix& interp_mat_inv, - std::array& interp_coeffs) { - std::array query_vector = {1, val_CV1, val_CV2}; +void CLookUpTable::GetInterpCoeffs(su2double val_CV1, su2double val_CV2, const su2activematrix& interp_mat_inv, + std::array& interp_coeffs) const { + std::array query_vector = {1, val_CV1, val_CV2}; su2double d; - for (int i = 0; i < 3; i++) { + for (auto i = 0u; i < N_POINTS_TRIANGLE; i++) { d = 0; - for (int j = 0; j < 3; j++) { + for (auto j = 0u; j < N_POINTS_TRIANGLE; j++) { d = d + interp_mat_inv[i][j] * query_vector[j]; } interp_coeffs[i] = d; @@ -689,7 +650,7 @@ su2double CLookUpTable::Interpolate(const su2double* val_samples, std::array CLookUpTable::FindNearestNeighbors(const su2double val_CV1, + const su2double val_CV2, + const unsigned long i_level) { + su2double min_distance = 1e99, second_distance = 1e99; + su2double norm_coeff_x = 1. / (*limits_table_x[i_level].second - *limits_table_x[i_level].first); + su2double norm_coeff_y = 1. / (*limits_table_y[i_level].second - *limits_table_y[i_level].first); + su2double val_CV1_norm = val_CV1 / (*limits_table_x[i_level].second - *limits_table_x[i_level].first); + su2double val_CV2_norm = val_CV2 / (*limits_table_y[i_level].second - *limits_table_y[i_level].first); + + const su2double* x_table = table_data[i_level][idx_CV1]; + const su2double* y_table = table_data[i_level][idx_CV2]; + unsigned long i_nearest = 0, i_second_nearest = 0; + + for (unsigned long i_point = 0; i_point < n_hull_points[i_level]; ++i_point) { + su2double next_x_norm = x_table[hull[i_level][i_point]] * norm_coeff_x; + su2double next_y_norm = y_table[hull[i_level][i_point]] * norm_coeff_y; + + su2double next_distance = pow(val_CV1_norm - next_x_norm, 2) + pow(val_CV2_norm - next_y_norm, 2); + + /* Check if distance to node is lower than current nearest or second nearest node. */ + if (next_distance < min_distance) { + second_distance = min_distance; + min_distance = next_distance; + + i_second_nearest = i_nearest; + i_nearest = hull[i_level][i_point]; + } else if ((next_distance > min_distance) && (next_distance < second_distance)) { + i_second_nearest = hull[i_level][i_point]; + + second_distance = next_distance; + } + } + return make_pair(i_nearest, i_second_nearest); +} + unsigned long CLookUpTable::FindNearestNeighborOnHull(su2double val_CV1, su2double val_CV2, unsigned long i_level) { su2double min_distance = 1.e99; su2double next_distance = 1.e99; - su2double next_x_norm; - su2double next_y_norm; unsigned long neighbor_id = 0; - const su2double* x_table = GetDataP(name_CV1, i_level); - const su2double* y_table = GetDataP(name_CV2, i_level); + const su2double* x_table = table_data[i_level][idx_CV1]; + const su2double* y_table = table_data[i_level][idx_CV2]; su2double norm_coeff_x = 1. / (limits_table_x[i_level].second - limits_table_x[i_level].first); su2double norm_coeff_y = 1. / (limits_table_y[i_level].second - limits_table_y[i_level].first); su2double val_CV1_norm = val_CV1 / (limits_table_x[i_level].second - limits_table_x[i_level].first); su2double val_CV2_norm = val_CV2 / (limits_table_y[i_level].second - limits_table_y[i_level].first); - for (unsigned long i_point = 0; i_point < n_hull_points[i_level]; ++i_point) { - next_x_norm = x_table[hull[i_level][i_point]] * norm_coeff_x; - next_y_norm = y_table[hull[i_level][i_point]] * norm_coeff_y; + for (auto i_point = 0u; i_point < n_hull_points[i_level]; ++i_point) { + su2double next_x_norm = x_table[hull[i_level][i_point]] * norm_coeff_x; + su2double next_y_norm = y_table[hull[i_level][i_point]] * norm_coeff_y; next_distance = sqrt(pow(val_CV1_norm - next_x_norm, 2) + pow(val_CV2_norm - next_y_norm, 2)); @@ -727,39 +721,25 @@ unsigned long CLookUpTable::FindNearestNeighborOnHull(su2double val_CV1, su2doub } void CLookUpTable::InterpolateToNearestNeighbors(const su2double val_CV1, const su2double val_CV2, - const std::vector& names_var, - std::vector& var_vals, const unsigned long i_level) { + const std::vector& idx_var, + std::vector& var_vals, const unsigned long i_level) { /* Interpolate data using distance-weighted averaging on the two nearest table nodes. */ - su2double min_distance = 1e99, second_distance = 1e99; su2double norm_coeff_x = 1. / (*limits_table_x[i_level].second - *limits_table_x[i_level].first); su2double norm_coeff_y = 1. / (*limits_table_y[i_level].second - *limits_table_y[i_level].first); su2double val_CV1_norm = val_CV1 / (*limits_table_x[i_level].second - *limits_table_x[i_level].first); su2double val_CV2_norm = val_CV2 / (*limits_table_y[i_level].second - *limits_table_y[i_level].first); - const su2double* x_table = GetDataP(name_CV1, i_level); - const su2double* y_table = GetDataP(name_CV2, i_level); - unsigned long i_nearest = 0, i_second_nearest = 0; - - for (unsigned long i_point = 0; i_point < n_hull_points[i_level]; ++i_point) { - su2double next_x_norm = x_table[hull[i_level][i_point]] * norm_coeff_x; - su2double next_y_norm = y_table[hull[i_level][i_point]] * norm_coeff_y; - - su2double next_distance = pow(val_CV1_norm - next_x_norm, 2) + pow(val_CV2_norm - next_y_norm, 2); - - /* Check if distance to node is lower than current nearest or second nearest node. */ - if (next_distance < min_distance) { - second_distance = min_distance; - min_distance = next_distance; - - i_second_nearest = i_nearest; - i_nearest = hull[i_level][i_point]; - } else if ((next_distance > min_distance) && (next_distance < second_distance)) { - i_second_nearest = hull[i_level][i_point]; - - second_distance = next_distance; - } - } + std::pair nearest_IDs = FindNearestNeighbors(val_CV1, val_CV2, i_level); + unsigned long i_nearest = nearest_IDs.first, i_second_nearest = nearest_IDs.second; + su2double x_nearest = table_data[i_level][idx_CV1][nearest_IDs.first], + x_second_nearest = table_data[i_level][idx_CV1][nearest_IDs.second], + y_nearest = table_data[i_level][idx_CV2][nearest_IDs.first], + y_second_nearest = table_data[i_level][idx_CV2][nearest_IDs.second]; + su2double min_distance = + pow(val_CV1_norm - x_nearest * norm_coeff_x, 2) + pow(val_CV2_norm - y_nearest * norm_coeff_y, 2); + su2double second_distance = + pow(val_CV1_norm - x_second_nearest * norm_coeff_x, 2) + pow(val_CV2_norm - y_second_nearest * norm_coeff_y, 2); min_distance = sqrt(min_distance); second_distance = sqrt(second_distance); @@ -767,12 +747,34 @@ void CLookUpTable::InterpolateToNearestNeighbors(const su2double val_CV1, const /* Interpolate data using distance-weighted averaging */ su2double delimiter = (1.0 / min_distance) + (1.0 / second_distance); for (auto iVar = 0u; iVar < var_vals.size(); iVar++) { - su2double data_nearest = GetDataP(names_var[iVar], i_level)[i_nearest], - data_second_nearest = GetDataP(names_var[iVar], i_level)[i_second_nearest]; - *var_vals[iVar] = (data_nearest * (1.0 / min_distance) + data_second_nearest * (1.0 / second_distance)) / delimiter; + if (idx_var[iVar] == idx_null) { + var_vals[iVar] = 0; + } else { + su2double data_nearest = table_data[i_level][idx_var[iVar]][i_nearest], + data_second_nearest = table_data[i_level][idx_var[iVar]][i_second_nearest]; + var_vals[iVar] = + (data_nearest * (1.0 / min_distance) + data_second_nearest * (1.0 / second_distance)) / delimiter; + } } } +void CLookUpTable::InterpolateToNearestNeighbors(const su2double val_CV1, const su2double val_CV2, + const std::vector& names_var, + std::vector& var_vals, const unsigned long i_level) { + vector idx_var; + idx_var.resize(names_var.size()); + for (auto iVar = 0u; iVar < names_var.size(); iVar++) idx_var[iVar] = GetIndexOfVar(names_var[iVar]); +} + +void CLookUpTable::InterpolateToNearestNeighbors(const su2double val_CV1, const su2double val_CV2, + const std::vector& idx_var, + std::vector& var_vals, const unsigned long i_level) { + vector output_var_vals; + output_var_vals.resize(var_vals.size()); + InterpolateToNearestNeighbors(val_CV1, val_CV2, idx_var, output_var_vals, i_level); + for (auto iVar = 0u; iVar < var_vals.size(); iVar++) *var_vals[iVar] = output_var_vals[iVar]; +} + void CLookUpTable::InterpolateToNearestNeighbors(const su2double val_CV1, const su2double val_CV2, const std::string& name_var, su2double* var_vals, const unsigned long i_level) { @@ -783,14 +785,14 @@ void CLookUpTable::InterpolateToNearestNeighbors(const su2double val_CV1, const bool CLookUpTable::IsInTriangle(su2double val_CV1, su2double val_CV2, unsigned long val_id_triangle, unsigned long i_level) { - su2double tri_x_0 = GetDataP(name_CV1, i_level)[triangles[i_level][val_id_triangle][0]]; - su2double tri_y_0 = GetDataP(name_CV2, i_level)[triangles[i_level][val_id_triangle][0]]; + su2double tri_x_0 = table_data[i_level][idx_CV1][triangles[i_level][val_id_triangle][0]]; + su2double tri_y_0 = table_data[i_level][idx_CV2][triangles[i_level][val_id_triangle][0]]; - su2double tri_x_1 = GetDataP(name_CV1, i_level)[triangles[i_level][val_id_triangle][1]]; - su2double tri_y_1 = GetDataP(name_CV2, i_level)[triangles[i_level][val_id_triangle][1]]; + su2double tri_x_1 = table_data[i_level][idx_CV1][triangles[i_level][val_id_triangle][1]]; + su2double tri_y_1 = table_data[i_level][idx_CV2][triangles[i_level][val_id_triangle][1]]; - su2double tri_x_2 = GetDataP(name_CV1, i_level)[triangles[i_level][val_id_triangle][2]]; - su2double tri_y_2 = GetDataP(name_CV2, i_level)[triangles[i_level][val_id_triangle][2]]; + su2double tri_x_2 = table_data[i_level][idx_CV1][triangles[i_level][val_id_triangle][2]]; + su2double tri_y_2 = table_data[i_level][idx_CV2][triangles[i_level][val_id_triangle][2]]; su2double area_tri = TriArea(tri_x_0, tri_y_0, tri_x_1, tri_y_1, tri_x_2, tri_y_2); @@ -800,3 +802,13 @@ bool CLookUpTable::IsInTriangle(su2double val_CV1, su2double val_CV2, unsigned l return (abs(area_tri - (area_0 + area_1 + area_2)) < area_tri * 1e-10); } + +bool CLookUpTable::CheckForVariables(const std::vector& vars_to_check) const { + for (const string& var_to_check : vars_to_check) { + if (!std::any_of(names_var.begin(), names_var.end(), + [var_to_check](const std::string& n) { return var_to_check == n; })) { + return false; + }; + } + return true; +} diff --git a/Common/src/containers/CTrapezoidalMap.cpp b/Common/src/containers/CTrapezoidalMap.cpp index b0c1d972b7a..e5494437362 100644 --- a/Common/src/containers/CTrapezoidalMap.cpp +++ b/Common/src/containers/CTrapezoidalMap.cpp @@ -178,7 +178,7 @@ CTrapezoidalMap::CTrapezoidalMap(const su2double* samples_x, const su2double* sa } } -unsigned long CTrapezoidalMap::GetTriangle(su2double val_x, su2double val_y) { +unsigned long CTrapezoidalMap::GetTriangle(const su2double val_x, const su2double val_y) { /* find x band in which val_x sits */ pair band = GetBand(val_x); @@ -210,16 +210,16 @@ unsigned long CTrapezoidalMap::GetTriangle(su2double val_x, su2double val_y) { return triangle[0]; } -pair CTrapezoidalMap::GetBand(su2double val_x) { +pair CTrapezoidalMap::GetBand(const su2double val_x) { unsigned long i_low = 0; unsigned long i_up = 0; - + su2double val_x_sample = val_x; /* check if val_x is in x-bounds of the table, if not then project val_x to either x-min or x-max */ - if (val_x < unique_bands_x.front()) val_x = unique_bands_x.front(); - if (val_x > unique_bands_x.back()) val_x = unique_bands_x.back(); + if (val_x_sample < unique_bands_x.front()) val_x_sample = unique_bands_x.front(); + if (val_x_sample > unique_bands_x.back()) val_x_sample = unique_bands_x.back(); std::pair::iterator, std::vector::iterator> bounds; - bounds = std::equal_range(unique_bands_x.begin(), unique_bands_x.end(), val_x); + bounds = std::equal_range(unique_bands_x.begin(), unique_bands_x.end(), val_x_sample); /*--- if upper bound = 0, then use the range [0,1] ---*/ i_up = max(1, bounds.first - unique_bands_x.begin()); diff --git a/Common/src/geometry/CGeometry.cpp b/Common/src/geometry/CGeometry.cpp index e1f199999f9..bbdbb0316d0 100644 --- a/Common/src/geometry/CGeometry.cpp +++ b/Common/src/geometry/CGeometry.cpp @@ -543,29 +543,29 @@ void CGeometry::PostP2PSends(CGeometry* geometry, const CConfig* config, unsigne END_SU2_OMP_MASTER } -void CGeometry::GetCommCountAndType(const CConfig* config, unsigned short commType, unsigned short& COUNT_PER_POINT, +void CGeometry::GetCommCountAndType(const CConfig* config, MPI_QUANTITIES commType, unsigned short& COUNT_PER_POINT, unsigned short& MPI_TYPE) const { switch (commType) { - case COORDINATES: + case MPI_QUANTITIES::COORDINATES: COUNT_PER_POINT = nDim; MPI_TYPE = COMM_TYPE_DOUBLE; break; - case GRID_VELOCITY: + case MPI_QUANTITIES::GRID_VELOCITY: COUNT_PER_POINT = nDim; MPI_TYPE = COMM_TYPE_DOUBLE; break; - case COORDINATES_OLD: + case MPI_QUANTITIES::COORDINATES_OLD: if (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND) COUNT_PER_POINT = nDim * 2; else COUNT_PER_POINT = nDim; MPI_TYPE = COMM_TYPE_DOUBLE; break; - case MAX_LENGTH: + case MPI_QUANTITIES::MAX_LENGTH: COUNT_PER_POINT = 1; MPI_TYPE = COMM_TYPE_DOUBLE; break; - case NEIGHBORS: + case MPI_QUANTITIES::NEIGHBORS: COUNT_PER_POINT = 1; MPI_TYPE = COMM_TYPE_UNSIGNED_SHORT; break; @@ -575,7 +575,7 @@ void CGeometry::GetCommCountAndType(const CConfig* config, unsigned short commTy } } -void CGeometry::InitiateComms(CGeometry* geometry, const CConfig* config, unsigned short commType) const { +void CGeometry::InitiateComms(CGeometry* geometry, const CConfig* config, MPI_QUANTITIES commType) const { if (nP2PSend == 0) return; /*--- Local variables ---*/ @@ -633,15 +633,15 @@ void CGeometry::InitiateComms(CGeometry* geometry, const CConfig* config, unsign buf_offset = (msg_offset + iSend) * COUNT_PER_POINT; switch (commType) { - case COORDINATES: + case MPI_QUANTITIES::COORDINATES: vector = nodes->GetCoord(iPoint); for (iDim = 0; iDim < nDim; iDim++) bufDSend[buf_offset + iDim] = vector[iDim]; break; - case GRID_VELOCITY: + case MPI_QUANTITIES::GRID_VELOCITY: vector = nodes->GetGridVel(iPoint); for (iDim = 0; iDim < nDim; iDim++) bufDSend[buf_offset + iDim] = vector[iDim]; break; - case COORDINATES_OLD: + case MPI_QUANTITIES::COORDINATES_OLD: vector = nodes->GetCoord_n(iPoint); for (iDim = 0; iDim < nDim; iDim++) { bufDSend[buf_offset + iDim] = vector[iDim]; @@ -653,10 +653,10 @@ void CGeometry::InitiateComms(CGeometry* geometry, const CConfig* config, unsign } } break; - case MAX_LENGTH: + case MPI_QUANTITIES::MAX_LENGTH: bufDSend[buf_offset] = nodes->GetMaxLength(iPoint); break; - case NEIGHBORS: + case MPI_QUANTITIES::NEIGHBORS: bufSSend[buf_offset] = geometry->nodes->GetnNeighbor(iPoint); break; default: @@ -672,7 +672,7 @@ void CGeometry::InitiateComms(CGeometry* geometry, const CConfig* config, unsign } } -void CGeometry::CompleteComms(CGeometry* geometry, const CConfig* config, unsigned short commType) { +void CGeometry::CompleteComms(CGeometry* geometry, const CConfig* config, MPI_QUANTITIES commType) { if (nP2PRecv == 0) return; /*--- Local variables ---*/ @@ -734,21 +734,21 @@ void CGeometry::CompleteComms(CGeometry* geometry, const CConfig* config, unsign /*--- Store the data correctly depending on the quantity. ---*/ switch (commType) { - case COORDINATES: + case MPI_QUANTITIES::COORDINATES: for (iDim = 0; iDim < nDim; iDim++) nodes->SetCoord(iPoint, iDim, bufDRecv[buf_offset + iDim]); break; - case GRID_VELOCITY: + case MPI_QUANTITIES::GRID_VELOCITY: for (iDim = 0; iDim < nDim; iDim++) nodes->SetGridVel(iPoint, iDim, bufDRecv[buf_offset + iDim]); break; - case COORDINATES_OLD: + case MPI_QUANTITIES::COORDINATES_OLD: nodes->SetCoord_n(iPoint, &bufDRecv[buf_offset]); if (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND) nodes->SetCoord_n1(iPoint, &bufDRecv[buf_offset + nDim]); break; - case MAX_LENGTH: + case MPI_QUANTITIES::MAX_LENGTH: nodes->SetMaxLength(iPoint, bufDRecv[buf_offset]); break; - case NEIGHBORS: + case MPI_QUANTITIES::NEIGHBORS: nodes->SetnNeighbor(iPoint, bufSRecv[buf_offset]); break; default: @@ -2327,8 +2327,8 @@ void CGeometry::RegisterCoordinates() const { } void CGeometry::UpdateGeometry(CGeometry** geometry_container, CConfig* config) { - geometry_container[MESH_0]->InitiateComms(geometry_container[MESH_0], config, COORDINATES); - geometry_container[MESH_0]->CompleteComms(geometry_container[MESH_0], config, COORDINATES); + geometry_container[MESH_0]->InitiateComms(geometry_container[MESH_0], config, MPI_QUANTITIES::COORDINATES); + geometry_container[MESH_0]->CompleteComms(geometry_container[MESH_0], config, MPI_QUANTITIES::COORDINATES); geometry_container[MESH_0]->SetControlVolume(config, UPDATE); geometry_container[MESH_0]->SetBoundControlVolume(config, UPDATE); @@ -2386,24 +2386,20 @@ void CGeometry::SetCustomBoundary(CConfig* config) { } void CGeometry::UpdateCustomBoundaryConditions(CGeometry** geometry_container, CConfig* config) { - unsigned short iMGfine, iMGlevel, nMGlevel, iMarker; - - nMGlevel = config->GetnMGLevels(); - for (iMGlevel = 1; iMGlevel <= nMGlevel; iMGlevel++) { - iMGfine = iMGlevel - 1; - for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { - if (config->GetMarker_All_PyCustom(iMarker)) { - switch (config->GetMarker_All_KindBC(iMarker)) { - case HEAT_FLUX: - geometry_container[iMGlevel]->SetMultiGridWallHeatFlux(geometry_container[iMGfine], iMarker); - break; - case ISOTHERMAL: - geometry_container[iMGlevel]->SetMultiGridWallTemperature(geometry_container[iMGfine], iMarker); - break; - // Inlet flow handled in solver class. - default: - break; - } + for (auto iMGlevel = 1u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + const auto iMGfine = iMGlevel - 1; + for (auto iMarker = 0u; iMarker < config->GetnMarker_All(); iMarker++) { + if (!config->GetMarker_All_PyCustom(iMarker)) continue; + switch (config->GetMarker_All_KindBC(iMarker)) { + case HEAT_FLUX: + geometry_container[iMGlevel]->SetMultiGridWallHeatFlux(geometry_container[iMGfine], iMarker); + break; + case ISOTHERMAL: + geometry_container[iMGlevel]->SetMultiGridWallTemperature(geometry_container[iMGfine], iMarker); + break; + // Inlet flow handled in solver class. + default: + break; } } } diff --git a/Common/src/geometry/CMultiGridGeometry.cpp b/Common/src/geometry/CMultiGridGeometry.cpp index 3e2b26c0198..5ae064d778f 100644 --- a/Common/src/geometry/CMultiGridGeometry.cpp +++ b/Common/src/geometry/CMultiGridGeometry.cpp @@ -972,7 +972,7 @@ void CMultiGridGeometry::SetMultiGridWallHeatFlux(const CGeometry* fine_grid, un wall_heat_flux.marker = val_marker; wall_heat_flux.target = CustomBoundaryHeatFlux[val_marker]; - SetMultiGridWallQuantity(fine_grid, val_marker, wall_heat_flux); + SetMultiGridMarkerQuantity(fine_grid, val_marker, wall_heat_flux); } void CMultiGridGeometry::SetMultiGridWallTemperature(const CGeometry* fine_grid, unsigned short val_marker) { @@ -990,7 +990,7 @@ void CMultiGridGeometry::SetMultiGridWallTemperature(const CGeometry* fine_grid, wall_temperature.marker = val_marker; wall_temperature.target = CustomBoundaryTemperature[val_marker]; - SetMultiGridWallQuantity(fine_grid, val_marker, wall_temperature); + SetMultiGridMarkerQuantity(fine_grid, val_marker, wall_temperature); } void CMultiGridGeometry::SetRestricted_GridVelocity(const CGeometry* fine_grid) { diff --git a/Common/src/geometry/CPhysicalGeometry.cpp b/Common/src/geometry/CPhysicalGeometry.cpp index 8d245ce1206..29f10a492b3 100644 --- a/Common/src/geometry/CPhysicalGeometry.cpp +++ b/Common/src/geometry/CPhysicalGeometry.cpp @@ -6364,8 +6364,8 @@ void CPhysicalGeometry::SetMaxLength(CConfig* config) { } END_SU2_OMP_FOR - InitiateComms(this, config, MAX_LENGTH); - CompleteComms(this, config, MAX_LENGTH); + InitiateComms(this, config, MPI_QUANTITIES::MAX_LENGTH); + CompleteComms(this, config, MPI_QUANTITIES::MAX_LENGTH); } void CPhysicalGeometry::MatchActuator_Disk(const CConfig* config) { diff --git a/Common/src/grid_movement/CFreeFormDefBox.cpp b/Common/src/grid_movement/CFreeFormDefBox.cpp index 78e4b384c9f..6cfd9cc8c85 100644 --- a/Common/src/grid_movement/CFreeFormDefBox.cpp +++ b/Common/src/grid_movement/CFreeFormDefBox.cpp @@ -144,7 +144,8 @@ CFreeFormDefBox::~CFreeFormDefBox() { for (iCornerPoints = 0; iCornerPoints < nCornerPoints; iCornerPoints++) delete[] Coord_Corner_Points[iCornerPoints]; delete[] Coord_Corner_Points; - for (iDim = 0; iDim < nDim; iDim++) { + /*--- nDim is 3 at allocation but might change later, so we used fixed 3 as upper bound for deallocation ---*/ + for (iDim = 0; iDim < 3; iDim++) { delete BlendingFunction[iDim]; } delete[] BlendingFunction; diff --git a/Common/src/grid_movement/CSurfaceMovement.cpp b/Common/src/grid_movement/CSurfaceMovement.cpp index 59b0cf7bfe8..5c29534fb39 100644 --- a/Common/src/grid_movement/CSurfaceMovement.cpp +++ b/Common/src/grid_movement/CSurfaceMovement.cpp @@ -33,12 +33,21 @@ CSurfaceMovement::CSurfaceMovement() : CGridMovement() { size = SU2_MPI::GetSize(); rank = SU2_MPI::GetRank(); + FFDBox = nullptr; nFFDBox = 0; nLevel = 0; FFDBoxDefinition = false; } -CSurfaceMovement::~CSurfaceMovement() = default; +CSurfaceMovement::~CSurfaceMovement() { + if (FFDBox != nullptr) { + for (unsigned int iFFDBox = 0; iFFDBox < MAX_NUMBER_FFD; ++iFFDBox) { + if (FFDBox[iFFDBox] != nullptr) delete FFDBox[iFFDBox]; + } + delete[] FFDBox; + FFDBox = nullptr; + } +} vector > CSurfaceMovement::SetSurface_Deformation(CGeometry* geometry, CConfig* config) { unsigned short iFFDBox, iDV, iLevel, iChild, iParent, jFFDBox, iMarker; @@ -60,7 +69,16 @@ vector > CSurfaceMovement::SetSurface_Deformation(CGeometry* g if (config->GetDesign_Variable(0) == FFD_SETTING) { /*--- Definition of the FFD deformation class ---*/ - FFDBox = new CFreeFormDefBox*[MAX_NUMBER_FFD]; + /*--- As this method might be called multiple times, properly delete old objects before allocating new ones. ---*/ + if (FFDBox != nullptr) { + for (iFFDBox = 0; iFFDBox < MAX_NUMBER_FFD; ++iFFDBox) { + if (FFDBox[iFFDBox] != nullptr) delete FFDBox[iFFDBox]; + } + delete[] FFDBox; + FFDBox = nullptr; + } + + FFDBox = new CFreeFormDefBox*[MAX_NUMBER_FFD](); /*--- Read the FFD information from the config file ---*/ @@ -167,7 +185,16 @@ vector > CSurfaceMovement::SetSurface_Deformation(CGeometry* g (config->GetDesign_Variable(0) == FFD_THICKNESS) || (config->GetDesign_Variable(0) == FFD_ANGLE_OF_ATTACK)) { /*--- Definition of the FFD deformation class ---*/ - FFDBox = new CFreeFormDefBox*[MAX_NUMBER_FFD]; + /*--- As this method might be called multiple times, properly delete old objects before allocating new ones. ---*/ + if (FFDBox != nullptr) { + for (iFFDBox = 0; iFFDBox < MAX_NUMBER_FFD; ++iFFDBox) { + if (FFDBox[iFFDBox] != nullptr) delete FFDBox[iFFDBox]; + } + delete[] FFDBox; + FFDBox = nullptr; + } + + FFDBox = new CFreeFormDefBox*[MAX_NUMBER_FFD](); /*--- Read the FFD information from the grid file ---*/ diff --git a/Common/src/grid_movement/CVolumetricMovement.cpp b/Common/src/grid_movement/CVolumetricMovement.cpp index 5b09a9cdd71..a3f91fa36c1 100644 --- a/Common/src/grid_movement/CVolumetricMovement.cpp +++ b/Common/src/grid_movement/CVolumetricMovement.cpp @@ -76,8 +76,8 @@ void CVolumetricMovement::UpdateGridCoord(CGeometry* geometry, CConfig* config) * Hence we still need a communication of the transformed coordinates, otherwise periodicity * is not maintained. ---*/ - geometry->InitiateComms(geometry, config, COORDINATES); - geometry->CompleteComms(geometry, config, COORDINATES); + geometry->InitiateComms(geometry, config, MPI_QUANTITIES::COORDINATES); + geometry->CompleteComms(geometry, config, MPI_QUANTITIES::COORDINATES); } void CVolumetricMovement::UpdateDualGrid(CGeometry* geometry, CConfig* config) { diff --git a/Common/src/linear_algebra/CSysMatrix.cpp b/Common/src/linear_algebra/CSysMatrix.cpp index 10747fadbcb..280d05b6b7f 100644 --- a/Common/src/linear_algebra/CSysMatrix.cpp +++ b/Common/src/linear_algebra/CSysMatrix.cpp @@ -226,7 +226,7 @@ void CSysMatrix::Initialize(unsigned long npoint, unsigned long npoi template void CSysMatrixComms::Initiate(const CSysVector& x, CGeometry* geometry, const CConfig* config, - unsigned short commType) { + MPI_QUANTITIES commType) { if (geometry->nP2PSend == 0) return; /*--- Local variables ---*/ @@ -236,13 +236,13 @@ void CSysMatrixComms::Initiate(const CSysVector& x, CGeometry* geometry, cons /*--- Create a boolean for reversing the order of comms. ---*/ - const bool reverse = (commType == SOLUTION_MATRIXTRANS); + const bool reverse = (commType == MPI_QUANTITIES::SOLUTION_MATRIXTRANS); /*--- Set the size of the data packet and type depending on quantity. ---*/ switch (commType) { - case SOLUTION_MATRIX: - case SOLUTION_MATRIXTRANS: + case MPI_QUANTITIES::SOLUTION_MATRIX: + case MPI_QUANTITIES::SOLUTION_MATRIXTRANS: break; default: SU2_MPI::Error("Unrecognized quantity for point-to-point MPI comms.", CURRENT_FUNCTION); @@ -265,7 +265,7 @@ void CSysMatrixComms::Initiate(const CSysVector& x, CGeometry* geometry, cons for (auto iMessage = 0; iMessage < geometry->nP2PSend; iMessage++) { switch (commType) { - case SOLUTION_MATRIX: { + case MPI_QUANTITIES::SOLUTION_MATRIX: { su2double* bufDSend = geometry->bufD_P2PSend; /*--- Get the offset for the start of this message. ---*/ @@ -294,7 +294,7 @@ void CSysMatrixComms::Initiate(const CSysVector& x, CGeometry* geometry, cons break; } - case SOLUTION_MATRIXTRANS: { + case MPI_QUANTITIES::SOLUTION_MATRIXTRANS: { /*--- We are going to communicate in reverse, so we use the recv buffer for the send instead. Also, all of the offsets and counts are derived from the recv data structures. ---*/ @@ -341,7 +341,7 @@ void CSysMatrixComms::Initiate(const CSysVector& x, CGeometry* geometry, cons } template -void CSysMatrixComms::Complete(CSysVector& x, CGeometry* geometry, const CConfig* config, unsigned short commType) { +void CSysMatrixComms::Complete(CSysVector& x, CGeometry* geometry, const CConfig* config, MPI_QUANTITIES commType) { if (geometry->nP2PRecv == 0) return; /*--- Local variables ---*/ @@ -366,7 +366,7 @@ void CSysMatrixComms::Complete(CSysVector& x, CGeometry* geometry, const CCon const auto source = status.MPI_SOURCE; switch (commType) { - case SOLUTION_MATRIX: { + case MPI_QUANTITIES::SOLUTION_MATRIX: { const su2double* bufDRecv = geometry->bufD_P2PRecv; /*--- We know the offsets based on the source rank. ---*/ @@ -400,7 +400,7 @@ void CSysMatrixComms::Complete(CSysVector& x, CGeometry* geometry, const CCon break; } - case SOLUTION_MATRIXTRANS: { + case MPI_QUANTITIES::SOLUTION_MATRIXTRANS: { /*--- We are going to communicate in reverse, so we use the send buffer for the recv instead. Also, all of the offsets and counts are derived from the send data structures. ---*/ @@ -1197,8 +1197,8 @@ void CSysMatrix::ComputePastixPreconditioner(const CSysVector(const CSysVector&, CGeometry*, const CConfig*, unsigned short); \ - template void CSysMatrixComms::Complete(CSysVector&, CGeometry*, const CConfig*, unsigned short); + template void CSysMatrixComms::Initiate(const CSysVector&, CGeometry*, const CConfig*, MPI_QUANTITIES); \ + template void CSysMatrixComms::Complete(CSysVector&, CGeometry*, const CConfig*, MPI_QUANTITIES); #define INSTANTIATE_MATRIX(TYPE) \ template class CSysMatrix; \ diff --git a/Docs/docmain.hpp b/Docs/docmain.hpp index 96743d0e371..5fefea50075 100644 --- a/Docs/docmain.hpp +++ b/Docs/docmain.hpp @@ -225,9 +225,3 @@ * \brief Classes for explicit (done by the programmer) vectorization (SIMD) of computations. * \ingroup Toolboxes */ - -/*! - * \defgroup Multi-Layer Perceptrons (MLP) - * \brief Data look up and interpolation via dense, feed-forward multi-layer perceptrons. - * \ingroup Toolboxes - */ diff --git a/SU2_CFD/include/drivers/CDriver.hpp b/SU2_CFD/include/drivers/CDriver.hpp index 4d284a56f0c..c5e78bd9037 100644 --- a/SU2_CFD/include/drivers/CDriver.hpp +++ b/SU2_CFD/include/drivers/CDriver.hpp @@ -505,7 +505,7 @@ class CDriver : public CDriverBase { /*! * \brief Set the direction of the inlet. * \param[in] iMarker - Marker index. - * \param[in] alpha - Angle (Zpos). + * \param[in] alpha - Angle around z axis. */ void SetInletAngle(unsigned short iMarker, passivedouble alpha); @@ -554,7 +554,7 @@ class CDriver : public CDriverBase { * \param[in] vel_z - Value of velocity along z-axis. */ void SetMarkerTranslationRate(unsigned short iMarker, passivedouble vel_x, passivedouble vel_y, passivedouble vel_z); - + /// \} }; diff --git a/SU2_CFD/include/drivers/CDriverBase.hpp b/SU2_CFD/include/drivers/CDriverBase.hpp index ea29323e189..c9c296ce57c 100644 --- a/SU2_CFD/include/drivers/CDriverBase.hpp +++ b/SU2_CFD/include/drivers/CDriverBase.hpp @@ -701,6 +701,39 @@ class CDriverBase { } } + /*! + * \brief Set the first variable in MARKER_INLET (usually temperature). + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \param[in] value - Value of the variable. + */ + void SetMarkerCustomInletFlowVar0(unsigned short iMarker, unsigned long iVertex, passivedouble value) { + GetSolverAndCheckMarker(FLOW_SOL, iMarker)->SetInletTtotal(iMarker, iVertex, value); + } + + /*! + * \brief Set the second variable in MARKER_INLET (usually total pressure). + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \param[in] value - Value of the variable. + */ + void SetMarkerCustomInletFlowVar1(unsigned short iMarker, unsigned long iVertex, passivedouble value) { + GetSolverAndCheckMarker(FLOW_SOL, iMarker)->SetInletPtotal(iMarker, iVertex, value); + } + + /*! + * \brief Set the flow direction vector (does not need to be a unit vector). + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \param[in] values - Flow direction vector. + */ + void SetMarkerCustomInletFlowDirection(unsigned short iMarker, unsigned long iVertex, std::vector values) { + auto* solver = GetSolverAndCheckMarker(FLOW_SOL, iMarker); + for (auto iDim = 0ul; iDim < GetNumberDimensions(); ++iDim) { + solver->SetInletFlowDir(iMarker, iVertex, iDim, values[iDim]); + } + } + /// \} protected: diff --git a/SU2_CFD/include/fluid/CDataDrivenFluid.hpp b/SU2_CFD/include/fluid/CDataDrivenFluid.hpp index 57ffca7cc88..1a524326c8a 100644 --- a/SU2_CFD/include/fluid/CDataDrivenFluid.hpp +++ b/SU2_CFD/include/fluid/CDataDrivenFluid.hpp @@ -95,7 +95,14 @@ class CDataDrivenFluid final : public CFluidModel { vector MLP_inputs; /*!< \brief Inputs for the multi-layer perceptron look-up operation. */ CLookUpTable* lookup_table; /*!< \brief Look-up table regression object. */ - + unsigned long LUT_idx_s, + LUT_idx_dsde_rho, + LUT_idx_dsdrho_e, + LUT_idx_d2sde2, + LUT_idx_d2sdedrho, + LUT_idx_d2sdrho2; + vector LUT_lookup_indices; + unsigned long outside_dataset, /*!< \brief Density-energy combination lies outside data set. */ nIter_Newton; /*!< \brief Number of Newton solver iterations. */ diff --git a/SU2_CFD/include/fluid/CFluidFlamelet.hpp b/SU2_CFD/include/fluid/CFluidFlamelet.hpp index b066b2d0353..49273b2a9e6 100644 --- a/SU2_CFD/include/fluid/CFluidFlamelet.hpp +++ b/SU2_CFD/include/fluid/CFluidFlamelet.hpp @@ -42,9 +42,11 @@ class CFluidFlamelet final : public CFluidModel { enum LOOKUP_TD { TEMPERATURE, HEATCAPACITY, VISCOSITY, CONDUCTIVITY, DIFFUSIONCOEFFICIENT, MOLARWEIGHT, SIZE }; + su2double beta_progvar, beta_enth_thermal, beta_enth, beta_mixfrac; int rank; - bool include_mixture_fraction = false; /*!< \brief include mixture fraction in controlling variables. */ + bool include_mixture_fraction = false, /*!< \brief include mixture fraction in controlling variables. */ + preferential_diffusion = false; /*!< \brief use preferential diffusion physics. */ unsigned short n_scalars, n_lookups, n_user_scalars, /*!< \brief number of passive reactant species. */ n_control_vars; /*!< \brief number of controlling variables. */ @@ -60,10 +62,17 @@ class CFluidFlamelet final : public CFluidModel { CLookUpTable* look_up_table; + vector LUT_idx_TD, + LUT_idx_Sources, + LUT_idx_LookUp, + LUT_idx_PD; + /*--- Class variables for the multi-layer perceptron method ---*/ #ifdef USE_MLPCPP + size_t n_betas; MLPToolbox::CLookUp_ANN* lookup_mlp; /*!< \brief Multi-layer perceptron collection. */ MLPToolbox::CIOMap* iomap_TD; /*!< \brief Input-output map for thermochemical properties. */ + MLPToolbox::CIOMap* iomap_PD; /*!< \brief Input-output map for the preferential diffusion scalars. */ MLPToolbox::CIOMap* iomap_Sources; /*!< \brief Input-output map for species source terms. */ MLPToolbox::CIOMap* iomap_LookUp; /*!< \brief Input-output map for passive look-up terms. */ MLPToolbox::CIOMap* iomap_Current; @@ -72,13 +81,28 @@ class CFluidFlamelet final : public CFluidModel { vector scalars_vector; vector varnames_TD, /*!< \brief Lookup names for thermodynamic state variables. */ - varnames_Sources, varnames_LookUp; + varnames_Sources, /*!< \brief Lookup names for source terms. */ + varnames_LookUp, /*!< \brief Lookup names for passive look-up terms. */ + varnames_PD; /*!< \brief Lookup names for preferential diffusion scalars. */ vector val_vars_TD, /*!< \brief References to thermodynamic state variables. */ - val_vars_Sources, val_vars_LookUp; + val_vars_Sources, /*!< \brief References to source terms. */ + val_vars_LookUp, /*!< \brief References passive look-up terms. */ + val_vars_PD; /*!< \brief References to preferential diffusion scalars. */ void PreprocessLookUp(CConfig* config); + /*! \brief + * Returns true if the string is null or zero (ignores case). + */ + inline bool noSource(const std::string& name_var) const { + if (name_var.compare("NULL") == 0 || name_var.compare("Null") == 0 || name_var.compare("null") == 0 || + name_var.compare("ZERO") == 0 || name_var.compare("Zero") == 0 || name_var.compare("zero") == 0) { + return true; + } else { + return false; + } + } public: CFluidFlamelet(CConfig* config, su2double value_pressure_operating); @@ -92,14 +116,14 @@ class CFluidFlamelet final : public CFluidModel { void SetTDState_T(su2double val_temperature, const su2double* val_scalars = nullptr) override; /*! - * \brief Evaluate the flamelet manifold. - * \param[in] input_scalar - scalar solution. - * \param[in] input_varnames - names of variables to evaluate. - * \param[in] output_refs - output data. - * \param[out] Extrapolation - scalar solution is within bounds (0) or out of bounds (1). + * \brief Evaluate data-set for flamelet simulations. + * \param[in] input_scalar - controlling variables used to interpolate manifold. + * \param[in] lookup_type - look-up operation to be performed (FLAMELET_LOOKUP_OPS) + * \param[in] output_refs - output variables where interpolated results are stored. + * \param[out] Extrapolation - query data is within manifold bounds (0) or out of bounds (1). */ - inline unsigned long EvaluateDataSet(const vector& input_scalar, unsigned short lookup_type, - vector& output_refs) override; + unsigned long EvaluateDataSet(const vector& input_scalar, unsigned short lookup_type, + vector& output_refs); /*! * \brief Check for out-of-bounds condition for data set interpolation. @@ -127,4 +151,10 @@ class CFluidFlamelet final : public CFluidModel { * \param[out] Mu - value of the laminar viscosity */ inline su2double GetLaminarViscosity() override { return Mu; } + + /*! + * \brief Preferential diffusion as relevant phenomenon in flamelet simulations. + * \return Inclusion of preferential diffusion model. + */ + inline bool GetPreferentialDiffusion() const override { return preferential_diffusion; } }; diff --git a/SU2_CFD/include/fluid/CFluidModel.hpp b/SU2_CFD/include/fluid/CFluidModel.hpp index 7fc767b17d2..29f0becdb0d 100644 --- a/SU2_CFD/include/fluid/CFluidModel.hpp +++ b/SU2_CFD/include/fluid/CFluidModel.hpp @@ -46,34 +46,34 @@ class CLookUpTable; */ class CFluidModel { protected: - su2double StaticEnergy{0.0}; /*!< \brief Internal Energy. */ - su2double Entropy{0.0}; /*!< \brief Entropy. */ - su2double Density{0.0}; /*!< \brief Density. */ - su2double Pressure{0.0}; /*!< \brief Pressure. */ - su2double SoundSpeed2{0.0}; /*!< \brief SpeedSound. */ - su2double Temperature{0.0}; /*!< \brief Temperature. */ - su2double dPdrho_e{0.0}; /*!< \brief DpDd_e. */ - su2double dPde_rho{0.0}; /*!< \brief DpDe_d. */ - su2double dTdrho_e{0.0}; /*!< \brief DTDd_e. */ - su2double dTde_rho{0.0}; /*!< \brief DTDe_d. */ - su2double dhdrho_P{0.0}; /*!< \brief DhDrho_p. */ - su2double dhdP_rho{0.0}; /*!< \brief DhDp_rho. */ - su2double dsdrho_P{0.0}; /*!< \brief DsDrho_p. */ - su2double dsdP_rho{0.0}; /*!< \brief DsDp_rho. */ - su2double Cp{0.0}; /*!< \brief Specific Heat Capacity at constant pressure. */ - su2double Cv{0.0}; /*!< \brief Specific Heat Capacity at constant volume. */ - su2double Mu{0.0}; /*!< \brief Laminar viscosity. */ - su2double Mu_Turb{0.0}; /*!< \brief Eddy viscosity provided by a turbulence model. */ - su2double dmudrho_T{0.0}; /*!< \brief Partial derivative of viscosity w.r.t. density. */ - su2double dmudT_rho{0.0}; /*!< \brief Partial derivative of viscosity w.r.t. temperature. */ - su2double Kt{0.0}; /*!< \brief Thermal conductivity. */ - su2double dktdrho_T{0.0}; /*!< \brief Partial derivative of conductivity w.r.t. density. */ - su2double dktdT_rho{0.0}; /*!< \brief Partial derivative of conductivity w.r.t. temperature. */ - su2double mass_diffusivity{0.0}; /*!< \brief Mass Diffusivity */ + su2double StaticEnergy{0.0}; /*!< \brief Internal Energy. */ + su2double Entropy{0.0}; /*!< \brief Entropy. */ + su2double Density{0.0}; /*!< \brief Density. */ + su2double Pressure{0.0}; /*!< \brief Pressure. */ + su2double SoundSpeed2{0.0}; /*!< \brief SpeedSound. */ + su2double Temperature{0.0}; /*!< \brief Temperature. */ + su2double dPdrho_e{0.0}; /*!< \brief DpDd_e. */ + su2double dPde_rho{0.0}; /*!< \brief DpDe_d. */ + su2double dTdrho_e{0.0}; /*!< \brief DTDd_e. */ + su2double dTde_rho{0.0}; /*!< \brief DTDe_d. */ + su2double dhdrho_P{0.0}; /*!< \brief DhDrho_p. */ + su2double dhdP_rho{0.0}; /*!< \brief DhDp_rho. */ + su2double dsdrho_P{0.0}; /*!< \brief DsDrho_p. */ + su2double dsdP_rho{0.0}; /*!< \brief DsDp_rho. */ + su2double Cp{0.0}; /*!< \brief Specific Heat Capacity at constant pressure. */ + su2double Cv{0.0}; /*!< \brief Specific Heat Capacity at constant volume. */ + su2double Mu{0.0}; /*!< \brief Laminar viscosity. */ + su2double Mu_Turb{0.0}; /*!< \brief Eddy viscosity provided by a turbulence model. */ + su2double dmudrho_T{0.0}; /*!< \brief Partial derivative of viscosity w.r.t. density. */ + su2double dmudT_rho{0.0}; /*!< \brief Partial derivative of viscosity w.r.t. temperature. */ + su2double Kt{0.0}; /*!< \brief Thermal conductivity. */ + su2double dktdrho_T{0.0}; /*!< \brief Partial derivative of conductivity w.r.t. density. */ + su2double dktdT_rho{0.0}; /*!< \brief Partial derivative of conductivity w.r.t. temperature. */ + su2double mass_diffusivity{0.0}; /*!< \brief Mass Diffusivity */ unique_ptr LaminarViscosity; /*!< \brief Laminar Viscosity Model */ unique_ptr ThermalConductivity; /*!< \brief Thermal Conductivity Model */ - unique_ptr MassDiffusivity; /*!< \brief Mass Diffusivity Model */ + unique_ptr MassDiffusivity; /*!< \brief Mass Diffusivity Model */ /*! * \brief Instantiate the right type of viscosity model based on config. @@ -144,10 +144,16 @@ class CFluidModel { virtual inline unsigned short GetNScalars() const { return 0; } /*! - * \brief Evaluate data manifold for flamelet or data-driven fluid problems. - * \param[in] input - input data for manifold regression. + * \brief Evaluate data-set for flamelet or data-driven fluid simulations. + * \param[in] input_scalar - data manifold query data. + * \param[in] lookup_type - look-up operation to be performed. + * \param[in] output_refs - output variables where interpolated results are stored. + * \param[out] Extrapolation - query data is within manifold bounds (0) or out of bounds (1). */ - virtual unsigned long EvaluateDataSet(const vector &input_scalar, unsigned short lookup_type, vector &output_refs) { return 0; } + virtual unsigned long EvaluateDataSet(const vector& input_scalar, unsigned short lookup_type, + vector& output_refs) { + return 0; + } /*! * \brief Get fluid dynamic viscosity. @@ -331,7 +337,7 @@ class CFluidModel { * \brief Virtual member. * \param[in] T - Temperature value at the point. */ - virtual void SetTDState_T(su2double val_Temperature, const su2double* val_scalars = nullptr) { } + virtual void SetTDState_T(su2double val_Temperature, const su2double* val_scalars = nullptr) {} /*! * \brief Set fluid eddy viscosity provided by a turbulence model needed for computing effective thermal conductivity. @@ -344,6 +350,12 @@ class CFluidModel { */ virtual unsigned long GetExtrapolation() const { return 0; } + /*! + * \brief Get the state of the Preferential diffusion model for flamelet simulations. + * \return True if preferential diffusion model is active, false otherwise. + */ + virtual bool GetPreferentialDiffusion() const { return false; } + /*! * \brief Get number of Newton solver iterations. * \return Newton solver iteration count at termination. diff --git a/SU2_CFD/include/interfaces/CInterface.hpp b/SU2_CFD/include/interfaces/CInterface.hpp index 9ec0599827e..a86db24b12a 100644 --- a/SU2_CFD/include/interfaces/CInterface.hpp +++ b/SU2_CFD/include/interfaces/CInterface.hpp @@ -219,4 +219,9 @@ class CInterface { */ void GatherAverageValues(CSolver *donor_solution, CSolver *target_solution, unsigned short donorZone); + /*! + * \brief Set the contact resistance value for the solid-to-solid heat transfer interface. + * \param[in] val_contact_resistance - Contact resistance value in m^2/W + */ + inline virtual void SetContactResistance(su2double val_contact_resistance) {}; }; diff --git a/SU2_CFD/include/interfaces/cht/CConjugateHeatInterface.hpp b/SU2_CFD/include/interfaces/cht/CConjugateHeatInterface.hpp index 919d4e8f7f1..982733d5e36 100644 --- a/SU2_CFD/include/interfaces/cht/CConjugateHeatInterface.hpp +++ b/SU2_CFD/include/interfaces/cht/CConjugateHeatInterface.hpp @@ -35,6 +35,7 @@ * \ingroup Interfaces */ class CConjugateHeatInterface : public CInterface { + su2double ContactResistance = 0; /*!<\brief Contact resistance value of the current inerface. */ public: /*! * \brief Constructor of the class. @@ -70,4 +71,10 @@ class CConjugateHeatInterface : public CInterface { */ void SetTarget_Variable(CSolver *target_solution, CGeometry *target_geometry, const CConfig *target_config, unsigned long Marker_Target, unsigned long Vertex_Target, unsigned long Point_Target) override; + + /*! + * \brief Set the contact resistance value for the solid-to-solid heat transfer interface. + * \param[in] val_contact_resistance - Contact resistance value in m^2/W + */ + void SetContactResistance(su2double val_contact_resistance) override { ContactResistance = val_contact_resistance; } }; diff --git a/SU2_CFD/include/iteration/CFluidIteration.hpp b/SU2_CFD/include/iteration/CFluidIteration.hpp index 07883903a05..7ce8cec5151 100644 --- a/SU2_CFD/include/iteration/CFluidIteration.hpp +++ b/SU2_CFD/include/iteration/CFluidIteration.hpp @@ -109,8 +109,12 @@ class CFluidIteration : public CIteration { /*! * \brief Monitors turbo computation (pressure and turbo ramps). + * \param[in] geometry_container - Geometrical definition of the problem + * \param[in] config_container - Defintion of the particular problem + * \param[in] ExtIter - The current iteration of the problem + * \param[in] iZone - The current zone */ - void TurboMonitor(CGeometry**** geometry_container, CConfig** config_container, unsigned long ExtIter); + void TurboMonitor(CGeometry**** geometry_container, CConfig** config_container, unsigned long ExtIter, unsigned short iZone); /*! * \brief Computes turboperformance. diff --git a/SU2_CFD/include/output/CTurboOutput.hpp b/SU2_CFD/include/output/CTurboOutput.hpp index cc7e2356f07..5a1741530cd 100644 --- a/SU2_CFD/include/output/CTurboOutput.hpp +++ b/SU2_CFD/include/output/CTurboOutput.hpp @@ -87,7 +87,7 @@ class CTurbomachineryCombinedPrimitiveStates { class CTurbomachineryState { private: su2double Density, Pressure, Entropy, Enthalpy, Temperature, TotalTemperature, TotalPressure, TotalEnthalpy; - su2double AbsFlowAngle, FlowAngle, MassFlow, Rothalpy, TotalRelPressure; + su2double AbsFlowAngle, FlowAngle, MassFlow, Rothalpy, TangVelocity, TotalRelPressure; vector Velocity, RelVelocity, Mach, RelMach; su2double Area, Radius; @@ -124,6 +124,8 @@ class CTurbomachineryState { const su2double& GetRothalpy() const { return Rothalpy; } + const su2double& GetTangVelocity() const { return TangVelocity; } + const vector& GetVelocity() const { return Velocity; } const vector& GetMach() const { return Mach; } @@ -207,7 +209,7 @@ class CPropellorBladePerformance : public CTurbomachineryBladePerformance { */ class CTurbomachineryStagePerformance { protected: - su2double TotalStaticEfficiency, TotalTotalEfficiency, NormEntropyGen, TotalStaticPressureRatio, TotalTotalPressureRatio, EulerianWork; + su2double TotalStaticEfficiency, TotalTotalEfficiency, NormEntropyGen, TotalStaticPressureRatio, TotalTotalPressureRatio, EulerianWork, TotalPressureLoss, KineticEnergyLoss; CFluidModel& fluidModel; public: @@ -232,6 +234,10 @@ class CTurbomachineryStagePerformance { su2double GetTotalStaticPressureRatio() const { return TotalStaticPressureRatio; } su2double GetTotalTotalPressureRatio() const { return TotalTotalPressureRatio; } + + su2double GetTotalPressureLoss() const { return TotalPressureLoss; } + + su2double GetKineticEnergyLoss() const { return KineticEnergyLoss; } }; /*! diff --git a/SU2_CFD/include/solvers/CEulerSolver.hpp b/SU2_CFD/include/solvers/CEulerSolver.hpp index 5dbef8b6784..d498b84c225 100644 --- a/SU2_CFD/include/solvers/CEulerSolver.hpp +++ b/SU2_CFD/include/solvers/CEulerSolver.hpp @@ -138,6 +138,7 @@ class CEulerSolver : public CFVMFlowSolverBaseval_marker where the total temperature is evaluated. * \return Value of the total temperature */ - inline su2double GetInlet_Ttotal(unsigned short val_marker, unsigned long val_vertex) const final { + inline su2double GetInletTtotal(unsigned short val_marker, unsigned long val_vertex) const final { return Inlet_Ttotal[val_marker][val_vertex]; } @@ -2129,7 +2129,7 @@ class CFVMFlowSolverBase : public CSolver { * \param[in] val_vertex - Vertex of the marker val_marker where the total pressure is evaluated. * \return Value of the total pressure */ - inline su2double GetInlet_Ptotal(unsigned short val_marker, unsigned long val_vertex) const final { + inline su2double GetInletPtotal(unsigned short val_marker, unsigned long val_vertex) const final { return Inlet_Ptotal[val_marker][val_vertex]; } @@ -2140,7 +2140,7 @@ class CFVMFlowSolverBase : public CSolver { * \param[in] val_dim - The component of the flow direction unit vector to be evaluated * \return Component of a unit vector representing the flow direction. */ - inline su2double GetInlet_FlowDir(unsigned short val_marker, unsigned long val_vertex, + inline su2double GetInletFlowDir(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim) const final { return Inlet_FlowDir[val_marker][val_vertex][val_dim]; } @@ -2151,7 +2151,7 @@ class CFVMFlowSolverBase : public CSolver { * \param[in] val_vertex - Vertex of the marker val_marker where the total temperature is set. * \param[in] val_ttotal - Value of the total temperature */ - inline void SetInlet_Ttotal(unsigned short val_marker, unsigned long val_vertex, su2double val_ttotal) final { + inline void SetInletTtotal(unsigned short val_marker, unsigned long val_vertex, su2double val_ttotal) final { /*--- Since this call can be accessed indirectly using python, do some error * checking to prevent segmentation faults ---*/ if (val_marker >= nMarker) @@ -2168,7 +2168,7 @@ class CFVMFlowSolverBase : public CSolver { * \param[in] val_vertex - Vertex of the marker val_marker where the total pressure is set. * \param[in] val_ptotal - Value of the total pressure */ - inline void SetInlet_Ptotal(unsigned short val_marker, unsigned long val_vertex, su2double val_ptotal) final { + inline void SetInletPtotal(unsigned short val_marker, unsigned long val_vertex, su2double val_ptotal) final { /*--- Since this call can be accessed indirectly using python, do some error * checking to prevent segmentation faults ---*/ if (val_marker >= nMarker) @@ -2186,8 +2186,8 @@ class CFVMFlowSolverBase : public CSolver { * \param[in] val_dim - The component of the flow direction unit vector to be set * \param[in] val_flowdir - Component of a unit vector representing the flow direction. */ - inline void SetInlet_FlowDir(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim, - su2double val_flowdir) final { + inline void SetInletFlowDir(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim, + su2double val_flowdir) final { /*--- Since this call can be accessed indirectly using python, do some error * checking to prevent segmentation faults ---*/ if (val_marker >= nMarker) @@ -2198,6 +2198,15 @@ class CFVMFlowSolverBase : public CSolver { Inlet_FlowDir[val_marker][val_vertex][val_dim] = val_flowdir; } + /*! + * \brief Update the multi-grid structure for the customized boundary conditions. + * \param geometry_container - Geometrical definition. + * \param solver_container - Solver definition. + * \param config - Definition of the particular problem. + */ + void UpdateCustomBoundaryConditions(CGeometry **geometry_container, CSolver ***solver_container, + CConfig *config) final; + /*! * \brief Updates the components of the farfield velocity vector. */ diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl index c3051311c30..eb3edb511db 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl @@ -266,8 +266,8 @@ void CFVMFlowSolverBase::CommunicateInitialState(CGeometry* geometry, cons /*--- Perform the MPI communication of the solution ---*/ - InitiateComms(geometry, config, SOLUTION); - CompleteComms(geometry, config, SOLUTION); + InitiateComms(geometry, config, MPI_QUANTITIES::SOLUTION); + CompleteComms(geometry, config, MPI_QUANTITIES::SOLUTION); /*--- Store the initial CFL number for all grid points. ---*/ @@ -383,7 +383,7 @@ void CFVMFlowSolverBase::SetPrimitive_Gradient_GG(CGeometry* geometry, con bool reconstruction) { const auto& primitives = nodes->GetPrimitive(); auto& gradient = reconstruction ? nodes->GetGradient_Reconstruction() : nodes->GetGradient_Primitive(); - const auto comm = reconstruction? PRIMITIVE_GRAD_REC : PRIMITIVE_GRADIENT; + const auto comm = reconstruction? MPI_QUANTITIES::PRIMITIVE_GRAD_REC : MPI_QUANTITIES::PRIMITIVE_GRADIENT; const auto commPer = reconstruction? PERIODIC_PRIM_GG_R : PERIODIC_PRIM_GG; computeGradientsGreenGauss(this, comm, commPer, *geometry, *config, primitives, 0, nPrimVarGrad, gradient); @@ -408,7 +408,7 @@ void CFVMFlowSolverBase::SetPrimitive_Gradient_LS(CGeometry* geometry, con const auto& primitives = nodes->GetPrimitive(); auto& rmatrix = nodes->GetRmatrix(); auto& gradient = reconstruction ? nodes->GetGradient_Reconstruction() : nodes->GetGradient_Primitive(); - const auto comm = reconstruction? PRIMITIVE_GRAD_REC : PRIMITIVE_GRADIENT; + const auto comm = reconstruction? MPI_QUANTITIES::PRIMITIVE_GRAD_REC : MPI_QUANTITIES::PRIMITIVE_GRADIENT; computeGradientsLeastSquares(this, comm, commPer, *geometry, *config, weighted, primitives, 0, nPrimVarGrad, gradient, rmatrix); @@ -423,7 +423,7 @@ void CFVMFlowSolverBase::SetPrimitive_Limiter(CGeometry* geometry, const C auto& primMax = nodes->GetSolution_Max(); auto& limiter = nodes->GetLimiter_Primitive(); - computeLimiters(kindLimiter, this, PRIMITIVE_LIMITER, PERIODIC_LIM_PRIM_1, PERIODIC_LIM_PRIM_2, *geometry, *config, 0, + computeLimiters(kindLimiter, this, MPI_QUANTITIES::PRIMITIVE_LIMITER, PERIODIC_LIM_PRIM_1, PERIODIC_LIM_PRIM_2, *geometry, *config, 0, nPrimVarGrad, primitives, gradient, primMin, primMax, limiter); } @@ -779,9 +779,9 @@ template void CFVMFlowSolverBase::SetUniformInlet(const CConfig* config, unsigned short iMarker) { if (config->GetMarker_All_KindBC(iMarker) == INLET_FLOW) { string Marker_Tag = config->GetMarker_All_TagBound(iMarker); - su2double p_total = config->GetInlet_Ptotal(Marker_Tag); - su2double t_total = config->GetInlet_Ttotal(Marker_Tag); - auto flow_dir = config->GetInlet_FlowDir(Marker_Tag); + su2double p_total = config->GetInletPtotal(Marker_Tag); + su2double t_total = config->GetInletTtotal(Marker_Tag); + auto flow_dir = config->GetInletFlowDir(Marker_Tag); for (unsigned long iVertex = 0; iVertex < nVertex[iMarker]; iVertex++) { Inlet_Ttotal[iMarker][iVertex] = t_total; @@ -800,6 +800,49 @@ void CFVMFlowSolverBase::SetUniformInlet(const CConfig* config, unsigned s } } +template +void CFVMFlowSolverBase::UpdateCustomBoundaryConditions( + CGeometry** geometry_container, CSolver*** solver_container, CConfig *config) { + struct { + const CSolver* fine_solver{nullptr}; + CSolver* coarse_solver{nullptr}; + unsigned short marker{0}; + unsigned short var{0}; + + su2double Get(unsigned long vertex) const { + if (var == 0) { + return fine_solver->GetInletTtotal(marker, vertex); + } else if (var == 1) { + return fine_solver->GetInletPtotal(marker, vertex); + } + return fine_solver->GetInletFlowDir(marker, vertex, var - 2); + } + + void Set(unsigned long vertex, const su2double& val) const { + if (var == 0) { + coarse_solver->SetInletTtotal(marker, vertex, val); + } else if (var == 1) { + coarse_solver->SetInletPtotal(marker, vertex, val); + } + coarse_solver->SetInletFlowDir(marker, vertex, var - 2, val); + } + } inlet_values; + + for (auto mg_coarse = 1u; mg_coarse <= config->GetnMGLevels(); ++mg_coarse) { + const auto mg_fine = mg_coarse - 1; + inlet_values.fine_solver = solver_container[mg_fine][FLOW_SOL]; + inlet_values.coarse_solver = solver_container[mg_coarse][FLOW_SOL]; + + for (auto marker = 0u; marker < config->GetnMarker_All(); ++marker) { + if (config->GetMarker_All_KindBC(marker) != INLET_FLOW) continue; + inlet_values.marker = marker; + for (inlet_values.var = 0; inlet_values.var < 2 + nDim; ++inlet_values.var) { + geometry_container[mg_coarse]->SetMultiGridMarkerQuantity(geometry_container[mg_fine], marker, inlet_values); + } + } + } +} + template void CFVMFlowSolverBase::LoadRestart_impl(CGeometry **geometry, CSolver ***solver, CConfig *config, int iter, bool update_geo, su2double* SolutionRestart, @@ -929,8 +972,8 @@ void CFVMFlowSolverBase::LoadRestart_impl(CGeometry **geometry, CSolver ** /*--- Compute the grid velocities on the coarser levels. ---*/ if (iMesh) geometry[iMesh]->SetRestricted_GridVelocity(geometry[iMesh - 1]); else { - geometry[MESH_0]->InitiateComms(geometry[MESH_0], config, GRID_VELOCITY); - geometry[MESH_0]->CompleteComms(geometry[MESH_0], config, GRID_VELOCITY); + geometry[MESH_0]->InitiateComms(geometry[MESH_0], config, MPI_QUANTITIES::GRID_VELOCITY); + geometry[MESH_0]->CompleteComms(geometry[MESH_0], config, MPI_QUANTITIES::GRID_VELOCITY); } } } @@ -941,8 +984,8 @@ void CFVMFlowSolverBase::LoadRestart_impl(CGeometry **geometry, CSolver ** on the fine level in order to have all necessary quantities updated, especially if this is a turbulent simulation (eddy viscosity). ---*/ - solver[MESH_0][FLOW_SOL]->InitiateComms(geometry[MESH_0], config, SOLUTION); - solver[MESH_0][FLOW_SOL]->CompleteComms(geometry[MESH_0], config, SOLUTION); + solver[MESH_0][FLOW_SOL]->InitiateComms(geometry[MESH_0], config, MPI_QUANTITIES::SOLUTION); + solver[MESH_0][FLOW_SOL]->CompleteComms(geometry[MESH_0], config, MPI_QUANTITIES::SOLUTION); /*--- For turbulent/species simulations the flow preprocessing is done by the turbulence/species solver * after it loads its variables (they are needed to compute flow primitives). In case turbulence and species, the @@ -957,8 +1000,8 @@ void CFVMFlowSolverBase::LoadRestart_impl(CGeometry **geometry, CSolver ** for (auto iMesh = 1u; iMesh <= config->GetnMGLevels(); iMesh++) { MultigridRestriction(*geometry[iMesh - 1], solver[iMesh - 1][FLOW_SOL]->GetNodes()->GetSolution(), *geometry[iMesh], solver[iMesh][FLOW_SOL]->GetNodes()->GetSolution()); - solver[iMesh][FLOW_SOL]->InitiateComms(geometry[iMesh], config, SOLUTION); - solver[iMesh][FLOW_SOL]->CompleteComms(geometry[iMesh], config, SOLUTION); + solver[iMesh][FLOW_SOL]->InitiateComms(geometry[iMesh], config, MPI_QUANTITIES::SOLUTION); + solver[iMesh][FLOW_SOL]->CompleteComms(geometry[iMesh], config, MPI_QUANTITIES::SOLUTION); if (config->GetKind_Turb_Model() == TURB_MODEL::NONE && config->GetKind_Species_Model() == SPECIES_MODEL::NONE) { diff --git a/SU2_CFD/include/solvers/CHeatSolver.hpp b/SU2_CFD/include/solvers/CHeatSolver.hpp index e82c96881d7..627983ec096 100644 --- a/SU2_CFD/include/solvers/CHeatSolver.hpp +++ b/SU2_CFD/include/solvers/CHeatSolver.hpp @@ -103,8 +103,8 @@ class CHeatSolver final : public CScalarSolver { * \param[in] config - Definition of the particular problem. * \note Calls a generic implementation after defining a SolverSpecificNumerics object. */ - inline void Viscous_Residual(unsigned long iEdge, CGeometry* geometry, CSolver** solver_container, - CNumerics* numerics, CConfig* config) override { + inline void Viscous_Residual(const unsigned long iEdge, const CGeometry* geometry, CSolver** solver_container, + CNumerics* numerics, const CConfig* config) override { const CVariable* flow_nodes = flow ? solver_container[FLOW_SOL]->GetNodes() : nullptr; const su2double const_diffusivity = config->GetThermalDiffusivity(); diff --git a/SU2_CFD/include/solvers/CScalarSolver.hpp b/SU2_CFD/include/solvers/CScalarSolver.hpp index ca84ea7c644..ca4ce3e2483 100644 --- a/SU2_CFD/include/solvers/CScalarSolver.hpp +++ b/SU2_CFD/include/solvers/CScalarSolver.hpp @@ -99,9 +99,9 @@ class CScalarSolver : public CSolver { * \param[in] config - Definition of the particular problem. */ template - FORCEINLINE void Viscous_Residual_impl(const SolverSpecificNumericsFunc& SolverSpecificNumerics, unsigned long iEdge, - CGeometry* geometry, CSolver** solver_container, CNumerics* numerics, - CConfig* config) { + FORCEINLINE void Viscous_Residual_impl(const SolverSpecificNumericsFunc& SolverSpecificNumerics, const unsigned long iEdge, + const CGeometry* geometry, CSolver** solver_container, CNumerics* numerics, + const CConfig* config) { const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); CFlowVariable* flowNodes = solver_container[FLOW_SOL] ? su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()) : nullptr; @@ -307,8 +307,8 @@ class CScalarSolver : public CSolver { * \param[in] config - Definition of the particular problem. * \note Calls a generic implementation after defining a SolverSpecificNumerics object. */ - inline virtual void Viscous_Residual(unsigned long iEdge, CGeometry* geometry, CSolver** solver_container, - CNumerics* numerics, CConfig* config) { + inline virtual void Viscous_Residual(const unsigned long iEdge, const CGeometry* geometry, CSolver** solver_container, + CNumerics* numerics, const CConfig* config) { /*--- Define an empty object for solver specific numerics contribution. In case there are none, this default *--- implementation will be called ---*/ auto SolverSpecificNumerics = [&](unsigned long iPoint, unsigned long jPoint) {}; diff --git a/SU2_CFD/include/solvers/CScalarSolver.inl b/SU2_CFD/include/solvers/CScalarSolver.inl index 6f9aeafac4a..1777fa2e289 100644 --- a/SU2_CFD/include/solvers/CScalarSolver.inl +++ b/SU2_CFD/include/solvers/CScalarSolver.inl @@ -531,8 +531,8 @@ void CScalarSolver::CompleteImplicitIteration(CGeometry* geometry, CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_IMPLICIT); } - InitiateComms(geometry, config, SOLUTION); - CompleteComms(geometry, config, SOLUTION); + InitiateComms(geometry, config, MPI_QUANTITIES::SOLUTION); + CompleteComms(geometry, config, MPI_QUANTITIES::SOLUTION); } template diff --git a/SU2_CFD/include/solvers/CSolver.hpp b/SU2_CFD/include/solvers/CSolver.hpp index 2b114a7714b..3c1062def94 100644 --- a/SU2_CFD/include/solvers/CSolver.hpp +++ b/SU2_CFD/include/solvers/CSolver.hpp @@ -240,7 +240,7 @@ class CSolver { * \param[out] MPI_TYPE - Enumerated type for the datatype of the quantity to be communicated. */ void GetCommCountAndType(const CConfig* config, - unsigned short commType, + MPI_QUANTITIES commType, unsigned short &COUNT_PER_POINT, unsigned short &MPI_TYPE) const; @@ -252,7 +252,7 @@ class CSolver { */ void InitiateComms(CGeometry *geometry, const CConfig *config, - unsigned short commType); + MPI_QUANTITIES commType); /*! * \brief Routine to complete the set of non-blocking communications launched by InitiateComms() and unpacking of the data in the solver class. @@ -262,7 +262,7 @@ class CSolver { */ void CompleteComms(CGeometry *geometry, const CConfig *config, - unsigned short commType); + MPI_QUANTITIES commType); /*! * \brief Helper function to define the type and number of variables per point for each communication type. @@ -2818,7 +2818,7 @@ class CSolver { * \param[in] val_vertex - Vertex of the marker val_marker where the total temperature is evaluated. * \return Value of the total temperature */ - inline virtual su2double GetInlet_Ttotal(unsigned short val_marker, unsigned long val_vertex) const { return 0; } + inline virtual su2double GetInletTtotal(unsigned short val_marker, unsigned long val_vertex) const { return 0; } /*! * \brief A virtual member @@ -2826,7 +2826,7 @@ class CSolver { * \param[in] val_vertex - Vertex of the marker val_marker where the total pressure is evaluated. * \return Value of the total pressure */ - inline virtual su2double GetInlet_Ptotal(unsigned short val_marker, unsigned long val_vertex) const { return 0; } + inline virtual su2double GetInletPtotal(unsigned short val_marker, unsigned long val_vertex) const { return 0; } /*! * \brief A virtual member @@ -2835,9 +2835,9 @@ class CSolver { * \param[in] val_dim - The component of the flow direction unit vector to be evaluated * \return Component of a unit vector representing the flow direction. */ - inline virtual su2double GetInlet_FlowDir(unsigned short val_marker, - unsigned long val_vertex, - unsigned short val_dim) const { return 0; } + inline virtual su2double GetInletFlowDir(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_dim) const { return 0; } /*! * \brief A virtual member @@ -2845,9 +2845,9 @@ class CSolver { * \param[in] val_vertex - Vertex of the marker val_marker where the total temperature is set. * \param[in] val_ttotal - Value of the total temperature */ - inline virtual void SetInlet_Ttotal(unsigned short val_marker, - unsigned long val_vertex, - su2double val_ttotal) { } + inline virtual void SetInletTtotal(unsigned short val_marker, + unsigned long val_vertex, + su2double val_ttotal) { } /*! * \brief A virtual member @@ -2855,7 +2855,7 @@ class CSolver { * \param[in] val_vertex - Vertex of the marker val_marker where the total pressure is set. * \param[in] val_ptotal - Value of the total pressure */ - inline virtual void SetInlet_Ptotal(unsigned short val_marker, + inline virtual void SetInletPtotal(unsigned short val_marker, unsigned long val_vertex, su2double val_ptotal) { } @@ -2866,10 +2866,10 @@ class CSolver { * \param[in] val_dim - The component of the flow direction unit vector to be set * \param[in] val_flowdir - Component of a unit vector representing the flow direction. */ - inline virtual void SetInlet_FlowDir(unsigned short val_marker, - unsigned long val_vertex, - unsigned short val_dim, - su2double val_flowdir) { } + inline virtual void SetInletFlowDir(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_dim, + su2double val_flowdir) { } /*! * \brief Updates the components of the farfield velocity vector. @@ -2922,11 +2922,14 @@ class CSolver { const CConfig *config) const { return 0; } /*! - * \brief Update the multi-grid structure for the customized boundary conditions + * \brief Update the multi-grid structure for the customized boundary conditions. * \param geometry_container - Geometrical definition. + * \param solver_container - Solver definition. * \param config - Definition of the particular problem. */ - inline virtual void UpdateCustomBoundaryConditions(CGeometry **geometry_container, CConfig *config) { } + inline virtual void UpdateCustomBoundaryConditions(CGeometry **geometry_container, + CSolver ***solver_container, + CConfig *config) { } /*! * \brief A virtual member. @@ -3799,6 +3802,13 @@ class CSolver { */ inline virtual su2double GetAverageDensity(unsigned short valMarker, unsigned short valSpan) const { return 0.0; } + /*! + * \brief virtual member + * \param[in] val_marker - boundary marker + * \return Value of the mass flow rate on the surface val_marker + */ + inline virtual su2double GetAverageMassFlowRate(unsigned short valMarker) const {return 0.0; } + /*! * \brief A virtual member. * \param[in] val_marker - bound marker. diff --git a/SU2_CFD/include/solvers/CSpeciesFlameletSolver.hpp b/SU2_CFD/include/solvers/CSpeciesFlameletSolver.hpp index e821e1d6a9e..1d1bd498230 100644 --- a/SU2_CFD/include/solvers/CSpeciesFlameletSolver.hpp +++ b/SU2_CFD/include/solvers/CSpeciesFlameletSolver.hpp @@ -37,7 +37,6 @@ */ class CSpeciesFlameletSolver final : public CSpeciesSolver { private: - vector conjugate_var; /*!< \brief CHT variables for each boundary and vertex. */ bool include_mixture_fraction = false; /*!< \brief include mixture fraction as a controlling variable. */ /*! * \brief Compute the preconditioner for low-Mach flows. @@ -63,8 +62,8 @@ class CSpeciesFlameletSolver final : public CSpeciesSolver { * \param[in] val_enth_out - pointer to output enthalpy variable. * \param[out] Converged - 0 if Newton solver converged, 1 if not. */ - unsigned long GetEnthFromTemp(CFluidModel* fluid_model, su2double const val_temp, - const su2double* scalar_solution, su2double* val_enth_out); + unsigned long GetEnthFromTemp(CFluidModel* fluid_model, su2double const val_temp, const su2double* scalar_solution, + su2double* val_enth_out); /*! * \brief Find maximum progress variable value within the manifold for the current solution. @@ -97,13 +96,23 @@ class CSpeciesFlameletSolver final : public CSpeciesSolver { unsigned long SetScalarLookUps(const CConfig* config, CFluidModel* fluid_model_local, unsigned long iPoint, const vector& scalars); + /*! + * \brief Retrieve the preferential diffusion scalar values from manifold. + * \param[in] config - definition of particular problem. + * \param[in] fluid_model_local - pointer to flamelet fluid model. + * \param[in] iPoint - node ID. + * \param[in] scalars - local scalar solution. + * \return - within manifold bounds (0) or outside manifold bounds (1). + */ + unsigned long SetPreferentialDiffusionScalars(const CConfig* config, CFluidModel* fluid_model_local, + unsigned long iPoint, const vector& scalars); + public: /*! - * \brief Constructor. + * \brief Define a Flamelet Generated Manifold species solver. * \param[in] geometry - Geometrical definition of the problem. * \param[in] config - Definition of the particular problem. * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] FluidModel */ CSpeciesFlameletSolver(CGeometry* geometry, CConfig* config, unsigned short iMesh); @@ -175,4 +184,16 @@ class CSpeciesFlameletSolver final : public CSpeciesSolver { */ void BC_ConjugateHeat_Interface(CGeometry* geometry, CSolver** solver_container, CNumerics* numerics, CConfig* config, unsigned short val_marker) override; + + /*! + * \brief Compute the fluxes due to viscous and preferential diffusion effects of the flamelet species at a particular edge. + * \param[in] iEdge - Edge for which we want to compute the flux + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \note Calls a generic implementation after defining a SolverSpecificNumerics object. + */ + void Viscous_Residual(const unsigned long iEdge, const CGeometry* geometry, CSolver** solver_container, CNumerics* numerics, + const CConfig* config) final; }; diff --git a/SU2_CFD/include/solvers/CSpeciesSolver.hpp b/SU2_CFD/include/solvers/CSpeciesSolver.hpp index 1ee78d90286..4fbb9419117 100644 --- a/SU2_CFD/include/solvers/CSpeciesSolver.hpp +++ b/SU2_CFD/include/solvers/CSpeciesSolver.hpp @@ -89,8 +89,8 @@ class CSpeciesSolver : public CScalarSolver { * \param[in] config - Definition of the particular problem. * \note Calls a generic implementation after defining a SolverSpecificNumerics object. */ - void Viscous_Residual(unsigned long iEdge, CGeometry* geometry, CSolver** solver_container, CNumerics* numerics, - CConfig* config) final; + void Viscous_Residual(const unsigned long iEdge, const CGeometry* geometry, CSolver** solver_container, CNumerics* numerics, + const CConfig* config) override; /*! * \brief Impose the inlet boundary condition. diff --git a/SU2_CFD/include/solvers/CTransLMSolver.hpp b/SU2_CFD/include/solvers/CTransLMSolver.hpp index 220f2b01ed7..98595abb266 100644 --- a/SU2_CFD/include/solvers/CTransLMSolver.hpp +++ b/SU2_CFD/include/solvers/CTransLMSolver.hpp @@ -98,8 +98,8 @@ class CTransLMSolver final : public CTurbSolver { * \param[in] config - Definition of the particular problem. * \note Calls a generic implementation after defining a SolverSpecificNumerics object. */ - void Viscous_Residual(unsigned long iEdge, CGeometry* geometry, CSolver** solver_container, - CNumerics* numerics, CConfig* config) override; + void Viscous_Residual(const unsigned long iEdge, const CGeometry* geometry, CSolver** solver_container, + CNumerics* numerics, const CConfig* config) override; /*! * \brief Source term computation. diff --git a/SU2_CFD/include/solvers/CTurbSASolver.hpp b/SU2_CFD/include/solvers/CTurbSASolver.hpp index cb0307817e7..c79649799cc 100644 --- a/SU2_CFD/include/solvers/CTurbSASolver.hpp +++ b/SU2_CFD/include/solvers/CTurbSASolver.hpp @@ -125,8 +125,8 @@ class CTurbSASolver final : public CTurbSolver { * \param[in] config - Definition of the particular problem. * \note Calls a generic implementation after defining a SolverSpecificNumerics object. */ - void Viscous_Residual(unsigned long iEdge, CGeometry* geometry, CSolver** solver_container, - CNumerics* numerics, CConfig* config) override; + void Viscous_Residual(const unsigned long iEdge, const CGeometry* geometry, CSolver** solver_container, + CNumerics* numerics, const CConfig* config) override; /*! * \brief Source term computation. diff --git a/SU2_CFD/include/solvers/CTurbSSTSolver.hpp b/SU2_CFD/include/solvers/CTurbSSTSolver.hpp index f4cf89d38d0..bdb4227a191 100644 --- a/SU2_CFD/include/solvers/CTurbSSTSolver.hpp +++ b/SU2_CFD/include/solvers/CTurbSSTSolver.hpp @@ -107,8 +107,8 @@ class CTurbSSTSolver final : public CTurbSolver { * \param[in] config - Definition of the particular problem. * \note Calls a generic implementation after defining a SolverSpecificNumerics object. */ - void Viscous_Residual(unsigned long iEdge, CGeometry* geometry, CSolver** solver_container, - CNumerics* numerics, CConfig* config) override; + void Viscous_Residual(const unsigned long iEdge, const CGeometry* geometry, CSolver** solver_container, + CNumerics* numerics, const CConfig* config) override; /*! * \brief Source term computation. diff --git a/SU2_CFD/src/CMarkerProfileReaderFVM.cpp b/SU2_CFD/src/CMarkerProfileReaderFVM.cpp index b9b27a176aa..b6b1e36479f 100644 --- a/SU2_CFD/src/CMarkerProfileReaderFVM.cpp +++ b/SU2_CFD/src/CMarkerProfileReaderFVM.cpp @@ -302,6 +302,10 @@ void CMarkerProfileReaderFVM::MergeProfileMarkers() { by the master and sorted by marker tag in one large n-dim. array. ---*/ su2double *Coords_Local; jPoint = 0; + + /*--- Index to the string in columNames and columnValues ---*/ + unsigned short columnIndex=0; + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { if (config->GetMarker_All_KindBC(iMarker) == markerType) { @@ -338,12 +342,12 @@ void CMarkerProfileReaderFVM::MergeProfileMarkers() { /*--- Store the column names ---*/ SPRINTF(&Buffer_Send_Name[jPoint*MAX_STRING_SIZE], "%s", - columnNames[iMarker].c_str()); + columnNames[columnIndex].c_str()); /*--- Store the column values ---*/ SPRINTF(&Buffer_Send_Value[jPoint*MAX_STRING_SIZE], "%s", - columnValues[iMarker].c_str()); + columnValues[columnIndex].c_str()); /*--- Increment jPoint as the counter. We need this because iPoint may include halo nodes that we skip over during this loop. ---*/ @@ -352,6 +356,7 @@ void CMarkerProfileReaderFVM::MergeProfileMarkers() { } } + columnIndex++; } } diff --git a/SU2_CFD/src/drivers/CDiscAdjMultizoneDriver.cpp b/SU2_CFD/src/drivers/CDiscAdjMultizoneDriver.cpp index fd70eaf1a4f..14d84721fd7 100644 --- a/SU2_CFD/src/drivers/CDiscAdjMultizoneDriver.cpp +++ b/SU2_CFD/src/drivers/CDiscAdjMultizoneDriver.cpp @@ -670,19 +670,7 @@ void CDiscAdjMultizoneDriver::SetRecording(RECORDING kind_recording, Kind_Tape t } if (kind_recording != RECORDING::CLEAR_INDICES && driver_config->GetWrt_AD_Statistics()) { - if (rank == MASTER_NODE) AD::PrintStatistics(); -#ifdef CODI_REVERSE_TYPE - if (size > SINGLE_NODE) { - su2double myMem = AD::getTape().getTapeValues().getUsedMemorySize(), totMem = 0.0; - SU2_MPI::Allreduce(&myMem, &totMem, 1, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); - if (rank == MASTER_NODE) { - cout << "MPI\n"; - cout << "-------------------------------------\n"; - cout << " Total memory used : " << totMem << " MB\n"; - cout << "-------------------------------------\n" << endl; - } - } -#endif + AD::PrintStatistics(SU2_MPI::GetComm(), rank == MASTER_NODE); } AD::StopRecording(); diff --git a/SU2_CFD/src/drivers/CDiscAdjSinglezoneDriver.cpp b/SU2_CFD/src/drivers/CDiscAdjSinglezoneDriver.cpp index 693388784a7..c0b2d7c94b3 100644 --- a/SU2_CFD/src/drivers/CDiscAdjSinglezoneDriver.cpp +++ b/SU2_CFD/src/drivers/CDiscAdjSinglezoneDriver.cpp @@ -305,19 +305,7 @@ void CDiscAdjSinglezoneDriver::SetRecording(RECORDING kind_recording){ SetObjFunction(); if (kind_recording != RECORDING::CLEAR_INDICES && config_container[ZONE_0]->GetWrt_AD_Statistics()) { - if (rank == MASTER_NODE) AD::PrintStatistics(); -#ifdef CODI_REVERSE_TYPE - if (size > SINGLE_NODE) { - su2double myMem = AD::getTape().getTapeValues().getUsedMemorySize(), totMem = 0.0; - SU2_MPI::Allreduce(&myMem, &totMem, 1, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); - if (rank == MASTER_NODE) { - cout << "MPI\n"; - cout << "-------------------------------------\n"; - cout << " Total memory used : " << totMem << " MB\n"; - cout << "-------------------------------------\n" << endl; - } - } -#endif + AD::PrintStatistics(SU2_MPI::GetComm(), rank == MASTER_NODE); } AD::StopRecording(); diff --git a/SU2_CFD/src/drivers/CDriver.cpp b/SU2_CFD/src/drivers/CDriver.cpp index 7160cc93e6f..645e79ff47b 100644 --- a/SU2_CFD/src/drivers/CDriver.cpp +++ b/SU2_CFD/src/drivers/CDriver.cpp @@ -912,8 +912,8 @@ void CDriver::InitializeGeometryFVM(CConfig *config, CGeometry **&geometry) { if ((rank == MASTER_NODE) && (size > SINGLE_NODE) && (iMGlevel == MESH_0)) cout << "Communicating number of neighbors." << endl; - geometry[iMGlevel]->InitiateComms(geometry[iMGlevel], config, NEIGHBORS); - geometry[iMGlevel]->CompleteComms(geometry[iMGlevel], config, NEIGHBORS); + geometry[iMGlevel]->InitiateComms(geometry[iMGlevel], config, MPI_QUANTITIES::NEIGHBORS); + geometry[iMGlevel]->CompleteComms(geometry[iMGlevel], config, MPI_QUANTITIES::NEIGHBORS); } } @@ -2389,7 +2389,9 @@ void CDriver::PreprocessDynamicMesh(CConfig *config, CGeometry **geometry, CSolv cout << "Setting dynamic mesh structure for zone "<< iZone + 1<<"." << endl; grid_movement = new CVolumetricMovement(geometry[MESH_0], config); - surface_movement = new CSurfaceMovement(); + if (surface_movement == nullptr) + surface_movement = new CSurfaceMovement(); + surface_movement->CopyBoundary(geometry[MESH_0], config); if (config->GetTime_Marching() == TIME_MARCHING::HARMONIC_BALANCE){ if (rank == MASTER_NODE) cout << endl << "Instance "<< iInst + 1 <<":" << endl; @@ -2488,14 +2490,23 @@ void CDriver::InitializeInterface(CConfig **config, CSolver***** solver, CGeomet if (rank == MASTER_NODE) cout << "boundary displacements from the structural solver." << endl; } else if (fluid_donor && fluid_target) { - /*--- Mixing plane for turbo machinery applications. ---*/ - if (config[donor]->GetBoolMixingPlaneInterface()) { - interface_type = MIXING_PLANE; - auto nVar = solver[donor][INST_0][MESH_0][FLOW_SOL]->GetnVar(); - interface[donor][target] = new CMixingPlaneInterface(nVar, 0); - if (rank == MASTER_NODE) { - cout << "Set mixing-plane interface from donor zone " - << donor << " to target zone " << target << "." << endl; + /*--- Interface handling for turbomachinery applications. ---*/ + if (config[donor]->GetBoolTurbomachinery()) { + auto interfaceIndex = donor+target; // Here we assume that the interfaces at each side are the same kind + switch (config[donor]->GetKind_TurboInterface(interfaceIndex)) { + case TURBO_INTERFACE_KIND::MIXING_PLANE: { + interface_type = MIXING_PLANE; + auto nVar = solver[donor][INST_0][MESH_0][FLOW_SOL]->GetnVar(); + interface[donor][target] = new CMixingPlaneInterface(nVar, 0); + if (rank == MASTER_NODE) cout << "using a mixing-plane interface from donor zone " << donor << " to target zone " << target << "." << endl; + break; + } + case TURBO_INTERFACE_KIND::FROZEN_ROTOR: { + auto nVar = solver[donor][INST_0][MESH_0][FLOW_SOL]->GetnPrimVar(); + interface_type = SLIDING_INTERFACE; + interface[donor][target] = new CSlidingInterface(nVar, 0); + if (rank == MASTER_NODE) cout << "using a fluid interface interface from donor zone " << donor << " to target zone " << target << "." << endl; + } } } else{ @@ -2506,19 +2517,21 @@ void CDriver::InitializeInterface(CConfig **config, CSolver***** solver, CGeomet } } else if (heat_donor || heat_target) { - if (heat_donor && heat_target) - SU2_MPI::Error("Conjugate heat transfer between solids is not implemented.", CURRENT_FUNCTION); - - const auto fluidZone = heat_target? donor : target; + if (heat_donor && heat_target){ + interface_type = CONJUGATE_HEAT_SS; - if (config[fluidZone]->GetEnergy_Equation() || (config[fluidZone]->GetKind_Regime() == ENUM_REGIME::COMPRESSIBLE) - || (config[fluidZone]->GetKind_FluidModel() == ENUM_FLUIDMODEL::FLUID_FLAMELET)) - interface_type = heat_target? CONJUGATE_HEAT_FS : CONJUGATE_HEAT_SF; - else if (config[fluidZone]->GetWeakly_Coupled_Heat()) - interface_type = heat_target? CONJUGATE_HEAT_WEAKLY_FS : CONJUGATE_HEAT_WEAKLY_SF; - else - interface_type = NO_TRANSFER; + } else { + const auto fluidZone = heat_target? donor : target; + if (config[fluidZone]->GetEnergy_Equation() || (config[fluidZone]->GetKind_Regime() == ENUM_REGIME::COMPRESSIBLE) + || (config[fluidZone]->GetKind_FluidModel() == ENUM_FLUIDMODEL::FLUID_FLAMELET)) + interface_type = heat_target? CONJUGATE_HEAT_FS : CONJUGATE_HEAT_SF; + else if (config[fluidZone]->GetWeakly_Coupled_Heat()) + interface_type = heat_target? CONJUGATE_HEAT_WEAKLY_FS : CONJUGATE_HEAT_WEAKLY_SF; + else + interface_type = NO_TRANSFER; + } + if (interface_type != NO_TRANSFER) { auto nVar = 4; interface[donor][target] = new CConjugateHeatInterface(nVar, 0); @@ -2691,7 +2704,7 @@ void CDriver::PreprocessTurbomachinery(CConfig** config, CGeometry**** geometry, } } - for (iZone = 0; iZone < nZone-1; iZone++) { + for (iZone = 0; iZone < nZone-1; iZone++) { geometry[nZone-1][INST_0][MESH_0]->SetAvgTurboGeoValues(config[iZone],geometry[iZone][INST_0][MESH_0], iZone); } diff --git a/SU2_CFD/src/drivers/CDriverBase.cpp b/SU2_CFD/src/drivers/CDriverBase.cpp index c964677e623..602e89e3ace 100644 --- a/SU2_CFD/src/drivers/CDriverBase.cpp +++ b/SU2_CFD/src/drivers/CDriverBase.cpp @@ -391,8 +391,8 @@ vector CDriverBase::GetMarkerVertexNormals(unsigned short iMarker } void CDriverBase::CommunicateMeshDisplacements() { - solver_container[selected_zone][INST_0][MESH_0][MESH_SOL]->InitiateComms(main_geometry, main_config, MESH_DISPLACEMENTS); - solver_container[selected_zone][INST_0][MESH_0][MESH_SOL]->CompleteComms(main_geometry, main_config, MESH_DISPLACEMENTS); + solver_container[selected_zone][INST_0][MESH_0][MESH_SOL]->InitiateComms(main_geometry, main_config, MPI_QUANTITIES::MESH_DISPLACEMENTS); + solver_container[selected_zone][INST_0][MESH_0][MESH_SOL]->CompleteComms(main_geometry, main_config, MPI_QUANTITIES::MESH_DISPLACEMENTS); } map CDriverBase::GetSolverIndices() const { diff --git a/SU2_CFD/src/drivers/CMultizoneDriver.cpp b/SU2_CFD/src/drivers/CMultizoneDriver.cpp index 641307e7a19..07069b4d0ab 100644 --- a/SU2_CFD/src/drivers/CMultizoneDriver.cpp +++ b/SU2_CFD/src/drivers/CMultizoneDriver.cpp @@ -563,6 +563,9 @@ bool CMultizoneDriver::TransferData(unsigned short donorZone, unsigned short tar BroadcastData(SPECIES_SOL, SPECIES_SOL); } break; + case CONJUGATE_HEAT_SS: + BroadcastData(HEAT_SOL, HEAT_SOL); + break; case CONJUGATE_HEAT_FS: BroadcastData(FLOW_SOL, HEAT_SOL); break; diff --git a/SU2_CFD/src/fluid/CDataDrivenFluid.cpp b/SU2_CFD/src/fluid/CDataDrivenFluid.cpp index fd11176eeba..09f187f2d1d 100644 --- a/SU2_CFD/src/fluid/CDataDrivenFluid.cpp +++ b/SU2_CFD/src/fluid/CDataDrivenFluid.cpp @@ -118,6 +118,21 @@ void CDataDrivenFluid::MapInputs_to_Outputs() { lookup_mlp->PairVariableswithMLPs(*iomap_rhoe); MLP_inputs.resize(2); #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_lookup_indices.push_back(LUT_idx_s); + LUT_lookup_indices.push_back(LUT_idx_dsde_rho); + LUT_lookup_indices.push_back(LUT_idx_dsdrho_e); + LUT_lookup_indices.push_back(LUT_idx_d2sde2); + LUT_lookup_indices.push_back(LUT_idx_d2sdedrho); + LUT_lookup_indices.push_back(LUT_idx_d2sdrho2); } } @@ -233,21 +248,10 @@ unsigned long CDataDrivenFluid::Predict_MLP(su2double rho, su2double e) { } unsigned long CDataDrivenFluid::Predict_LUT(su2double rho, su2double e) { - unsigned long exit_code; - std::vector output_names_rhoe_LUT; - std::vector outputs_LUT; - output_names_rhoe_LUT.resize(output_names_rhoe.size()); - for (auto iOutput = 0u; iOutput < output_names_rhoe.size(); iOutput++) { - output_names_rhoe_LUT[iOutput] = output_names_rhoe[iOutput]; - } - - outputs_LUT.resize(outputs_rhoe.size()); - for (auto iOutput = 0u; iOutput < outputs_rhoe.size(); iOutput++) { - outputs_LUT[iOutput] = outputs_rhoe[iOutput]; - } - - exit_code = lookup_table->LookUp_XY(output_names_rhoe_LUT, outputs_LUT, rho, e); - return exit_code; + bool inside = lookup_table->LookUp_XY(LUT_lookup_indices, outputs_rhoe, rho, e); + if (inside) + return 0; + return 1; } void CDataDrivenFluid::Evaluate_Dataset(su2double rho, su2double e) { diff --git a/SU2_CFD/src/fluid/CFluidFlamelet.cpp b/SU2_CFD/src/fluid/CFluidFlamelet.cpp index 569c4ae6a2a..18dbcd2a43a 100644 --- a/SU2_CFD/src/fluid/CFluidFlamelet.cpp +++ b/SU2_CFD/src/fluid/CFluidFlamelet.cpp @@ -25,6 +25,8 @@ * License along with SU2. If not, see . */ +#include +#include #include "../include/fluid/CFluidFlamelet.hpp" #include "../../../Common/include/containers/CLookUpTable.hpp" #if defined(HAVE_MLPCPP) @@ -47,14 +49,13 @@ CFluidFlamelet::CFluidFlamelet(CConfig* config, su2double value_pressure_operati cout << "Number of user scalars: " << n_user_scalars << endl; cout << "Number of control variables: " << n_control_vars << endl; } - scalars_vector.resize(n_scalars); table_scalar_names.resize(n_scalars); for (auto iCV = 0u; iCV < n_control_vars; iCV++) table_scalar_names[iCV] = config->GetControllingVariableName(iCV); /*--- auxiliary species transport equations---*/ - for (size_t i_aux = 0; i_aux < n_user_scalars; i_aux++) { + for (auto i_aux = 0u; i_aux < n_user_scalars; i_aux++) { table_scalar_names[n_control_vars + i_aux] = config->GetUserScalarName(i_aux); } @@ -93,31 +94,31 @@ CFluidFlamelet::CFluidFlamelet(CConfig* config, su2double value_pressure_operati Pressure = value_pressure_operating; PreprocessLookUp(config); + + if (rank == MASTER_NODE) { + cout << "Preferential diffusion: " << (preferential_diffusion ? "Enabled" : "Disabled") << endl; + } } CFluidFlamelet::~CFluidFlamelet() { - switch (Kind_DataDriven_Method) { - case ENUM_DATADRIVEN_METHOD::LUT: - delete look_up_table; - break; - case ENUM_DATADRIVEN_METHOD::MLP: + if (Kind_DataDriven_Method == ENUM_DATADRIVEN_METHOD::LUT) + delete look_up_table; #ifdef USE_MLPCPP - delete iomap_TD; - delete iomap_Sources; - delete iomap_LookUp; - delete lookup_mlp; + if (Kind_DataDriven_Method == ENUM_DATADRIVEN_METHOD::MLP) { + delete iomap_TD; + delete iomap_Sources; + delete iomap_LookUp; + delete lookup_mlp; + if (preferential_diffusion) delete iomap_PD; + } #endif - break; - default: - break; - } } void CFluidFlamelet::SetTDState_T(su2double val_temperature, const su2double* val_scalars) { for (auto iVar = 0u; iVar < n_scalars; iVar++) scalars_vector[iVar] = val_scalars[iVar]; /*--- Add all quantities and their names to the look up vectors. ---*/ - EvaluateDataSet(scalars_vector, FLAMELET_LOOKUP_OPS::TD, val_vars_TD); + EvaluateDataSet(scalars_vector, FLAMELET_LOOKUP_OPS::THERMO, val_vars_TD); Temperature = val_vars_TD[LOOKUP_TD::TEMPERATURE]; Cp = val_vars_TD[LOOKUP_TD::HEATCAPACITY]; @@ -183,9 +184,51 @@ void CFluidFlamelet::PreprocessLookUp(CConfig* config) { /*--- Passive look-up terms ---*/ size_t n_lookups = config->GetNLookups(); - varnames_LookUp.resize(n_lookups); - val_vars_LookUp.resize(n_lookups); - for (auto iLookup = 0u; iLookup < n_lookups; iLookup++) varnames_LookUp[iLookup] = config->GetLookupName(iLookup); + if (n_lookups == 0) { + varnames_LookUp.resize(1); + val_vars_LookUp.resize(1); + varnames_LookUp[0] = "NULL"; + } else { + varnames_LookUp.resize(n_lookups); + val_vars_LookUp.resize(n_lookups); + for (auto iLookup = 0u; iLookup < n_lookups; iLookup++) varnames_LookUp[iLookup] = config->GetLookupName(iLookup); + } + + /*--- Preferential diffusion scalars ---*/ + varnames_PD.resize(FLAMELET_PREF_DIFF_SCALARS::N_BETA_TERMS); + val_vars_PD.resize(FLAMELET_PREF_DIFF_SCALARS::N_BETA_TERMS); + + varnames_PD[FLAMELET_PREF_DIFF_SCALARS::I_BETA_PROGVAR] = "Beta_ProgVar"; + varnames_PD[FLAMELET_PREF_DIFF_SCALARS::I_BETA_ENTH_THERMAL] = "Beta_Enth_Thermal"; + varnames_PD[FLAMELET_PREF_DIFF_SCALARS::I_BETA_ENTH] = "Beta_Enth"; + varnames_PD[FLAMELET_PREF_DIFF_SCALARS::I_BETA_MIXFRAC] = "Beta_MixFrac"; + + val_vars_PD[FLAMELET_PREF_DIFF_SCALARS::I_BETA_PROGVAR] = beta_progvar; + val_vars_PD[FLAMELET_PREF_DIFF_SCALARS::I_BETA_ENTH_THERMAL] = beta_enth_thermal; + val_vars_PD[FLAMELET_PREF_DIFF_SCALARS::I_BETA_ENTH] = beta_enth; + val_vars_PD[FLAMELET_PREF_DIFF_SCALARS::I_BETA_MIXFRAC] = beta_mixfrac; + + preferential_diffusion = config->GetPreferentialDiffusion(); + switch (Kind_DataDriven_Method) { + case ENUM_DATADRIVEN_METHOD::LUT: + preferential_diffusion = look_up_table->CheckForVariables(varnames_PD); + break; + case ENUM_DATADRIVEN_METHOD::MLP: +#ifdef USE_MLPCPP + n_betas = 0; + for (auto iMLP = 0u; iMLP < config->GetNDataDriven_Files(); 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 && config->GetPreferentialDiffusion()) + SU2_MPI::Error("Preferential diffusion scalars not included in flamelet manifold.", CURRENT_FUNCTION); if (Kind_DataDriven_Method == ENUM_DATADRIVEN_METHOD::MLP) { #ifdef USE_MLPCPP @@ -195,33 +238,72 @@ void CFluidFlamelet::PreprocessLookUp(CConfig* config) { lookup_mlp->PairVariableswithMLPs(*iomap_TD); lookup_mlp->PairVariableswithMLPs(*iomap_Sources); lookup_mlp->PairVariableswithMLPs(*iomap_LookUp); + if (preferential_diffusion) { + iomap_PD = new MLPToolbox::CIOMap(controlling_variable_names, varnames_PD); + lookup_mlp->PairVariableswithMLPs(*iomap_PD); + } #endif + } else { + for (auto iVar=0u; iVar < varnames_TD.size(); iVar++) { + LUT_idx_TD.push_back(look_up_table->GetIndexOfVar(varnames_TD[iVar])); + } + for (auto iVar=0u; iVar < varnames_Sources.size(); iVar++) { + unsigned long LUT_idx; + if (noSource(varnames_Sources[iVar])) { + LUT_idx = look_up_table->GetNullIndex(); + } else { + LUT_idx = look_up_table->GetIndexOfVar(varnames_Sources[iVar]); + } + LUT_idx_Sources.push_back(LUT_idx); + } + for (auto iVar=0u; iVar < varnames_LookUp.size(); iVar++) { + unsigned long LUT_idx; + if (noSource(varnames_LookUp[iVar])) + LUT_idx = look_up_table->GetNullIndex(); + else + LUT_idx = look_up_table->GetIndexOfVar(varnames_LookUp[iVar]); + LUT_idx_LookUp.push_back(LUT_idx); + } + if (preferential_diffusion) { + for (auto iVar=0u; iVar < varnames_PD.size(); iVar++) { + LUT_idx_PD.push_back(look_up_table->GetIndexOfVar(varnames_PD[iVar])); + } + } } } unsigned long CFluidFlamelet::EvaluateDataSet(const vector& input_scalar, unsigned short lookup_type, vector& output_refs) { + AD::StartPreacc(); + for (auto iVar = 0u; iVar < input_scalar.size(); iVar++) AD::SetPreaccIn(input_scalar[iVar]); + su2double val_enth = input_scalar[I_ENTH]; su2double val_prog = input_scalar[I_PROGVAR]; su2double val_mixfrac = include_mixture_fraction ? input_scalar[I_MIXFRAC] : 0.0; - vector varnames; vector val_vars; vector refs_vars; + vector LUT_idx; switch (lookup_type) { - case FLAMELET_LOOKUP_OPS::TD: - varnames = varnames_TD; + case FLAMELET_LOOKUP_OPS::THERMO: + LUT_idx = LUT_idx_TD; #ifdef USE_MLPCPP iomap_Current = iomap_TD; +#endif + break; + case FLAMELET_LOOKUP_OPS::PREFDIF: + LUT_idx = LUT_idx_PD; +#ifdef USE_MLPCPP + iomap_Current = iomap_PD; #endif break; case FLAMELET_LOOKUP_OPS::SOURCES: - varnames = varnames_Sources; + LUT_idx = LUT_idx_Sources; #ifdef USE_MLPCPP iomap_Current = iomap_Sources; #endif break; case FLAMELET_LOOKUP_OPS::LOOKUP: - varnames = varnames_LookUp; + LUT_idx = LUT_idx_LookUp; #ifdef USE_MLPCPP iomap_Current = iomap_LookUp; #endif @@ -229,17 +311,21 @@ unsigned long CFluidFlamelet::EvaluateDataSet(const vector& input_sca default: break; } - if (output_refs.size() != varnames.size()) - SU2_MPI::Error(string("Output vector size incompatible with manifold lookup operation."), CURRENT_FUNCTION); + /*--- Add all quantities and their names to the look up vectors. ---*/ + bool inside; switch (Kind_DataDriven_Method) { case ENUM_DATADRIVEN_METHOD::LUT: + if (output_refs.size() != LUT_idx.size()) + SU2_MPI::Error(string("Output vector size incompatible with manifold lookup operation."), CURRENT_FUNCTION); if (include_mixture_fraction) { - extrapolation = look_up_table->LookUp_XYZ(varnames, output_refs, val_prog, val_enth, val_mixfrac); + inside = look_up_table->LookUp_XYZ(LUT_idx, output_refs, val_prog, val_enth, val_mixfrac); } else { - extrapolation = look_up_table->LookUp_XY(varnames, output_refs, val_prog, val_enth); + 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()); @@ -251,6 +337,7 @@ unsigned long CFluidFlamelet::EvaluateDataSet(const vector& input_sca default: break; } - + 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/CIntegration.cpp b/SU2_CFD/src/integration/CIntegration.cpp index 87e34cd1c8a..f53d50639cc 100644 --- a/SU2_CFD/src/integration/CIntegration.cpp +++ b/SU2_CFD/src/integration/CIntegration.cpp @@ -171,14 +171,13 @@ void CIntegration::Space_Integration(CGeometry *geometry, break; case CHT_WALL_INTERFACE: - if ( MainSolver == FLOW_SOL && (config->GetKind_FluidModel() == FLUID_FLAMELET) ){ - solver_container[MainSolver]->BC_Isothermal_Wall(geometry, solver_container, conv_bound_numerics, visc_bound_numerics, config, iMarker); - break; - } - if ((MainSolver == SPECIES_SOL) || (MainSolver == HEAT_SOL) || ((MainSolver == FLOW_SOL) && ((config->GetKind_Regime() == ENUM_REGIME::COMPRESSIBLE) || config->GetEnergy_Equation()))) { - solver_container[MainSolver]->BC_ConjugateHeat_Interface(geometry, solver_container, conv_bound_numerics, config, iMarker); - } - else { + if ((MainSolver == FLOW_SOL && (config->GetKind_FluidModel() == FLUID_FLAMELET)) || + (MainSolver == SPECIES_SOL) || (MainSolver == HEAT_SOL) || + ((MainSolver == FLOW_SOL) && + ((config->GetKind_Regime() == ENUM_REGIME::COMPRESSIBLE) || config->GetEnergy_Equation()))) { + solver_container[MainSolver]->BC_ConjugateHeat_Interface(geometry, solver_container, conv_bound_numerics, + config, iMarker); + } else { solver_container[MainSolver]->BC_HeatFlux_Wall(geometry, solver_container, conv_bound_numerics, visc_bound_numerics, config, iMarker); } break; diff --git a/SU2_CFD/src/integration/CMultiGridIntegration.cpp b/SU2_CFD/src/integration/CMultiGridIntegration.cpp index a6750435d97..f8a7c1a9645 100644 --- a/SU2_CFD/src/integration/CMultiGridIntegration.cpp +++ b/SU2_CFD/src/integration/CMultiGridIntegration.cpp @@ -366,8 +366,8 @@ void CMultiGridIntegration::GetProlongated_Correction(unsigned short RunTime_EqS /*--- MPI the set solution old ---*/ - sol_coarse->InitiateComms(geo_coarse, config, SOLUTION_OLD); - sol_coarse->CompleteComms(geo_coarse, config, SOLUTION_OLD); + sol_coarse->InitiateComms(geo_coarse, config, MPI_QUANTITIES::SOLUTION_OLD); + 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++) { @@ -479,8 +479,8 @@ void CMultiGridIntegration::SetProlongated_Correction(CSolver *sol_fine, CGeomet /*--- MPI the new interpolated solution ---*/ - sol_fine->InitiateComms(geo_fine, config, SOLUTION); - sol_fine->CompleteComms(geo_fine, config, SOLUTION); + sol_fine->InitiateComms(geo_fine, config, MPI_QUANTITIES::SOLUTION); + sol_fine->CompleteComms(geo_fine, config, MPI_QUANTITIES::SOLUTION); } @@ -608,8 +608,8 @@ void CMultiGridIntegration::SetRestricted_Solution(unsigned short RunTime_EqSyst /*--- MPI the new interpolated solution ---*/ - sol_coarse->InitiateComms(geo_coarse, config, SOLUTION); - sol_coarse->CompleteComms(geo_coarse, config, SOLUTION); + sol_coarse->InitiateComms(geo_coarse, config, MPI_QUANTITIES::SOLUTION); + sol_coarse->CompleteComms(geo_coarse, config, MPI_QUANTITIES::SOLUTION); } diff --git a/SU2_CFD/src/integration/CSingleGridIntegration.cpp b/SU2_CFD/src/integration/CSingleGridIntegration.cpp index 56b74282cde..de70accb876 100644 --- a/SU2_CFD/src/integration/CSingleGridIntegration.cpp +++ b/SU2_CFD/src/integration/CSingleGridIntegration.cpp @@ -111,8 +111,8 @@ void CSingleGridIntegration::SetRestricted_Solution(unsigned short RunTime_EqSys CGeometry *geo_fine, CGeometry *geo_coarse, CConfig *config) { CSolver::MultigridRestriction(*geo_fine, sol_fine->GetNodes()->GetSolution(), *geo_coarse, sol_coarse->GetNodes()->GetSolution()); - sol_coarse->InitiateComms(geo_coarse, config, SOLUTION); - sol_coarse->CompleteComms(geo_coarse, config, SOLUTION); + sol_coarse->InitiateComms(geo_coarse, config, MPI_QUANTITIES::SOLUTION); + sol_coarse->CompleteComms(geo_coarse, config, MPI_QUANTITIES::SOLUTION); } void CSingleGridIntegration::SetRestricted_EddyVisc(unsigned short RunTime_EqSystem, CSolver *sol_fine, CSolver *sol_coarse, @@ -160,7 +160,7 @@ void CSingleGridIntegration::SetRestricted_EddyVisc(unsigned short RunTime_EqSys /*--- MPI the new interpolated solution (this also includes the eddy viscosity) ---*/ - sol_coarse->InitiateComms(geo_coarse, config, SOLUTION_EDDY); - sol_coarse->CompleteComms(geo_coarse, config, SOLUTION_EDDY); + sol_coarse->InitiateComms(geo_coarse, config, MPI_QUANTITIES::SOLUTION_EDDY); + sol_coarse->CompleteComms(geo_coarse, config, MPI_QUANTITIES::SOLUTION_EDDY); } diff --git a/SU2_CFD/src/interfaces/CInterface.cpp b/SU2_CFD/src/interfaces/CInterface.cpp index 050c948bc1f..bad7c06dae1 100644 --- a/SU2_CFD/src/interfaces/CInterface.cpp +++ b/SU2_CFD/src/interfaces/CInterface.cpp @@ -108,6 +108,11 @@ void CInterface::BroadcastData(const CInterpolator& interpolator, su2activematrix sendDonorVar(nLocalVertexDonor, nVar); 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++) { const auto iPoint = donor_geometry->vertex[markDonor][iVertex]->GetNode(); @@ -248,7 +253,7 @@ void CInterface::PreprocessAverage(CGeometry *donor_geometry, CGeometry *target_ Donor_Flag= -1; for (int iSize=0; iSize 0.0){ + if(BuffMarkerDonor[iSize] >= 0.0){ Marker_Donor = BuffMarkerDonor[iSize]; Donor_Flag = BuffDonorFlag[iSize]; break; @@ -273,8 +278,8 @@ void CInterface::PreprocessAverage(CGeometry *donor_geometry, CGeometry *target_ break; } /*--- If the tag hasn't matched any tag within the Flow markers ---*/ - Marker_Target = -1; - + Marker_Target = -1; + Target_Flag = -1; } if (Marker_Target != -1 && Marker_Donor != -1){ @@ -286,7 +291,7 @@ void CInterface::PreprocessAverage(CGeometry *donor_geometry, CGeometry *target_ for(iSpan = 1; iSpan SpanValuesDonor[jSpan]){ @@ -633,8 +638,6 @@ void CInterface::AllgatherAverage(CSolver *donor_solution, CSolver *target_solut delete [] avgNuTarget; delete [] avgKineTarget; delete [] avgOmegaTarget; - - } void CInterface::GatherAverageValues(CSolver *donor_solution, CSolver *target_solution, unsigned short donorZone){ diff --git a/SU2_CFD/src/interfaces/cfd/CMixingPlaneInterface.cpp b/SU2_CFD/src/interfaces/cfd/CMixingPlaneInterface.cpp index f35dc776f9e..d1bbcf2ff0b 100644 --- a/SU2_CFD/src/interfaces/cfd/CMixingPlaneInterface.cpp +++ b/SU2_CFD/src/interfaces/cfd/CMixingPlaneInterface.cpp @@ -118,7 +118,7 @@ void CMixingPlaneInterface::SetAverageValues(CSolver *donor_solution, CSolver *t unsigned short iSpan; for(iSpan = 0; iSpanSetDensityIn(donor_solution->GetDensityIn(donorZone, iSpan), donorZone, iSpan); target_solution->SetPressureIn(donor_solution->GetPressureIn(donorZone, iSpan), donorZone, iSpan); target_solution->SetTurboVelocityIn(donor_solution->GetTurboVelocityIn(donorZone, iSpan), donorZone, iSpan); diff --git a/SU2_CFD/src/interfaces/cht/CConjugateHeatInterface.cpp b/SU2_CFD/src/interfaces/cht/CConjugateHeatInterface.cpp index 54ad481b488..908ea27ae7f 100644 --- a/SU2_CFD/src/interfaces/cht/CConjugateHeatInterface.cpp +++ b/SU2_CFD/src/interfaces/cht/CConjugateHeatInterface.cpp @@ -132,8 +132,10 @@ void CConjugateHeatInterface::GetDonor_Variable(CSolver *donor_solution, CGeomet if ((donor_config->GetKind_CHT_Coupling() == CHT_COUPLING::DIRECT_TEMPERATURE_ROBIN_HEATFLUX) || (donor_config->GetKind_CHT_Coupling() == CHT_COUPLING::AVERAGED_TEMPERATURE_ROBIN_HEATFLUX)) { + /*--- Apply contact resistance to solid-to-solid heat transfer boundary ---*/ const su2double rho_cp_solid = donor_config->GetSpecific_Heat_Cp()*donor_config->GetMaterialDensity(0); - conductivity_over_dist = thermal_diffusivity*rho_cp_solid/dist; + thermal_conductivity = thermal_diffusivity * rho_cp_solid; + conductivity_over_dist = thermal_conductivity/(dist + thermal_conductivity * ContactResistance); } } diff --git a/SU2_CFD/src/iteration/CDiscAdjFEAIteration.cpp b/SU2_CFD/src/iteration/CDiscAdjFEAIteration.cpp index d7848499f62..53f1bff6945 100644 --- a/SU2_CFD/src/iteration/CDiscAdjFEAIteration.cpp +++ b/SU2_CFD/src/iteration/CDiscAdjFEAIteration.cpp @@ -233,11 +233,11 @@ void CDiscAdjFEAIteration::SetDependencies(CSolver***** solver, CGeometry**** ge /*--- MPI dependencies. ---*/ - dir_solver->InitiateComms(structural_geometry, config[iZone], SOLUTION_FEA); - dir_solver->CompleteComms(structural_geometry, config[iZone], SOLUTION_FEA); + dir_solver->InitiateComms(structural_geometry, config[iZone], MPI_QUANTITIES::SOLUTION_FEA); + dir_solver->CompleteComms(structural_geometry, config[iZone], MPI_QUANTITIES::SOLUTION_FEA); - structural_geometry->InitiateComms(structural_geometry, config[iZone], COORDINATES); - structural_geometry->CompleteComms(structural_geometry, config[iZone], COORDINATES); + structural_geometry->InitiateComms(structural_geometry, config[iZone], MPI_QUANTITIES::COORDINATES); + structural_geometry->CompleteComms(structural_geometry, config[iZone], MPI_QUANTITIES::COORDINATES); } END_SU2_OMP_PARALLEL diff --git a/SU2_CFD/src/iteration/CDiscAdjFluidIteration.cpp b/SU2_CFD/src/iteration/CDiscAdjFluidIteration.cpp index 6bde7b99418..27173f3357e 100644 --- a/SU2_CFD/src/iteration/CDiscAdjFluidIteration.cpp +++ b/SU2_CFD/src/iteration/CDiscAdjFluidIteration.cpp @@ -468,26 +468,26 @@ void CDiscAdjFluidIteration::SetDependencies(CSolver***** solver, CGeometry**** /*--- Compute coupling between flow, turbulent and species equations ---*/ solvers0[FLOW_SOL]->Preprocessing(geometry0, solvers0, config[iZone], MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, true); - solvers0[FLOW_SOL]->InitiateComms(geometry0, config[iZone], SOLUTION); - solvers0[FLOW_SOL]->CompleteComms(geometry0, config[iZone], SOLUTION); + solvers0[FLOW_SOL]->InitiateComms(geometry0, config[iZone], MPI_QUANTITIES::SOLUTION); + solvers0[FLOW_SOL]->CompleteComms(geometry0, config[iZone], MPI_QUANTITIES::SOLUTION); if (turbulent && !config[iZone]->GetFrozen_Visc_Disc()) { solvers0[TURB_SOL]->Postprocessing(geometry0, solvers0, config[iZone], MESH_0); - solvers0[TURB_SOL]->InitiateComms(geometry0, config[iZone], SOLUTION); - solvers0[TURB_SOL]->CompleteComms(geometry0, config[iZone], SOLUTION); + solvers0[TURB_SOL]->InitiateComms(geometry0, config[iZone], MPI_QUANTITIES::SOLUTION); + solvers0[TURB_SOL]->CompleteComms(geometry0, config[iZone], MPI_QUANTITIES::SOLUTION); } if (config[iZone]->GetKind_Species_Model() != SPECIES_MODEL::NONE) { solvers0[SPECIES_SOL]->Preprocessing(geometry0, solvers0, config[iZone], MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, true); - solvers0[SPECIES_SOL]->InitiateComms(geometry0, config[iZone], SOLUTION); - solvers0[SPECIES_SOL]->CompleteComms(geometry0, config[iZone], SOLUTION); + solvers0[SPECIES_SOL]->InitiateComms(geometry0, config[iZone], MPI_QUANTITIES::SOLUTION); + solvers0[SPECIES_SOL]->CompleteComms(geometry0, config[iZone], MPI_QUANTITIES::SOLUTION); } if (config[iZone]->GetWeakly_Coupled_Heat()) { solvers0[HEAT_SOL]->Set_Heatflux_Areas(geometry0, config[iZone]); solvers0[HEAT_SOL]->Preprocessing(geometry0, solvers0, config[iZone], MESH_0, NO_RK_ITER, RUNTIME_HEAT_SYS, true); solvers0[HEAT_SOL]->Postprocessing(geometry0, solvers0, config[iZone], MESH_0); - solvers0[HEAT_SOL]->InitiateComms(geometry0, config[iZone], SOLUTION); - solvers0[HEAT_SOL]->CompleteComms(geometry0, config[iZone], SOLUTION); + solvers0[HEAT_SOL]->InitiateComms(geometry0, config[iZone], MPI_QUANTITIES::SOLUTION); + solvers0[HEAT_SOL]->CompleteComms(geometry0, config[iZone], MPI_QUANTITIES::SOLUTION); } } @@ -495,8 +495,8 @@ void CDiscAdjFluidIteration::SetDependencies(CSolver***** solver, CGeometry**** if (config[iZone]->AddRadiation()) { solvers0[RAD_SOL]->Postprocessing(geometry0, solvers0, config[iZone], MESH_0); - solvers0[RAD_SOL]->InitiateComms(geometry0, config[iZone], SOLUTION); - solvers0[RAD_SOL]->CompleteComms(geometry0, config[iZone], SOLUTION); + solvers0[RAD_SOL]->InitiateComms(geometry0, config[iZone], MPI_QUANTITIES::SOLUTION); + solvers0[RAD_SOL]->CompleteComms(geometry0, config[iZone], MPI_QUANTITIES::SOLUTION); } } diff --git a/SU2_CFD/src/iteration/CDiscAdjHeatIteration.cpp b/SU2_CFD/src/iteration/CDiscAdjHeatIteration.cpp index 1c3666d5216..f0c14d4168a 100644 --- a/SU2_CFD/src/iteration/CDiscAdjHeatIteration.cpp +++ b/SU2_CFD/src/iteration/CDiscAdjHeatIteration.cpp @@ -213,8 +213,8 @@ void CDiscAdjHeatIteration::SetDependencies(CSolver***** solver, CGeometry**** g solvers0[HEAT_SOL]->Preprocessing(geometries[MESH_0], solvers0, config[iZone], MESH_0, NO_RK_ITER, RUNTIME_HEAT_SYS, true); solvers0[HEAT_SOL]->Postprocessing(geometries[MESH_0], solvers0, config[iZone], MESH_0); - solvers0[HEAT_SOL]->InitiateComms(geometries[MESH_0], config[iZone], SOLUTION); - solvers0[HEAT_SOL]->CompleteComms(geometries[MESH_0], config[iZone], SOLUTION); + solvers0[HEAT_SOL]->InitiateComms(geometries[MESH_0], config[iZone], MPI_QUANTITIES::SOLUTION); + solvers0[HEAT_SOL]->CompleteComms(geometries[MESH_0], config[iZone], MPI_QUANTITIES::SOLUTION); } void CDiscAdjHeatIteration::RegisterOutput(CSolver***** solver, CGeometry**** geometry, CConfig** config, diff --git a/SU2_CFD/src/iteration/CFluidIteration.cpp b/SU2_CFD/src/iteration/CFluidIteration.cpp index d5ae7bd22e4..bd60c38a961 100644 --- a/SU2_CFD/src/iteration/CFluidIteration.cpp +++ b/SU2_CFD/src/iteration/CFluidIteration.cpp @@ -200,6 +200,15 @@ void CFluidIteration::Update(COutput* output, CIntegration**** integration, CGeo solver[val_iZone][val_iInst][MESH_0][HEAT_SOL], config[val_iZone], MESH_0); } + + /*--- Update dual time solver for species transport equations (including flamelet) ---*/ + + if (config[val_iZone]->GetKind_Species_Model() != SPECIES_MODEL::NONE) { + integration[val_iZone][val_iInst][SPECIES_SOL]->SetDualTime_Solver(geometry[val_iZone][val_iInst][MESH_0], + solver[val_iZone][val_iInst][MESH_0][SPECIES_SOL], + config[val_iZone], MESH_0); + } + } } @@ -224,7 +233,7 @@ bool CFluidIteration::Monitor(COutput* output, CIntegration**** integration, CGe config[val_iZone]->GetInnerIter(), val_iInst); } - TurboMonitor(geometry, config, config[val_iZone]->GetInnerIter()); + TurboMonitor(geometry, config, config[val_iZone]->GetInnerIter(), val_iZone); } output->SetHistoryOutput(geometry[val_iZone][val_iInst][MESH_0], solver[val_iZone][val_iInst][MESH_0], config[val_iZone], config[val_iZone]->GetTimeIter(), config[val_iZone]->GetOuterIter(), @@ -242,45 +251,38 @@ bool CFluidIteration::Monitor(COutput* output, CIntegration**** integration, CGe return StopCalc; } -void CFluidIteration::TurboMonitor(CGeometry**** geometry_container, CConfig** config_container, unsigned long iter) { - - auto* config = config_container[ZONE_0]; +void CFluidIteration::TurboMonitor(CGeometry**** geometry_container, CConfig** config_container, unsigned long iter, unsigned short iZone) { + auto* config = config_container[iZone]; if (config_container[ZONE_0]->GetMultizone_Problem()) iter = config_container[ZONE_0]->GetOuterIter(); - - /*--- ROTATING FRAME Ramp: Compute the updated rotational velocity. ---*/ if (config->GetGrid_Movement() && config->GetRampRotatingFrame()) { const unsigned long rampFreq = SU2_TYPE::Int(config->GetRampRotatingFrame_Coeff(1)); const unsigned long finalRamp_Iter = SU2_TYPE::Int(config->GetRampRotatingFrame_Coeff(2)); const su2double rot_z_ini = config->GetRampRotatingFrame_Coeff(0); - const bool print = false; + const bool print = (config->GetComm_Level() == COMM_FULL); if(iter % rampFreq == 0 && iter <= finalRamp_Iter){ - for (auto iZone = 0u; iZone < nZone; iZone++) { - const su2double rot_z_final = config_container[iZone]->GetFinalRotation_Rate_Z(); + const su2double rot_z_final = config->GetFinalRotation_Rate_Z(); - if (fabs(rot_z_final) > 0.0) { - const su2double rot_z = rot_z_ini + iter * ( rot_z_final - rot_z_ini) / finalRamp_Iter; - config_container[iZone]->SetRotation_Rate(2, rot_z); - if (rank == MASTER_NODE && print && iter > 0) { - cout << "\nUpdated rotating frame grid velocities for zone " << iZone << ".\n"; - } - geometry_container[iZone][INST_0][MESH_0]->SetRotationalVelocity(config_container[iZone], print); - geometry_container[iZone][INST_0][MESH_0]->SetShroudVelocity(config_container[iZone]); + if (fabs(rot_z_final) > 0.0) { + const su2double rot_z = rot_z_ini + iter * ( rot_z_final - rot_z_ini) / finalRamp_Iter; + config->SetRotation_Rate(2, rot_z); + if (rank == MASTER_NODE && iter > 0) { + cout << "\nUpdated rotating frame grid velocities for zone " << iZone << ".\n"; } + geometry_container[iZone][INST_0][MESH_0]->SetRotationalVelocity(config, print); + geometry_container[iZone][INST_0][MESH_0]->SetShroudVelocity(config); } - for (auto iZone = 0u; iZone < nZone; iZone++) { - geometry_container[iZone][INST_0][MESH_0]->SetAvgTurboValue(config_container[iZone], iZone, INFLOW, false); - geometry_container[iZone][INST_0][MESH_0]->SetAvgTurboValue(config_container[iZone],iZone, OUTFLOW, false); - geometry_container[iZone][INST_0][MESH_0]->GatherInOutAverageValues(config_container[iZone], false); - } + geometry_container[iZone][INST_0][MESH_0]->SetAvgTurboValue(config, iZone, INFLOW, false); + geometry_container[iZone][INST_0][MESH_0]->SetAvgTurboValue(config, iZone, OUTFLOW, false); + geometry_container[iZone][INST_0][MESH_0]->GatherInOutAverageValues(config, false); - for (auto iZone = 0; iZone < nZone-1; iZone++) { - geometry_container[nZone-1][INST_0][MESH_0]->SetAvgTurboGeoValues(config_container[iZone],geometry_container[iZone][INST_0][MESH_0], iZone); + if (iZone < nZone - 1) { + geometry_container[nZone-1][INST_0][MESH_0]->SetAvgTurboGeoValues(config ,geometry_container[iZone][INST_0][MESH_0], iZone); } } } @@ -294,28 +296,26 @@ void CFluidIteration::TurboMonitor(CGeometry**** geometry_container, CConfig** c if (iter % rampFreq == 0 && iter <= finalRamp_Iter) { const su2double outPres = outPres_ini + iter * (outPres_final - outPres_ini) / finalRamp_Iter; - if (rank == MASTER_NODE) config->SetMonitotOutletPressure(outPres); - - for (auto iZone = 0u; iZone < nZone; iZone++) { - for (auto iMarker = 0; iMarker < config_container[iZone]->GetnMarker_All(); iMarker++) { - const auto KindBC = config_container[iZone]->GetMarker_All_KindBC(iMarker); - const auto Marker_Tag = config_container[iZone]->GetMarker_All_TagBound(iMarker); - unsigned short KindBCOption; - switch (KindBC) { - case RIEMANN_BOUNDARY: - KindBCOption = config_container[iZone]->GetKind_Data_Riemann(Marker_Tag); - if (KindBCOption == STATIC_PRESSURE || KindBCOption == RADIAL_EQUILIBRIUM) { - SU2_MPI::Error("Outlet pressure ramp only implemented for NRBC", CURRENT_FUNCTION); - } - break; - case GILES_BOUNDARY: - KindBCOption = config_container[iZone]->GetKind_Data_Giles(Marker_Tag); - if (KindBCOption == STATIC_PRESSURE || KindBCOption == STATIC_PRESSURE_1D || - KindBCOption == RADIAL_EQUILIBRIUM ) { - config_container[iZone]->SetGiles_Var1(outPres, Marker_Tag); - } - break; - } + if (rank == MASTER_NODE) config->SetMonitorOutletPressure(outPres); + + for (auto iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { + const auto KindBC = config->GetMarker_All_KindBC(iMarker); + const auto Marker_Tag = config->GetMarker_All_TagBound(iMarker); + unsigned short KindBCOption; + switch (KindBC) { + case RIEMANN_BOUNDARY: + KindBCOption = config->GetKind_Data_Riemann(Marker_Tag); + if (KindBCOption == STATIC_PRESSURE || KindBCOption == RADIAL_EQUILIBRIUM) { + SU2_MPI::Error("Outlet pressure ramp only implemented for NRBC", CURRENT_FUNCTION); + } + break; + case GILES_BOUNDARY: + KindBCOption = config->GetKind_Data_Giles(Marker_Tag); + if (KindBCOption == STATIC_PRESSURE || KindBCOption == STATIC_PRESSURE_1D || + KindBCOption == RADIAL_EQUILIBRIUM ) { + config->SetGiles_Var1(outPres, Marker_Tag); + } + break; } } } diff --git a/SU2_CFD/src/meson.build b/SU2_CFD/src/meson.build index 43e8aaed5de..3b40822a34f 100644 --- a/SU2_CFD/src/meson.build +++ b/SU2_CFD/src/meson.build @@ -189,6 +189,11 @@ su2_cfd_src += files(['iteration/CIteration.cpp', su2_cfd_src += files(['limiters/CLimiterDetails.cpp']) +profiling_args = [] +if get_option('enable-gprof') + profiling_args = ['-pg','-no-pie'] +endif + if get_option('enable-normal') su2_cfd_lib = static_library('SU2core', su2_cfd_src, @@ -201,7 +206,8 @@ if get_option('enable-normal') 'SU2_CFD.cpp', install : true, dependencies : [su2_cfd_dep, su2_deps, common_dep], - cpp_args: ['-fPIC'] + [default_warning_flags, su2_cpp_args]) + cpp_args: ['-fPIC'] + [default_warning_flags, su2_cpp_args] + profiling_args, + link_args: profiling_args) endif if get_option('enable-autodiff') @@ -216,7 +222,8 @@ if get_option('enable-autodiff') 'SU2_CFD.cpp', install : true, dependencies : [su2_cfd_dep_ad, su2_deps, codi_dep, commonAD_dep], - cpp_args: ['-fPIC'] + [default_warning_flags, su2_cpp_args, codi_rev_args]) + cpp_args: ['-fPIC'] + [default_warning_flags, su2_cpp_args, codi_rev_args] + profiling_args, + link_args: profiling_args) endif if get_option('enable-directdiff') @@ -231,6 +238,7 @@ if get_option('enable-directdiff') 'SU2_CFD.cpp', install : true, dependencies : [su2_cfd_dep_dd, su2_deps, codi_dep, commonDD_dep], - cpp_args: ['-fPIC'] + [default_warning_flags, su2_cpp_args, codi_for_args]) + cpp_args: ['-fPIC'] + [default_warning_flags, su2_cpp_args, codi_for_args] + profiling_args, + link_args: profiling_args) endif diff --git a/SU2_CFD/src/output/CFlowCompOutput.cpp b/SU2_CFD/src/output/CFlowCompOutput.cpp index 1666191e07f..8108765de02 100644 --- a/SU2_CFD/src/output/CFlowCompOutput.cpp +++ b/SU2_CFD/src/output/CFlowCompOutput.cpp @@ -604,6 +604,8 @@ void CFlowCompOutput::LoadTurboHistoryData(std::shared_ptrGetOutletState().GetMachValue()); SetHistoryOutputValue("AbsFlowAngleIn_" + tag.str(), BladePerf->GetInletState().GetAbsFlowAngle()*180/PI_NUMBER); SetHistoryOutputValue("AbsFlowAngleOut_" + tag.str(), BladePerf->GetOutletState().GetAbsFlowAngle()*180/PI_NUMBER); + SetHistoryOutputValue("KineticEnergyLoss_" + tag.str(), BladePerf->GetKineticEnergyLoss()); + SetHistoryOutputValue("TotPressureLoss_" + tag.str(), BladePerf->GetTotalPressureLoss()); } SetHistoryOutputValue("EntropyGeneration", TurboStagePerf->GetNormEntropyGen()*100); SetHistoryOutputValue("EulerianWork", TurboStagePerf->GetEulerianWork()); @@ -611,6 +613,8 @@ void CFlowCompOutput::LoadTurboHistoryData(std::shared_ptrGetTotalTotalEfficiency()*100); SetHistoryOutputValue("PressureRatioTS", TurboStagePerf->GetTotalStaticPressureRatio()); SetHistoryOutputValue("PressureRatioTT", TurboStagePerf->GetTotalTotalPressureRatio()); + SetHistoryOutputValue("KineticEnergyLoss_Stage", TurboStagePerf->GetKineticEnergyLoss()); + SetHistoryOutputValue("TotPressureLoss_Stage", TurboStagePerf->GetTotalPressureLoss()); } void CFlowCompOutput::WriteTurboSpanwisePerformance(std::shared_ptr TurboPerf, CGeometry *geometry, CConfig **config, unsigned short val_iZone) { diff --git a/SU2_CFD/src/output/CFlowOutput.cpp b/SU2_CFD/src/output/CFlowOutput.cpp index 65fac24ddaf..7c7d5632445 100644 --- a/SU2_CFD/src/output/CFlowOutput.cpp +++ b/SU2_CFD/src/output/CFlowOutput.cpp @@ -1218,6 +1218,9 @@ void CFlowOutput::LoadHistoryDataScalar(const CConfig* config, const CSolver* co const auto& cv_name = config->GetControllingVariableName(iCV); SetHistoryOutputValue("RMS_" + cv_name, log10(solver[SPECIES_SOL]->GetRes_RMS(iCV))); SetHistoryOutputValue("MAX_" + cv_name, log10(solver[SPECIES_SOL]->GetRes_Max(iCV))); + if (multiZone) { + SetHistoryOutputValue("BGS_" + cv_name, log10(solver[SPECIES_SOL]->GetRes_BGS(iCV))); + } } /*--- auxiliary species transport ---*/ for (unsigned short iReactant=0; iReactantGetNUserScalars(); iReactant++){ @@ -4075,12 +4078,16 @@ void CFlowOutput::AddTurboOutput(unsigned short nZone){ AddHistoryOutput("MachOut_" + tag, "MachOut_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Total-to-Static efficiency " + tag, HistoryFieldType::DEFAULT); AddHistoryOutput("AbsFlowAngleIn_" + tag, "AbsFlowAngleIn_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Absolute flow angle in " + tag, HistoryFieldType::DEFAULT); AddHistoryOutput("AbsFlowAngleOut_" + tag, "AbsFlowAngleOut_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Absolute flow angle out " + tag, HistoryFieldType::DEFAULT); + AddHistoryOutput("KineticEnergyLoss_" + tag, "KELC_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Blade Kinetic Energy Loss Coefficient", HistoryFieldType::DEFAULT); + AddHistoryOutput("TotPressureLoss_" + tag, "TPLC_" + tag, ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Blade Pressure Loss Coefficient", HistoryFieldType::DEFAULT); } //Adds turbomachinery machine performance variables AddHistoryOutput("EntropyGeneration", "EntropyGen", ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Machine entropy generation", HistoryFieldType::DEFAULT); - AddHistoryOutput("EulerianWork", "EulerianWork", ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Machine entropy generation", HistoryFieldType::DEFAULT); - AddHistoryOutput("TotalStaticEfficiency", "TotStaticEff", ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Machine entropy generation", HistoryFieldType::DEFAULT); - AddHistoryOutput("TotalTotalEfficiency", "TotTotEff", ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Machine entropy generation", HistoryFieldType::DEFAULT); - AddHistoryOutput("PressureRatioTS", "PRTS", ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Machine entropy generation", HistoryFieldType::DEFAULT); - AddHistoryOutput("PressureRatioTT", "PRTT", ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Machine entropy generation", HistoryFieldType::DEFAULT); + AddHistoryOutput("EulerianWork", "EulerianWork", ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Machine Eulerian work", HistoryFieldType::DEFAULT); + AddHistoryOutput("TotalStaticEfficiency", "TotStaticEff", ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Machine total-to-static efficiency", HistoryFieldType::DEFAULT); + AddHistoryOutput("TotalTotalEfficiency", "TotTotEff", ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Machine total-to-total efficiency", HistoryFieldType::DEFAULT); + AddHistoryOutput("PressureRatioTS", "PRTS", ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Machine total-to-static pressure ratio", HistoryFieldType::DEFAULT); + AddHistoryOutput("PressureRatioTT", "PRTT", ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Machine total-to-toal pressure ratio", HistoryFieldType::DEFAULT); + AddHistoryOutput("KineticEnergyLoss_Stage", "KELC_all", ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Machine Kinetic Energy Loss Coefficient", HistoryFieldType::DEFAULT); + AddHistoryOutput("TotPressureLoss_Stage", "TPLC_all", ScreenOutputFormat::SCIENTIFIC, "TURBO_PERF", "Machine Pressure Loss Coefficient", HistoryFieldType::DEFAULT); } diff --git a/SU2_CFD/src/output/COutput.cpp b/SU2_CFD/src/output/COutput.cpp index c49a2627b22..d8aa5c16af9 100644 --- a/SU2_CFD/src/output/COutput.cpp +++ b/SU2_CFD/src/output/COutput.cpp @@ -191,7 +191,7 @@ void COutput::SetHistoryOutput(CGeometry *geometry, unsigned long InnerIter) { curTimeIter = TimeIter; - curAbsTimeIter = TimeIter - config->GetRestart_Iter(); + curAbsTimeIter = max(TimeIter, config->GetStartWindowIteration()) - config->GetStartWindowIteration(); curOuterIter = OuterIter; curInnerIter = InnerIter; @@ -250,7 +250,6 @@ void COutput::SetHistoryOutput(CGeometry ****geometry, CSolver *****solver, CCon if (rank == MASTER_NODE){ LoadTurboHistoryData(TurboStagePerf, TurboPerf, config[val_iZone]); } - SetHistoryOutput(geometry[val_iZone][val_iInst][MESH_0], solver[val_iZone][val_iInst][MESH_0], config[val_iZone], TimeIter, OuterIter,InnerIter); } @@ -258,7 +257,7 @@ void COutput::SetHistoryOutput(CGeometry ****geometry, CSolver *****solver, CCon void COutput::SetMultizoneHistoryOutput(COutput **output, CConfig **config, CConfig *driver_config, unsigned long TimeIter, unsigned long OuterIter){ curTimeIter = TimeIter; - curAbsTimeIter = TimeIter - driver_config->GetRestart_Iter(); + curAbsTimeIter = max(TimeIter, driver_config->GetStartWindowIteration()) - driver_config->GetStartWindowIteration(); curOuterIter = OuterIter; /*--- Retrieve residual and extra data -----------------------------------------------------------------*/ @@ -2414,4 +2413,4 @@ void COutput::PrintVolumeFields(){ VolumeFieldTable.PrintFooter(); } -} \ No newline at end of file +} diff --git a/SU2_CFD/src/output/CTurboOutput.cpp b/SU2_CFD/src/output/CTurboOutput.cpp index b0e61f10e25..59430179231 100644 --- a/SU2_CFD/src/output/CTurboOutput.cpp +++ b/SU2_CFD/src/output/CTurboOutput.cpp @@ -60,7 +60,7 @@ void CTurbomachineryState::ComputeState(CFluidModel& fluidModel, const CTurbomac Pressure = primitiveState.GetPressure(); std::vector velocity = primitiveState.GetVelocity(); Velocity.assign(velocity.begin(), velocity.end()); - su2double tangVel = primitiveState.GetTangVelocity(); + TangVelocity = primitiveState.GetTangVelocity(); /*--- Compute static TD quantities ---*/ fluidModel.SetTDState_Prho(Pressure, Density); @@ -81,9 +81,9 @@ void CTurbomachineryState::ComputeState(CFluidModel& fluidModel, const CTurbomac std::for_each(Mach.begin(), Mach.end(), [&](su2double& el) { el /= soundSpeed; }); /*--- Compute relative kinematic quantities ---*/ - su2double tangVel2 = tangVel * tangVel; + su2double tangVel2 = TangVelocity * TangVelocity; RelVelocity.assign(Velocity.begin(), Velocity.end()); - RelVelocity[1] -= tangVel; + RelVelocity[1] -= TangVelocity; su2double relVel2 = GetRelVelocityValue(); FlowAngle = atan(RelVelocity[1] / RelVelocity[0]); RelMach.assign(RelVelocity.begin(), RelVelocity.end()); @@ -244,6 +244,8 @@ void CTurbomachineryStagePerformance::ComputeTurbineStagePerformance(const CTurb fluidModel.SetTDState_Ps(OutState.GetPressure(), InState.GetEntropy()); su2double enthalpyOutIs = fluidModel.GetStaticEnergy() + OutState.GetPressure() / fluidModel.GetDensity(); su2double totEnthalpyOutIs = enthalpyOutIs + 0.5 * OutState.GetVelocityValue() * OutState.GetVelocityValue(); + su2double tangVel = OutState.GetTangVelocity(); + su2double relVelOutIs2 = 2 * (OutState.GetRothalpy() - enthalpyOutIs) + tangVel * tangVel; /*--- Compute turbine stage performance ---*/ NormEntropyGen = (OutState.GetEntropy() - InState.GetEntropy()) / InState.GetEntropy(); @@ -252,6 +254,9 @@ void CTurbomachineryStagePerformance::ComputeTurbineStagePerformance(const CTurb TotalTotalEfficiency = EulerianWork / (InState.GetTotalEnthalpy() - totEnthalpyOutIs); TotalStaticPressureRatio = InState.GetTotalPressure() / OutState.GetPressure(); TotalTotalPressureRatio = InState.GetTotalPressure() / OutState.GetTotalPressure(); + TotalPressureLoss = (InState.GetTotalRelPressure() - OutState.GetTotalRelPressure()) / + (OutState.GetTotalRelPressure() - OutState.GetPressure()); + KineticEnergyLoss = 2 * (OutState.GetEnthalpy() - enthalpyOutIs) / relVelOutIs2; } void CTurbomachineryStagePerformance::ComputeCompressorStagePerformance(const CTurbomachineryState& InState, diff --git a/SU2_CFD/src/python_wrapper_structure.cpp b/SU2_CFD/src/python_wrapper_structure.cpp index 97cf441f1e5..a0018371443 100644 --- a/SU2_CFD/src/python_wrapper_structure.cpp +++ b/SU2_CFD/src/python_wrapper_structure.cpp @@ -36,23 +36,17 @@ void CDriver::PreprocessPythonInterface(CConfig** config, CGeometry**** geometry /*--- Initialize boundary conditions customization, this is achieved through the Python wrapper. --- */ for (iZone = 0; iZone < nZone; iZone++) { if (config[iZone]->GetnMarker_PyCustom() > 0) { - if (rank == MASTER_NODE) cout << "----------------- Python Interface Preprocessing ( Zone " << iZone << " ) -----------------" << endl; - - if (rank == MASTER_NODE) cout << "Setting customized boundary conditions for zone " << iZone << endl; + if (rank == MASTER_NODE) { + cout << "----------------- Python Interface Preprocessing ( Zone " << iZone << " ) -----------------\n"; + cout << "Setting customized boundary conditions for zone " << iZone << endl; + } for (iMesh = 0; iMesh <= config[iZone]->GetnMGLevels(); iMesh++) { geometry[iZone][INST_0][iMesh]->SetCustomBoundary(config[iZone]); } geometry[iZone][INST_0][MESH_0]->UpdateCustomBoundaryConditions(geometry[iZone][INST_0], config[iZone]); - if ((config[iZone]->GetKind_Solver() == MAIN_SOLVER::EULER) || - (config[iZone]->GetKind_Solver() == MAIN_SOLVER::NAVIER_STOKES) || - (config[iZone]->GetKind_Solver() == MAIN_SOLVER::RANS) || - (config[iZone]->GetKind_Solver() == MAIN_SOLVER::INC_EULER) || - (config[iZone]->GetKind_Solver() == MAIN_SOLVER::INC_NAVIER_STOKES) || - (config[iZone]->GetKind_Solver() == MAIN_SOLVER::INC_RANS) || - (config[iZone]->GetKind_Solver() == MAIN_SOLVER::NEMO_EULER) || - (config[iZone]->GetKind_Solver() == MAIN_SOLVER::NEMO_NAVIER_STOKES)) { - solver[iZone][INST_0][MESH_0][FLOW_SOL]->UpdateCustomBoundaryConditions(geometry[iZone][INST_0], config[iZone]); + if (solver[iZone][INST_0][MESH_0][FLOW_SOL]) { + solver[iZone][INST_0][MESH_0][FLOW_SOL]->UpdateCustomBoundaryConditions(geometry[iZone][INST_0], solver[iZone][INST_0], config[iZone]); } } } @@ -77,7 +71,7 @@ string CDriver::GetSurfaceFileName() const { return config_container[selected_zo //////////////////////////////////////////////////////////////////////////////// void CDriver::SetHeatSourcePosition(passivedouble alpha, passivedouble pos_x, passivedouble pos_y, - passivedouble pos_z) { + passivedouble pos_z) { CSolver* solver = solver_container[selected_zone][INST_0][MESH_0][RAD_SOL]; config_container[selected_zone]->SetHeatSource_Rot_Z(alpha); @@ -87,13 +81,15 @@ void CDriver::SetHeatSourcePosition(passivedouble alpha, passivedouble pos_x, pa } void CDriver::SetInletAngle(unsigned short iMarker, passivedouble alpha) { - su2double alpha_rad = alpha * PI_NUMBER / 180.0; + const su2double alpha_rad = alpha * PI_NUMBER / 180.0; - unsigned long iVertex; + const auto* geometry = geometry_container[selected_zone][INST_0][MESH_0]; + auto* flow_solver = solver_container[selected_zone][INST_0][MESH_0][FLOW_SOL]; - for (iVertex = 0; iVertex < geometry_container[selected_zone][INST_0][MESH_0]->nVertex[iMarker]; iVertex++) { - solver_container[selected_zone][INST_0][MESH_0][FLOW_SOL]->SetInlet_FlowDir(iMarker, iVertex, 0, cos(alpha_rad)); - solver_container[selected_zone][INST_0][MESH_0][FLOW_SOL]->SetInlet_FlowDir(iMarker, iVertex, 1, sin(alpha_rad)); + for (auto iVertex = 0ul; iVertex < geometry->nVertex[iMarker]; ++iVertex) { + flow_solver->SetInletFlowDir(iMarker, iVertex, 0, cos(alpha_rad)); + flow_solver->SetInletFlowDir(iMarker, iVertex, 1, sin(alpha_rad)); + if (geometry->GetnDim() == 3) flow_solver->SetInletFlowDir(iMarker, iVertex, 2, 0); } } diff --git a/SU2_CFD/src/solvers/CAdjEulerSolver.cpp b/SU2_CFD/src/solvers/CAdjEulerSolver.cpp index e43bd91c871..17128c7fec8 100644 --- a/SU2_CFD/src/solvers/CAdjEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CAdjEulerSolver.cpp @@ -328,8 +328,8 @@ CAdjEulerSolver::CAdjEulerSolver(CGeometry *geometry, CConfig *config, unsigned /*--- MPI solution ---*/ - InitiateComms(geometry, config, SOLUTION); - CompleteComms(geometry, config, SOLUTION); + InitiateComms(geometry, config, MPI_QUANTITIES::SOLUTION); + CompleteComms(geometry, config, MPI_QUANTITIES::SOLUTION); SolverName = "ADJ.FLOW"; } @@ -888,8 +888,8 @@ void CAdjEulerSolver::SetInitialCondition(CGeometry **geometry, CSolver ***solve for (auto iMesh = 1ul; iMesh <= config->GetnMGLevels(); iMesh++) { MultigridRestriction(*geometry[iMesh - 1], solver_container[iMesh - 1][ADJFLOW_SOL]->GetNodes()->GetSolution(), *geometry[iMesh], solver_container[iMesh][ADJFLOW_SOL]->GetNodes()->GetSolution()); - solver_container[iMesh][ADJFLOW_SOL]->InitiateComms(geometry[iMesh], config, SOLUTION); - solver_container[iMesh][ADJFLOW_SOL]->CompleteComms(geometry[iMesh], config, SOLUTION); + solver_container[iMesh][ADJFLOW_SOL]->InitiateComms(geometry[iMesh], config, MPI_QUANTITIES::SOLUTION); + solver_container[iMesh][ADJFLOW_SOL]->CompleteComms(geometry[iMesh], config, MPI_QUANTITIES::SOLUTION); } } @@ -1343,8 +1343,8 @@ void CAdjEulerSolver::SetCentered_Dissipation_Sensor(CGeometry *geometry, CConfi /*--- MPI parallelization ---*/ - InitiateComms(geometry, config, SENSOR); - CompleteComms(geometry, config, SENSOR); + InitiateComms(geometry, config, MPI_QUANTITIES::SENSOR); + CompleteComms(geometry, config, MPI_QUANTITIES::SENSOR); } @@ -1377,8 +1377,8 @@ void CAdjEulerSolver::ExplicitRK_Iteration(CGeometry *geometry, CSolver **solver /*--- MPI solution ---*/ - InitiateComms(geometry, config, SOLUTION); - CompleteComms(geometry, config, SOLUTION); + InitiateComms(geometry, config, MPI_QUANTITIES::SOLUTION); + CompleteComms(geometry, config, MPI_QUANTITIES::SOLUTION); /*--- Compute the root mean square residual ---*/ SetResidual_RMS(geometry, config); @@ -1411,8 +1411,8 @@ void CAdjEulerSolver::ExplicitEuler_Iteration(CGeometry *geometry, CSolver **sol /*--- MPI solution ---*/ - InitiateComms(geometry, config, SOLUTION); - CompleteComms(geometry, config, SOLUTION); + InitiateComms(geometry, config, MPI_QUANTITIES::SOLUTION); + CompleteComms(geometry, config, MPI_QUANTITIES::SOLUTION); /*--- Compute the root mean square residual ---*/ SetResidual_RMS(geometry, config); @@ -1491,8 +1491,8 @@ void CAdjEulerSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **sol /*--- MPI solution ---*/ - InitiateComms(geometry, config, SOLUTION); - CompleteComms(geometry, config, SOLUTION); + InitiateComms(geometry, config, MPI_QUANTITIES::SOLUTION); + CompleteComms(geometry, config, MPI_QUANTITIES::SOLUTION); /*--- Compute the root mean square residual ---*/ @@ -3880,8 +3880,8 @@ void CAdjEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConf it down to the coarse levels. We also call the preprocessing routine on the fine level in order to have all necessary quantities updated. ---*/ - solver[MESH_0][ADJFLOW_SOL]->InitiateComms(geometry[MESH_0], config, SOLUTION); - solver[MESH_0][ADJFLOW_SOL]->CompleteComms(geometry[MESH_0], config, SOLUTION); + solver[MESH_0][ADJFLOW_SOL]->InitiateComms(geometry[MESH_0], config, MPI_QUANTITIES::SOLUTION); + solver[MESH_0][ADJFLOW_SOL]->CompleteComms(geometry[MESH_0], config, MPI_QUANTITIES::SOLUTION); solver[MESH_0][ADJFLOW_SOL]->Preprocessing(geometry[MESH_0], solver[MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); /*--- Interpolate the solution down to the coarse multigrid levels ---*/ @@ -3889,8 +3889,8 @@ void CAdjEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConf for (iMesh = 1; iMesh <= config->GetnMGLevels(); iMesh++) { MultigridRestriction(*geometry[iMesh - 1], solver[iMesh - 1][ADJFLOW_SOL]->GetNodes()->GetSolution(), *geometry[iMesh], solver[iMesh][ADJFLOW_SOL]->GetNodes()->GetSolution()); - solver[iMesh][ADJFLOW_SOL]->InitiateComms(geometry[iMesh], config, SOLUTION); - solver[iMesh][ADJFLOW_SOL]->CompleteComms(geometry[iMesh], config, SOLUTION); + solver[iMesh][ADJFLOW_SOL]->InitiateComms(geometry[iMesh], config, MPI_QUANTITIES::SOLUTION); + solver[iMesh][ADJFLOW_SOL]->CompleteComms(geometry[iMesh], config, MPI_QUANTITIES::SOLUTION); solver[iMesh][ADJFLOW_SOL]->Preprocessing(geometry[iMesh], solver[iMesh], config, iMesh, NO_RK_ITER, RUNTIME_FLOW_SYS, false); } diff --git a/SU2_CFD/src/solvers/CAdjNSSolver.cpp b/SU2_CFD/src/solvers/CAdjNSSolver.cpp index b9da5ad2b63..c07425a2bdc 100644 --- a/SU2_CFD/src/solvers/CAdjNSSolver.cpp +++ b/SU2_CFD/src/solvers/CAdjNSSolver.cpp @@ -281,8 +281,8 @@ CAdjNSSolver::CAdjNSSolver(CGeometry *geometry, CConfig *config, unsigned short /*--- MPI solution ---*/ - InitiateComms(geometry, config, SOLUTION); - CompleteComms(geometry, config, SOLUTION); + InitiateComms(geometry, config, MPI_QUANTITIES::SOLUTION); + CompleteComms(geometry, config, MPI_QUANTITIES::SOLUTION); } diff --git a/SU2_CFD/src/solvers/CAdjTurbSolver.cpp b/SU2_CFD/src/solvers/CAdjTurbSolver.cpp index 58403f541a4..3d5b6eb7024 100644 --- a/SU2_CFD/src/solvers/CAdjTurbSolver.cpp +++ b/SU2_CFD/src/solvers/CAdjTurbSolver.cpp @@ -158,8 +158,8 @@ CAdjTurbSolver::CAdjTurbSolver(CGeometry *geometry, CConfig *config, unsigned sh /*--- MPI solution ---*/ - InitiateComms(geometry, config, SOLUTION); - CompleteComms(geometry, config, SOLUTION); + InitiateComms(geometry, config, MPI_QUANTITIES::SOLUTION); + CompleteComms(geometry, config, MPI_QUANTITIES::SOLUTION); } @@ -511,8 +511,8 @@ void CAdjTurbSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solv /*--- MPI solution ---*/ - InitiateComms(geometry, config, SOLUTION); - CompleteComms(geometry, config, SOLUTION); + InitiateComms(geometry, config, MPI_QUANTITIES::SOLUTION); + CompleteComms(geometry, config, MPI_QUANTITIES::SOLUTION); /*--- Compute the root mean square residual ---*/ diff --git a/SU2_CFD/src/solvers/CBaselineSolver.cpp b/SU2_CFD/src/solvers/CBaselineSolver.cpp index bc8b9c1ebc5..411cce58397 100644 --- a/SU2_CFD/src/solvers/CBaselineSolver.cpp +++ b/SU2_CFD/src/solvers/CBaselineSolver.cpp @@ -459,8 +459,8 @@ void CBaselineSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConf /*--- MPI solution ---*/ - InitiateComms(geometry[iInst], config, SOLUTION); - CompleteComms(geometry[iInst], config, SOLUTION); + InitiateComms(geometry[iInst], config, MPI_QUANTITIES::SOLUTION); + CompleteComms(geometry[iInst], config, MPI_QUANTITIES::SOLUTION); /*--- Update the geometry for flows on dynamic meshes ---*/ @@ -468,11 +468,11 @@ void CBaselineSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConf /*--- Communicate the new coordinates and grid velocities at the halos ---*/ - geometry[iInst]->InitiateComms(geometry[iInst], config, COORDINATES); - geometry[iInst]->CompleteComms(geometry[iInst], config, COORDINATES); + geometry[iInst]->InitiateComms(geometry[iInst], config, MPI_QUANTITIES::COORDINATES); + geometry[iInst]->CompleteComms(geometry[iInst], config, MPI_QUANTITIES::COORDINATES); - geometry[iInst]->InitiateComms(geometry[iInst], config, GRID_VELOCITY); - geometry[iInst]->CompleteComms(geometry[iInst], config, GRID_VELOCITY); + geometry[iInst]->InitiateComms(geometry[iInst], config, MPI_QUANTITIES::GRID_VELOCITY); + geometry[iInst]->CompleteComms(geometry[iInst], config, MPI_QUANTITIES::GRID_VELOCITY); } diff --git a/SU2_CFD/src/solvers/CEulerSolver.cpp b/SU2_CFD/src/solvers/CEulerSolver.cpp index 16cdfe59a4b..8e4c9a01147 100644 --- a/SU2_CFD/src/solvers/CEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CEulerSolver.cpp @@ -232,6 +232,9 @@ CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config, Exhaust_Pressure.resize(nMarker); Exhaust_Area.resize(nMarker); + /*--- Turbomachinery simulation ---*/ + AverageMassFlowRate.resize(nMarker); + /*--- Read farfield conditions from config ---*/ Temperature_Inf = config->GetTemperature_FreeStreamND(); @@ -279,6 +282,8 @@ CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config, Exhaust_Temperature[iMarker] = Temperature_Inf; Exhaust_Pressure[iMarker] = Pressure_Inf; Exhaust_Area[iMarker] = 0.0; + + AverageMassFlowRate[iMarker] = 0.0; } /*--- Initialize the solution to the far-field state everywhere. ---*/ @@ -2351,8 +2356,8 @@ void CEulerSolver::SetUndivided_Laplacian(CGeometry *geometry, const CConfig *co /*--- MPI parallelization ---*/ - InitiateComms(geometry, config, UNDIVIDED_LAPLACIAN); - CompleteComms(geometry, config, UNDIVIDED_LAPLACIAN); + InitiateComms(geometry, config, MPI_QUANTITIES::UNDIVIDED_LAPLACIAN); + CompleteComms(geometry, config, MPI_QUANTITIES::UNDIVIDED_LAPLACIAN); } @@ -2415,8 +2420,8 @@ void CEulerSolver::SetUpwind_Ducros_Sensor(CGeometry *geometry, CConfig *config) } END_SU2_OMP_FOR - InitiateComms(geometry, config, SENSOR); - CompleteComms(geometry, config, SENSOR); + InitiateComms(geometry, config, MPI_QUANTITIES::SENSOR); + CompleteComms(geometry, config, MPI_QUANTITIES::SENSOR); } @@ -4692,23 +4697,6 @@ void CEulerSolver::SetCoefficient_Gradients(CConfig *config) const{ config->SetdCL_dAlpha(dCL_dAlpha_); } -void CEulerSolver::UpdateCustomBoundaryConditions(CGeometry **geometry_container, CConfig *config){ - - unsigned short nMGlevel; - unsigned long iMarker; - - // TODO: Update the fluid boundary conditions for MG - nMGlevel = config->GetnMGLevels(); - if (nMGlevel > 1) { - for (iMarker=0; iMarker < nMarker; iMarker++) { - bool isCustomizable = config->GetMarker_All_PyCustom(iMarker); - bool isInlet = (config->GetMarker_All_KindBC(iMarker) == INLET_FLOW); - if (isCustomizable && isInlet) - SU2_MPI::Error("Custom inlet BCs are not currently compatible with multigrid.", CURRENT_FUNCTION); - } - } -} - void CEulerSolver::Evaluate_ObjFunc(const CConfig *config, CSolver**) { unsigned short iMarker_Monitoring, Kind_ObjFunc; @@ -5067,8 +5055,8 @@ void CEulerSolver::BC_Riemann(CGeometry *geometry, CSolver **solver_container, su2double Velocity_i[MAXNDIM]={0}; for (auto iDim=0u; iDim < nDim; iDim++) Velocity_i[iDim] = nodes->GetVelocity(iPoint,iDim); - - const auto Velocity2_i = GeometryToolbox::SquaredNorm(nDim, Velocity_i); + + const auto Velocity2_i = GeometryToolbox::SquaredNorm(nDim, Velocity_i); const auto Density_i = nodes->GetDensity(iPoint); @@ -5090,7 +5078,7 @@ void CEulerSolver::BC_Riemann(CGeometry *geometry, CSolver **solver_container, T_Total{0}, P_Total{0}, Density_e{0}, StaticEnthalpy_e{0}, StaticEnergy_e{0}; su2double Velocity2_e{0}, NormalVelocity{0}, TangVelocity{0}, VelMag_e{0}; - su2double Velocity_e[MAXNDIM] = {0}; + su2double Velocity_e[MAXNDIM] = {0}; const su2double * Flow_Dir, * Mach; switch(config->GetKind_Data_Riemann(Marker_Tag)) { @@ -5146,10 +5134,10 @@ void CEulerSolver::BC_Riemann(CGeometry *geometry, CSolver **solver_container, GetFluidModel()->SetTDState_PT(P_static, T_static); /* --- Compute the boundary state u_e --- */ - for (auto iDim = 0u; iDim < nDim; iDim++) + for (auto iDim = 0u; iDim < nDim; iDim++) Velocity_e[iDim] = Mach[iDim]*GetFluidModel()->GetSoundSpeed(); - Velocity2_e = GeometryToolbox::SquaredNorm(nDim, Velocity_e); + Velocity2_e = GeometryToolbox::SquaredNorm(nDim, Velocity_e); Density_e = GetFluidModel()->GetDensity(); StaticEnergy_e = GetFluidModel()->GetStaticEnergy(); Energy_e = StaticEnergy_e + 0.5 * Velocity2_e; @@ -5176,7 +5164,7 @@ void CEulerSolver::BC_Riemann(CGeometry *geometry, CSolver **solver_container, for (auto iDim = 0u; iDim < nDim; iDim++) Velocity_e[iDim] = Mach[iDim]*GetFluidModel()->GetSoundSpeed(); - Velocity2_e = GeometryToolbox::SquaredNorm(nDim, Velocity_e); + Velocity2_e = GeometryToolbox::SquaredNorm(nDim, Velocity_e); Density_e = GetFluidModel()->GetDensity(); StaticEnergy_e = GetFluidModel()->GetStaticEnergy(); Energy_e = StaticEnergy_e + 0.5 * Velocity2_e; @@ -5208,10 +5196,10 @@ void CEulerSolver::BC_Riemann(CGeometry *geometry, CSolver **solver_container, /* --- Compute the boundary state u_e --- */ GetFluidModel()->SetTDState_Prho(Pressure_e, Density_e); - for (auto iDim = 0u; iDim < nDim; iDim++) + for (auto iDim = 0u; iDim < nDim; iDim++) Velocity_e[iDim] = Velocity_i[iDim]; - Velocity2_e = GeometryToolbox::SquaredNorm(nDim, Velocity_e); + Velocity2_e = GeometryToolbox::SquaredNorm(nDim, Velocity_e); Energy_e = GetFluidModel()->GetStaticEnergy() + 0.5*Velocity2_e; break; @@ -5235,7 +5223,7 @@ void CEulerSolver::BC_Riemann(CGeometry *geometry, CSolver **solver_container, } /*--- Flow eigenvalues, boundary state u_e and u_i ---*/ - su2double Lambda_i[MAXNVAR] = {0}, u_e[MAXNVAR] = {0}, u_i[MAXNVAR]={0}, u_b[MAXNVAR]={0}, + su2double Lambda_i[MAXNVAR] = {0}, u_e[MAXNVAR] = {0}, u_i[MAXNVAR]={0}, u_b[MAXNVAR]={0}, dw[MAXNVAR]={0}; u_e[0] = Density_e; u_i[0] = Density_i; @@ -5302,7 +5290,7 @@ void CEulerSolver::BC_Riemann(CGeometry *geometry, CSolver **solver_container, LinSysRes.AddBlock(iPoint, Residual); if (implicit) { - su2double **Jacobian_b = new su2double*[nVar], + su2double **Jacobian_b = new su2double*[nVar], **Jacobian_i = new su2double*[nVar]; su2double **DubDu = new su2double*[nVar]; for (auto iVar = 0u; iVar < nVar; iVar++){ @@ -5333,7 +5321,7 @@ void CEulerSolver::BC_Riemann(CGeometry *geometry, CSolver **solver_container, if (dynamic_grid){ const auto gridVel = geometry->nodes->GetGridVel(iPoint); const auto projVelocity = GeometryToolbox::DotProduct(nDim, gridVel, Normal); - for (auto iVar = 0u; iVar < nVar; iVar++) + for (auto iVar = 0u; iVar < nVar; iVar++) Jacobian_b[iVar][iVar] -= projVelocity; } @@ -5394,7 +5382,7 @@ void CEulerSolver::BC_Riemann(CGeometry *geometry, CSolver **solver_container, visc_numerics->SetPrimVarGradient(nodes->GetGradient_Primitive(iPoint), nodes->GetGradient_Primitive(iPoint)); /*--- Secondary variables ---*/ - + auto S_domain = nodes->GetSecondary(iPoint); /*--- Compute secondary thermodynamic properties (partial derivatives...) ---*/ @@ -6407,13 +6395,7 @@ void CEulerSolver::BC_Giles(CGeometry *geometry, CSolver **solver_container, CNu Pressure_e /= config->GetPressure_Ref(); /* --- Compute avg characteristic jump --- */ - if (nDim == 2){ - c_avg[3] = -2.0*(AveragePressure[val_marker][iSpan]-Pressure_e); - } - else - { - c_avg[4] = -2.0*(AveragePressure[val_marker][iSpan]-Pressure_e); - } + c_avg[nDim + 1] = -2.0*(AveragePressure[val_marker][iSpan]-Pressure_e); break; case STATIC_PRESSURE_1D: @@ -6421,13 +6403,7 @@ void CEulerSolver::BC_Giles(CGeometry *geometry, CSolver **solver_container, CNu Pressure_e /= config->GetPressure_Ref(); /* --- Compute avg characteristic jump --- */ - if (nDim == 2){ - c_avg[3] = -2.0*(AveragePressure[val_marker][nSpanWiseSections]-Pressure_e); - } - else - { - c_avg[4] = -2.0*(AveragePressure[val_marker][nSpanWiseSections]-Pressure_e); - } + c_avg[nDim + 1] = -2.0*(AveragePressure[val_marker][nSpanWiseSections]-Pressure_e); break; case RADIAL_EQUILIBRIUM: @@ -6438,6 +6414,16 @@ void CEulerSolver::BC_Giles(CGeometry *geometry, CSolver **solver_container, CNu break; + case MASS_FLOW_OUTLET: + auto const MassFlowRate_e = config->GetGiles_Var1(Marker_Tag); + auto const relFacMassFlowRate = config->GetGiles_Var2(Marker_Tag); + + Pressure_e = AveragePressure[val_marker][nSpanWiseSections]+relFacMassFlowRate*GetFluidModel()->GetdPdrho_e()*(AverageMassFlowRate[val_marker]-MassFlowRate_e); + + /*--- Compute avg characteristic jump ---*/ + c_avg[nDim + 1] = -2.0*(AveragePressure[val_marker][iSpan]-Pressure_e); + break; + } /*--- Loop over all the vertices on this boundary marker ---*/ @@ -6609,7 +6595,7 @@ void CEulerSolver::BC_Giles(CGeometry *geometry, CSolver **solver_container, CNu break; - case STATIC_PRESSURE:case STATIC_PRESSURE_1D:case MIXING_OUT:case RADIAL_EQUILIBRIUM:case MIXING_OUT_1D: + case STATIC_PRESSURE:case STATIC_PRESSURE_1D:case MIXING_OUT:case RADIAL_EQUILIBRIUM:case MIXING_OUT_1D: case MASS_FLOW_OUTLET: /* --- implementation of Giles BC---*/ if(config->GetSpatialFourier()){ @@ -8795,9 +8781,9 @@ void CEulerSolver::PreprocessAverage(CSolver **solver, CGeometry *geometry, CCon const auto nSpanWiseSections = config->GetnSpanWiseSections(); const auto iZone = config->GetiZone(); - + for (auto iSpan= 0u; iSpan < nSpanWiseSections; iSpan++){ - su2double TotalAreaVelocity[MAXNDIM]={0.0}, + su2double TotalAreaVelocity[MAXNDIM]={0.0}, TotalAreaPressure{0}, TotalAreaDensity{0}; for (auto iMarker = 0u; iMarker < config->GetnMarker_All(); iMarker++){ @@ -8981,13 +8967,13 @@ void CEulerSolver::TurboAverageProcess(CSolver **solver, CGeometry *geometry, CC TotalMassPressure += Area*(Density*TurboVelocity[0] )*Pressure; TotalMassDensity += Area*(Density*TurboVelocity[0] )*Density; - + for (auto iDim = 0u; iDim < nDim; iDim++) { TotalVelocity[iDim] += Velocity[iDim]; TotalAreaVelocity[iDim] += Area*Velocity[iDim]; TotalMassVelocity[iDim] += Area*(Density*TurboVelocity[0] )*Velocity[iDim]; } - + TotalFluxes[0] += Area*(Density*TurboVelocity[0]); TotalFluxes[1] += Area*(Density*TurboVelocity[0]*TurboVelocity[0] + Pressure); for (auto iDim = 2; iDim < nDim+1; iDim++) @@ -9036,7 +9022,7 @@ void CEulerSolver::TurboAverageProcess(CSolver **solver, CGeometry *geometry, CC UpdateTotalQuantities(iMarker, jSpan, iVertex); } } - } + } } // marker_flag match } // iMarkerTP match @@ -9105,8 +9091,7 @@ void CEulerSolver::TurboAverageProcess(CSolver **solver, CGeometry *geometry, CC /*--- Compute the averaged value for the boundary of interest for the span of interest ---*/ const bool belowMachLimit = (abs(MachTest)< config->GetAverageMachLimit()); - su2double avgDensity{0}, avgPressure{0}, avgKine{0}, avgOmega{0}, avgNu{0}, - avgVelocity[MAXNDIM] = {0}; + su2double avgDensity{0}, avgPressure{0}, avgKine{0}, avgOmega{0}, avgNu{0}, avgVelocity[MAXNDIM] = {0}; for (auto iVar = 0u; iVarGetKind_Data_Giles(Marker_Tag) == RADIAL_EQUILIBRIUM){ RadialEquilibriumPressure[iMarker][nSpanWiseSections/2] = config->GetGiles_Var1(Marker_Tag)/config->GetPressure_Ref(); } - } + } for (auto iSpan= nSpanWiseSections/2; iSpan < nSpanWiseSections-1; iSpan++){ const auto Radius2 = geometry->GetTurboRadius(iMarker,iSpan+1); const auto Radius1 = geometry->GetTurboRadius(iMarker,iSpan); @@ -9325,9 +9314,9 @@ void CEulerSolver::MixedOut_Average(CConfig *config, su2double val_init_pressure su2double vel[MAXNDIM] = {0}; vel[0] = (val_Averaged_Flux[1] - pressure_mix) / val_Averaged_Flux[0]; - for (auto iDim = 1u; iDim < nDim; iDim++) + for (auto iDim = 1u; iDim < nDim; iDim++) vel[iDim] = val_Averaged_Flux[iDim+1] / val_Averaged_Flux[0]; - + const su2double velsq = GeometryToolbox::DotProduct(nDim, vel, vel); diff --git a/SU2_CFD/src/solvers/CFEASolver.cpp b/SU2_CFD/src/solvers/CFEASolver.cpp index f67a0199d01..fd142988bce 100644 --- a/SU2_CFD/src/solvers/CFEASolver.cpp +++ b/SU2_CFD/src/solvers/CFEASolver.cpp @@ -3116,8 +3116,8 @@ void CFEASolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *c /*--- MPI. If dynamic, we also need to communicate the old solution. ---*/ - InitiateComms(geometry[MESH_0], config, SOLUTION_FEA); - CompleteComms(geometry[MESH_0], config, SOLUTION_FEA); + InitiateComms(geometry[MESH_0], config, MPI_QUANTITIES::SOLUTION_FEA); + CompleteComms(geometry[MESH_0], config, MPI_QUANTITIES::SOLUTION_FEA); /*--- It's important to not push back the solution when this function is used to load solutions for * unsteady discrete adjoints, otherwise we overwrite one of the two solutions needed. ---*/ diff --git a/SU2_CFD/src/solvers/CFEM_DG_EulerSolver.cpp b/SU2_CFD/src/solvers/CFEM_DG_EulerSolver.cpp index f01ea90e7b1..73b04c709eb 100644 --- a/SU2_CFD/src/solvers/CFEM_DG_EulerSolver.cpp +++ b/SU2_CFD/src/solvers/CFEM_DG_EulerSolver.cpp @@ -7578,9 +7578,9 @@ void CFEM_DG_EulerSolver::BoundaryStates_Inlet(CConfig *config, /*--- Retrieve the specified total conditions for this inlet. ---*/ string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - su2double P_Total = config->GetInlet_Ptotal(Marker_Tag); - su2double T_Total = config->GetInlet_Ttotal(Marker_Tag); - auto Flow_Dir = config->GetInlet_FlowDir(Marker_Tag); + su2double P_Total = config->GetInletPtotal(Marker_Tag); + su2double T_Total = config->GetInletTtotal(Marker_Tag); + auto Flow_Dir = config->GetInletFlowDir(Marker_Tag); /*--- Non-dim. the inputs if necessary, and compute the total enthalpy. ---*/ P_Total /= config->GetPressure_Ref(); diff --git a/SU2_CFD/src/solvers/CGradientSmoothingSolver.cpp b/SU2_CFD/src/solvers/CGradientSmoothingSolver.cpp index 1f3a425aae6..47a624faada 100644 --- a/SU2_CFD/src/solvers/CGradientSmoothingSolver.cpp +++ b/SU2_CFD/src/solvers/CGradientSmoothingSolver.cpp @@ -287,8 +287,8 @@ void CGradientSmoothingSolver::ApplyGradientSmoothingDV(CGeometry* geometry, CNu /*--- Matrix vector product with the Laplace-Beltrami stiffness matrix. ---*/ if (config->GetSmoothOnSurface()) { - CSysMatrixComms::Initiate(helperVecIn, geometry, config, SOLUTION_MATRIX); - CSysMatrixComms::Complete(helperVecIn, geometry, config, SOLUTION_MATRIX); + CSysMatrixComms::Initiate(helperVecIn, geometry, config, MPI_QUANTITIES::SOLUTION_MATRIX); + CSysMatrixComms::Complete(helperVecIn, geometry, config, MPI_QUANTITIES::SOLUTION_MATRIX); mat_vec(helperVecIn, helperVecAux); @@ -306,8 +306,8 @@ void CGradientSmoothingSolver::ApplyGradientSmoothingDV(CGeometry* geometry, CNu grid_movement->SetVolume_Deformation(geometry, config, false, true, true); CGradientSmoothingSolverDetails::ReadVectorToGeometry(geometry, helperVecIn); - CSysMatrixComms::Initiate(helperVecIn, geometry, config, SOLUTION_MATRIX); - CSysMatrixComms::Complete(helperVecIn, geometry, config, SOLUTION_MATRIX); + CSysMatrixComms::Initiate(helperVecIn, geometry, config, MPI_QUANTITIES::SOLUTION_MATRIX); + CSysMatrixComms::Complete(helperVecIn, geometry, config, MPI_QUANTITIES::SOLUTION_MATRIX); mat_vec(helperVecIn, helperVecAux); diff --git a/SU2_CFD/src/solvers/CHeatSolver.cpp b/SU2_CFD/src/solvers/CHeatSolver.cpp index b01870e29bb..64ddb898e74 100644 --- a/SU2_CFD/src/solvers/CHeatSolver.cpp +++ b/SU2_CFD/src/solvers/CHeatSolver.cpp @@ -152,8 +152,8 @@ CHeatSolver::CHeatSolver(CGeometry *geometry, CConfig *config, unsigned short iM /*--- MPI solution ---*/ - InitiateComms(geometry, config, SOLUTION); - CompleteComms(geometry, config, SOLUTION); + InitiateComms(geometry, config, MPI_QUANTITIES::SOLUTION); + CompleteComms(geometry, config, MPI_QUANTITIES::SOLUTION); /*--- Store the initial CFL number for all grid points. ---*/ @@ -246,8 +246,8 @@ void CHeatSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig * on the fine level in order to have all necessary quantities updated, especially if this is a turbulent simulation (eddy viscosity). ---*/ - solver[MESH_0][HEAT_SOL]->InitiateComms(geometry[MESH_0], config, SOLUTION); - solver[MESH_0][HEAT_SOL]->CompleteComms(geometry[MESH_0], config, SOLUTION); + solver[MESH_0][HEAT_SOL]->InitiateComms(geometry[MESH_0], config, MPI_QUANTITIES::SOLUTION); + solver[MESH_0][HEAT_SOL]->CompleteComms(geometry[MESH_0], config, MPI_QUANTITIES::SOLUTION); solver[MESH_0][HEAT_SOL]->Preprocessing(geometry[MESH_0], solver[MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_HEAT_SYS, false); @@ -256,8 +256,8 @@ void CHeatSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig * for (auto iMesh = 1u; iMesh <= config->GetnMGLevels(); iMesh++) { MultigridRestriction(*geometry[iMesh - 1], solver[iMesh - 1][HEAT_SOL]->GetNodes()->GetSolution(), *geometry[iMesh], solver[iMesh][HEAT_SOL]->GetNodes()->GetSolution()); - solver[iMesh][HEAT_SOL]->InitiateComms(geometry[iMesh], config, SOLUTION); - solver[iMesh][HEAT_SOL]->CompleteComms(geometry[iMesh], config, SOLUTION); + solver[iMesh][HEAT_SOL]->InitiateComms(geometry[iMesh], config, MPI_QUANTITIES::SOLUTION); + solver[iMesh][HEAT_SOL]->CompleteComms(geometry[iMesh], config, MPI_QUANTITIES::SOLUTION); solver[iMesh][HEAT_SOL]->Preprocessing(geometry[iMesh], solver[iMesh], config, iMesh, NO_RK_ITER, RUNTIME_HEAT_SYS, false); } @@ -934,8 +934,8 @@ void CHeatSolver::SetInitialCondition(CGeometry **geometry, CSolver ***solver_co for (auto iMesh = 1u; iMesh <= config->GetnMGLevels(); iMesh++) { MultigridRestriction(*geometry[iMesh - 1], solver_container[iMesh - 1][HEAT_SOL]->GetNodes()->GetSolution(), *geometry[iMesh], solver_container[iMesh][HEAT_SOL]->GetNodes()->GetSolution()); - solver_container[iMesh][HEAT_SOL]->InitiateComms(geometry[iMesh], config, SOLUTION); - solver_container[iMesh][HEAT_SOL]->CompleteComms(geometry[iMesh], config, SOLUTION); + solver_container[iMesh][HEAT_SOL]->InitiateComms(geometry[iMesh], config, MPI_QUANTITIES::SOLUTION); + solver_container[iMesh][HEAT_SOL]->CompleteComms(geometry[iMesh], config, MPI_QUANTITIES::SOLUTION); } } diff --git a/SU2_CFD/src/solvers/CMeshSolver.cpp b/SU2_CFD/src/solvers/CMeshSolver.cpp index 39e17b322c8..e875dcab694 100644 --- a/SU2_CFD/src/solvers/CMeshSolver.cpp +++ b/SU2_CFD/src/solvers/CMeshSolver.cpp @@ -479,14 +479,14 @@ void CMeshSolver::DeformMesh(CGeometry **geometry, CNumerics **numerics, CConfig if (multizone) nodes->Set_BGSSolution_k(); /*--- Capture a few MPI dependencies for AD. ---*/ - geometry[MESH_0]->InitiateComms(geometry[MESH_0], config, COORDINATES); - geometry[MESH_0]->CompleteComms(geometry[MESH_0], config, COORDINATES); + geometry[MESH_0]->InitiateComms(geometry[MESH_0], config, MPI_QUANTITIES::COORDINATES); + geometry[MESH_0]->CompleteComms(geometry[MESH_0], config, MPI_QUANTITIES::COORDINATES); - InitiateComms(geometry[MESH_0], config, SOLUTION); - CompleteComms(geometry[MESH_0], config, SOLUTION); + InitiateComms(geometry[MESH_0], config, MPI_QUANTITIES::SOLUTION); + CompleteComms(geometry[MESH_0], config, MPI_QUANTITIES::SOLUTION); - InitiateComms(geometry[MESH_0], config, MESH_DISPLACEMENTS); - CompleteComms(geometry[MESH_0], config, MESH_DISPLACEMENTS); + InitiateComms(geometry[MESH_0], config, MPI_QUANTITIES::MESH_DISPLACEMENTS); + CompleteComms(geometry[MESH_0], config, MPI_QUANTITIES::MESH_DISPLACEMENTS); /*--- Compute the stiffness matrix, no point recording because we clear the residual. ---*/ @@ -562,8 +562,8 @@ void CMeshSolver::UpdateGridCoord(CGeometry *geometry, const CConfig *config){ END_SU2_OMP_FOR /*--- Communicate the updated displacements and mesh coordinates. ---*/ - geometry->InitiateComms(geometry, config, COORDINATES); - geometry->CompleteComms(geometry, config, COORDINATES); + geometry->InitiateComms(geometry, config, MPI_QUANTITIES::COORDINATES); + geometry->CompleteComms(geometry, config, MPI_QUANTITIES::COORDINATES); } @@ -818,8 +818,8 @@ void CMeshSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig * } /*--- Communicate the loaded displacements. ---*/ - solver[MESH_0][MESH_SOL]->InitiateComms(geometry[MESH_0], config, SOLUTION); - solver[MESH_0][MESH_SOL]->CompleteComms(geometry[MESH_0], config, SOLUTION); + solver[MESH_0][MESH_SOL]->InitiateComms(geometry[MESH_0], config, MPI_QUANTITIES::SOLUTION); + solver[MESH_0][MESH_SOL]->CompleteComms(geometry[MESH_0], config, MPI_QUANTITIES::SOLUTION); /*--- Init the linear system solution. ---*/ for (unsigned long iPoint = 0; iPoint < nPoint; ++iPoint) { @@ -880,7 +880,7 @@ void CMeshSolver::RestartOldGeometry(CGeometry *geometry, const CConfig *config) for(unsigned short iStep = 1; iStep <= nSteps; ++iStep) { - unsigned short CommType = (iStep == 1) ? SOLUTION_TIME_N : SOLUTION_TIME_N1; + MPI_QUANTITIES CommType = (iStep == 1) ? MPI_QUANTITIES::SOLUTION_TIME_N : MPI_QUANTITIES::SOLUTION_TIME_N1; /*--- Modify file name for an unsteady restart ---*/ int Unst_RestartIter; diff --git a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp index 0905ddeda32..776a3baaafd 100644 --- a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp @@ -1618,14 +1618,13 @@ void CNEMOEulerSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, Pressure, Density, Energy, Mach2, SoundSpeed2, SoundSpeed_Total2, Vel_Mag, alpha, aa, bb, cc, dd, Area, UnitNormal[3] = {0.0}; - const su2double *Flow_Dir; + su2double Flow_Dir[MAXNDIM] = {}; bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); bool dynamic_grid = config->GetGrid_Movement(); su2double Two_Gamma_M1 = 2.0/Gamma_Minus_One; su2double Gas_Constant = config->GetGas_ConstantND(); - INLET_TYPE Kind_Inlet = config->GetKind_Inlet(); - string Marker_Tag = config->GetMarker_All_TagBound(val_marker); + INLET_TYPE Kind_Inlet = config->GetKind_Inlet(); auto *U_domain = new su2double[nVar]; auto *U_inlet = new su2double[nVar]; auto *V_domain = new su2double[nPrimVar]; auto *V_inlet = new su2double[nPrimVar]; @@ -1659,6 +1658,10 @@ void CNEMOEulerSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, for (auto iVar = 0ul; iVar < nVar; iVar++) U_domain[iVar] = nodes->GetSolution(iPoint, iVar); for (auto iVar = 0ul; iVar < nPrimVar; iVar++) V_domain[iVar] = nodes->GetPrimitive(iPoint,iVar); + const su2double* dir = Inlet_FlowDir[val_marker][iVertex]; + const su2double mag = GeometryToolbox::Norm(nDim, dir); + for (auto iDim = 0ul; iDim < nDim; iDim++) Flow_Dir[iDim] = dir[iDim] / mag; + /*--- Build the fictitious intlet state based on characteristics ---*/ /*--- Subsonic inflow: there is one outgoing characteristic (u-c), @@ -1674,9 +1677,8 @@ void CNEMOEulerSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, case INLET_TYPE::TOTAL_CONDITIONS: /*--- Retrieve the specified total conditions for this inlet. ---*/ - P_Total = config->GetInlet_Ptotal(Marker_Tag); - T_Total = config->GetInlet_Ttotal(Marker_Tag); - Flow_Dir = config->GetInlet_FlowDir(Marker_Tag); + P_Total = Inlet_Ptotal[val_marker][iVertex]; + T_Total = Inlet_Ttotal[val_marker][iVertex]; /*--- Non-dim. the inputs if necessary. ---*/ P_Total /= config->GetPressure_Ref(); @@ -1773,13 +1775,12 @@ void CNEMOEulerSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, break; - /*--- Mass flow has been specified at the inlet. ---*/ + /*--- Mass flow has been specified at the inlet. ---*/ case INLET_TYPE::MASS_FLOW: /*--- Retrieve the specified mass flow for the inlet. ---*/ - Density = config->GetInlet_Ttotal(Marker_Tag); - Vel_Mag = config->GetInlet_Ptotal(Marker_Tag); - Flow_Dir = config->GetInlet_FlowDir(Marker_Tag); + Vel_Mag = Inlet_Ptotal[val_marker][iVertex]; + Density = Inlet_Ttotal[val_marker][iVertex]; /*--- Non-dim. the inputs if necessary. ---*/ Density /= config->GetDensity_Ref(); @@ -2354,7 +2355,7 @@ void CNEMOEulerSolver::SetPressureDiffusionSensor(CGeometry *geometry, CConfig * /*--- MPI parallelization ---*/ - InitiateComms(geometry, config, SENSOR); - CompleteComms(geometry, config, SENSOR); + InitiateComms(geometry, config, MPI_QUANTITIES::SENSOR); + CompleteComms(geometry, config, MPI_QUANTITIES::SENSOR); } diff --git a/SU2_CFD/src/solvers/CNEMONSSolver.cpp b/SU2_CFD/src/solvers/CNEMONSSolver.cpp index b6642b5cf8d..b30b99edebe 100644 --- a/SU2_CFD/src/solvers/CNEMONSSolver.cpp +++ b/SU2_CFD/src/solvers/CNEMONSSolver.cpp @@ -146,7 +146,7 @@ unsigned long CNEMONSSolver::SetPrimitive_Variables(CSolver **solver_container,C void CNEMONSSolver::SetPrimitive_Gradient_GG(CGeometry *geometry, const CConfig *config, bool reconstruction) { auto& gradient = reconstruction ? nodes->GetGradient_Reconstruction() : nodes->GetGradient_Primitive(); - const auto comm = reconstruction? PRIMITIVE_GRAD_REC : PRIMITIVE_GRADIENT; + const auto comm = reconstruction? MPI_QUANTITIES::PRIMITIVE_GRAD_REC : MPI_QUANTITIES::PRIMITIVE_GRADIENT; const auto commPer = reconstruction? PERIODIC_PRIM_GG_R : PERIODIC_PRIM_GG; /*--- Get indices of species & mixture density ---*/ diff --git a/SU2_CFD/src/solvers/CRadP1Solver.cpp b/SU2_CFD/src/solvers/CRadP1Solver.cpp index af40b22f2bc..d102e3b1d9a 100644 --- a/SU2_CFD/src/solvers/CRadP1Solver.cpp +++ b/SU2_CFD/src/solvers/CRadP1Solver.cpp @@ -553,8 +553,8 @@ void CRadP1Solver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver /*--- MPI solution ---*/ - InitiateComms(geometry, config, SOLUTION); - CompleteComms(geometry, config, SOLUTION); + InitiateComms(geometry, config, MPI_QUANTITIES::SOLUTION); + CompleteComms(geometry, config, MPI_QUANTITIES::SOLUTION); /*--- Compute the root mean square residual ---*/ diff --git a/SU2_CFD/src/solvers/CRadSolver.cpp b/SU2_CFD/src/solvers/CRadSolver.cpp index ca5becad7af..735983fa586 100644 --- a/SU2_CFD/src/solvers/CRadSolver.cpp +++ b/SU2_CFD/src/solvers/CRadSolver.cpp @@ -149,8 +149,8 @@ void CRadSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *c } /*--- MPI communication ---*/ - solver[MESH_0][RAD_SOL]->InitiateComms(geometry[MESH_0], config, SOLUTION); - solver[MESH_0][RAD_SOL]->CompleteComms(geometry[MESH_0], config, SOLUTION); + solver[MESH_0][RAD_SOL]->InitiateComms(geometry[MESH_0], config, MPI_QUANTITIES::SOLUTION); + solver[MESH_0][RAD_SOL]->CompleteComms(geometry[MESH_0], config, MPI_QUANTITIES::SOLUTION); /*--- Preprocess the fluid solver to compute the primitive variables ---*/ solver[MESH_0][FLOW_SOL]->Preprocessing(geometry[MESH_0], solver[MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); diff --git a/SU2_CFD/src/solvers/CSolver.cpp b/SU2_CFD/src/solvers/CSolver.cpp index 03c79b46fc3..b9d03fe3ee2 100644 --- a/SU2_CFD/src/solvers/CSolver.cpp +++ b/SU2_CFD/src/solvers/CSolver.cpp @@ -1322,60 +1322,60 @@ void CSolver::CompletePeriodicComms(CGeometry *geometry, } void CSolver::GetCommCountAndType(const CConfig* config, - unsigned short commType, + MPI_QUANTITIES commType, unsigned short &COUNT_PER_POINT, unsigned short &MPI_TYPE) const { switch (commType) { - case SOLUTION: - case SOLUTION_OLD: - case UNDIVIDED_LAPLACIAN: - case SOLUTION_LIMITER: + case MPI_QUANTITIES::SOLUTION: + case MPI_QUANTITIES::SOLUTION_OLD: + case MPI_QUANTITIES::UNDIVIDED_LAPLACIAN: + case MPI_QUANTITIES::SOLUTION_LIMITER: COUNT_PER_POINT = nVar; MPI_TYPE = COMM_TYPE_DOUBLE; break; - case MAX_EIGENVALUE: - case SENSOR: + case MPI_QUANTITIES::MAX_EIGENVALUE: + case MPI_QUANTITIES::SENSOR: COUNT_PER_POINT = 1; MPI_TYPE = COMM_TYPE_DOUBLE; break; - case SOLUTION_GRADIENT: - case SOLUTION_GRAD_REC: + case MPI_QUANTITIES::SOLUTION_GRADIENT: + case MPI_QUANTITIES::SOLUTION_GRAD_REC: COUNT_PER_POINT = nVar*nDim; MPI_TYPE = COMM_TYPE_DOUBLE; break; - case PRIMITIVE_GRADIENT: - case PRIMITIVE_GRAD_REC: + case MPI_QUANTITIES::PRIMITIVE_GRADIENT: + case MPI_QUANTITIES::PRIMITIVE_GRAD_REC: COUNT_PER_POINT = nPrimVarGrad*nDim; MPI_TYPE = COMM_TYPE_DOUBLE; break; - case PRIMITIVE_LIMITER: + case MPI_QUANTITIES::PRIMITIVE_LIMITER: COUNT_PER_POINT = nPrimVarGrad; MPI_TYPE = COMM_TYPE_DOUBLE; break; - case SOLUTION_EDDY: + case MPI_QUANTITIES::SOLUTION_EDDY: COUNT_PER_POINT = nVar+1; MPI_TYPE = COMM_TYPE_DOUBLE; break; - case SOLUTION_FEA: + case MPI_QUANTITIES::SOLUTION_FEA: if (config->GetTime_Domain()) COUNT_PER_POINT = nVar*3; else COUNT_PER_POINT = nVar; MPI_TYPE = COMM_TYPE_DOUBLE; break; - case AUXVAR_GRADIENT: + case MPI_QUANTITIES::AUXVAR_GRADIENT: COUNT_PER_POINT = nDim*base_nodes->GetnAuxVar(); MPI_TYPE = COMM_TYPE_DOUBLE; break; - case MESH_DISPLACEMENTS: + case MPI_QUANTITIES::MESH_DISPLACEMENTS: COUNT_PER_POINT = nDim; MPI_TYPE = COMM_TYPE_DOUBLE; break; - case SOLUTION_TIME_N: + case MPI_QUANTITIES::SOLUTION_TIME_N: COUNT_PER_POINT = nVar; MPI_TYPE = COMM_TYPE_DOUBLE; break; - case SOLUTION_TIME_N1: + case MPI_QUANTITIES::SOLUTION_TIME_N1: COUNT_PER_POINT = nVar; MPI_TYPE = COMM_TYPE_DOUBLE; break; @@ -1387,25 +1387,25 @@ void CSolver::GetCommCountAndType(const CConfig* config, } namespace CommHelpers { - CVectorOfMatrix& selectGradient(CVariable* nodes, unsigned short commType) { + CVectorOfMatrix& selectGradient(CVariable* nodes, MPI_QUANTITIES commType) { switch(commType) { - case SOLUTION_GRAD_REC: return nodes->GetGradient_Reconstruction(); - case PRIMITIVE_GRADIENT: return nodes->GetGradient_Primitive(); - case PRIMITIVE_GRAD_REC: return nodes->GetGradient_Reconstruction(); - case AUXVAR_GRADIENT: return nodes->GetAuxVarGradient(); + case MPI_QUANTITIES::SOLUTION_GRAD_REC: return nodes->GetGradient_Reconstruction(); + case MPI_QUANTITIES::PRIMITIVE_GRADIENT: return nodes->GetGradient_Primitive(); + case MPI_QUANTITIES::PRIMITIVE_GRAD_REC: return nodes->GetGradient_Reconstruction(); + case MPI_QUANTITIES::AUXVAR_GRADIENT: return nodes->GetAuxVarGradient(); default: return nodes->GetGradient(); } } - su2activematrix& selectLimiter(CVariable* nodes, unsigned short commType) { - if (commType == PRIMITIVE_LIMITER) return nodes->GetLimiter_Primitive(); + su2activematrix& selectLimiter(CVariable* nodes, MPI_QUANTITIES commType) { + if (commType == MPI_QUANTITIES::PRIMITIVE_LIMITER) return nodes->GetLimiter_Primitive(); return nodes->GetLimiter(); } } void CSolver::InitiateComms(CGeometry *geometry, const CConfig *config, - unsigned short commType) { + MPI_QUANTITIES commType) { /*--- Local variables ---*/ @@ -1470,44 +1470,44 @@ void CSolver::InitiateComms(CGeometry *geometry, buf_offset = (msg_offset + iSend)*COUNT_PER_POINT; switch (commType) { - case SOLUTION: + case MPI_QUANTITIES::SOLUTION: for (iVar = 0; iVar < nVar; iVar++) bufDSend[buf_offset+iVar] = base_nodes->GetSolution(iPoint, iVar); break; - case SOLUTION_OLD: + case MPI_QUANTITIES::SOLUTION_OLD: for (iVar = 0; iVar < nVar; iVar++) bufDSend[buf_offset+iVar] = base_nodes->GetSolution_Old(iPoint, iVar); break; - case SOLUTION_EDDY: + case MPI_QUANTITIES::SOLUTION_EDDY: for (iVar = 0; iVar < nVar; iVar++) bufDSend[buf_offset+iVar] = base_nodes->GetSolution(iPoint, iVar); bufDSend[buf_offset+nVar] = base_nodes->GetmuT(iPoint); break; - case UNDIVIDED_LAPLACIAN: + case MPI_QUANTITIES::UNDIVIDED_LAPLACIAN: for (iVar = 0; iVar < nVar; iVar++) bufDSend[buf_offset+iVar] = base_nodes->GetUndivided_Laplacian(iPoint, iVar); break; - case SOLUTION_LIMITER: - case PRIMITIVE_LIMITER: + case MPI_QUANTITIES::SOLUTION_LIMITER: + case MPI_QUANTITIES::PRIMITIVE_LIMITER: for (iVar = 0; iVar < COUNT_PER_POINT; iVar++) bufDSend[buf_offset+iVar] = limiter(iPoint, iVar); break; - case MAX_EIGENVALUE: + case MPI_QUANTITIES::MAX_EIGENVALUE: bufDSend[buf_offset] = base_nodes->GetLambda(iPoint); break; - case SENSOR: + case MPI_QUANTITIES::SENSOR: bufDSend[buf_offset] = base_nodes->GetSensor(iPoint); break; - case SOLUTION_GRADIENT: - case PRIMITIVE_GRADIENT: - case SOLUTION_GRAD_REC: - case PRIMITIVE_GRAD_REC: - case AUXVAR_GRADIENT: + case MPI_QUANTITIES::SOLUTION_GRADIENT: + case MPI_QUANTITIES::PRIMITIVE_GRADIENT: + case MPI_QUANTITIES::SOLUTION_GRAD_REC: + case MPI_QUANTITIES::PRIMITIVE_GRAD_REC: + case MPI_QUANTITIES::AUXVAR_GRADIENT: for (iVar = 0; iVar < nVarGrad; iVar++) for (iDim = 0; iDim < nDim; iDim++) bufDSend[buf_offset+iVar*nDim+iDim] = gradient(iPoint, iVar, iDim); break; - case SOLUTION_FEA: + case MPI_QUANTITIES::SOLUTION_FEA: for (iVar = 0; iVar < nVar; iVar++) { bufDSend[buf_offset+iVar] = base_nodes->GetSolution(iPoint, iVar); if (config->GetTime_Domain()) { @@ -1516,15 +1516,15 @@ void CSolver::InitiateComms(CGeometry *geometry, } } break; - case MESH_DISPLACEMENTS: + case MPI_QUANTITIES::MESH_DISPLACEMENTS: for (iDim = 0; iDim < nDim; iDim++) bufDSend[buf_offset+iDim] = base_nodes->GetBound_Disp(iPoint, iDim); break; - case SOLUTION_TIME_N: + case MPI_QUANTITIES::SOLUTION_TIME_N: for (iVar = 0; iVar < nVar; iVar++) bufDSend[buf_offset+iVar] = base_nodes->GetSolution_time_n(iPoint, iVar); break; - case SOLUTION_TIME_N1: + case MPI_QUANTITIES::SOLUTION_TIME_N1: for (iVar = 0; iVar < nVar; iVar++) bufDSend[buf_offset+iVar] = base_nodes->GetSolution_time_n1(iPoint, iVar); break; @@ -1547,7 +1547,7 @@ void CSolver::InitiateComms(CGeometry *geometry, void CSolver::CompleteComms(CGeometry *geometry, const CConfig *config, - unsigned short commType) { + MPI_QUANTITIES commType) { /*--- Local variables ---*/ @@ -1618,44 +1618,44 @@ void CSolver::CompleteComms(CGeometry *geometry, /*--- Store the data correctly depending on the quantity. ---*/ switch (commType) { - case SOLUTION: + case MPI_QUANTITIES::SOLUTION: for (iVar = 0; iVar < nVar; iVar++) base_nodes->SetSolution(iPoint, iVar, bufDRecv[buf_offset+iVar]); break; - case SOLUTION_OLD: + case MPI_QUANTITIES::SOLUTION_OLD: for (iVar = 0; iVar < nVar; iVar++) base_nodes->SetSolution_Old(iPoint, iVar, bufDRecv[buf_offset+iVar]); break; - case SOLUTION_EDDY: + case MPI_QUANTITIES::SOLUTION_EDDY: for (iVar = 0; iVar < nVar; iVar++) base_nodes->SetSolution(iPoint, iVar, bufDRecv[buf_offset+iVar]); base_nodes->SetmuT(iPoint,bufDRecv[buf_offset+nVar]); break; - case UNDIVIDED_LAPLACIAN: + case MPI_QUANTITIES::UNDIVIDED_LAPLACIAN: for (iVar = 0; iVar < nVar; iVar++) base_nodes->SetUnd_Lapl(iPoint, iVar, bufDRecv[buf_offset+iVar]); break; - case SOLUTION_LIMITER: - case PRIMITIVE_LIMITER: + case MPI_QUANTITIES::SOLUTION_LIMITER: + case MPI_QUANTITIES::PRIMITIVE_LIMITER: for (iVar = 0; iVar < COUNT_PER_POINT; iVar++) limiter(iPoint,iVar) = bufDRecv[buf_offset+iVar]; break; - case MAX_EIGENVALUE: + case MPI_QUANTITIES::MAX_EIGENVALUE: base_nodes->SetLambda(iPoint,bufDRecv[buf_offset]); break; - case SENSOR: + case MPI_QUANTITIES::SENSOR: base_nodes->SetSensor(iPoint,bufDRecv[buf_offset]); break; - case SOLUTION_GRADIENT: - case PRIMITIVE_GRADIENT: - case SOLUTION_GRAD_REC: - case PRIMITIVE_GRAD_REC: - case AUXVAR_GRADIENT: + case MPI_QUANTITIES::SOLUTION_GRADIENT: + case MPI_QUANTITIES::PRIMITIVE_GRADIENT: + case MPI_QUANTITIES::SOLUTION_GRAD_REC: + case MPI_QUANTITIES::PRIMITIVE_GRAD_REC: + case MPI_QUANTITIES::AUXVAR_GRADIENT: for (iVar = 0; iVar < nVarGrad; iVar++) for (iDim = 0; iDim < nDim; iDim++) gradient(iPoint,iVar,iDim) = bufDRecv[buf_offset+iVar*nDim+iDim]; break; - case SOLUTION_FEA: + case MPI_QUANTITIES::SOLUTION_FEA: for (iVar = 0; iVar < nVar; iVar++) { base_nodes->SetSolution(iPoint, iVar, bufDRecv[buf_offset+iVar]); if (config->GetTime_Domain()) { @@ -1664,15 +1664,15 @@ void CSolver::CompleteComms(CGeometry *geometry, } } break; - case MESH_DISPLACEMENTS: + case MPI_QUANTITIES::MESH_DISPLACEMENTS: for (iDim = 0; iDim < nDim; iDim++) base_nodes->SetBound_Disp(iPoint, iDim, bufDRecv[buf_offset+iDim]); break; - case SOLUTION_TIME_N: + case MPI_QUANTITIES::SOLUTION_TIME_N: for (iVar = 0; iVar < nVar; iVar++) base_nodes->Set_Solution_time_n(iPoint, iVar, bufDRecv[buf_offset+iVar]); break; - case SOLUTION_TIME_N1: + case MPI_QUANTITIES::SOLUTION_TIME_N1: for (iVar = 0; iVar < nVar; iVar++) base_nodes->Set_Solution_time_n1(iPoint, iVar, bufDRecv[buf_offset+iVar]); break; @@ -1821,6 +1821,7 @@ void CSolver::AdaptCFLNumber(CGeometry **geometry, /* Loop over all points on this grid and apply CFL adaption. */ su2double myCFLMin = 1e30, myCFLMax = 0.0, myCFLSum = 0.0; + const su2double CFLTurbReduction = config->GetCFLRedCoeff_Turb(); SU2_OMP_MASTER if ((iMesh == MESH_0) && fullComms) { @@ -1885,7 +1886,7 @@ void CSolver::AdaptCFLNumber(CGeometry **geometry, CFL *= CFLFactor; solverFlow->GetNodes()->SetLocalCFL(iPoint, CFL); if ((iMesh == MESH_0) && solverTurb) { - solverTurb->GetNodes()->SetLocalCFL(iPoint, CFL); + solverTurb->GetNodes()->SetLocalCFL(iPoint, CFL * CFLTurbReduction); } /* Store min and max CFL for reporting on the fine grid. */ @@ -2095,7 +2096,7 @@ void CSolver::SetAuxVar_Gradient_GG(CGeometry *geometry, const CConfig *config) const auto& solution = base_nodes->GetAuxVar(); auto& gradient = base_nodes->GetAuxVarGradient(); - computeGradientsGreenGauss(this, AUXVAR_GRADIENT, PERIODIC_NONE, *geometry, + computeGradientsGreenGauss(this, MPI_QUANTITIES::AUXVAR_GRADIENT, PERIODIC_NONE, *geometry, *config, solution, 0, base_nodes->GetnAuxVar(), gradient); } @@ -2106,7 +2107,7 @@ void CSolver::SetAuxVar_Gradient_LS(CGeometry *geometry, const CConfig *config) auto& gradient = base_nodes->GetAuxVarGradient(); auto& rmatrix = base_nodes->GetRmatrix(); - computeGradientsLeastSquares(this, AUXVAR_GRADIENT, PERIODIC_NONE, *geometry, *config, + computeGradientsLeastSquares(this, MPI_QUANTITIES::AUXVAR_GRADIENT, PERIODIC_NONE, *geometry, *config, weighted, solution, 0, base_nodes->GetnAuxVar(), gradient, rmatrix); } @@ -2114,7 +2115,7 @@ void CSolver::SetSolution_Gradient_GG(CGeometry *geometry, const CConfig *config const auto& solution = base_nodes->GetSolution(); auto& gradient = reconstruction? base_nodes->GetGradient_Reconstruction() : base_nodes->GetGradient(); - const auto comm = reconstruction? SOLUTION_GRAD_REC : SOLUTION_GRADIENT; + const auto comm = reconstruction? MPI_QUANTITIES::SOLUTION_GRAD_REC : MPI_QUANTITIES::SOLUTION_GRADIENT; const auto commPer = reconstruction? PERIODIC_SOL_GG_R : PERIODIC_SOL_GG; computeGradientsGreenGauss(this, comm, commPer, *geometry, *config, solution, 0, nVar, gradient); @@ -2138,7 +2139,7 @@ void CSolver::SetSolution_Gradient_LS(CGeometry *geometry, const CConfig *config const auto& solution = base_nodes->GetSolution(); auto& rmatrix = base_nodes->GetRmatrix(); auto& gradient = reconstruction? base_nodes->GetGradient_Reconstruction() : base_nodes->GetGradient(); - const auto comm = reconstruction? SOLUTION_GRAD_REC : SOLUTION_GRADIENT; + const auto comm = reconstruction? MPI_QUANTITIES::SOLUTION_GRAD_REC : MPI_QUANTITIES::SOLUTION_GRADIENT; computeGradientsLeastSquares(this, comm, commPer, *geometry, *config, weighted, solution, 0, nVar, gradient, rmatrix); } @@ -2183,8 +2184,8 @@ void CSolver::SetUndivided_Laplacian(CGeometry *geometry, const CConfig *config) /*--- MPI parallelization ---*/ - InitiateComms(geometry, config, UNDIVIDED_LAPLACIAN); - CompleteComms(geometry, config, UNDIVIDED_LAPLACIAN); + InitiateComms(geometry, config, MPI_QUANTITIES::UNDIVIDED_LAPLACIAN); + CompleteComms(geometry, config, MPI_QUANTITIES::UNDIVIDED_LAPLACIAN); } @@ -2238,7 +2239,7 @@ void CSolver::SetGridVel_Gradient(CGeometry *geometry, const CConfig *config) co auto& gridVelGrad = geometry->nodes->GetGridVel_Grad(); auto rmatrix = CVectorOfMatrix(nPoint,nDim,nDim); - computeGradientsLeastSquares(nullptr, GRID_VELOCITY, PERIODIC_NONE, *geometry, *config, + computeGradientsLeastSquares(nullptr, MPI_QUANTITIES::GRID_VELOCITY, PERIODIC_NONE, *geometry, *config, true, gridVel, 0, nDim, gridVelGrad, rmatrix); } @@ -2251,7 +2252,7 @@ void CSolver::SetSolution_Limiter(CGeometry *geometry, const CConfig *config) { auto& solMax = base_nodes->GetSolution_Max(); auto& limiter = base_nodes->GetLimiter(); - computeLimiters(kindLimiter, this, SOLUTION_LIMITER, PERIODIC_LIM_SOL_1, PERIODIC_LIM_SOL_2, + computeLimiters(kindLimiter, this, MPI_QUANTITIES::SOLUTION_LIMITER, PERIODIC_LIM_SOL_1, PERIODIC_LIM_SOL_2, *geometry, *config, 0, nVar, solution, gradient, solMin, solMax, limiter); } @@ -2723,8 +2724,8 @@ void CSolver::Restart_OldGeometry(CGeometry *geometry, CConfig *config) const { /*--- It's necessary to communicate this information ---*/ - geometry->InitiateComms(geometry, config, COORDINATES_OLD); - geometry->CompleteComms(geometry, config, COORDINATES_OLD); + geometry->InitiateComms(geometry, config, MPI_QUANTITIES::COORDINATES_OLD); + geometry->CompleteComms(geometry, config, MPI_QUANTITIES::COORDINATES_OLD); } @@ -3589,9 +3590,9 @@ void CSolver::LoadInletProfile(CGeometry **geometry, if (config->GetMarker_All_KindBC(iMarker) != KIND_MARKER) continue; string Marker_Tag = config->GetMarker_All_TagBound(iMarker); - su2double p_total = config->GetInlet_Ptotal(Marker_Tag); - su2double t_total = config->GetInlet_Ttotal(Marker_Tag); - auto flow_dir = config->GetInlet_FlowDir(Marker_Tag); + su2double p_total = config->GetInletPtotal(Marker_Tag); + su2double t_total = config->GetInletTtotal(Marker_Tag); + auto flow_dir = config->GetInletFlowDir(Marker_Tag); std::stringstream columnName,columnValue; columnValue << setprecision(15); diff --git a/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp b/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp index 66b90d3e39b..d41818a5bde 100644 --- a/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp +++ b/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp @@ -68,9 +68,19 @@ void CSpeciesFlameletSolver::Preprocessing(CGeometry* geometry, CSolver** solver unsigned short RunTime_EqSystem, bool Output) { unsigned long n_not_in_domain_local = 0, n_not_in_domain_global = 0; vector scalars_vector(nVar); - + unsigned long spark_iter_start, spark_duration; + bool ignition = false; auto* flowNodes = su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()); + /*--- Retrieve spark ignition parameters for spark-type ignition. ---*/ + if ((config->GetFlameletInitType() == FLAMELET_INIT_TYPE::SPARK) && !config->GetRestart()) { + auto spark_init = config->GetFlameInit(); + spark_iter_start = ceil(spark_init[4]); + spark_duration = ceil(spark_init[5]); + unsigned long iter = config->GetMultizone_Problem() ? config->GetOuterIter() : config->GetInnerIter(); + ignition = ((iter >= spark_iter_start) && (iter <= (spark_iter_start + spark_duration)) && !config->GetRestart()); + } + SU2_OMP_SAFE_GLOBAL_ACCESS(config->SetGlobalParam(config->GetKind_Solver(), RunTime_EqSystem);) SU2_OMP_FOR_STAT(omp_chunk_size) @@ -81,19 +91,35 @@ void CSpeciesFlameletSolver::Preprocessing(CGeometry* geometry, CSolver** solver /*--- Compute total source terms from the production and consumption. ---*/ unsigned long misses = SetScalarSources(config, fluid_model_local, i_point, scalars_vector); + + if (ignition) { + /*--- Apply source terms within spark radius. ---*/ + su2double dist_from_center = 0, + spark_radius = config->GetFlameInit()[3]; + dist_from_center = GeometryToolbox::SquaredDistance(nDim, geometry->nodes->GetCoord(i_point), config->GetFlameInit()); + if (dist_from_center < pow(spark_radius,2)) { + for (auto iVar = 0u; iVar < nVar; iVar++) + nodes->SetScalarSource(i_point, iVar, nodes->GetScalarSources(i_point)[iVar] + config->GetSpark()[iVar]); + } + } + nodes->SetTableMisses(i_point, misses); n_not_in_domain_local += misses; /*--- Obtain passive look-up scalars. ---*/ SetScalarLookUps(config, fluid_model_local, i_point, scalars_vector); /*--- Set mass diffusivity based on thermodynamic state. ---*/ - su2double T = flowNodes->GetTemperature(i_point); + auto T = flowNodes->GetTemperature(i_point); fluid_model_local->SetTDState_T(T, scalars); /*--- set the diffusivity in the fluid model to the diffusivity obtained from the lookup table ---*/ for (auto i_scalar = 0u; i_scalar < nVar; ++i_scalar) { nodes->SetDiffusivity(i_point, fluid_model_local->GetMassDiffusivity(i_scalar), i_scalar); } + /*--- Obtain preferential diffusion scalar values. ---*/ + if (config->GetPreferentialDiffusion()) + SetPreferentialDiffusionScalars(config, fluid_model_local, i_point, scalars_vector); + if (!Output) LinSysRes.SetBlock_Zero(i_point); } END_SU2_OMP_FOR @@ -102,6 +128,20 @@ void CSpeciesFlameletSolver::Preprocessing(CGeometry* geometry, CSolver** solver SU2_MPI::GetComm()); if ((rank == MASTER_NODE) && (n_not_in_domain_global > 0)) cout << "Number of points outside manifold domain: " << n_not_in_domain_global << endl; + + /*--- Compute preferential diffusion scalar gradients. ---*/ + if (config->GetPreferentialDiffusion()) { + switch (config->GetKind_Gradient_Method()) { + case GREEN_GAUSS: + SetAuxVar_Gradient_GG(geometry, config); + break; + case WEIGHTED_LEAST_SQUARES: + SetAuxVar_Gradient_LS(geometry, config); + break; + default: + break; + } + } /*--- Clear Residual and Jacobian. Upwind second order reconstruction and gradients ---*/ CommonPreprocessing(geometry, config, Output); } @@ -115,13 +155,22 @@ void CSpeciesFlameletSolver::SetInitialCondition(CGeometry** geometry, CSolver** cout << "Initializing progress variable and total enthalpy (using temperature)" << endl; } - const su2double* flame_init = config->GetFlameInit(); - const su2double flame_offset[3] = {flame_init[0], flame_init[1], flame_init[2]}; - const su2double flame_normal[3] = {flame_init[3], flame_init[4], flame_init[5]}; - const su2double flame_thickness = flame_init[6]; - const su2double flame_burnt_thickness = flame_init[7]; + 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 = (config->GetFlameletInitType() == FLAMELET_INIT_TYPE::FLAME_FRONT); + + if (flame_front_ignition) { + /*--- Collect flame front ignition parameters. ---*/ + auto flame_init = config->GetFlameInit(); + for (auto iDim = 0u; iDim < 3; ++iDim) { + flame_offset[iDim] = flame_init[iDim]; + flame_normal[iDim] = flame_init[3 + iDim]; + } + flame_thickness = flame_init[6]; + flame_burnt_thickness = flame_init[7]; + flamenorm = GeometryToolbox::Norm(nDim, flame_normal); + } - const su2double flamenorm = GeometryToolbox::Norm(nDim, flame_normal); const su2double temp_inlet = config->GetInc_Temperature_Init(); su2double enth_inlet = config->GetSpecies_Init()[I_ENTH]; @@ -134,6 +183,19 @@ void CSpeciesFlameletSolver::SetInitialCondition(CGeometry** geometry, CSolver** const auto& cv_name = config->GetControllingVariableName(iCV); cout << "initial condition: " << cv_name << " = " << config->GetSpecies_Init()[iCV] << endl; } + switch (config->GetFlameletInitType()) { + case FLAMELET_INIT_TYPE::FLAME_FRONT: + cout << "Ignition with a straight flame front" << endl; + break; + case FLAMELET_INIT_TYPE::SPARK: + cout << "Ignition with an artificial spark" << endl; + break; + case FLAMELET_INIT_TYPE::NONE: + cout << "No solution ignition (cold flow)" << endl; + break; + default: + break; + } } CFluidModel* fluid_model_local; @@ -157,37 +219,40 @@ void CSpeciesFlameletSolver::SetInitialCondition(CGeometry** geometry, CSolver** for (unsigned long i_point = 0; i_point < nPoint; i_point++) { auto coords = geometry[i_mesh]->nodes->GetCoord(i_point); - /*--- Determine if point is above or below the plane, assuming the normal - is pointing towards the burned region. ---*/ - point_loc = 0.0; - for (unsigned short i_dim = 0; i_dim < geometry[i_mesh]->GetnDim(); i_dim++) { - point_loc += flame_normal[i_dim] * (coords[i_dim] - flame_offset[i_dim]); - } - - /*--- Compute the exact distance from point to plane. ---*/ - point_loc = point_loc / flamenorm; - - /* --- Unburnt region upstream of the flame. --- */ - if (point_loc <= 0) { - scalar_init[I_PROGVAR] = prog_unburnt; - n_points_unburnt_local++; - - /* --- Flame zone where we lineary increase from unburnt to burnt conditions. --- */ - } else if ((point_loc > 0) && (point_loc <= flame_thickness)) { - scalar_init[I_PROGVAR] = prog_unburnt + point_loc * (prog_burnt - prog_unburnt) / flame_thickness; - n_points_flame_local++; - - /* --- Burnt region behind the flame zone. --- */ - } else if ((point_loc > flame_thickness) && (point_loc <= flame_thickness + flame_burnt_thickness)) { - scalar_init[I_PROGVAR] = prog_burnt; - n_points_burnt_local++; - - /* --- Unburnt region downstream of the flame and burnt region. --- */ + if (flame_front_ignition) { + /*--- Determine if point is above or below the plane, assuming the normal + is pointing towards the burned region. ---*/ + point_loc = 0.0; + for (unsigned short i_dim = 0; i_dim < geometry[i_mesh]->GetnDim(); i_dim++) { + point_loc += flame_normal[i_dim] * (coords[i_dim] - flame_offset[i_dim]); + } + + /*--- Compute the exact distance from point to plane. ---*/ + point_loc = point_loc / flamenorm; + + /* --- Unburnt region upstream of the flame. --- */ + if (point_loc <= 0) { + scalar_init[I_PROGVAR] = prog_unburnt; + n_points_unburnt_local++; + + /* --- Flame zone where we lineary increase from unburnt to burnt conditions. --- */ + } else if ((point_loc > 0) && (point_loc <= flame_thickness)) { + scalar_init[I_PROGVAR] = prog_unburnt + point_loc * (prog_burnt - prog_unburnt) / flame_thickness; + n_points_flame_local++; + + /* --- Burnt region behind the flame zone. --- */ + } else if ((point_loc > flame_thickness) && (point_loc <= flame_thickness + flame_burnt_thickness)) { + scalar_init[I_PROGVAR] = prog_burnt; + n_points_burnt_local++; + + /* --- Unburnt region downstream of the flame and burnt region. --- */ + } else { + scalar_init[I_PROGVAR] = prog_unburnt; + n_points_unburnt_local++; + } } else { scalar_init[I_PROGVAR] = prog_unburnt; - n_points_unburnt_local++; } - /* --- Perform manifold evaluation to check whether initial scalar is out-of-bounds. --- */ fluid_model_local->SetTDState_T(temp_inlet, scalar_init); n_not_in_domain_local += fluid_model_local->GetExtrapolation(); @@ -200,11 +265,11 @@ void CSpeciesFlameletSolver::SetInitialCondition(CGeometry** geometry, CSolver** solver_container[i_mesh][SPECIES_SOL]->GetNodes()->SetSolution(i_point, scalar_init); } - solver_container[i_mesh][SPECIES_SOL]->InitiateComms(geometry[i_mesh], config, SOLUTION); - solver_container[i_mesh][SPECIES_SOL]->CompleteComms(geometry[i_mesh], config, SOLUTION); + 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); - solver_container[i_mesh][FLOW_SOL]->InitiateComms(geometry[i_mesh], config, SOLUTION); - solver_container[i_mesh][FLOW_SOL]->CompleteComms(geometry[i_mesh], config, SOLUTION); + solver_container[i_mesh][FLOW_SOL]->InitiateComms(geometry[i_mesh], config, MPI_QUANTITIES::SOLUTION); + solver_container[i_mesh][FLOW_SOL]->CompleteComms(geometry[i_mesh], config, MPI_QUANTITIES::SOLUTION); solver_container[i_mesh][FLOW_SOL]->Preprocessing(geometry[i_mesh], solver_container[i_mesh], config, i_mesh, NO_RK_ITER, RUNTIME_FLOW_SYS, false); @@ -225,9 +290,11 @@ void CSpeciesFlameletSolver::SetInitialCondition(CGeometry** geometry, CSolver** if (rank == MASTER_NODE) { cout << endl; - cout << " Number of points in unburnt region: " << n_points_unburnt_global << "." << endl; - cout << " Number of points in burnt region : " << n_points_burnt_global << "." << endl; - cout << " Number of points in flame zone : " << n_points_flame_global << "." << endl; + if (flame_front_ignition) { + cout << " Number of points in unburnt region: " << n_points_unburnt_global << "." << endl; + cout << " Number of points in burnt region : " << n_points_burnt_global << "." << endl; + cout << " Number of points in flame zone : " << n_points_flame_global << "." << endl; + } if (n_not_in_domain_global > 0) cout << " Initial condition: Number of points outside of table domain: " << n_not_in_domain_global << " !!!" @@ -321,7 +388,7 @@ void CSpeciesFlameletSolver::BC_Inlet(CGeometry* geometry, CSolver** solver_cont CNumerics* visc_numerics, CConfig* config, unsigned short val_marker) { string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - su2double temp_inlet = config->GetInlet_Ttotal(Marker_Tag); + su2double temp_inlet = config->GetInletTtotal(Marker_Tag); /*--- We compute inlet enthalpy from the temperature and progress variable. ---*/ su2double enth_inlet; @@ -331,8 +398,8 @@ void CSpeciesFlameletSolver::BC_Inlet(CGeometry* geometry, CSolver** solver_cont SU2_OMP_FOR_STAT(OMP_MIN_SIZE) for (auto iVertex = 0u; iVertex < geometry->nVertex[val_marker]; iVertex++) { Inlet_SpeciesVars[val_marker][iVertex][I_ENTH] = enth_inlet; - END_SU2_OMP_FOR } + END_SU2_OMP_FOR /*--- Call the general inlet boundary condition implementation. ---*/ CSpeciesSolver::BC_Inlet(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); @@ -343,10 +410,8 @@ void CSpeciesFlameletSolver::BC_Isothermal_Wall_Generic(CGeometry* geometry, CSo CConfig* config, unsigned short val_marker, bool cht_mode) { const bool implicit = config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT; const string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - su2double temp_wall; CFluidModel* fluid_model_local = solver_container[FLOW_SOL]->GetFluidModel(); auto* flowNodes = su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()); - su2double enth_wall; unsigned long n_not_iterated = 0; /*--- Loop over all the vertices on this boundary marker. ---*/ @@ -354,6 +419,7 @@ void CSpeciesFlameletSolver::BC_Isothermal_Wall_Generic(CGeometry* geometry, CSo for (unsigned long iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { unsigned long iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); + su2double temp_wall, enth_wall; if (cht_mode) temp_wall = solver_container[FLOW_SOL]->GetConjugateHeatVariable(val_marker, iVertex, 0); else @@ -402,7 +468,7 @@ void CSpeciesFlameletSolver::BC_Isothermal_Wall_Generic(CGeometry* geometry, CSo su2double dist_ij = sqrt(dist_ij_2); /*--- Compute the normal gradient in temperature using Twall. ---*/ - + ///TODO: Account for preferential diffusion in computation of the heat flux su2double dTdn = -(flowNodes->GetTemperature(Point_Normal) - temp_wall) / dist_ij; /*--- Get thermal conductivity. ---*/ @@ -442,13 +508,13 @@ unsigned long CSpeciesFlameletSolver::SetScalarSources(const CConfig* config, CF vector table_sources(config->GetNControlVars() + 2 * config->GetNUserScalars()); unsigned long misses = fluid_model_local->EvaluateDataSet(scalars, FLAMELET_LOOKUP_OPS::SOURCES, table_sources); + table_sources[I_PROGVAR] = fmax(0, table_sources[I_PROGVAR]); nodes->SetTableMisses(iPoint, misses); /*--- The source term for progress variable is always positive, we clip from below to makes sure. --- */ vector source_scalar(config->GetNScalars()); for (auto iCV = 0u; iCV < config->GetNControlVars(); iCV++) source_scalar[iCV] = table_sources[iCV]; - source_scalar[I_PROGVAR] = fmax(EPS, source_scalar[I_PROGVAR]); /*--- Source term for the auxiliary species transport equations. ---*/ for (size_t i_aux = 0; i_aux < config->GetNUserScalars(); i_aux++) { @@ -466,17 +532,212 @@ unsigned long CSpeciesFlameletSolver::SetScalarSources(const CConfig* config, CF unsigned long CSpeciesFlameletSolver::SetScalarLookUps(const CConfig* config, CFluidModel* fluid_model_local, unsigned long iPoint, const vector& scalars) { - /*--- Compute total source terms from the production and consumption. ---*/ + /*--- Retrieve the passive look-up variables from the manifold. ---*/ + unsigned long misses{0}; + /*--- Skip if no passive look-ups are listed ---*/ + if (config->GetNLookups() > 0) { + vector lookup_scalar(config->GetNLookups()); + misses = fluid_model_local->EvaluateDataSet(scalars, FLAMELET_LOOKUP_OPS::LOOKUP, lookup_scalar); + + for (auto i_lookup = 0u; i_lookup < config->GetNLookups(); i_lookup++) { + nodes->SetLookupScalar(iPoint, lookup_scalar[i_lookup], i_lookup); + } + } + + return misses; +} - vector lookup_scalar(config->GetNLookups()); - unsigned long misses = fluid_model_local->EvaluateDataSet(scalars, FLAMELET_LOOKUP_OPS::LOOKUP, lookup_scalar); +unsigned long CSpeciesFlameletSolver::SetPreferentialDiffusionScalars(const CConfig* config, + CFluidModel* fluid_model_local, + unsigned long iPoint, + const vector& scalars) { + /*--- Retrieve the preferential diffusion scalar values from the manifold. ---*/ - for (auto i_lookup = 0u; i_lookup < config->GetNLookups(); i_lookup++) { - nodes->SetLookupScalar(iPoint, lookup_scalar[i_lookup], i_lookup); + vector beta_scalar(FLAMELET_PREF_DIFF_SCALARS::N_BETA_TERMS); + unsigned long misses = fluid_model_local->EvaluateDataSet(scalars, FLAMELET_LOOKUP_OPS::PREFDIF, beta_scalar); + + for (auto i_beta = 0u; i_beta < FLAMELET_PREF_DIFF_SCALARS::N_BETA_TERMS; i_beta++) { + nodes->SetAuxVar(iPoint, i_beta, beta_scalar[i_beta]); } return misses; } +void CSpeciesFlameletSolver::Viscous_Residual(const unsigned long iEdge, const CGeometry* geometry, CSolver** solver_container, + CNumerics* numerics, const CConfig* config) { + /*--- Overloaded viscous residual method which accounts for preferential diffusion. ---*/ + const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT), + PreferentialDiffusion = config->GetPreferentialDiffusion(); + + /*--- Points in edge ---*/ + auto iPoint = geometry->edges->GetNode(iEdge, 0); + auto jPoint = geometry->edges->GetNode(iEdge, 1); + + auto SolverSpecificNumerics = [&](unsigned long iPoint, unsigned long jPoint) { + /*--- Mass diffusivity coefficients. ---*/ + + numerics->SetDiffusionCoeff(nodes->GetDiffusivity(iPoint), nodes->GetDiffusivity(jPoint)); + }; + + /*--- Regular viscous scalar residual computation. ---*/ + + Viscous_Residual_impl(SolverSpecificNumerics, iEdge, geometry, solver_container, numerics, config); + + /*--- Viscous residual due to preferential diffusion ---*/ + if (PreferentialDiffusion) { + CFlowVariable* flowNodes = su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()); + + su2double scalar_i[MAXNVAR] = {0}, + scalar_j[MAXNVAR] = {0}, + diff_coeff_beta_i[MAXNVAR] = {0}, + diff_coeff_beta_j[MAXNVAR] = {0}; + + // Number of active transport scalars + const auto n_CV = config->GetNControlVars(); + + su2activematrix scalar_grad_i(MAXNVAR, MAXNDIM), scalar_grad_j(MAXNVAR, MAXNDIM); + /*--- Looping over spatial dimensions to fill in the diffusion scalar gradients. ---*/ + /*--- The scalar gradient is subtracted to account for regular viscous diffusion. ---*/ + for (auto iScalar = 0u; iScalar < n_CV; ++iScalar) { + for (auto iDim = 0u; iDim < nDim; ++iDim) { + switch (iScalar) { + case I_PROGVAR: + scalar_grad_i[iScalar][iDim] = + nodes->GetAuxVarGradient(iPoint, FLAMELET_PREF_DIFF_SCALARS::I_BETA_PROGVAR, iDim) - + nodes->GetGradient(iPoint, I_PROGVAR, iDim); + scalar_grad_j[iScalar][iDim] = + nodes->GetAuxVarGradient(jPoint, FLAMELET_PREF_DIFF_SCALARS::I_BETA_PROGVAR, iDim) - + nodes->GetGradient(jPoint, I_PROGVAR, iDim); + break; + case I_ENTH: + scalar_grad_i[iScalar][iDim] = + nodes->GetAuxVarGradient(iPoint, FLAMELET_PREF_DIFF_SCALARS::I_BETA_ENTH, iDim) - + nodes->GetGradient(iPoint, I_ENTH, iDim); + scalar_grad_j[iScalar][iDim] = + nodes->GetAuxVarGradient(jPoint, FLAMELET_PREF_DIFF_SCALARS::I_BETA_ENTH, iDim) - + nodes->GetGradient(jPoint, I_ENTH, iDim); + break; + case I_MIXFRAC: + scalar_grad_i[iScalar][iDim] = + nodes->GetAuxVarGradient(iPoint, FLAMELET_PREF_DIFF_SCALARS::I_BETA_MIXFRAC, iDim) - + nodes->GetGradient(iPoint, I_MIXFRAC, iDim); + scalar_grad_j[iScalar][iDim] = + nodes->GetAuxVarGradient(jPoint, FLAMELET_PREF_DIFF_SCALARS::I_BETA_MIXFRAC, iDim) - + nodes->GetGradient(jPoint, I_MIXFRAC, iDim); + break; + default: + break; + } + } + } + /*--- No preferential diffusion modification for passive species. ---*/ + for (auto iScalar = n_CV; iScalar < nVar; ++iScalar) { + for (auto iDim = 0u; iDim < nDim; ++iDim) { + scalar_grad_i[iScalar][iDim] = 0; + scalar_grad_j[iScalar][iDim] = 0; + } + } + + for (auto iScalar = 0u; iScalar < n_CV; ++iScalar) { + /*--- Filling in the preferential diffusion scalars (beta_pv, beta_h2, beta_Z). ---*/ + switch (iScalar) { + case I_PROGVAR: + scalar_i[iScalar] = nodes->GetAuxVar(iPoint, FLAMELET_PREF_DIFF_SCALARS::I_BETA_PROGVAR) - + nodes->GetSolution(iPoint, iScalar); + scalar_j[iScalar] = nodes->GetAuxVar(jPoint, FLAMELET_PREF_DIFF_SCALARS::I_BETA_PROGVAR) - + nodes->GetSolution(jPoint, iScalar); + break; + case I_ENTH: + scalar_i[iScalar] = + nodes->GetAuxVar(iPoint, FLAMELET_PREF_DIFF_SCALARS::I_BETA_ENTH) - nodes->GetSolution(iPoint, iScalar); + scalar_j[iScalar] = + nodes->GetAuxVar(jPoint, FLAMELET_PREF_DIFF_SCALARS::I_BETA_ENTH) - nodes->GetSolution(jPoint, iScalar); + break; + case I_MIXFRAC: + scalar_i[iScalar] = nodes->GetAuxVar(iPoint, FLAMELET_PREF_DIFF_SCALARS::I_BETA_MIXFRAC) - + nodes->GetSolution(iPoint, iScalar); + scalar_j[iScalar] = nodes->GetAuxVar(jPoint, FLAMELET_PREF_DIFF_SCALARS::I_BETA_MIXFRAC) - + nodes->GetSolution(jPoint, iScalar); + break; + default: + break; + } + diff_coeff_beta_i[iScalar] = nodes->GetDiffusivity(iPoint, iScalar); + diff_coeff_beta_j[iScalar] = nodes->GetDiffusivity(jPoint, iScalar); + } + + for (auto iScalar = n_CV; iScalar < nVar; ++iScalar) { + scalar_i[iScalar] = 0; + scalar_j[iScalar] = 0; + diff_coeff_beta_i[iScalar] = 0; + diff_coeff_beta_j[iScalar] = 0; + } + + numerics->SetScalarVar(scalar_i, scalar_j); + + numerics->SetScalarVarGradient(CMatrixView(scalar_grad_i), CMatrixView(scalar_grad_j)); + + numerics->SetDiffusionCoeff(diff_coeff_beta_i, diff_coeff_beta_j); + + /*--- Computing first preferential residual component. ---*/ + auto residual_PD = numerics->ComputeResidual(config); + + if (ReducerStrategy) { + EdgeFluxes.SubtractBlock(iEdge, residual_PD); + + if (implicit) Jacobian.UpdateBlocksSub(iEdge, residual_PD.jacobian_i, residual_PD.jacobian_j); + } else { + LinSysRes.SubtractBlock(iPoint, residual_PD); + LinSysRes.AddBlock(jPoint, residual_PD); + /*--- Set implicit computation ---*/ + if (implicit) Jacobian.UpdateBlocksSub(iEdge, iPoint, jPoint, residual_PD.jacobian_i, residual_PD.jacobian_j); + } + + /* Computing the second preferential diffusion terms due to heat flux */ + for (auto iScalar = 0u; iScalar < nVar; ++iScalar) { + for (auto iDim = 0u; iDim < nDim; ++iDim) { + if (iScalar == I_ENTH) { + /* Setting the temperature gradient */ + scalar_grad_i[iScalar][iDim] = flowNodes->GetGradient_Primitive(iPoint, prim_idx.Temperature(), iDim); + scalar_grad_j[iScalar][iDim] = flowNodes->GetGradient_Primitive(jPoint, prim_idx.Temperature(), iDim); + } else { + scalar_grad_i[iScalar][iDim] = 0; + scalar_grad_j[iScalar][iDim] = 0; + } + } + + if (iScalar == I_ENTH) { + scalar_i[iScalar] = flowNodes->GetTemperature(iPoint); + scalar_j[iScalar] = flowNodes->GetTemperature(jPoint); + diff_coeff_beta_i[iScalar] = nodes->GetAuxVar(iPoint, FLAMELET_PREF_DIFF_SCALARS::I_BETA_ENTH_THERMAL) * + nodes->GetDiffusivity(iPoint, iScalar); + diff_coeff_beta_j[iScalar] = nodes->GetAuxVar(jPoint, FLAMELET_PREF_DIFF_SCALARS::I_BETA_ENTH_THERMAL) * + nodes->GetDiffusivity(jPoint, iScalar); + } else { + scalar_i[iScalar] = 0; + scalar_j[iScalar] = 0; + diff_coeff_beta_i[iScalar] = 0; + diff_coeff_beta_j[iScalar] = 0; + } + } + + numerics->SetScalarVar(scalar_i, scalar_j); + + numerics->SetScalarVarGradient(CMatrixView(scalar_grad_i), CMatrixView(scalar_grad_j)); + + numerics->SetDiffusionCoeff(diff_coeff_beta_i, diff_coeff_beta_j); + + auto residual_thermal = numerics->ComputeResidual(config); + + if (ReducerStrategy) { + EdgeFluxes.SubtractBlock(iEdge, residual_thermal); + } else { + LinSysRes.SubtractBlock(iPoint, residual_thermal); + LinSysRes.AddBlock(jPoint, residual_thermal); + /* No implicit part for the preferential diffusion of heat */ + } + } +} + unsigned long CSpeciesFlameletSolver::GetEnthFromTemp(CFluidModel* fluid_model, su2double const val_temp, const su2double* scalar_solution, su2double* val_enth) { /*--- convergence criterion for temperature in [K], high accuracy needed for restarts. ---*/ diff --git a/SU2_CFD/src/solvers/CSpeciesSolver.cpp b/SU2_CFD/src/solvers/CSpeciesSolver.cpp index f5f5ed16603..3c7ac895708 100644 --- a/SU2_CFD/src/solvers/CSpeciesSolver.cpp +++ b/SU2_CFD/src/solvers/CSpeciesSolver.cpp @@ -60,8 +60,8 @@ CSpeciesSolver::CSpeciesSolver(CGeometry* geometry, CConfig* config, unsigned sh /*--- MPI solution ---*/ - InitiateComms(geometry, config, SOLUTION); - CompleteComms(geometry, config, SOLUTION); + InitiateComms(geometry, config, MPI_QUANTITIES::SOLUTION); + CompleteComms(geometry, config, MPI_QUANTITIES::SOLUTION); SlidingState.resize(nMarker); SlidingStateNodes.resize(nMarker); @@ -248,8 +248,8 @@ void CSpeciesSolver::LoadRestart(CGeometry** geometry, CSolver*** solver, CConfi /*--- MPI solution and compute the eddy viscosity ---*/ - solver[MESH_0][SPECIES_SOL]->InitiateComms(geometry[MESH_0], config, SOLUTION); - solver[MESH_0][SPECIES_SOL]->CompleteComms(geometry[MESH_0], config, SOLUTION); + solver[MESH_0][SPECIES_SOL]->InitiateComms(geometry[MESH_0], config, MPI_QUANTITIES::SOLUTION); + solver[MESH_0][SPECIES_SOL]->CompleteComms(geometry[MESH_0], config, MPI_QUANTITIES::SOLUTION); // Flow-Pre computes/sets mixture properties solver[MESH_0][FLOW_SOL]->Preprocessing(geometry[MESH_0], solver[MESH_0], config, MESH_0, NO_RK_ITER, @@ -267,8 +267,8 @@ void CSpeciesSolver::LoadRestart(CGeometry** geometry, CSolver*** solver, CConfi for (auto iMesh = 1u; iMesh <= config->GetnMGLevels(); iMesh++) { MultigridRestriction(*geometry[iMesh - 1], solver[iMesh - 1][SPECIES_SOL]->GetNodes()->GetSolution(), *geometry[iMesh], solver[iMesh][SPECIES_SOL]->GetNodes()->GetSolution()); - solver[iMesh][SPECIES_SOL]->InitiateComms(geometry[iMesh], config, SOLUTION); - solver[iMesh][SPECIES_SOL]->CompleteComms(geometry[iMesh], config, SOLUTION); + solver[iMesh][SPECIES_SOL]->InitiateComms(geometry[iMesh], config, MPI_QUANTITIES::SOLUTION); + solver[iMesh][SPECIES_SOL]->CompleteComms(geometry[iMesh], config, MPI_QUANTITIES::SOLUTION); solver[iMesh][FLOW_SOL]->Preprocessing(geometry[iMesh], solver[iMesh], config, iMesh, NO_RK_ITER, RUNTIME_FLOW_SYS, false); @@ -314,8 +314,8 @@ void CSpeciesSolver::Preprocessing(CGeometry* geometry, CSolver** solver_contain CommonPreprocessing(geometry, config, Output); } -void CSpeciesSolver::Viscous_Residual(unsigned long iEdge, CGeometry* geometry, CSolver** solver_container, - CNumerics* numerics, CConfig* config) { +void CSpeciesSolver::Viscous_Residual(const unsigned long iEdge, const CGeometry* geometry, CSolver** solver_container, + CNumerics* numerics, const CConfig* config) { /*--- Define an object to set solver specific numerics contribution. ---*/ auto SolverSpecificNumerics = [&](unsigned long iPoint, unsigned long jPoint) { /*--- Mass diffusivity coefficients. ---*/ @@ -345,7 +345,7 @@ void CSpeciesSolver::BC_Inlet(CGeometry* geometry, CSolver** solver_container, C /*--- Identify the boundary by string name ---*/ string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - + if (config->GetMarker_StrongBC(Marker_Tag)==true) { nodes->SetSolution_Old(iPoint, Inlet_SpeciesVars[val_marker][iVertex]); diff --git a/SU2_CFD/src/solvers/CTransLMSolver.cpp b/SU2_CFD/src/solvers/CTransLMSolver.cpp index b67e1b1af96..1fdf2a47de1 100644 --- a/SU2_CFD/src/solvers/CTransLMSolver.cpp +++ b/SU2_CFD/src/solvers/CTransLMSolver.cpp @@ -132,8 +132,8 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh /*--- MPI solution ---*/ - InitiateComms(geometry, config, SOLUTION); - CompleteComms(geometry, config, SOLUTION); + InitiateComms(geometry, config, MPI_QUANTITIES::SOLUTION); + CompleteComms(geometry, config, MPI_QUANTITIES::SOLUTION); /*--- Initializate quantities for SlidingMesh Interface ---*/ @@ -263,8 +263,8 @@ void CTransLMSolver::Postprocessing(CGeometry *geometry, CSolver **solver_contai } -void CTransLMSolver::Viscous_Residual(unsigned long iEdge, CGeometry* geometry, CSolver** solver_container, - CNumerics* numerics, CConfig* config) { +void CTransLMSolver::Viscous_Residual(const unsigned long iEdge, const CGeometry* geometry, CSolver** solver_container, + CNumerics* numerics, const CConfig* config) { /*--- Define an object to set solver specific numerics contribution. ---*/ @@ -561,8 +561,8 @@ void CTransLMSolver::LoadRestart(CGeometry** geometry, CSolver*** solver, CConfi /*--- MPI solution and compute the eddy viscosity ---*/ - solver[MESH_0][TRANS_SOL]->InitiateComms(geometry[MESH_0], config, SOLUTION); - solver[MESH_0][TRANS_SOL]->CompleteComms(geometry[MESH_0], config, SOLUTION); + solver[MESH_0][TRANS_SOL]->InitiateComms(geometry[MESH_0], config, MPI_QUANTITIES::SOLUTION); + solver[MESH_0][TRANS_SOL]->CompleteComms(geometry[MESH_0], config, MPI_QUANTITIES::SOLUTION); /*--- For turbulent+species simulations the solver Pre-/Postprocessing is done by the species solver. ---*/ if (config->GetKind_Species_Model() == SPECIES_MODEL::NONE) { @@ -578,8 +578,8 @@ void CTransLMSolver::LoadRestart(CGeometry** geometry, CSolver*** solver, CConfi MultigridRestriction(*geometry[iMesh - 1], solver[iMesh - 1][TRANS_SOL]->GetNodes()->GetSolution(), *geometry[iMesh], solver[iMesh][TRANS_SOL]->GetNodes()->GetSolution()); - solver[iMesh][TRANS_SOL]->InitiateComms(geometry[iMesh], config, SOLUTION); - solver[iMesh][TRANS_SOL]->CompleteComms(geometry[iMesh], config, SOLUTION); + solver[iMesh][TRANS_SOL]->InitiateComms(geometry[iMesh], config, MPI_QUANTITIES::SOLUTION); + solver[iMesh][TRANS_SOL]->CompleteComms(geometry[iMesh], config, MPI_QUANTITIES::SOLUTION); if (config->GetKind_Species_Model() == SPECIES_MODEL::NONE) { solver[iMesh][FLOW_SOL]->Preprocessing(geometry[iMesh], solver[iMesh], config, iMesh, NO_RK_ITER, RUNTIME_FLOW_SYS, diff --git a/SU2_CFD/src/solvers/CTurbSASolver.cpp b/SU2_CFD/src/solvers/CTurbSASolver.cpp index f3a6d57b589..f53596e9901 100644 --- a/SU2_CFD/src/solvers/CTurbSASolver.cpp +++ b/SU2_CFD/src/solvers/CTurbSASolver.cpp @@ -134,8 +134,8 @@ CTurbSASolver::CTurbSASolver(CGeometry *geometry, CConfig *config, unsigned shor /*--- MPI solution ---*/ - InitiateComms(geometry, config, SOLUTION_EDDY); - CompleteComms(geometry, config, SOLUTION_EDDY); + InitiateComms(geometry, config, MPI_QUANTITIES::SOLUTION_EDDY); + CompleteComms(geometry, config, MPI_QUANTITIES::SOLUTION_EDDY); /*--- Initializate quantities for SlidingMesh Interface ---*/ @@ -291,8 +291,8 @@ void CTurbSASolver::Postprocessing(CGeometry *geometry, CSolver **solver_contain AD::EndNoSharedReading(); } -void CTurbSASolver::Viscous_Residual(unsigned long iEdge, CGeometry* geometry, CSolver** solver_container, - CNumerics* numerics, CConfig* config) { +void CTurbSASolver::Viscous_Residual(const unsigned long iEdge, const CGeometry* geometry, CSolver** solver_container, + CNumerics* numerics, const CConfig* config) { /*--- Define an object to set solver specific numerics contribution. ---*/ auto SolverSpecificNumerics = [&](unsigned long iPoint, unsigned long jPoint) { diff --git a/SU2_CFD/src/solvers/CTurbSSTSolver.cpp b/SU2_CFD/src/solvers/CTurbSSTSolver.cpp index 1973b70a331..555f8e77155 100644 --- a/SU2_CFD/src/solvers/CTurbSSTSolver.cpp +++ b/SU2_CFD/src/solvers/CTurbSSTSolver.cpp @@ -142,8 +142,8 @@ CTurbSSTSolver::CTurbSSTSolver(CGeometry *geometry, CConfig *config, unsigned sh /*--- MPI solution ---*/ - InitiateComms(geometry, config, SOLUTION_EDDY); - CompleteComms(geometry, config, SOLUTION_EDDY); + InitiateComms(geometry, config, MPI_QUANTITIES::SOLUTION_EDDY); + CompleteComms(geometry, config, MPI_QUANTITIES::SOLUTION_EDDY); /*--- Initialize quantities for SlidingMesh Interface ---*/ @@ -276,8 +276,8 @@ void CTurbSSTSolver::Postprocessing(CGeometry *geometry, CSolver **solver_contai AD::EndNoSharedReading(); } -void CTurbSSTSolver::Viscous_Residual(unsigned long iEdge, CGeometry* geometry, CSolver** solver_container, - CNumerics* numerics, CConfig* config) { +void CTurbSSTSolver::Viscous_Residual(const unsigned long iEdge, const CGeometry* geometry, CSolver** solver_container, + CNumerics* numerics, const CConfig* config) { /*--- Define an object to set solver specific numerics contribution. ---*/ auto SolverSpecificNumerics = [&](unsigned long iPoint, unsigned long jPoint) { diff --git a/SU2_CFD/src/solvers/CTurbSolver.cpp b/SU2_CFD/src/solvers/CTurbSolver.cpp index c4b5a0b2e2b..d0744a7e223 100644 --- a/SU2_CFD/src/solvers/CTurbSolver.cpp +++ b/SU2_CFD/src/solvers/CTurbSolver.cpp @@ -167,8 +167,8 @@ void CTurbSolver::LoadRestart(CGeometry** geometry, CSolver*** solver, CConfig* /*--- MPI solution and compute the eddy viscosity ---*/ - solver[MESH_0][TURB_SOL]->InitiateComms(geometry[MESH_0], config, SOLUTION); - solver[MESH_0][TURB_SOL]->CompleteComms(geometry[MESH_0], config, SOLUTION); + solver[MESH_0][TURB_SOL]->InitiateComms(geometry[MESH_0], config, MPI_QUANTITIES::SOLUTION); + solver[MESH_0][TURB_SOL]->CompleteComms(geometry[MESH_0], config, MPI_QUANTITIES::SOLUTION); /*--- For turbulent+species simulations the solver Pre-/Postprocessing is done by the species solver. ---*/ if (config->GetKind_Species_Model() == SPECIES_MODEL::NONE && config->GetKind_Trans_Model() == TURB_TRANS_MODEL::NONE) { @@ -182,8 +182,8 @@ void CTurbSolver::LoadRestart(CGeometry** geometry, CSolver*** solver, CConfig* for (auto iMesh = 1u; iMesh <= config->GetnMGLevels(); iMesh++) { MultigridRestriction(*geometry[iMesh - 1], solver[iMesh - 1][TURB_SOL]->GetNodes()->GetSolution(), *geometry[iMesh], solver[iMesh][TURB_SOL]->GetNodes()->GetSolution()); - solver[iMesh][TURB_SOL]->InitiateComms(geometry[iMesh], config, SOLUTION); - solver[iMesh][TURB_SOL]->CompleteComms(geometry[iMesh], config, SOLUTION); + solver[iMesh][TURB_SOL]->InitiateComms(geometry[iMesh], config, MPI_QUANTITIES::SOLUTION); + solver[iMesh][TURB_SOL]->CompleteComms(geometry[iMesh], config, MPI_QUANTITIES::SOLUTION); if (config->GetKind_Species_Model() == SPECIES_MODEL::NONE) { solver[iMesh][FLOW_SOL]->Preprocessing(geometry[iMesh], solver[iMesh], config, iMesh, NO_RK_ITER, RUNTIME_FLOW_SYS, diff --git a/SU2_CFD/src/variables/CSpeciesFlameletVariable.cpp b/SU2_CFD/src/variables/CSpeciesFlameletVariable.cpp index da10ba21bd8..3dd1b222750 100644 --- a/SU2_CFD/src/variables/CSpeciesFlameletVariable.cpp +++ b/SU2_CFD/src/variables/CSpeciesFlameletVariable.cpp @@ -53,4 +53,9 @@ CSpeciesFlameletVariable::CSpeciesFlameletVariable(const su2double* species_inf, source_scalar.resize(nPoint, config->GetNScalars()) = su2double(0.0); lookup_scalar.resize(nPoint, config->GetNLookups()) = su2double(0.0); table_misses.resize(nPoint) = 0; + + if (config->GetPreferentialDiffusion()) { + AuxVar.resize(nPoint, FLAMELET_PREF_DIFF_SCALARS::N_BETA_TERMS) = su2double(0.0); + Grad_AuxVar.resize(nPoint, FLAMELET_PREF_DIFF_SCALARS::N_BETA_TERMS, nDim, 0.0); + } } diff --git a/SU2_GEO/src/SU2_GEO.cpp b/SU2_GEO/src/SU2_GEO.cpp index 86b9ee5c6e0..4e1d3bad9fe 100644 --- a/SU2_GEO/src/SU2_GEO.cpp +++ b/SU2_GEO/src/SU2_GEO.cpp @@ -1429,14 +1429,15 @@ int main(int argc, char* argv[]) { delete[] Xcoord_Airfoil; delete[] Ycoord_Airfoil; delete[] Zcoord_Airfoil; + delete[] Variable_Airfoil; delete[] ObjectiveFunc; delete[] ObjectiveFunc_New; delete[] Gradient; for (iPlane = 0; iPlane < nPlane; iPlane++) { - delete Plane_P0[iPlane]; - delete Plane_Normal[iPlane]; + delete[] Plane_P0[iPlane]; + delete[] Plane_Normal[iPlane]; } delete[] Plane_P0; delete[] Plane_Normal; diff --git a/TestCases/TestCase.py b/TestCases/TestCase.py index 6d577b47df4..0818c6074a0 100644 --- a/TestCases/TestCase.py +++ b/TestCases/TestCase.py @@ -45,6 +45,7 @@ def is_float(test_string): def parse_args(description: str): parser = argparse.ArgumentParser(description=description) parser.add_argument('--tsan', action='store_true', help='Run thread sanitizer tests. Requires a tsan-enabled SU2 build.') + parser.add_argument('--asan', action='store_true', help='Run address sanitizer tests. Requires an asan-enabled SU2 build.') return parser.parse_args() class TestCase: @@ -114,6 +115,7 @@ def __init__(self,tag_in): self.cpu_arch = platform.machine().casefold() self.enabled_on_cpu_arch = ["x86_64","amd64","aarch64","arm64"] self.enabled_with_tsan = True + self.enabled_with_asan = True self.command = self.Command() self.timeout = 0 self.tol = 0.0 @@ -125,9 +127,9 @@ def __init__(self,tag_in): self.reference_file_aarch64 = "" self.test_file = "of_grad.dat" - def run_test(self, running_with_tsan=False): + def run_test(self, with_tsan=False, with_asan=False): - if not self.is_enabled(running_with_tsan): + if not self.is_enabled(with_tsan, with_asan): return True print('==================== Start Test: %s ===================='%self.tag) @@ -142,7 +144,7 @@ def run_test(self, running_with_tsan=False): # Adjust the number of iterations in the config file if len(self.test_vals) != 0: - self.adjust_iter(running_with_tsan) + self.adjust_iter(with_tsan, with_asan) # Check for disabling the restart if self.no_restart: @@ -186,7 +188,7 @@ def run_test(self, running_with_tsan=False): delta_vals = [] sim_vals = [] - if not running_with_tsan: # tsan findings result in non-zero return code, no need to examine the output + if not with_tsan and not with_asan: # sanitizer findings result in non-zero return code, no need to examine the output # Examine the output f = open(logfilename,'r') output = f.readlines() @@ -260,7 +262,7 @@ def run_test(self, running_with_tsan=False): if not start_solver: print('ERROR: The code was not able to get to the "Begin solver" section.') - if not running_with_tsan and iter_missing: + if not with_tsan and not with_asan and iter_missing: print('ERROR: The iteration number %d could not be found.'%self.test_iter) print('CPU architecture=%s' % self.cpu_arch) @@ -281,9 +283,9 @@ def run_test(self, running_with_tsan=False): os.chdir(workdir) return passed - def run_filediff(self, running_with_tsan=False): + def run_filediff(self, with_tsan=False, with_asan=False): - if not self.is_enabled(running_with_tsan): + if not self.is_enabled(with_tsan, with_asan): return True print('==================== Start Test: %s ===================='%self.tag) @@ -291,7 +293,7 @@ def run_filediff(self, running_with_tsan=False): timed_out = False # Adjust the number of iterations in the config file - self.adjust_iter(running_with_tsan) + self.adjust_iter(with_tsan, with_asan) self.adjust_test_data() @@ -330,7 +332,7 @@ def run_filediff(self, running_with_tsan=False): print("Output from the failed case:") subprocess.call(["cat", logfilename]) - if not running_with_tsan: # thread sanitizer tests only check the return code, no need to compare outputs + if not with_tsan and not with_asan: # sanitizer tests only check the return code, no need to compare outputs diff_time_start = datetime.datetime.now() if not timed_out and passed: # Compare files @@ -468,9 +470,9 @@ def run_filediff(self, running_with_tsan=False): os.chdir(workdir) return passed - def run_opt(self): + def run_opt(self, with_tsan=False, with_asan=False): - if not self.is_enabled(): + if not self.is_enabled(with_tsan, with_asan): return True print('==================== Start Test: %s ===================='%self.tag) @@ -593,9 +595,9 @@ def run_opt(self): os.chdir(workdir) return passed - def run_geo(self): + def run_geo(self, with_tsan=False, with_asan=False): - if not self.is_enabled(): + if not self.is_enabled(with_tsan, with_asan): return True print('==================== Start Test: %s ===================='%self.tag) @@ -640,52 +642,59 @@ def run_geo(self): timed_out = True passed = False - # Examine the output - f = open(logfilename,'r') - output = f.readlines() + # check for non-zero return code + process.communicate() + if process.returncode != 0: + passed = False + delta_vals = [] sim_vals = [] - data = [] - if not timed_out: - start_solver = False - for line in output: - if not start_solver: # Don't bother parsing anything before SU2_GEO starts - if line.find('Station 1') > -1: - start_solver=True - elif line.find('Station 2') > -1: # jump out of loop if we hit the next station - break - else: # Found the lines; parse the input - - if line.find('Chord') > -1: - raw_data = line.replace(",", "").split() - data.append(raw_data[1]) - found_chord = True - data.append(raw_data[5]) - found_radius = True - data.append(raw_data[8]) - found_toc = True - data.append(raw_data[10]) - found_aoa = True - - if found_chord and found_radius and found_toc and found_aoa: # Found what we're checking for - iter_missing = False - if not len(self.test_vals)==len(data): # something went wrong... probably bad input - print("Error in test_vals!") - passed = 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 - else: - iter_missing = True - if not start_solver: - passed = False + if not with_tsan and not with_asan: # sanitizer findings result in non-zero return code, no need to examine the output + # Examine the output + f = open(logfilename,'r') + output = f.readlines() + data = [] + if not timed_out: + start_solver = False + for line in output: + if not start_solver: # Don't bother parsing anything before SU2_GEO starts + if line.find('Station 1') > -1: + start_solver=True + elif line.find('Station 2') > -1: # jump out of loop if we hit the next station + break + else: # Found the lines; parse the input + + if line.find('Chord') > -1: + raw_data = line.replace(",", "").split() + data.append(raw_data[1]) + found_chord = True + data.append(raw_data[5]) + found_radius = True + data.append(raw_data[8]) + found_toc = True + data.append(raw_data[10]) + found_aoa = True + + if found_chord and found_radius and found_toc and found_aoa: # Found what we're checking for + iter_missing = False + if not len(self.test_vals)==len(data): # something went wrong... probably bad input + print("Error in test_vals!") + passed = 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 + else: + iter_missing = True - if iter_missing: - passed = False + if not start_solver: + passed = False + + if iter_missing: + passed = False # Write the test results #for j in output: @@ -703,20 +712,21 @@ def run_geo(self): if timed_out: print('ERROR: Execution timed out. timeout=%d'%self.timeout) - if exceed_tol: - print('ERROR: Difference between computed input and test_vals exceeded tolerance. TOL=%f'%self.tol) + if not with_tsan and not with_asan: + if exceed_tol: + print('ERROR: Difference between computed input and test_vals exceeded tolerance. TOL=%f'%self.tol) - if not start_solver: - print('ERROR: The code was not able to get to the "OBJFUN" section.') + if not start_solver: + print('ERROR: The code was not able to get to the "OBJFUN" section.') - if iter_missing: - print('ERROR: The SU2_GEO values could not be found.') + if iter_missing: + print('ERROR: The SU2_GEO values could not be found.') - print_vals(self.test_vals, name="test_vals (stored)") + print_vals(self.test_vals, name="test_vals (stored)") - print_vals(sim_vals, name="sim_vals (computed)") + print_vals(sim_vals, name="sim_vals (computed)") - print_vals(delta_vals, name="delta_vals") + print_vals(delta_vals, name="delta_vals") print('test duration: %.2f min'%(running_time/60.0)) print('==================== End Test: %s ====================\n'%self.tag) @@ -725,9 +735,9 @@ def run_geo(self): os.chdir(workdir) return passed - def run_def(self): + def run_def(self, with_tsan=False, with_asan=False): - if not self.is_enabled(): + if not self.is_enabled(with_tsan, with_asan): return True print('==================== Start Test: %s ===================='%self.tag) @@ -767,48 +777,55 @@ def run_def(self): timed_out = True passed = False - # Examine the output - f = open(logfilename,'r') - output = f.readlines() + # check for non-zero return code + process.communicate() + if process.returncode != 0: + passed = False + delta_vals = [] sim_vals = [] - if not timed_out: - start_solver = False - for line in output: - if not start_solver: # Don't bother parsing anything before -- Volumetric grid deformation --- - if line.find('Volumetric grid deformation') > -1: - start_solver=True - else: # Found the -- Volumetric grid deformation --- line; parse the input - raw_data = line.split() - try: - iter_number = int(raw_data[0]) - data = raw_data[len(raw_data)-1:] # Take the last column for comparison - except ValueError: - continue - except IndexError: - continue - if iter_number == self.test_iter: # Found the iteration number we're checking for - iter_missing = False - if not len(self.test_vals)==len(data): # something went wrong... probably bad input - print("Error in test_vals!") - passed = False - break - 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 + if not with_tsan and not with_asan: # sanitizer findings result in non-zero return code, no need to examine the output + # Examine the output + f = open(logfilename,'r') + output = f.readlines() + if not timed_out: + start_solver = False + for line in output: + if not start_solver: # Don't bother parsing anything before -- Volumetric grid deformation --- + if line.find('Volumetric grid deformation') > -1: + start_solver=True + else: # Found the -- Volumetric grid deformation --- line; parse the input + raw_data = line.split() + try: + iter_number = int(raw_data[0]) + data = raw_data[len(raw_data)-1:] # Take the last column for comparison + except ValueError: + continue + except IndexError: + continue + + if iter_number == self.test_iter: # Found the iteration number we're checking for + iter_missing = False + if not len(self.test_vals)==len(data): # something went wrong... probably bad input + print("Error in test_vals!") passed = False - break - else: - iter_missing = True + break + 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 + break + else: + iter_missing = True - if not start_solver: - passed = False + if not start_solver: + passed = False - if iter_missing: - passed = False + if iter_missing: + passed = False # Write the test results #for j in output: @@ -826,22 +843,23 @@ def run_def(self): if timed_out: print('ERROR: Execution timed out. timeout=%d sec'%self.timeout) - if exceed_tol: - print('ERROR: Difference between computed input and test_vals exceeded tolerance. TOL=%e'%self.tol) + if not with_tsan and not with_asan: + if exceed_tol: + print('ERROR: Difference between computed input and test_vals exceeded tolerance. TOL=%e'%self.tol) - if not start_solver: - print('ERROR: The code was not able to get to the "Begin solver" section.') + if not start_solver: + print('ERROR: The code was not able to get to the "Begin solver" section.') - if iter_missing: - print('ERROR: The iteration number %d could not be found.'%self.test_iter) + if iter_missing: + print('ERROR: The iteration number %d could not be found.'%self.test_iter) - print('test_iter=%d' % self.test_iter) + print('test_iter=%d' % self.test_iter) - print_vals(self.test_vals, name="test_vals (stored)") + print_vals(self.test_vals, name="test_vals (stored)") - print_vals(sim_vals, name="sim_vals (computed)") + print_vals(sim_vals, name="sim_vals (computed)") - print_vals(delta_vals, name="delta_vals") + print_vals(delta_vals, name="delta_vals") print('test duration: %.2f min'%(running_time/60.0)) #print('==================== End Test: %s ====================\n'%self.tag) @@ -850,7 +868,7 @@ def run_def(self): os.chdir(workdir) return passed - def adjust_iter(self, running_with_tsan=False): + def adjust_iter(self, with_tsan=False, with_asan=False): # Read the cfg file workdir = os.getcwd() @@ -861,7 +879,7 @@ def adjust_iter(self, running_with_tsan=False): new_iter = self.test_iter + 1 - if running_with_tsan: + if with_tsan or with_asan: # detect restart restart_iter = 0 @@ -942,18 +960,19 @@ def disable_restart(self): return - def is_enabled(self, running_with_tsan=False): + def is_enabled(self, with_tsan=False, with_asan=False): is_enabled_on_arch = self.cpu_arch in self.enabled_on_cpu_arch if not is_enabled_on_arch: print('Ignoring test "%s" because it is not enabled for the current CPU architecture: %s' % (self.tag, self.cpu_arch)) - tsan_compatible = not running_with_tsan or self.enabled_with_tsan + tsan_compatible = not with_tsan or self.enabled_with_tsan + asan_compatible = not with_asan or self.enabled_with_asan if not tsan_compatible: print('Ignoring test "%s" because it is not enabled to run with the thread sanitizer.' % self.tag) - return is_enabled_on_arch and tsan_compatible + return is_enabled_on_arch and tsan_compatible and asan_compatible def adjust_test_data(self): 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 new file mode 100644 index 00000000000..3f294865a17 --- /dev/null +++ b/TestCases/flamelet/07_laminar_premixed_h2_flame_cfd/laminar_premixed_h2_flame_cfd.cfg @@ -0,0 +1,120 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Laminar premixed hydrogen flame with heat exchanger % +% Author: Evert Bunschoten % +% Institution: Delft University of Technology % +% Date: 01/11/2023 % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +SOLVER = INC_NAVIER_STOKES +KIND_TURB_MODEL= NONE +MATH_PROBLEM= DIRECT +RESTART_SOL =YES +% ---------------- INCOMPRESSIBLE FLOW CONDITION DEFINITION -------------------% +% +INC_DENSITY_MODEL= VARIABLE +INC_ENERGY_EQUATION = YES +INC_VELOCITY_INIT= (1.13, 0.0, 0.0 ) +INC_TEMPERATURE_INIT= 300.0 +THERMODYNAMIC_PRESSURE= 101325 +INC_NONDIM= DIMENSIONAL + +% -------------------- FLUID MODEL --------------------------------------- % +% +FLUID_MODEL= FLUID_FLAMELET +VISCOSITY_MODEL= FLAMELET +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) +PREFERENTIAL_DIFFUSION= YES + +% -------------------- SCALAR TRANSPORT ---------------------------------------% +% +% Using an artificial spark to ignite the solution at some location and iteration +FLAME_INIT_METHOD= SPARK +% Spark parameters in order: +% x-location of spark center (m) +% y-location of spark center (m) +% z-location of spark center (m) +% Spark radius (m) +% Iteration at which the artificial spark starts +% Spark iteration duration +SPARK_INIT= (0.001, 0.0004, 0, 5e-4, 10, 10) + +% Controlling variable source terms applied within the spark sphere for the spark +% duration. +SPARK_REACTION_RATES= (1000, 0, 0) + +SPECIES_INIT = (-0.49904325357252965, 2226.901776784524, 0.01446751783896619) + +% Passive reactants in flamelet problem + +CONTROLLING_VARIABLE_NAMES= (ProgressVariable, EnthalpyTot, MixtureFraction) +CONTROLLING_VARIABLE_SOURCE_NAMES= (ProdRateTot_PV, NULL, NULL) + +SPECIES_CLIPPING=YES +SPECIES_CLIPPING_MAX=+4.5623852432084366e-01 +8.6731375409855954e+06 1.0 +SPECIES_CLIPPING_MIN= -6.8059708053507162e-01 -4.9308262569627967e+06 0.0 + +MARKER_INLET_SPECIES = (inlet, -0.49904325357252965, 2226.901776784524, 0.01446751783896619) + +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +MARKER_ISOTHERMAL= (burner_wall, 300, hex_wall, 300) +MARKER_SYM= (sides) +INC_INLET_TYPE= VELOCITY_INLET +MARKER_INLET = (inlet, 300.000, 0.575, 1.0, 0.0, 0.0) +INC_OUTLET_TYPE= PRESSURE_OUTLET +MARKER_OUTLET= (outlet, 0.0) +MARKER_ANALYZE_AVERAGE = AREA + +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +NUM_METHOD_GRAD= GREEN_GAUSS +CFL_NUMBER =50 +CFL_ADAPT= NO +ITER=5 +OUTPUT_WRT_FREQ= 20 +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +LINEAR_SOLVER= FGMRES +LINEAR_SOLVER_PREC= ILU +LINEAR_SOLVER_ERROR= 1E-4 +LINEAR_SOLVER_ITER=20 +% +% -------------------- FLOW AND SPECIES NUMERICAL METHOD DEFINITION -----------------------% +% +CONV_NUM_METHOD_FLOW= FDS +CONV_NUM_METHOD_SPECIES= BOUNDED_SCALAR +MUSCL_FLOW= YES +MUSCL_SPECIES= YES +SLOPE_LIMITER_FLOW = NONE +SLOPE_LIMITER_SPECIES= NONE +TIME_DISCRE_FLOW= EULER_IMPLICIT +TIME_DISCRE_SPECIES= EULER_IMPLICIT + +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +CONV_FIELD = RMS_EnthalpyTot +CONV_RESIDUAL_MINVAL= -5 +CONV_STARTITER= 20 +SCREEN_OUTPUT = INNER_ITER RMS_PRESSURE RMS_ProgressVariable RMS_EnthalpyTot RMS_MixtureFraction +HISTORY_OUTPUT = WALL_TIME RMS_RES +VOLUME_OUTPUT = SOLUTION + +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +MESH_FORMAT= SU2 +MESH_FILENAME = 2Dhex_BL.su2 +OUTPUT_FILES = (RESTART,PARAVIEW) +TABULAR_FORMAT = CSV +CONV_FILENAME= history +VOLUME_FILENAME= flow + + diff --git a/TestCases/hybrid_regression.py b/TestCases/hybrid_regression.py index 8745a96f610..bd7635e1413 100644 --- a/TestCases/hybrid_regression.py +++ b/TestCases/hybrid_regression.py @@ -561,7 +561,7 @@ def main(): Jones_tc_restart.cfg_dir = "turbomachinery/APU_turbocharger" Jones_tc_restart.cfg_file = "Jones_restart.cfg" Jones_tc_restart.test_iter = 5 - Jones_tc_restart.test_vals = [-6.594590, -2.792279, -14.336129, -8.776066, -11.371439, -5.845633, 73273, 73273, 0.019884, 82.491] + Jones_tc_restart.test_vals = [-6.614623, -3.001323, -14.336147, -8.776081, -11.382919, -5.852327, 73273, 73273, 0.019884, 82.491] test_list.append(Jones_tc_restart) # 2D axial stage diff --git a/TestCases/parallel_regression.py b/TestCases/parallel_regression.py index cf1bd627e38..05cca0d50fb 100644 --- a/TestCases/parallel_regression.py +++ b/TestCases/parallel_regression.py @@ -69,6 +69,15 @@ def main(): cfd_flamelet_ch4_partial_premix.new_output = True test_list.append(cfd_flamelet_ch4_partial_premix) + # 2D planar laminar premixed hydrogen flame on isothermal burner with heat exchanger emulator (restart) + cfd_flamelet_h2 = TestCase('cfd_flamelet_h2') + cfd_flamelet_h2.cfg_dir = "flamelet/07_laminar_premixed_h2_flame_cfd" + cfd_flamelet_h2.cfg_file = "laminar_premixed_h2_flame_cfd.cfg" + cfd_flamelet_h2.test_iter = 5 + cfd_flamelet_h2.test_vals = [-10.003106, -9.843748, -3.289857, -11.338273] + cfd_flamelet_h2.new_output = True + test_list.append(cfd_flamelet_h2) + ######################### ## NEMO solver ### ######################### @@ -1044,12 +1053,21 @@ def main(): ### Turbomachinery ### ###################################### + # Aachen Turbine restart + Aachen_3D_restart = TestCase('aachen_turbine_restart') + Aachen_3D_restart.cfg_dir = "turbomachinery/Aachen_turbine" + Aachen_3D_restart.cfg_file = "aachen_3D_MP_restart.cfg" + Aachen_3D_restart.test_iter = 5 + Aachen_3D_restart.enabled_with_asan = False + Aachen_3D_restart.test_vals = [-9.853215, -8.891480, -9.610418, -8.028579, -7.792957, -4.384186] + test_list.append(Aachen_3D_restart) + # Jones APU Turbocharger restart Jones_tc_restart = TestCase('jones_turbocharger_restart') Jones_tc_restart.cfg_dir = "turbomachinery/APU_turbocharger" Jones_tc_restart.cfg_file = "Jones_restart.cfg" Jones_tc_restart.test_iter = 5 - Jones_tc_restart.test_vals = [-6.594590, -2.792281, -14.336129, -8.776067, -11.371439, -5.845633, 73273, 73273, 0.019884, 82.491] + Jones_tc_restart.test_vals = [-6.614623, -3.001323, -14.336147, -8.776081, -11.382919, -5.852327, 73273, 73273, 0.019884, 82.491] test_list.append(Jones_tc_restart) # 2D axial stage @@ -1057,8 +1075,8 @@ def main(): axial_stage2D.cfg_dir = "turbomachinery/axial_stage_2D" axial_stage2D.cfg_file = "Axial_stage2D.cfg" axial_stage2D.test_iter = 20 - axial_stage2D.test_vals = [0.983754, 1.534455, -2.888523, 2.606770, -2.418403, 3.087203, 106380, 106380, 5.7325, 64.711] - axial_stage2D.test_vals_aarch64 = [0.983754, 1.534455, -2.888523, 2.606770, -2.418403, 3.087203, 106380, 106380, 5.7325, 64.711] + axial_stage2D.test_vals = [0.983754, 1.534455, -2.888523, 2.606770, -2.418403, 3.087203, 106380, 106380, 5.7325, 64.711] + axial_stage2D.test_vals_aarch64 = [0.983754, 1.534455, -2.888523, 2.606770, -2.418403, 3.087203, 106380, 106380, 5.7325, 64.711] test_list.append(axial_stage2D) # 2D transonic stator restart @@ -1066,7 +1084,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 = [-5.011834, -3.091110, -2.757795, 1.087934, -3.544707, 2.166101, -471630, 94.868, -0.035888] + transonic_stator_restart.test_vals = [-5.011834, -3.091110, -2.757795, 1.087934, -3.544707, 2.166101, -471630, 94.868, -0.035888] transonic_stator_restart.test_vals_aarch64 = [-5.011834, -3.091110, -2.757795, 1.087934, -3.544707, 2.166101, -471630, 94.868, -0.035888] test_list.append(transonic_stator_restart) @@ -1297,6 +1315,7 @@ def main(): sp_pinArray_3d_cht_mf_hf_tp.multizone = True test_list.append(sp_pinArray_3d_cht_mf_hf_tp) + ########################## ### Python wrapper ### ########################## @@ -1370,7 +1389,7 @@ def main(): pywrapper_unsteadyFSI.test_iter = 4 pywrapper_unsteadyFSI.test_vals = [0, 31, 5, 58, -1.756780, -2.828276, -7.652558, -6.863929, 1.5618e-04] pywrapper_unsteadyFSI.command = TestCase.Command("mpirun -np 2", "python", "run.py") - pywrapper_unsteadyFSI.unsteady = True + pywrapper_unsteadyFSI.unsteady = True pywrapper_unsteadyFSI.multizone = True test_list.append(pywrapper_unsteadyFSI) @@ -1562,13 +1581,13 @@ def main(): ##################### # CGNS writer - cgns_writer = TestCase('cgns_writer') - cgns_writer.cfg_dir = "cgns_writer" - cgns_writer.cfg_file = "config.cfg" - cgns_writer.test_iter = 1 - cgns_writer.test_vals = [-2.974473, 0.665204, 5.068846, -7.003873] - cgns_writer.command = TestCase.Command("mpirun -n 2", "SU2_CFD") - cgns_writer.new_output = True + cgns_writer = TestCase('cgns_writer') + cgns_writer.cfg_dir = "cgns_writer" + cgns_writer.cfg_file = "config.cfg" + cgns_writer.test_iter = 1 + cgns_writer.test_vals = [-2.974473, 0.665204, 5.068846, -7.003873] + cgns_writer.command = TestCase.Command("mpirun -n 2", "SU2_CFD") + cgns_writer.new_output = True test_list.append(cgns_writer) ###################################### @@ -1798,14 +1817,14 @@ def main(): test_list.append(sphere_ffd_def_bspline) # Inviscid NACA0012 (triangles) - naca0012_cst = TestCase('naca0012_cst') - naca0012_cst.cfg_dir = "deformation/cst" - naca0012_cst.cfg_file = "naca0012.cfg" + naca0012_cst = TestCase('naca0012_cst') + naca0012_cst.cfg_dir = "deformation/cst" + naca0012_cst.cfg_file = "naca0012.cfg" naca0012_cst.test_iter = 10 naca0012_cst.test_vals = [0.000385514] #residual - naca0012_cst.command = TestCase.Command("mpirun -n 2", "SU2_DEF") - naca0012_cst.timeout = 1600 - naca0012_cst.tol = 1e-8 + naca0012_cst.command = TestCase.Command("mpirun -n 2", "SU2_DEF") + naca0012_cst.timeout = 1600 + naca0012_cst.tol = 1e-8 pass_list.append(naca0012_cst.run_def()) test_list.append(naca0012_cst) diff --git a/TestCases/py_wrapper/custom_inlet/lam_flatplate.cfg b/TestCases/py_wrapper/custom_inlet/lam_flatplate.cfg new file mode 100644 index 00000000000..bc9ea1fc61f --- /dev/null +++ b/TestCases/py_wrapper/custom_inlet/lam_flatplate.cfg @@ -0,0 +1,97 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Test custom inlets via Python wrapper. % +% Author: P. Gomes % +% Date: 2nd Jun 2024 % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +SOLVER= NAVIER_STOKES +KIND_TURB_MODEL= NONE +RESTART_SOL= NO +% +TIME_DOMAIN= YES +TIME_STEP= 0.005 +TIME_MARCHING= DUAL_TIME_STEPPING-2ND_ORDER +% +SCREEN_OUTPUT= TIME_ITER, INNER_ITER, RMS_RES, LINSOL_RESIDUAL, FORCE_X, SURFACE_MASSFLOW +HISTORY_OUTPUT = ITER, RMS_RES, AERO_COEFF, FLOW_COEFF, FLOW_COEFF_SURF + +% -------------------- COMPRESSIBLE FREE-STREAM DEFINITION --------------------% +% +MACH_NUMBER= 0.1 +INIT_OPTION= TD_CONDITIONS +FREESTREAM_OPTION= TEMPERATURE_FS +FREESTREAM_TEMPERATURE= 297.62 +REYNOLDS_NUMBER= 600 +REYNOLDS_LENGTH= 0.02 + +% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% +% +REF_ORIGIN_MOMENT_X = 0.00 +REF_ORIGIN_MOMENT_Y = 0.00 +REF_ORIGIN_MOMENT_Z = 0.00 +REF_LENGTH= 0.02 +REF_AREA= 0.02 +% +FLUID_MODEL= IDEAL_GAS +GAMMA_VALUE= 1.4 +GAS_CONSTANT= 287.87 +VISCOSITY_MODEL= CONSTANT_VISCOSITY +MU_CONSTANT= 0.001 + +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +MARKER_HEATFLUX= ( y_minus, 0.0 ) +MARKER_SYM= ( y_plus ) +% +MARKER_INLET= ( x_minus, 300.0, 100000.0, 1.0, 0.0, 0.0 ) +MARKER_OUTLET= ( x_plus, 99000.0 ) +% +MARKER_PLOTTING= ( y_minus ) +MARKER_MONITORING= ( y_minus ) +MARKER_ANALYZE= ( x_minus, x_plus ) + +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +NUM_METHOD_GRAD= GREEN_GAUSS +CFL_NUMBER= 1e3 +CFL_ADAPT= NO +TIME_DISCRE_FLOW= EULER_IMPLICIT +% +MGLEVEL= 2 +MGCYCLE= V_CYCLE +MG_PRE_SMOOTH= ( 1, 1, 1 ) +MG_POST_SMOOTH= ( 0, 0, 0 ) +MG_DAMP_RESTRICTION= 0.5 +MG_DAMP_PROLONGATION= 0.5 + +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +LINEAR_SOLVER= FGMRES +LINEAR_SOLVER_PREC= ILU +LINEAR_SOLVER_ERROR= 0.2 +LINEAR_SOLVER_ITER= 5 + +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +CONV_NUM_METHOD_FLOW= ROE +MUSCL_FLOW= YES +SLOPE_LIMITER_FLOW= NONE + +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +INNER_ITER= 100 +CONV_RESIDUAL_MINVAL= -2 +CONV_FIELD= REL_RMS_DENSITY +CONV_STARTITER= 0 +MAX_TIME= 0.5 +TIME_ITER= 21 + +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +MESH_FORMAT= RECTANGLE +MESH_BOX_LENGTH= (0.1, 0.01, 0) +MESH_BOX_SIZE= (65, 17, 0) + diff --git a/TestCases/py_wrapper/custom_inlet/run.py b/TestCases/py_wrapper/custom_inlet/run.py new file mode 100644 index 00000000000..cc804c4ec89 --- /dev/null +++ b/TestCases/py_wrapper/custom_inlet/run.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python + +## \file run.py +# \brief Unsteady inlet boundary conditions. +# \version 8.0.1 "Harrier" +# +# SU2 Project Website: https://su2code.github.io +# +# The SU2 Project is maintained by the SU2 Foundation +# (http://su2foundation.org) +# +# Copyright 2012-2024, 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 . + +import sys +import pysu2 +import math +# from mpi4py import MPI + +def main(): + """ + Run the flow solver with a custom inlet (function of time and space). + """ + # comm = MPI.COMM_WORLD + comm = 0 + + # Initialize the primal driver of SU2, this includes solver preprocessing. + try: + driver = pysu2.CSinglezoneDriver('lam_flatplate.cfg', 1, comm) + except TypeError as exception: + print('A TypeError occured in pysu2.CSinglezoneDriver : ', exception) + raise + + # Get the ID of the inlet marker. + all_marker_ids = driver.GetMarkerIndices() + marker_name = 'x_minus' + marker_id = all_marker_ids[marker_name] if marker_name in all_marker_ids else -1 + + # Run the time loop in python to vary the inlet conditions. + dt = driver.GetUnsteadyTimeStep() + + print("\n------------------------------ Begin Solver -----------------------------") + sys.stdout.flush() + + for time_iter in range(driver.GetNumberTimeIter()): + # Change the total pressure. + if marker_id >= 0: + for i_vertex in range(driver.GetNumberMarkerNodes(marker_id)): + y = driver.MarkerCoordinates(marker_id)(i_vertex, 1) + t = time_iter * dt + pt = 1e5 + 2e4 * y / 0.01 * (1 - math.cos(2 * math.pi * t / 0.1)) + driver.SetMarkerCustomInletFlowVar1(marker_id, i_vertex, pt) + driver.BoundaryConditionsUpdate() + + driver.Preprocess(time_iter) + + # Run one time iteration. + driver.Run() + driver.Postprocess() + driver.Update() + + # Monitor the solver and output solution to file if required. + driver.Monitor(time_iter) + driver.Output(time_iter) + + # Finalize the solver and exit cleanly. + driver.Finalize() + +if __name__ == '__main__': + main() diff --git a/TestCases/py_wrapper/flatPlate_rigidMotion/launch_flatPlate_rigidMotion.py b/TestCases/py_wrapper/flatPlate_rigidMotion/launch_flatPlate_rigidMotion.py index 138351cdf58..8b66256bd1a 100755 --- a/TestCases/py_wrapper/flatPlate_rigidMotion/launch_flatPlate_rigidMotion.py +++ b/TestCases/py_wrapper/flatPlate_rigidMotion/launch_flatPlate_rigidMotion.py @@ -62,7 +62,7 @@ def main(): # Initialize the corresponding driver of SU2, this includes solver preprocessing try: - SU2Driver = pysu2.CSinglezoneDriver(options.filename, options.nZone, comm); + SU2Driver = pysu2.CSinglezoneDriver(options.filename, options.nZone, comm) except TypeError as exception: print('A TypeError occured in pysu2.CDriver : ',exception) if options.with_MPI == True: diff --git a/TestCases/serial_regression.py b/TestCases/serial_regression.py index cecb6408e22..fcdacb032a7 100644 --- a/TestCases/serial_regression.py +++ b/TestCases/serial_regression.py @@ -28,12 +28,15 @@ from __future__ import print_function, division, absolute_import import sys from TestCase import TestCase +from TestCase import parse_args def main(): '''This program runs SU2 and ensures that the output matches specified values. This will be used to do checks when code is pushed to github to make sure nothing is broken. ''' + args = parse_args('Serial Regression Tests') + test_list = [] ######################### @@ -852,12 +855,20 @@ def main(): ### Turbomachinery ### ###################################### + # Aachen Turbine restart + Aachen_3D_restart = TestCase('aachen_turbine_restart') + Aachen_3D_restart.cfg_dir = "turbomachinery/Aachen_turbine" + Aachen_3D_restart.cfg_file = "aachen_3D_MP_restart.cfg" + Aachen_3D_restart.test_iter = 5 + Aachen_3D_restart.test_vals = [-9.853207, -8.891479, -9.610411, -8.028566, -7.792947, -4.384177] + test_list.append(Aachen_3D_restart) + # Jones APU Turbocharger restart Jones_tc_restart = TestCase('jones_turbocharger_restart') Jones_tc_restart.cfg_dir = "turbomachinery/APU_turbocharger" Jones_tc_restart.cfg_file = "Jones_restart.cfg" Jones_tc_restart.test_iter = 5 - Jones_tc_restart.test_vals = [-6.594586, -2.792279, -14.336132, -8.776068, -11.371439, -5.845632, 73273, 73273, 0.019884, 82.491] + Jones_tc_restart.test_vals = [-6.614623, -3.001323, -14.336147, -8.776081, -11.382919, -5.852327, 73273, 73273, 0.019884, 82.491] test_list.append(Jones_tc_restart) # 2D axial stage @@ -1188,7 +1199,7 @@ def main(): if test.tol == 0.0: test.tol = 0.00001 - pass_list = [ test.run_test() for test in test_list ] + pass_list = [ test.run_test(args.tsan, args.asan) for test in test_list ] ###################################### @@ -1203,7 +1214,7 @@ def main(): naca0012_geo.command = TestCase.Command(exec = "SU2_GEO") naca0012_geo.timeout = 1600 naca0012_geo.tol = 0.00001 - pass_list.append(naca0012_geo.run_geo()) + pass_list.append(naca0012_geo.run_geo(args.tsan, args.asan)) test_list.append(naca0012_geo) ###################################### @@ -1220,7 +1231,7 @@ def main(): intersect_def.timeout = 1600 intersect_def.tol = 1e-04 - pass_list.append(intersect_def.run_def()) + pass_list.append(intersect_def.run_def(args.tsan, args.asan)) test_list.append(intersect_def) # Inviscid NACA0012 (triangles) @@ -1233,7 +1244,7 @@ def main(): naca0012_def.timeout = 1600 naca0012_def.tol = 1e-08 - pass_list.append(naca0012_def.run_def()) + pass_list.append(naca0012_def.run_def(args.tsan, args.asan)) test_list.append(naca0012_def) # Inviscid NACA0012 based on SURFACE_FILE input (surface_bump.dat) @@ -1246,7 +1257,7 @@ def main(): naca0012_def_file.timeout = 1600 naca0012_def_file.tol = 1e-8 - pass_list.append(naca0012_def_file.run_def()) + pass_list.append(naca0012_def_file.run_def(args.tsan, args.asan)) test_list.append(naca0012_def_file) # RAE2822 (mixed tris + quads) @@ -1259,7 +1270,7 @@ def main(): rae2822_def.timeout = 1600 rae2822_def.tol = 1e-13 - pass_list.append(rae2822_def.run_def()) + pass_list.append(rae2822_def.run_def(args.tsan, args.asan)) test_list.append(rae2822_def) # Turb NACA4412 (quads, wall distance) @@ -1272,7 +1283,7 @@ def main(): naca4412_def.timeout = 1600 naca4412_def.tol = 1e-12 - pass_list.append(naca4412_def.run_def()) + pass_list.append(naca4412_def.run_def(args.tsan, args.asan)) test_list.append(naca4412_def) # Brick of tets (inverse volume) @@ -1285,7 +1296,7 @@ def main(): brick_tets_def.timeout = 1600 brick_tets_def.tol = 1e-09 - pass_list.append(brick_tets_def.run_def()) + pass_list.append(brick_tets_def.run_def(args.tsan, args.asan)) test_list.append(brick_tets_def) # Brick of isotropic hexas (inverse volume) @@ -1298,7 +1309,7 @@ def main(): brick_hex_def.timeout = 1600 brick_hex_def.tol = 1e-09 - pass_list.append(brick_hex_def.run_def()) + pass_list.append(brick_hex_def.run_def(args.tsan, args.asan)) test_list.append(brick_hex_def) # Brick with a pyramid layer (inverse volume) @@ -1311,7 +1322,7 @@ def main(): brick_pyra_def.timeout = 1600 brick_pyra_def.tol = 1e-08 - pass_list.append(brick_pyra_def.run_def()) + pass_list.append(brick_pyra_def.run_def(args.tsan, args.asan)) test_list.append(brick_pyra_def) # Brick of isotropic prisms (inverse volume) @@ -1324,7 +1335,7 @@ def main(): brick_prism_def.timeout = 1600 brick_prism_def.tol = 1e-08 - pass_list.append(brick_prism_def.run_def()) + pass_list.append(brick_prism_def.run_def(args.tsan, args.asan)) test_list.append(brick_prism_def) # Brick of prisms with high aspect ratio cells near the wall (wall distance) @@ -1337,7 +1348,7 @@ def main(): brick_prism_rans_def.timeout = 1600 brick_prism_rans_def.tol = 1e-12 - pass_list.append(brick_prism_rans_def.run_def()) + pass_list.append(brick_prism_rans_def.run_def(args.tsan, args.asan)) test_list.append(brick_prism_rans_def) # Brick of hexas with high aspect ratio cells near the wall (inverse volume) @@ -1350,7 +1361,7 @@ def main(): brick_hex_rans_def.timeout = 1600 brick_hex_rans_def.tol = 1e-12 - pass_list.append(brick_hex_rans_def.run_def()) + pass_list.append(brick_hex_rans_def.run_def(args.tsan, args.asan)) test_list.append(brick_hex_rans_def) # Cylindrical FFD test @@ -1363,7 +1374,7 @@ def main(): cylinder_ffd_def.timeout = 1600 cylinder_ffd_def.tol = 1e-09 - pass_list.append(cylinder_ffd_def.run_def()) + pass_list.append(cylinder_ffd_def.run_def(args.tsan, args.asan)) test_list.append(cylinder_ffd_def) # Spherical FFD test @@ -1376,7 +1387,7 @@ def main(): sphere_ffd_def.timeout = 1600 sphere_ffd_def.tol = 1e-08 - pass_list.append(sphere_ffd_def.run_def()) + pass_list.append(sphere_ffd_def.run_def(args.tsan, args.asan)) test_list.append(sphere_ffd_def) # Spherical FFD test using BSplines @@ -1389,7 +1400,7 @@ def main(): sphere_ffd_def_bspline.timeout = 1600 sphere_ffd_def_bspline.tol = 1e-08 - pass_list.append(sphere_ffd_def_bspline.run_def()) + pass_list.append(sphere_ffd_def_bspline.run_def(args.tsan, args.asan)) test_list.append(sphere_ffd_def_bspline) ###################################### @@ -1405,7 +1416,8 @@ def main(): contadj_euler_py.timeout = 1600 contadj_euler_py.reference_file = "of_grad_cd.dat.ref" contadj_euler_py.test_file = "of_grad_cd.dat" - pass_list.append(contadj_euler_py.run_filediff()) + contadj_euler_py.enabled_with_asan = False + pass_list.append(contadj_euler_py.run_filediff(args.tsan, args.asan)) test_list.append(contadj_euler_py) # test shape_optimization.py @@ -1417,7 +1429,8 @@ def main(): shape_opt_euler_py.command = TestCase.Command(exec = "shape_optimization.py", param = "-g CONTINUOUS_ADJOINT -f") shape_opt_euler_py.timeout = 1600 shape_opt_euler_py.tol = 0.00001 - pass_list.append(shape_opt_euler_py.run_opt()) + shape_opt_euler_py.enabled_with_asan = False + pass_list.append(shape_opt_euler_py.run_opt(args.tsan, args.asan)) test_list.append(shape_opt_euler_py) # Multiple functionals with the continuous adjoint @@ -1429,7 +1442,8 @@ def main(): contadj_multi_py.timeout = 1600 contadj_multi_py.reference_file = "of_grad_combo.dat.ref" contadj_multi_py.test_file = "of_grad_combo.dat" - pass_list.append(contadj_multi_py.run_filediff()) + contadj_multi_py.enabled_with_asan = False + pass_list.append(contadj_multi_py.run_filediff(args.tsan, args.asan)) test_list.append(contadj_multi_py) # Optimization with multiple objectives, with gradients evaluated individually @@ -1467,7 +1481,8 @@ def main(): 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 - pass_list.append(opt_multiobj1surf_py.run_opt()) + opt_multiobj1surf_py.enabled_with_asan = False + pass_list.append(opt_multiobj1surf_py.run_opt(args.tsan, args.asan)) test_list.append(opt_multiobj1surf_py) # test optimization, with a single objective evaluated on multiple surfaces @@ -1479,7 +1494,8 @@ def main(): 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 - pass_list.append(opt_2surf1obj_py.run_opt()) + opt_2surf1obj_py.enabled_with_asan = False + pass_list.append(opt_2surf1obj_py.run_opt(args.tsan, args.asan)) test_list.append(opt_2surf1obj_py) ########################## @@ -1495,8 +1511,9 @@ def main(): pywrapper_naca0012.command = TestCase.Command(exec = "SU2_CFD.py", param = "-f") pywrapper_naca0012.timeout = 1600 pywrapper_naca0012.tol = 0.00001 + pywrapper_naca0012.enabled_with_asan = False test_list.append(pywrapper_naca0012) - pass_list.append(pywrapper_naca0012.run_test()) + pass_list.append(pywrapper_naca0012.run_test(args.tsan, args.asan)) # NACA0012 (SST, FUN3D results for finest grid: CL=1.0840, CD=0.01253) pywrapper_turb_naca0012_sst = TestCase('pywrapper_turb_naca0012_sst') @@ -1508,8 +1525,9 @@ def main(): pywrapper_turb_naca0012_sst.command = TestCase.Command(exec = "SU2_CFD.py", param = "-f") pywrapper_turb_naca0012_sst.timeout = 3200 pywrapper_turb_naca0012_sst.tol = 0.00001 + pywrapper_turb_naca0012_sst.enabled_with_asan = False test_list.append(pywrapper_turb_naca0012_sst) - pass_list.append(pywrapper_turb_naca0012_sst.run_test()) + pass_list.append(pywrapper_turb_naca0012_sst.run_test(args.tsan, args.asan)) # Square cylinder pywrapper_square_cylinder = TestCase('pywrapper_square_cylinder') @@ -1521,8 +1539,9 @@ def main(): pywrapper_square_cylinder.timeout = 1600 pywrapper_square_cylinder.tol = 0.00001 pywrapper_square_cylinder.unsteady = True + pywrapper_square_cylinder.enabled_with_asan = False test_list.append(pywrapper_square_cylinder) - pass_list.append(pywrapper_square_cylinder.run_test()) + pass_list.append(pywrapper_square_cylinder.run_test(args.tsan, args.asan)) # Aeroelastic pywrapper_aeroelastic = TestCase('pywrapper_aeroelastic') @@ -1534,8 +1553,9 @@ def main(): pywrapper_aeroelastic.timeout = 1600 pywrapper_aeroelastic.tol = 0.00001 pywrapper_aeroelastic.unsteady = True + pywrapper_aeroelastic.enabled_with_asan = False test_list.append(pywrapper_aeroelastic) - pass_list.append(pywrapper_aeroelastic.run_test()) + pass_list.append(pywrapper_aeroelastic.run_test(args.tsan, args.asan)) # FSI, 2d pywrapper_fsi2d = TestCase('pywrapper_fsi2d') @@ -1548,8 +1568,9 @@ def main(): pywrapper_fsi2d.multizone = True pywrapper_fsi2d.timeout = 1600 pywrapper_fsi2d.tol = 0.00001 + pywrapper_fsi2d.enabled_with_asan = False test_list.append(pywrapper_fsi2d) - pass_list.append(pywrapper_fsi2d.run_test()) + pass_list.append(pywrapper_fsi2d.run_test(args.tsan, args.asan)) # Unsteady CHT pywrapper_unsteadyCHT = TestCase('pywrapper_unsteadyCHT') @@ -1561,8 +1582,9 @@ def main(): pywrapper_unsteadyCHT.timeout = 1600 pywrapper_unsteadyCHT.tol = 0.00001 pywrapper_unsteadyCHT.unsteady = True + pywrapper_unsteadyCHT.enabled_with_asan = False test_list.append(pywrapper_unsteadyCHT) - pass_list.append(pywrapper_unsteadyCHT.run_test()) + pass_list.append(pywrapper_unsteadyCHT.run_test(args.tsan, args.asan)) # Rigid motion pywrapper_rigidMotion = TestCase('pywrapper_rigidMotion') @@ -1574,8 +1596,23 @@ def main(): pywrapper_rigidMotion.timeout = 1600 pywrapper_rigidMotion.tol = 0.00001 pywrapper_rigidMotion.unsteady = True + pywrapper_rigidMotion.enabled_with_asan = False test_list.append(pywrapper_rigidMotion) - pass_list.append(pywrapper_rigidMotion.run_test()) + pass_list.append(pywrapper_rigidMotion.run_test(args.tsan, args.asan)) + + # Custom inlet + pywrapper_custom_inlet = TestCase('pywrapper_custom_inlet') + 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.124164, -1.544359, -3.808866, 1.338411, -0.752679, 0.161436, -1.2391e-02, 5.1662e-01, -5.2901e-01] + pywrapper_custom_inlet.command = TestCase.Command(exec = "python", param = "run.py") + pywrapper_custom_inlet.timeout = 1600 + pywrapper_custom_inlet.tol = 0.0001 + pywrapper_custom_inlet.unsteady = True + pywrapper_custom_inlet.enabled_with_asan = False + test_list.append(pywrapper_custom_inlet) + pass_list.append(pywrapper_custom_inlet.run_test(args.tsan, args.asan)) # Tests summary print('==================================================================') diff --git a/TestCases/serial_regression_AD.py b/TestCases/serial_regression_AD.py index 2a0ac757097..ac268040cd5 100644 --- a/TestCases/serial_regression_AD.py +++ b/TestCases/serial_regression_AD.py @@ -30,12 +30,15 @@ import sys from TestCase import TestCase +from TestCase import parse_args def main(): '''This program runs SU2 and ensures that the output matches specified values. This will be used to do checks when code is pushed to github to make sure nothing is broken. ''' + args = parse_args('Serial Regression AD Tests') + test_list = [] ##################################### @@ -223,7 +226,7 @@ def main(): if test.tol == 0.0: test.tol = 0.00001 - pass_list = [ test.run_test() for test in test_list ] + pass_list = [ test.run_test(args.tsan, args.asan) for test in test_list ] ################################### ### Coupled RHT-CFD Adjoint ### @@ -239,7 +242,8 @@ def main(): discadj_rht.reference_file = "of_grad_cd.csv.ref" discadj_rht.reference_file_aarch64 = "of_grad_cd_aarch64.csv.ref" discadj_rht.test_file = "of_grad_cd.csv" - pass_list.append(discadj_rht.run_filediff()) + discadj_rht.enabled_with_asan = False + pass_list.append(discadj_rht.run_filediff(args.tsan, args.asan)) test_list.append(discadj_rht) ###################################### @@ -256,7 +260,8 @@ def main(): discadj_euler_py.reference_file = "of_grad_cd_disc.dat.ref" discadj_euler_py.reference_file_aarch64 = "of_grad_cd_disc_aarch64.dat.ref" discadj_euler_py.test_file = "of_grad_cd.dat" - pass_list.append(discadj_euler_py.run_filediff()) + discadj_euler_py.enabled_with_asan = False + pass_list.append(discadj_euler_py.run_filediff(args.tsan, args.asan)) test_list.append(discadj_euler_py) # test discrete_adjoint with multiple ffd boxes @@ -269,7 +274,8 @@ def main(): discadj_multiple_ffd_py.reference_file = "of_grad_cd.dat.ref" discadj_multiple_ffd_py.reference_file_aarch64 = "of_grad_cd_aarch64.dat.ref" discadj_multiple_ffd_py.test_file = "of_grad_cd.dat" - pass_list.append(discadj_multiple_ffd_py.run_filediff()) + discadj_multiple_ffd_py.enabled_with_asan = False + pass_list.append(discadj_multiple_ffd_py.run_filediff(args.tsan, args.asan)) test_list.append(discadj_multiple_ffd_py) # test direct_differentiation.py @@ -282,7 +288,8 @@ def main(): directdiff_euler_py.reference_file = "of_grad_directdiff.dat.ref" directdiff_euler_py.reference_file_aarch64 = "of_grad_directdiff_aarch64.dat.ref" directdiff_euler_py.test_file = "DIRECTDIFF/of_grad_directdiff.dat" - pass_list.append(directdiff_euler_py.run_filediff()) + directdiff_euler_py.enabled_with_asan = False + pass_list.append(directdiff_euler_py.run_filediff(args.tsan, args.asan)) test_list.append(directdiff_euler_py) # test direct_differentiation.py with multiple ffd boxes @@ -295,7 +302,8 @@ def main(): directdiff_multiple_ffd_py.reference_file = "of_grad_directdiff.dat.ref" directdiff_multiple_ffd_py.reference_file_aarch64 = "of_grad_directdiff_aarch64.dat.ref" directdiff_multiple_ffd_py.test_file = "DIRECTDIFF/of_grad_directdiff.dat" - pass_list.append(directdiff_multiple_ffd_py.run_filediff()) + directdiff_multiple_ffd_py.enabled_with_asan = False + pass_list.append(directdiff_multiple_ffd_py.run_filediff(args.tsan, args.asan)) test_list.append(directdiff_multiple_ffd_py) # test continuous_adjoint.py, with multiple objectives @@ -320,8 +328,9 @@ def main(): pywrapper_FEA_AD_FlowLoad.timeout = 1600 pywrapper_FEA_AD_FlowLoad.tol = 0.000001 pywrapper_FEA_AD_FlowLoad.new_output = False + pywrapper_FEA_AD_FlowLoad.enabled_with_asan = False test_list.append(pywrapper_FEA_AD_FlowLoad) - pass_list.append(pywrapper_FEA_AD_FlowLoad.run_test()) + pass_list.append(pywrapper_FEA_AD_FlowLoad.run_test(args.tsan, args.asan)) # Flow AD Mesh Displacement Sensitivity pywrapper_CFD_AD_MeshDisp = TestCase('pywrapper_CFD_AD_MeshDisp') @@ -333,8 +342,9 @@ def main(): pywrapper_CFD_AD_MeshDisp.timeout = 1600 pywrapper_CFD_AD_MeshDisp.tol = 0.000001 pywrapper_CFD_AD_MeshDisp.new_output = False + pywrapper_CFD_AD_MeshDisp.enabled_with_asan = False test_list.append(pywrapper_CFD_AD_MeshDisp) - pass_list.append(pywrapper_CFD_AD_MeshDisp.run_test()) + pass_list.append(pywrapper_CFD_AD_MeshDisp.run_test(args.tsan, args.asan)) ################################### @@ -350,7 +360,8 @@ def main(): grad_smooth_naca0012.reference_file = "of_hess.dat.ref" grad_smooth_naca0012.reference_file_aarch64 = "of_hess_aarch64.dat.ref" grad_smooth_naca0012.test_file = "of_hess.dat" - pass_list.append(grad_smooth_naca0012.run_filediff()) + grad_smooth_naca0012.enabled_with_asan = False + pass_list.append(grad_smooth_naca0012.run_filediff(args.tsan, args.asan)) test_list.append(grad_smooth_naca0012) # Tests summary diff --git a/TestCases/turbomachinery/Aachen_turbine/aachen_3D_MP_restart.cfg b/TestCases/turbomachinery/Aachen_turbine/aachen_3D_MP_restart.cfg new file mode 100644 index 00000000000..97f2e133e61 --- /dev/null +++ b/TestCases/turbomachinery/Aachen_turbine/aachen_3D_MP_restart.cfg @@ -0,0 +1,356 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: AACHEN turbine 3D % +% Author: S. Vitale, A. Cappiello % +% Institution: Delft University of Technology % +% Date: Oct 20th, 2023 % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +% Physical governing equations +SOLVER= RANS +% +% Specify turbulent model (NONE, SA, SST) +KIND_TURB_MODEL= SA +% +% Mathematical problem (DIRECT, ADJOINT, LINEARIZED) +MATH_PROBLEM= DIRECT +% +% Restart solution (NO, YES) +RESTART_SOL= YES +% +MULTIZONE= YES +% +% List of config files for zone-specific options +CONFIG_LIST=(stator1.cfg, rotor.cfg, stator2.cfg) +% +% -------------------- COMPRESSIBLE FREE-STREAM DEFINITION --------------------% +% +% Mach number (non-dimensional, based on the free-stream values) +MACH_NUMBER= 0.05 +% +% Angle of attack (degrees, only for compressible flows) +AOA= 0.0 +% +% Free-stream pressure (101325.0 N/m^2 by default, only Euler flows) +FREESTREAM_PRESSURE= 140000.0 +% +% Free-stream temperature (273.15 K by default) +FREESTREAM_TEMPERATURE= 300.0 +% +% Free-stream temperature (1.2886 Kg/m3 by default) +FREESTREAM_DENSITY= 1.7418 +% +% Free-stream option to choose if you want to use Density (DENSITY_FS) or Temperature TEMPERATURE_FS) to initialize the solution +FREESTREAM_OPTION= TEMPERATURE_FS +% +% Free-stream Turbulence Intensity +FREESTREAM_TURBULENCEINTENSITY = 0.025 +% +% Free-stream Turbulent to Laminar viscosity ratio +FREESTREAM_TURB2LAMVISCRATIO = 100.0 +% +% +%Init option to choose between Reynolds (default) or thermodynamics quantities for initializing the solution (REYNOLDS, TD_CONDITIONS) +INIT_OPTION= TD_CONDITIONS +% +% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% +% +% Reference origin for moment computation +REF_ORIGIN_MOMENT_X = 0.00 +REF_ORIGIN_MOMENT_Y = 0.00 +REF_ORIGIN_MOMENT_Z = 0.00 +% +% Reference area for force coefficients (0 implies automatic calculation) +REF_AREA= 1.0 +% +% Flow non-dimensionalization +REF_DIMENSIONALIZATION= DIMENSIONAL +% +% +% ------------------------------ EQUATION OF STATE ----------------------------% +% +% Different gas model (STANDARD_AIR, IDEAL_GAS, VW_GAS, PR_GAS) +FLUID_MODEL= IDEAL_GAS +% +% Ratio of specific heats (1.4 default and the value is hardcoded for the model STANDARD_AIR) +GAMMA_VALUE= 1.4 +% +% Specific gas constant (287.058 J/kg*K default and this value is hardcoded for the model STANDARD_AIR) +GAS_CONSTANT= 287.058 +% +% Critical Temperature (273.15 K by default) +CRITICAL_TEMPERATURE= 273.15 +% +% Critical Pressure (101325.0 N/m^2 by default) +CRITICAL_PRESSURE= 101325.0 +% +% Acentri factor (0.035 (air)) +ACENTRIC_FACTOR= 0.035 +% +% --------------------------- VISCOSITY MODEL ---------------------------------% +% +% Viscosity model (SUTHERLAND, CONSTANT_VISCOSITY). +VISCOSITY_MODEL= SUTHERLAND +% +% Molecular Viscosity that would be constant (1.716E-5 by default) +MU_CONSTANT= 1.716E-5 +% +% Sutherland Viscosity Ref (1.716E-5 default value for AIR SI) +MU_REF= 1.716E-5 +% +% Sutherland Temperature Ref (273.15 K default value for AIR SI) +MU_T_REF= 273.15 +% +% Sutherland constant (110.4 default value for AIR SI) +SUTHERLAND_CONSTANT= 110.4 +% +% --------------------------- THERMAL CONDUCTIVITY MODEL ----------------------% +% +% Conductivity model (CONSTANT_CONDUCTIVITY, CONSTANT_PRANDTL). +CONDUCTIVITY_MODEL= CONSTANT_PRANDTL +% +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +%Navier-Stokes wall boundary marker(s) (NONE = no marker) +MARKER_HEATFLUX= (BLADE1, 0.0, BLADE2, 0.0, BLADE3, 0.0, HUB1, 0.0, SHROUD1, 0.0, HUB2, 0.0, SHROUD2, 0.0, HUB3, 0.0, SHROUD3, 0.0) +% +% Periodic boundary marker(s) (NONE = no marker) +% Format: ( periodic marker, donor marker, rot_cen_x, rot_cen_y, rot_cen_z, rot_angle_x-axis, rot_angle_y-axis, rot_angle_z-axis, translation_x, translation_y, translation_z) +MARKER_PERIODIC= (PER1_STATOR1, PER2_STATOR1, 0.0, 0.0, 0.0, 0.0, 0.0, 8.7804878, 0.0, 0.0, 0.0, PER1_ROTOR, PER2_ROTOR, 0.0, 0.0, 0.0, 0.0, 0.0, 8.7804878, 0.0, 0.0, 0.0, PER1_STATOR2, PER2_STATOR2, 0.0, 0.0, 0.0, 0.0, 0.0, 8.7804878, 0.0, 0.0, 0.0) +% +% +%-------- INFLOW/OUTFLOW BOUNDARY CONDITION SPECIFIC FOR TURBOMACHINERY --------% +% +% Inflow and Outflow markers must be specified, for each blade (zone), following the natural groth of the machine (i.e, from the first blade to the last) +MARKER_TURBOMACHINERY= (INFLOW_STATOR1, OUTFLOW_STATOR1, INFLOW_ROTOR, OUTFLOW_ROTOR, INFLOW_STATOR2, OUTFLOW_STATOR2) +MARKER_ANALYZE = (INFLOW_STATOR1, OUTFLOW_STATOR2) +% Mixing-plane interface markers must be specified to activate the transfer of information between zones +MARKER_MIXINGPLANE_INTERFACE= (OUTFLOW_STATOR1, INFLOW_ROTOR, OUTFLOW_ROTOR, INFLOW_STATOR2) +% Mixing-plane interface markers must be specified to activate the transfer of information between zones +MARKER_ZONE_INTERFACE= (OUTFLOW_STATOR1, INFLOW_ROTOR, OUTFLOW_ROTOR, INFLOW_STATOR2) +% +% Non reflecting boundary condition for inflow, outfolw and mixing-plane +% Format inlet: ( marker, TOTAL_CONDITIONS_PT, Total Pressure , Total Temperature, Flow dir-norm, Flow dir-tang, Flow dir-span, under-relax-avg, under-relax-fourier) +% Format outlet: ( marker, STATIC_PRESSURE, Static Pressure value, -, -, -, -, under-relax-avg, under-relax-fourier) +% Format mixing-plane in and out: ( marker, MIXING_IN or MIXING_OUT, -, -, -, -, -, -, under-relax-avg, under-relax-fourier) +MARKER_GILES= (INFLOW_STATOR1, TOTAL_CONDITIONS_PT, 158245.38, 308.26, 1.0, 0.0, 0.0, 0.3, 0.0, OUTFLOW_STATOR1, MIXING_OUT, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3, 0.0, INFLOW_ROTOR, MIXING_IN, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3, 0.0, OUTFLOW_ROTOR, MIXING_OUT, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3, 0.0, INFLOW_STATOR2, MIXING_IN, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3, 0.0, OUTFLOW_STATOR2, STATIC_PRESSURE_1D, 110050.96, 0.0, 0.0, 0.0, 0.0 , 1.0, 0.0) +SPATIAL_FOURIER= NO +% +% This option insert an extra under relaxation factor for the Giles BC at the hub and shroud levels +GILES_EXTRA_RELAXFACTOR= (0.05, 0.05) +% +%---------------------------- TURBOMACHINERY SIMULATION -----------------------------% +% +% Format: (marker) +% If the ROTATING_FRAME option is activated, this option force +% the velocity on the boundaries specified to 0.0 +MARKER_SHROUD= (SHROUD1, SHROUD2, SHROUD3) +% +% Specify kind of architecture (AXIAL, CENTRIPETAL, CENTRIFUGAL, CENTRIPETAL_AXIAL) +TURBOMACHINERY_KIND= AXIAL AXIAL AXIAL +% +% Uncomment to work with new_turbo_outputs +TURBO_PERF_KIND= (TURBINE, TURBINE, TURBINE) +% +% Specify kind of interpolation for the mixing-plane (LINEAR_INTERPOLATION, NEAREST_SPAN, MATCHING) +MIXINGPLANE_INTERFACE_KIND= LINEAR_INTERPOLATION +% +% Specify option for turbulent mixing-plane (YES, NO) default NO +TURBULENT_MIXINGPLANE= YES +% +% Specify ramp option for Outlet pressure (YES, NO) default NO +RAMP_OUTLET_PRESSURE= NO +% +% Parameters of the outlet pressure ramp (starting outlet pressure, updating-iteration-frequency, total number of iteration for the ramp) +RAMP_OUTLET_PRESSURE_COEFF= (140000.0, 10.0, 2000) +% +% Specify Kind of average process for linearizing the Navier-Stokes equation at inflow and outflow BC included mixing-plane +% (ALGEBRAIC, AREA, MASSSFLUX, MIXEDOUT) default AREA +AVERAGE_PROCESS_KIND= MIXEDOUT +% +% Specify Kind of average process for computing turbomachienry performance parameters +% (ALGEBRAIC, AREA, MASSSFLUX, MIXEDOUT) default AREA +PERFORMANCE_AVERAGE_PROCESS_KIND= MIXEDOUT +% +%Parameters of the Newton method for the MIXEDOUT average algorithm (under relaxation factor, tollerance, max number of iterations) +MIXEDOUT_COEFF= (1.0, 1.0E-05, 15) +% +% Limit of Mach number below which the mixedout algorithm is substituted with a AREA average algorithm +AVERAGE_MACH_LIMIT= 0.03 +% +% +% ------------------------ SURFACES IDENTIFICATION ----------------------------% +% +% Marker(s) of the surface in the surface flow solution file +MARKER_PLOTTING= (BLADE1, BLADE2, BLADE3) +MARKER_MONITORING= (BLADE1, BLADE2, BLADE3) +% +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +% Numerical method for spatial gradients (GREEN_GAUSS, WEIGHTED_LEAST_SQUARES) +NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES +% +% Courant-Friedrichs-Lewy condition of the finest grid +CFL_NUMBER= 10 +% +% Adaptive CFL number (NO, YES) +CFL_ADAPT= NO +% +% Parameters of the adaptive CFL number (factor down, factor up, CFL min value, CFL max value ) +CFL_ADAPT_PARAM= ( 1.3, 1.2, 1.0, 10.0) +% +% +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +% Linear solver or smoother for implicit formulations +LINEAR_SOLVER= FGMRES +% +% Preconditioner of the Krylov linear solver (ILU, LU_SGS, LINELET, JACOBI) +LINEAR_SOLVER_PREC= LU_SGS +% +% Min error of the linear solver for the implicit formulation +LINEAR_SOLVER_ERROR= 1E-4 +% +% Max number of iterations of the linear solver for the implicit formulation +LINEAR_SOLVER_ITER= 15 +% +% ----------------------- SLOPE LIMITER DEFINITION ----------------------------% +% +% Coefficient for the limiter +VENKAT_LIMITER_COEFF= 0.01 +% +% Freeze the value of the limiter after a number of iterations +LIMITER_ITER= 999999 +% +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +% Convective numerical method +CONV_NUM_METHOD_FLOW= ROE +ENTROPY_FIX_COEFF= 0.001 +% +JST_SENSOR_COEFF= ( 0.5, 0.25 ) +% Spatial numerical order integration +MUSCL_FLOW= NO +% +% Slope limiter (VENKATAKRISHNAN, VAN_ALBADA) +SLOPE_LIMITER_FLOW= VENKATAKRISHNAN +% +% +% Time discretization (RUNGE-KUTTA_EXPLICIT, EULER_IMPLICIT, EULER_EXPLICIT) +TIME_DISCRE_FLOW= EULER_IMPLICIT +% +% -------------------- TURBULENT NUMERICAL METHOD DEFINITION ------------------% +% +% Convective numerical method (SCALAR_UPWIND) +CONV_NUM_METHOD_TURB= SCALAR_UPWIND +% +% Spatial numerical order integration +MUSCL_TURB= NO +% +% Slope limiter (VENKATAKRISHNAN, MINMOD) +SLOPE_LIMITER_TURB= VENKATAKRISHNAN +% +% Time discretization (EULER_IMPLICIT) +TIME_DISCRE_TURB= EULER_IMPLICIT +% +% Reduction factor of the CFL coefficient in the turbulence problem +CFL_REDUCTION_TURB= 0.1 +% +% ----------------------- DESIGN VARIABLE PARAMETERS --------------------------% +% +% Kind of deformation (NO_DEFORMATION, TRANSLATION, ROTATION, SCALE, +% FFD_SETTING, FFD_NACELLE +% FFD_CONTROL_POINT, FFD_CAMBER, FFD_THICKNESS, FFD_TWIST +% FFD_CONTROL_POINT_2D, FFD_CAMBER_2D, FFD_THICKNESS_2D, FFD_TWIST_2D, +% HICKS_HENNE, SURFACE_BUMP) +DV_KIND= NO_DEFORMATION +% +% Marker of the surface in which we are going apply the shape deformation +DV_MARKER= (BLADE1, BLADE2, BLADE3) +% +% Parameters of the shape deformation +DV_PARAM= ( 1, 0.5) +% +% Value of the shape deformation +DV_VALUE= 0.01 +% +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +% Number of total iterations +OUTER_ITER=10 +% +% Convergence criteria (CAUCHY, RESIDUAL) +CONV_FIELD=RMS_ENERGY[0] +% +% Min value of the residual (log10 of the residual) +CONV_RESIDUAL_MINVAL= -12 +% +% Start convergence criteria at iteration number +CONV_STARTITER= 10 +% +% Screen output fields (use 'SU2_CFD -d ' to view list of available fields) +SCREEN_OUTPUT= (OUTER_ITER, RMS_DENSITY[0], RMS_DENSITY[1], RMS_DENSITY[2], RMS_MOMENTUM-X[0], RMS_MOMENTUM-Y[0], RMS_ENERGY[0]) +% +% History output groups (use 'SU2_CFD -d ' to view list of available fields) +HISTORY_OUTPUT= (ITER, RMS_RES, TURBO_PERF) +% +% Volume output fields/groups (use 'SU2_CFD -d ' to view list of available fields) +VOLUME_OUTPUT= (COORDINATES, SOLUTION, PRIMITIVE, TURBOMACHINERY, RESIDUAL, LIMITER, VORTEX_IDENTIFICATION) +% +OUTPUT_FILES= (TECPLOT_ASCII, SURFACE_TECPLOT_ASCII, RESTART) +% +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +% Mesh input file +MESH_FILENAME= Aachen_3D_41_blade_coarse.su2 +% +% Mesh input file format +MESH_FORMAT= SU2 +% +% Mesh output file +MESH_OUT_FILENAME= Aachen_3D_41_blade_coarse.su2 +% +% Restart flow input file +SOLUTION_FILENAME= solution_flow.dat +% +% Restart adjoint input file +SOLUTION_ADJ_FILENAME= solution_adj.dat +% +% Output file format +TABULAR_FORMAT= TECPLOT +% +% Output file convergence history (w/o extension) +CONV_FILENAME= history +% +% Output file restart flow +RESTART_FILENAME= restart_flow.dat +% +% Output file restart adjoint +RESTART_ADJ_FILENAME= restart_adj.dat +% +% Output file flow (w/o extension) variables +VOLUME_FILENAME= flow +% +% Output file adjoint (w/o extension) variables +VOLUME_ADJ_FILENAME= adjoint +% +% Output objective function gradient (using continuous adjoint) +GRAD_OBJFUNC_FILENAME= of_grad.dat +% +% Output file surface flow coefficient (w/o extension) +SURFACE_FILENAME= surface_flow +% +% Output file surface adjoint coefficient (w/o extension) +SURFACE_ADJ_FILENAME= surface_adjoint +% +% Writing solution file frequency +OUTPUT_WRT_FREQ= 500 +% +% Writing convergence history frequency +HISTORY_WRT_FREQ_OUTER= 1 +WRT_ZONE_HIST = YES diff --git a/TestCases/turbomachinery/Aachen_turbine/rotor.cfg b/TestCases/turbomachinery/Aachen_turbine/rotor.cfg new file mode 100644 index 00000000000..ed7d886a96b --- /dev/null +++ b/TestCases/turbomachinery/Aachen_turbine/rotor.cfg @@ -0,0 +1,19 @@ +% ----------------------- DYNAMIC MESH DEFINITION -----------------------------% +% +% +% Type of dynamic mesh (NONE, ROTATING_FRAME) +GRID_MOVEMENT= ROTATING_FRAME +% +% Motion mach number (non-dimensional). Used for intitializing a viscous flow +% with the Reynolds number and for computing force coeffs. with dynamic meshes. +MACH_MOTION= 0.35 +% +MOTION_ORIGIN= 0.0 0.0 0.0 +% Angular velocity vector (rad/s) about the motion origi. Example 1250 RPM -> 130.89969389957471 rad/s 7508.3 +ROTATION_RATE= 0.0 0.0 -366.52 + +% Specify ramp option fr rotating frame (YES, NO) default NO +RAMP_ROTATING_FRAME= NO +% +% Parameters of the rotating frame ramp (starting rotational speed, updating-iteration-frequency, total number of iteration for the ramp) +RAMP_ROTATING_FRAME_COEFF= (0.0, 39.0, 500) diff --git a/TestCases/turbomachinery/Aachen_turbine/stator1.cfg b/TestCases/turbomachinery/Aachen_turbine/stator1.cfg new file mode 100644 index 00000000000..8c4f1def0c3 --- /dev/null +++ b/TestCases/turbomachinery/Aachen_turbine/stator1.cfg @@ -0,0 +1,6 @@ +% ----------------------- DYNAMIC MESH DEFINITION -----------------------------% +% +% +% Type of dynamic mesh (NONE, ROTATING_FRAME) +GRID_MOVEMENT= ROTATING_FRAME +% \ No newline at end of file diff --git a/TestCases/turbomachinery/Aachen_turbine/stator2.cfg b/TestCases/turbomachinery/Aachen_turbine/stator2.cfg new file mode 100644 index 00000000000..8c4f1def0c3 --- /dev/null +++ b/TestCases/turbomachinery/Aachen_turbine/stator2.cfg @@ -0,0 +1,6 @@ +% ----------------------- DYNAMIC MESH DEFINITION -----------------------------% +% +% +% Type of dynamic mesh (NONE, ROTATING_FRAME) +GRID_MOVEMENT= ROTATING_FRAME +% \ No newline at end of file diff --git a/TestCases/tutorials.py b/TestCases/tutorials.py index 849a4f85c26..6406f452631 100644 --- a/TestCases/tutorials.py +++ b/TestCases/tutorials.py @@ -64,6 +64,15 @@ def main(): cht_incompressible.multizone = True test_list.append(cht_incompressible) + # Solid-to-solid and solid-to-fluid CHT with contact resistance + cht_CR = TestCase('cht_solid_solid') + cht_CR.cfg_dir = "../Tutorials/multiphysics/contact_resistance_cht" + cht_CR.cfg_file = "master.cfg" + cht_CR.test_iter = 80 + cht_CR.test_vals = [ -8.857438, -9.377593, -10.097769, -2.122358] + cht_CR.multizone = True + test_list.append(cht_CR) + ### Incompressible Flow # 2D pin case massflow periodic with heatflux BC and prescribed extracted outlet heat @@ -120,6 +129,16 @@ def main(): sudo_tutorial.command = TestCase.Command("mpirun -n 2", "SU2_CFD") test_list.append(sudo_tutorial) + ### Incompressible Combustion + + # Pre-mixed, laminar hydrogen flame with heat loss + premixed_hydrogen = TestCase('premixed_hydrogen') + premixed_hydrogen.cfg_dir = "../Tutorials/incompressible_flow/Inc_Combustion/1__premixed_hydrogen" + premixed_hydrogen.cfg_file = "H2_burner.cfg" + premixed_hydrogen.test_iter = 10 + premixed_hydrogen.test_vals = [-9.905856, -10.449512, -11.035999, -4.331440, -11.882740] + test_list.append(premixed_hydrogen) + ### Compressible Flow # Inviscid Bump diff --git a/UnitTests/Common/containers/CLookupTable_tests.cpp b/UnitTests/Common/containers/CLookupTable_tests.cpp index 487ecdc481b..7192d529398 100644 --- a/UnitTests/Common/containers/CLookupTable_tests.cpp +++ b/UnitTests/Common/containers/CLookupTable_tests.cpp @@ -50,8 +50,9 @@ TEST_CASE("LUTreader", "[tabulated chemistry]") { su2double prog = 0.55; su2double enth = -0.5; string look_up_tag = "Density"; + unsigned long idx_tag = look_up_table.GetIndexOfVar(look_up_tag); su2double look_up_dat; - look_up_table.LookUp_XY(look_up_tag, &look_up_dat, prog, enth); + look_up_table.LookUp_XY(idx_tag, &look_up_dat, prog, enth); CHECK(look_up_dat == Approx(1.02)); /*--- look up a single value for viscosity ---*/ @@ -59,7 +60,8 @@ TEST_CASE("LUTreader", "[tabulated chemistry]") { prog = 0.6; enth = 0.9; look_up_tag = "Viscosity"; - look_up_table.LookUp_XY(look_up_tag, &look_up_dat, prog, enth); + idx_tag = look_up_table.GetIndexOfVar(look_up_tag); + look_up_table.LookUp_XY(idx_tag, &look_up_dat, prog, enth); CHECK(look_up_dat == Approx(0.0000674286)); /* find the table limits */ @@ -77,7 +79,8 @@ TEST_CASE("LUTreader", "[tabulated chemistry]") { prog = 1.10; enth = 1.1; look_up_tag = "Density"; - look_up_table.LookUp_XY(look_up_tag, &look_up_dat, prog, enth); + idx_tag = look_up_table.GetIndexOfVar(look_up_tag); + look_up_table.LookUp_XY(idx_tag, &look_up_dat, prog, enth); CHECK(look_up_dat == Approx(1.1738796125)); } @@ -98,8 +101,9 @@ TEST_CASE("LUTreader_3D", "[tabulated chemistry]") { su2double enth = -0.5; su2double mfrac = 0.5; string look_up_tag = "Density"; + unsigned long idx_tag = look_up_table.GetIndexOfVar(look_up_tag); su2double look_up_dat; - look_up_table.LookUp_XYZ(look_up_tag, &look_up_dat, prog, enth, mfrac); + look_up_table.LookUp_XYZ(idx_tag, &look_up_dat, prog, enth, mfrac); CHECK(look_up_dat == Approx(1.02)); /*--- look up a single value for viscosity ---*/ @@ -108,7 +112,8 @@ TEST_CASE("LUTreader_3D", "[tabulated chemistry]") { enth = 0.9; mfrac = 0.8; look_up_tag = "Viscosity"; - look_up_table.LookUp_XYZ(look_up_tag, &look_up_dat, prog, enth, mfrac); + idx_tag = look_up_table.GetIndexOfVar(look_up_tag); + look_up_table.LookUp_XYZ(idx_tag, &look_up_dat, prog, enth, mfrac); CHECK(look_up_dat == Approx(0.0000674286)); /* find the table limits */ @@ -127,6 +132,7 @@ TEST_CASE("LUTreader_3D", "[tabulated chemistry]") { enth = 1.1; mfrac = 2.0; look_up_tag = "Density"; - look_up_table.LookUp_XYZ(look_up_tag, &look_up_dat, prog, enth, mfrac); + idx_tag = look_up_table.GetIndexOfVar(look_up_tag); + look_up_table.LookUp_XYZ(idx_tag, &look_up_dat, prog, enth, mfrac); CHECK(look_up_dat == Approx(1.1738796125)); } diff --git a/UnitTests/SU2_CFD/gradients.cpp b/UnitTests/SU2_CFD/gradients.cpp index e0829ce1104..2f69d407d3a 100644 --- a/UnitTests/SU2_CFD/gradients.cpp +++ b/UnitTests/SU2_CFD/gradients.cpp @@ -132,8 +132,8 @@ void testGreenGauss() { TestField field; C3DDoubleMatrix gradient(field.geometry->GetnPoint(), field.nVar, field.geometry->GetnDim()); - computeGradientsGreenGauss(nullptr, SOLUTION, PERIODIC_NONE, *field.geometry.get(), *field.config.get(), field, 0, - field.nVar, gradient); + computeGradientsGreenGauss(nullptr, MPI_QUANTITIES::SOLUTION, PERIODIC_NONE, *field.geometry.get(), + *field.config.get(), field, 0, field.nVar, gradient); check(field, gradient); } @@ -144,8 +144,8 @@ void testLeastSquares(bool weighted) { C3DDoubleMatrix R(field.geometry->GetnPoint(), nDim, nDim); C3DDoubleMatrix gradient(field.geometry->GetnPoint(), field.nVar, nDim); - computeGradientsLeastSquares(nullptr, SOLUTION, PERIODIC_NONE, *field.geometry.get(), *field.config.get(), weighted, - field, 0, field.nVar, gradient, R); + computeGradientsLeastSquares(nullptr, MPI_QUANTITIES::SOLUTION, PERIODIC_NONE, *field.geometry.get(), + *field.config.get(), weighted, field, 0, field.nVar, gradient, R); check(field, gradient); } diff --git a/config_template.cfg b/config_template.cfg index bf3e6bae907..74832ef98db 100644 --- a/config_template.cfg +++ b/config_template.cfg @@ -869,6 +869,11 @@ SPECIES_CLIPPING_MAX= 1.0 SPECIES_CLIPPING_MIN= 0.0 % --------------------- FLAMELET MODEL -----------------------------% +% The flamelet model uses the prompts INTERPOLATION_METHOD and FILENAMES_INTERPOLATOR +% for definition of the flamelet manifold. Either LUT or MLP can be used as options. +% If the terms "Beta_ProgVar", "Beta_Enth_Thermal", "Beta_Enth", and "Beta_Mixfrac" are +% found in the variables list of the manifold, preferential diffusion is assumed. + % % Names of the user defined (auxiliary) transport equations. USER_SCALAR_NAMES= (Y-CO) @@ -894,8 +899,27 @@ CONTROLLING_VARIABLE_NAMES= (ProgressVariable, EnthalpyTot) % controlling variables without source terms, use "zero" or "null", similar to the % option USER_SOURCE_NAMES. CONTROLLING_VARIABLE_SOURCE_NAMES= (ProdRateTot_PV, NULL) -% -% flamelet initialization + +% Method used to ignite the solution: +% FLAME_FRONT : the flame is initialized using a plane, defined by a point and a normal. On one side, the solution is initialized +% using 'burnt' conditions and on the other side 'unburnt' conditions. The normal points in the direction of the 'burnt' +% condition. +% SPARK : the solution is ignited through application of a set of source terms within a specified region for a set number +% of solver iterations. This artificial spark can be applied after a certain number of iterations has passed, allowing for +% the flow to evolve before igniting the mixture. +% NONE : no artificial solution ignition. +% By default, this option is set to NONE +FLAME_INIT_METHOD= FLAME_FRONT + +% Enable preferential diffusion for progress variable, total enthalpy, mixture fraction FGM problems. +% If 'YES', the preferential diffusion model from Efimov et al.(2021) is used for computing the viscous residual terms. +% If enabled, make sure the variables "Beta_ProgVar", "Beta_Enth_Thermal", "Beta_Enth", and "Beta_MixFrac", corresponding +% to the preferential diffusion terms of the progress variable, temperature, total enthalpy, and mixture fraction +% respectively are included in the manifold. +% By default, this option is disabled. +PREFERENTIAL_DIFFUSION= NO + +% FLAME_FRONT initialization % the flame is initialized using a plane, defined by a point and a normal. On one side, the solution is initialized % using 'burnt' conditions and on the other side 'unburnt' conditions. The normal points in the direction of the 'burnt' % condition. @@ -904,6 +928,21 @@ CONTROLLING_VARIABLE_SOURCE_NAMES= (ProdRateTot_PV, NULL) % (x7) = thickness of the reaction zone, this is the transition from unburnt to burnt conditions. % (x8) = Thickness of the 'burnt' zone, after this length, the conditions will be 'unburnt' again. FLAME_INIT= (0.004, 0.0, 0.0, 1.0, 0.0, 0.0, 0.2e-3, 1.0) + +% SPARK initialization +% the solution is ignited through application of a set of source terms within a specified region for a set number +% of solver iterations. This artificial spark can be applied after a certain number of iterations has passed, allowing for +% the flow to evolve before igniting the mixture. +% (x1,x2,x3) = spark center location. +% (x4) = spark radius where within the artificial spark is applied. +% (x5,x6) = spark iteration start and number of iterations in which the artifical spark is applied. For single-zone problems +% the number of iterations are inner-loop iterations, for multi-zone problems, outer-loop iterations are considered. +SPARK_INIT= (0.004, 0.0, 0.0, 1e-4, 100, 10) + +% Source terms (density times species time rate of change) applied to the species equations in the spark region for the duration of the spark. +% The number of terms should equate the total number of species in the flamelet problem. +SPARK_REACTION_RATES= (1000, 0, 0) + % % --------------------- INVERSE DESIGN SIMULATION -----------------------------% % diff --git a/externals/codi b/externals/codi index 9ca6c382806..c6b039e5c9e 160000 --- a/externals/codi +++ b/externals/codi @@ -1 +1 @@ -Subproject commit 9ca6c38280610b3ea5337ca3e5b5085ee1c66b59 +Subproject commit c6b039e5c9edb7675f90ffc725f9dd8e66571264 diff --git a/meson_options.txt b/meson_options.txt index 7b2902bba0b..08fbac80669 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -20,7 +20,8 @@ option('extra-deps', type : 'string', value : '', description: 'comma-separated 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-mlpcpp', type : 'boolean', value : false, description: 'enable MLPCpp support') +option('enable-mlpcpp', type : 'boolean', value : false, description: 'enable profiling through gprof') +option('enable-gprof', type : 'boolean', value : false, description: 'enable MLPCpp support') option('opdi-backend', type : 'combo', choices : ['auto', 'macro', 'ompt'], value : 'auto', description: 'OpDiLib backend choice') option('codi-tape', type : 'combo', choices : ['JacobianLinear', 'JacobianReuse', 'JacobianMultiUse', 'PrimalLinear', 'PrimalReuse', 'PrimalMultiUse'], value : 'JacobianLinear', description: 'CoDiPack tape choice') option('opdi-shared-read-opt', type : 'boolean', value : true, description : 'OpDiLib shared reading optimization') diff --git a/meson_scripts/init.py b/meson_scripts/init.py index b347432f473..bc58f9a9564 100755 --- a/meson_scripts/init.py +++ b/meson_scripts/init.py @@ -55,7 +55,7 @@ def init_submodules( # This information of the modules is used if projects was not cloned using git # The sha tag must be maintained manually to point to the correct commit - sha_version_codi = "9ca6c38280610b3ea5337ca3e5b5085ee1c66b59" + sha_version_codi = "c6b039e5c9edb7675f90ffc725f9dd8e66571264" github_repo_codi = "https://github.com/scicompkl/CoDiPack" sha_version_medi = "ab3a7688f6d518f8d940eb61a341d89f51922ba4" github_repo_medi = "https://github.com/SciCompKL/MeDiPack" @@ -71,7 +71,7 @@ def init_submodules( github_repo_coolprop = "https://github.com/CoolProp/CoolProp" sha_version_mel = "46205ab019e5224559091375a6d71aabae6bc5b9" github_repo_mel = "https://github.com/pcarruscag/MEL" - sha_version_mlpcpp = "665c45b7d3533c977eb1f637918d5b8b75c07d3b" + sha_version_mlpcpp = "c19c53ea2b85ccfb185f1c6c87044dc0b5bc7ae0" github_repo_mlpcpp = "https://github.com/EvertBunschoten/MLPCpp" medi_name = "MeDiPack" diff --git a/subprojects/MLPCpp b/subprojects/MLPCpp index 665c45b7d35..c19c53ea2b8 160000 --- a/subprojects/MLPCpp +++ b/subprojects/MLPCpp @@ -1 +1 @@ -Subproject commit 665c45b7d3533c977eb1f637918d5b8b75c07d3b +Subproject commit c19c53ea2b85ccfb185f1c6c87044dc0b5bc7ae0