diff --git a/AUTHORS.md b/AUTHORS.md index f47640de49a..f8c364f411b 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -71,6 +71,7 @@ Eduardo Molina Edwin van der Weide Ethan Alan Hereth Florian Dittmann +Filip Hahs Francesco Poli Francisco D. Palacios Gaurav Bansal diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index 85f2b81046e..fa86705d931 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -1173,6 +1173,7 @@ class CConfig { string caseName; /*!< \brief Name of the current case */ unsigned long edgeColorGroupSize; /*!< \brief Size of the edge groups colored for OpenMP parallelization of edge loops. */ + bool edgeColoringRelaxDiscAdj; /*!< \brief Allow fallback to smaller edge color group sizes and use more colors for the discrete adjoint. */ INLET_SPANWISE_INTERP Kind_InletInterpolationFunction; /*!brief type of spanwise interpolation function to use for the inlet face. */ INLET_INTERP_TYPE Kind_Inlet_InterpolationType; /*!brief type of spanwise interpolation data to use for the inlet face. */ @@ -5947,6 +5948,15 @@ class CConfig { */ su2double GetMarkerTranslationRate(unsigned short iMarkerMoving, unsigned short iDim) const { return MarkerTranslation_Rate[3*iMarkerMoving + iDim];} + /*! + * \brief Set the translation rate of the marker. + * \param[in] iDim - spatial component + * \param[in] val - translational velocity + */ + void SetMarkerTranslationRate(unsigned short iMarkerMoving, unsigned short iDim, su2double val) { + MarkerTranslation_Rate[3 * iMarkerMoving + iDim] = val; + } + /*! * \brief Get the rotation rate of the mesh. * \param[in] iDim - spatial component @@ -5970,6 +5980,16 @@ class CConfig { */ su2double GetMarkerRotationRate(unsigned short iMarkerMoving, unsigned short iDim) const { return MarkerRotation_Rate[3*iMarkerMoving + iDim];} + /*! + * \brief Set the rotation rate of the marker. + * \param[in] iMarkerMoving - Index of the moving marker (as specified in Marker_Moving) + * \param[in] iDim - spatial component + * \param[in] val - Rotational velocity + */ + void SetMarkerRotationRate(unsigned short iMarkerMoving, unsigned short iDim, su2double val) { + MarkerRotation_Rate[3 * iMarkerMoving + iDim] = val; + } + /*! * \brief Get the pitching rate of the mesh. * \param[in] iDim - spatial component @@ -9678,6 +9698,11 @@ class CConfig { */ unsigned long GetEdgeColoringGroupSize(void) const { return edgeColorGroupSize; } + /*! + * \brief Check if the discrete adjoint is allowed to relax the coloring, that is, allow smaller edge color group sizes and allow more colors. + */ + bool GetEdgeColoringRelaxDiscAdj() const { return edgeColoringRelaxDiscAdj; } + /*! * \brief Get the ParMETIS load balancing tolerance. */ diff --git a/Common/include/geometry/CGeometry.hpp b/Common/include/geometry/CGeometry.hpp index f8111060725..4af65411cc2 100644 --- a/Common/include/geometry/CGeometry.hpp +++ b/Common/include/geometry/CGeometry.hpp @@ -1720,10 +1720,14 @@ class CGeometry { /*! * \brief Get the edge coloring. * \note This method computes the coloring if that has not been done yet. + * \note Can be instructed to determine and use the maximum edge color group size between 1 and + * CGeometry::edgeColorGroupSize that yields a coloring that is at least as efficient as #COLORING_EFF_THRESH. * \param[out] efficiency - optional output of the coloring efficiency. + * \param[in] maximizeEdgeColorGroupSize - use the maximum edge color group size that gives an efficient coloring. * \return Reference to the coloring. */ - const CCompressedSparsePatternUL& GetEdgeColoring(su2double* efficiency = nullptr); + const CCompressedSparsePatternUL& GetEdgeColoring(su2double* efficiency = nullptr, + bool maximizeEdgeColorGroupSize = false); /*! * \brief Force the natural (sequential) edge coloring. diff --git a/Common/include/toolboxes/graph_toolbox.hpp b/Common/include/toolboxes/graph_toolbox.hpp index c5929e8f8da..f1c0854ce27 100644 --- a/Common/include/toolboxes/graph_toolbox.hpp +++ b/Common/include/toolboxes/graph_toolbox.hpp @@ -484,7 +484,7 @@ T createNaturalColoring(Index_t numInnerIndexes) { * \param[out] indexColor - Optional, vector with colors given to the outer indices. * \return Coloring in the same type of the input pattern. */ -template +template T colorSparsePattern(const T& pattern, size_t groupSize = 1, bool balanceColors = false, std::vector* indexColor = nullptr) { static_assert(std::is_integral::value, ""); diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index 4f3e863542e..b1bdfbce47d 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -2933,6 +2933,9 @@ void CConfig::SetConfig_Options() { /* DESCRIPTION: Size of the edge groups colored for thread parallel edge loops (0 forces the reducer strategy). */ addUnsignedLongOption("EDGE_COLORING_GROUP_SIZE", edgeColorGroupSize, 512); + /* DESCRIPTION: Allow fallback to smaller edge color group sizes for the discrete adjoint and allow more colors. */ + addBoolOption("EDGE_COLORING_RELAX_DISC_ADJ", edgeColoringRelaxDiscAdj, true); + /*--- options that are used for libROM ---*/ /*!\par CONFIG_CATEGORY:libROM options \ingroup Config*/ diff --git a/Common/src/geometry/CGeometry.cpp b/Common/src/geometry/CGeometry.cpp index 9ed1804186a..aeca6421763 100644 --- a/Common/src/geometry/CGeometry.cpp +++ b/Common/src/geometry/CGeometry.cpp @@ -3609,7 +3609,7 @@ const su2vector& CGeometry::GetTransposeSparsePatternMap(Connecti return pattern.transposePtr(); } -const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficiency) { +const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficiency, bool maximizeEdgeColorGroupSize) { /*--- Check for dry run mode with dummy geometry. ---*/ if (nEdge == 0) return edgeColoring; @@ -3637,7 +3637,60 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien /*--- Color the edges. ---*/ constexpr bool balanceColors = true; - edgeColoring = colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); + + /*--- If requested, find an efficient coloring with maximum color group size (up to edgeColorGroupSize). ---*/ + if (maximizeEdgeColorGroupSize) { + auto upperEdgeColorGroupSize = edgeColorGroupSize + 1; /* upper bound that is deemed too large */ + auto nextEdgeColorGroupSize = edgeColorGroupSize; /* next value that we are going to try */ + auto lowerEdgeColorGroupSize = 1ul; /* lower bound that is known to work */ + + bool admissibleColoring = false; /* keep track wether the last tested coloring is admissible */ + + while (true) { + edgeColoring = colorSparsePattern(pattern, nextEdgeColorGroupSize, balanceColors); + + /*--- If the coloring fails, reduce the color group size. ---*/ + if (edgeColoring.empty()) { + upperEdgeColorGroupSize = nextEdgeColorGroupSize; + admissibleColoring = false; + } + /*--- If the coloring succeeds, check the efficiency. ---*/ + else { + const su2double currentEfficiency = + coloringEfficiency(edgeColoring, omp_get_max_threads(), nextEdgeColorGroupSize); + + /*--- If the coloring is not efficient, reduce the color group size. ---*/ + if (currentEfficiency < COLORING_EFF_THRESH) { + upperEdgeColorGroupSize = nextEdgeColorGroupSize; + admissibleColoring = false; + } + /*--- Otherwise, enlarge the color group size. ---*/ + else { + lowerEdgeColorGroupSize = nextEdgeColorGroupSize; + admissibleColoring = true; + } + } + + const auto increment = (upperEdgeColorGroupSize - lowerEdgeColorGroupSize) / 2; + nextEdgeColorGroupSize = lowerEdgeColorGroupSize + increment; + + /*--- Terminating condition. ---*/ + if (increment == 0) { + break; + } + } + + edgeColorGroupSize = nextEdgeColorGroupSize; + + /*--- If the last tested coloring was not admissible, recompute the final coloring. ---*/ + if (!admissibleColoring) { + edgeColoring = colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); + } + } + /*--- No adaptivity. ---*/ + else { + edgeColoring = colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); + } /*--- If the coloring fails use the natural coloring. This is a * "soft" failure as this "bad" coloring should be detected diff --git a/SU2_CFD/include/drivers/CDriver.hpp b/SU2_CFD/include/drivers/CDriver.hpp index 5ac33896849..72de6af4c89 100644 --- a/SU2_CFD/include/drivers/CDriver.hpp +++ b/SU2_CFD/include/drivers/CDriver.hpp @@ -536,6 +536,24 @@ class CDriver : public CDriverBase { */ void SetRotationRate(passivedouble rot_x, passivedouble rot_y, passivedouble rot_z); + /*! + * \brief Set the moving wall marker rotation rates. + * \param[in] iMaker - Index of moving wall marker. + * \param[in] rot_x - Value of Angular velocity about x-axes. + * \param[in] rot_y - Value of Angular velocity about y-axes. + * \param[in] rot_z - Value of Angular velocity about z-axes. + */ + void SetMarkerRotationRate(unsigned short iMarker, passivedouble rot_x, passivedouble rot_y, passivedouble rot_z); + + /*! + * \brief Set the moving wall marker translation rates. + * \param[in] iMaker - Index of moving wall marker. + * \param[in] vel_x - Value of velocity along x-axis. + * \param[in] vel_y - Value of velocity along y-axis. + * \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/solvers/CFVMFlowSolverBase.inl b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl index 40af46827be..c2af5a18d82 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl @@ -288,7 +288,16 @@ void CFVMFlowSolverBase::HybridParallelInitialization(const CConfig& confi * sum the fluxes for each cell and set the diagonal of the system matrix. ---*/ su2double parallelEff = 1.0; + +#ifdef CODI_REVERSE_TYPE + /*--- For the discrete adjoint, the reducer strategy is costly. Prefer coloring, possibly with reduced edge color + * group size. Find the maximum edge color group size that yields an efficient coloring. Also, allow larger numbers + * of colors. ---*/ + const bool relax = config.GetEdgeColoringRelaxDiscAdj(); + const auto& coloring = geometry.GetEdgeColoring(¶llelEff, relax); +#else const auto& coloring = geometry.GetEdgeColoring(¶llelEff); +#endif /*--- The decision to use the strategy is local to each rank. ---*/ ReducerStrategy = parallelEff < COLORING_EFF_THRESH; @@ -324,6 +333,29 @@ void CFVMFlowSolverBase::HybridParallelInitialization(const CConfig& confi << "\n The memory usage of the discrete adjoint solver is higher when using the fallback." #endif << endl; + } else { + if (SU2_MPI::GetRank() == MASTER_NODE) { + cout << "All ranks use edge coloring." << endl; + } + } + + const su2double coloredParallelEff = ReducerStrategy ? 1.0 : parallelEff; + su2double minColoredParallelEff = 1.0; + SU2_MPI::Reduce(&coloredParallelEff, &minColoredParallelEff, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, SU2_MPI::GetComm()); + + const unsigned long coloredNumColors = ReducerStrategy ? 0 : coloring.getOuterSize(); + unsigned long maxColoredNumColors = 0; + SU2_MPI::Reduce(&coloredNumColors, &maxColoredNumColors, 1, MPI_UNSIGNED_LONG, MPI_MAX, MASTER_NODE, SU2_MPI::GetComm()); + + const unsigned long coloredEdgeColorGroupSize = ReducerStrategy ? 1 << 30 : geometry.GetEdgeColorGroupSize(); + unsigned long minColoredEdgeColorGroupSize = 1 << 30; + SU2_MPI::Reduce(&coloredEdgeColorGroupSize, &minColoredEdgeColorGroupSize, 1, MPI_UNSIGNED_LONG, MPI_MIN, MASTER_NODE, SU2_MPI::GetComm()); + + if (SU2_MPI::GetRank() == MASTER_NODE && numRanksUsingReducer != SU2_MPI::GetSize()) { + cout << "Among the ranks that use edge coloring,\n" + << " the minimum efficiency is " << minColoredParallelEff << ",\n" + << " the maximum number of colors is " << maxColoredNumColors << ",\n" + << " the minimum edge color group size is " << minColoredEdgeColorGroupSize << "." << endl; } } diff --git a/SU2_CFD/include/solvers/CScalarSolver.inl b/SU2_CFD/include/solvers/CScalarSolver.inl index 5b6415d65b0..343944ebd6c 100644 --- a/SU2_CFD/include/solvers/CScalarSolver.inl +++ b/SU2_CFD/include/solvers/CScalarSolver.inl @@ -46,7 +46,15 @@ CScalarSolver::CScalarSolver(CGeometry* geometry, CConfig* config, #ifdef HAVE_OMP /*--- Get the edge coloring, see notes in CEulerSolver's constructor. ---*/ su2double parallelEff = 1.0; +#ifdef CODI_REVERSE_TYPE + /*--- For the discrete adjoint, the reducer strategy is costly. Prefer coloring, possibly with reduced edge color + * group size. Find the maximum edge color group size that yields an efficient coloring. Also, allow larger numbers + * of colors. ---*/ + const bool relax = config->GetEdgeColoringRelaxDiscAdj(); + const auto& coloring = geometry->GetEdgeColoring(¶llelEff, relax); +#else const auto& coloring = geometry->GetEdgeColoring(¶llelEff); +#endif ReducerStrategy = parallelEff < COLORING_EFF_THRESH; diff --git a/SU2_CFD/src/iteration/CIteration.cpp b/SU2_CFD/src/iteration/CIteration.cpp index 98190ef3972..977e8b713ef 100644 --- a/SU2_CFD/src/iteration/CIteration.cpp +++ b/SU2_CFD/src/iteration/CIteration.cpp @@ -90,9 +90,11 @@ void CIteration::SetGrid_Movement(CGeometry** geometry, CSurfaceMovement* surfac break; } - if (config->GetSurface_Movement(AEROELASTIC) || config->GetSurface_Movement(AEROELASTIC_RIGID_MOTION)) { + if (config->GetSurface_Movement(AEROELASTIC) || config->GetSurface_Movement(AEROELASTIC_RIGID_MOTION) || config->GetSurface_Movement(MOVING_WALL)) { /*--- Apply rigid mesh transformation to entire grid first, if necessary ---*/ + if (IntIter == 0) { + if (Kind_Grid_Movement == AEROELASTIC_RIGID_MOTION) { if (rank == MASTER_NODE) cout << endl << " Performing rigid mesh transformation." << endl; @@ -110,6 +112,11 @@ void CIteration::SetGrid_Movement(CGeometry** geometry, CSurfaceMovement* surfac grid_movement->UpdateMultiGrid(geometry, config); } + if (config->GetSurface_Movement(MOVING_WALL)) { + for (auto iMGlevel = 0u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + geometry[iMGlevel]->SetWallVelocity(config, iMGlevel == 0u); + } + } } diff --git a/SU2_CFD/src/output/filewriter/CCGNSFileWriter.cpp b/SU2_CFD/src/output/filewriter/CCGNSFileWriter.cpp index 34f75473b61..a4b89f39551 100644 --- a/SU2_CFD/src/output/filewriter/CCGNSFileWriter.cpp +++ b/SU2_CFD/src/output/filewriter/CCGNSFileWriter.cpp @@ -38,7 +38,6 @@ void CCGNSFileWriter::WriteData(string val_filename) { /*--- We append the pre-defined suffix (extension) to the filename (prefix) ---*/ val_filename.append(fileExt); - /*--- Open the CGNS file for writing. ---*/ InitializeMeshFile(val_filename); @@ -132,15 +131,16 @@ void CCGNSFileWriter::WriteField(int iField, const string& FieldName) { /*--- Coordinate vector is written in blocks, one for each process. ---*/ cgsize_t nodeBegin = 1; auto nodeEnd = static_cast(nLocalPoints); - - if (isCoord) { - int CoordinateNumber; - CallCGNS(cg_coord_partial_write(cgnsFileID, cgnsBase, cgnsZone, dataType, FieldName.c_str(), &nodeBegin, &nodeEnd, - sendBufferField.data(), &CoordinateNumber)); - } else { - int fieldNumber; - CallCGNS(cg_field_partial_write(cgnsFileID, cgnsBase, cgnsZone, cgnsFields, dataType, FieldName.c_str(), &nodeBegin, - &nodeEnd, sendBufferField.data(), &fieldNumber)); + if (nLocalPoints > 0) { + if (isCoord) { + int CoordinateNumber; + CallCGNS(cg_coord_partial_write(cgnsFileID, cgnsBase, cgnsZone, dataType, FieldName.c_str(), &nodeBegin, &nodeEnd, + sendBufferField.data(), &CoordinateNumber)); + } else { + int fieldNumber; + CallCGNS(cg_field_partial_write(cgnsFileID, cgnsBase, cgnsZone, cgnsFields, dataType, FieldName.c_str(), &nodeBegin, + &nodeEnd, sendBufferField.data(), &fieldNumber)); + } } for (int i = 0; i < size; ++i) { diff --git a/SU2_CFD/src/python_wrapper_structure.cpp b/SU2_CFD/src/python_wrapper_structure.cpp index 490cc193953..cac6186e04c 100644 --- a/SU2_CFD/src/python_wrapper_structure.cpp +++ b/SU2_CFD/src/python_wrapper_structure.cpp @@ -163,3 +163,15 @@ void CDriver::SetRotationRate(passivedouble rot_x, passivedouble rot_y, passived main_config->SetRotation_Rate(2, rot_z); } +void CDriver::SetMarkerRotationRate(unsigned short iMarker, passivedouble rot_x, passivedouble rot_y, passivedouble rot_z) { + config_container[selected_zone]->SetMarkerRotationRate(iMarker, 0, rot_x); + config_container[selected_zone]->SetMarkerRotationRate(iMarker, 1, rot_y); + config_container[selected_zone]->SetMarkerRotationRate(iMarker, 2, rot_z); +} + +void CDriver::SetMarkerTranslationRate(unsigned short iMarker, passivedouble vel_x, passivedouble vel_y, passivedouble vel_z) { + config_container[selected_zone]->SetMarkerTranslationRate(iMarker, 0, vel_x); + config_container[selected_zone]->SetMarkerTranslationRate(iMarker, 1, vel_y); + config_container[selected_zone]->SetMarkerTranslationRate(iMarker, 2, vel_z); +} + diff --git a/TestCases/cgns_writer/config.cfg b/TestCases/cgns_writer/config.cfg new file mode 100644 index 00000000000..12930ef75c9 --- /dev/null +++ b/TestCases/cgns_writer/config.cfg @@ -0,0 +1,96 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Subsonic U-Turn % +% Author: Andrea Rausa % +% Institution: Politecnico di Milano % +% Date: 12/2/2023 % +% File Version 8.0.0 "Harrier" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +SOLVER= RANS +KIND_TURB_MODEL= SST +MATH_PROBLEM= DIRECT +RESTART_SOL= NO + +% -------------------- COMPRESSIBLE FREE-STREAM DEFINITION --------------------% +% +MACH_NUMBER= 0.2 +AOA= 0.0 +FREESTREAM_TEMPERATURE= 270.0 +REYNOLDS_NUMBER= 3.28E6 +REYNOLDS_LENGTH= 1 +REF_DIMENSIONALIZATION= FREESTREAM_VEL_EQ_MACH + +% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% +% +REF_ORIGIN_MOMENT_X = -0.2473 +REF_ORIGIN_MOMENT_Y = 0.00 +REF_ORIGIN_MOMENT_Z = 0.00 +REF_LENGTH= 1 +REF_AREA= 1 + +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +MARKER_HEATFLUX= ( OuterWall, 0.0, InnerWall, 0.0 ) +MARKER_FAR= ( Inlet, Outlet ) +MARKER_PLOTTING= ( InnerWall ) +MARKER_MONITORING= ( InnerWall ) + +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +LINEAR_SOLVER= FGMRES +LINEAR_SOLVER_PREC= ILU +LINEAR_SOLVER_ERROR= 1.0e-6 +LINEAR_SOLVER_ITER= 15 + +% -------------------------- MULTIGRID PARAMETERS -----------------------------% +% +CFL_ADAPT= YES +CFL_NUMBER= 1 +CFL_REDUCTION_TURB= 1.0 +CFL_ADAPT_PARAM= ( 0.5, 1.01, 1.0, 5, 0.0001) +ITER= 1 + +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +CONV_NUM_METHOD_FLOW= ROE +USE_VECTORIZATION= YES +MUSCL_FLOW= NO +SLOPE_LIMITER_FLOW= VENKATAKRISHNAN +VENKAT_LIMITER_COEFF= 0.03 +TIME_DISCRE_FLOW= EULER_IMPLICIT + +% -------------------- TURBULENT NUMERICAL METHOD DEFINITION ------------------% +% +CONV_NUM_METHOD_TURB= SCALAR_UPWIND +MUSCL_TURB= NO +TIME_DISCRE_TURB= EULER_IMPLICIT + + +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +CONV_FIELD= MOMENT_X +CONV_STARTITER= 10 +CONV_CAUCHY_ELEMS= 100 +CONV_CAUCHY_EPS= 1E-6 + +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +MESH_FILENAME= mesh.su2 +MESH_FORMAT= SU2 +SOLUTION_FILENAME= restart_flow +TABULAR_FORMAT= CSV +CONV_FILENAME= history_First +RESTART_FILENAME= restart_flow +VOLUME_FILENAME= flow +SURFACE_FILENAME= surface_flow +OUTPUT_WRT_FREQ= 100 +SCREEN_OUTPUT= (INNER_ITER, WALL_TIME, RMS_DENSITY, LIFT, DRAG, MOMENT_Z) +OUTPUT_FILES= (SURFACE_CGNS) +WRT_FORCES_BREAKDOWN= NO +VOLUME_OUTPUT= (COORDINATES) +HISTORY_OUTPUT= (ITER) diff --git a/TestCases/hybrid_regression.py b/TestCases/hybrid_regression.py index 1f21bf4a9ad..36450f79e35 100644 --- a/TestCases/hybrid_regression.py +++ b/TestCases/hybrid_regression.py @@ -436,7 +436,7 @@ def main(): cavity.cfg_dir = "moving_wall/cavity" cavity.cfg_file = "lam_cavity.cfg" cavity.test_iter = 25 - cavity.test_vals = [-5.627934, -0.164469, 0.052000, 2.547063] + cavity.test_vals = [-5.627868, -0.164404, 0.053310, 2.545839] test_list.append(cavity) # Spinning cylinder @@ -444,8 +444,8 @@ def main(): spinning_cylinder.cfg_dir = "moving_wall/spinning_cylinder" spinning_cylinder.cfg_file = "spinning_cylinder.cfg" spinning_cylinder.test_iter = 25 - spinning_cylinder.test_vals = [-8.001291, -2.607959, 1.501321, 1.488559] - spinning_cylinder.test_vals_aarch64 = [-8.001291, -2.607959, 1.501321, 1.488559] + spinning_cylinder.test_vals = [-8.006541, -2.609759, 1.495662, 1.486341] + spinning_cylinder.test_vals_aarch64 = [-8.006541, -2.609759, 1.495662, 1.486341] test_list.append(spinning_cylinder) ###################################### diff --git a/TestCases/hybrid_regression_AD.py b/TestCases/hybrid_regression_AD.py index 7205140ad4c..dbaab977df3 100644 --- a/TestCases/hybrid_regression_AD.py +++ b/TestCases/hybrid_regression_AD.py @@ -242,7 +242,7 @@ def main(): pywrapper_FEA_AD_FlowLoad.test_vals_aarch64 = [-0.131745, -0.553214, -0.000364, -0.003101] pywrapper_FEA_AD_FlowLoad.command = TestCase.Command(exec = "python", param = "run_adjoint.py --parallel -f") pywrapper_FEA_AD_FlowLoad.timeout = 1600 - pywrapper_FEA_AD_FlowLoad.tol = 5e-3 + pywrapper_FEA_AD_FlowLoad.tol = 1e-2 pywrapper_FEA_AD_FlowLoad.new_output = False pywrapper_FEA_AD_FlowLoad.enabled_with_tsan = False test_list.append(pywrapper_FEA_AD_FlowLoad) @@ -257,7 +257,7 @@ def main(): pywrapper_CFD_AD_MeshDisp.test_vals_aarch64 = [30.000000, -2.516536, 1.386443, 0.000000] pywrapper_CFD_AD_MeshDisp.command = TestCase.Command(exec = "python", param = "run_adjoint.py --parallel -f") pywrapper_CFD_AD_MeshDisp.timeout = 1600 - pywrapper_CFD_AD_MeshDisp.tol = 1e-3 + pywrapper_CFD_AD_MeshDisp.tol = 1e-2 pywrapper_CFD_AD_MeshDisp.new_output = False pywrapper_CFD_AD_MeshDisp.enabled_with_tsan = False test_list.append(pywrapper_CFD_AD_MeshDisp) diff --git a/TestCases/parallel_regression.py b/TestCases/parallel_regression.py index 9996abca751..b743d64e625 100644 --- a/TestCases/parallel_regression.py +++ b/TestCases/parallel_regression.py @@ -934,7 +934,7 @@ def main(): cavity.cfg_dir = "moving_wall/cavity" cavity.cfg_file = "lam_cavity.cfg" cavity.test_iter = 25 - cavity.test_vals = [-5.611007, -0.146826, 1.113206, 1.491678] + cavity.test_vals = [-5.610928, -0.146749, 1.114461, 1.490381] test_list.append(cavity) # Spinning cylinder @@ -942,7 +942,7 @@ def main(): spinning_cylinder.cfg_dir = "moving_wall/spinning_cylinder" spinning_cylinder.cfg_file = "spinning_cylinder.cfg" spinning_cylinder.test_iter = 25 - spinning_cylinder.test_vals = [-7.802803, -2.362844, 1.687705, 1.519676] + spinning_cylinder.test_vals = [-7.806016, -2.364954, 1.683365, 1.517059] test_list.append(spinning_cylinder) ###################################### @@ -1564,6 +1564,20 @@ def main(): species3_multizone_restart.multizone = True test_list.append(species3_multizone_restart) + ##################### + ## CGNS writer ### + ##################### + + # 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 + test_list.append(cgns_writer) + ###################################### ### RUN TESTS ### ###################################### diff --git a/TestCases/py_wrapper/rotating_cylinder/run.py b/TestCases/py_wrapper/rotating_cylinder/run.py new file mode 100644 index 00000000000..537cdcb696e --- /dev/null +++ b/TestCases/py_wrapper/rotating_cylinder/run.py @@ -0,0 +1,19 @@ +import pysu2 # imports the SU2 wrapped module +from mpi4py import MPI +import numpy as np + +comm = MPI.COMM_WORLD +rank = comm.Get_rank() +rotation_vector = np.linspace(0,20,10) +SU2Driver = pysu2.CSinglezoneDriver("spinning_cylinder.cfg",1, comm) + +for i, rate in enumerate(rotation_vector): + SU2Driver.SetMarkerRotationRate(0,0,0,rate) + SU2Driver.Preprocess(i) + SU2Driver.Run() + SU2Driver.Postprocess() + SU2Driver.Output(i) + SU2Driver.Update() +SU2Driver.Finalize() + + \ No newline at end of file diff --git a/TestCases/py_wrapper/rotating_cylinder/spinning_cylinder.cfg b/TestCases/py_wrapper/rotating_cylinder/spinning_cylinder.cfg new file mode 100644 index 00000000000..194a46064dd --- /dev/null +++ b/TestCases/py_wrapper/rotating_cylinder/spinning_cylinder.cfg @@ -0,0 +1,115 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Laminar flow around a spinning cylinder % +% Author: Thomas D. Economon % +% Institution: Stanford University % +% Date: 2013.08.21 % +% File Version 7.5.1 "Blackbird" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +SOLVER= NAVIER_STOKES +KIND_TURB_MODEL= NONE +MATH_PROBLEM= DIRECT +RESTART_SOL= NO + +% ----------- COMPRESSIBLE AND INCOMPRESSIBLE FREE-STREAM DEFINITION ----------% +% +MACH_NUMBER= 0.1 +AOA= 0.0 +SIDESLIP_ANGLE= 0.0 +FREESTREAM_TEMPERATURE= 288.15 +REYNOLDS_NUMBER= 200.0 +REYNOLDS_LENGTH= 1.0 + +% ----------------------- DYNAMIC MESH DEFINITION -----------------------------% +% +SURFACE_MOVEMENT= MOVING_WALL +MACH_MOTION= 0.1 +MARKER_MOVING= ( cylinder ) +SURFACE_MOTION_ORIGIN= 0.5 0.0 0.0 +SURFACE_ROTATION_RATE = 0.0 0.0 -199.0738 + +% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% +% +REF_ORIGIN_MOMENT_X = 0.00 +REF_ORIGIN_MOMENT_Y = 0.00 +REF_ORIGIN_MOMENT_Z = 0.00 +REF_LENGTH= 1.0 +REF_AREA= 1.0 + +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +MARKER_HEATFLUX= ( cylinder, 0.0 ) +MARKER_FAR= ( farfield ) +MARKER_PLOTTING= ( cylinder ) +MARKER_MONITORING= ( cylinder ) + +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES +CFL_NUMBER= 100.0 +CFL_ADAPT= NO +CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) +ITER= 99999 + +% ----------------------- SLOPE LIMITER DEFINITION ----------------------------% +% +VENKAT_LIMITER_COEFF= 0.03 +ADJ_SHARP_LIMITER_COEFF= 3.0 +REF_SHARP_EDGES= 3.0 +SENS_REMOVE_SHARP= NO + +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +LINEAR_SOLVER= FGMRES +LINEAR_SOLVER_PREC= LU_SGS +LINEAR_SOLVER_ERROR= 1E-4 +LINEAR_SOLVER_ITER= 5 + +% -------------------------- MULTIGRID PARAMETERS -----------------------------% +% +MGLEVEL= 3 +MGCYCLE= V_CYCLE +MG_PRE_SMOOTH= ( 1, 1, 1, 1 ) +MG_POST_SMOOTH= ( 0, 0, 0, 0 ) +MG_CORRECTION_SMOOTH= ( 0, 0, 0, 0 ) +MG_DAMP_RESTRICTION= 0.5 +MG_DAMP_PROLONGATION= 0.5 + +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +CONV_NUM_METHOD_FLOW= ROE +MUSCL_FLOW= YES +SLOPE_LIMITER_FLOW= NONE +JST_SENSOR_COEFF= ( 0.5, 0.02 ) +TIME_DISCRE_FLOW= EULER_IMPLICIT + +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +CONV_RESIDUAL_MINVAL= -15 +CONV_STARTITER= 10 +CONV_CAUCHY_ELEMS= 100 +CONV_CAUCHY_EPS= 1E-7 + +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +MESH_FILENAME= mesh_cylinder_lam.su2 +MESH_FORMAT= SU2 +MESH_OUT_FILENAME= mesh_out.su2 +SOLUTION_FILENAME= solution_flow.dat +SOLUTION_ADJ_FILENAME= solution_adj.dat +TABULAR_FORMAT= CSV +CONV_FILENAME= history +RESTART_FILENAME= restart_flow.dat +RESTART_ADJ_FILENAME= restart_adj.dat +VOLUME_FILENAME= flow +VOLUME_ADJ_FILENAME= adjoint +GRAD_OBJFUNC_FILENAME= of_grad.dat +SURFACE_FILENAME= surface_flow +SURFACE_ADJ_FILENAME= surface_adjoint +OUTPUT_WRT_FREQ= 100 +SCREEN_OUTPUT= (INNER_ITER, RMS_DENSITY, RMS_ENERGY, LIFT, DRAG) diff --git a/TestCases/serial_regression.py b/TestCases/serial_regression.py index 56d4d46938d..a6e5302fae6 100644 --- a/TestCases/serial_regression.py +++ b/TestCases/serial_regression.py @@ -750,7 +750,7 @@ def main(): cavity.cfg_dir = "moving_wall/cavity" cavity.cfg_file = "lam_cavity.cfg" cavity.test_iter = 25 - cavity.test_vals = [-5.627934, -0.164470, 0.051972, 2.547039] + cavity.test_vals = [ -5.627868, -0.164405, 0.053283, 2.545817] test_list.append(cavity) # Spinning cylinder @@ -758,7 +758,7 @@ def main(): spinning_cylinder.cfg_dir = "moving_wall/spinning_cylinder" spinning_cylinder.cfg_file = "spinning_cylinder.cfg" spinning_cylinder.test_iter = 25 - spinning_cylinder.test_vals = [-7.889994, -2.469385, 1.708162, 1.670039] + spinning_cylinder.test_vals = [-7.892807, -2.467378, 1.702819, 1.669208] test_list.append(spinning_cylinder) ###################################### @@ -1066,6 +1066,7 @@ def main(): airfoilRBF.cfg_dir = "fea_fsi/Airfoil_RBF" airfoilRBF.cfg_file = "config.cfg" airfoilRBF.test_iter = 1 + airfoilRBF.test_vals = [1.000000, -2.786186, -4.977944] airfoilRBF.tol = 0.0001 airfoilRBF.multizone = True diff --git a/config_template.cfg b/config_template.cfg index 5ca66b5cafd..8ef0d882a0f 100644 --- a/config_template.cfg +++ b/config_template.cfg @@ -2171,6 +2171,14 @@ UQ_DELTA_B= 1.0 % The optimum value/strategy is case-dependent. EDGE_COLORING_GROUP_SIZE= 512 % +% Coloring tends to perform better for the discrete adjoint than reductions because +% it uses less memory and enables the shared reading optimization for color loops. +% This option allows an automatic fallback to smaller edge color group sizes on ranks +% where the requested edge color group size is not efficient. Specifically, the largest +% edge color group size up to EDGE_COLORING_GROUP_SIZE is chosen that is at least +% 0.875 efficient. Also, this option allows using more colors, up to 255 instead of up to 64. +EDGE_COLORING_RELAX_DISC_ADJ= YES +% % Independent "threads per MPI rank" setting for LU-SGS and ILU preconditioners. % For problems where time is spend mostly in the solution of linear systems (e.g. elasticity, % very high CFL central schemes), AND, if the memory bandwidth of the machine is saturated