diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index 2f103c455276..66f7e35a23ea 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -9099,7 +9099,7 @@ class CConfig { * \brief Check if values passed to the BC_HeatFlux-Routine are already integrated. * \return YES if the passed values is the integrated heat flux over the marker's surface. */ - bool GetIntegrated_HeatFlux(void) const { return Integrated_HeatFlux; } + bool GetIntegrated_HeatFlux() const { return Integrated_HeatFlux; } /*! * \brief Get Compute Average. diff --git a/Common/include/geometry/CGeometry.hpp b/Common/include/geometry/CGeometry.hpp index f1acbb31ceed..cbd4170f0dbe 100644 --- a/Common/include/geometry/CGeometry.hpp +++ b/Common/include/geometry/CGeometry.hpp @@ -199,6 +199,7 @@ class CGeometry { unsigned long *nElem_Bound{nullptr}; /*!< \brief Number of elements of the boundary. */ string *Tag_to_Marker{nullptr}; /*!< \brief Names of boundary markers. */ vector bound_is_straight; /*!< \brief Bool if boundary-marker is straight(2D)/plane(3D) for each local marker. */ + vector SurfaceAreaCfgFile; /*!< \brief Total Surface area for all markers. */ /*--- Partitioning-specific variables ---*/ @@ -910,6 +911,20 @@ class CGeometry { */ inline virtual void SetRestricted_GridVelocity(const CGeometry *fine_grid) {} + /*! + * \brief Compute the surface area of all global markers. + * \param[in] config - Definition of the particular problem. + */ + void ComputeSurfaceAreaCfgFile(const CConfig *config); + + /*! + * \brief Get global Surface Area to a local marker. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Local surface marker. + * \return Global Surface Area to the local marker + */ + su2double GetSurfaceArea(const CConfig *config, unsigned short val_marker) const; + /*! * \brief Check if a boundary is straight(2D) / plane(3D) for EULER_WALL and SYMMETRY_PLANE * only and store the information in bound_is_straight. For all other boundary types diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index 9877faf0c2df..f505d1b78526 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -1572,6 +1572,8 @@ void CConfig::SetConfig_Options() { /*!\brief MARKER_HEATFLUX \n DESCRIPTION: Specified heat flux wall boundary marker(s) Format: ( Heat flux marker, wall heat flux (static), ... ) \ingroup Config*/ addStringDoubleListOption("MARKER_HEATFLUX", nMarker_HeatFlux, Marker_HeatFlux, Heat_Flux); + /*!\brief INTEGRATED_HEATFLUX \n DESCRIPTION: Prescribe Heatflux in [W] instead of [W/m^2] \ingroup Config \default false */ + addBoolOption("INTEGRATED_HEATFLUX", Integrated_HeatFlux, false); /*!\brief MARKER_HEATTRANSFER DESCRIPTION: Heat flux with specified heat transfer coefficient boundary marker(s)\n * Format: ( Heat transfer marker, heat transfer coefficient, wall temperature (static), ... ) \ingroup Config */ addExhaustOption("MARKER_HEATTRANSFER", nMarker_HeatTransfer, Marker_HeatTransfer, HeatTransfer_Coeff, HeatTransfer_WallTemp); @@ -1589,8 +1591,6 @@ void CConfig::SetConfig_Options() { /* DESCRIPTION: Fan poly efficiency */ addDoubleOption("FAN_POLY_EFF", Fan_Poly_Eff, 1.0); /*!\brief SUBSONIC_ENGINE\n DESCRIPTION: Engine subsonic intake region \ingroup Config*/ - addBoolOption("INTEGRATED_HEATFLUX", Integrated_HeatFlux, false); - /*!\brief SUBSONIC_ENGINE\n DESCRIPTION: Engine subsonic intake region \ingroup Config*/ addBoolOption("SUBSONIC_ENGINE", SubsonicEngine, false); /* DESCRIPTION: Actuator disk double surface */ addBoolOption("ACTDISK_DOUBLE_SURFACE", ActDisk_DoubleSurface, false); diff --git a/Common/src/geometry/CGeometry.cpp b/Common/src/geometry/CGeometry.cpp index 48e31afae303..e1ae8e9a5d02 100644 --- a/Common/src/geometry/CGeometry.cpp +++ b/Common/src/geometry/CGeometry.cpp @@ -2436,6 +2436,8 @@ void CGeometry::UpdateGeometry(CGeometry **geometry_container, CConfig *config) } + /*--- Compute the global surface areas for all markers. ---*/ + geometry_container[MESH_0]->ComputeSurfaceAreaCfgFile(config); } void CGeometry::SetCustomBoundary(CConfig *config) { @@ -2503,6 +2505,57 @@ void CGeometry::UpdateCustomBoundaryConditions(CGeometry **geometry_container, C } } +void CGeometry::ComputeSurfaceAreaCfgFile(const CConfig *config) { + const auto nMarker_Global = config->GetnMarker_CfgFile(); + SurfaceAreaCfgFile.resize(nMarker_Global); + vector LocalSurfaceArea(nMarker_Global, 0.0); + + /*--- Loop over all local markers ---*/ + for (unsigned short iMarker = 0; iMarker < nMarker; iMarker++) { + + const auto Local_TagBound = config->GetMarker_All_TagBound(iMarker); + + /*--- Loop over all global markers, and find the local-global pair via + matching unique string tags. ---*/ + for (unsigned short iMarker_Global = 0; iMarker_Global < nMarker_Global; iMarker_Global++) { + + const auto Global_TagBound = config->GetMarker_CfgFile_TagBound(iMarker_Global); + if (Local_TagBound == Global_TagBound) { + + for(auto iVertex = 0ul; iVertex < nVertex[iMarker]; iVertex++ ) { + + const auto iPoint = vertex[iMarker][iVertex]->GetNode(); + + if(!nodes->GetDomain(iPoint)) continue; + + const auto AreaNormal = vertex[iMarker][iVertex]->GetNormal(); + const auto Area = GeometryToolbox::Norm(nDim, AreaNormal); + + LocalSurfaceArea[iMarker_Global] += Area; + }// for iVertex + }//if Local == Global + }//for iMarker_Global + }//for iMarker + + SU2_MPI::Allreduce(LocalSurfaceArea.data(), SurfaceAreaCfgFile.data(), SurfaceAreaCfgFile.size(), MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); +} + +su2double CGeometry::GetSurfaceArea(const CConfig *config, unsigned short val_marker) const { + /*---Find the precomputed marker surface area by local-global string-matching. ---*/ + const auto Marker_Tag = config->GetMarker_All_TagBound(val_marker); + + for (unsigned short iMarker_Global = 0; iMarker_Global < config->GetnMarker_CfgFile(); iMarker_Global++) { + + const auto Global_TagBound = config->GetMarker_CfgFile_TagBound(iMarker_Global); + + if (Marker_Tag == Global_TagBound) + return SurfaceAreaCfgFile[iMarker_Global]; + + } + + SU2_MPI::Error("Unable to match local-marker with cfg-marker for Surface Area.", CURRENT_FUNCTION); + return 0.0; +} void CGeometry::ComputeSurf_Straightness(CConfig *config, bool print_on_screen) { diff --git a/Common/src/geometry/meshreader/CSU2ASCIIMeshReaderFVM.cpp b/Common/src/geometry/meshreader/CSU2ASCIIMeshReaderFVM.cpp index 3b2c052b9143..6a4fd4385993 100644 --- a/Common/src/geometry/meshreader/CSU2ASCIIMeshReaderFVM.cpp +++ b/Common/src/geometry/meshreader/CSU2ASCIIMeshReaderFVM.cpp @@ -99,7 +99,7 @@ bool CSU2ASCIIMeshReaderFVM::ReadMetadata(const bool single_pass, CConfig *confi string text_line; if ((nZones > 1 && multizone_file) || harmonic_balance) { if (harmonic_balance) { - cout << "Reading time instance " << config->GetiInst()+1 << "." << endl; + if (rank == MASTER_NODE) cout << "Reading time instance " << config->GetiInst()+1 << "." << endl; } else { bool foundZone = false; @@ -109,7 +109,7 @@ bool CSU2ASCIIMeshReaderFVM::ReadMetadata(const bool single_pass, CConfig *confi text_line.erase (0,6); unsigned short jZone = atoi(text_line.c_str()); if (jZone == myZone+1) { - cout << "Reading zone " << myZone << " from native SU2 ASCII mesh." << endl; + if (rank == MASTER_NODE) cout << "Reading zone " << myZone << " from native SU2 ASCII mesh." << endl; foundZone = true; break; } diff --git a/SU2_CFD/src/drivers/CDriver.cpp b/SU2_CFD/src/drivers/CDriver.cpp index fa14d73fe349..f6d336671efa 100644 --- a/SU2_CFD/src/drivers/CDriver.cpp +++ b/SU2_CFD/src/drivers/CDriver.cpp @@ -812,6 +812,10 @@ void CDriver::Geometrical_Preprocessing_FVM(CConfig *config, CGeometry **&geomet geometry[MESH_0]->ComputeSurf_Curvature(config); } + /*--- Compute the global surface areas for all markers. ---*/ + + geometry[MESH_0]->ComputeSurfaceAreaCfgFile(config); + /*--- Check for periodicity and disable MG if necessary. ---*/ if (rank == MASTER_NODE) cout << "Checking for periodicity." << endl; diff --git a/SU2_CFD/src/solvers/CHeatSolver.cpp b/SU2_CFD/src/solvers/CHeatSolver.cpp index cd1465983c4d..cdebdc79e69c 100644 --- a/SU2_CFD/src/solvers/CHeatSolver.cpp +++ b/SU2_CFD/src/solvers/CHeatSolver.cpp @@ -621,38 +621,21 @@ void CHeatSolver::BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_conta } } -void CHeatSolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker) { +void CHeatSolver::BC_HeatFlux_Wall(CGeometry* geometry, CSolver** solver_container, CNumerics* conv_numerics, + CNumerics* visc_numerics, CConfig* config, unsigned short val_marker) { + const auto Marker_Tag = config->GetMarker_All_TagBound(val_marker); - su2double Area, *Normal; - - string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - - su2double Wall_HeatFlux = config->GetWall_HeatFlux(Marker_Tag); - if(config->GetIntegrated_HeatFlux()) { - - string HeatFlux_Tag, Marker_Tag; - - for (auto iMarker_HeatFlux = 0u; iMarker_HeatFlux < config->GetnMarker_HeatFlux(); iMarker_HeatFlux++ ) { - - HeatFlux_Tag = config->GetMarker_HeatFlux_TagBound(iMarker_HeatFlux); - Marker_Tag = config->GetMarker_All_TagBound(val_marker); - - if (Marker_Tag == HeatFlux_Tag) { - Wall_HeatFlux = Wall_HeatFlux / Surface_Areas[iMarker_HeatFlux]; - } - } + su2double Wall_HeatFlux = config->GetWall_HeatFlux(Marker_Tag) / config->GetHeat_Flux_Ref(); + if (config->GetIntegrated_HeatFlux()) { + Wall_HeatFlux /= geometry->GetSurfaceArea(config, val_marker); } - Wall_HeatFlux = Wall_HeatFlux/config->GetHeat_Flux_Ref(); for (auto iVertex = 0ul; iVertex < geometry->nVertex[val_marker]; iVertex++) { - const auto iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); if (geometry->nodes->GetDomain(iPoint)) { - - Normal = geometry->vertex[val_marker][iVertex]->GetNormal(); - Area = GeometryToolbox::Norm(nDim, Normal); + const auto Normal = geometry->vertex[val_marker][iVertex]->GetNormal(); + const auto Area = GeometryToolbox::Norm(nDim, Normal); Res_Visc[0] = 0.0; @@ -662,7 +645,6 @@ void CHeatSolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_contain LinSysRes.SubtractBlock(iPoint, Res_Visc); } - } } diff --git a/SU2_CFD/src/solvers/CIncNSSolver.cpp b/SU2_CFD/src/solvers/CIncNSSolver.cpp index 9329c8b023a7..b75a6f449d50 100644 --- a/SU2_CFD/src/solvers/CIncNSSolver.cpp +++ b/SU2_CFD/src/solvers/CIncNSSolver.cpp @@ -384,16 +384,20 @@ void CIncNSSolver::BC_Wall_Generic(const CGeometry *geometry, const CConfig *con su2double Wall_HeatFlux = 0.0, Twall = 0.0, Tinfinity = 0.0, Transfer_Coefficient = 0.0; - switch(kind_boundary) { + switch (kind_boundary) { case HEAT_FLUX: - Wall_HeatFlux = config->GetWall_HeatFlux(Marker_Tag)/config->GetHeat_Flux_Ref(); + Wall_HeatFlux = config->GetWall_HeatFlux(Marker_Tag) / config->GetHeat_Flux_Ref(); + if (config->GetIntegrated_HeatFlux()) { + Wall_HeatFlux /= geometry->GetSurfaceArea(config, val_marker); + } break; case ISOTHERMAL: - Twall = config->GetIsothermal_Temperature(Marker_Tag)/config->GetTemperature_Ref(); + Twall = config->GetIsothermal_Temperature(Marker_Tag) / config->GetTemperature_Ref(); break; case HEAT_TRANSFER: - Transfer_Coefficient = config->GetWall_HeatTransfer_Coefficient(Marker_Tag) * config->GetTemperature_Ref()/config->GetHeat_Flux_Ref(); - Tinfinity = config->GetWall_HeatTransfer_Temperature(Marker_Tag)/config->GetTemperature_Ref(); + Transfer_Coefficient = config->GetWall_HeatTransfer_Coefficient(Marker_Tag) * config->GetTemperature_Ref() / + config->GetHeat_Flux_Ref(); + Tinfinity = config->GetWall_HeatTransfer_Temperature(Marker_Tag) / config->GetTemperature_Ref(); break; default: SU2_MPI::Error("Unknown type of boundary condition.", CURRENT_FUNCTION); diff --git a/SU2_CFD/src/solvers/CNEMONSSolver.cpp b/SU2_CFD/src/solvers/CNEMONSSolver.cpp index cd353655da43..e595fbb4f31f 100644 --- a/SU2_CFD/src/solvers/CNEMONSSolver.cpp +++ b/SU2_CFD/src/solvers/CNEMONSSolver.cpp @@ -250,7 +250,10 @@ void CNEMONSSolver::BC_HeatFluxNonCatalytic_Wall(CGeometry *geometry, /*--- Local variables ---*/ const auto Marker_Tag = config->GetMarker_All_TagBound(val_marker); - su2double Wall_HeatFlux = config->GetWall_HeatFlux(Marker_Tag)/config->GetHeat_Flux_Ref(); + su2double Wall_HeatFlux = config->GetWall_HeatFlux(Marker_Tag) / config->GetHeat_Flux_Ref(); + if (config->GetIntegrated_HeatFlux()) { + Wall_HeatFlux /= geometry->GetSurfaceArea(config, val_marker); + } const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); /*--- Set "Proportional control" coefficient ---*/ @@ -405,7 +408,10 @@ void CNEMONSSolver::BC_HeatFluxCatalytic_Wall(CGeometry *geometry, string Marker_Tag = config->GetMarker_All_TagBound(val_marker); /*--- Get the specified wall heat flux from config ---*/ - su2double Wall_HeatFlux = config->GetWall_HeatFlux(Marker_Tag); + su2double Wall_HeatFlux = config->GetWall_HeatFlux(Marker_Tag) / config->GetHeat_Flux_Ref(); + if (config->GetIntegrated_HeatFlux()) { + Wall_HeatFlux /= geometry->GetSurfaceArea(config, val_marker); + } /*--- Get the locations of the primitive variables ---*/ const unsigned short T_INDEX = nodes->GetTIndex(); diff --git a/SU2_CFD/src/solvers/CNSSolver.cpp b/SU2_CFD/src/solvers/CNSSolver.cpp index b6911f527886..1b2ab04ff5f2 100644 --- a/SU2_CFD/src/solvers/CNSSolver.cpp +++ b/SU2_CFD/src/solvers/CNSSolver.cpp @@ -421,9 +421,8 @@ void CNSSolver::BC_HeatTransfer_Wall(const CGeometry *geometry, const CConfig *c BC_HeatFlux_Wall_Generic(geometry, config, val_marker, HEAT_TRANSFER); } -void CNSSolver::BC_HeatFlux_Wall_Generic(const CGeometry *geometry, const CConfig *config, - unsigned short val_marker, unsigned short kind_boundary) { - +void CNSSolver::BC_HeatFlux_Wall_Generic(const CGeometry* geometry, const CConfig* config, unsigned short val_marker, + unsigned short kind_boundary) { /*--- Identify the boundary by string name and get the specified wall heat flux from config as well as the wall function treatment. ---*/ @@ -435,12 +434,15 @@ void CNSSolver::BC_HeatFlux_Wall_Generic(const CGeometry *geometry, const CConfi su2double Wall_HeatFlux = 0.0, Tinfinity = 0.0, Transfer_Coefficient = 0.0; if (kind_boundary == HEAT_FLUX) { - Wall_HeatFlux = config->GetWall_HeatFlux(Marker_Tag)/config->GetHeat_Flux_Ref(); - } - else if (kind_boundary == HEAT_TRANSFER) { + Wall_HeatFlux = config->GetWall_HeatFlux(Marker_Tag) / config->GetHeat_Flux_Ref(); + if (config->GetIntegrated_HeatFlux()) { + Wall_HeatFlux /= geometry->GetSurfaceArea(config, val_marker); + } + } else if (kind_boundary == HEAT_TRANSFER) { /*--- The required heatflux will be computed for each iPoint individually based on local Temperature. ---*/ - Transfer_Coefficient = config->GetWall_HeatTransfer_Coefficient(Marker_Tag) * config->GetTemperature_Ref()/config->GetHeat_Flux_Ref(); - Tinfinity = config->GetWall_HeatTransfer_Temperature(Marker_Tag)/config->GetTemperature_Ref(); + Transfer_Coefficient = config->GetWall_HeatTransfer_Coefficient(Marker_Tag) * config->GetTemperature_Ref() / + config->GetHeat_Flux_Ref(); + Tinfinity = config->GetWall_HeatTransfer_Temperature(Marker_Tag) / config->GetTemperature_Ref(); } // Wall_Function = config->GetWallFunction_Treatment(Marker_Tag); diff --git a/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_3d/configSolid.cfg b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_3d/configSolid.cfg index 6f1a22914445..731429e16e23 100644 --- a/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_3d/configSolid.cfg +++ b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_3d/configSolid.cfg @@ -25,7 +25,9 @@ THERMAL_CONDUCTIVITY_CONSTANT= 200 % MARKER_SYM= ( solid_sym_sides) % -MARKER_HEATFLUX= ( solid_bottom_heater, 5e5, \ +% 5e5[W/m^2]@solid_bottom_heat * 3.59172e-5[m^2]@solid_bottom_heater = 17.9586 [W] +INTEGRATED_HEATFLUX= YES +MARKER_HEATFLUX= ( solid_bottom_heater, 17.9586, \ solid_block_inlet, 0.0, \ solid_block_outlet, 0.0, \ solid_pin1_inlet, 0.0, \ diff --git a/TestCases/parallel_regression.py b/TestCases/parallel_regression.py index ca1a8b3f48db..46b5dc098bf2 100644 --- a/TestCases/parallel_regression.py +++ b/TestCases/parallel_regression.py @@ -1428,7 +1428,7 @@ def main(): sp_pinArray_3d_cht_mf_hf_tp.cfg_dir = "incomp_navierstokes/streamwise_periodic/chtPinArray_3d" sp_pinArray_3d_cht_mf_hf_tp.cfg_file = "configMaster.cfg" sp_pinArray_3d_cht_mf_hf_tp.test_iter = 30 - sp_pinArray_3d_cht_mf_hf_tp.test_vals = [0.511984, -3.063453, -0.451962, -0.008477, 214.707868, 365.670000] #last 7 lines + sp_pinArray_3d_cht_mf_hf_tp.test_vals = [0.511984, -0.894867, -0.451962, -0.008477, 214.707868, 365.670000] #last 7 lines sp_pinArray_3d_cht_mf_hf_tp.su2_exec = "mpirun -n 2 SU2_CFD" sp_pinArray_3d_cht_mf_hf_tp.timeout = 1600 sp_pinArray_3d_cht_mf_hf_tp.tol = 0.00001