diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index 45c4618fa48..761ebf5cd92 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -413,6 +413,7 @@ class CConfig { unsigned long IntIter; /*!< \brief Current internal iteration number. */ unsigned long OuterIter; /*!< \brief Current Outer iterations for multizone problems. */ unsigned long InnerIter; /*!< \brief Current inner iterations for multizone problems. */ + unsigned long FOInit_Iter; unsigned long TimeIter; /*!< \brief Current time iterations for multizone problems. */ long Unst_AdjointIter; /*!< \brief Iteration number to begin the reverse time integration in the direct solver for the unsteady adjoint. */ long Iter_Avg_Objective; /*!< \brief Iteration the number of time steps to be averaged, counting from the back */ @@ -711,6 +712,7 @@ class CConfig { unsigned short Res_FEM_CRIT; /*!< \brief Criteria to apply to the FEM convergence (absolute/relative). */ unsigned long StartConv_Iter; /*!< \brief Start convergence criteria at iteration. */ su2double Cauchy_Eps; /*!< \brief Epsilon used for the convergence. */ + bool First_Order_Initialization; /*!< \brief Boolean flag for whether to perform a first order simulation prior to running a MUSCL reconstructed simulation*/ bool Restart, /*!< \brief Restart solution (for direct, adjoint, and linearized problems).*/ Wrt_Restart_Compact, /*!< \brief Write compact restart files with minimum nr. of variables. */ Read_Binary_Restart, /*!< \brief Read binary SU2 native restart files.*/ @@ -1176,6 +1178,7 @@ class CConfig { nInnerIter, /*!< \brief Determines the number of inner iterations in each multizone block */ nTimeIter, /*!< \brief Determines the number of time iterations in the multizone problem */ nIter, /*!< \brief Determines the number of pseudo-time iterations in a single-zone problem */ + nFOInit_Iter, /*!< \brief Determines the number of inner iterations used for the first order initialization */ Restart_Iter; /*!< \brief Determines the restart iteration in the multizone problem */ su2double Time_Step; /*!< \brief Determines the time step for the multizone problem */ su2double Max_Time; /*!< \brief Determines the maximum time for the time-domain problems */ @@ -3191,6 +3194,12 @@ class CConfig { */ void SetTimeIter(unsigned long val_iter) { TimeIter = val_iter; } + /*! + * \brief Set the number of inner iterations + * \return Number of inner iterations on each multizone block + */ + void SetnInner_Iter(unsigned long val_iter) { nInnerIter = val_iter; } + /*! * \brief Get the current time iteration number. * \param[in] val_iter - Current time iterationnumber. @@ -4557,6 +4566,38 @@ class CConfig { */ bool GetMUSCL_Species(void) const { return MUSCL_Species; } + /*! + * \brief Set the value of the boolean for choosing MUSCL. + * \param[in] val_update - the bool for whether to update the MUSCL_Flow. + */ + void SetMUSCL_Flow(bool val_update) { MUSCL_Flow = val_update; } + + /*! + * \brief Set the value of the boolean for choosing MUSCL. + * \param[in] val_update - the bool for whether to update the MUSCL_Turb. + */ + void SetMUSCL_Turb(bool val_update) { MUSCL_Turb = val_update; } + + /*! + * \brief Set the value of the boolean for choosing MUSCL. + * \param[in] val_update - the bool for whether to update the MUSCL_Species. + */ + void SetMUSCL_Species(bool val_update) { MUSCL_Species = val_update; } + + /*! + * \brief Set the value of the boolean for choosing MUSCL. + * \param[in] val_update - the bool for whether to update the MUSCL_Heat. + */ + void SetMUSCL_Heat(bool val_update) { MUSCL_Heat = val_update; } + + void SetRestart_FileName(string val_filename) { Restart_FileName = val_filename; } + void SetSolution_FileName(string val_filename) { Solution_FileName = val_filename; } + /*! + * \brief Set the value of the boolean for choosing MUSCL. + * \param[in] val_update - the bool for whether to update the MUSCL_Heat. + */ + void SetRestart(bool val_update) { Restart = val_update; } + /*! * \brief Get if the upwind scheme used MUSCL or not. * \note This is the information that the code will use, the method will @@ -5476,6 +5517,13 @@ class CConfig { */ bool GetMultizone_AdaptFilename(void) const { return Multizone_Adapt_FileName; } + /*! + * \brief Get whether to "Use Accurate Jacobians" for Standard SA turbulence model. + * \return yes/no. + */ + bool GetFirst_Order_Init(void) const { return First_Order_Initialization; } + void SetFirst_Order_Init(bool val_update) { First_Order_Initialization = val_update; } + /*! * \brief Provides the number of variables. * \return Number of variables. @@ -9467,6 +9515,12 @@ class CConfig { */ unsigned long GetnTime_Iter(void) const { return nTimeIter; } + /*! + * \brief Get the number of inner iterations + * \return Number of inner iterations on each multizone block + */ + unsigned long GetnFO_Init_Iter(void) const { return nFOInit_Iter; } + /*! * \brief Set the number of time iterations * \param[in] val_iter - Number of time steps run diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index 2cc59b320a9..7da2a396846 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -1066,7 +1066,7 @@ void CConfig::SetPointersNull() { InnerIter = 0; nIntCoeffs = 0; OuterIter = 0; - + FOInit_Iter = 0; AoA_Offset = 0; AoS_Offset = 0; @@ -1196,6 +1196,8 @@ void CConfig::SetConfig_Options() { addEnumOption("SYSTEM_MEASUREMENTS", SystemMeasurements, Measurements_Map, SI); /*!\brief MULTIZONE_ADAPT_FILENAME \n DESCRIPTION: Append zone number to restart and solution filenames. \ingroup Config*/ addBoolOption("MULTIZONE_ADAPT_FILENAME", Multizone_Adapt_FileName, YES); + /*!\brief INIT_FO_SOL \n DESCRIPTION: Perform a first order simulation to initialize MUSCL reconstructed flow. \ingroup Config*/ + addBoolOption("INIT_FO_SOL", First_Order_Initialization, NO); /*!\par CONFIG_CATEGORY: FluidModel \ingroup Config*/ /*!\brief FLUID_MODEL \n DESCRIPTION: Fluid model \n OPTIONS: See \link FluidModel_Map \endlink \n DEFAULT: STANDARD_AIR \ingroup Config*/ @@ -2612,6 +2614,8 @@ void CConfig::SetConfig_Options() { addUnsignedLongOption("TIME_ITER", nTimeIter, 1); /* DESCRIPTION: Number of iterations in each single-zone block. */ addUnsignedLongOption("ITER", nIter, 1000); + /* DESCRIPTION: Number of first order iterations in each single-zone block before running MUSCL. */ + addUnsignedLongOption("FO_INIT_ITER", nFOInit_Iter, 1); /* DESCRIPTION: Restart iteration in the multizone problem. */ addUnsignedLongOption("RESTART_ITER", Restart_Iter, 1); /* DESCRIPTION: Minimum error threshold for the linear solver for the implicit formulation */ diff --git a/SU2_CFD/include/drivers/CSinglezoneDriver.hpp b/SU2_CFD/include/drivers/CSinglezoneDriver.hpp index 68fe837d14d..4f4a93abc2a 100644 --- a/SU2_CFD/include/drivers/CSinglezoneDriver.hpp +++ b/SU2_CFD/include/drivers/CSinglezoneDriver.hpp @@ -104,6 +104,11 @@ class CSinglezoneDriver : public CDriver { */ void SetInitialMesh() override; + /*! + * \brief Perform a first order simulation as an initial solution before running MUSCL reconstructed flow. + */ + void FirstOrderInit(); + /*! * \brief Monitor * \param ExtIter diff --git a/SU2_CFD/src/drivers/CSinglezoneDriver.cpp b/SU2_CFD/src/drivers/CSinglezoneDriver.cpp index 565f8e8bb52..7485819549b 100644 --- a/SU2_CFD/src/drivers/CSinglezoneDriver.cpp +++ b/SU2_CFD/src/drivers/CSinglezoneDriver.cpp @@ -61,6 +61,16 @@ void CSinglezoneDriver::StartSolver() { << driver_config->GetnTime_Iter() - config_container[ZONE_0]->GetRestart_Iter() << " time steps." << endl; } + if (config_container[ZONE_0]->GetFirst_Order_Init()) { + if (rank == MASTER_NODE) {cout << endl << "--------------------- Running First Order Simulation --------------------" << endl;} + FirstOrderInit(); + if (rank == MASTER_NODE) {cout << endl << "--------------------- Running Second Order Simulation -------------------" << endl;} + config_container[ZONE_0]->SetRestart(true); + config_container[ZONE_0]->SetSolution_FileName("fo_sol_" + config_container[ZONE_0]->GetRestart_FileName()); + SU2_MPI::Barrier(SU2_MPI::GetComm()); + config_container[ZONE_0]->SetFirst_Order_Init(false); + } + /*--- Set the initial time iteration to the restart iteration. ---*/ if (config_container[ZONE_0]->GetRestart() && driver_config->GetTime_Domain()) TimeIter = config_container[ZONE_0]->GetRestart_Iter(); @@ -102,6 +112,46 @@ void CSinglezoneDriver::StartSolver() { } +void CSinglezoneDriver::FirstOrderInit() { + /*--- Save original settings to be restored after FO run ---*/ + bool muscl_flow_orig = config_container[ZONE_0]->GetMUSCL_Flow(); + bool muscl_turb_orig = config_container[ZONE_0]->GetMUSCL_Turb(); + bool muscl_species_orig = config_container[ZONE_0]->GetMUSCL_Species(); + bool muscl_heat_orig = config_container[ZONE_0]->GetMUSCL_Heat(); + unsigned long origInner = config_container[ZONE_0]->GetnInner_Iter(); + unsigned long foInner = config_container[ZONE_0]->GetnFO_Init_Iter(); + + /*--- Disable all MUSCL options before running FO ---*/ + config_container[ZONE_0]->SetMUSCL_Flow(false); + config_container[ZONE_0]->SetMUSCL_Turb(false); + config_container[ZONE_0]->SetMUSCL_Species(false); + config_container[ZONE_0]->SetMUSCL_Heat(false); + config_container[ZONE_0]->SetnInner_Iter(foInner); // Set total iterations + + /*--- Run the problem the number of time iterations required is reached. ---*/ + while ( TimeIter < config_container[ZONE_0]->GetnTime_Iter()) { + Preprocess(TimeIter); + Run(); + Postprocess(); + Update(); + Monitor(TimeIter); + Output(TimeIter); + if (StopCalc) break; + TimeIter++; + } + + SU2_MPI::Barrier(SU2_MPI::GetComm()); + StopCalc = false; + + /*--- Restore original settings after FO run ---*/ + config_container[ZONE_0]->SetMUSCL_Flow(muscl_flow_orig); + config_container[ZONE_0]->SetMUSCL_Turb(muscl_turb_orig); + config_container[ZONE_0]->SetMUSCL_Species(muscl_species_orig); + config_container[ZONE_0]->SetMUSCL_Heat(muscl_heat_orig); + config_container[ZONE_0]->SetnInner_Iter(origInner); // Restore original + +} + void CSinglezoneDriver::Preprocess(unsigned long TimeIter) { /*--- Set the current time iteration in the config and also in the driver @@ -138,6 +188,16 @@ void CSinglezoneDriver::Preprocess(unsigned long TimeIter) { config_container[ZONE_0], TimeIter); } + /* DEBUG: Check the settings */ + if (rank == MASTER_NODE) { + cout << boolalpha; + cout << "[Pre-Proc] MUSCL_FLOW = " << config_container[ZONE_0]->GetMUSCL_Flow() << "\n" + << "[Pre-Proc] MUSCL_TURB = " << config_container[ZONE_0]->GetMUSCL_Turb() << "\n" + << "[Pre-Proc] MUSCL_SPECIES= " << config_container[ZONE_0]->GetMUSCL_Species()<< "\n" + << "[Pre-Proc] MUSCL_HEAT = " << config_container[ZONE_0]->GetMUSCL_Heat() << "\n" + << "[Pre-Proc] nInner_Iter = " << config_container[ZONE_0]->GetnInner_Iter() << endl; + } + SU2_MPI::Barrier(SU2_MPI::GetComm()); /*--- Run a predictor step ---*/ diff --git a/SU2_CFD/src/output/COutput.cpp b/SU2_CFD/src/output/COutput.cpp index 90d39de199c..7ccf33595fd 100644 --- a/SU2_CFD/src/output/COutput.cpp +++ b/SU2_CFD/src/output/COutput.cpp @@ -85,6 +85,7 @@ COutput::COutput(const CConfig *config, unsigned short ndim, bool fem_output): /*--- Retrieve the history filename ---*/ historyFilename = config->GetConv_FileName(); + if (config->GetFirst_Order_Init() && !config->GetMUSCL_Flow()) historyFilename = "fo_sol_" + historyFilename; /*--- Add the correct file extension depending on the file format ---*/ @@ -418,6 +419,7 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form if (fileName.empty()) fileName = config->GetFilename(surfaceFilename, "", curTimeIter); + if (config->GetFirst_Order_Init() && !config->GetMUSCL_Flow()) fileName = "fo_sol_" + fileName; if (!config->GetWrt_Surface_Overwrite()) filename_iter = config->GetFilename_Iter(fileName, curInnerIter, curOuterIter); @@ -440,6 +442,7 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form if (fileName.empty()) fileName = config->GetFilename(restartFilename, "", curTimeIter); + if (config->GetFirst_Order_Init() && !config->GetMUSCL_Flow()) fileName = "fo_sol_" + fileName; if (!config->GetWrt_Restart_Overwrite()) filename_iter = config->GetFilename_Iter(fileName, curInnerIter, curOuterIter); @@ -459,6 +462,7 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form if (fileName.empty()) fileName = config->GetFilename(restartFilename, "", curTimeIter); + if (config->GetFirst_Order_Init() && !config->GetMUSCL_Flow()) fileName = "fo_sol_" + fileName; if (!config->GetWrt_Restart_Overwrite()) filename_iter = config->GetFilename_Iter(fileName, curInnerIter, curOuterIter); @@ -479,6 +483,7 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form if (fileName.empty()) fileName = config->GetFilename(volumeFilename, "", curTimeIter); + if (config->GetFirst_Order_Init() && !config->GetMUSCL_Flow()) fileName = "fo_sol_" + fileName; if (!config->GetWrt_Volume_Overwrite()) filename_iter = config->GetFilename_Iter(fileName, curInnerIter, curOuterIter); @@ -498,6 +503,7 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form if (fileName.empty()) fileName = config->GetFilename(volumeFilename, "", curTimeIter); + if (config->GetFirst_Order_Init() && !config->GetMUSCL_Flow()) fileName = "fo_sol_" + fileName; if (!config->GetWrt_Volume_Overwrite()) filename_iter = config->GetFilename_Iter(fileName, curInnerIter, curOuterIter); @@ -517,6 +523,7 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form if (fileName.empty()) fileName = config->GetFilename(volumeFilename, "", curTimeIter); + if (config->GetFirst_Order_Init() && !config->GetMUSCL_Flow()) fileName = "fo_sol_" + fileName; if (!config->GetWrt_Volume_Overwrite()) filename_iter = config->GetFilename_Iter(fileName, curInnerIter, curOuterIter); @@ -536,6 +543,7 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form if (fileName.empty()) fileName = config->GetFilename(volumeFilename, "", curTimeIter); + if (config->GetFirst_Order_Init() && !config->GetMUSCL_Flow()) fileName = "fo_sol_" + fileName; if (!config->GetWrt_Volume_Overwrite()) filename_iter = config->GetFilename_Iter(fileName, curInnerIter, curOuterIter); @@ -555,6 +563,7 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form if (fileName.empty()) fileName = config->GetFilename(volumeFilename, "", curTimeIter); + if (config->GetFirst_Order_Init() && !config->GetMUSCL_Flow()) fileName = "fo_sol_" + fileName; if (!config->GetWrt_Volume_Overwrite()) filename_iter = config->GetFilename_Iter(fileName, curInnerIter, curOuterIter); @@ -574,6 +583,7 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form if (fileName.empty()) fileName = config->GetUnsteady_FileName(volumeFilename, curTimeIter, ""); + if (config->GetFirst_Order_Init() && !config->GetMUSCL_Flow()) fileName = "fo_sol_" + fileName; if (!config->GetWrt_Volume_Overwrite()) filename_iter = config->GetFilename_Iter(fileName, curInnerIter, curOuterIter); @@ -603,6 +613,7 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form if (fileName.empty()) fileName = config->GetFilename(volumeFilename, "", curTimeIter); + if (config->GetFirst_Order_Init() && !config->GetMUSCL_Flow()) fileName = "fo_sol_" + fileName; if (!config->GetWrt_Volume_Overwrite()) filename_iter = config->GetFilename_Iter(fileName, curInnerIter, curOuterIter); @@ -622,6 +633,7 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form if (fileName.empty()) fileName = config->GetFilename(surfaceFilename, "", curTimeIter); + if (config->GetFirst_Order_Init() && !config->GetMUSCL_Flow()) fileName = "fo_sol_" + fileName; if (!config->GetWrt_Surface_Overwrite()) filename_iter = config->GetFilename_Iter(fileName, curInnerIter, curOuterIter); @@ -642,6 +654,7 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form if (fileName.empty()) fileName = config->GetFilename(surfaceFilename, "", curTimeIter); + if (config->GetFirst_Order_Init() && !config->GetMUSCL_Flow()) fileName = "fo_sol_" + fileName; if (!config->GetWrt_Surface_Overwrite()) filename_iter = config->GetFilename_Iter(fileName, curInnerIter, curOuterIter); @@ -662,6 +675,7 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form if (fileName.empty()) fileName = config->GetFilename(surfaceFilename, "", curTimeIter); + if (config->GetFirst_Order_Init() && !config->GetMUSCL_Flow()) fileName = "fo_sol_" + fileName; if (!config->GetWrt_Surface_Overwrite()) filename_iter = config->GetFilename_Iter(fileName, curInnerIter, curOuterIter); @@ -682,6 +696,7 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form if (fileName.empty()) fileName = config->GetFilename(surfaceFilename, "", curTimeIter); + if (config->GetFirst_Order_Init() && !config->GetMUSCL_Flow()) fileName = "fo_sol_" + fileName; if (!config->GetWrt_Surface_Overwrite()) filename_iter = config->GetFilename_Iter(fileName, curInnerIter, curOuterIter); @@ -702,6 +717,7 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form if (fileName.empty()) fileName = config->GetFilename(surfaceFilename, "", curTimeIter); + if (config->GetFirst_Order_Init() && !config->GetMUSCL_Flow()) fileName = "fo_sol_" + fileName; if (!config->GetWrt_Surface_Overwrite()) filename_iter = config->GetFilename_Iter(fileName, curInnerIter, curOuterIter); @@ -722,6 +738,7 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form if (fileName.empty()) fileName = config->GetFilename(surfaceFilename, "", curTimeIter); + if (config->GetFirst_Order_Init() && !config->GetMUSCL_Flow()) fileName = "fo_sol_" + fileName; if (!config->GetWrt_Surface_Overwrite()) filename_iter = config->GetFilename_Iter(fileName, curInnerIter, curOuterIter); @@ -741,6 +758,7 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form if (fileName.empty()) fileName = config->GetFilename(volumeFilename, "", curTimeIter); + if (config->GetFirst_Order_Init() && !config->GetMUSCL_Flow()) fileName = "fo_sol_" + fileName; if (!config->GetWrt_Volume_Overwrite()) filename_iter = config->GetFilename_Iter(fileName, curInnerIter, curOuterIter); @@ -759,6 +777,7 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form if (fileName.empty()) fileName = config->GetFilename(surfaceFilename, "", curTimeIter); + if (config->GetFirst_Order_Init() && !config->GetMUSCL_Flow()) fileName = "fo_sol_" + fileName; if (!config->GetWrt_Surface_Overwrite()) filename_iter = config->GetFilename_Iter(fileName, curInnerIter, curOuterIter); diff --git a/config_template.cfg b/config_template.cfg index b733de0c0a2..eb87c28c87e 100644 --- a/config_template.cfg +++ b/config_template.cfg @@ -66,6 +66,9 @@ RESTART_SOL= NO % default restart fields in them, add the keyword COMPACT to VOLUME_OUTPUT. WRT_RESTART_COMPACT= YES % +% Perform a first order simulation to initialize the MUSCL reconstructed flow +INIT_FO_SOL= NO +% % Discard the data storaged in the solution and geometry files % e.g. AOA, dCL/dAoA, dCD/dCL, iter, etc. % Note that AoA in the solution and geometry files is critical