diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index dc96c21ad3b..711d28055a3 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -5601,14 +5601,14 @@ class CConfig { unsigned short GetnVar(void); /*! - * \brief Provides the number of variables. - * \return Number of variables. + * \brief Provides the total number of zones. + * \return Total number of zones. */ unsigned short GetnZone(void) const { return nZone; } /*! - * \brief Provides the number of variables. - * \return Number of variables. + * \brief Provides the zone index the configuration belongs to. + * \return Zone index. */ unsigned short GetiZone(void) const { return iZone; } diff --git a/Common/include/basic_types/ad_structure.hpp b/Common/include/basic_types/ad_structure.hpp index 1f223937f39..79d1636b7f5 100644 --- a/Common/include/basic_types/ad_structure.hpp +++ b/Common/include/basic_types/ad_structure.hpp @@ -1,7 +1,7 @@ /*! * \file ad_structure.hpp * \brief Main routines for the algorithmic differentiation (AD) structure. - * \author T. Albring, J. Blühdorn + * \author T. Albring, J. Blühdorn, O. Burghardt * \version 8.4.0 "Harrier" * * SU2 Project Website: https://su2code.github.io @@ -36,7 +36,22 @@ * In case there is no reverse type configured, they have no effect at all, * and so the real versions of the routined are after #else. */ + namespace AD { + +enum class TAPE_DEBUG_OPTION { + IGNORE_PREACC, + ACTIVATE_PREACC, + IGNORE_SINGLE_ZONE, + ACTIVATE_SINGLE_ZONE, + IGNORE_ZONES, + ACTIVATE_ZONES, + ACTIVATE_ALL_ERRORS, + MULTIZONE_TAGS, + INIT_RUN, + CHECK_RUN +}; + #ifndef CODI_REVERSE_TYPE using Identifier = int; @@ -287,6 +302,13 @@ inline void SetIndex(Identifier& index, const su2double& data) {} */ inline void SetTag(int tag) {} +/*! + * \brief Compute the zone-specific tag. + * \param[in] iZone - Zone index from which the zone-specific tag is formed. + * \return The zone-specific tag. + */ +inline int GetTag(unsigned short iZone) { return 0; } + /*! * \brief Sets the tag of a variable to 0. * \param[in] v - the variable whose tag is cleared. @@ -296,33 +318,45 @@ inline void ClearTagOnVariable(su2double& v) {} /*! * \brief Struct to store information about errors during a tag debug run. */ -struct ErrorReport {}; +struct DebugControl {}; /*! - * \brief Set a reference to the output file of an ErrorReport. - * \param[in] report - the ErrorReport whose output file is set. - * \param[in] output_file - pointer to the output file. + * \brief Set a pointer to the current DebugControl. + * \param[in] control - pointer to the current debug control. + */ +inline void SetDebugControl(DebugControl* control) {} + +/*! + * \brief Set options which kind of tag mismatches are considered errors and written to file. + * \param[in] option - specification which kind of tag mismatches are considered. + * \param[in] izone - the zone w.r.t. which a tag mismatch is allowed. */ -inline void SetDebugReportFile(ErrorReport& report, std::ostream* output_file) {} +inline void SetTapeDebugOption(TAPE_DEBUG_OPTION option, unsigned short izone = 0) {} /*! - * \brief Set the ErrorReport to which error information from a tag debug recording is written. - * \param[in] report - the ErrorReport to which error information is written. + * \brief Activate the error callback by letting the tape call tagErrorCallback whenever a tag mismatch arises. */ -inline void SetTagErrorCallback(ErrorReport& report) {} +inline void ActivateTagErrorCallback() {} /*! - * \brief Reset the error counter in an ErrorReport. - * \param[in] report - the ErrorReport whose error counter is resetted. + * \brief Set a pointer to the output file of a DebugControl. + * \param[in] control - the DebugControl whose output file is set. + * \param[in] output_file - pointer to the output file. + */ +inline void SetDebugReportFile(DebugControl& control, std::ostream* output_file) {} + +/*! + * \brief Reset the error counter in a DebugControl. + * \param[in] control - the DebugControl whose error counter is resetted. */ -inline void ResetErrorCounter(ErrorReport& report) {} +inline void ResetErrorCounter(DebugControl& control) {} /*! - * \brief Get the error count of an ErrorReport. - * \param[in] report - the ErrorReport whose pointer to its error counter is returned. + * \brief Get the error count of a DebugControl. + * \param[in] control - the DebugControl whose error count is reported. * \return Value of the error counter. */ -inline unsigned long GetErrorCount(const ErrorReport& report) { return 0; } +inline unsigned long GetErrorCount(const DebugControl& control) { return 0; } /*! * \brief Pushes back the current tape position to the tape position's vector. @@ -744,37 +778,125 @@ FORCEINLINE void ResumePreaccumulation(bool wasActive) { SU2_OMP_SAFE_GLOBAL_ACCESS(PreaccEnabled = true;) } -struct ErrorReport { +#ifdef CODI_TAG_TAPE + +struct DebugControl { + bool multizone_tags = false; + bool init_run = false; + bool ignore_preacc = false; + bool ignore_single_zone = false; + bool ignore_zones = false; + unsigned short ignore_izone = 0; unsigned long ErrorCounter = 0; std::ostream* out = &std::cout; }; -FORCEINLINE void ResetErrorCounter(ErrorReport& report) { report.ErrorCounter = 0; } +FORCEINLINE void ResetErrorCounter(DebugControl& control) { control.ErrorCounter = 0; } -FORCEINLINE void SetDebugReportFile(ErrorReport& report, std::ostream* output_file) { report.out = output_file; } +FORCEINLINE void SetDebugReportFile(DebugControl& control, std::ostream* output_file) { control.out = output_file; } -FORCEINLINE unsigned long GetErrorCount(const ErrorReport& report) { return report.ErrorCounter; } +FORCEINLINE unsigned long GetErrorCount(const DebugControl& control) { return control.ErrorCounter; } -#ifdef CODI_TAG_TAPE +extern DebugControl* current_control; + +FORCEINLINE void SetDebugControl(DebugControl* control) { current_control = control; } FORCEINLINE void SetTag(int tag) { AD::getTape().setCurTag(tag); } + +FORCEINLINE int GetTag(unsigned short iZone) { + if (current_control->init_run) { + return (current_control->multizone_tags) ? ((int)iZone + 1) * 10 + 1 : 1; + } else { + return (current_control->multizone_tags) ? ((int)iZone + 1) * 10 + 2 : 2; + } +} + FORCEINLINE void ClearTagOnVariable(su2double& v) { AD::getTape().clearTagOnVariable(v); } static void tagErrorCallback(const int& correctTag, const int& wrongTag, void* userData) { - auto* report = static_cast(userData); + auto* status = static_cast(userData); + + bool throw_mismatch_error = true; + + if (status->ignore_preacc || status->ignore_single_zone || status->ignore_zones) { + /*--- The callback could be due to a preaccumulation tag mismatch, if not, we deduce + * that it is either due to a zone index mismatch, or due to a mismatch in the least + * significant bit that will always result in an error. ---*/ + + if (correctTag == 1337) { + if (status->ignore_preacc) { + throw_mismatch_error = false; + } + } else if (correctTag % 10 == wrongTag % 10) { + if (status->ignore_single_zone) { + /*--- A mismatch with a specified zone index might be allowed. ---*/ + if (wrongTag / 10 == status->ignore_single_zone) { + throw_mismatch_error = false; + } + } + if (status->ignore_zones) { + throw_mismatch_error = false; + } + } + } + + if (throw_mismatch_error) { + status->ErrorCounter += 1; + *(status->out) << "Use of variable with bad tag '" << std::setw(2) << std::setfill('0') << wrongTag + << "', should be '" << std::setw(2) << std::setfill('0') << correctTag << "'." << std::endl; + } +} - report->ErrorCounter += 1; - *(report->out) << "Use of variable with bad tag '" << wrongTag << "', should be '" << correctTag << "'." << std::endl; +FORCEINLINE void SetTapeDebugOption(TAPE_DEBUG_OPTION option, unsigned short izone = 0) { + if (option == AD::TAPE_DEBUG_OPTION::IGNORE_PREACC) { + current_control->ignore_preacc = true; + } + if (option == AD::TAPE_DEBUG_OPTION::ACTIVATE_PREACC || option == AD::TAPE_DEBUG_OPTION::ACTIVATE_ALL_ERRORS) { + current_control->ignore_preacc = false; + } + if (option == AD::TAPE_DEBUG_OPTION::IGNORE_SINGLE_ZONE) { + current_control->ignore_single_zone = true; + current_control->ignore_izone = izone; + } + if (option == AD::TAPE_DEBUG_OPTION::ACTIVATE_SINGLE_ZONE || option == AD::TAPE_DEBUG_OPTION::ACTIVATE_ALL_ERRORS) { + current_control->ignore_single_zone = false; + } + if (option == AD::TAPE_DEBUG_OPTION::IGNORE_ZONES) { + current_control->ignore_zones = true; + } + if (option == AD::TAPE_DEBUG_OPTION::ACTIVATE_ZONES || option == AD::TAPE_DEBUG_OPTION::ACTIVATE_ALL_ERRORS) { + current_control->ignore_zones = false; + } + if (option == AD::TAPE_DEBUG_OPTION::INIT_RUN) { + current_control->init_run = true; + } + if (option == AD::TAPE_DEBUG_OPTION::CHECK_RUN) { + current_control->init_run = false; + } + if (option == AD::TAPE_DEBUG_OPTION::MULTIZONE_TAGS) { + current_control->multizone_tags = true; + } } -FORCEINLINE void SetTagErrorCallback(ErrorReport& report) { - AD::getTape().setTagErrorCallback(tagErrorCallback, &report); +FORCEINLINE void ActivateTagErrorCallback() { + if (current_control != NULL) { + AD::getTape().setTagErrorCallback(tagErrorCallback, current_control); + } else { + std::cout << "No tape debug control set!" << std::endl; + } } #else +struct DebugControl {}; +FORCEINLINE void ResetErrorCounter(DebugControl& control) {} +FORCEINLINE void SetDebugReportFile(DebugControl& control, std::ostream* output_file) {} +FORCEINLINE unsigned long GetErrorCount(const DebugControl& control) { return 0; } +FORCEINLINE void SetDebugControl(DebugControl* status) {} FORCEINLINE void SetTag(int tag) {} +FORCEINLINE int GetTag(unsigned short iZone) { return 0; } FORCEINLINE void ClearTagOnVariable(su2double& v) {} -FORCEINLINE void SetTagErrorCallback(ErrorReport report) {} +FORCEINLINE void SetTapeDebugOption(TAPE_DEBUG_OPTION option, unsigned short izone = 0) {} +FORCEINLINE void ActivateTagErrorCallback() {} #endif // CODI_TAG_TAPE diff --git a/Common/include/option_structure.hpp b/Common/include/option_structure.hpp index 690350fae05..41b552814b7 100644 --- a/Common/include/option_structure.hpp +++ b/Common/include/option_structure.hpp @@ -2618,7 +2618,7 @@ enum class CHECK_TAPE_VARIABLES { }; static const MapType CheckTapeVariables_Map = { MakePair("SOLVER_VARIABLES", CHECK_TAPE_VARIABLES::SOLVER_VARIABLES) - MakePair("SOLVER_VARIABLES_AND_MESH_COORDINATES", CHECK_TAPE_VARIABLES::MESH_COORDINATES) + MakePair("MESH_COORDINATES", CHECK_TAPE_VARIABLES::MESH_COORDINATES) }; enum class RECORDING { @@ -2626,11 +2626,7 @@ enum class RECORDING { SOLUTION_VARIABLES, MESH_COORDS, MESH_DEFORM, - SOLUTION_AND_MESH, - TAG_INIT_SOLVER_VARIABLES, - TAG_CHECK_SOLVER_VARIABLES, - TAG_INIT_SOLVER_AND_MESH, - TAG_CHECK_SOLVER_AND_MESH + SOLUTION_AND_MESH }; /*! diff --git a/Common/src/basic_types/ad_structure.cpp b/Common/src/basic_types/ad_structure.cpp index 5deabbd6a3f..07a36a4b42a 100644 --- a/Common/src/basic_types/ad_structure.cpp +++ b/Common/src/basic_types/ad_structure.cpp @@ -48,6 +48,10 @@ SU2_OMP(threadprivate(PreaccHelper)) ExtFuncHelper FuncHelper; +#ifdef CODI_TAG_TAPE +DebugControl* current_control = NULL; +#endif // CODI_TAG_TAPE + #endif void Initialize() { diff --git a/SU2_CFD/include/drivers/CDiscAdjMultizoneDriver.hpp b/SU2_CFD/include/drivers/CDiscAdjMultizoneDriver.hpp index 784fae55a85..6e1a012a890 100644 --- a/SU2_CFD/include/drivers/CDiscAdjMultizoneDriver.hpp +++ b/SU2_CFD/include/drivers/CDiscAdjMultizoneDriver.hpp @@ -141,16 +141,6 @@ class CDiscAdjMultizoneDriver : public CMultizoneDriver { */ void StartSolver() override; - /*! - * \brief [Overload] Launch the tape test mode for the discrete adjoint multizone solver. - */ - void TapeTest (); - - /*! - * \brief [Overload] Get error numbers after a tape test run of the discrete adjoint multizone solver. - */ - int TapeTestGatherErrors(AD::ErrorReport& error_report) const; - /*! * \brief Preprocess the multizone iteration */ @@ -303,4 +293,15 @@ class CDiscAdjMultizoneDriver : public CMultizoneDriver { } } + /*! + * \brief Launch the tape test run of the discrete adjoint multizone solver. + */ + void TapeTest (); + + /*! + * \brief Get the total error count after a tape test run of the discrete adjoint multizone solver. + * \param[in] debug_control - DebugControl from which this rank's contribution to the total error count is read. + * \return The total error count across all ranks. + */ + int TapeTestGatherErrors(AD::DebugControl& debug_control) const; }; diff --git a/SU2_CFD/src/drivers/CDiscAdjMultizoneDriver.cpp b/SU2_CFD/src/drivers/CDiscAdjMultizoneDriver.cpp index 392abeebe9f..d40e3ea7a01 100644 --- a/SU2_CFD/src/drivers/CDiscAdjMultizoneDriver.cpp +++ b/SU2_CFD/src/drivers/CDiscAdjMultizoneDriver.cpp @@ -231,46 +231,72 @@ void CDiscAdjMultizoneDriver::StartSolver() { void CDiscAdjMultizoneDriver::TapeTest() { + if (nZone > 100) { + SU2_MPI::Error("The tape debug mode tag system is limited to a maximum zone number of 100.", CURRENT_FUNCTION); + } + if (rank == MASTER_NODE) { cout <<"\n---------------------------- Start Debug Run ----------------------------" << endl; } int total_errors = 0; - AD::ErrorReport error_report; - AD::SetTagErrorCallback(error_report); - std::ofstream out1("run1_process" + to_string(rank) + ".out"); - std::ofstream out2("run2_process" + to_string(rank) + ".out"); - AD::ResetErrorCounter(error_report); - AD::SetDebugReportFile(error_report, &out1); + /*--- Errors are reported to an instance of AD::DebugControl that holds an error counter, a pointer to + * an error log file and configurations determined by the TAPE_DEBUG_OPTION settings. ---*/ + AD::DebugControl debug_control; + + /*--- Set a pointer to the current status internally in the AD structure. ---*/ + AD::SetDebugControl(&debug_control); + + AD::ActivateTagErrorCallback(); + + /*--- For multizone cases (nZone > 1), we use zone-specific tags. ---*/ + if(nZone > 1) { AD::SetTapeDebugOption(AD::TAPE_DEBUG_OPTION::MULTIZONE_TAGS); } + + /*--- Set the default tag mismatch callback (consider every mismatch an error). ---*/ + AD::SetTapeDebugOption(AD::TAPE_DEBUG_OPTION::ACTIVATE_ALL_ERRORS); - /*--- This recording will assign the initial (same) tag to each registered variable. + // Make this a config option? + // AD::SetCallbackMode(AD::TAPE_TEST_MODE::IGNORE_ZONES); + + /*--- Reset the error counter and set the error log file (each process writes its own). ---*/ + AD::ResetErrorCounter(debug_control); + std::ofstream out("debug_run_process" + to_string(rank) + ".out"); + AD::SetDebugReportFile(debug_control, &out); + + /*--- This recording will assign an initial, zone-specific tag to each registered variable. * During the recording, each dependent variable will be assigned the same tag. ---*/ + out << "-----------------------------------------------------------------------------------------" << std::endl; + out << "INITIAL recording." << std::endl; + out << "Errors appearing in this recording are most likely preaccumulation errors (preaccumulation tag: 1337).\n" << std::endl; + + AD::SetTapeDebugOption(AD::TAPE_DEBUG_OPTION::INIT_RUN); + if(driver_config->GetAD_CheckTapeType() == CHECK_TAPE_TYPE::OBJECTIVE_FUNCTION) { if(driver_config->GetAD_CheckTapeVariables() == CHECK_TAPE_VARIABLES::MESH_COORDINATES) { if (rank == MASTER_NODE) cout << "\nChecking OBJECTIVE_FUNCTION_TAPE for SOLVER_VARIABLES_AND_MESH_COORDINATES." << endl; - SetRecording(RECORDING::TAG_INIT_SOLVER_AND_MESH, Kind_Tape::OBJECTIVE_FUNCTION_TAPE, ZONE_0); + SetRecording(RECORDING::MESH_COORDS, Kind_Tape::OBJECTIVE_FUNCTION_TAPE, ZONE_0); } else { if (rank == MASTER_NODE) cout << "\nChecking OBJECTIVE_FUNCTION_TAPE for SOLVER_VARIABLES." << endl; - SetRecording(RECORDING::TAG_INIT_SOLVER_VARIABLES, Kind_Tape::OBJECTIVE_FUNCTION_TAPE, ZONE_0); + SetRecording(RECORDING::SOLUTION_VARIABLES, Kind_Tape::OBJECTIVE_FUNCTION_TAPE, ZONE_0); } } else { if(driver_config->GetAD_CheckTapeVariables() == CHECK_TAPE_VARIABLES::MESH_COORDINATES) { if (rank == MASTER_NODE) cout << "\nChecking FULL_SOLVER_TAPE for SOLVER_VARIABLES_AND_MESH_COORDINATES." << endl; - SetRecording(RECORDING::TAG_INIT_SOLVER_AND_MESH, Kind_Tape::FULL_SOLVER_TAPE, ZONE_0); + SetRecording(RECORDING::MESH_COORDS, Kind_Tape::FULL_SOLVER_TAPE, ZONE_0); } else { if (rank == MASTER_NODE) cout << "\nChecking FULL_SOLVER_TAPE for SOLVER_VARIABLES." << endl; - SetRecording(RECORDING::TAG_INIT_SOLVER_VARIABLES, Kind_Tape::FULL_SOLVER_TAPE, ZONE_0); + SetRecording(RECORDING::SOLUTION_VARIABLES, Kind_Tape::FULL_SOLVER_TAPE, ZONE_0); } } - total_errors = TapeTestGatherErrors(error_report); - AD::ResetErrorCounter(error_report); - AD::SetDebugReportFile(error_report, &out2); + /*--- Gather errors from all ranks from the initial recording (e.g. preaccumulation errors). ---*/ + total_errors = TapeTestGatherErrors(debug_control); + AD::ResetErrorCounter(debug_control); /*--- This recording repeats the initial recording with a different tag. * If a variable was used before it became dependent on the inputs, this variable will still carry the tag @@ -278,19 +304,29 @@ void CDiscAdjMultizoneDriver::TapeTest() { * In such a case, a possible reason could be that such a variable is set by a post-processing routine while * for a mathematically correct recording this dependency must be included earlier. ---*/ + out << "-------------------------------------------------------------------------------------------------" << std::endl; + out << "IZONE = " << iZone << ", SECOND recording." << std::endl; + out << "Errors appearing hereafter are most likely mathematical errors (e.g. check for circular dependencies)." << std::endl; + + AD::SetTapeDebugOption(AD::TAPE_DEBUG_OPTION::CHECK_RUN); + + /*--- We ignore preaccumulation mismatches during the second recording as they have already been reported. ---*/ + AD::SetTapeDebugOption(AD::TAPE_DEBUG_OPTION::IGNORE_PREACC); + if(driver_config->GetAD_CheckTapeType() == CHECK_TAPE_TYPE::OBJECTIVE_FUNCTION) { if(driver_config->GetAD_CheckTapeVariables() == CHECK_TAPE_VARIABLES::MESH_COORDINATES) - SetRecording(RECORDING::TAG_CHECK_SOLVER_AND_MESH, Kind_Tape::OBJECTIVE_FUNCTION_TAPE, ZONE_0); + SetRecording(RECORDING::MESH_COORDS, Kind_Tape::OBJECTIVE_FUNCTION_TAPE, ZONE_0); else - SetRecording(RECORDING::TAG_CHECK_SOLVER_VARIABLES, Kind_Tape::OBJECTIVE_FUNCTION_TAPE, ZONE_0); + SetRecording(RECORDING::SOLUTION_VARIABLES, Kind_Tape::OBJECTIVE_FUNCTION_TAPE, ZONE_0); } else { if(driver_config->GetAD_CheckTapeVariables() == CHECK_TAPE_VARIABLES::MESH_COORDINATES) - SetRecording(RECORDING::TAG_CHECK_SOLVER_AND_MESH, Kind_Tape::FULL_SOLVER_TAPE, ZONE_0); + SetRecording(RECORDING::MESH_COORDS, Kind_Tape::FULL_SOLVER_TAPE, ZONE_0); else - SetRecording(RECORDING::TAG_CHECK_SOLVER_VARIABLES, Kind_Tape::FULL_SOLVER_TAPE, ZONE_0); + SetRecording(RECORDING::SOLUTION_VARIABLES, Kind_Tape::FULL_SOLVER_TAPE, ZONE_0); } - total_errors += TapeTestGatherErrors(error_report); + total_errors += TapeTestGatherErrors(debug_control); + if (rank == MASTER_NODE) { cout << "\n------------------------- Tape Test Run Summary -------------------------" << endl; @@ -299,9 +335,9 @@ void CDiscAdjMultizoneDriver::TapeTest() { } } -int CDiscAdjMultizoneDriver::TapeTestGatherErrors(AD::ErrorReport& error_report) const { +int CDiscAdjMultizoneDriver::TapeTestGatherErrors(AD::DebugControl& debug_control) const { - int num_errors = AD::GetErrorCount(error_report); + int num_errors = AD::GetErrorCount(debug_control); int total_errors = 0; std::vector process_error(size); SU2_MPI::Allreduce(&num_errors, &total_errors, 1, MPI_INT, MPI_SUM, SU2_MPI::GetComm()); @@ -706,10 +742,6 @@ void CDiscAdjMultizoneDriver::SetRecording(RECORDING kind_recording, Kind_Tape t case RECORDING::CLEAR_INDICES: cout << "Clearing the computational graph." << endl; break; case RECORDING::MESH_COORDS: cout << "Storing computational graph wrt MESH COORDINATES." << endl; break; case RECORDING::SOLUTION_VARIABLES: cout << "Storing computational graph wrt CONSERVATIVE VARIABLES." << endl; break; - case RECORDING::TAG_INIT_SOLVER_VARIABLES: cout << "Simulating recording with tag 1 on conservative variables." << endl; AD::SetTag(1); break; - case RECORDING::TAG_CHECK_SOLVER_VARIABLES: cout << "Checking first recording with tag 2 on conservative variables." << endl; AD::SetTag(2); break; - case RECORDING::TAG_INIT_SOLVER_AND_MESH: cout << "Simulating recording with tag 1 on conservative variables and mesh coordinates." << endl; AD::SetTag(1); break; - case RECORDING::TAG_CHECK_SOLVER_AND_MESH: cout << "Checking first recording with tag 2 on conservative variables and mesh coordinates." << endl; AD::SetTag(2); break; default: break; } } @@ -734,6 +766,12 @@ void CDiscAdjMultizoneDriver::SetRecording(RECORDING kind_recording, Kind_Tape t type_recording = RECORDING::MESH_DEFORM; } + /*--- If we are in tape debug mode, set a global (but zone-specific) tag. + * Every variable that we register below will be initialized with this tag. ---*/ + int tag = AD::GetTag(iZone); + cout << " - with tag " << tag << " on zone " << iZone << "." << endl; + AD::SetTag(tag); + iteration_container[iZone][INST_0]->RegisterInput(solver_container, geometry_container, config_container, iZone, INST_0, type_recording); } @@ -742,6 +780,10 @@ void CDiscAdjMultizoneDriver::SetRecording(RECORDING kind_recording, Kind_Tape t AD::Push_TapePosition(); /// REGISTERED for (iZone = 0; iZone < nZone; iZone++) { + + /*--- If in tape debug mode, set the zone-specific tag for computations in this zone. ---*/ + AD::SetTag(AD::GetTag(iZone)); + iteration_container[iZone][INST_0]->SetDependencies(solver_container, geometry_container, numerics_container, config_container, iZone, INST_0, kind_recording); } @@ -755,6 +797,10 @@ void CDiscAdjMultizoneDriver::SetRecording(RECORDING kind_recording, Kind_Tape t if ((tape_type == Kind_Tape::OBJECTIVE_FUNCTION_TAPE) || (kind_recording == RECORDING::MESH_COORDS)) { HandleDataTransfer(); for (iZone = 0; iZone < nZone; iZone++) { + + /*--- If in tape debug mode, set the zone-specific test tag for computations in this zone. ---*/ + AD::SetTag(AD::GetTag(iZone)); + if (Has_Deformation(iZone)) { iteration_container[iZone][INST_0]->SetDependencies(solver_container, geometry_container, numerics_container, config_container, iZone, INST_0, kind_recording); @@ -781,6 +827,9 @@ void CDiscAdjMultizoneDriver::SetRecording(RECORDING kind_recording, Kind_Tape t AD::Push_TapePosition(); /// enter_zone + /*--- If in tape debug mode, set the zone-specific test tag for computations in this zone. ---*/ + AD::SetTag(AD::GetTag(iZone)); + DirectIteration(iZone, kind_recording); iteration_container[iZone][INST_0]->RegisterOutput(solver_container, geometry_container, @@ -863,10 +912,7 @@ void CDiscAdjMultizoneDriver::SetObjFunction(RECORDING kind_recording) { AD::RegisterOutput(ObjFunc); AD::SetIndex(ObjFunc_Index, ObjFunc); if (kind_recording == RECORDING::SOLUTION_VARIABLES || - kind_recording == RECORDING::TAG_INIT_SOLVER_VARIABLES || - kind_recording == RECORDING::TAG_CHECK_SOLVER_VARIABLES || - kind_recording == RECORDING::TAG_INIT_SOLVER_AND_MESH || - kind_recording == RECORDING::TAG_CHECK_SOLVER_AND_MESH) { + kind_recording == RECORDING::MESH_COORDS) { cout << " Objective function : " << ObjFunc << endl; } } diff --git a/SU2_CFD/src/iteration/CDiscAdjFluidIteration.cpp b/SU2_CFD/src/iteration/CDiscAdjFluidIteration.cpp index a10f7c4505f..1067b58a023 100644 --- a/SU2_CFD/src/iteration/CDiscAdjFluidIteration.cpp +++ b/SU2_CFD/src/iteration/CDiscAdjFluidIteration.cpp @@ -404,12 +404,15 @@ void CDiscAdjFluidIteration::RegisterInput(CSolver***** solver, CGeometry**** ge SU2_OMP_PARALLEL_(if(solvers0[ADJFLOW_SOL]->GetHasHybridParallel())) { + bool AD_debug_mesh_coordinates = false; + if (config[iZone]->GetAD_CheckTapeVariables() == CHECK_TAPE_VARIABLES::MESH_COORDINATES) { + cout << "Register additional SOLUTION VARIABLES for tag debug mode (zone " << iZone << ")." << endl; + AD_debug_mesh_coordinates = true; + } + if (kind_recording == RECORDING::SOLUTION_VARIABLES || - kind_recording == RECORDING::TAG_INIT_SOLVER_VARIABLES || - kind_recording == RECORDING::TAG_CHECK_SOLVER_VARIABLES || - kind_recording == RECORDING::TAG_INIT_SOLVER_AND_MESH || - kind_recording == RECORDING::TAG_CHECK_SOLVER_AND_MESH || - kind_recording == RECORDING::SOLUTION_AND_MESH) { + kind_recording == RECORDING::SOLUTION_AND_MESH || + AD_debug_mesh_coordinates) { /*--- Register flow and turbulent variables as input ---*/ @@ -436,9 +439,7 @@ void CDiscAdjFluidIteration::RegisterInput(CSolver***** solver, CGeometry**** ge } if (kind_recording == RECORDING::MESH_COORDS || - kind_recording == RECORDING::SOLUTION_AND_MESH || - kind_recording == RECORDING::TAG_INIT_SOLVER_AND_MESH || - kind_recording == RECORDING::TAG_CHECK_SOLVER_AND_MESH) { + kind_recording == RECORDING::SOLUTION_AND_MESH) { /*--- Register node coordinates as input ---*/ geometry0->RegisterCoordinates();