diff --git a/Common/include/geometry/CMultiGridGeometry.hpp b/Common/include/geometry/CMultiGridGeometry.hpp index ba635b40f8c..3658dc0ea2f 100644 --- a/Common/include/geometry/CMultiGridGeometry.hpp +++ b/Common/include/geometry/CMultiGridGeometry.hpp @@ -48,7 +48,16 @@ class CMultiGridGeometry final : public CGeometry { * \return TRUE or FALSE depending if the control volume can be agglomerated. */ bool SetBoundAgglomeration(unsigned long CVPoint, vector marker_seed, const CGeometry* fine_grid, - const CConfig* config) const; + const CConfig* config, const vector& mixedBC) const; + + /*! + * \brief Find nodes where two boundary conditions of different type meet. These are never + * agglomerated, since a coarse CV holding one would average both conditions. + * \param[in] fine_grid - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \return One flag per fine grid point, set where that point must stay on its own. + */ + vector FindMixedBoundaryNodes(const CGeometry* fine_grid, const CConfig* config) const; /*! * \brief Determine if a Point can be agglomerated using geometrical criteria. @@ -62,11 +71,10 @@ class CMultiGridGeometry final : public CGeometry { * \brief Determine if a CVPoint can be agglomerated, if it has the same marker point as the seed. * \param[out] Suitable_Indirect_Neighbors - List of Indirect Neighbours that can be agglomerated. * \param[in] iPoint - Seed point. - * \param[in] Index_CoarseCV - Index of agglomerated point. * \param[in] fine_grid - Geometrical definition of the problem. */ void SetSuitableNeighbors(vector& Suitable_Indirect_Neighbors, unsigned long iPoint, - unsigned long Index_CoarseCV, const CGeometry* fine_grid) const; + const CGeometry* fine_grid) const; /*! * \brief Compute local curvature at a boundary vertex on Euler wall. @@ -78,16 +86,75 @@ class CMultiGridGeometry final : public CGeometry { su2double ComputeLocalCurvature(const CGeometry* fine_grid, unsigned long iPoint, unsigned short iMarker) const; /*! - * \brief Agglomerate high-aspect-ratio interior cells along implicit lines from wall vertices. + * \brief Pave the domain with columns grown from the boundary patches by one breadth first walk, + * so that every node goes to the patch that reaches it in the fewest steps. * \param[in,out] Index_CoarseCV - Current coarse CV index, incremented as new coarse CVs are created. * \param[in] fine_grid - Fine grid geometry. * \param[in] config - Configuration. - * \param[in,out] MGQueue_InnerCV - Queue for domain agglomeration; processed points are removed. + * \param[in] iMesh - Multigrid level being built, used to label the summary. + * \param[in] mixedBC - Nodes that must stay on their own, from FindMixedBoundaryNodes. + * \param[in] onPhysBoundary - Nodes carrying a physical boundary condition, excluding SEND_RECEIVE. + * \param[in] onPeriodic - Nodes on a periodic marker, which a column never claims. + * \param[out] neverGrewCV - Coarse CV index of every column that never grew past its seed layer. + * \return Summary of the paving, empty except on the master rank. + */ + string PaveAdvancingFronts(unsigned long& Index_CoarseCV, const CGeometry* fine_grid, const CConfig* config, + unsigned short iMesh, const vector& mixedBC, const vector& onPhysBoundary, + const vector& onPeriodic, vector& neverGrewCV); + + /*! + * \brief Boundary nodes that seed a column, ordered with the most anisotropic first. + */ + struct CFrontSeeds { + vector node; /*!< \brief Seed node on the boundary. */ + vector> normal; /*!< \brief Unit normal there, pointing into the domain. */ + vector strength; /*!< \brief Local anisotropy, the ordering key. */ + vector tier; /*!< \brief Paving order: 0 viscous wall, 1 Euler + wall, 2 anything else. */ + unsigned long nRefusedCurvature = 0; /*!< \brief Euler wall nodes the curvature limit kept out. */ + }; + + /*! + * \brief Collect the boundary nodes that seed a column: those where the stiffest edge is also the + * edge most nearly along the boundary normal, so the mesh is layered against this boundary. + * \param[in] fine_grid - Fine grid geometry. + * \param[in] config - Definition of the particular problem. + * \return Seed nodes and their inward boundary normals, most anisotropic first. */ - void AgglomerateImplicitLines(unsigned long& Index_CoarseCV, const CGeometry* fine_grid, const CConfig* config, - CMultiGridQueue& MGQueue_InnerCV); + CFrontSeeds SeedFrontNodes(const CGeometry* fine_grid, const CConfig* config) const; + + /*! + * \brief Element strip a column follows while the mesh is extruded along it. + */ + struct CWalkState { + unsigned long elem; /*!< \brief Element the column stands in, or NO_ELEM once it is lost. */ + unsigned short face; /*!< \brief Local face it entered that element through. */ + }; + + /*! + * \brief Partition the seed nodes into compact surface patches. A patch is a boundary face where + * the primal grid gives one, otherwise it is built by repeated pairwise matching. + * \param[in] seeds - Seed nodes from SeedFrontNodes. + * \param[in] fine_grid - Fine grid geometry. + * \param[in] config - Definition of the particular problem. + * \param[in] mixedBC - Nodes that must stay on their own, from FindMixedBoundaryNodes. + * \param[out] walk - Element and face each patch starts from, NO_ELEM where it has none. + * \return One vector of indices into seeds.node per patch, at most two entries in 2D, four in 3D. + */ + vector> BuildFrontPatches(const CFrontSeeds& seeds, const CGeometry* fine_grid, + const CConfig* config, const vector& mixedBC, + vector& walk) const; + + string levelReport; /*!< \brief Console summary for this level. */ public: + /*! + * \brief Get the console summary for this level, held back so it does not interleave with the + * multigrid table. + * \return Summary text, empty except on the master rank. + */ + const string& GetLevelReport() const { return levelReport; } + /*--- This is to suppress Woverloaded-virtual, omitting it has no negative impact. ---*/ using CGeometry::SetBoundControlVolume; using CGeometry::SetControlVolume; diff --git a/Common/include/geometry/dual_grid/CPoint.hpp b/Common/include/geometry/dual_grid/CPoint.hpp index 73e6f8fb047..bac83ccbfd2 100644 --- a/Common/include/geometry/dual_grid/CPoint.hpp +++ b/Common/include/geometry/dual_grid/CPoint.hpp @@ -656,6 +656,15 @@ class CPoint { Children_CV[iPoint][nchildren_CV] = children_CV; } + /*! + * \brief Set all the children control volumes of an agglomerated control volume at once. + * \param[in] iPoint - Index of the point. + * \param[in] children_CV - Indices of the children control volumes. + */ + inline void SetChildren_CV(unsigned long iPoint, const vector& children_CV) { + Children_CV[iPoint] = children_CV; + } + /*! * \brief Get the parent control volume of an agglomerated control volume. * \param[in] iPoint - Index of the point. @@ -673,6 +682,14 @@ class CPoint { return Children_CV[iPoint][nchildren_CV]; } + /*! + * \brief Get the children control volumes of an agglomerated control volume. Only the first + * GetnChildren_CV entries are meaningful, the storage may be longer. + * \param[in] iPoint - Index of the point. + * \return Indices of the children control volumes. + */ + inline const vector& GetChildren_CV(unsigned long iPoint) const { return Children_CV[iPoint]; } + /*! * \brief Get information about if a control volume has been agglomerated. * \param[in] iPoint - Index of the point. diff --git a/Common/include/option_structure.hpp b/Common/include/option_structure.hpp index 5669a6ec32a..bcd2e9c0632 100644 --- a/Common/include/option_structure.hpp +++ b/Common/include/option_structure.hpp @@ -1225,7 +1225,7 @@ inline SST_ParsedOptions ParseSSTOptions(const SST_OPTIONS *SST_Options, unsigne struct CMGOptions { su2double MG_Smooth_Res_Threshold{0.0}; /*!< \brief RMS reduction threshold for MG smoothing early exit. */ su2double MG_Smooth_Coeff{0.0}; /*!< \brief Jacobi smoother coefficient for coarse-grid correction. */ - unsigned long MG_Min_MeshSize{0}; /*!< \brief Minimum CVs on coarsest MG level. */ + unsigned long MG_Min_MeshSize{0}; /*!< \brief Minimum CVs on coarsest MG level, over all ranks. */ std::vector MG_PreSmooth; /*!< \brief Multigrid pre-smoothing iterations per level. */ std::vector MG_PostSmooth; /*!< \brief Multigrid post-smoothing iterations per level. */ std::vector MG_CorrecSmooth; /*!< \brief Multigrid Jacobi correction-smoothing per level. */ @@ -1234,7 +1234,6 @@ struct CMGOptions { bool MG_Smooth_Output{false}; /*!< \brief Output compact per-cycle smoothing summary. */ su2double MG_Smooth_StagnationTol{0.0}; /*!< \brief Stagnation early exit: stop if current_rms >= prev_rms * tol. 0 = disabled. */ bool MG_Implicit_Lines{false}; /*!< \brief Enable implicit-lines agglomeration from walls. */ - unsigned long MG_Implicit_Lines_MaxLength{20}; /*!< \brief Maximum nodes on a wall-normal implicit line (including wall seed). */ unsigned long MG_Startup_Iter{100}; /*!< \brief Iterations per mesh during FMG startup, and the length of each level's CFL ramp. 0 = no iteration budget. */ su2double MG_Startup_Convergence{-2.0}; /*!< \brief FMG: orders of magnitude (log10) that CONV_FIELD must drop on the active level before promoting to the next finer one. Negative is a diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index 0d257b77148..fd4207b0c5f 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -2093,16 +2093,17 @@ void CConfig::SetConfig_Options() { addDoubleOption("MG_SMOOTH_RES_THRESHOLD", MGOptions.MG_Smooth_Res_Threshold, 0.9); /*!\brief MG_SMOOTH_OUTPUT\n DESCRIPTION: Print compact per-cycle smoothing iteration summary. DEFAULT: NO \ingroup Config*/ addBoolOption("MG_SMOOTH_OUTPUT", MGOptions.MG_Smooth_Output, false); - /*!\brief MG_SMOOTH_STAGNATION_TOL\n DESCRIPTION: Stop smoothing if current_rms >= previous_rms * this value. Values < 1.0 enable early exit on stagnation, 1.0 only exits on defect growth. DEFAULT: 0.99 \ingroup Config*/ + /*!\brief MG_SMOOTH_STAGNATION_TOL\n DESCRIPTION: Stop smoothing if current_rms >= previous_rms * this value. + * Values < 1.0 enable early exit on stagnation, 1.0 only exits on defect growth. DEFAULT: 0.99 \ingroup Config*/ addDoubleOption("MG_SMOOTH_STAGNATION_TOL", MGOptions.MG_Smooth_StagnationTol, 0.99); /*!\brief MG_SMOOTH_COEFF\n DESCRIPTION: Smoothing coefficient for the correction prolongation Jacobi smoother. DEFAULT: 1.25 \ingroup Config*/ addDoubleOption("MG_SMOOTH_COEFF", MGOptions.MG_Smooth_Coeff, 1.25); - /*!\brief MG_MIN_MESHSIZE\n DESCRIPTION: Minimum number of CVs on the coarsest multigrid level. Levels that would produce fewer CVs are not created. DEFAULT: 50 \ingroup Config*/ + /*!\brief MG_MIN_MESHSIZE\n DESCRIPTION: Minimum number of CVs on the coarsest multigrid level, counted over the + * whole level rather than per rank, so the hierarchy does not change with the number of ranks. DEFAULT: 500 \ingroup Config*/ addUnsignedLongOption("MG_MIN_MESHSIZE", MGOptions.MG_Min_MeshSize, 500); - /*!\brief MG_IMPLICIT_LINES\n DESCRIPTION: Enable agglomeration along implicit lines from wall seeds. DEFAULT: NO \ingroup Config*/ + /*!\brief MG_IMPLICIT_LINES\n DESCRIPTION: Pave the coarse grid with advancing fronts raised from boundaries + * that carry a stretched layer normal to themselves. DEFAULT: NO \ingroup Config*/ addBoolOption("MG_IMPLICIT_LINES", MGOptions.MG_Implicit_Lines, false); - /*!\brief MG_IMPLICIT_LINES_MAX_LENGTH\n DESCRIPTION: Maximum number of nodes on a wall-normal implicit agglomeration line (including the wall seed node). DEFAULT: 20 \ingroup Config*/ - addUnsignedLongOption("MG_IMPLICIT_LINES_MAX_LENGTH", MGOptions.MG_Implicit_Lines_MaxLength, 20); /*!\brief MG_STARTUP_ITER\n DESCRIPTION: Max number of iterations spent on each mesh during the Full * Multigrid (FMG) startup phase. DEFAULT: 100 \ingroup Config*/ addUnsignedLongOption("MG_STARTUP_ITER", MGOptions.MG_Startup_Iter, 100); @@ -2117,7 +2118,8 @@ void CConfig::SetConfig_Options() { /*!\brief MG_STARTUP_STAGNATION_ITER\n DESCRIPTION: Consecutive stalled iterations required before Full-MG promotes * on stagnation. 0 disables it, as MG_STARTUP_STAGNATION= 0 does. DEFAULT: 5 \ingroup Config*/ addUnsignedLongOption("MG_STARTUP_STAGNATION_ITER", MGOptions.MG_Startup_Stagnation_Iter, 5); - /*!\brief MG_CFL_SCALING\n DESCRIPTION: Per-level CFL scaling factors for coarse MG levels. Entry i is the ratio CFL(i+1)/CFL(i). If fewer values than nMGLevels are given, the last value is repeated. DEFAULT: 0.25 (i.e., 1/4 per level) \ingroup Config*/ + /*!\brief MG_CFL_SCALING\n DESCRIPTION: Per-level CFL scaling factors for coarse MG levels. Entry i is the ratio CFL(i+1)/CFL(i). + * If fewer values than nMGLevels are given, the last value is repeated. DEFAULT: 0.25 (i.e., 1/4 per level) \ingroup Config*/ addDoubleListOption("MG_CFL_SCALING", nMG_CflScaling_p, MG_CflScaling_p); /*!\par CONFIG_CATEGORY: Spatial Discretization \ingroup Config*/ diff --git a/Common/src/geometry/CMultiGridGeometry.cpp b/Common/src/geometry/CMultiGridGeometry.cpp index 684da742b13..d3bca729bf5 100644 --- a/Common/src/geometry/CMultiGridGeometry.cpp +++ b/Common/src/geometry/CMultiGridGeometry.cpp @@ -30,11 +30,51 @@ #include "../../include/toolboxes/printing_toolbox.hpp" #include "../../../Common/include/toolboxes/geometry_toolbox.hpp" +#include +#include +#include +#include +#include +#include + +namespace { + +/*--- Euler wall nodes are not agglomerated where the surface turns by more than this, in + * degrees. ---*/ +constexpr passivedouble EULER_WALL_MAX_CURVATURE = 45.0; + +/*--- Fine points one coarse CV may hold: a quadrilateral in 2D, a hexahedron in 3D. ---*/ +constexpr short int MaxAgglomSize(unsigned short nDim) { return (nDim == 2) ? 4 : 8; } + +/*--- Equivalence-class id per entity for the set of physical markers it lies on: entities with the + * same set share an id, 0 means no marker. The pairs are consumed. ---*/ +vector MarkerSetClasses(unsigned long nEntity, vector>& pairs) { + vector classOfEntity(nEntity, 0); + + std::sort(pairs.begin(), pairs.end()); + pairs.erase(std::unique(pairs.begin(), pairs.end()), pairs.end()); + + map, unsigned long> classOf; + unsigned long nClass = 0; + for (size_t i = 0; i < pairs.size();) { + size_t j = i; + vector markerSet; + while ((j < pairs.size()) && (pairs[j].first == pairs[i].first)) markerSet.push_back(pairs[j++].second); + + const auto res = classOf.emplace(std::move(markerSet), nClass + 1); + if (res.second) nClass++; + classOfEntity[pairs[i].first] = res.first->second; + i = j; + } + return classOfEntity; +} + +} // namespace + CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, unsigned short iMesh) : CGeometry() { nDim = fine_grid->GetnDim(); // Write the number of dimensions of the coarse grid. - /*--- Maximum agglomeration size in 2D is 4 nodes, in 3D is 8 nodes. ---*/ - const short int maxAgglomSize = (nDim == 2) ? 4 : 8; + const short int maxAgglomSize = MaxAgglomSize(nDim); /*--- Inherit boundary properties from fine grid ---*/ boundIsStraight = fine_grid->boundIsStraight; @@ -46,9 +86,6 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un 3rd) One marker ---> Surface (always agglomerate) 4th) No marker ---> Internal Volume (always agglomerate) ---*/ - // Note that for MPI, we introduce interfaces and we can choose to have agglomeration over - // the interface or not. Nishikawa chooses not to agglomerate over interfaces. - /*--- Set a marker to indicate indirect agglomeration, for quads and hexs, i.e. consider up to neighbors of neighbors. For other levels this information is propagated down during their construction. ---*/ @@ -68,6 +105,14 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un } } + /*--- Index of a coarse CV that does not exist, and of a fine point with no parent yet. ---*/ + constexpr auto NO_CV = std::numeric_limits::max(); + + /*--- Clear the parents the halo points were given when this fine grid was itself agglomerated. + * Everything below reads NO_CV as "not agglomerated on this rank". ---*/ + for (auto iPoint = fine_grid->GetnPointDomain(); iPoint < fine_grid->GetnPoint(); iPoint++) + fine_grid->nodes->SetParent_CV(iPoint, NO_CV); + /*--- Create the coarse grid structure using as baseline the fine grid ---*/ CMultiGridQueue MGQueue_InnerCV(fine_grid->GetnPoint()); @@ -77,22 +122,52 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un unsigned long Index_CoarseCV = 0; - /*--- Statistics for Euler wall agglomeration ---*/ - map euler_wall_agglomerated, euler_wall_rejected_curvature, - euler_wall_rejected_straight; - for (unsigned short iMarker = 0; iMarker < fine_grid->GetnMarker(); iMarker++) { - if (config->GetMarker_All_KindBC(iMarker) == EULER_WALL) { - euler_wall_agglomerated[iMarker] = 0; - euler_wall_rejected_curvature[iMarker] = 0; - euler_wall_rejected_straight[iMarker] = 0; - } + /*--- Euler wall seeds taken and refused, per config file marker so the counts reduce over the + * ranks. A local marker index names a different boundary on each rank. ---*/ + vector eulerTaken(config->GetnMarker_CfgFile(), 0); + vector eulerRefused(config->GetnMarker_CfgFile(), 0); + vector cfgMarker(fine_grid->GetnMarker(), 0); + for (auto iMarker = 0u; iMarker < fine_grid->GetnMarker(); iMarker++) + if (config->GetMarker_All_KindBC(iMarker) == EULER_WALL) + cfgMarker[iMarker] = config->GetMarker_CfgFile_TagBound(config->GetMarker_All_TagBound(iMarker)); + + /*--- Points carrying a physical boundary condition. This does not include SEND_RECEIVE. ---*/ + vector onPhysBoundary(fine_grid->GetnPoint(), 0); + for (auto iMarker = 0u; iMarker < fine_grid->GetnMarker(); iMarker++) { + if (config->GetMarker_All_KindBC(iMarker) == SEND_RECEIVE) continue; + for (auto iVertex = 0ul; iVertex < fine_grid->GetnVertex(iMarker); iVertex++) + onPhysBoundary[fine_grid->vertex[iMarker][iVertex]->GetNode()] = 1; + } + /*--- Nodes on a periodic marker. Periodic donor matching is rebuilt per level and pairs one + * coarse vertex per marker, so a coarse CV holding two of these would receive twice. ---*/ + vector onPeriodic(fine_grid->GetnPoint(), 0); + for (auto iMarker = 0u; iMarker < fine_grid->GetnMarker(); iMarker++) { + if (config->GetMarker_All_KindBC(iMarker) != PERIODIC_BOUNDARY) continue; + for (auto iVertex = 0ul; iVertex < fine_grid->GetnVertex(iMarker); iVertex++) + onPeriodic[fine_grid->vertex[iMarker][iVertex]->GetNode()] = 1; } + /*--- Nodes where two different boundary conditions meet. ---*/ + const auto mixedBC = FindMixedBoundaryNodes(fine_grid, config); + + /*--- STEP 0: pave the domain with advancing fronts rising from the boundaries. The coarse CVs it + * creates occupy [firstLineCV, endLineCV). ---*/ + const auto firstLineCV = Index_CoarseCV; + vector neverGrewCV; + if (config->GetMGOptions().MG_Implicit_Lines) { + levelReport = + PaveAdvancingFronts(Index_CoarseCV, fine_grid, config, iMesh, mixedBC, onPhysBoundary, onPeriodic, neverGrewCV); + } + const auto endLineCV = Index_CoarseCV; + /*--- STEP 1: The first step is the boundary agglomeration. ---*/ for (auto iMarker = 0u; iMarker < fine_grid->GetnMarker(); iMarker++) { /*--- Skip periodic boundaries: do not agglomerate on periodic markers. ---*/ if (config->GetMarker_All_KindBC(iMarker) == PERIODIC_BOUNDARY) continue; + /*--- Skip SEND_RECEIVE markers, those points are left to the domain pass. ---*/ + if (config->GetMarker_All_KindBC(iMarker) == SEND_RECEIVE) continue; + for (auto iVertex = 0ul; iVertex < fine_grid->GetnVertex(iMarker); iVertex++) { const auto iPoint = fine_grid->vertex[iMarker][iVertex]->GetNode(); @@ -115,16 +190,17 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un nodes->SetChildren_CV(Index_CoarseCV, 0, iPoint); bool agglomerate_seed = false; auto counter = 0; - unsigned short copy_marker[3] = {}; + unsigned short copy_marker[2] = {}; marker_seed.push_back(iMarker); - /*--- For a particular point in the fine grid we save all the markers - that are in that point ---*/ + /*--- For a particular point in the fine grid we save all the physical markers that are in + that point. ---*/ for (auto jMarker = 0u; jMarker < fine_grid->GetnMarker(); jMarker++) { - const string Marker_Tag = config->GetMarker_All_TagBound(iMarker); + if (config->GetMarker_All_KindBC(jMarker) == SEND_RECEIVE) continue; if (fine_grid->nodes->GetVertex(iPoint, jMarker) != -1) { - copy_marker[counter] = jMarker; + /*--- Count every physical marker, only the first two are read back. ---*/ + if (counter < 2) copy_marker[counter] = jMarker; counter++; if (jMarker != iMarker) { @@ -151,35 +227,25 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un if (!boundIsStraight[marker_seed[0]]) { /*--- Compute local curvature at this point ---*/ su2double local_curvature = ComputeLocalCurvature(fine_grid, iPoint, marker_seed[0]); - // limit to 45 degrees - if (local_curvature >= 45.0) { + if (local_curvature >= EULER_WALL_MAX_CURVATURE) { agglomerate_seed = false; // High curvature: do not agglomerate - euler_wall_rejected_curvature[marker_seed[0]]++; + eulerRefused[cfgMarker[marker_seed[0]]]++; } else { - euler_wall_agglomerated[marker_seed[0]]++; + eulerTaken[cfgMarker[marker_seed[0]]]++; } } else { /*--- Straight wall: agglomerate ---*/ - euler_wall_agglomerated[marker_seed[0]]++; + eulerTaken[cfgMarker[marker_seed[0]]]++; } } - - /*--- Note that if the (single) marker is a SEND_RECEIVE, then the node is actually an interior point. - In that case it can only be agglomerated with another interior point. ---*/ - if (config->GetMarker_All_KindBC(marker_seed[0]) == SEND_RECEIVE) { - agglomerate_seed = true; - } } - /*--- Note that in 2D, this is a corner and we do not agglomerate unless one of them is SEND_RECEIVE. ---*/ - /*--- In 3D, we agglomerate if the 2 markers are the same. ---*/ + /*--- Two physical markers meet here. ---*/ if (counter == 2) { - if (nDim == 2) { - agglomerate_seed = ((config->GetMarker_All_KindBC(copy_marker[0]) == SEND_RECEIVE) || - (config->GetMarker_All_KindBC(copy_marker[1]) == SEND_RECEIVE)); - } - /*--- agglomerate if both markers are the same. ---*/ - if (nDim == 3) agglomerate_seed = (copy_marker[0] == copy_marker[1]); + /*--- In 2D that is a corner in the geometry, which is never agglomerated. ---*/ + if (nDim == 2) agglomerate_seed = false; + /*--- In 3D, this is a ridge point (an edge where two surface markers meet). ---*/ + if (nDim == 3) agglomerate_seed = true; /*--- Euler walls: check curvature-based agglomeration criterion for both markers ---*/ // only in 3d because in 2d it's a corner @@ -189,16 +255,15 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un if (!boundIsStraight[copy_marker[i]]) { /*--- Compute local curvature at this point ---*/ su2double local_curvature = ComputeLocalCurvature(fine_grid, iPoint, copy_marker[i]); - // limit to 45 degrees - if (local_curvature >= 45.0) { + if (local_curvature >= EULER_WALL_MAX_CURVATURE) { agglomerate_seed = false; // High curvature: do not agglomerate - euler_wall_rejected_curvature[copy_marker[i]]++; + eulerRefused[cfgMarker[copy_marker[i]]]++; euler_wall_rejected_here = true; } } /*--- Track agglomeration if not rejected ---*/ if (agglomerate_seed && !euler_wall_rejected_here) { - euler_wall_agglomerated[copy_marker[i]]++; + eulerTaken[cfgMarker[copy_marker[i]]]++; } } } @@ -208,6 +273,9 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un if (counter > 2) agglomerate_seed = false; + /*--- ...and so is a node where two markers of different type meet, in any dimension. ---*/ + if (mixedBC[iPoint]) agglomerate_seed = false; + /*--- If the seed (parent) can be agglomerated, we try to agglomerate connected childs to the parent ---*/ /*--- Note that in 2D we allow a maximum of 4 nodes to be agglomerated ---*/ @@ -217,7 +285,7 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un for (auto CVPoint : fine_grid->nodes->GetPoints(iPoint)) { /*--- The new point can be agglomerated ---*/ - if (SetBoundAgglomeration(CVPoint, marker_seed, fine_grid, config)) { + if (SetBoundAgglomeration(CVPoint, marker_seed, fine_grid, config, mixedBC)) { /*--- We set the value of the parent ---*/ fine_grid->nodes->SetParent_CV(CVPoint, Index_CoarseCV); @@ -231,23 +299,23 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un /*--- In 3D, we agglomerate exactly 2 nodes if the nodes are on the surface edge. ---*/ if ((nDim == 3) && (counter == 2)) break; /*--- Apply maxAgglomSize limit for 3D internal boundary face nodes (counter==1 in 3D). ---*/ - if (nChildren == maxAgglomSize) break; + if (nChildren >= maxAgglomSize) break; } } - /*--- Only take into account indirect neighbors for 3D faces, not 2D. ---*/ - if (nDim == 3) { + /*--- Indirect neighbors only for 3D faces. ---*/ + if ((nDim == 3) && (nChildren < maxAgglomSize)) { Suitable_Indirect_Neighbors.clear(); if (fine_grid->nodes->GetAgglomerate_Indirect(iPoint)) - SetSuitableNeighbors(Suitable_Indirect_Neighbors, iPoint, Index_CoarseCV, fine_grid); + SetSuitableNeighbors(Suitable_Indirect_Neighbors, iPoint, fine_grid); /*--- Now we do a sweep over all the indirect nodes that can be added ---*/ for (auto CVPoint : Suitable_Indirect_Neighbors) { /*--- The new point can be agglomerated ---*/ - if (SetBoundAgglomeration(CVPoint, marker_seed, fine_grid, config)) { + if (SetBoundAgglomeration(CVPoint, marker_seed, fine_grid, config, mixedBC)) { /*--- We set the value of the parent ---*/ fine_grid->nodes->SetParent_CV(CVPoint, Index_CoarseCV); @@ -263,7 +331,7 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un nodes->SetChildren_CV(Index_CoarseCV, nChildren, CVPoint); nChildren++; /*--- Apply maxAgglomSize limit for 3D internal boundary face nodes. ---*/ - if (nChildren == maxAgglomSize) break; + if (nChildren >= maxAgglomSize) break; } } } @@ -281,6 +349,9 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un i.e. make one coarse CV with a single child. ---*/ for (auto iMarker = 0u; iMarker < fine_grid->GetnMarker(); iMarker++) { + /*--- As in STEP 1, a SEND_RECEIVE marker does not make a point a boundary point. ---*/ + if (config->GetMarker_All_KindBC(iMarker) == SEND_RECEIVE) continue; + for (auto iVertex = 0ul; iVertex < fine_grid->GetnVertex(iMarker); iVertex++) { const auto iPoint = fine_grid->vertex[iMarker][iVertex]->GetNode(); @@ -311,12 +382,18 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un } } - /*--- Agglomerate high-aspect-ratio interior nodes along implicit lines from walls. ---*/ - if (config->GetMGOptions().MG_Implicit_Lines) { - AgglomerateImplicitLines(Index_CoarseCV, fine_grid, config, MGQueue_InnerCV); - } + /*--- STEP 2: Agglomerate the domain points. A seed grows one node at a time, taking the candidate + * that shares the most edges with the current members. ---*/ + vector inCV(fine_grid->GetnPoint(), 0); + vector isCandidate(fine_grid->GetnPoint(), 0); + vector members, candidates; + members.reserve(maxAgglomSize); - /*--- STEP 2: Agglomerate the domain points. ---*/ + /*--- A local frame at the seed: up to nDim of its incident edges, as mutually orthogonal as + * possible, each with its own length. ---*/ + vector> frameDir, edgeDir; + vector frameLen, edgeLen; + vector edgeUsed; auto iteration = 0ul; while (!MGQueue_InnerCV.EmptyQueue() && (iteration < fine_grid->GetnPoint())) { @@ -328,79 +405,137 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un if ((!fine_grid->nodes->GetAgglomerate(iPoint)) && (fine_grid->nodes->GetDomain(iPoint)) && (GeometricalCheck(iPoint, fine_grid, config))) { - unsigned short nChildren = 1; - - /*--- We set an index for the parent control volume ---*/ - - fine_grid->nodes->SetParent_CV(iPoint, Index_CoarseCV); - - /*--- We add the seed point (child) to the parent control volume ---*/ - - nodes->SetChildren_CV(Index_CoarseCV, 0, iPoint); - - /*--- Update the queue with the seed point (remove the seed and - increase the priority of its neighbors) ---*/ - - MGQueue_InnerCV.Update(iPoint, fine_grid); - - /*--- Now we do a sweep over all the nodes that surround the seed point ---*/ - - for (auto CVPoint : fine_grid->nodes->GetPoints(iPoint)) { - /*--- Determine if the CVPoint can be agglomerated ---*/ + members.clear(); + candidates.clear(); + unsigned short nChildren = 0; + + /*--- Take a node into the CV and let the frontier grow with it. ---*/ + auto addMember = [&](unsigned long CVPoint) { + fine_grid->nodes->SetParent_CV(CVPoint, Index_CoarseCV); + nodes->SetChildren_CV(Index_CoarseCV, nChildren, CVPoint); + nChildren++; - if ((!fine_grid->nodes->GetAgglomerate(CVPoint)) && (fine_grid->nodes->GetDomain(CVPoint)) && - (GeometricalCheck(CVPoint, fine_grid, config))) { - /*--- We set the value of the parent ---*/ + if (fine_grid->nodes->GetAgglomerate_Indirect(CVPoint)) nodes->SetAgglomerate_Indirect(Index_CoarseCV, true); - fine_grid->nodes->SetParent_CV(CVPoint, Index_CoarseCV); + /*--- Remove it from the queue and raise the priority of its neighbours. ---*/ + MGQueue_InnerCV.Update(CVPoint, fine_grid); - /*--- We set the value of the child ---*/ + members.push_back(CVPoint); + inCV[CVPoint] = 1; - nodes->SetChildren_CV(Index_CoarseCV, nChildren, CVPoint); - nChildren++; + for (auto jPoint : fine_grid->nodes->GetPoints(CVPoint)) { + if (inCV[jPoint] || isCandidate[jPoint]) continue; + if (fine_grid->nodes->GetAgglomerate(jPoint) || !fine_grid->nodes->GetDomain(jPoint)) continue; + if (!GeometricalCheck(jPoint, fine_grid, config)) continue; + isCandidate[jPoint] = 1; + candidates.push_back(jPoint); + } + }; - /*--- Update the queue with the new control volume (remove the CV and - increase the priority of its neighbors) ---*/ + addMember(iPoint); - MGQueue_InnerCV.Update(CVPoint, fine_grid); + edgeDir.clear(); + edgeLen.clear(); + su2double seedShortest = std::numeric_limits::max(); + for (auto jPoint : fine_grid->nodes->GetPoints(iPoint)) { + su2double e[MAXNDIM] = {0.0}; + GeometryToolbox::Distance(nDim, fine_grid->nodes->GetCoord(jPoint), fine_grid->nodes->GetCoord(iPoint), e); + const su2double len = GeometryToolbox::Norm(nDim, e); + if (len <= 0.0) continue; + std::array u{}; + for (unsigned short d = 0; d < nDim; ++d) u[d] = e[d] / len; + edgeDir.push_back(u); + edgeLen.push_back(len); + seedShortest = std::min(seedShortest, len); + } + /*--- A seed with no usable edge cannot be measured against anything, leave the scale at one. ---*/ + if (seedShortest == std::numeric_limits::max()) seedShortest = 1.0; + + /*--- The shortest edge goes in first, the rest in order of how orthogonal they are to what is + * already in the frame. ---*/ + frameDir.clear(); + frameLen.clear(); + edgeUsed.assign(edgeDir.size(), 0); + while (frameDir.size() < nDim) { + long pick = -1; + su2double bestScore = -1.0; + for (size_t i = 0; i < edgeDir.size(); ++i) { + if (edgeUsed[i]) continue; + su2double score; + if (frameDir.empty()) { + score = 1.0 / edgeLen[i]; + } else { + score = 2.0; + for (const auto& f : frameDir) { + su2double a = 0.0; + for (unsigned short d = 0; d < nDim; ++d) a += f[d] * edgeDir[i][d]; + score = std::min(score, 1.0 - fabs(a)); + } + } + if (score > bestScore) { + bestScore = score; + pick = static_cast(i); + } } - if (nChildren == maxAgglomSize) break; + if (pick < 0) break; + edgeUsed[pick] = 1; + frameDir.push_back(edgeDir[pick]); + frameLen.push_back(edgeLen[pick]); } + /*--- Without a full frame the offset cannot be resolved, fall back to one isotropic scale. ---*/ + const bool haveFrame = (frameDir.size() == nDim); + + while (nChildren < maxAgglomSize) { + /*--- Centroid of what the CV holds so far, used only to break ties. ---*/ + su2double centroid[MAXNDIM] = {0.0}; + for (auto jPoint : members) { + const auto* coord = fine_grid->nodes->GetCoord(jPoint); + for (auto iDim = 0u; iDim < nDim; iDim++) centroid[iDim] += coord[iDim] / su2double(members.size()); + } - /*--- Identify the indirect neighbors ---*/ - - Suitable_Indirect_Neighbors.clear(); - if (fine_grid->nodes->GetAgglomerate_Indirect(iPoint)) - SetSuitableNeighbors(Suitable_Indirect_Neighbors, iPoint, Index_CoarseCV, fine_grid); - - /*--- Now we do a sweep over all the indirect nodes that can be added ---*/ - - for (auto CVPoint : Suitable_Indirect_Neighbors) { - // if we have reached the maximum, get out. - if (nChildren == maxAgglomSize) break; - /*--- The new point can be agglomerated ---*/ - - if ((!fine_grid->nodes->GetAgglomerate(CVPoint)) && (fine_grid->nodes->GetDomain(CVPoint))) { - /*--- We set the value of the parent ---*/ - - fine_grid->nodes->SetParent_CV(CVPoint, Index_CoarseCV); - - /*--- We set the indirect agglomeration information ---*/ - - if (fine_grid->nodes->GetAgglomerate_Indirect(CVPoint)) nodes->SetAgglomerate_Indirect(Index_CoarseCV, true); - - /*--- We set the value of the child ---*/ - - nodes->SetChildren_CV(Index_CoarseCV, nChildren, CVPoint); - nChildren++; - - /*--- Update the queue with the new control volume (remove the CV and - increase the priority of the neighbors) ---*/ + unsigned long best = NO_CV; + unsigned short best_shared = 0; + su2double best_dist = std::numeric_limits::max(); + + for (auto CVPoint : candidates) { + if (inCV[CVPoint]) continue; + + unsigned short shared = 0; + for (auto jPoint : fine_grid->nodes->GetPoints(CVPoint)) shared += inCV[jPoint]; + + /*--- Distance to the centroid in cells: the offset is scaled by the seed edge pointing + * most nearly along it. ---*/ + su2double off[MAXNDIM] = {0.0}; + for (unsigned short d = 0; d < nDim; ++d) off[d] = fine_grid->nodes->GetCoord(CVPoint)[d] - centroid[d]; + const su2double offLen = GeometryToolbox::Norm(nDim, off); + + su2double dist = 0.0; + if (haveFrame) { + for (size_t k = 0; k < frameDir.size(); ++k) { + su2double p = 0.0; + for (unsigned short d = 0; d < nDim; ++d) p += off[d] * frameDir[k][d]; + const su2double q = p / frameLen[k]; + dist += q * q; + } + } else { + const su2double r = offLen / seedShortest; + dist = r * r; + } - MGQueue_InnerCV.Update(CVPoint, fine_grid); + if ((shared > best_shared) || ((shared == best_shared) && (dist < best_dist))) { + best = CVPoint; + best_shared = shared; + best_dist = dist; + } } + + if (best == NO_CV) break; + addMember(best); } + for (auto jPoint : members) inCV[jPoint] = 0; + for (auto jPoint : candidates) isCandidate[jPoint] = 0; + /*--- Update the number of control of childrens ---*/ nodes->SetnChildren_CV(Index_CoarseCV, nChildren); @@ -428,76 +563,193 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un nPointDomain = Index_CoarseCV; nPoint = nPointDomain; - /*--- Check that there are no hanging nodes. Detect isolated points - (only 1 neighbor), and merge their children CV's with the neighbor. ---*/ + /*--- Coarse neighbours, so the repair passes below can find a CV a merge can go to. ---*/ SetPoint_Connectivity(fine_grid); + /*--- Coarse CVs the repair passes must leave exactly as the agglomeration made them, and those + * holding a boundary node at all. ---*/ + vector mustStayAlone(nPointDomain, false); + vector cvOnBoundary(nPointDomain, false); + for (auto iCoarsePoint = 0ul; iCoarsePoint < nPointDomain; iCoarsePoint++) + for (auto iChildren = 0u; iChildren < nodes->GetnChildren_CV(iCoarsePoint); iChildren++) { + const auto iFinePoint = nodes->GetChildren_CV(iCoarsePoint, iChildren); + if (mixedBC[iFinePoint] || onPeriodic[iFinePoint]) mustStayAlone[iCoarsePoint] = true; + if (onPhysBoundary[iFinePoint]) cvOnBoundary[iCoarsePoint] = true; + } + + /*--- Which physical boundaries each coarse CV sits on, as a marker-set class. Comparing classes + * keeps a merge inside one boundary. Halo points hold the parent sentinel and drop out. ---*/ + vector> cvMarker; + for (auto iMarker = 0u; iMarker < fine_grid->GetnMarker(); iMarker++) { + if (config->GetMarker_All_KindBC(iMarker) == SEND_RECEIVE) continue; + for (auto iVertex = 0ul; iVertex < fine_grid->nVertex[iMarker]; iVertex++) { + const auto iParent = fine_grid->nodes->GetParent_CV(fine_grid->vertex[iMarker][iVertex]->GetNode()); + if (iParent < nPointDomain) cvMarker.push_back({iParent, static_cast(iMarker)}); + } + } + const auto cvMarkerClass = MarkerSetClasses(nPointDomain, cvMarker); + + /*--- Columns that never advanced past their seed layer, which are not stacks. ---*/ + vector neverGrew(nPointDomain, false); + for (auto iCV : neverGrewCV) + if (iCV < nPointDomain) neverGrew[iCV] = true; + + /*--- A boundary CV the paving built is the base of a stack and keeps its footprint. ---*/ + auto isStackBase = [&](unsigned long iCoarsePoint) { + return cvOnBoundary[iCoarsePoint] && (iCoarsePoint >= firstLineCV) && (iCoarsePoint < endLineCV) && + !neverGrew[iCoarsePoint]; + }; + + /*--- The coarse connectivity only knows about CVs of this rank, so a CV reaching over a partition + * boundary can look isolated. ---*/ + vector touchesPartition(nPointDomain, false); for (auto iCoarsePoint = 0ul; iCoarsePoint < nPointDomain; iCoarsePoint++) { - if (nodes->GetnPoint(iCoarsePoint) == 1) { - /*--- Find the neighbor of the isolated point. This neighbor is the right control volume ---*/ + for (auto iChildren = 0u; iChildren < nodes->GetnChildren_CV(iCoarsePoint); iChildren++) { + const auto iFinePoint = nodes->GetChildren_CV(iCoarsePoint, iChildren); + for (auto iFinePoint_Neighbor : fine_grid->nodes->GetPoints(iFinePoint)) { + if (fine_grid->nodes->GetParent_CV(iFinePoint_Neighbor) == NO_CV) { + touchesPartition[iCoarsePoint] = true; + break; + } + } + if (touchesPartition[iCoarsePoint]) break; + } + } - const auto iCoarsePoint_Complete = nodes->GetPoint(iCoarsePoint, 0); + /*--- Whether jCV may take children from iCV: the agglomeration has not pinned it, and it sits on + * the same boundaries. ---*/ + auto mayMerge = [&](unsigned long iCV, unsigned long jCV) { + return !mustStayAlone[jCV] && !isStackBase(jCV) && (cvMarkerClass[jCV] == cvMarkerClass[iCV]); + }; + + /*--- Append one fine point to a coarse CV. ---*/ + auto giveChild = [&](unsigned long iFinePoint, unsigned long toCV) { + const auto nChildren = nodes->GetnChildren_CV(toCV); + nodes->SetChildren_CV(toCV, nChildren, iFinePoint); + nodes->SetnChildren_CV(toCV, nChildren + 1); + fine_grid->nodes->SetParent_CV(iFinePoint, toCV); + }; + + /*--- Empty one coarse CV into another. ---*/ + auto mergeInto = [&](unsigned long fromCV, unsigned long toCV) { + for (auto iChildren = 0u; iChildren < nodes->GetnChildren_CV(fromCV); iChildren++) + giveChild(nodes->GetChildren_CV(fromCV, iChildren), toCV); + nodes->SetnChildren_CV(fromCV, 0); + }; + + /*--- Neighbour with the fewest children that may take this CV, NO_CV if there is none. Neighbours + * an earlier merge in the same pass emptied are not revived. ---*/ + auto smallestPartner = [&](unsigned long iCV, unsigned short maxPartnerSize, bool keepOffPartition) { + auto best = NO_CV; + auto best_nChildren = std::numeric_limits::max(); + for (auto jCV : nodes->GetPoints(iCV)) { + const auto nChildren = nodes->GetnChildren_CV(jCV); + if ((nChildren == 0) || (nChildren > maxPartnerSize) || (nChildren >= best_nChildren)) continue; + if (keepOffPartition && touchesPartition[jCV]) continue; + if (!mayMerge(iCV, jCV)) continue; + best_nChildren = nChildren; + best = jCV; + } + return best; + }; - /*--- Check if merging would exceed the maximum agglomeration size ---*/ - auto nChildren_Target = nodes->GetnChildren_CV(iCoarsePoint_Complete); - auto nChildren_Isolated = nodes->GetnChildren_CV(iCoarsePoint); - auto nChildren_Total = nChildren_Target + nChildren_Isolated; + /*--- A CV with a single coarse neighbour is merged into it. ---*/ - /*--- If the total would exceed maxAgglomSize, try to redistribute children to neighbors ---*/ - if (nChildren_Total > maxAgglomSize) { - /*--- Find neighbors of the target coarse point that have room ---*/ - unsigned short nChildrenToRedistribute = nChildren_Total - maxAgglomSize; + for (auto iCoarsePoint = 0ul; iCoarsePoint < nPointDomain; iCoarsePoint++) { + if (mustStayAlone[iCoarsePoint] || touchesPartition[iCoarsePoint]) continue; + if (nodes->GetnPoint(iCoarsePoint) != 1) continue; + + const auto iTarget = nodes->GetPoint(iCoarsePoint, 0); + if (isStackBase(iCoarsePoint) || !mayMerge(iCoarsePoint, iTarget)) continue; + /*--- Two boundary rows that already hold more than one node each must never fuse into one + * oversized CV. A genuine singleton leftover may still be absorbed. ---*/ + if (cvOnBoundary[iCoarsePoint] && cvOnBoundary[iTarget] && (nodes->GetnChildren_CV(iCoarsePoint) > 1)) continue; + + /*--- Make room in the target by handing its last children to its other neighbours. The merge + * runs whether or not that succeeds, so the size limit can still be exceeded. ---*/ + int nAfterMerge = nodes->GetnChildren_CV(iTarget) + nodes->GetnChildren_CV(iCoarsePoint); + for (auto jCoarsePoint : nodes->GetPoints(iTarget)) { + if (nAfterMerge <= maxAgglomSize) break; + /*--- The isolated CV hands anything it takes straight back below. ---*/ + if ((jCoarsePoint == iCoarsePoint) || !mayMerge(iTarget, jCoarsePoint)) continue; + + while ((nAfterMerge > maxAgglomSize) && (nodes->GetnChildren_CV(jCoarsePoint) < maxAgglomSize)) { + const auto nChildren = nodes->GetnChildren_CV(iTarget); + if (nChildren == 0) break; + giveChild(nodes->GetChildren_CV(iTarget, nChildren - 1), jCoarsePoint); + nodes->SetnChildren_CV(iTarget, nChildren - 1); + nAfterMerge--; + } + } - for (auto jCoarsePoint : nodes->GetPoints(iCoarsePoint_Complete)) { - if (nChildrenToRedistribute == 0) break; + mergeInto(iCoarsePoint, iTarget); + } - auto nChildren_Neighbor = nodes->GetnChildren_CV(jCoarsePoint); - if (nChildren_Neighbor < maxAgglomSize) { - unsigned short nCanTransfer = - min(nChildrenToRedistribute, static_cast(maxAgglomSize - nChildren_Neighbor)); + /*--- A CV left holding a single child joins the neighbour with the fewest, even where that takes + the neighbour one past maxAgglomSize. ---*/ - /*--- Transfer children from target to neighbor ---*/ - for (unsigned short iTransfer = 0; iTransfer < nCanTransfer; iTransfer++) { - /*--- Take from the end of the target's children list ---*/ - auto nChildren_Current = nodes->GetnChildren_CV(iCoarsePoint_Complete); - if (nChildren_Current > 0) { - auto iFinePoint = nodes->GetChildren_CV(iCoarsePoint_Complete, nChildren_Current - 1); + for (auto iCoarsePoint = 0ul; iCoarsePoint < nPointDomain; iCoarsePoint++) { + if (nodes->GetnChildren_CV(iCoarsePoint) != 1) continue; + if (mustStayAlone[iCoarsePoint] || isStackBase(iCoarsePoint)) continue; + /*--- Already handled above, or truly islanded. ---*/ + if (nodes->GetnPoint(iCoarsePoint) <= 1) continue; - /*--- Add to neighbor ---*/ - auto nChildren_Neighbor_Current = nodes->GetnChildren_CV(jCoarsePoint); - nodes->SetChildren_CV(jCoarsePoint, nChildren_Neighbor_Current, iFinePoint); - nodes->SetnChildren_CV(jCoarsePoint, nChildren_Neighbor_Current + 1); + const auto iTarget = smallestPartner(iCoarsePoint, std::numeric_limits::max(), false); + if (iTarget != NO_CV) mergeInto(iCoarsePoint, iTarget); + } - /*--- Update parent ---*/ - fine_grid->nodes->SetParent_CV(iFinePoint, jCoarsePoint); + /*--- Merge a paved CV of at most SMALL_STACK_CV children into an equally small neighbour, which + the two passes above do not reach. Two of them can never exceed maxAgglomSize together. ---*/ - /*--- Remove from target (by reducing count) ---*/ - nodes->SetnChildren_CV(iCoarsePoint_Complete, nChildren_Current - 1); + constexpr unsigned short SMALL_STACK_CV = 2; /*!< \brief The block size a narrow stack emits + between flushes; see BlockFor. */ - nChildrenToRedistribute--; - } - } - } - } + for (auto iCoarsePoint = 0ul; iCoarsePoint < nPointDomain; iCoarsePoint++) { + const auto nChildren = nodes->GetnChildren_CV(iCoarsePoint); + if ((nChildren == 0) || (nChildren > SMALL_STACK_CV)) continue; + if (mustStayAlone[iCoarsePoint] || isStackBase(iCoarsePoint) || touchesPartition[iCoarsePoint]) continue; + /*--- Interior stack fragments only, a boundary row keeps its footprint. ---*/ + if (cvOnBoundary[iCoarsePoint]) continue; + + const auto iTarget = smallestPartner(iCoarsePoint, SMALL_STACK_CV, true); + if (iTarget != NO_CV) mergeInto(iCoarsePoint, iTarget); + } - /*--- Update the target's child count after redistribution ---*/ - nChildren_Target = nodes->GetnChildren_CV(iCoarsePoint_Complete); + /*--- Compact the coarse numbering, squeezing out the indices the repair passes emptied. The + children lists, indirect-agglomeration flags and owned parent indices are remapped. ---*/ + + { + vector newIndex(nPointDomain, NO_CV); + unsigned long nKept = 0; + for (auto iCoarsePoint = 0ul; iCoarsePoint < nPointDomain; iCoarsePoint++) + if (nodes->GetnChildren_CV(iCoarsePoint) > 0) newIndex[iCoarsePoint] = nKept++; + + if (nKept < nPointDomain) { + /*--- Move the survivors down. newIndex[i] <= i, so a forward sweep never lands on a CV that has + not been moved yet. ---*/ + for (auto iCoarsePoint = 0ul; iCoarsePoint < nPointDomain; iCoarsePoint++) { + const auto iNew = newIndex[iCoarsePoint]; + if ((iNew == NO_CV) || (iNew == iCoarsePoint)) continue; + nodes->SetChildren_CV(iNew, nodes->GetChildren_CV(iCoarsePoint)); + nodes->SetnChildren_CV(iNew, nodes->GetnChildren_CV(iCoarsePoint)); + nodes->SetAgglomerate_Indirect(iNew, nodes->GetAgglomerate_Indirect(iCoarsePoint)); } - - /*--- Add the isolated point's children to the target control volume ---*/ - auto nChildren = nChildren_Target; - for (auto iChildren = 0u; iChildren < nodes->GetnChildren_CV(iCoarsePoint); iChildren++) { - const auto iFinePoint = nodes->GetChildren_CV(iCoarsePoint, iChildren); - nodes->SetChildren_CV(iCoarsePoint_Complete, nChildren, iFinePoint); - nChildren++; - fine_grid->nodes->SetParent_CV(iFinePoint, iCoarsePoint_Complete); + for (auto iCoarsePoint = nKept; iCoarsePoint < nPointDomain; iCoarsePoint++) + nodes->SetnChildren_CV(iCoarsePoint, 0); + + for (auto iFinePoint = 0ul; iFinePoint < fine_grid->GetnPointDomain(); iFinePoint++) { + const auto iParent = fine_grid->nodes->GetParent_CV(iFinePoint); + if (iParent == NO_CV) continue; + /*--- A fine point may only reference a CV the compaction kept. ---*/ + if ((iParent >= nPointDomain) || (newIndex[iParent] == NO_CV)) + SU2_MPI::Error("Multigrid compaction: a fine point still references an emptied coarse CV.", CURRENT_FUNCTION); + fine_grid->nodes->SetParent_CV(iFinePoint, newIndex[iParent]); } - /*--- Update the number of children control volumes ---*/ - - nodes->SetnChildren_CV(iCoarsePoint_Complete, nChildren); - nodes->SetnChildren_CV(iCoarsePoint, 0); + nPointDomain = nKept; + nPoint = nKept; + Index_CoarseCV = nKept; } } @@ -506,16 +758,6 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un nodes->ResetPoints(); #ifdef HAVE_MPI - /*--- Reset halo point parents before MPI agglomeration. - When creating level N from level N-1, the fine grid (level N-1) - already has Parent_CV set from when it was created from level N-2. - Those parent indices point to level N, but when creating level N+1, they would be - incorrectly interpreted as level N+1 indices. ---*/ - - for (auto iPoint = fine_grid->GetnPointDomain(); iPoint < fine_grid->GetnPoint(); iPoint++) { - fine_grid->nodes->SetParent_CV(iPoint, std::numeric_limits::max()); - } - /*--- Dealing with MPI parallelization, the objective is that the received nodes must be agglomerated in the same way as the donor (send) nodes. Send the node agglomeration information of the donor (parent and children). The agglomerated halos of this rank are set according to the rank where @@ -571,20 +813,20 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un vector Parent_Local(nVertexR); vector Children_Local(nVertexR); - /*--- First pass: Determine which parents will actually be used (have non-skipped children). - This prevents creating orphaned halo CVs that have coordinates (0,0,0). ---*/ + /*--- First pass: determine which parents will actually be used, i.e. have non-skipped + children. ---*/ vector parent_used(Aux_Parent.size(), false); - vector parent_local_index(Aux_Parent.size(), std::numeric_limits::max()); + vector parent_local_index(Aux_Parent.size(), NO_CV); for (auto iVertex = 0ul; iVertex < nVertexR; iVertex++) { const auto iPoint_Fine = fine_grid->vertex[MarkerR][iVertex]->GetNode(); auto existing_parent = fine_grid->nodes->GetParent_CV(iPoint_Fine); /*--- Skip if already agglomerated (first-wins policy) ---*/ - if (existing_parent != std::numeric_limits::max()) continue; + if (existing_parent != NO_CV) continue; /*--- Skip if received parent is invalid (sending rank didn't agglomerate this point) ---*/ - if (Parent_Remote[iVertex] == std::numeric_limits::max()) continue; + if (Parent_Remote[iVertex] == NO_CV) continue; /*--- Find which parent this vertex maps to ---*/ for (auto jVertex = 0ul; jVertex < Aux_Parent.size(); jVertex++) { @@ -606,7 +848,7 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un /*--- Now map each received vertex to its local parent ---*/ for (auto iVertex = 0ul; iVertex < nVertexR; iVertex++) { - Parent_Local[iVertex] = std::numeric_limits::max(); + Parent_Local[iVertex] = NO_CV; for (auto jVertex = 0ul; jVertex < Aux_Parent.size(); jVertex++) { if (Parent_Remote[iVertex] == Aux_Parent[jVertex]) { Parent_Local[iVertex] = parent_local_index[jVertex]; @@ -626,11 +868,11 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un /*--- Skip if this halo point was already agglomerated (first-wins policy) ---*/ auto existing_parent = fine_grid->nodes->GetParent_CV(iPoint_Fine); - if (existing_parent != std::numeric_limits::max()) continue; + if (existing_parent != NO_CV) continue; /*--- Skip if parent mapping is invalid (sender didn't agglomerate) ---*/ const auto iPoint_Coarse = Parent_Local[iVertex]; - if (iPoint_Coarse == std::numeric_limits::max()) continue; + if (iPoint_Coarse == NO_CV) continue; /*--- Append to existing children, don't overwrite ---*/ auto existing_children_count = nodes->GetnChildren_CV(iPoint_Coarse); @@ -649,6 +891,17 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un nPoint = Index_CoarseCV; + /*--- Name each coarse point, halos too, by the smallest global index it holds, so every level + * carries a name its owner and the ranks that only see it agree on. ---*/ + + for (auto iCoarsePoint = 0ul; iCoarsePoint < nPoint; iCoarsePoint++) { + auto globalIndex = NO_CV; + for (auto iChildren = 0u; iChildren < nodes->GetnChildren_CV(iCoarsePoint); iChildren++) + globalIndex = + std::min(globalIndex, fine_grid->nodes->GetGlobalIndex(nodes->GetChildren_CV(iCoarsePoint, iChildren))); + if (globalIndex != NO_CV) nodes->SetGlobalIndex(iCoarsePoint, globalIndex); + } + /*--- Console output with the summary of the agglomeration ---*/ unsigned long nPointFine = fine_grid->GetnPointDomain(); unsigned long Global_nPointCoarse, Global_nPointFine; @@ -659,15 +912,16 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un SetGlobal_nPointDomain(Global_nPointCoarse); if (iMesh != MESH_0) { - /*--- Note: CFL at the coarse levels have a large impact on convergence, - this should be rewritten to use adaptive CFL. ---*/ - const su2double Coeff = 1.5; - const su2double CFL = config->GetCFL(iMesh - 1) / Coeff; - config->SetCFL(iMesh, CFL); + /*--- Seed the coarse-level CFL with the same per-level reduction CMultiGridIntegration + applies after every cycle. ---*/ + const su2double scale = max(su2double(1e-6), min(su2double(1.0), config->GetMGOptions().MG_CflScaling[iMesh - 1])); + config->SetCFL(iMesh, config->GetCFL(iMesh - 1) * scale); } const su2double ratio = su2double(Global_nPointFine) / su2double(Global_nPointCoarse); + /*--- Stop coarsening on the size of the whole level, so the hierarchy a case gets does not + depend on how many ranks it happens to run on. ---*/ if (Global_nPointCoarse < config->GetMGOptions().MG_Min_MeshSize) { if (rank == MASTER_NODE) cout << "MG level " << iMesh << " has only " << Global_nPointCoarse @@ -694,41 +948,26 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un } } - /*--- Output Euler wall agglomeration statistics ---*/ - if (rank == MASTER_NODE) { - /*--- Gather global statistics for Euler walls ---*/ - bool has_euler_walls = false; - for (unsigned short iMarker = 0; iMarker < fine_grid->GetnMarker(); iMarker++) { - if (config->GetMarker_All_KindBC(iMarker) == EULER_WALL) { - has_euler_walls = true; - break; - } - } + /*--- Euler wall seeds this level took, one line per marker. Every rank reaches the reduction. ---*/ - if (has_euler_walls) { - cout << endl; - cout << "Euler Wall Agglomeration Statistics (45° curvature threshold):" << endl; - cout << "----------------------------------------------------------------" << endl; - - for (unsigned short iMarker = 0; iMarker < fine_grid->GetnMarker(); iMarker++) { - if (config->GetMarker_All_KindBC(iMarker) == EULER_WALL) { - string marker_name = config->GetMarker_All_TagBound(iMarker); - unsigned long agglomerated = euler_wall_agglomerated[iMarker]; - unsigned long rejected = euler_wall_rejected_curvature[iMarker]; - unsigned long total = agglomerated + rejected; - - if (total > 0) { - su2double accept_rate = 100.0 * su2double(agglomerated) / su2double(total); - cout << " Marker: " << marker_name << endl; - cout << " Seeds agglomerated: " << agglomerated << " (" << std::setprecision(1) << std::fixed - << accept_rate << "%)" << endl; - cout << " Seeds rejected (>45° curv): " << rejected << " (" << std::setprecision(1) << std::fixed - << (100.0 - accept_rate) << "%)" << endl; - } - } - } - cout << "----------------------------------------------------------------" << endl; + vector eulerTakenGlobal(eulerTaken.size()), eulerRefusedGlobal(eulerRefused.size()); + SU2_MPI::Allreduce(eulerTaken.data(), eulerTakenGlobal.data(), eulerTaken.size(), MPI_UNSIGNED_LONG, MPI_SUM, + SU2_MPI::GetComm()); + SU2_MPI::Allreduce(eulerRefused.data(), eulerRefusedGlobal.data(), eulerRefused.size(), MPI_UNSIGNED_LONG, MPI_SUM, + SU2_MPI::GetComm()); + + if (rank == MASTER_NODE) { + stringstream euler; + euler << std::fixed << std::setprecision(1); + for (auto iMarker = 0u; iMarker < eulerTakenGlobal.size(); iMarker++) { + const auto total = eulerTakenGlobal[iMarker] + eulerRefusedGlobal[iMarker]; + if (total == 0) continue; + euler << " MG level " << iMesh << " Euler wall " << config->GetMarker_CfgFile_TagBound(iMarker) << ": " + << eulerTakenGlobal[iMarker] << " seeds agglomerated, " << eulerRefusedGlobal[iMarker] << " refused above " + << EULER_WALL_MAX_CURVATURE << " degrees of curvature (" + << 100.0 * passivedouble(eulerRefusedGlobal[iMarker]) / passivedouble(total) << "%)\n"; } + levelReport += euler.str(); } edgeColorGroupSize = config->GetEdgeColoringGroupSize(); @@ -736,23 +975,42 @@ CMultiGridGeometry::CMultiGridGeometry(CGeometry* fine_grid, CConfig* config, un bool CMultiGridGeometry::GeometricalCheck(unsigned long iPoint, const CGeometry* fine_grid, const CConfig* config) const { - su2double max_dimension = 1.2; + /*--- A control volume whose edge exceeds MAX_DIMENSION times the domain's is not agglomerated. + * Raising both sides to the power nDim gives the same test on volumes, without the roots. ---*/ + constexpr passivedouble MAX_DIMENSION = 1.2; + su2double scale = MAX_DIMENSION * MAX_DIMENSION; + if (nDim == 3) scale *= MAX_DIMENSION; - /*--- Evaluate the total size of the element ---*/ + return fine_grid->nodes->GetVolume(iPoint) * scale <= config->GetDomainVolume(); +} - bool Volume = true; - su2double ratio = pow(fine_grid->nodes->GetVolume(iPoint), 1.0 / su2double(nDim)) * max_dimension; - su2double limit = pow(config->GetDomainVolume(), 1.0 / su2double(nDim)); - if (ratio > limit) { - Volume = false; - cout << "Volume limit reached!" << endl; - } +vector CMultiGridGeometry::FindMixedBoundaryNodes(const CGeometry* fine_grid, const CConfig* config) const { + vector mixed(fine_grid->GetnPoint(), 0); + + /*--- The first physical condition seen at each node, -1 until one is. A second one of a different + * kind is what makes the node mixed. ---*/ + vector firstBC(fine_grid->GetnPoint(), -1); - return (Volume); + for (auto iMarker = 0u; iMarker < fine_grid->GetnMarker(); iMarker++) { + if (config->GetMarker_All_KindBC(iMarker) == SEND_RECEIVE) continue; + const auto bc = static_cast(config->GetMarker_All_KindBC(iMarker)); + for (auto iVertex = 0ul; iVertex < fine_grid->GetnVertex(iMarker); iVertex++) { + const auto iPoint = fine_grid->vertex[iMarker][iVertex]->GetNode(); + if (firstBC[iPoint] < 0) + firstBC[iPoint] = bc; + else if (firstBC[iPoint] != bc) + mixed[iPoint] = 1; + } + } + return mixed; } bool CMultiGridGeometry::SetBoundAgglomeration(unsigned long CVPoint, vector marker_seed, - const CGeometry* fine_grid, const CConfig* config) const { + const CGeometry* fine_grid, const CConfig* config, + const vector& mixedBC) const { + /*--- A node where two boundary conditions of different type meet is never merged with anything. ---*/ + if (mixedBC[CVPoint]) return false; + bool agglomerate_CV = false; /*--- Basic condition, the point has not been previously agglomerated, it belongs to the domain, @@ -763,21 +1021,22 @@ bool CMultiGridGeometry::SetBoundAgglomeration(unsigned long CVPoint, vectornodes->GetBoundary(CVPoint)) { - /*--- Identify the markers of the vertex that we want to agglomerate ---*/ + /*--- Identify the physical markers of the vertex that we want to agglomerate. A candidate whose + markers are all SEND_RECEIVE ends up with counter == 0 and is rejected below. ---*/ - // count number of markers on the agglomeration candidate - for (auto jMarker = 0u; jMarker < fine_grid->GetnMarker() && counter < 3; jMarker++) { + for (auto jMarker = 0u; jMarker < fine_grid->GetnMarker(); jMarker++) { + if (config->GetMarker_All_KindBC(jMarker) == SEND_RECEIVE) continue; if (fine_grid->nodes->GetVertex(CVPoint, jMarker) != -1) { - copy_marker[counter] = jMarker; + if (counter < 2) copy_marker[counter] = jMarker; counter++; } } - /*--- The basic condition is that the agglomerated vertex must have the same physical marker, - but eventually a send-receive condition ---*/ + /*--- The basic condition is that the agglomerated vertex must have the same physical marker + as the seed. ---*/ /*--- Only one marker in the vertex that is going to be agglomerated ---*/ @@ -787,16 +1046,6 @@ bool CMultiGridGeometry::SetBoundAgglomeration(unsigned long CVPoint, vectorGetMarker_All_KindBC(other_marker) == SEND_RECEIVE) { - agglomerate_CV = true; - } - } } /*--- If there are two markers in the vertex that is going to be aglomerated ---*/ @@ -806,7 +1055,7 @@ bool CMultiGridGeometry::SetBoundAgglomeration(unsigned long CVPoint, vector& Suitable_Indirect_Neighbors, unsigned long iPoint, - unsigned long Index_CoarseCV, const CGeometry* fine_grid) const { + const CGeometry* fine_grid) const { /*--- Create a list with the first neighbors, including the seed. ---*/ vector First_Neighbor_Points; @@ -835,7 +1082,7 @@ void CMultiGridGeometry::SetSuitableNeighbors(vector& Suitable_In /*--- Create a list with the second neighbors, without first, and seed neighbors. ---*/ - vector Second_Neighbor_Points, Second_Origin_Points, Suitable_Second_Neighbors; + vector Second_Neighbor_Points, Second_Origin_Points; for (auto jPoint : fine_grid->nodes->GetPoints(iPoint)) { for (auto kPoint : fine_grid->nodes->GetPoints(jPoint)) { @@ -860,20 +1107,9 @@ void CMultiGridGeometry::SetSuitableNeighbors(vector& Suitable_In if ((Second_Neighbor_Points[iNeighbor] == Second_Neighbor_Points[jNeighbor]) && (Second_Origin_Points[iNeighbor] != Second_Origin_Points[jNeighbor])) { Suitable_Indirect_Neighbors.push_back(Second_Neighbor_Points[iNeighbor]); - - /*--- Create a list of suitable second neighbors, that we will use - to compute the third neighbors. --*/ - - Suitable_Second_Neighbors.push_back(Second_Neighbor_Points[iNeighbor]); } } } - - /*--- Remove duplicates ---*/ - - sort(Suitable_Second_Neighbors.begin(), Suitable_Second_Neighbors.end()); - auto it1 = unique(Suitable_Second_Neighbors.begin(), Suitable_Second_Neighbors.end()); - Suitable_Second_Neighbors.resize(it1 - Suitable_Second_Neighbors.begin()); } void CMultiGridGeometry::SetPoint_Connectivity(const CGeometry* fine_grid) { @@ -887,6 +1123,9 @@ void CMultiGridGeometry::SetPoint_Connectivity(const CGeometry* fine_grid) { /*--- loop over the parent CVs (coarse grid) of its (fine) neighbors. ---*/ for (auto iFinePoint_Neighbor : fine_grid->nodes->GetPoints(iFinePoint)) { const auto iParent = fine_grid->nodes->GetParent_CV(iFinePoint_Neighbor); + /*--- Skip neighbors whose parent is not known yet, halo points still hold the sentinel until + the MPI relay has run. ---*/ + if (iParent == std::numeric_limits::max()) continue; /*--- If it is not the target coarse point, it is a coarse neighbor. ---*/ if (iParent != iCoarsePoint) { /*--- Avoid duplicates. ---*/ @@ -1218,8 +1457,7 @@ void CMultiGridGeometry::FindNormal_Neighbor(const CConfig* config) { su2double CMultiGridGeometry::ComputeLocalCurvature(const CGeometry* fine_grid, unsigned long iPoint, unsigned short iMarker) const { - /*--- Compute local curvature (maximum angle between adjacent face normals) at a boundary vertex. - This is used to determine if agglomeration is safe based on a curvature threshold. ---*/ + /*--- Local curvature is the maximum angle between adjacent face normals at a boundary vertex. ---*/ /*--- Get the vertex index for this point on this marker ---*/ long iVertex = fine_grid->nodes->GetVertex(iPoint, iMarker); @@ -1280,232 +1518,913 @@ su2double CMultiGridGeometry::ComputeLocalCurvature(const CGeometry* fine_grid, return max_angle; } -void CMultiGridGeometry::AgglomerateImplicitLines(unsigned long& Index_CoarseCV, const CGeometry* fine_grid, - const CConfig* config, CMultiGridQueue& MGQueue_InnerCV) { - /*--- Parameters ---*/ - const su2double ANGLE_THRESHOLD_DEG = 20.0; /*!< Stop line if direction deviates more than this. */ - const unsigned long MAX_LINE_LENGTH = config->GetMGOptions().MG_Implicit_Lines_MaxLength; - const su2double cos_threshold = cos(ANGLE_THRESHOLD_DEG * PI_NUMBER / 180.0); - - const unsigned long nPointFine = fine_grid->GetnPoint(); - - /*--- Collect implicit lines starting at viscous (no-slip) wall vertices only. - * Seeding from non-wall boundaries (farfield, inlet, outlet, symmetry) would - * claim interior BL cells before the wall lines can reach them, leaving - * wall-seeded lines with length < 3 (discarded). Restricting to viscous walls - * ensures the boundary-layer cells are agglomerated wall-first. - * Each line: [wall_node, interior_1, interior_2, ...]. - * The wall node (index 0) is already agglomerated by boundary agglomeration; - * only interior nodes (index >= 1) are paired into coarse CVs. ---*/ - vector> lines; +namespace { + +/*--- Unit normal of a boundary at a vertex, false if the marker does not reach iPoint. Boundary + * normals point into the domain. ---*/ +bool VertexUnitNormal(const CGeometry* grid, unsigned short nDim, unsigned long iPoint, unsigned short iMarker, + su2double* unitNormal) { + const long iVertex = grid->nodes->GetVertex(iPoint, iMarker); + if (iVertex == -1) return false; + grid->vertex[iMarker][iVertex]->GetNormal(unitNormal); + const su2double nrm = GeometryToolbox::Norm(nDim, unitNormal); + if (nrm <= 0.0) return false; + for (unsigned short d = 0; d < nDim; ++d) unitNormal[d] /= nrm; + return true; +} + +/*--- Fine layers the next coarse CV of a column holds: two, or one if that would exceed the + * agglomeration size limit. ---*/ +unsigned long BlockFor(short int maxAgglomSize, size_t width) { + return (width * 2 > static_cast(maxAgglomSize)) ? 1 : 2; +} + +constexpr unsigned short NO_FACE = std::numeric_limits::max(); +constexpr auto NO_ELEM = std::numeric_limits::max(); + +/*--- Face an element is left by when it is entered through the given one. Only the extruded + * types have one. ---*/ +unsigned short OppositeFace(unsigned short vtkType, unsigned short iFace) { + switch (vtkType) { + case QUADRILATERAL: { + static const unsigned short opposite[4] = {2, 3, 0, 1}; + return opposite[iFace]; + } + case HEXAHEDRON: { + static const unsigned short opposite[6] = {2, 3, 0, 1, 5, 4}; + return opposite[iFace]; + } + case PRISM: { + /*--- Only the two triangles pair; the quadrilateral sides are not crossed. ---*/ + static const unsigned short opposite[5] = {NO_FACE, NO_FACE, NO_FACE, 4, 3}; + return opposite[iFace]; + } + default: + return NO_FACE; + } +} + +/*--- Sorted nodes of a face, the key that names it in either element holding it. ---*/ +void FaceNodes(const CGeometry* grid, unsigned long iElem, unsigned short iFace, vector& face) { + const auto* elem = grid->elem[iElem]; + face.clear(); + for (unsigned short k = 0; k < elem->GetnNodesFace(iFace); ++k) + face.push_back(elem->GetNode(elem->GetFaces(iFace, k))); + std::sort(face.begin(), face.end()); +} + +/*--- Local index of the face with these nodes, or NO_FACE. ---*/ +unsigned short LocalFace(const CGeometry* grid, unsigned long iElem, const vector& face, + vector& scratch) { + for (unsigned short iFace = 0; iFace < grid->elem[iElem]->GetnFaces(); ++iFace) { + FaceNodes(grid, iElem, iFace, scratch); + if (scratch == face) return iFace; + } + return NO_FACE; +} + +/*--- Whether the primal grid is available, which it is on the fine mesh only. ---*/ +bool HasElements(const CGeometry* grid) { return (grid->elem != nullptr) && (grid->GetnElem() > 0); } + +} // namespace + +CMultiGridGeometry::CFrontSeeds CMultiGridGeometry::SeedFrontNodes(const CGeometry* fine_grid, + const CConfig* config) const { + CFrontSeeds seeds; + vector taken(fine_grid->GetnPoint(), 0); + + /*--- Stiffness the smoother sees across an edge, from the dual face it carries. ---*/ + auto edgeWeight = [&](unsigned long iPoint, unsigned short iNeigh) { + const auto jPoint = fine_grid->nodes->GetPoint(iPoint, iNeigh); + const auto iEdge = fine_grid->nodes->GetEdge(iPoint, iNeigh); + const su2double area = GeometryToolbox::Norm(nDim, fine_grid->edges->GetNormal(iEdge)); + return 0.5 * area * (1.0 / fine_grid->nodes->GetVolume(iPoint) + 1.0 / fine_grid->nodes->GetVolume(jPoint)); + }; + + /*--- Local anisotropy at a node, the stiffest edge over the slackest. It orders the seeds so + * that the thinnest mesh is served first, and is zero where no edge is usable. ---*/ + auto layerStrength = [&](unsigned long iPoint) { + su2double wMin = std::numeric_limits::max(), wMax = 0.0; + + for (auto iNeigh = 0u; iNeigh < fine_grid->nodes->GetnPoint(iPoint); ++iNeigh) { + const su2double w = edgeWeight(iPoint, iNeigh); + wMax = std::max(wMax, w); + wMin = std::min(wMin, w); + } + + if (wMax <= 0.0) return su2double(0.0); + return (wMin > 0.0) ? wMax / wMin : su2double(1.0); + }; + + /*--- Paving order: a no-slip wall first, a slip wall next, everything else last. ---*/ + auto tierOfBC = [](unsigned short bc) -> char { + if ((bc == HEAT_FLUX) || (bc == ISOTHERMAL) || (bc == CHT_WALL_INTERFACE) || (bc == SMOLUCHOWSKI_MAXWELL)) return 0; + return (bc == EULER_WALL) ? 1 : 2; + }; for (auto iMarker = 0u; iMarker < fine_grid->GetnMarker(); iMarker++) { - /*--- Only seed lines from viscous (no-slip) wall markers. - * Non-wall boundaries (farfield, inlet, outlet, symmetry) must NOT seed - * lines because they would prematurely claim boundary-layer interior nodes. ---*/ const auto bc = config->GetMarker_All_KindBC(iMarker); - if (bc != HEAT_FLUX && bc != ISOTHERMAL && bc != CHT_WALL_INTERFACE && bc != SMOLUCHOWSKI_MAXWELL) continue; + /*--- Periodic boundaries have their own matching, and a halo marker is not a boundary. ---*/ + if ((bc == SEND_RECEIVE) || (bc == PERIODIC_BOUNDARY)) continue; for (auto iVertex = 0ul; iVertex < fine_grid->GetnVertex(iMarker); iVertex++) { const auto iPoint = fine_grid->vertex[iMarker][iVertex]->GetNode(); + if (!fine_grid->nodes->GetDomain(iPoint)) continue; + if (fine_grid->nodes->GetAgglomerate(iPoint)) continue; + if (taken[iPoint]) continue; /*--- A node on two markers seeds only one column. ---*/ - /*--- Get vertex normal to seed the line direction ---*/ - const long ChildVertex = fine_grid->nodes->GetVertex(iPoint, iMarker); - if (ChildVertex == -1) continue; su2double Normal[MAXNDIM] = {0.0}; - fine_grid->vertex[iMarker][ChildVertex]->GetNormal(Normal); - - /*--- Normalize the direction ---*/ - su2double prev_dir[MAXNDIM] = {0.0}; - su2double norm_prev = 0.0; - for (unsigned short d = 0; d < nDim; ++d) { - prev_dir[d] = Normal[d]; - norm_prev += Normal[d] * Normal[d]; + if (!VertexUnitNormal(fine_grid, nDim, iPoint, iMarker, Normal)) continue; + + /*--- Every boundary node seeds. Seeding only part of a boundary leaves patches with no + * neighbour to pair with, and a patch below full width coarsens worse than no paving. ---*/ + const su2double strength = layerStrength(iPoint); + if (strength <= 0.0) continue; + + /*--- A column claims its seed before the boundary pass runs, so the Euler wall curvature + * limit is applied here too, on the same terms. ---*/ + if ((bc == EULER_WALL) && !fine_grid->boundIsStraight[iMarker] && + (ComputeLocalCurvature(fine_grid, iPoint, iMarker) >= EULER_WALL_MAX_CURVATURE)) { + seeds.nRefusedCurvature++; + continue; } - if (norm_prev <= 0.0) continue; - norm_prev = sqrt(norm_prev); - for (unsigned short d = 0; d < nDim; ++d) prev_dir[d] /= norm_prev; - - /*--- Build the implicit line by following the best-aligned interior neighbor ---*/ - vector L; - L.push_back(iPoint); - auto current = iPoint; - - while (L.size() < MAX_LINE_LENGTH) { - su2double best_dot = -2.0; - unsigned long best_neighbor = ULONG_MAX; - - for (auto jPoint : fine_grid->nodes->GetPoints(current)) { - if (jPoint == current) continue; - if (!fine_grid->nodes->GetDomain(jPoint)) continue; - if (fine_grid->nodes->GetBoundary(jPoint)) continue; - if (fine_grid->nodes->GetAgglomerate(jPoint)) continue; - - /*--- Compute normalized direction to candidate ---*/ - su2double vec[MAXNDIM] = {0.0}; - GeometryToolbox::Distance(nDim, fine_grid->nodes->GetCoord(jPoint), fine_grid->nodes->GetCoord(current), vec); - const su2double len = GeometryToolbox::Norm(nDim, vec); - if (len <= 0.0) continue; - for (unsigned short d = 0; d < nDim; ++d) vec[d] /= len; - - /*--- Alignment with previous direction ---*/ - const su2double dot = GeometryToolbox::DotProduct(nDim, vec, prev_dir); - if (dot > best_dot) { - best_dot = dot; - best_neighbor = jPoint; - } - } - - if (best_neighbor == ULONG_MAX || best_dot < cos_threshold) break; - L.push_back(best_neighbor); + std::array n0{}; + for (unsigned short d = 0; d < nDim; ++d) n0[d] = Normal[d]; + seeds.node.push_back(iPoint); + seeds.normal.push_back(n0); + seeds.strength.push_back(strength); + seeds.tier.push_back(tierOfBC(bc)); + taken[iPoint] = 1; + } + } - /*--- Update direction for next step ---*/ - GeometryToolbox::Distance(nDim, fine_grid->nodes->GetCoord(best_neighbor), fine_grid->nodes->GetCoord(current), - prev_dir); - const su2double len = GeometryToolbox::Norm(nDim, prev_dir); - if (len <= 0.0) break; - for (unsigned short d = 0; d < nDim; ++d) prev_dir[d] /= len; + /*--- Most anisotropic first, so the thinnest mesh takes contested nodes, with the global index + * as the tie-break. ---*/ + vector order(seeds.node.size()); + for (auto i = 0ul; i < order.size(); ++i) order[i] = i; + std::sort(order.begin(), order.end(), [&](unsigned long a, unsigned long b) { + if (seeds.strength[a] != seeds.strength[b]) return seeds.strength[a] > seeds.strength[b]; + return fine_grid->nodes->GetGlobalIndex(seeds.node[a]) < fine_grid->nodes->GetGlobalIndex(seeds.node[b]); + }); + + CFrontSeeds sorted; + sorted.nRefusedCurvature = seeds.nRefusedCurvature; + sorted.node.reserve(order.size()); + sorted.normal.reserve(order.size()); + sorted.strength.reserve(order.size()); + sorted.tier.reserve(order.size()); + for (auto i : order) { + sorted.node.push_back(seeds.node[i]); + sorted.normal.push_back(seeds.normal[i]); + sorted.strength.push_back(seeds.strength[i]); + sorted.tier.push_back(seeds.tier[i]); + } + return sorted; +} +vector> CMultiGridGeometry::BuildFrontPatches(const CFrontSeeds& seeds, + const CGeometry* fine_grid, const CConfig* config, + const vector& mixedBC, + vector& walk) const { + /*--- A boundary face is already the footprint of one element strip, so it is taken as the patch. + * Seeds it leaves over are grouped by repeated pairwise matching. ---*/ + const auto nSeeds = seeds.node.size(); + const unsigned long max_group = (nDim == 2) ? 2 : 4; + + /*--- Marker-set class of each seed. Seeds may only be matched when these agree. ---*/ + const auto nMarkerFine = fine_grid->GetnMarker(); + vector> seedMarker; + for (unsigned long si = 0; si < nSeeds; ++si) + for (auto iMarker = 0u; iMarker < nMarkerFine; iMarker++) + if ((config->GetMarker_All_KindBC(iMarker) != SEND_RECEIVE) && + (fine_grid->nodes->GetVertex(seeds.node[si], iMarker) != -1)) + seedMarker.push_back({si, static_cast(iMarker)}); + const auto sig = MarkerSetClasses(nSeeds, seedMarker); + + /*--- Seed-to-seed adjacency, inherited from the boundary nodes' mesh connectivity. ---*/ + vector seedOfNode(fine_grid->GetnPoint(), -1); + for (unsigned long si = 0; si < nSeeds; ++si) seedOfNode[seeds.node[si]] = static_cast(si); + + vector> adj(nSeeds); + for (unsigned long si = 0; si < nSeeds; ++si) + for (auto jPoint : fine_grid->nodes->GetPoints(seeds.node[si])) { + const auto sj = seedOfNode[jPoint]; + if ((sj >= 0) && (static_cast(sj) != si)) adj[si].push_back(static_cast(sj)); + } - current = best_neighbor; + /*--- Global point index of each seed, used below as the partitioning-independent sort key. ---*/ + vector sgkey(nSeeds); + for (unsigned long si = 0; si < nSeeds; ++si) sgkey[si] = fine_grid->nodes->GetGlobalIndex(seeds.node[si]); + + /*--- Boundary faces whose nodes are all seeds, taken in a partitioning independent order and + * claimed whole, so consecutive faces sharing a node cannot both become a patch. ---*/ + vector faceOfSeed(nSeeds, -1); + vector faceWalk; + if (HasElements(fine_grid)) { + struct CFaceSeed { + unsigned long key; /*!< \brief Lowest global index on the face. */ + vector si; /*!< \brief Its seeds. */ + CWalkState walk; /*!< \brief Element strip it opens. */ + }; + vector candidates; + vector face, faceScratch; + + for (auto iMarker = 0u; iMarker < fine_grid->GetnMarker(); iMarker++) { + const auto bc = config->GetMarker_All_KindBC(iMarker); + if ((bc == SEND_RECEIVE) || (bc == PERIODIC_BOUNDARY)) continue; + + for (auto iElem = 0ul; iElem < fine_grid->nElem_Bound[iMarker]; iElem++) { + const auto* bElem = fine_grid->bound[iMarker][iElem]; + if (bElem->GetnNodes() > max_group) continue; + + CFaceSeed cand; + cand.key = std::numeric_limits::max(); + face.clear(); + bool ok = true; + for (unsigned short k = 0; (k < bElem->GetnNodes()) && ok; ++k) { + const auto iPoint = bElem->GetNode(k); + const auto si = seedOfNode[iPoint]; + ok = (si >= 0) && !mixedBC[iPoint]; + if (!ok) break; + face.push_back(iPoint); + cand.si.push_back(static_cast(si)); + cand.key = std::min(cand.key, sgkey[si]); + } + if (!ok) continue; + for (auto si : cand.si) ok = ok && (sig[si] == sig[cand.si.front()]); + if (!ok) continue; + + std::sort(face.begin(), face.end()); + const auto iVolume = bElem->GetDomainElement(); + const auto iFace = LocalFace(fine_grid, iVolume, face, faceScratch); + if (iFace == NO_FACE) continue; + if (OppositeFace(fine_grid->elem[iVolume]->GetVTK_Type(), iFace) == NO_FACE) continue; + + cand.walk = {iVolume, iFace}; + candidates.push_back(std::move(cand)); } + } - /*--- Accept only lines with at least 2 interior nodes (length >= 3 including wall) ---*/ - if (L.size() >= 3) { - lines.push_back(std::move(L)); + std::sort(candidates.begin(), candidates.end(), + [](const CFaceSeed& a, const CFaceSeed& b) { return a.key < b.key; }); + for (const auto& cand : candidates) { + bool free = true; + for (auto si : cand.si) free = free && (faceOfSeed[si] < 0); + if (!free) continue; + for (auto si : cand.si) faceOfSeed[si] = static_cast(faceWalk.size()); + faceWalk.push_back(cand.walk); + } + } + + vector> groups(faceWalk.size()); + vector groupOf(nSeeds); + /*--- A patch taken from a face is final and takes no part in the matching. ---*/ + vector frozen(faceWalk.size(), 1); + groups.reserve(nSeeds + faceWalk.size()); + + for (unsigned long si = 0; si < nSeeds; ++si) + if (faceOfSeed[si] >= 0) groups[faceOfSeed[si]].push_back(si); + for (unsigned long si = 0; si < nSeeds; ++si) + if (faceOfSeed[si] < 0) { + groups.push_back({si}); + frozen.push_back(0); + } + for (unsigned long g = 0; g < groups.size(); ++g) + for (auto si : groups[g]) groupOf[si] = g; + + const unsigned nRounds = (max_group <= 2) ? 1 : 2; + + /*--- One admissible merge of two groups, weighted by how many seed-to-seed adjacencies they + * share: 2 for a group lying alongside, 1 for one continuing in the same direction. ---*/ + struct CMerge { + unsigned long g, h; /*!< \brief The two groups, g < h. */ + unsigned long weight; /*!< \brief Shared adjacencies: 2 makes a square, 1 makes a strip. */ + unsigned long size; /*!< \brief Seeds the merged group would hold. */ + unsigned long keyG, keyH; /*!< \brief Their global-index keys, the deterministic tie-break. */ + }; + + vector merges; + vector touched, nShared(nSeeds, 0); + vector gkey; + vector consumed; + + for (unsigned round = 0; round < nRounds; ++round) { + const auto nGroups = groups.size(); + + /*--- Sort key of each group: the smallest global point index it holds. ---*/ + gkey.assign(nGroups, std::numeric_limits::max()); + for (unsigned long g = 0; g < nGroups; ++g) + for (auto si : groups[g]) gkey[g] = std::min(gkey[g], sgkey[si]); + + /*--- Every merge this round could make, counted once per unordered pair by taking only + * h > g. ---*/ + merges.clear(); + for (unsigned long g = 0; g < nGroups; ++g) { + /*--- A node where two different boundary conditions meet stays a patch of its own, so both + * sides of a merge are tested for it. ---*/ + if (frozen[g] || mixedBC[seeds.node[groups[g].front()]]) continue; + touched.clear(); + for (auto si : groups[g]) + for (auto sj : adj[si]) { + const auto h = groupOf[sj]; + if (h <= g) continue; + if (frozen[h] || mixedBC[seeds.node[groups[h].front()]]) continue; + if (groups[g].size() + groups[h].size() > max_group) continue; + if (sig[groups[h].front()] != sig[groups[g].front()]) continue; + if (nShared[h]++ == 0) touched.push_back(h); + } + for (auto h : touched) { + merges.push_back( + {g, h, nShared[h], static_cast(groups[g].size() + groups[h].size()), gkey[g], gkey[h]}); + nShared[h] = 0; } } + + /*--- Best merges first over all groups at once, so every square is considered before the first + * strip. At equal weight the bigger patch wins, to fill max_group before settling for less. ---*/ + std::sort(merges.begin(), merges.end(), [](const CMerge& a, const CMerge& b) { + if (a.weight != b.weight) return a.weight > b.weight; + if (a.size != b.size) return a.size > b.size; + if (a.keyG != b.keyG) return a.keyG < b.keyG; + return a.keyH < b.keyH; + }); + + consumed.assign(nGroups, 0); + vector> merged; + vector mergedFrozen; + merged.reserve(nGroups); + + for (const auto& m : merges) { + if (consumed[m.g] || consumed[m.h]) continue; + consumed[m.g] = consumed[m.h] = 1; + auto group = groups[m.g]; + group.insert(group.end(), groups[m.h].begin(), groups[m.h].end()); + merged.push_back(std::move(group)); + mergedFrozen.push_back(0); + } + /*--- Whatever found no partner passes through unchanged. ---*/ + for (unsigned long g = 0; g < nGroups; ++g) + if (!consumed[g]) { + merged.push_back(std::move(groups[g])); + mergedFrozen.push_back(frozen[g]); + } + + groups = std::move(merged); + frozen = std::move(mergedFrozen); + for (unsigned long g = 0; g < groups.size(); ++g) + for (auto si : groups[g]) groupOf[si] = g; + } + + /*--- A patch keeps the strip it opened only while it is still exactly that face. ---*/ + walk.assign(groups.size(), {NO_ELEM, NO_FACE}); + for (unsigned long g = 0; g < groups.size(); ++g) { + const auto id = faceOfSeed[groups[g].front()]; + if (id < 0) continue; + bool whole = true; + for (auto si : groups[g]) whole = whole && (faceOfSeed[si] == id); + if (whole) walk[g] = faceWalk[id]; } - if (lines.empty()) return; + return groups; +} - if (rank == MASTER_NODE) { - cout << "Implicit line agglomeration: detected " << lines.size() << " lines." << endl; +string CMultiGridGeometry::PaveAdvancingFronts(unsigned long& Index_CoarseCV, const CGeometry* fine_grid, + const CConfig* config, unsigned short iMesh, const vector& mixedBC, + const vector& onPhysBoundary, const vector& onPeriodic, + vector& neverGrewCV) { + /*--- Columns rise from the boundary patches one layer per round, and one that runs into a + * partition interface is handed to the rank beyond it. ---*/ + const auto nPointFine = fine_grid->GetnPoint(); + constexpr auto NO_COLUMN = std::numeric_limits::max(); + const short int maxAgglomSize = MaxAgglomSize(nDim); + + /*--- SeedFrontNodes returns the seeds ordered by anisotropy. ---*/ + const auto seeds = SeedFrontNodes(fine_grid, config); + vector walkOf; + const auto patches = BuildFrontPatches(seeds, fine_grid, config, mixedBC, walkOf); + + /*--- Patches take their seeds in seed order, so the most anisotropic boundary is served first. ---*/ + vector order(patches.size()), patchKey(patches.size(), NO_COLUMN); + for (auto iPatch = 0ul; iPatch < patches.size(); ++iPatch) { + order[iPatch] = iPatch; + for (auto si : patches[iPatch]) patchKey[iPatch] = std::min(patchKey[iPatch], si); + } + std::sort(order.begin(), order.end(), [&](unsigned long a, unsigned long b) { return patchKey[a] < patchKey[b]; }); + + vector columnOf(nPointFine, NO_COLUMN), layerOf(nPointFine, 0); + + /*--- Per column state. Columns inherited from another rank are appended while the sweeps run. ---*/ + vector> layer(patches.size()); + vector depthOf(patches.size(), 0); + vector alive(patches.size(), 0); + /*--- A column that started on a boundary patch opens with a boundary row, an inherited one + * continues in open mesh and has no such row. ---*/ + vector isSeeded(patches.size(), 1); + /*--- A patch never straddles two markers, so its tier is that of any of its seeds. ---*/ + vector tierOf(patches.size(), 0); + + /*--- Where each node of the current layer is travelling: the step it last took, or at the + * boundary the inward normal there. ---*/ + vector>> dirOf(patches.size()); + + for (auto iPatch : order) { + for (auto si : patches[iPatch]) { + const auto iPoint = seeds.node[si]; + if (columnOf[iPoint] != NO_COLUMN) continue; + if (fine_grid->nodes->GetAgglomerate(iPoint) || !fine_grid->nodes->GetDomain(iPoint)) continue; + if (!GeometricalCheck(iPoint, fine_grid, config)) continue; + columnOf[iPoint] = iPatch; + layer[iPatch].push_back(iPoint); + dirOf[iPatch].push_back(seeds.normal[si]); + } + tierOf[iPatch] = seeds.tier[patches[iPatch].front()]; + /*--- A strip is only followed from the whole face that opened it. ---*/ + if (layer[iPatch].size() != patches[iPatch].size()) walkOf[iPatch] = {NO_ELEM, NO_FACE}; } - /*--- Advancing-front greedy pairing with cross-line merging. - * For each pair stage k, process interior positions (1+2k, 1+2k+1). - * When two lines share the same wall-node parent CV, merge their pairs - * into a single 4-child coarse CV. Otherwise create 2-child coarse CVs. ---*/ - vector reserved(nPointFine, 0); - unsigned pair_idx = 0; - - while (true) { - bool any_work = false; - - /*--- Build map: wall parent CV -> list of line indices ---*/ - unordered_map> parent_to_lines; - parent_to_lines.reserve(lines.size()); - for (unsigned long li = 0; li < lines.size(); ++li) { - const auto& L = lines[li]; - if (L.empty()) continue; - const auto idx2 = 1 + 2 * pair_idx + 1; - if (L.size() <= idx2) continue; // no pair at this stage - const auto pW = fine_grid->nodes->GetParent_CV(L[0]); - parent_to_lines[pW].push_back(li); + /*--- A column may take a node only if it is free and carries no condition of its own. ---*/ + auto admissible = [&](unsigned long jPoint) { + return (columnOf[jPoint] == NO_COLUMN) && fine_grid->nodes->GetDomain(jPoint) && + !fine_grid->nodes->GetAgglomerate(jPoint) && !onPhysBoundary[jPoint] && !onPeriodic[jPoint] && + !mixedBC[jPoint] && GeometricalCheck(jPoint, fine_grid, config); + }; + + /*--- The SEND_RECEIVE marker pairs, and where each halo node sits in the flat exchange buffer. + * A handover travels the opposite way to the usual exchange. ---*/ + struct CHandoverPair { + unsigned short markerS, markerR; + int send_to, receive_from; + unsigned long nVertexS, nVertexR, offS, offR; + }; + vector handPairs; + unsigned long nSendTotal = 0, nRecvTotal = 0; + for (auto iMarker = 0u; iMarker < config->GetnMarker_All(); iMarker++) { + if (!((config->GetMarker_All_KindBC(iMarker) == SEND_RECEIVE) && (config->GetMarker_All_SendRecv(iMarker) > 0))) + continue; + CHandoverPair hp; + hp.markerS = iMarker; + hp.markerR = iMarker + 1; + hp.send_to = config->GetMarker_All_SendRecv(hp.markerS) - 1; + hp.receive_from = abs(config->GetMarker_All_SendRecv(hp.markerR)) - 1; + hp.nVertexS = fine_grid->nVertex[hp.markerS]; + hp.nVertexR = fine_grid->nVertex[hp.markerR]; + hp.offS = nSendTotal; + hp.offR = nRecvTotal; + nSendTotal += hp.nVertexS; + nRecvTotal += hp.nVertexR; + handPairs.push_back(hp); + } + + /*--- Where a halo node sits in the flat receive buffer, and which pair owns each slot. The + * vertex within the pair is the slot less that pair's offset. ---*/ + vector haloSlot(nPointFine, -1); + vector pairOfSlot(nRecvTotal, 0); + for (auto iPair = 0ul; iPair < handPairs.size(); ++iPair) { + const auto& hp = handPairs[iPair]; + for (auto iVertex = 0ul; iVertex < hp.nVertexR; iVertex++) { + const auto iPoint = fine_grid->vertex[hp.markerR][iVertex]->GetNode(); + haloSlot[iPoint] = static_cast(hp.offR + iVertex); + pairOfSlot[hp.offR + iVertex] = static_cast(iPair); } + } - vector line_processed(lines.size(), 0); + /*--- Summed over all ranks for the report. ---*/ + enum { + P_COLUMNS, + P_SEEDS, + P_CVS, + P_COVERED, + P_SEED_CURV, + P_HANDED, + P_ADOPTED, + P_DROPPED, + P_PATCH1, + P_PATCH2, + P_PATCH3, + P_PATCH4, + P_COUNT + }; + unsigned long ct[P_COUNT] = {0}; + ct[P_SEEDS] = seeds.node.size(); + ct[P_SEED_CURV] = seeds.nRefusedCurvature; + + vector candidates, haloWanted, distinct, faceAhead, faceScratch; + vector> stepDir, haloStep; + vector haloClaim(nPointFine, NO_COLUMN); + vector tagOut(nRecvTotal, 0), tagIn(nSendTotal, 0); + /*--- The direction a handed over column travels. It only steers discrete choices and is never + * differentiated, so it crosses as a passive type. ---*/ + using CPassiveMPI = SelectMPIWrapper::W; + vector dirOut(nRecvTotal * nDim, 0.0), dirIn(nSendTotal * nDim, 0.0); + + /*--- One tier is paved out everywhere before the next starts, so an inherited column belongs to + * the tier that is running. ---*/ + constexpr char N_TIER = 3; + vector active; + for (char tier = 0; tier < N_TIER; ++tier) { + /*--- The columns of this tier still advancing, in seed order. A column that stops drops out at + * the end of the round, so a deep mesh does not rescan the ones that finished early. ---*/ + active.clear(); + for (auto iColumn : order) + if (tierOf[iColumn] == tier) { + alive[iColumn] = !layer[iColumn].empty(); + if (alive[iColumn]) active.push_back(iColumn); + } - /*--- A) Cross-line merges: parents with multiple lines ---*/ - for (auto& [parent, line_ids] : parent_to_lines) { - if (line_ids.size() < 2) continue; + /*--- Advance every column as far as it goes here, then offer the ones an interface stopped. ---*/ + for (;;) { + for (unsigned long iRound = 1;; ++iRound) { + bool advanced = false; + + for (auto iColumn : active) { + if (!alive[iColumn]) continue; + const auto width = layer[iColumn].size(); + + /*--- Successors beyond the interface are tracked apart: this rank cannot claim them, + * only offer the column to their owner. ---*/ + candidates.clear(); + haloWanted.clear(); + haloStep.clear(); + stepDir.clear(); + + /*--- While the primal grid still carries the column, the layer ahead is the far face of + * the element it stands in, so the mesh names it and nothing is chosen. ---*/ + bool walked = false; + if (walkOf[iColumn].elem != NO_ELEM) { + const auto iElem = walkOf[iColumn].elem; + const auto jFace = OppositeFace(fine_grid->elem[iElem]->GetVTK_Type(), walkOf[iColumn].face); + if (jFace != NO_FACE) { + FaceNodes(fine_grid, iElem, jFace, faceAhead); + if (faceAhead.size() == width) { + size_t nFree = 0, nHalo = 0; + for (auto jPoint : faceAhead) { + if (admissible(jPoint)) + nFree++; + else if (!fine_grid->nodes->GetDomain(jPoint) && (haloSlot[jPoint] >= 0) && + (haloClaim[jPoint] == NO_COLUMN)) + nHalo++; + } - for (size_t k = 0; k + 1 < line_ids.size(); k += 2) { - const auto li1 = line_ids[k]; - const auto li2 = line_ids[k + 1]; - if (line_processed[li1] || line_processed[li2]) continue; + /*--- One step for the whole layer, which steers it on if the strip runs out. ---*/ + std::array step{}; + for (auto jPoint : faceAhead) + for (unsigned short d = 0; d < nDim; ++d) + step[d] += fine_grid->nodes->GetCoord(jPoint, d) / su2double(width); + for (auto iPoint : layer[iColumn]) + for (unsigned short d = 0; d < nDim; ++d) + step[d] -= fine_grid->nodes->GetCoord(iPoint, d) / su2double(width); + const su2double len = GeometryToolbox::Norm(nDim, step.data()); + if (len > 0.0) + for (unsigned short d = 0; d < nDim; ++d) step[d] /= len; + + if (nFree == width) { + candidates = faceAhead; + stepDir.assign(width, step); + const auto jElem = fine_grid->elem[iElem]->GetNeighbor_Elements(jFace); + walkOf[iColumn] = {NO_ELEM, NO_FACE}; + if (jElem >= 0) { + const auto kFace = LocalFace(fine_grid, jElem, faceAhead, faceScratch); + if (kFace != NO_FACE) walkOf[iColumn] = {static_cast(jElem), kFace}; + } + walked = true; + } else if (nHalo == width) { + haloWanted = faceAhead; + haloStep.assign(width, step); + walked = true; + } + } + } + } - const auto& L1 = lines[li1]; - const auto& L2 = lines[li2]; - const auto idx1 = 1 + 2 * pair_idx; - const auto idx2 = idx1 + 1; - if (L1.size() <= idx2 || L2.size() <= idx2) continue; + /*--- Off the strip the column carries on by the way it was going. ---*/ + if (!walked) walkOf[iColumn] = {NO_ELEM, NO_FACE}; + + if (!walked) + for (size_t k = 0; k < layer[iColumn].size(); ++k) { + const auto iPoint = layer[iColumn][k]; + const auto& marching = dirOf[iColumn][k]; + + /*--- Where this node goes is decided before whether it may: the neighbour that best + * carries on the way it was travelling, and only that one is then tested. ---*/ + auto best = NO_COLUMN; + su2double bestAlign = -2.0; + std::array bestStep{}; + + for (auto iNeigh = 0u; iNeigh < fine_grid->nodes->GetnPoint(iPoint); ++iNeigh) { + const auto jPoint = fine_grid->nodes->GetPoint(iPoint, iNeigh); + + su2double step[MAXNDIM] = {0.0}; + GeometryToolbox::Distance(nDim, fine_grid->nodes->GetCoord(jPoint), fine_grid->nodes->GetCoord(iPoint), + step); + const su2double len = GeometryToolbox::Norm(nDim, step); + if (len <= 0.0) continue; + for (unsigned short d = 0; d < nDim; ++d) step[d] /= len; + + const su2double align = GeometryToolbox::DotProduct(nDim, step, marching.data()); + if (align > bestAlign) { + bestAlign = align; + best = jPoint; + for (unsigned short d = 0; d < nDim; ++d) bestStep[d] = step[d]; + } + } - const auto a = L1[idx1], b = L1[idx2]; - const auto c = L2[idx1], d = L2[idx2]; + if (best == NO_COLUMN) continue; - /*--- Skip if any node is already claimed ---*/ - if (fine_grid->nodes->GetAgglomerate(a) || fine_grid->nodes->GetAgglomerate(b) || - fine_grid->nodes->GetAgglomerate(c) || fine_grid->nodes->GetAgglomerate(d)) - continue; - if (reserved[a] || reserved[b] || reserved[c] || reserved[d]) continue; + if (admissible(best)) { + candidates.push_back(best); + stepDir.push_back(bestStep); + } else if (!fine_grid->nodes->GetDomain(best) && (haloSlot[best] >= 0) && + (haloClaim[best] == NO_COLUMN)) { + haloWanted.push_back(best); + haloStep.push_back(bestStep); + } + } - /*--- Geometrical quality check ---*/ - if (!GeometricalCheck(a, fine_grid, config) || !GeometricalCheck(b, fine_grid, config) || - !GeometricalCheck(c, fine_grid, config) || !GeometricalCheck(d, fine_grid, config)) - continue; + /*--- A column advances only onto a whole layer of its own width, one successor per node + * and no two of them the same. ---*/ + auto complete = [&](vector& set) { + if (set.size() != width) return false; + distinct = set; + std::sort(distinct.begin(), distinct.end()); + distinct.erase(std::unique(distinct.begin(), distinct.end()), distinct.end()); + if (distinct.size() != width) return false; + return true; + }; + + if (complete(candidates)) { + for (auto jPoint : candidates) { + columnOf[jPoint] = iColumn; + layerOf[jPoint] = iRound; + } + depthOf[iColumn] = iRound; + layer[iColumn] = candidates; + dirOf[iColumn] = stepDir; + advanced = true; + continue; + } + + /*--- Nothing left here. If the whole layer wants to step across an interface, offer the + * column to the owner of that mesh; a layer split by the interface is let go. ---*/ + alive[iColumn] = 0; + if ((size > 1) && complete(haloWanted)) { + /*--- An offer is named by the lowest interface position it covers, which both ranks + * read off the same matched vertex lists. ---*/ + for (auto jPoint : haloWanted) haloClaim[jPoint] = iColumn; + for (auto k = 0ul; k < haloWanted.size(); ++k) + for (unsigned short d = 0; d < nDim; ++d) + dirOut[haloSlot[haloWanted[k]] * nDim + d] = SU2_TYPE::GetValue(haloStep[k][d]); + + for (auto iPair = 0ul; iPair < handPairs.size(); ++iPair) { + auto tag = std::numeric_limits::max(); + for (auto jPoint : haloWanted) + if (pairOfSlot[haloSlot[jPoint]] == iPair) + tag = std::min(tag, static_cast(haloSlot[jPoint]) - handPairs[iPair].offR); + if (tag == std::numeric_limits::max()) continue; + + tag += 1; /*--- Zero means no offer. ---*/ + for (auto jPoint : haloWanted) + if (pairOfSlot[haloSlot[jPoint]] == iPair) tagOut[haloSlot[jPoint]] = tag; + ct[P_HANDED]++; + } + } + } + + active.erase( + std::remove_if(active.begin(), active.end(), [&](unsigned long iColumn) { return !alive[iColumn]; }), + active.end()); + if (!advanced) break; + } + + if (size <= 1) break; - /*--- Guard against duplicate indices ---*/ - if (a == b || a == c || a == d || b == c || b == d || c == d) { - for (auto other_li : line_ids) line_processed[other_li] = 1; + /*--- Every rank reaches this exchange and the collective that follows it. ---*/ + for (const auto& hp : handPairs) { + SU2_MPI::Sendrecv(tagOut.data() + hp.offR, hp.nVertexR, MPI_UNSIGNED_LONG, hp.receive_from, 0, + tagIn.data() + hp.offS, hp.nVertexS, MPI_UNSIGNED_LONG, hp.send_to, 0, SU2_MPI::GetComm(), + MPI_STATUS_IGNORE); + CPassiveMPI::Sendrecv(dirOut.data() + hp.offR * nDim, hp.nVertexR * nDim, MPI_DOUBLE, hp.receive_from, 1, + dirIn.data() + hp.offS * nDim, hp.nVertexS * nDim, MPI_DOUBLE, hp.send_to, 1, + SU2_MPI::GetComm(), MPI_STATUS_IGNORE); + } + + /*--- Grouping the arrivals by tag rebuilds the footprint the sender stood on. The map orders + * the tags, so every rank adopts in the same order. ---*/ + map, vector>> adopted; + for (auto iPair = 0ul; iPair < handPairs.size(); ++iPair) { + const auto& hp = handPairs[iPair]; + for (auto iVertex = 0ul; iVertex < hp.nVertexS; iVertex++) { + const auto tag = tagIn[hp.offS + iVertex]; + if (tag != 0) + adopted[{iPair, tag}].push_back({fine_grid->vertex[hp.markerS][iVertex]->GetNode(), hp.offS + iVertex}); + } + } + + unsigned long nAdopted = 0; + vector group; + vector> inheritedDir; + for (auto& item : adopted) { + auto& arrivals = item.second; + std::sort(arrivals.begin(), arrivals.end()); + arrivals.erase(std::unique(arrivals.begin(), arrivals.end(), + [](const std::pair& a, + const std::pair& b) { return a.first == b.first; }), + arrivals.end()); + + group.clear(); + for (const auto& arrival : arrivals) group.push_back(arrival.first); + + /*--- The mesh may have been taken since the offer was made, and a footprint is adopted whole + * or not at all. ---*/ + bool free = !group.empty(); + for (auto iPoint : group) free = free && admissible(iPoint); + if (!free) { + ct[P_DROPPED]++; continue; } - /*--- Create 4-child coarse CV ---*/ - fine_grid->nodes->SetParent_CV(a, Index_CoarseCV); - nodes->SetChildren_CV(Index_CoarseCV, 0, a); - fine_grid->nodes->SetParent_CV(b, Index_CoarseCV); - nodes->SetChildren_CV(Index_CoarseCV, 1, b); - fine_grid->nodes->SetParent_CV(c, Index_CoarseCV); - nodes->SetChildren_CV(Index_CoarseCV, 2, c); - fine_grid->nodes->SetParent_CV(d, Index_CoarseCV); - nodes->SetChildren_CV(Index_CoarseCV, 3, d); - nodes->SetnChildren_CV(Index_CoarseCV, 4); - - reserved[a] = reserved[b] = reserved[c] = reserved[d] = 1; - MGQueue_InnerCV.RemoveCV(a); - MGQueue_InnerCV.RemoveCV(b); - MGQueue_InnerCV.RemoveCV(c); - MGQueue_InnerCV.RemoveCV(d); + /*--- The column keeps travelling the way the rank that offered it was going. ---*/ + inheritedDir.clear(); + for (const auto& arrival : arrivals) { + std::array dir{}; + for (unsigned short d = 0; d < nDim; ++d) dir[d] = dirIn[arrival.second * nDim + d]; + inheritedDir.push_back(dir); + } - Index_CoarseCV++; - line_processed[li1] = line_processed[li2] = 1; - for (auto other_li : line_ids) - if (other_li != li1 && other_li != li2) line_processed[other_li] = 1; - any_work = true; + /*--- Pick the strip up again on this side: of the two elements holding the arriving face, + * the column enters the one ahead of it. ---*/ + CWalkState state{NO_ELEM, NO_FACE}; + if (HasElements(fine_grid)) { + faceAhead = group; + std::sort(faceAhead.begin(), faceAhead.end()); + su2double faceCentre[MAXNDIM] = {0.0}; + for (auto iPoint : faceAhead) + for (unsigned short d = 0; d < nDim; ++d) + faceCentre[d] += fine_grid->nodes->GetCoord(iPoint, d) / su2double(faceAhead.size()); + + for (auto iElem = 0u; iElem < fine_grid->nodes->GetnElem(faceAhead.front()); ++iElem) { + const auto jElem = fine_grid->nodes->GetElem(faceAhead.front(), iElem); + const auto jFace = LocalFace(fine_grid, jElem, faceAhead, faceScratch); + if (jFace == NO_FACE) continue; + if (OppositeFace(fine_grid->elem[jElem]->GetVTK_Type(), jFace) == NO_FACE) continue; + + const auto nNode = fine_grid->elem[jElem]->GetnNodes(); + su2double ahead = 0.0; + for (unsigned short d = 0; d < nDim; ++d) { + su2double centre = 0.0; + for (unsigned short k = 0; k < nNode; ++k) + centre += fine_grid->nodes->GetCoord(fine_grid->elem[jElem]->GetNode(k), d) / su2double(nNode); + ahead += (centre - faceCentre[d]) * inheritedDir.front()[d]; + } + if (ahead > 0.0) { + state = {jElem, jFace}; + break; + } + } + } + + const auto iColumn = layer.size(); + for (auto iPoint : group) { + columnOf[iPoint] = iColumn; + layerOf[iPoint] = 0; + } + layer.push_back(group); + walkOf.push_back(state); + dirOf.push_back(inheritedDir); + depthOf.push_back(0); + alive.push_back(1); + isSeeded.push_back(0); + tierOf.push_back(tier); + order.push_back(iColumn); + active.push_back(iColumn); + nAdopted++; + ct[P_ADOPTED]++; } + + std::fill(tagOut.begin(), tagOut.end(), 0); + std::fill(tagIn.begin(), tagIn.end(), 0); + std::fill(dirOut.begin(), dirOut.end(), 0.0); + std::fill(dirIn.begin(), dirIn.end(), 0.0); + std::fill(haloClaim.begin(), haloClaim.end(), NO_COLUMN); + + unsigned long nAdoptedGlobal = 0; + SU2_MPI::Allreduce(&nAdopted, &nAdoptedGlobal, 1, MPI_UNSIGNED_LONG, MPI_SUM, SU2_MPI::GetComm()); + if (nAdoptedGlobal == 0) break; } + } - /*--- B) Single-line 2-child merges for remaining lines ---*/ - for (unsigned long li = 0; li < lines.size(); ++li) { - if (line_processed[li]) continue; - const auto& L = lines[li]; - const auto idx1 = 1 + 2 * pair_idx; - const auto idx2 = idx1 + 1; - if (L.size() <= idx2) continue; - - const auto a = L[idx1], b = L[idx2]; - if (fine_grid->nodes->GetAgglomerate(a) || fine_grid->nodes->GetAgglomerate(b)) continue; - if (reserved[a] || reserved[b]) continue; - if (!GeometricalCheck(a, fine_grid, config) || !GeometricalCheck(b, fine_grid, config)) continue; - - /*--- Create 2-child coarse CV ---*/ - fine_grid->nodes->SetParent_CV(a, Index_CoarseCV); - nodes->SetChildren_CV(Index_CoarseCV, 0, a); - fine_grid->nodes->SetParent_CV(b, Index_CoarseCV); - nodes->SetChildren_CV(Index_CoarseCV, 1, b); - nodes->SetnChildren_CV(Index_CoarseCV, 2); - - reserved[a] = reserved[b] = 1; - MGQueue_InnerCV.RemoveCV(a); - MGQueue_InnerCV.RemoveCV(b); + /*--- Gather each column by layer. ---*/ + const auto nColumn = layer.size(); + vector>> byLayer(nColumn); + for (auto iPoint = 0ul; iPoint < nPointFine; ++iPoint) { + const auto iColumn = columnOf[iPoint]; + if (iColumn == NO_COLUMN) continue; + if (byLayer[iColumn].size() <= layerOf[iPoint]) byLayer[iColumn].resize(layerOf[iPoint] + 1); + byLayer[iColumn][layerOf[iPoint]].push_back(iPoint); + } - Index_CoarseCV++; - any_work = true; + auto emitGroup = [&](const vector& group) { + nodes->SetChildren_CV(Index_CoarseCV, group); + for (auto iPoint : group) { + fine_grid->nodes->SetParent_CV(iPoint, Index_CoarseCV); + if (fine_grid->nodes->GetAgglomerate_Indirect(iPoint)) nodes->SetAgglomerate_Indirect(Index_CoarseCV, true); } + nodes->SetnChildren_CV(Index_CoarseCV, static_cast(group.size())); + return Index_CoarseCV++; + }; + + auto minDepth = std::numeric_limits::max(), maxDepth = 0ul; + vector group; + + /*--- Hand a set of nodes out as coarse CVs, each connected and within the size limit. ---*/ + vector inSet(nPointFine, 0); + vector chunk, stack; + auto emitConnected = [&](const vector& set) { + for (auto iPoint : set) inSet[iPoint] = 1; + + for (auto iSeed : set) { + if (!inSet[iSeed]) continue; + chunk.clear(); + stack.assign(1, iSeed); + inSet[iSeed] = 0; + + while (!stack.empty() && (chunk.size() < static_cast(maxAgglomSize))) { + const auto iPoint = stack.back(); + stack.pop_back(); + chunk.push_back(iPoint); + for (auto jPoint : fine_grid->nodes->GetPoints(iPoint)) { + if (!inSet[jPoint]) continue; + if (chunk.size() + stack.size() >= static_cast(maxAgglomSize)) break; + inSet[jPoint] = 0; + stack.push_back(jPoint); + } + } + /*--- Whatever the cell had no room for waits for the next one. ---*/ + for (auto iPoint : stack) inSet[iPoint] = 1; + stack.clear(); - pair_idx++; - if (!any_work) break; + emitGroup(chunk); + ct[P_CVS]++; + ct[P_COVERED] += chunk.size(); + } + }; + + for (auto iColumn = 0ul; iColumn < nColumn; ++iColumn) { + const auto& layers = byLayer[iColumn]; + if (layers.empty() || layers[0].empty()) continue; + + ct[P_COLUMNS]++; + ct[P_PATCH1 + std::min(layers[0].size(), 4) - 1]++; + minDepth = std::min(minDepth, depthOf[iColumn]); + maxDepth = std::max(maxDepth, depthOf[iColumn]); + + auto iLayer = 0ul; + if (isSeeded[iColumn]) { + /*--- The boundary row is a coarse CV of its own, which fixes the footprint above it. ---*/ + const auto baseCV = emitGroup(layers[0]); + ct[P_CVS]++; + ct[P_COVERED] += layers[0].size(); + if (depthOf[iColumn] == 0) neverGrewCV.push_back(baseCV); + iLayer = 1; + } - /*--- Check if any line still has pairs at the next stage ---*/ - bool any_more = false; - for (const auto& L : lines) { - if (L.size() > 1 + 2 * pair_idx + 1) { - any_more = true; - break; + /*--- Above it, consecutive layers are blocked so the coarse cell coarsens by the same ratio + * along the column as the patch does across it. ---*/ + while (iLayer < layers.size()) { + group.clear(); + const auto block = BlockFor(maxAgglomSize, layers[iLayer].size()); + for (auto k = 0ul; (k < block) && (iLayer < layers.size()); ++k) { + if (!group.empty() && (group.size() + layers[iLayer].size() > static_cast(maxAgglomSize))) break; + group.insert(group.end(), layers[iLayer].begin(), layers[iLayer].end()); + iLayer++; + } + /*--- A single layer wider than the limit still has to go somewhere. ---*/ + if (group.empty()) { + group = layers[iLayer]; + iLayer++; } + emitConnected(group); } - if (!any_more) break; } + if (minDepth == std::numeric_limits::max()) minDepth = 0; + + /*--- One line per level, summed over the ranks. Every rank reaches these collectives. ---*/ + unsigned long ctGlobal[P_COUNT] = {0}; + SU2_MPI::Allreduce(ct, ctGlobal, P_COUNT, MPI_UNSIGNED_LONG, MPI_SUM, SU2_MPI::GetComm()); + unsigned long minDepthGlobal = 0, maxDepthGlobal = 0; + SU2_MPI::Allreduce(&minDepth, &minDepthGlobal, 1, MPI_UNSIGNED_LONG, MPI_MIN, SU2_MPI::GetComm()); + SU2_MPI::Allreduce(&maxDepth, &maxDepthGlobal, 1, MPI_UNSIGNED_LONG, MPI_MAX, SU2_MPI::GetComm()); + + if (rank != MASTER_NODE) return ""; + + stringstream out; + out << " MG level " << iMesh << " paving: " << ctGlobal[P_COLUMNS] << " columns from " << ctGlobal[P_SEEDS] + << " seeds, " << ctGlobal[P_CVS] << " CVs covering " << ctGlobal[P_COVERED] << " nodes, depth " << minDepthGlobal + << " to " << maxDepthGlobal << "\n"; + out << " patches 1/2/3/4 wide: " << ctGlobal[P_PATCH1] << "/" << ctGlobal[P_PATCH2] << "/" << ctGlobal[P_PATCH3] + << "/" << ctGlobal[P_PATCH4] << ", " << ctGlobal[P_SEED_CURV] << " seeds refused on curvature"; + if (ctGlobal[P_HANDED] != 0) + out << ", " << ctGlobal[P_HANDED] << " columns offered across a partition, " << ctGlobal[P_ADOPTED] << " adopted, " + << ctGlobal[P_DROPPED] << " dropped"; + out << "\n"; + return out.str(); } diff --git a/Common/src/geometry/CPhysicalGeometry.cpp b/Common/src/geometry/CPhysicalGeometry.cpp index 0f5dbc59afb..6928c2d922b 100644 --- a/Common/src/geometry/CPhysicalGeometry.cpp +++ b/Common/src/geometry/CPhysicalGeometry.cpp @@ -7666,8 +7666,8 @@ void CPhysicalGeometry::ComputeMeshQualityStatistics(const CConfig* config) { /*--- Compute the metrics with a final loop over the vertices. Also compute the local min and max values here for reporting. ---*/ - su2double orthoMin = 1.e6, arMin = 1.e6, vrMin = 1.e6; - su2double orthoMax = 0.0, arMax = 0.0, vrMax = 0.0; + su2double orthoMin = 1.e6, arMin = 1.e6, vrMin = 1.e6, volMin = 1.e6; + su2double orthoMax = 0.0, arMax = 0.0, vrMax = 0.0, volMax = 0.0; for (unsigned long iPoint = 0; iPoint < nPointDomain; iPoint++) { Orthogonality[iPoint] = Orthogonality[iPoint] / SurfaceArea[iPoint]; orthoMin = min(Orthogonality[iPoint], orthoMin); @@ -7680,6 +7680,12 @@ void CPhysicalGeometry::ComputeMeshQualityStatistics(const CConfig* config) { Volume_Ratio[iPoint] = SubVolume_Max[iPoint] / SubVolume_Min[iPoint]; vrMin = min(Volume_Ratio[iPoint], vrMin); vrMax = max(Volume_Ratio[iPoint], vrMax); + + /*--- The dual CV's own volume, not a ratio: a collapsed cell can have a normal aspect + ratio and sub-volume ratio yet still be degenerate in absolute size. ---*/ + const su2double Volume_i = SU2_TYPE::GetValue(nodes->GetVolume(iPoint)); + volMin = min(Volume_i, volMin); + volMax = max(Volume_i, volMax); } /*--- Reduction to find the min and max values globally. ---*/ @@ -7696,6 +7702,10 @@ void CPhysicalGeometry::ComputeMeshQualityStatistics(const CConfig* config) { SU2_MPI::Allreduce(&vrMin, &Global_VR_Min, 1, MPI_DOUBLE, MPI_MIN, SU2_MPI::GetComm()); SU2_MPI::Allreduce(&vrMax, &Global_VR_Max, 1, MPI_DOUBLE, MPI_MAX, SU2_MPI::GetComm()); + su2double Global_Vol_Min, Global_Vol_Max; + SU2_MPI::Allreduce(&volMin, &Global_Vol_Min, 1, MPI_DOUBLE, MPI_MIN, SU2_MPI::GetComm()); + SU2_MPI::Allreduce(&volMax, &Global_Vol_Max, 1, MPI_DOUBLE, MPI_MAX, SU2_MPI::GetComm()); + /*--- Print the summary to the console for the user. ---*/ PrintingToolbox::CTablePrinter MetricsTable(&std::cout); @@ -7707,6 +7717,7 @@ void CPhysicalGeometry::ComputeMeshQualityStatistics(const CConfig* config) { MetricsTable << "Orthogonality Angle (deg.)" << Global_Ortho_Min << Global_Ortho_Max; MetricsTable << "CV Face Area Aspect Ratio" << Global_AR_Min << Global_AR_Max; MetricsTable << "CV Sub-Volume Ratio" << Global_VR_Min << Global_VR_Max; + MetricsTable << "CV Volume" << Global_Vol_Min << Global_Vol_Max; MetricsTable.PrintFooter(); } diff --git a/QuickStart/inv_NACA0012.cfg b/QuickStart/inv_NACA0012.cfg index 8a66537ad51..1ce4f3630b9 100644 --- a/QuickStart/inv_NACA0012.cfg +++ b/QuickStart/inv_NACA0012.cfg @@ -116,10 +116,10 @@ LINEAR_SOLVER= FGMRES LINEAR_SOLVER_PREC= ILU % % Minimum error of the linear solver for implicit formulations -LINEAR_SOLVER_ERROR= 1E-10 +LINEAR_SOLVER_ERROR= 1E-3 % % Max number of iterations of the linear solver for the implicit formulation -LINEAR_SOLVER_ITER= 10 +LINEAR_SOLVER_ITER= 5 % -------------------------- MULTIGRID PARAMETERS -----------------------------% % @@ -130,7 +130,7 @@ MGLEVEL= 3 MGCYCLE= W_CYCLE % % Multi-Grid PreSmoothing Level -MG_PRE_SMOOTH= ( 1, 2, 3, 3 ) +MG_PRE_SMOOTH= ( 1, 2, 2, 2 ) % % Multi-Grid PostSmoothing Level MG_POST_SMOOTH= ( 0, 0, 0, 0 ) diff --git a/SU2_CFD/include/integration/CMultiGridIntegration.hpp b/SU2_CFD/include/integration/CMultiGridIntegration.hpp index eee8c7235fd..d73b4962128 100644 --- a/SU2_CFD/include/integration/CMultiGridIntegration.hpp +++ b/SU2_CFD/include/integration/CMultiGridIntegration.hpp @@ -321,12 +321,17 @@ class CMultiGridIntegration final : public CIntegration { static constexpr int MAX_MG_LEVELS = 10; + /*--- Bounds the fixed-size stack buffers in the restriction and prolongation kernels, + * independently of the CSysMatrix limit of the same name. ---*/ + static constexpr unsigned short MAXNVAR = 25; + static constexpr unsigned short MAXNDIM = 3; + /*--- Early-exit smoothing state (shared across OMP threads via master write + barrier). ---*/ - bool mg_early_exit_flag = false; /*!< \brief Shared flag for early exit across OMP threads. */ + bool mg_early_exit_flag = false; /*!< \brief Shared flag for early exit across OMP threads. */ passivedouble mg_initial_smooth_rms = 0.0; /*!< \brief Initial RMS residual before current smoothing phase (FAS). */ passivedouble mg_prev_smooth_rms = 0.0; /*!< \brief RMS residual from previous smoothing step; used for stagnation detection. */ - passivedouble mg_fine_rms_ema = 0.0; /*!< \brief EMA of fine-grid pre-smooth RMS across cycles; cross-cycle trend signal. */ - passivedouble last_crossCycleRatio = 1.0; /*!< \brief crossCycleRatio from the most recent cycle; stored for display only. */ + passivedouble mg_fine_rms_ema = 0.0; /*!< \brief EMA of fine-grid pre-smooth RMS across cycles; cross-cycle trend signal. */ + passivedouble last_crossCycleRatio = 1.0; /*!< \brief crossCycleRatio from the most recent cycle; stored for display only. */ /*--- Actual iteration counts per MG level, filled each cycle for the compact output summary. ---*/ unsigned short lastPreSmoothIters[MAX_MG_LEVELS+1] = {}; diff --git a/SU2_CFD/src/drivers/CDriver.cpp b/SU2_CFD/src/drivers/CDriver.cpp index b99dfe15378..29fb325fa23 100644 --- a/SU2_CFD/src/drivers/CDriver.cpp +++ b/SU2_CFD/src/drivers/CDriver.cpp @@ -800,11 +800,43 @@ void CDriver::InitializeGeometryFVM(CConfig *config, CGeometry **&geometry) { /*--- Loop over all the new grid ---*/ + /*--- Per level summaries, held back so they do not interleave with the multigrid table. ---*/ + string levelReports; + string volRatioReport; + + /*--- Smallest and largest CV volume on a level and their ratio, reduced over the ranks. A + * diagnostic ratio is not an AD quantity, so it crosses as a passive type. ---*/ + using CPassiveMPI = SelectMPIWrapper::W; + auto volumeRange = [](const CGeometry* grid) { + passivedouble vmin = std::numeric_limits::max(), vmax = 0.0; + for (auto iPoint = 0ul; iPoint < grid->GetnPointDomain(); iPoint++) { + const passivedouble vol = SU2_TYPE::GetValue(grid->nodes->GetVolume(iPoint)); + vmin = std::min(vmin, vol); + vmax = std::max(vmax, vol); + } + std::array range{}; + CPassiveMPI::Allreduce(&vmin, range.data(), 1, MPI_DOUBLE, MPI_MIN, SU2_MPI::GetComm()); + CPassiveMPI::Allreduce(&vmax, range.data() + 1, 1, MPI_DOUBLE, MPI_MAX, SU2_MPI::GetComm()); + range[2] = range[1] / std::max(std::numeric_limits::min(), range[0]); + return range; + }; + + /*--- Agglomeration should not spread the CV volumes far wider than the fine grid already does. + * An absolute limit cannot tell a coarsened mesh from a badly stretched input one. ---*/ + constexpr passivedouble VOL_RATIO_GROWTH_WARN = 10.0; + const passivedouble fineVolRatio = volumeRange(geometry[MESH_0])[2]; + if ((rank == MASTER_NODE) && (config->GetnMGLevels() > 0)) { + stringstream ss; + ss << " MG level 0 CV volume ratio " << fineVolRatio << ", the baseline the levels below are judged against\n"; + volRatioReport += ss.str(); + } + for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { /*--- Create main agglomeration structure ---*/ - geometry[iMGlevel] = new CMultiGridGeometry(geometry[iMGlevel-1], config, iMGlevel); + auto* coarse_grid = new CMultiGridGeometry(geometry[iMGlevel-1], config, iMGlevel); + geometry[iMGlevel] = coarse_grid; /*--- Protect against the situation that we were not able to complete the agglomeration for this level, i.e., there weren't enough points. @@ -815,6 +847,7 @@ void CDriver::InitializeGeometryFVM(CConfig *config, CGeometry **&geometry) { geometry[iMGlevel] = nullptr; break; } + levelReports += coarse_grid->GetLevelReport(); /*--- Compute points surrounding points. ---*/ @@ -828,7 +861,24 @@ void CDriver::InitializeGeometryFVM(CConfig *config, CGeometry **&geometry) { /*--- Create the control volume structures ---*/ geometry[iMGlevel]->SetControlVolume(geometry[iMGlevel-1], ALLOCATE); + + /*--- Every rank reaches the reduction inside volumeRange. ---*/ + { + const auto range = volumeRange(geometry[iMGlevel]); + + if (rank == MASTER_NODE) { + stringstream ss; + ss << " MG level " << iMGlevel << " CV volume: min " << range[0] << ", max " << range[1] << ", ratio " + << range[2] << "\n"; + if (range[2] > VOL_RATIO_GROWTH_WARN * fineVolRatio) + ss << " WARNING: MG level " << iMGlevel << " spreads CV volumes " << range[2] / fineVolRatio + << " times wider than the fine grid does.\n"; + volRatioReport += ss.str(); + } + } + geometry[iMGlevel]->SetBoundControlVolume(geometry[iMGlevel-1], config, ALLOCATE); + geometry[iMGlevel]->SetCoord(geometry[iMGlevel-1]); /*--- Find closest, most normal, neighbor to a surface point ---*/ @@ -841,6 +891,18 @@ void CDriver::InitializeGeometryFVM(CConfig *config, CGeometry **&geometry) { } + if (rank == MASTER_NODE) cout << levelReports << volRatioReport; + + /*--- MG_MIN_MESHSIZE is a floor on the whole level, so the hierarchy does not vary with rank + * count. ---*/ + if ((rank == MASTER_NODE) && (requestedMGlevels > 0)) { + if (config->GetnMGLevels() == 0) + cout << "\nWARNING: no multigrid levels used, lower MG_MIN_MESHSIZE if you want multigrid.\n" << endl; + else + cout << config->GetnMGLevels() << " multigrid levels used, maximum allowed is " << requestedMGlevels + << ". Change MGLEVEL or MG_MIN_MESHSIZE to use a different number." << endl; + } + if (config->GetWrt_MultiGrid()) geometry[MESH_0]->ColorMGLevels(config->GetnMGLevels(), geometry); /*--- For unsteady simulations, initialize the grid volumes diff --git a/SU2_CFD/src/integration/CMultiGridIntegration.cpp b/SU2_CFD/src/integration/CMultiGridIntegration.cpp index fecbf0491b7..607a0915d3c 100644 --- a/SU2_CFD/src/integration/CMultiGridIntegration.cpp +++ b/SU2_CFD/src/integration/CMultiGridIntegration.cpp @@ -34,13 +34,8 @@ namespace { /*!\cond PRIVATE - * Global-trend damping update. Uses the cross-cycle EMA ratio to detect - * long-term divergence or convergence and adjusts both damping factors - * from a single, smooth signal. - * - * crossCycleRatio < LO : SCALE_UP (residual below EMA trend) - * crossCycleRatio >= HI : SCALE_DOWN (residual above EMA trend) - * [LO, HI) : no change (neutral zone) + * Moves both damping factors from the cross-cycle EMA ratio: below LO scale up, + * at or above HI scale down, in between leave them alone. \endcond */ static su2double applyGlobalTrend(su2double factor, passivedouble crossCycleRatio) { constexpr passivedouble SCALE_DOWN = 0.92; @@ -177,8 +172,8 @@ void CMultiGridIntegration::SetCoarseGridCFL(CGeometry ****geometry, CSolver *** CFL_target[lvl] = CFL_target[lvl-1] * scale; } - /*--- Ramp from the CFL the level below handed over at, which it may never have reached its - * target. The coarsest level has none and starts from its own target scaled down once more. ---*/ + /*--- Ramp from the CFL the level below handed over at. The coarsest level has none and starts + * from its own target scaled down once more. ---*/ const passivedouble CFL_handover = (mg_ramp_cfl_start > 0.0) ? mg_ramp_cfl_start : CFL_target[nMGLevels] * CFL_scale[nMGLevels]; @@ -489,8 +484,8 @@ void CMultiGridIntegration::MultiGrid_Iteration(CGeometry ****geometry, END_SU2_OMP_SAFE_GLOBAL_ACCESS } - /*--- Print compact smoothing summary when MG_SMOOTH_OUTPUT= YES. ---*/ - if (mgOptsZone.MG_Smooth_Output) { + /*--- Print compact smoothing summary when MG_SMOOTH_OUTPUT= YES and MGLEVEL > 0. ---*/ + if ((mgOptsZone.MG_Smooth_Output) && (nMGLevels > 0)) { BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS if (SU2_MPI::GetRank() == MASTER_NODE) { @@ -513,8 +508,13 @@ void CMultiGridIntegration::MultiGrid_Iteration(CGeometry ****geometry, return ss.str(); }; + const string eqName = (RunTime_EqSystem == RUNTIME_FLOW_SYS) ? "Flow" : + (RunTime_EqSystem == RUNTIME_TURB_SYS) ? "Turb" : + (RunTime_EqSystem == RUNTIME_SPECIES_SYS) ? "Species" : + (RunTime_EqSystem == RUNTIME_TRANS_SYS) ? "Trans" : "Other"; + PrintingToolbox::CTablePrinter table(&std::cout); - table.AddColumn("Smoother", 13); + table.AddColumn("Smoother [" + eqName + "]", 13 + 7); for (unsigned short i = 0; i <= nMGLevels; ++i) table.AddColumn("Level " + std::to_string(i), 38); table.PrintHeader(); @@ -877,14 +877,17 @@ void CMultiGridIntegration::GetProlongated_Correction(unsigned short RunTime_EqS SU2_ZONE_SCOPED const unsigned short nVar = sol_coarse->GetnVar(); - su2activevector Solution(nVar); + + if (nVar > MAXNVAR) { + SU2_MPI::Error("nVar larger than expected, increase MAXNVAR.", CURRENT_FUNCTION); + } SU2_OMP_FOR_STAT(roundUpDiv(geo_coarse->GetnPointDomain(), omp_get_num_threads())) for (auto Point_Coarse = 0ul; Point_Coarse < geo_coarse->GetnPointDomain(); Point_Coarse++) { - su2double Area_Parent = geo_coarse->nodes->GetVolume(Point_Coarse); + su2double Solution[MAXNVAR] = {0.0}; - Solution = su2double(0); + su2double Area_Parent = geo_coarse->nodes->GetVolume(Point_Coarse); /*--- Accumulate children contributions with stable ordering ---*/ /*--- Process all children in sequential order to ensure deterministic FP summation ---*/ @@ -903,8 +906,7 @@ void CMultiGridIntegration::GetProlongated_Correction(unsigned short RunTime_EqS for (auto iVar = 0u; iVar < nVar; iVar++) Solution[iVar] += Solution_Coarse[iVar]; - for (auto iVar = 0u; iVar < nVar; iVar++) - sol_coarse->GetNodes()->SetSolution_Old(Point_Coarse, Solution.data()); + sol_coarse->GetNodes()->SetSolution_Old(Point_Coarse, Solution); } END_SU2_OMP_FOR @@ -931,16 +933,21 @@ void CMultiGridIntegration::GetProlongated_Correction(unsigned short RunTime_EqS } } - /*--- MPI the set solution old ---*/ + /*--- MPI the set 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 (auto Point_Coarse = 0ul; Point_Coarse < geo_coarse->GetnPointDomain(); Point_Coarse++) { + /*--- Interpolate the coarse-grid correction onto the fine + * grid and store in LinSysRes. ---*/ + + /*--- Halos too: the correction smoother reads them before its first exchange. ---*/ + SU2_OMP_FOR_STAT(roundUpDiv(geo_coarse->GetnPoint(), omp_get_num_threads())) + for (auto Point_Coarse = 0ul; Point_Coarse < geo_coarse->GetnPoint(); Point_Coarse++) { + const auto* Correction = sol_coarse->GetNodes()->GetSolution_Old(Point_Coarse); for (auto iChildren = 0u; iChildren < geo_coarse->nodes->GetnChildren_CV(Point_Coarse); iChildren++) { - auto Point_Fine = geo_coarse->nodes->GetChildren_CV(Point_Coarse, iChildren); - sol_fine->LinSysRes.SetBlock(Point_Fine, sol_coarse->GetNodes()->GetSolution_Old(Point_Coarse)); + const auto Point_Fine = geo_coarse->nodes->GetChildren_CV(Point_Coarse, iChildren); + sol_fine->LinSysRes.SetBlock(Point_Fine, Correction); } } END_SU2_OMP_FOR @@ -969,10 +976,10 @@ void CMultiGridIntegration::SmoothProlongated_Correction(unsigned short RunTime_ for (auto iSmooth = 0u; iSmooth < val_nSmooth; iSmooth++) { - /*--- Loop over all mesh points (sum the residuals of direct neighbors). ---*/ + /*--- Loop over the domain points, exclude halo points ---*/ - SU2_OMP_FOR_STAT(roundUpDiv(geometry->GetnPoint(), omp_get_num_threads())) - for (auto iPoint = 0ul; iPoint < geometry->GetnPoint(); ++iPoint) { + SU2_OMP_FOR_STAT(roundUpDiv(geometry->GetnPointDomain(), omp_get_num_threads())) + for (auto iPoint = 0ul; iPoint < geometry->GetnPointDomain(); ++iPoint) { solver->GetNodes()->SetResidualSumZero(iPoint); @@ -985,10 +992,10 @@ void CMultiGridIntegration::SmoothProlongated_Correction(unsigned short RunTime_ } END_SU2_OMP_FOR - /*--- Loop over all mesh points (update residuals with the neighbor averages). ---*/ + /*--- Loop over the domain points (update residuals with the neighbor averages). ---*/ - SU2_OMP_FOR_STAT(roundUpDiv(geometry->GetnPoint(), omp_get_num_threads())) - for (auto iPoint = 0ul; iPoint < geometry->GetnPoint(); ++iPoint) { + SU2_OMP_FOR_STAT(roundUpDiv(geometry->GetnPointDomain(), omp_get_num_threads())) + for (auto iPoint = 0ul; iPoint < geometry->GetnPointDomain(); ++iPoint) { su2double factor = 1.0/(1.0+val_smooth_coeff*su2double(geometry->nodes->GetnPoint(iPoint))); @@ -1000,12 +1007,13 @@ void CMultiGridIntegration::SmoothProlongated_Correction(unsigned short RunTime_ } END_SU2_OMP_FOR - /*--- Restore original residuals (without average) at boundary points. ---*/ + /*--- Restore original residuals at physical boundary points. ---*/ for (auto iMarker = 0u; iMarker < geometry->GetnMarker(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) != INTERNAL_BOUNDARY) && (config->GetMarker_All_KindBC(iMarker) != NEARFIELD_BOUNDARY) && - (config->GetMarker_All_KindBC(iMarker) != PERIODIC_BOUNDARY)) { + (config->GetMarker_All_KindBC(iMarker) != PERIODIC_BOUNDARY) && + (config->GetMarker_All_KindBC(iMarker) != SEND_RECEIVE)) { SU2_OMP_FOR_STAT(32) for (auto iVertex = 0ul; iVertex < geometry->GetnVertex(iMarker); iVertex++) { @@ -1017,6 +1025,13 @@ void CMultiGridIntegration::SmoothProlongated_Correction(unsigned short RunTime_ } } + /*--- Refresh the halo entries of the correction with the values their owner ranks just + * computed. ---*/ + + SU2_OMP_BARRIER + CSysMatrixComms::Initiate(solver->LinSysRes, geometry, config); + CSysMatrixComms::Complete(solver->LinSysRes, geometry, config); + } /*--- Record final correction norm for debugging output. ---*/ @@ -1171,26 +1186,27 @@ void CMultiGridIntegration::SetForcing_Term(CSolver *sol_fine, CSolver *sol_coar CGeometry *geo_coarse, CConfig *config, unsigned short iMesh) { SU2_ZONE_SCOPED - const su2double *Residual_Fine; - const unsigned short nVar = sol_coarse->GetnVar(); const su2double factor = config->GetDamp_Res_Restric(); - su2activevector Residual(nVar); + if (nVar > MAXNVAR) { + SU2_MPI::Error("nVar larger than expected, increase MAXNVAR.", CURRENT_FUNCTION); + } SU2_OMP_FOR_STAT(roundUpDiv(geo_coarse->GetnPointDomain(), omp_get_num_threads())) for (auto Point_Coarse = 0ul; Point_Coarse < geo_coarse->GetnPointDomain(); Point_Coarse++) { sol_coarse->GetNodes()->SetRes_TruncErrorZero(Point_Coarse); - Residual = su2double(0); + su2double RestrictedDefect[MAXNVAR] = {0.0}; + for (auto iChildren = 0u; iChildren < geo_coarse->nodes->GetnChildren_CV(Point_Coarse); iChildren++) { auto Point_Fine = geo_coarse->nodes->GetChildren_CV(Point_Coarse, iChildren); - Residual_Fine = sol_fine->LinSysRes.GetBlock(Point_Fine); + const su2double* Residual_Fine = sol_fine->LinSysRes.GetBlock(Point_Fine); for (auto iVar = 0u; iVar < nVar; iVar++) - Residual[iVar] += factor * Residual_Fine[iVar]; + RestrictedDefect[iVar] += factor * Residual_Fine[iVar]; } - sol_coarse->GetNodes()->AddRes_TruncError(Point_Coarse, Residual.data()); + sol_coarse->GetNodes()->AddRes_TruncError(Point_Coarse, RestrictedDefect); } END_SU2_OMP_FOR @@ -1289,17 +1305,18 @@ void CMultiGridIntegration::SetRestricted_Gradient(unsigned short RunTime_EqSyst const unsigned short nDim = geo_coarse->GetnDim(); const unsigned short nVar = sol_coarse->GetnVar(); - auto **Gradient = new su2double* [nVar]; - for (auto iVar = 0u; iVar < nVar; iVar++) - Gradient[iVar] = new su2double [nDim]; + if (nVar > MAXNVAR) { + SU2_MPI::Error("nVar larger than expected, increase MAXNVAR.", CURRENT_FUNCTION); + } SU2_OMP_FOR_STAT(roundUpDiv(geo_coarse->GetnPoint(), omp_get_num_threads())) for (auto Point_Coarse = 0ul; Point_Coarse < geo_coarse->GetnPoint(); Point_Coarse++) { - su2double Area_Parent = geo_coarse->nodes->GetVolume(Point_Coarse); - for (auto iVar = 0u; iVar < nVar; iVar++) - for (auto iDim = 0u; iDim < nDim; iDim++) - Gradient[iVar][iDim] = 0.0; + su2double GradientData[MAXNVAR][MAXNDIM] = {{0.0}}; + su2double* Gradient[MAXNVAR]; + for (auto iVar = 0u; iVar < nVar; iVar++) Gradient[iVar] = GradientData[iVar]; + + su2double Area_Parent = geo_coarse->nodes->GetVolume(Point_Coarse); for (auto iChildren = 0u; iChildren < geo_coarse->nodes->GetnChildren_CV(Point_Coarse); iChildren++) { unsigned long Point_Fine = geo_coarse->nodes->GetChildren_CV(Point_Coarse, iChildren); @@ -1314,10 +1331,6 @@ void CMultiGridIntegration::SetRestricted_Gradient(unsigned short RunTime_EqSyst } END_SU2_OMP_FOR - for (auto iVar = 0u; iVar < nVar; iVar++) - delete [] Gradient[iVar]; - delete [] Gradient; - } void CMultiGridIntegration::NonDimensional_Parameters(CGeometry **geometry, CSolver ***solver_container, diff --git a/SU2_CFD/src/integration/CSingleGridIntegration.cpp b/SU2_CFD/src/integration/CSingleGridIntegration.cpp index fab97842048..29c71b2ed36 100644 --- a/SU2_CFD/src/integration/CSingleGridIntegration.cpp +++ b/SU2_CFD/src/integration/CSingleGridIntegration.cpp @@ -49,6 +49,20 @@ void CSingleGridIntegration::SingleGrid_Iteration(CGeometry ****geometry, CSolve CGeometry* geometry_fine = geometry[iZone][iInst][FinestMesh]; CSolver** solvers_fine = solver_container[iZone][iInst][FinestMesh]; + /*--- CFL scaling of turbulence during the warmpup phase if FMG. ---*/ + if ((RunTime_EqSystem == RUNTIME_TURB_SYS) && (FinestMesh != MESH_0)) { + const su2double turbReduction = SU2_TYPE::GetValue(config[iZone]->GetCFLRedCoeff_Turb()); + const su2double turbCFL = SU2_TYPE::GetValue(config[iZone]->GetCFL(FinestMesh)) * turbReduction; + auto* turbSolver = solvers_fine[Solver_Position]; + + SU2_OMP_SAFE_GLOBAL_ACCESS(turbSolver->SetCFL_Local_Stats(turbCFL);) + SU2_OMP_FOR_STAT(roundUpDiv(geometry_fine->GetnPoint(), omp_get_num_threads())) + for (auto iPoint = 0ul; iPoint < geometry_fine->GetnPoint(); ++iPoint) { + turbSolver->GetNodes()->SetLocalCFL(iPoint, turbCFL); + } + END_SU2_OMP_FOR + } + /*--- Preprocessing ---*/ solvers_fine[Solver_Position]->Preprocessing(geometry_fine, solvers_fine, config[iZone], diff --git a/TestCases/cont_adj_euler/naca0012/inv_NACA0012.cfg b/TestCases/cont_adj_euler/naca0012/inv_NACA0012.cfg index b4a5b29c580..a459e69930c 100644 --- a/TestCases/cont_adj_euler/naca0012/inv_NACA0012.cfg +++ b/TestCases/cont_adj_euler/naca0012/inv_NACA0012.cfg @@ -61,8 +61,8 @@ LINEAR_SOLVER_ILU_FILL_IN= 0 % MGLEVEL= 2 MGCYCLE= W_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/cont_adj_euler/naca0012/of_grad_cd_disc.dat.ref b/TestCases/cont_adj_euler/naca0012/of_grad_cd_disc.dat.ref index a18ea246d5b..a48569d6eee 100644 --- a/TestCases/cont_adj_euler/naca0012/of_grad_cd_disc.dat.ref +++ b/TestCases/cont_adj_euler/naca0012/of_grad_cd_disc.dat.ref @@ -1,39 +1,39 @@ VARIABLES="VARIABLE" , "GRADIENT" , "FINDIFF_STEP" - 0 , -9252.48 , 0.001 - 1 , -12069.7 , 0.001 - 2 , -9121.57 , 0.001 - 3 , -4501.43 , 0.001 - 4 , 17.2477 , 0.001 - 5 , 3791.15 , 0.001 - 6 , 6746.92 , 0.001 - 7 , 9074.82 , 0.001 - 8 , 11055.2 , 0.001 - 9 , 12958.1 , 0.001 - 10 , 14976.4 , 0.001 - 11 , 17163.0 , 0.001 - 12 , 19338.7 , 0.001 - 13 , 20908.5 , 0.001 - 14 , 20442.6 , 0.001 - 15 , 14730.6 , 0.001 - 16 , -3146.36 , 0.001 - 17 , -46143.3 , 0.001 - 18 , -121515.0 , 0.001 - 19 , -23126.9 , 0.001 - 20 , -22603.3 , 0.001 - 21 , -15691.7 , 0.001 - 22 , -9459.14 , 0.001 - 23 , -5880.71 , 0.001 - 24 , -4985.65 , 0.001 - 25 , -6039.68 , 0.001 - 26 , -8128.46 , 0.001 - 27 , -10463.5 , 0.001 - 28 , -12519.2 , 0.001 - 29 , -14057.4 , 0.001 - 30 , -15078.1 , 0.001 - 31 , -15707.7 , 0.001 - 32 , -15951.5 , 0.001 - 33 , -15062.1 , 0.001 - 34 , -10170.7 , 0.001 - 35 , 5416.98 , 0.001 - 36 , 40795.0 , 0.001 - 37 , 88620.5 , 0.001 + 0 , -10689.5 , 0.001 + 1 , -12144.6 , 0.001 + 2 , -8762.05 , 0.001 + 3 , -4451.56 , 0.001 + 4 , -630.073 , 0.001 + 5 , 2322.33 , 0.001 + 6 , 4481.78 , 0.001 + 7 , 6108.15 , 0.001 + 8 , 7517.01 , 0.001 + 9 , 9023.9 , 0.001 + 10 , 10920.9 , 0.001 + 11 , 13461.1 , 0.001 + 12 , 16829.3 , 0.001 + 13 , 21052.3 , 0.001 + 14 , 25706.8 , 0.001 + 15 , 28993.6 , 0.001 + 16 , 24856.4 , 0.001 + 17 , -5567.38 , 0.001 + 18 , -106217.0 , 0.001 + 19 , -21943.0 , 0.001 + 20 , -19777.3 , 0.001 + 21 , -12602.0 , 0.001 + 22 , -6567.33 , 0.001 + 23 , -3158.11 , 0.001 + 24 , -2237.28 , 0.001 + 25 , -3090.39 , 0.001 + 26 , -4911.81 , 0.001 + 27 , -7053.43 , 0.001 + 28 , -9138.62 , 0.001 + 29 , -11090.4 , 0.001 + 30 , -13107.0 , 0.001 + 31 , -15592.1 , 0.001 + 32 , -18965.1 , 0.001 + 33 , -23083.3 , 0.001 + 34 , -25736.6 , 0.001 + 35 , -19628.7 , 0.001 + 36 , 12122.8 , 0.001 + 37 , 91322.0 , 0.001 diff --git a/TestCases/cont_adj_euler/naca0012/of_grad_directdiff.dat.ref b/TestCases/cont_adj_euler/naca0012/of_grad_directdiff.dat.ref index 7db911616f7..c87c1c9a2a4 100644 --- a/TestCases/cont_adj_euler/naca0012/of_grad_directdiff.dat.ref +++ b/TestCases/cont_adj_euler/naca0012/of_grad_directdiff.dat.ref @@ -1,4 +1,4 @@ VARIABLES="VARIABLE" , "DRAG" , "EFFICIENCY" , "FORCE_X" , "FORCE_Y" , "FORCE_Z" , "LIFT" , "MOMENT_X" , "MOMENT_Y" , "MOMENT_Z" , "SIDEFORCE" - 0 , 0.2688089461 , -21.61711857 , 0.3003183821 , -1.441124643 , 0.0 , -1.447333105 , 0.0 , 0.0 , 0.3977552572 , 0.0 - 1 , 0.5278545669 , -37.13677946 , 0.580192762 , -2.392867291 , 0.0 , -2.404954692 , 0.0 , 0.0 , 0.1526764135 , 0.0 - 2 , 0.7714722803 , -44.76622728 , 0.8308940915 , -2.714847262 , 0.0 , -2.732327061 , 0.0 , 0.0 , -0.1348424792 , 0.0 + 0 , -0.4704786435 , -33.40446141 , -0.3888715474 , -3.745132593 , 0.0 , -3.735758164 , 0.0 , 0.0 , 0.4834798526 , 0.0 + 1 , 0.412031843 , -39.78218403 , 0.4880368175 , -3.47876392 , 0.0 , -3.488582535 , 0.0 , 0.0 , 0.2021305183 , 0.0 + 2 , 0.8908446367 , -37.475187 , 0.9514902759 , -2.769632304 , 0.0 , -2.789729858 , 0.0 , 0.0 , -0.1182204408 , 0.0 diff --git a/TestCases/cont_adj_euler/wedge/inv_wedge_ROE.cfg b/TestCases/cont_adj_euler/wedge/inv_wedge_ROE.cfg index e3060e2ff84..5df0df92717 100644 --- a/TestCases/cont_adj_euler/wedge/inv_wedge_ROE.cfg +++ b/TestCases/cont_adj_euler/wedge/inv_wedge_ROE.cfg @@ -56,8 +56,8 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/cont_adj_euler/wedge/inv_wedge_ROE_multiobj.cfg b/TestCases/cont_adj_euler/wedge/inv_wedge_ROE_multiobj.cfg index 31e95954953..f5164a6a85d 100644 --- a/TestCases/cont_adj_euler/wedge/inv_wedge_ROE_multiobj.cfg +++ b/TestCases/cont_adj_euler/wedge/inv_wedge_ROE_multiobj.cfg @@ -60,8 +60,8 @@ LINEAR_SOLVER_ILU_FILL_IN= 0 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/cont_adj_euler/wedge/of_grad_combo.dat.ref b/TestCases/cont_adj_euler/wedge/of_grad_combo.dat.ref index 17f951cf4f5..916efa61b3c 100644 --- a/TestCases/cont_adj_euler/wedge/of_grad_combo.dat.ref +++ b/TestCases/cont_adj_euler/wedge/of_grad_combo.dat.ref @@ -1,5 +1,5 @@ VARIABLES="VARIABLE" , "GRADIENT" , "FINDIFF_STEP" - 0 , 0.00701908 , 0.0001 - 1 , 0.00485645 , 0.0001 - 2 , 0.002445 , 0.0001 - 3 , 0.000872591 , 0.0001 + 0 , 0.00702689 , 0.0001 + 1 , 0.00485994 , 0.0001 + 2 , 0.0024459 , 0.0001 + 3 , 0.000872721 , 0.0001 diff --git a/TestCases/cont_adj_navierstokes/cylinder/lam_cylinder.cfg b/TestCases/cont_adj_navierstokes/cylinder/lam_cylinder.cfg index b2ab1d7e6f8..69c42c4b273 100644 --- a/TestCases/cont_adj_navierstokes/cylinder/lam_cylinder.cfg +++ b/TestCases/cont_adj_navierstokes/cylinder/lam_cylinder.cfg @@ -60,8 +60,8 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/cont_adj_rans/oneram6/turb_ONERAM6.cfg b/TestCases/cont_adj_rans/oneram6/turb_ONERAM6.cfg index bbb03a5fc9e..b367bf3fcc8 100644 --- a/TestCases/cont_adj_rans/oneram6/turb_ONERAM6.cfg +++ b/TestCases/cont_adj_rans/oneram6/turb_ONERAM6.cfg @@ -61,8 +61,8 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/cont_adj_rans/rae2822/turb_SA_RAE2822.cfg b/TestCases/cont_adj_rans/rae2822/turb_SA_RAE2822.cfg index 5afab7ac9a2..68cbeb08673 100644 --- a/TestCases/cont_adj_rans/rae2822/turb_SA_RAE2822.cfg +++ b/TestCases/cont_adj_rans/rae2822/turb_SA_RAE2822.cfg @@ -55,8 +55,8 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/disc_adj_euler/arina2k/Arina2KRS.cfg b/TestCases/disc_adj_euler/arina2k/Arina2KRS.cfg index 80771a1b2be..50c181745b6 100644 --- a/TestCases/disc_adj_euler/arina2k/Arina2KRS.cfg +++ b/TestCases/disc_adj_euler/arina2k/Arina2KRS.cfg @@ -109,8 +109,8 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/disc_adj_euler/naca0012_pitching/inv_NACA0012_pitching.cfg b/TestCases/disc_adj_euler/naca0012_pitching/inv_NACA0012_pitching.cfg index 84bd700d982..364b372e558 100644 --- a/TestCases/disc_adj_euler/naca0012_pitching/inv_NACA0012_pitching.cfg +++ b/TestCases/disc_adj_euler/naca0012_pitching/inv_NACA0012_pitching.cfg @@ -74,8 +74,8 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/disc_adj_euler/naca0012_pitching_def/inv_NACA0012_pitching_deform.cfg b/TestCases/disc_adj_euler/naca0012_pitching_def/inv_NACA0012_pitching_deform.cfg index 3df91b6f367..42e8ae7f6ce 100644 --- a/TestCases/disc_adj_euler/naca0012_pitching_def/inv_NACA0012_pitching_deform.cfg +++ b/TestCases/disc_adj_euler/naca0012_pitching_def/inv_NACA0012_pitching_deform.cfg @@ -57,8 +57,8 @@ LINEAR_SOLVER_ITER= 3 % -------------------------- MULTIGRID PARAMETERS -----------------------------% MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/disc_adj_euler/naca0012_pitching_def/inv_NACA0012_pitching_deform_ad.cfg b/TestCases/disc_adj_euler/naca0012_pitching_def/inv_NACA0012_pitching_deform_ad.cfg index 2a377323c52..d655ca88395 100644 --- a/TestCases/disc_adj_euler/naca0012_pitching_def/inv_NACA0012_pitching_deform_ad.cfg +++ b/TestCases/disc_adj_euler/naca0012_pitching_def/inv_NACA0012_pitching_deform_ad.cfg @@ -57,8 +57,8 @@ LINEAR_SOLVER_ITER= 3 % -------------------------- MULTIGRID PARAMETERS -----------------------------% MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/euler/CRM/inv_CRM_JST.cfg b/TestCases/euler/CRM/inv_CRM_JST.cfg index 63c749021f2..6d10c6a4aad 100644 --- a/TestCases/euler/CRM/inv_CRM_JST.cfg +++ b/TestCases/euler/CRM/inv_CRM_JST.cfg @@ -43,11 +43,11 @@ MARKER_MONITORING= ( fuselage , Wing , HTP ) % ------------- COMMON PARAMETERS TO DEFINE THE NUMERICAL METHOD --------------% % NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES -CFL_NUMBER= 5.0 +CFL_NUMBER= 1000.0 CFL_ADAPT= NO CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) -EXT_ITER= 99999 +ITER= 1000 LINEAR_SOLVER= FGMRES LINEAR_SOLVER_ERROR= 1E-1 LINEAR_SOLVER_ITER= 3 @@ -55,12 +55,16 @@ LINEAR_SOLVER_ITER= 3 % -------------------------- MULTIGRID PARAMETERS -----------------------------% % MGLEVEL= 3 +MG_MIN_MESHSIZE= 100 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_SMOOTH_OUTPUT= NO +MG_SMOOTH_EARLY_EXIT= NO +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 +MG_IMPLICIT_LINES= YES % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % @@ -102,3 +106,4 @@ GRAD_OBJFUNC_FILENAME= of_grad SURFACE_FILENAME= surface_flow SURFACE_ADJ_FILENAME= surface_adjoint OUTPUT_WRT_FREQ= 50 + diff --git a/TestCases/euler/biparabolic/BIPARABOLIC.cfg b/TestCases/euler/biparabolic/BIPARABOLIC.cfg index 5b932b272bf..572e2a86d04 100644 --- a/TestCases/euler/biparabolic/BIPARABOLIC.cfg +++ b/TestCases/euler/biparabolic/BIPARABOLIC.cfg @@ -56,8 +56,8 @@ EXT_ITER= 99999999 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/euler/channel/inv_channel.cfg b/TestCases/euler/channel/inv_channel.cfg index 5161a04413d..500545a18a8 100644 --- a/TestCases/euler/channel/inv_channel.cfg +++ b/TestCases/euler/channel/inv_channel.cfg @@ -47,29 +47,31 @@ MARKER_MONITORING= ( upper_wall, lower_wall ) % ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% % NUM_METHOD_GRAD= GREEN_GAUSS -CFL_NUMBER= 6.0 +CFL_NUMBER= 1000.0 CFL_ADAPT= NO -CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) +CFL_ADAPT_PARAM= ( 0.9, 1.1, 100.0, 10000., 0.1 ) RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) -EXT_ITER= 999999 +ITER= 2000 % ------------------------ LINEAR SOLVER DEFINITION ---------------------------% % LINEAR_SOLVER= FGMRES LINEAR_SOLVER_PREC= LU_SGS LINEAR_SOLVER_ERROR= 1E-1 -LINEAR_SOLVER_ITER= 3 +LINEAR_SOLVER_ITER= 5 % -------------------------- MULTIGRID PARAMETERS -----------------------------% % MGLEVEL= 3 -MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MGCYCLE= W_CYCLE +MG_SMOOTH_OUTPUT= NO +MG_SMOOTH_EARLY_EXIT= NO +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 - +MG_DAMP_RESTRICTION= 0.80 +MG_DAMP_PROLONGATION= 0.80 +MG_IMPLICIT_LINES= YES % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % CONV_NUM_METHOD_FLOW= JST @@ -79,7 +81,7 @@ TIME_DISCRE_FLOW= EULER_IMPLICIT % --------------------------- CONVERGENCE PARAMETERS --------------------------% % -CONV_RESIDUAL_MINVAL= -12 +CONV_RESIDUAL_MINVAL= -10 CONV_STARTITER= 10 CONV_CAUCHY_ELEMS= 100 CONV_CAUCHY_EPS= 1E-10 @@ -101,3 +103,5 @@ GRAD_OBJFUNC_FILENAME= of_grad SURFACE_FILENAME= surface_flow SURFACE_ADJ_FILENAME= surface_adjoint OUTPUT_WRT_FREQ= 250 +SCREEN_OUTPUT= (INNER_ITER, WALL_TIME, RMS_DENSITY, RMS_MOMENTUM-X, RMS_MOMENTUM-Y, RMS_ENERGY, \ + LINSOL_ITER, LINSOL_RESIDUAL, LIFT, DRAG, AVG_CFL) diff --git a/TestCases/euler/channel/inv_channel_RK.cfg b/TestCases/euler/channel/inv_channel_RK.cfg index 6d44b6ad5e0..f0a487a55f5 100644 --- a/TestCases/euler/channel/inv_channel_RK.cfg +++ b/TestCases/euler/channel/inv_channel_RK.cfg @@ -44,11 +44,11 @@ MARKER_MONITORING= ( upper_wall, lower_wall ) % ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% % NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES -CFL_NUMBER= 1.0 +CFL_NUMBER= 1 CFL_ADAPT= NO -CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) +CFL_ADAPT_PARAM= ( 0.9, 1.1, 1.0, 100.0, 0.1 ) RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) -ITER= 110 +ITER= 1000 LINEAR_SOLVER= BCGSTAB LINEAR_SOLVER_ERROR= 1E-1 LINEAR_SOLVER_ITER= 10 @@ -57,11 +57,11 @@ LINEAR_SOLVER_ITER= 10 % MGLEVEL= 3 MGCYCLE= W_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) -MG_CORRECTION_SMOOTH= ( 4, 4, 4, 4 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) +MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % @@ -94,4 +94,4 @@ GRAD_OBJFUNC_FILENAME= of_grad SURFACE_FILENAME= surface_flow SURFACE_ADJ_FILENAME= surface_adjoint OUTPUT_WRT_FREQ= 250 -SCREEN_OUTPUT = (INNER_ITER, RMS_DENSITY, RMS_ENERGY, LIFT, DRAG) +SCREEN_OUTPUT = (INNER_ITER, RMS_DENSITY, RMS_ENERGY, LIFT, DRAG, AVG_CFL) diff --git a/TestCases/euler/oneram6/inv_ONERAM6.cfg b/TestCases/euler/oneram6/inv_ONERAM6.cfg index 6517b957871..22edf9991ee 100644 --- a/TestCases/euler/oneram6/inv_ONERAM6.cfg +++ b/TestCases/euler/oneram6/inv_ONERAM6.cfg @@ -13,7 +13,7 @@ % SOLVER= EULER MATH_PROBLEM= DIRECT -RESTART_SOL= YES +RESTART_SOL= NO READ_BINARY_RESTART= NO % -------------------- COMPRESSIBLE FREE-STREAM DEFINITION --------------------% @@ -49,15 +49,15 @@ MARKER_DESIGNING = ( WING ) % NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES OBJECTIVE_FUNCTION= DRAG -CFL_NUMBER= 5.0 +CFL_NUMBER= 1000.0 CFL_ADAPT= NO CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) ITER= 99999 LINEAR_SOLVER= FGMRES LINEAR_SOLVER_PREC= LU_SGS -LINEAR_SOLVER_ERROR= 1E-6 -LINEAR_SOLVER_ITER= 2 +LINEAR_SOLVER_ERROR= 1E-1 +LINEAR_SOLVER_ITER= 5 % ----------------------- SLOPE LIMITER DEFINITION ----------------------------% % @@ -69,12 +69,13 @@ SENS_REMOVE_SHARP= YES % -------------------------- MULTIGRID PARAMETERS -----------------------------% % MGLEVEL= 3 -MGCYCLE= W_CYCLE -MG_PRE_SMOOTH= ( 1, 2, 3, 3 ) -MG_POST_SMOOTH= ( 0, 0, 0, 0 ) -MG_CORRECTION_SMOOTH= ( 0, 0, 0, 0 ) -MG_DAMP_RESTRICTION= 0.9 -MG_DAMP_PROLONGATION= 0.9 +MGCYCLE= V_CYCLE +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) +MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 +MG_IMPLICIT_LINES= YES % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % @@ -92,7 +93,7 @@ TIME_DISCRE_ADJFLOW= EULER_IMPLICIT % --------------------------- CONVERGENCE PARAMETERS --------------------------& % CONV_RESIDUAL_MINVAL= -12 -CONV_STARTITER= 25 +CONV_STARTITER= 10 CONV_CAUCHY_ELEMS= 100 CONV_CAUCHY_EPS= 1E-10 diff --git a/TestCases/euler/wedge/inv_wedge_HLLC.cfg b/TestCases/euler/wedge/inv_wedge_HLLC.cfg index 64fb1967366..c89cdbd4b27 100644 --- a/TestCases/euler/wedge/inv_wedge_HLLC.cfg +++ b/TestCases/euler/wedge/inv_wedge_HLLC.cfg @@ -42,7 +42,7 @@ MARKER_MONITORING= ( upper, lower ) % ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% % NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES -CFL_NUMBER= 100.0 +CFL_NUMBER= 500.0 CFL_ADAPT= NO CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) @@ -55,11 +55,12 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 1, 2, 2, 2 ) +MG_POST_SMOOTH= ( 0, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 +MG_IMPLICIT_LINES= YES % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % diff --git a/TestCases/fea_fsi/Airfoil_RBF/configFlow.cfg b/TestCases/fea_fsi/Airfoil_RBF/configFlow.cfg index a21011c6eca..6ac608b5221 100644 --- a/TestCases/fea_fsi/Airfoil_RBF/configFlow.cfg +++ b/TestCases/fea_fsi/Airfoil_RBF/configFlow.cfg @@ -79,8 +79,8 @@ CFL_NUMBER= 10.0 % Multigrid ------------------------------------------------------------ % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/fixed_cl/naca0012/inv_NACA0012.cfg b/TestCases/fixed_cl/naca0012/inv_NACA0012.cfg index b9c7cc06667..ade966ede21 100644 --- a/TestCases/fixed_cl/naca0012/inv_NACA0012.cfg +++ b/TestCases/fixed_cl/naca0012/inv_NACA0012.cfg @@ -69,11 +69,11 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % diff --git a/TestCases/fixed_cl/naca0012/inv_NACA0012_ContAdj.cfg b/TestCases/fixed_cl/naca0012/inv_NACA0012_ContAdj.cfg index fdaf77d4d4c..e0e0df79f06 100644 --- a/TestCases/fixed_cl/naca0012/inv_NACA0012_ContAdj.cfg +++ b/TestCases/fixed_cl/naca0012/inv_NACA0012_ContAdj.cfg @@ -70,8 +70,8 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/hybrid_regression.py b/TestCases/hybrid_regression.py index cb34f9a4852..149f4a92160 100644 --- a/TestCases/hybrid_regression.py +++ b/TestCases/hybrid_regression.py @@ -64,7 +64,7 @@ def main(): channel.cfg_dir = "euler/channel" channel.cfg_file = "inv_channel_RK.cfg" channel.test_iter = 20 - channel.test_vals = [-2.000214, 3.536937, 0.034200, 0.193725] + channel.test_vals = [3.601531, 0.116605, 0.168986, 1.000000] test_list.append(channel) # NACA0012 @@ -72,7 +72,7 @@ def main(): naca0012.cfg_dir = "euler/naca0012" naca0012.cfg_file = "inv_NACA0012_Roe.cfg" naca0012.test_iter = 20 - naca0012.test_vals = [-4.387446, -3.845358, 0.296291, 0.025143] + naca0012.test_vals = [-4.031227, -3.524077, 0.272155, 0.009374] test_list.append(naca0012) # Supersonic wedge @@ -80,7 +80,7 @@ def main(): wedge.cfg_dir = "euler/wedge" wedge.cfg_file = "inv_wedge_HLLC.cfg" wedge.test_iter = 20 - wedge.test_vals = [-3.690258, 2.034169, -0.249531, 0.043953] + wedge.test_vals = [-0.480786, 5.329367, -0.244869, 0.043126] test_list.append(wedge) # ONERA M6 Wing @@ -88,7 +88,7 @@ def main(): oneram6.cfg_dir = "euler/oneram6" oneram6.cfg_file = "inv_ONERAM6.cfg" oneram6.test_iter = 10 - oneram6.test_vals = [0.280803, 0.008625] + oneram6.test_vals = [0.277392, 0.006227] test_list.append(oneram6) # Fixed CL NACA0012 @@ -96,7 +96,7 @@ def main(): fixedCL_naca0012.cfg_dir = "fixed_cl/naca0012" fixedCL_naca0012.cfg_file = "inv_NACA0012.cfg" fixedCL_naca0012.test_iter = 10 - fixedCL_naca0012.test_vals = [-4.010006, 1.521019, 0.300952, 0.019472] + fixedCL_naca0012.test_vals = [-3.943952, 1.585415, 0.300912, 0.019470] test_list.append(fixedCL_naca0012) # HYPERSONIC FLOW PAST BLUNT BODY @@ -116,7 +116,7 @@ def main(): flatplate.cfg_dir = "navierstokes/flatplate" flatplate.cfg_file = "lam_flatplate.cfg" flatplate.test_iter = 100 - flatplate.test_vals = [-6.543292, -1.065161, 0.001196, 0.029390, 2.361500, -2.332100, 0.000000, 0.000000] + flatplate.test_vals = [-8.265203, -2.790380, 0.001084, 0.036280, 2.361500, -2.325300, 0.000000, 0.000000] test_list.append(flatplate) # Laminar cylinder (steady) @@ -124,7 +124,7 @@ def main(): cylinder.cfg_dir = "navierstokes/cylinder" cylinder.cfg_file = "lam_cylinder.cfg" cylinder.test_iter = 25 - cylinder.test_vals = [-8.500691, -3.024888, 0.037975, 1.664042, 0.000000] + cylinder.test_vals = [-8.638753, -3.154563, 0.005584, 1.614194, 0.000000] test_list.append(cylinder) # Laminar cylinder (low Mach correction) @@ -132,7 +132,7 @@ def main(): cylinder_lowmach.cfg_dir = "navierstokes/cylinder" cylinder_lowmach.cfg_file = "cylinder_lowmach.cfg" cylinder_lowmach.test_iter = 25 - cylinder_lowmach.test_vals = [-6.476618, -1.014896, 0.594402, 70.856953, 0.000000] + cylinder_lowmach.test_vals = [-8.730784, -3.268719, 0.318044, 1.770346, 0.000000] cylinder_lowmach.test_vals_aarch64 = [-6.830996, -1.368850, -0.143956, 73.963354, 0] test_list.append(cylinder_lowmach) @@ -149,8 +149,8 @@ def main(): poiseuille_profile.cfg_dir = "navierstokes/poiseuille" poiseuille_profile.cfg_file = "profile_poiseuille.cfg" poiseuille_profile.test_iter = 10 - poiseuille_profile.test_vals = [-12.005123, -7.582375, -0.000000, 2.089953] - poiseuille_profile.test_vals_aarch64 = [-12.009012, -7.262530, -0.000000, 2.089953] + poiseuille_profile.test_vals = [-12.004080, -7.638116, -0.000000, 2.089953] + poiseuille_profile.test_vals_aarch64 = [-12.004276, -7.636719, -0.000000, 2.089953] test_list.append(poiseuille_profile) # 2D Rotational Periodic @@ -170,7 +170,7 @@ def main(): rae2822_sa.cfg_dir = "rans/rae2822" rae2822_sa.cfg_file = "turb_SA_RAE2822.cfg" rae2822_sa.test_iter = 20 - rae2822_sa.test_vals = [-2.190528, -5.335496, 0.383385, 0.077606, 0.000000] + rae2822_sa.test_vals = [-2.639525, -4.027096, 0.792680, 0.020549, 1000.000000] test_list.append(rae2822_sa) # RAE2822 SST @@ -178,7 +178,7 @@ def main(): rae2822_sst.cfg_dir = "rans/rae2822" rae2822_sst.cfg_file = "turb_SST_RAE2822.cfg" rae2822_sst.test_iter = 20 - rae2822_sst.test_vals = [-1.028081, 5.870628, 0.370417, 0.074982, 0.000000] + rae2822_sst.test_vals = [-1.501958, 5.889330, 0.635453, 0.021771, 100.000000] test_list.append(rae2822_sst) # RAE2822 SST_SUST @@ -186,7 +186,7 @@ def main(): rae2822_sst_sust.cfg_dir = "rans/rae2822" rae2822_sst_sust.cfg_file = "turb_SST_SUST_RAE2822.cfg" rae2822_sst_sust.test_iter = 20 - rae2822_sst_sust.test_vals = [-2.487683, 5.870614, 0.370417, 0.074982] + rae2822_sst_sust.test_vals = [-2.465534, 5.844290, 0.496763, 0.041047] test_list.append(rae2822_sst_sust) # Flat plate @@ -194,7 +194,7 @@ def main(): turb_flatplate.cfg_dir = "rans/flatplate" turb_flatplate.cfg_file = "turb_SA_flatplate.cfg" turb_flatplate.test_iter = 20 - turb_flatplate.test_vals = [-4.958328, -7.438303, -0.187472, 0.015052] + turb_flatplate.test_vals = [-0.187373, 0.003723, 10.000000, -1.443902] test_list.append(turb_flatplate) # ONERA M6 Wing @@ -279,7 +279,7 @@ def main(): turb_naca0012_sst_restart_mg.cfg_file = "turb_NACA0012_sst_multigrid_restart.cfg" turb_naca0012_sst_restart_mg.test_iter = 20 turb_naca0012_sst_restart_mg.ntest_vals = 5 - turb_naca0012_sst_restart_mg.test_vals = [-6.589092, -5.057151, 0.830239, -0.008809, 0.078148] + turb_naca0012_sst_restart_mg.test_vals = [-6.551665, -5.057150, 0.830240, -0.008811, 0.078187] test_list.append(turb_naca0012_sst_restart_mg) ############################# @@ -360,7 +360,7 @@ def main(): inc_euler_naca0012.cfg_dir = "incomp_euler/naca0012" inc_euler_naca0012.cfg_file = "incomp_NACA0012.cfg" inc_euler_naca0012.test_iter = 20 - inc_euler_naca0012.test_vals = [-5.858104, -4.937295, 0.519817, 0.008958] + inc_euler_naca0012.test_vals = [-6.668256, -5.851153, 0.531532, 0.008487] test_list.append(inc_euler_naca0012) # NACA0012 Hydrofoil, pressure-based. Exercises the OpenMP path of the Poisson @@ -403,7 +403,7 @@ def main(): inc_nozzle.cfg_dir = "incomp_euler/nozzle" inc_nozzle.cfg_file = "inv_nozzle.cfg" inc_nozzle.test_iter = 20 - inc_nozzle.test_vals = [-6.171116, -5.413059, 0.008862, 0.127559] + inc_nozzle.test_vals = [-6.121917, -5.432144, 0.000056, 0.125551] test_list.append(inc_nozzle) ############################# @@ -415,7 +415,7 @@ def main(): inc_lam_cylinder.cfg_dir = "incomp_navierstokes/cylinder" inc_lam_cylinder.cfg_file = "incomp_cylinder.cfg" inc_lam_cylinder.test_iter = 10 - inc_lam_cylinder.test_vals = [-4.161196, -3.573053, 0.025533, 4.944646] + inc_lam_cylinder.test_vals = [-4.814160, -5.008238, 0.001269, 3.114987] test_list.append(inc_lam_cylinder) # Buoyancy-driven cavity @@ -480,7 +480,7 @@ def main(): cavity.cfg_dir = "moving_wall/cavity" cavity.cfg_file = "lam_cavity.cfg" cavity.test_iter = 25 - cavity.test_vals = [-7.927912, -2.479033, 0.012837, 0.005130] + cavity.test_vals = [-7.887109, -2.429088, 0.013598, 0.005372] test_list.append(cavity) # Spinning cylinder @@ -488,7 +488,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.533970, -2.066690, 1.832252, 1.843016] + spinning_cylinder.test_vals = [-7.614070, -2.155206, 1.804022, 1.893004] spinning_cylinder.test_vals_aarch64 = [-8.008023, -2.611064, 1.497308, 1.487483] test_list.append(spinning_cylinder) @@ -510,7 +510,7 @@ def main(): sine_gust.cfg_dir = "gust" sine_gust.cfg_file = "inv_gust_NACA0012.cfg" sine_gust.test_iter = 5 - sine_gust.test_vals = [-1.977498, 3.481817, -0.010188, -0.004302] + sine_gust.test_vals = [-1.977498, 3.481817, -0.010724, -0.005369] sine_gust.unsteady = True test_list.append(sine_gust) @@ -529,7 +529,7 @@ def main(): gust_mesh_defo.cfg_dir = "gust" gust_mesh_defo.cfg_file = "gust_with_mesh_deformation.cfg" gust_mesh_defo.test_iter = 6 - gust_mesh_defo.test_vals = [-1.844761, 0.001100, -0.000310] + gust_mesh_defo.test_vals = [-1.844761, 0.001290, -0.000316] gust_mesh_defo.unsteady = True gust_mesh_defo.enabled_with_tsan = False test_list.append(gust_mesh_defo) @@ -539,7 +539,7 @@ def main(): aeroelastic.cfg_dir = "aeroelastic" aeroelastic.cfg_file = "aeroelastic_NACA64A010.cfg" aeroelastic.test_iter = 2 - aeroelastic.test_vals = [-1.876631, 4.021073, 0.081270, 0.027580, -0.001642, -0.000127, -1.052233] + aeroelastic.test_vals = [-1.876632, 4.021071, 0.080087, 0.027953, -0.001641, -0.000127, -1.052229] aeroelastic.unsteady = True aeroelastic.enabled_on_cpu_arch = ["x86_64"] # Requires AVX-capable architecture test_list.append(aeroelastic) @@ -567,7 +567,7 @@ def main(): unst_deforming_naca0012.cfg_dir = "disc_adj_euler/naca0012_pitching_def" unst_deforming_naca0012.cfg_file = "inv_NACA0012_pitching_deform.cfg" unst_deforming_naca0012.test_iter = 5 - unst_deforming_naca0012.test_vals = [-3.665299, -3.794240, -3.717018, -3.148592] + unst_deforming_naca0012.test_vals = [-3.666867, -3.796806, -3.719022, -3.150288] unst_deforming_naca0012.unsteady = True unst_deforming_naca0012.enabled_with_tsan = False test_list.append(unst_deforming_naca0012) @@ -580,8 +580,8 @@ def main(): edge_VW = TestCase('edge_VW') edge_VW.cfg_dir = "nicf/edge" edge_VW.cfg_file = "edge_VW.cfg" - edge_VW.test_iter = 30 - edge_VW.test_vals = [-7.124287, -0.922783, -0.000009, 0.000000] + edge_VW.test_iter = 25 + edge_VW.test_vals = [-11.670757, -5.483973, -0.000009, 0.000000] test_list.append(edge_VW) # Rarefaction shock wave edge_PPR @@ -589,7 +589,7 @@ def main(): edge_PPR.cfg_dir = "nicf/edge" edge_PPR.cfg_file = "edge_PPR.cfg" edge_PPR.test_iter = 20 - edge_PPR.test_vals = [-12.028835, -5.863587, -0.000034, 0.000000] + edge_PPR.test_vals = [-12.338051, -6.157966, -0.000034, 0.000000] edge_PPR.test_vals_aarch64 = [ -7.139211, -0.980821, -0.000034, 0.000000] test_list.append(edge_PPR) @@ -711,7 +711,7 @@ def main(): bars_SST_2D.cfg_dir = "sliding_interface/bars_SST_2D" bars_SST_2D.cfg_file = "bars.cfg" bars_SST_2D.test_iter = 13 - bars_SST_2D.test_vals = [13.000000, -0.391571, -1.460869] + bars_SST_2D.test_vals = [13.000000, -0.455981, -1.541069] bars_SST_2D.multizone = True test_list.append(bars_SST_2D) diff --git a/TestCases/hybrid_regression_AD.py b/TestCases/hybrid_regression_AD.py index 6c806175fae..b2086915f9d 100644 --- a/TestCases/hybrid_regression_AD.py +++ b/TestCases/hybrid_regression_AD.py @@ -100,7 +100,7 @@ def main(): discadj_incomp_NACA0012.cfg_dir = "disc_adj_incomp_euler/naca0012" discadj_incomp_NACA0012.cfg_file = "incomp_NACA0012_disc.cfg" discadj_incomp_NACA0012.test_iter = 20 - discadj_incomp_NACA0012.test_vals = [20.000000, -3.122052, -2.290797, 0.000000] + discadj_incomp_NACA0012.test_vals = [20.000000, -3.134641, -2.294877, 0.000000] test_list.append(discadj_incomp_NACA0012) ##################################### diff --git a/TestCases/incomp_euler/naca0012/incomp_NACA0012.cfg b/TestCases/incomp_euler/naca0012/incomp_NACA0012.cfg index 7e1b23e85b1..147b06b9aac 100644 --- a/TestCases/incomp_euler/naca0012/incomp_NACA0012.cfg +++ b/TestCases/incomp_euler/naca0012/incomp_NACA0012.cfg @@ -43,7 +43,7 @@ MARKER_MONITORING= ( airfoil ) % ------------- COMMON PARAMETERS TO DEFINE THE NUMERICAL METHOD --------------% % NUM_METHOD_GRAD= GREEN_GAUSS -CFL_NUMBER= 200.0 +CFL_NUMBER= 1000.0 CFL_ADAPT= NO CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) @@ -61,11 +61,11 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= W_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % diff --git a/TestCases/incomp_euler/naca0012/incomp_pb_NACA0012.cfg b/TestCases/incomp_euler/naca0012/incomp_pb_NACA0012.cfg index 28a632767ef..68af0e94f86 100644 --- a/TestCases/incomp_euler/naca0012/incomp_pb_NACA0012.cfg +++ b/TestCases/incomp_euler/naca0012/incomp_pb_NACA0012.cfg @@ -73,8 +73,8 @@ POISSON_LINEAR_SOLVER_ITER= 1000 % MGLEVEL= 0 MGCYCLE= W_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/incomp_euler/nozzle/inv_nozzle.cfg b/TestCases/incomp_euler/nozzle/inv_nozzle.cfg index b9641ab63de..d1131c92804 100644 --- a/TestCases/incomp_euler/nozzle/inv_nozzle.cfg +++ b/TestCases/incomp_euler/nozzle/inv_nozzle.cfg @@ -46,7 +46,7 @@ MARKER_ANALYZE_AVERAGE = AREA % ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% % NUM_METHOD_GRAD= GREEN_GAUSS -CFL_NUMBER= 500 +CFL_NUMBER= 1000.0 % ------------------------ LINEAR SOLVER DEFINITION ---------------------------% % @@ -59,12 +59,13 @@ LINEAR_SOLVER_ITER= 3 % -------------------------- MULTIGRID PARAMETERS -----------------------------% % MGLEVEL= 3 -MGCYCLE= W_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_MIN_MESHSIZE= 500 +MGCYCLE= V_CYCLE +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 % ----------- SLOPE LIMITER AND DISSIPATION SENSOR DEFINITION -----------------% % diff --git a/TestCases/incomp_navierstokes/cylinder/incomp_cylinder.cfg b/TestCases/incomp_navierstokes/cylinder/incomp_cylinder.cfg index 08ecc2a02ca..a2398fd3c28 100644 --- a/TestCases/incomp_navierstokes/cylinder/incomp_cylinder.cfg +++ b/TestCases/incomp_navierstokes/cylinder/incomp_cylinder.cfg @@ -44,7 +44,7 @@ MARKER_MONITORING= ( cylinder ) % ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% % NUM_METHOD_GRAD= GREEN_GAUSS -CFL_NUMBER= 100.0 +CFL_NUMBER= 1000.0 CFL_ADAPT= NO CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) @@ -55,11 +55,11 @@ VENKAT_LIMITER_COEFF= 0.01 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % diff --git a/TestCases/incomp_navierstokes/cylinder/incomp_pb_cylinder.cfg b/TestCases/incomp_navierstokes/cylinder/incomp_pb_cylinder.cfg index b06b23eb1ed..fdb46dcbdce 100644 --- a/TestCases/incomp_navierstokes/cylinder/incomp_pb_cylinder.cfg +++ b/TestCases/incomp_navierstokes/cylinder/incomp_pb_cylinder.cfg @@ -67,8 +67,8 @@ POISSON_LINEAR_SOLVER_ITER= 1000 % MGLEVEL= 0 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/incomp_navierstokes/sphere/sphere.cfg b/TestCases/incomp_navierstokes/sphere/sphere.cfg index 2f9eef68ff8..5a9b2612aaf 100644 --- a/TestCases/incomp_navierstokes/sphere/sphere.cfg +++ b/TestCases/incomp_navierstokes/sphere/sphere.cfg @@ -66,12 +66,13 @@ LINEAR_SOLVER_ITER= 3 % -------------------------- MULTIGRID PARAMETERS -----------------------------% % MGLEVEL= 3 -MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MGCYCLE= W_CYCLE +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 +MG_IMPLICIT_LINES= YES % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % diff --git a/TestCases/moving_wall/cavity/lam_cavity.cfg b/TestCases/moving_wall/cavity/lam_cavity.cfg index 03831d2122b..2b5215474c9 100644 --- a/TestCases/moving_wall/cavity/lam_cavity.cfg +++ b/TestCases/moving_wall/cavity/lam_cavity.cfg @@ -65,8 +65,8 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 2 MGCYCLE= W_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 1, 1, 1, 1 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/moving_wall/spinning_cylinder/spinning_cylinder.cfg b/TestCases/moving_wall/spinning_cylinder/spinning_cylinder.cfg index c70e86f9714..2bd1df3235d 100644 --- a/TestCases/moving_wall/spinning_cylinder/spinning_cylinder.cfg +++ b/TestCases/moving_wall/spinning_cylinder/spinning_cylinder.cfg @@ -74,8 +74,8 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/multiple_ffd/naca0012/inv_NACA0012_ffd.cfg b/TestCases/multiple_ffd/naca0012/inv_NACA0012_ffd.cfg index f981139fb0c..91e7861d1f8 100644 --- a/TestCases/multiple_ffd/naca0012/inv_NACA0012_ffd.cfg +++ b/TestCases/multiple_ffd/naca0012/inv_NACA0012_ffd.cfg @@ -62,8 +62,8 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/multiple_ffd/naca0012/of_grad_cd.dat.ref b/TestCases/multiple_ffd/naca0012/of_grad_cd.dat.ref index 9f66318faa5..2f2e345e422 100644 --- a/TestCases/multiple_ffd/naca0012/of_grad_cd.dat.ref +++ b/TestCases/multiple_ffd/naca0012/of_grad_cd.dat.ref @@ -1,3 +1,3 @@ VARIABLES="VARIABLE" , "GRADIENT" , "FINDIFF_STEP" - 0 , 0.0518141 , 0.001 - 1 , -0.100128 , 0.001 + 0 , 0.0440381 , 0.001 + 1 , -0.0848429 , 0.001 diff --git a/TestCases/multiple_ffd/naca0012/of_grad_directdiff.dat.ref b/TestCases/multiple_ffd/naca0012/of_grad_directdiff.dat.ref index 13b9e7b640d..ef3b2d9f463 100644 --- a/TestCases/multiple_ffd/naca0012/of_grad_directdiff.dat.ref +++ b/TestCases/multiple_ffd/naca0012/of_grad_directdiff.dat.ref @@ -1,3 +1,3 @@ VARIABLES="VARIABLE" , "DRAG" , "EFFICIENCY" , "FORCE_X" , "FORCE_Y" , "FORCE_Z" , "LIFT" , "MOMENT_X" , "MOMENT_Y" , "MOMENT_Z" , "SIDEFORCE" - 0 , 0.05574220713 , -0.3793750988 , 0.05560191869 , 0.007037405532 , 0.0 , 0.005822781356 , 0.0 , 0.0 , 0.02947622997 , 0.0 - 1 , -0.106175883 , 0.8749922756 , -0.1062584399 , 0.002625280933 , 0.0 , 0.004942671837 , 0.0 , 0.0 , 0.06524923045 , 0.0 + 0 , 0.04790586765 , -0.4797536912 , 0.04825151062 , -0.01531800012 , 0.0 , -0.01636695601 , 0.0 , 0.0 , 0.03036927931 , 0.0 + 1 , -0.09320474204 , 0.3762440542 , -0.0926027588 , -0.02860524743 , 0.0 , -0.02657832162 , 0.0 , 0.0 , 0.06626460628 , 0.0 diff --git a/TestCases/navierstokes/cylinder/cylinder_lowmach.cfg b/TestCases/navierstokes/cylinder/cylinder_lowmach.cfg index 1c175581e3a..402b8c9158b 100644 --- a/TestCases/navierstokes/cylinder/cylinder_lowmach.cfg +++ b/TestCases/navierstokes/cylinder/cylinder_lowmach.cfg @@ -42,7 +42,7 @@ MARKER_MONITORING= ( cylinder ) % ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% % NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES -CFL_NUMBER= 4.0 +CFL_NUMBER= 100.0 CFL_ADAPT= NO CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) @@ -58,12 +58,12 @@ LINEAR_SOLVER_ITER= 3 % -------------------------- MULTIGRID PARAMETERS -----------------------------% % MGLEVEL= 3 -MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MGCYCLE= W_CYCLE +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % diff --git a/TestCases/navierstokes/cylinder/lam_cylinder.cfg b/TestCases/navierstokes/cylinder/lam_cylinder.cfg index 70f8692f64b..95ee6ca4d59 100644 --- a/TestCases/navierstokes/cylinder/lam_cylinder.cfg +++ b/TestCases/navierstokes/cylinder/lam_cylinder.cfg @@ -42,7 +42,7 @@ MARKER_MONITORING= ( cylinder ) % ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% % NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES -CFL_NUMBER= 500.0 +CFL_NUMBER= 10000.0 CFL_ADAPT= NO CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) @@ -59,11 +59,11 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % diff --git a/TestCases/navierstokes/flatplate/lam_flatplate.cfg b/TestCases/navierstokes/flatplate/lam_flatplate.cfg index f213b10a0a7..77c342091f8 100644 --- a/TestCases/navierstokes/flatplate/lam_flatplate.cfg +++ b/TestCases/navierstokes/flatplate/lam_flatplate.cfg @@ -46,7 +46,7 @@ MARKER_ANALYZE= (inlet, outlet) % ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% % NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES -CFL_NUMBER= 1000 +CFL_NUMBER= 10000 CFL_ADAPT= NO % ------------------------ LINEAR SOLVER DEFINITION ---------------------------% @@ -60,11 +60,12 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 +MG_IMPLICIT_LINES= YES % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % diff --git a/TestCases/navierstokes/naca0012/lam_NACA0012.cfg b/TestCases/navierstokes/naca0012/lam_NACA0012.cfg index c6e40834d62..31d55929a98 100644 --- a/TestCases/navierstokes/naca0012/lam_NACA0012.cfg +++ b/TestCases/navierstokes/naca0012/lam_NACA0012.cfg @@ -55,8 +55,8 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/navierstokes/poiseuille/profile_poiseuille.cfg b/TestCases/navierstokes/poiseuille/profile_poiseuille.cfg index 87f72e10bf6..2cca0561a17 100644 --- a/TestCases/navierstokes/poiseuille/profile_poiseuille.cfg +++ b/TestCases/navierstokes/poiseuille/profile_poiseuille.cfg @@ -86,11 +86,11 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % diff --git a/TestCases/nicf/LS89/turb_SA_PR.cfg b/TestCases/nicf/LS89/turb_SA_PR.cfg index fa3f99d7d06..218f82aa896 100644 --- a/TestCases/nicf/LS89/turb_SA_PR.cfg +++ b/TestCases/nicf/LS89/turb_SA_PR.cfg @@ -85,8 +85,8 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/nicf/edge/edge_PPR.cfg b/TestCases/nicf/edge/edge_PPR.cfg index fb4285bd17c..93b1e8c9c5e 100644 --- a/TestCases/nicf/edge/edge_PPR.cfg +++ b/TestCases/nicf/edge/edge_PPR.cfg @@ -84,7 +84,7 @@ TIME_DISCRE_FLOW= EULER_IMPLICIT % --------------------------- CONVERGENCE PARAMETERS --------------------------% % -CONV_RESIDUAL_MINVAL= -12 +CONV_RESIDUAL_MINVAL= -13 CONV_STARTITER= 10 CONV_CAUCHY_ELEMS= 100 CONV_CAUCHY_EPS= 1E-10 diff --git a/TestCases/nicf/edge/edge_VW.cfg b/TestCases/nicf/edge/edge_VW.cfg index eddaf6c02f5..9de0e93a841 100644 --- a/TestCases/nicf/edge/edge_VW.cfg +++ b/TestCases/nicf/edge/edge_VW.cfg @@ -68,11 +68,11 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= W_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 1, 1, 1, 1 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % diff --git a/TestCases/optimization_euler/multiobjective_wedge/inv_wedge_ROE_2surf_1obj.cfg b/TestCases/optimization_euler/multiobjective_wedge/inv_wedge_ROE_2surf_1obj.cfg index fe73206fbd5..af79fb1802e 100644 --- a/TestCases/optimization_euler/multiobjective_wedge/inv_wedge_ROE_2surf_1obj.cfg +++ b/TestCases/optimization_euler/multiobjective_wedge/inv_wedge_ROE_2surf_1obj.cfg @@ -60,8 +60,8 @@ LINEAR_SOLVER_ILU_FILL_IN= 0 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/optimization_euler/multiobjective_wedge/inv_wedge_ROE_multiobj.cfg b/TestCases/optimization_euler/multiobjective_wedge/inv_wedge_ROE_multiobj.cfg index 77bfc365f31..74848bc84ad 100644 --- a/TestCases/optimization_euler/multiobjective_wedge/inv_wedge_ROE_multiobj.cfg +++ b/TestCases/optimization_euler/multiobjective_wedge/inv_wedge_ROE_multiobj.cfg @@ -63,8 +63,8 @@ LINEAR_SOLVER_ILU_FILL_IN= 0 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/optimization_euler/multiobjective_wedge/inv_wedge_ROE_multiobj_1surf.cfg b/TestCases/optimization_euler/multiobjective_wedge/inv_wedge_ROE_multiobj_1surf.cfg index 33a7eb40455..2a9c321e2fe 100644 --- a/TestCases/optimization_euler/multiobjective_wedge/inv_wedge_ROE_multiobj_1surf.cfg +++ b/TestCases/optimization_euler/multiobjective_wedge/inv_wedge_ROE_multiobj_1surf.cfg @@ -61,8 +61,8 @@ LINEAR_SOLVER_ILU_FILL_IN= 0 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/optimization_euler/multiobjective_wedge/inv_wedge_ROE_multiobj_combo.cfg b/TestCases/optimization_euler/multiobjective_wedge/inv_wedge_ROE_multiobj_combo.cfg index bbc023e4fbb..03439302684 100644 --- a/TestCases/optimization_euler/multiobjective_wedge/inv_wedge_ROE_multiobj_combo.cfg +++ b/TestCases/optimization_euler/multiobjective_wedge/inv_wedge_ROE_multiobj_combo.cfg @@ -63,8 +63,8 @@ LINEAR_SOLVER_ILU_FILL_IN= 0 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/optimization_euler/pitching_oneram6/pitching_ONERAM6.cfg b/TestCases/optimization_euler/pitching_oneram6/pitching_ONERAM6.cfg index f2034a74bfb..6ea6f37d0d5 100644 --- a/TestCases/optimization_euler/pitching_oneram6/pitching_ONERAM6.cfg +++ b/TestCases/optimization_euler/pitching_oneram6/pitching_ONERAM6.cfg @@ -81,8 +81,8 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/optimization_euler/steady_naca0012/inv_NACA0012_adv.cfg b/TestCases/optimization_euler/steady_naca0012/inv_NACA0012_adv.cfg index 5733a124917..14a0c24e4ce 100644 --- a/TestCases/optimization_euler/steady_naca0012/inv_NACA0012_adv.cfg +++ b/TestCases/optimization_euler/steady_naca0012/inv_NACA0012_adv.cfg @@ -62,8 +62,8 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/optimization_euler/steady_naca0012/inv_NACA0012_basic.cfg b/TestCases/optimization_euler/steady_naca0012/inv_NACA0012_basic.cfg index 0efd0b15b95..864fc4dce40 100644 --- a/TestCases/optimization_euler/steady_naca0012/inv_NACA0012_basic.cfg +++ b/TestCases/optimization_euler/steady_naca0012/inv_NACA0012_basic.cfg @@ -60,8 +60,8 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/optimization_rans/steady_oneram6/turb_ONERAM6.cfg b/TestCases/optimization_rans/steady_oneram6/turb_ONERAM6.cfg index ce90b4d5267..92c6d3509f5 100644 --- a/TestCases/optimization_rans/steady_oneram6/turb_ONERAM6.cfg +++ b/TestCases/optimization_rans/steady_oneram6/turb_ONERAM6.cfg @@ -61,8 +61,8 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/optimization_rans/steady_rae2822/turb_SA_RAE2822.cfg b/TestCases/optimization_rans/steady_rae2822/turb_SA_RAE2822.cfg index b01ee0b2e7b..d7dd735ae89 100644 --- a/TestCases/optimization_rans/steady_rae2822/turb_SA_RAE2822.cfg +++ b/TestCases/optimization_rans/steady_rae2822/turb_SA_RAE2822.cfg @@ -54,8 +54,8 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/parallel_regression.py b/TestCases/parallel_regression.py index 87edd6666a1..e6a4367810f 100755 --- a/TestCases/parallel_regression.py +++ b/TestCases/parallel_regression.py @@ -238,7 +238,7 @@ def main(): channel.cfg_dir = "euler/channel" channel.cfg_file = "inv_channel_RK.cfg" channel.test_iter = 20 - channel.test_vals = [-1.990518, 3.545643, 0.031745, 0.194289] + channel.test_vals = [3.612169, 0.104888, 0.172110, 1.000000] test_list.append(channel) # NACA0012, native SU2 binary mesh format (.su2b) @@ -266,7 +266,7 @@ def main(): naca0012.cfg_dir = "euler/naca0012" naca0012.cfg_file = "inv_NACA0012_Roe_su2bin.cfg" naca0012.test_iter = 20 - naca0012.test_vals = [-4.452603, -3.920573, 0.296003, 0.024298] + naca0012.test_vals = [-4.026356, -3.521920, 0.274929, 0.009852] test_list.append(naca0012) # Supersonic wedge @@ -274,7 +274,7 @@ def main(): wedge.cfg_dir = "euler/wedge" wedge.cfg_file = "inv_wedge_HLLC.cfg" wedge.test_iter = 20 - wedge.test_vals = [-3.675516, 2.048742, -0.249531, 0.043953] + wedge.test_vals = [-4.142624, 1.585638, -0.249527, 0.043953] test_list.append(wedge) # ONERA M6 Wing @@ -282,7 +282,7 @@ def main(): oneram6.cfg_dir = "euler/oneram6" oneram6.cfg_file = "inv_ONERAM6.cfg" oneram6.test_iter = 10 - oneram6.test_vals = [-11.534670, -11.009582, 0.280800, 0.008623] + oneram6.test_vals = [-4.787340, -4.166981, 0.277687, 0.006533] oneram6.timeout = 3200 test_list.append(oneram6) @@ -291,7 +291,7 @@ def main(): fixedCL_naca0012.cfg_dir = "fixed_cl/naca0012" fixedCL_naca0012.cfg_file = "inv_NACA0012.cfg" fixedCL_naca0012.test_iter = 10 - fixedCL_naca0012.test_vals = [-3.962426, 1.570772, 0.300985, 0.019475] + fixedCL_naca0012.test_vals = [-3.887564, 1.642912, 0.300963, 0.019476] test_list.append(fixedCL_naca0012) # Polar sweep of the inviscid NACA0012 @@ -300,7 +300,7 @@ def main(): polar_naca0012.cfg_file = "inv_NACA0012.cfg" polar_naca0012.polar = True polar_naca0012.test_iter = 10 - polar_naca0012.test_vals = [-1.279651, 4.168190, 0.002681, 0.083781] + polar_naca0012.test_vals = [-1.315764, 4.158361, 0.002646, 0.114559] polar_naca0012.test_vals_aarch64 = [-1.083394, 4.386134, 0.001588, 0.033513] polar_naca0012.command = TestCase.Command(exec = "compute_polar.py", param = "-i 11") # flaky test on arm64 @@ -336,7 +336,7 @@ def main(): ramp_msw.cfg_dir = "euler/ramp" ramp_msw.cfg_file = "inv_ramp_msw.cfg" ramp_msw.test_iter = 100 - ramp_msw.test_vals = [-7.242600, -1.471141, -0.077507, 0.054419] + ramp_msw.test_vals = [-6.866685, -1.104657, -0.077507, 0.054419] ramp_msw.tol = [0.2, 0.2, 0.00001, 0.00001] test_list.append(ramp_msw) @@ -357,7 +357,7 @@ def main(): flatplate.cfg_dir = "navierstokes/flatplate" flatplate.cfg_file = "lam_flatplate.cfg" flatplate.test_iter = 100 - flatplate.test_vals = [-6.496808, -1.017942, 0.001224, 0.028377, 2.361500, -2.333200, 0.000000, 0.000000] + flatplate.test_vals = [-8.165135, -2.690978, 0.001084, 0.036277, 2.361500, -2.325300, 0.000000, 0.000000] test_list.append(flatplate) # Supersonic laminar flat plate @@ -365,7 +365,7 @@ def main(): flatplate_supersonic.cfg_dir = "navierstokes/flatplate" flatplate_supersonic.cfg_file = "flatplate_supersonic.cfg" flatplate_supersonic.test_iter = 100 - flatplate_supersonic.test_vals = [100.000000, -2.940787, -0.677195, -0.570647, 2.495441, 0.001678] + flatplate_supersonic.test_vals = [100.000000, -2.940836, -0.677210, -0.570631, 2.495392, 0.001469] test_list.append(flatplate_supersonic) # Custom objective function @@ -390,7 +390,7 @@ def main(): cylinder.cfg_dir = "navierstokes/cylinder" cylinder.cfg_file = "lam_cylinder.cfg" cylinder.test_iter = 25 - cylinder.test_vals = [-8.427810, -2.952885, -0.007651, 1.646675, 0.000000] + cylinder.test_vals = [-8.557685, -3.072812, -0.018904, 1.610320, 0.000000] test_list.append(cylinder) # Laminar cylinder (low Mach correction) @@ -398,7 +398,7 @@ def main(): cylinder_lowmach.cfg_dir = "navierstokes/cylinder" cylinder_lowmach.cfg_file = "cylinder_lowmach.cfg" cylinder_lowmach.test_iter = 25 - cylinder_lowmach.test_vals = [-6.469226, -1.007489, -0.631813, 78.583596, 0.000000] + cylinder_lowmach.test_vals = [-8.737675, -3.275569, 0.050297, 1.839111, 0.000000] test_list.append(cylinder_lowmach) @@ -416,7 +416,7 @@ def main(): poiseuille_profile.cfg_dir = "navierstokes/poiseuille" poiseuille_profile.cfg_file = "profile_poiseuille.cfg" poiseuille_profile.test_iter = 10 - poiseuille_profile.test_vals = [-12.004294, -7.578130, -0.000000, 2.089953] + poiseuille_profile.test_vals = [-12.003186, -7.623957, -0.000000, 2.089953] poiseuille_profile.test_vals_aarch64 = [-12.007498, -7.226926, -0.000000, 2.089953] poiseuille_profile.tol = [0.001, 0.001, 1e-5, 1e-5, 1e-5] test_list.append(poiseuille_profile) @@ -430,7 +430,7 @@ def main(): rae2822_sa.cfg_dir = "rans/rae2822" rae2822_sa.cfg_file = "turb_SA_RAE2822.cfg" rae2822_sa.test_iter = 20 - rae2822_sa.test_vals = [-2.187402, -5.330154, 0.393514, 0.075585, 0.000000] + rae2822_sa.test_vals = [-2.888183, -5.136146, 0.788144, 0.019032, 1000.000000] test_list.append(rae2822_sa) # RAE2822 SST @@ -438,7 +438,7 @@ def main(): rae2822_sst.cfg_dir = "rans/rae2822" rae2822_sst.cfg_file = "turb_SST_RAE2822.cfg" rae2822_sst.test_iter = 20 - rae2822_sst.test_vals = [-1.037030, 5.861942, 0.362143, 0.073809, 0.000000] + rae2822_sst.test_vals = [-1.495621, 5.875629, 0.638353, 0.020410, 100.000000] test_list.append(rae2822_sst) # RAE2822 SST_SUST @@ -446,7 +446,7 @@ def main(): rae2822_sst_sust.cfg_dir = "rans/rae2822" rae2822_sst_sust.cfg_file = "turb_SST_SUST_RAE2822.cfg" rae2822_sst_sust.test_iter = 20 - rae2822_sst_sust.test_vals = [-2.484221, 5.861926, 0.362143, 0.073809] + rae2822_sst_sust.test_vals = [-2.465087, 5.851605, 0.496009, 0.041100] test_list.append(rae2822_sst_sust) # Flat plate @@ -454,7 +454,7 @@ def main(): turb_flatplate.cfg_dir = "rans/flatplate" turb_flatplate.cfg_file = "turb_SA_flatplate.cfg" turb_flatplate.test_iter = 20 - turb_flatplate.test_vals = [-4.949425, -7.443679, -0.187485, 0.015345] + turb_flatplate.test_vals = [-0.187388, 0.003749, 10.000000, -1.406182] test_list.append(turb_flatplate) # Flat plate (compressible) with species inlet @@ -462,7 +462,7 @@ def main(): turb_flatplate_species.cfg_dir = "rans/flatplate" turb_flatplate_species.cfg_file = "turb_SA_flatplate_species.cfg" turb_flatplate_species.test_iter = 20 - turb_flatplate_species.test_vals = [-4.795630, -1.532152, -2.318309, 0.717570, -3.574258, 3.000000, -0.931729, 2.000000, -1.526521, 3.000000, -0.705481, 0.999934, 0.999934] + turb_flatplate_species.test_vals = [-5.359043, -1.881674, -3.075839, 0.124416, -3.602253, 2.000000, -1.239286, 1.000000, -1.158672, 3.000000, -0.849003, 0.999876, 0.999876] test_list.append(turb_flatplate_species) # Flat plate SST compressibility correction Wilcox @@ -634,7 +634,7 @@ def main(): turb_naca0012_sst_restart_mg.cfg_file = "turb_NACA0012_sst_multigrid_restart.cfg" turb_naca0012_sst_restart_mg.test_iter = 20 turb_naca0012_sst_restart_mg.ntest_vals = 5 - turb_naca0012_sst_restart_mg.test_vals = [-6.566317, -5.057149, 0.830238, -0.008702, 0.078154] + turb_naca0012_sst_restart_mg.test_vals = [-6.560190, -5.057149, 0.830238, -0.008812, 0.078167] turb_naca0012_sst_restart_mg.timeout = 3200 turb_naca0012_sst_restart_mg.tol = 0.000001 test_list.append(turb_naca0012_sst_restart_mg) @@ -648,7 +648,7 @@ def main(): inc_euler_naca0012.cfg_dir = "incomp_euler/naca0012" inc_euler_naca0012.cfg_file = "incomp_NACA0012.cfg" inc_euler_naca0012.test_iter = 20 - inc_euler_naca0012.test_vals = [-6.067964, -5.125607, 0.525745, 0.008772] + inc_euler_naca0012.test_vals = [-6.920909, -6.189139, 0.531865, 0.008472] test_list.append(inc_euler_naca0012) # NACA0012 Hydrofoil @@ -664,7 +664,7 @@ def main(): inc_nozzle.cfg_dir = "incomp_euler/nozzle" inc_nozzle.cfg_file = "inv_nozzle.cfg" inc_nozzle.test_iter = 20 - inc_nozzle.test_vals = [-6.053549, -5.296666, 0.001330, 0.124087] + inc_nozzle.test_vals = [-6.051005, -5.361765, 0.006999, 0.127295] test_list.append(inc_nozzle) # Laminar wall mounted cylinder, Euler walls, cylinder wall diagonally split @@ -684,7 +684,7 @@ def main(): inc_lam_cylinder.cfg_dir = "incomp_navierstokes/cylinder" inc_lam_cylinder.cfg_file = "incomp_cylinder.cfg" inc_lam_cylinder.test_iter = 10 - inc_lam_cylinder.test_vals = [-4.156113, -3.553508, -0.024563, 5.105605] + inc_lam_cylinder.test_vals = [-4.816099, -5.029676, -0.000155, 3.113777] test_list.append(inc_lam_cylinder) # Laminar cylinder, pressure-based @@ -711,7 +711,7 @@ def main(): inc_lam_sphere.cfg_dir = "incomp_navierstokes/sphere" inc_lam_sphere.cfg_file = "sphere.cfg" inc_lam_sphere.test_iter = 5 - inc_lam_sphere.test_vals = [-7.600533, -8.244915, -8.361301, -9.325293, 0.121003, 25.782687, -1.881890] + inc_lam_sphere.test_vals = [-7.599894, -8.023038, -8.135420, -8.783151, 0.121003, 25.782689, -1.574889] test_list.append(inc_lam_sphere) # Laminar sphere, Re=1, pressure-based. Only 3D pressure-based case in the regression suite. @@ -883,7 +883,7 @@ def main(): turbmod_sa_bsl_rae2822.cfg_dir = "turbulence_models/sa/rae2822" turbmod_sa_bsl_rae2822.cfg_file = "turb_SA_BSL_RAE2822.cfg" turbmod_sa_bsl_rae2822.test_iter = 20 - turbmod_sa_bsl_rae2822.test_vals = [-2.801007, 0.156786, -0.273213, -5.259038, 0.799641, 0.025816] + turbmod_sa_bsl_rae2822.test_vals = [-3.182935, -0.447793, -0.875861, -3.286652, 0.769925, 0.017709] test_list.append(turbmod_sa_bsl_rae2822) # SA Negative @@ -900,7 +900,7 @@ def main(): turbmod_sa_comp_rae2822.cfg_dir = "turbulence_models/sa/rae2822" turbmod_sa_comp_rae2822.cfg_file = "turb_SA_COMP_RAE2822.cfg" turbmod_sa_comp_rae2822.test_iter = 20 - turbmod_sa_comp_rae2822.test_vals = [-2.802560, 0.155007, -0.274449, -5.266509, 0.799829, 0.025809] + turbmod_sa_comp_rae2822.test_vals = [-3.192776, -0.471890, -0.893254, -5.190537, 0.777261, 0.017904] test_list.append(turbmod_sa_comp_rae2822) # SA Edwards @@ -908,7 +908,7 @@ def main(): turbmod_sa_edw_rae2822.cfg_dir = "turbulence_models/sa/rae2822" turbmod_sa_edw_rae2822.cfg_file = "turb_SA_EDW_RAE2822.cfg" turbmod_sa_edw_rae2822.test_iter = 20 - turbmod_sa_edw_rae2822.test_vals = [-2.795889, 0.162853, -0.269375, -5.943329, 0.799775, 0.025699] + turbmod_sa_edw_rae2822.test_vals = [-3.198033, -0.439446, -0.883563, -3.899428, 0.786167, 0.017883] test_list.append(turbmod_sa_edw_rae2822) # SA Compressibility and Edwards @@ -916,7 +916,7 @@ def main(): turbmod_sa_comp_edw_rae2822.cfg_dir = "turbulence_models/sa/rae2822" turbmod_sa_comp_edw_rae2822.cfg_file = "turb_SA_COMP_EDW_RAE2822.cfg" turbmod_sa_comp_edw_rae2822.test_iter = 20 - turbmod_sa_comp_edw_rae2822.test_vals = [-2.798258, 0.160264, -0.271408, -5.944887, 0.799936, 0.025689] + turbmod_sa_comp_edw_rae2822.test_vals = [-2.943295, -0.168387, -0.632480, -5.127730, 0.802507, 0.020196] test_list.append(turbmod_sa_comp_edw_rae2822) # SA QCR @@ -924,7 +924,7 @@ def main(): turbmod_sa_qcr_rae2822.cfg_dir = "turbulence_models/sa/rae2822" turbmod_sa_qcr_rae2822.cfg_file = "turb_SA_QCR_RAE2822.cfg" turbmod_sa_qcr_rae2822.test_iter = 20 - turbmod_sa_qcr_rae2822.test_vals = [-2.784977, 0.174833, -0.258852, -5.275520, 0.799156, 0.025897] + turbmod_sa_qcr_rae2822.test_vals = [-3.056565, -0.419621, -0.805532, -3.857890, 0.760796, 0.016908] test_list.append(turbmod_sa_qcr_rae2822) ############################ @@ -948,7 +948,7 @@ def main(): contadj_naca0012.cfg_dir = "cont_adj_euler/naca0012" contadj_naca0012.cfg_file = "inv_NACA0012.cfg" contadj_naca0012.test_iter = 5 - contadj_naca0012.test_vals = [-9.527707, -15.088310, -0.726250, 0.020280] + contadj_naca0012.test_vals = [-9.547544, -15.069350, -0.726250, 0.020280] contadj_naca0012.test_vals_aarch64 = [-9.662546, -14.998818, -0.726250, 0.020280] test_list.append(contadj_naca0012) @@ -957,7 +957,7 @@ def main(): contadj_oneram6.cfg_dir = "cont_adj_euler/oneram6" contadj_oneram6.cfg_file = "inv_ONERAM6.cfg" contadj_oneram6.test_iter = 10 - contadj_oneram6.test_vals = [-12.087421, -12.650762, -1.086100, 0.007556] + contadj_oneram6.test_vals = [-12.085026, -12.651321, -1.086100, 0.007556] test_list.append(contadj_oneram6) # Inviscid WEDGE: tests averaged outflow total pressure adjoint @@ -973,7 +973,7 @@ def main(): contadj_fixed_CL_naca0012.cfg_dir = "fixed_cl/naca0012" contadj_fixed_CL_naca0012.cfg_file = "inv_NACA0012_ContAdj.cfg" contadj_fixed_CL_naca0012.test_iter = 100 - contadj_fixed_CL_naca0012.test_vals = [1.377921, -4.048140, -0.008264, 0.003369] + contadj_fixed_CL_naca0012.test_vals = [1.408903, -4.010709, 0.005808, 0.004028] test_list.append(contadj_fixed_CL_naca0012) ################################### @@ -985,7 +985,7 @@ def main(): contadj_ns_cylinder.cfg_dir = "cont_adj_navierstokes/cylinder" contadj_ns_cylinder.cfg_file = "lam_cylinder.cfg" contadj_ns_cylinder.test_iter = 20 - contadj_ns_cylinder.test_vals = [-3.634298, -9.089945, 2.056700, -0.000000] + contadj_ns_cylinder.test_vals = [-3.626865, -9.079504, 2.056700, -0.000000] test_list.append(contadj_ns_cylinder) # Adjoint laminar naca0012 subsonic @@ -1029,7 +1029,7 @@ def main(): contadj_rans_rae2822.cfg_dir = "cont_adj_rans/rae2822" contadj_rans_rae2822.cfg_file = "turb_SA_RAE2822.cfg" contadj_rans_rae2822.test_iter = 20 - contadj_rans_rae2822.test_vals = [-5.399567, -10.904741, -0.212470, 0.005448] + contadj_rans_rae2822.test_vals = [-5.399270, -10.904277, -0.212470, 0.005448] test_list.append(contadj_rans_rae2822) ############################# @@ -1109,7 +1109,7 @@ def main(): rot_naca0012.cfg_dir = "rotating/naca0012" rot_naca0012.cfg_file = "rot_NACA0012.cfg" rot_naca0012.test_iter = 25 - rot_naca0012.test_vals = [-1.284573, 4.252376, -0.001615, 0.112755] + rot_naca0012.test_vals = [-0.023432, 0.083323, 2.000000, -1.181593] test_list.append(rot_naca0012) # Lid-driven cavity @@ -1117,7 +1117,7 @@ def main(): cavity.cfg_dir = "moving_wall/cavity" cavity.cfg_file = "lam_cavity.cfg" cavity.test_iter = 25 - cavity.test_vals = [-7.838584, -2.378333, 0.009057, 0.006632] + cavity.test_vals = [-7.770113, -2.308185, 0.011072, 0.008947] test_list.append(cavity) # Spinning cylinder @@ -1125,7 +1125,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.401660, -1.942949, 2.534412, 1.997391] + spinning_cylinder.test_vals = [-7.471334, -2.007097, 2.183550, 1.847845] test_list.append(spinning_cylinder) ###################################### @@ -1146,7 +1146,7 @@ def main(): sine_gust.cfg_dir = "gust" sine_gust.cfg_file = "inv_gust_NACA0012.cfg" sine_gust.test_iter = 5 - sine_gust.test_vals = [-1.977498, 3.481817, -0.010210, -0.004556] + sine_gust.test_vals = [-1.977498, 3.481817, -0.011360, -0.005241] sine_gust.unsteady = True test_list.append(sine_gust) @@ -1196,8 +1196,8 @@ def main(): edge_VW = TestCase('edge_VW') edge_VW.cfg_dir = "nicf/edge" edge_VW.cfg_file = "edge_VW.cfg" - edge_VW.test_iter = 25 - edge_VW.test_vals = [-3.109008, 3.092306, -0.000009, 0.000000] + edge_VW.test_iter = 20 + edge_VW.test_vals = [-4.444040, 1.757269, -0.000009, 0.000000] test_list.append(edge_VW) # Rarefaction shock wave edge_PPR @@ -1205,7 +1205,7 @@ def main(): edge_PPR.cfg_dir = "nicf/edge" edge_PPR.cfg_file = "edge_PPR.cfg" edge_PPR.test_iter = 20 - edge_PPR.test_vals = [-10.058036, -3.902722, -0.000034, 0.000000] + edge_PPR.test_vals = [-9.533869, -3.385210, -0.000034, 0.000000] test_list.append(edge_PPR) # Rarefaction Q1D nozzle, include CoolProp fluid model @@ -1360,7 +1360,7 @@ def main(): bars_SST_2D.cfg_dir = "sliding_interface/bars_SST_2D" bars_SST_2D.cfg_file = "bars.cfg" bars_SST_2D.test_iter = 13 - bars_SST_2D.test_vals = [13.000000, -0.395917, -1.480210] + bars_SST_2D.test_vals = [13.000000, -0.457912, -1.541047] bars_SST_2D.multizone = True test_list.append(bars_SST_2D) @@ -1551,7 +1551,7 @@ def main(): pywrapper_naca0012.cfg_dir = "euler/naca0012" pywrapper_naca0012.cfg_file = "inv_NACA0012_Roe.cfg" pywrapper_naca0012.test_iter = 80 - pywrapper_naca0012.test_vals = [-6.853230, -6.303063, 0.335702, 0.023274] + pywrapper_naca0012.test_vals = [-5.699819, -5.186257, 0.334856, 0.023343] pywrapper_naca0012.command = TestCase.Command("mpirun -np 2", "SU2_CFD.py", "--parallel -f") test_list.append(pywrapper_naca0012) @@ -1581,7 +1581,7 @@ def main(): pywrapper_aeroelastic.cfg_dir = "aeroelastic" pywrapper_aeroelastic.cfg_file = "aeroelastic_NACA64A010.cfg" pywrapper_aeroelastic.test_iter = 2 - pywrapper_aeroelastic.test_vals = [-1.876630, 4.021073, 0.082632, 0.027609, -0.001642, -0.000127, -0.965661] + pywrapper_aeroelastic.test_vals = [-1.876636, 4.021064, 0.080986, 0.027812, -0.001643, -0.000126, -0.965663] pywrapper_aeroelastic.command = TestCase.Command("mpirun -np 2", "SU2_CFD.py", "--parallel -f") pywrapper_aeroelastic.unsteady = True test_list.append(pywrapper_aeroelastic) @@ -1622,7 +1622,7 @@ def main(): pywrapper_unsteadyCHT.cfg_dir = "py_wrapper/flatPlate_unsteady_CHT" pywrapper_unsteadyCHT.cfg_file = "unsteady_CHT_FlatPlate_Conf.cfg" pywrapper_unsteadyCHT.test_iter = 5 - pywrapper_unsteadyCHT.test_vals = [-1.614169, 2.260087, 0.018775, 0.168073] + pywrapper_unsteadyCHT.test_vals = [-1.614168, 2.260203, -0.008065, 0.201068] pywrapper_unsteadyCHT.command = TestCase.Command("mpirun -np 2", "python", "launch_unsteady_CHT_FlatPlate.py --parallel -f") pywrapper_unsteadyCHT.unsteady = True test_list.append(pywrapper_unsteadyCHT) diff --git a/TestCases/parallel_regression_AD.py b/TestCases/parallel_regression_AD.py index 2e145789e9e..0b5d8724f62 100644 --- a/TestCases/parallel_regression_AD.py +++ b/TestCases/parallel_regression_AD.py @@ -104,7 +104,7 @@ def main(): discadj_incomp_NACA0012.cfg_dir = "disc_adj_incomp_euler/naca0012" discadj_incomp_NACA0012.cfg_file = "incomp_NACA0012_disc.cfg" discadj_incomp_NACA0012.test_iter = 20 - discadj_incomp_NACA0012.test_vals = [20.000000, -3.096582, -2.323911, 0.000000] + discadj_incomp_NACA0012.test_vals = [20.000000, -3.126844, -2.284292, 0.000000] test_list.append(discadj_incomp_NACA0012) ##################################### diff --git a/TestCases/py_wrapper/custom_inlet/lam_flatplate.cfg b/TestCases/py_wrapper/custom_inlet/lam_flatplate.cfg index 3660dd1d6e1..020daebb932 100644 --- a/TestCases/py_wrapper/custom_inlet/lam_flatplate.cfg +++ b/TestCases/py_wrapper/custom_inlet/lam_flatplate.cfg @@ -62,8 +62,8 @@ TIME_DISCRE_FLOW= EULER_IMPLICIT % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/py_wrapper/rotating_cylinder/spinning_cylinder.cfg b/TestCases/py_wrapper/rotating_cylinder/spinning_cylinder.cfg index 73c0fe931be..1af176928e6 100644 --- a/TestCases/py_wrapper/rotating_cylinder/spinning_cylinder.cfg +++ b/TestCases/py_wrapper/rotating_cylinder/spinning_cylinder.cfg @@ -74,8 +74,8 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/py_wrapper/translating_NACA0012/config.cfg b/TestCases/py_wrapper/translating_NACA0012/config.cfg index adfce41ed71..35b34e3a3c5 100644 --- a/TestCases/py_wrapper/translating_NACA0012/config.cfg +++ b/TestCases/py_wrapper/translating_NACA0012/config.cfg @@ -55,8 +55,8 @@ CFL_ADAPT= NO % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/py_wrapper/translating_NACA0012/forces_0.csv.ref b/TestCases/py_wrapper/translating_NACA0012/forces_0.csv.ref index 7602bf98c36..3aa219b7120 100644 --- a/TestCases/py_wrapper/translating_NACA0012/forces_0.csv.ref +++ b/TestCases/py_wrapper/translating_NACA0012/forces_0.csv.ref @@ -1,200 +1,200 @@ -199, -0.91, -0.00, 0.00 -0, -2.81, 19.36, 0.00 -1, -4.04, 27.84, 0.00 -2, -5.06, 34.89, 0.00 -3, -5.96, 41.22, 0.00 -4, -6.74, 46.79, 0.00 -5, -7.38, 51.39, 0.00 -6, -7.93, 55.45, 0.00 -7, -8.34, 58.60, 0.00 -8, -8.66, 61.16, 0.00 -9, -8.85, 62.88, 0.00 -10, -8.96, 64.08, 0.00 -11, -8.96, 64.56, 0.00 -12, -8.89, 64.51, 0.00 -13, -8.70, 63.68, 0.00 -14, -8.46, 62.43, 0.00 -15, -8.12, 60.46, 0.00 -16, -7.73, 58.13, 0.00 -17, -7.26, 55.15, 0.00 -18, -6.74, 51.77, 0.00 -19, -6.15, 47.79, 0.00 -20, -5.53, 43.47, 0.00 -21, -4.87, 38.71, 0.00 -22, -4.16, 33.49, 0.00 -23, -3.41, 27.84, 0.00 -24, -2.65, 21.90, 0.00 -25, -1.87, 15.65, 0.00 -26, -1.06, 9.02, 0.00 -27, -0.25, 2.17, 0.00 -28, 0.59, -5.20, 0.00 -29, 1.47, -13.09, 0.00 -30, 2.32, -21.04, 0.00 -31, 3.18, -29.33, 0.00 -32, 4.02, -37.73, 0.00 -33, 4.83, -46.23, 0.00 -34, 5.65, -55.07, 0.00 -35, 6.43, -63.94, 0.00 -36, 7.21, -73.28, 0.00 -37, 7.96, -82.77, 0.00 -38, 8.71, -92.70, 0.00 -39, 9.45, -103.10, 0.00 -40, 10.12, -113.32, 0.00 -41, 10.74, -123.75, 0.00 -42, 11.28, -133.98, 0.00 -43, 11.76, -144.27, 0.00 -44, 12.16, -154.42, 0.00 -45, 12.43, -163.95, 0.00 -46, 12.66, -173.97, 0.00 -47, 12.73, -182.77, 0.00 -48, 12.74, -192.14, 0.00 -49, 12.38, -196.96, 0.00 -50, 12.15, -205.21, 0.00 -51, 11.33, -204.66, 0.00 -52, 11.18, -217.62, 0.00 -53, 10.64, -225.59, 0.00 -54, 10.41, -243.33, 0.00 -55, 9.98, -261.63, 0.00 -56, 9.05, -271.88, 0.00 -57, 8.38, -297.01, 0.00 -58, 7.37, -322.02, 0.00 -59, 6.73, -389.49, 0.00 -60, 4.98, -437.02, 0.00 -61, 2.24, -427.29, 0.00 -62, -0.51, -413.94, 0.00 -63, -3.21, -400.44, 0.00 -64, -5.89, -389.11, 0.00 -65, -8.49, -375.82, 0.00 -66, -11.02, -361.82, 0.00 -67, -13.42, -346.89, 0.00 -68, -15.69, -331.52, 0.00 -69, -17.69, -313.40, 0.00 -70, -19.62, -297.17, 0.00 -71, -21.05, -276.48, 0.00 -72, -22.44, -258.43, 0.00 -73, -23.19, -236.27, 0.00 -74, -24.06, -218.46, 0.00 -75, -24.21, -196.97, 0.00 -76, -24.27, -177.79, 0.00 -77, -23.30, -154.22, 0.00 -78, -22.88, -137.20, 0.00 -79, -21.44, -116.69, 0.00 -80, -19.90, -98.46, 0.00 -81, -16.57, -74.54, 0.00 -82, -13.73, -56.16, 0.00 -83, -7.93, -29.49, 0.00 -84, -4.05, -13.67, 0.00 -85, 3.26, 9.96, 0.00 -86, 9.23, 25.42, 0.00 -87, 20.02, 49.49, 0.00 -88, 27.36, 60.38, 0.00 -89, 40.28, 78.78, 0.00 -90, 48.10, 82.53, 0.00 -91, 63.94, 95.06, 0.00 -92, 74.19, 93.96, 0.00 -93, 79.91, 84.25, 0.00 -94, 91.23, 77.50, 0.00 -95, 118.76, 77.35, 0.00 -96, 121.73, 55.80, 0.00 -97, 8.09, 2.19, 0.00 -98, 47.54, 6.38, 0.00 -99, -0.51, 0.00, 0.00 -100, 64.46, -8.65, 0.00 -101, 176.83, -47.86, 0.00 -102, 126.10, -57.80, 0.00 -103, 100.61, -65.53, 0.00 -104, 75.11, -63.81, 0.00 -105, 45.32, -47.78, 0.00 -106, 30.04, -38.05, 0.00 -107, 10.85, -16.13, 0.00 -108, -0.49, 0.83, 0.00 -109, -11.86, 23.19, 0.00 -110, -19.44, 42.91, 0.00 -111, -29.85, 73.80, 0.00 -112, -34.62, 95.32, 0.00 -113, -41.75, 127.45, 0.00 -114, -45.17, 152.36, 0.00 -115, -49.69, 184.71, 0.00 -116, -51.82, 212.01, 0.00 -117, -52.68, 237.02, 0.00 -118, -52.19, 258.18, 0.00 -119, -52.00, 283.02, 0.00 -120, -51.05, 306.08, 0.00 -121, -50.11, 331.62, 0.00 -122, -48.48, 355.15, 0.00 -123, -46.74, 380.31, 0.00 -124, -44.35, 402.71, 0.00 -125, -41.93, 427.20, 0.00 -126, -38.98, 448.90, 0.00 -127, -36.03, 473.18, 0.00 -128, -32.62, 494.05, 0.00 -129, -29.21, 517.44, 0.00 -130, -25.44, 537.50, 0.00 -131, -21.63, 559.29, 0.00 -132, -17.61, 578.46, 0.00 -133, -13.52, 598.34, 0.00 -134, -9.33, 616.18, 0.00 -135, -5.09, 635.07, 0.00 -136, -0.80, 651.77, 0.00 -137, 3.49, 668.01, 0.00 -138, 7.77, 682.29, 0.00 -139, 12.02, 696.11, 0.00 -140, 16.21, 708.87, 0.00 -141, 20.32, 720.40, 0.00 -142, 24.34, 730.98, 0.00 -143, 28.29, 741.71, 0.00 -144, 32.10, 750.50, 0.00 -145, 35.82, 759.33, 0.00 -146, 39.35, 766.05, 0.00 -147, 42.78, 772.64, 0.00 -148, 45.99, 776.96, 0.00 -149, 49.11, 781.64, 0.00 -150, 51.99, 784.09, 0.00 -151, 54.79, 786.89, 0.00 -152, 57.33, 787.54, 0.00 -153, 59.66, 786.77, 0.00 -154, 61.73, 783.94, 0.00 -155, 63.04, 773.18, 0.00 -156, 66.19, 786.02, 0.00 -157, 64.98, 748.75, 0.00 -158, 10.80, 121.00, 0.00 -159, -0.83, -9.03, 0.00 -160, 3.07, 32.68, 0.00 -161, 0.90, 9.39, 0.00 -162, -0.01, -0.08, 0.00 -163, 0.07, 0.74, 0.00 -164, -0.07, -0.71, 0.00 -165, -0.36, -3.47, 0.00 -166, -0.79, -7.38, 0.00 -167, -1.28, -11.85, 0.00 -168, -1.77, -16.08, 0.00 -169, -2.26, -20.12, 0.00 -170, -2.79, -24.49, 0.00 -171, -3.30, -28.47, 0.00 -172, -3.86, -32.82, 0.00 -173, -4.38, -36.71, 0.00 -174, -4.94, -40.85, 0.00 -175, -5.46, -44.55, 0.00 -176, -6.01, -48.45, 0.00 -177, -6.51, -51.82, 0.00 -178, -7.02, -55.18, 0.00 -179, -7.47, -58.05, 0.00 -180, -7.91, -60.74, 0.00 -181, -8.28, -62.89, 0.00 -182, -8.62, -64.87, 0.00 -183, -8.90, -66.27, 0.00 -184, -9.11, -67.24, 0.00 -185, -9.24, -67.62, 0.00 -186, -9.33, -67.68, 0.00 -187, -9.30, -66.98, 0.00 -188, -9.21, -65.83, 0.00 -189, -9.04, -64.21, 0.00 -190, -8.77, -61.97, 0.00 -191, -8.40, -59.03, 0.00 -192, -7.93, -55.43, 0.00 -193, -7.33, -51.05, 0.00 -194, -6.65, -46.16, 0.00 -195, -5.84, -40.38, 0.00 -196, -4.91, -33.90, 0.00 -197, -3.87, -26.67, 0.00 -198, -2.64, -18.21, 0.00 +199, -0.99, -0.00, 0.00 +0, -2.91, 20.02, 0.00 +1, -4.27, 29.42, 0.00 +2, -5.43, 37.48, 0.00 +3, -6.49, 44.88, 0.00 +4, -7.43, 51.52, 0.00 +5, -8.23, 57.28, 0.00 +6, -8.93, 62.42, 0.00 +7, -9.50, 66.76, 0.00 +8, -9.96, 70.36, 0.00 +9, -10.31, 73.26, 0.00 +10, -10.55, 75.47, 0.00 +11, -10.71, 77.10, 0.00 +12, -10.75, 78.01, 0.00 +13, -10.71, 78.35, 0.00 +14, -10.57, 78.03, 0.00 +15, -10.36, 77.16, 0.00 +16, -10.07, 75.79, 0.00 +17, -9.73, 73.92, 0.00 +18, -9.31, 71.49, 0.00 +19, -8.85, 68.73, 0.00 +20, -8.32, 65.37, 0.00 +21, -7.77, 61.78, 0.00 +22, -7.15, 57.64, 0.00 +23, -6.53, 53.27, 0.00 +24, -5.85, 48.43, 0.00 +25, -5.18, 43.45, 0.00 +26, -4.46, 37.94, 0.00 +27, -3.74, 32.28, 0.00 +28, -2.99, 26.23, 0.00 +29, -2.26, 20.13, 0.00 +30, -1.50, 13.62, 0.00 +31, -0.77, 7.14, 0.00 +32, -0.03, 0.27, 0.00 +33, 0.64, -6.16, 0.00 +34, 1.33, -12.94, 0.00 +35, 1.88, -18.69, 0.00 +36, 2.50, -25.43, 0.00 +37, 2.94, -30.60, 0.00 +38, 3.61, -38.39, 0.00 +39, 4.12, -44.94, 0.00 +40, 5.20, -58.26, 0.00 +41, 6.45, -74.32, 0.00 +42, 8.48, -100.75, 0.00 +43, 10.40, -127.62, 0.00 +44, 12.32, -156.48, 0.00 +45, 14.32, -188.86, 0.00 +46, 15.99, -219.70, 0.00 +47, 17.77, -255.19, 0.00 +48, 19.05, -287.25, 0.00 +49, 20.43, -325.17, 0.00 +50, 21.21, -358.33, 0.00 +51, 21.60, -390.04, 0.00 +52, 20.80, -404.89, 0.00 +53, 19.46, -412.52, 0.00 +54, 17.55, -410.28, 0.00 +55, 15.38, -403.24, 0.00 +56, 12.80, -384.55, 0.00 +57, 10.01, -354.85, 0.00 +58, 7.33, -320.56, 0.00 +59, 5.62, -325.28, 0.00 +60, 4.54, -398.71, 0.00 +61, 2.33, -444.80, 0.00 +62, -0.55, -444.61, 0.00 +63, -3.45, -430.49, 0.00 +64, -6.33, -418.34, 0.00 +65, -9.16, -405.22, 0.00 +66, -11.93, -391.89, 0.00 +67, -14.56, -376.47, 0.00 +68, -17.08, -360.79, 0.00 +69, -19.39, -343.61, 0.00 +70, -21.54, -326.20, 0.00 +71, -23.38, -307.04, 0.00 +72, -25.04, -288.42, 0.00 +73, -26.35, -268.52, 0.00 +74, -27.44, -249.13, 0.00 +75, -28.26, -229.94, 0.00 +76, -28.70, -210.22, 0.00 +77, -28.76, -190.36, 0.00 +78, -28.57, -171.29, 0.00 +79, -27.84, -151.55, 0.00 +80, -26.53, -131.24, 0.00 +81, -24.47, -110.11, 0.00 +82, -22.10, -90.41, 0.00 +83, -17.63, -65.56, 0.00 +84, -13.82, -46.59, 0.00 +85, -9.00, -27.47, 0.00 +86, -3.97, -10.94, 0.00 +87, 2.04, 5.04, 0.00 +88, 8.66, 19.11, 0.00 +89, 17.22, 33.67, 0.00 +90, 26.22, 44.98, 0.00 +91, 38.13, 56.68, 0.00 +92, 50.18, 63.55, 0.00 +93, 64.64, 68.16, 0.00 +94, 81.14, 68.93, 0.00 +95, 92.61, 60.32, 0.00 +96, 98.61, 45.20, 0.00 +97, 91.85, 24.86, 0.00 +98, 60.95, 8.18, 0.00 +99, 54.21, -0.00, 0.00 +100, 87.82, -11.78, 0.00 +101, 110.00, -29.77, 0.00 +102, 92.95, -42.60, 0.00 +103, 73.45, -47.84, 0.00 +104, 54.95, -46.68, 0.00 +105, 39.22, -41.36, 0.00 +106, 29.77, -37.70, 0.00 +107, 13.13, -19.52, 0.00 +108, 1.46, -2.51, 0.00 +109, -12.03, 23.53, 0.00 +110, -21.14, 46.66, 0.00 +111, -30.42, 75.21, 0.00 +112, -36.34, 100.05, 0.00 +113, -42.50, 129.72, 0.00 +114, -45.24, 152.58, 0.00 +115, -47.68, 177.27, 0.00 +116, -48.11, 196.85, 0.00 +117, -49.30, 221.84, 0.00 +118, -49.86, 246.67, 0.00 +119, -50.26, 273.55, 0.00 +120, -49.99, 299.73, 0.00 +121, -49.24, 325.87, 0.00 +122, -47.80, 350.18, 0.00 +123, -46.06, 374.79, 0.00 +124, -43.92, 398.75, 0.00 +125, -41.45, 422.34, 0.00 +126, -38.71, 445.76, 0.00 +127, -35.65, 468.20, 0.00 +128, -32.39, 490.54, 0.00 +129, -28.90, 511.99, 0.00 +130, -25.24, 533.17, 0.00 +131, -21.41, 553.63, 0.00 +132, -17.46, 573.42, 0.00 +133, -13.40, 592.80, 0.00 +134, -9.25, 611.37, 0.00 +135, -5.04, 629.20, 0.00 +136, -0.80, 646.64, 0.00 +137, 3.47, 662.94, 0.00 +138, 7.73, 678.10, 0.00 +139, 11.96, 692.64, 0.00 +140, 16.15, 706.26, 0.00 +141, 20.27, 718.38, 0.00 +142, 24.31, 730.12, 0.00 +143, 28.27, 741.00, 0.00 +144, 32.10, 750.49, 0.00 +145, 35.79, 758.77, 0.00 +146, 39.36, 766.12, 0.00 +147, 42.77, 772.47, 0.00 +148, 46.02, 777.49, 0.00 +149, 49.12, 781.76, 0.00 +150, 52.03, 784.73, 0.00 +151, 54.76, 786.49, 0.00 +152, 57.27, 786.70, 0.00 +153, 59.65, 786.61, 0.00 +154, 62.04, 787.97, 0.00 +155, 63.93, 784.13, 0.00 +156, 65.88, 782.40, 0.00 +157, 67.06, 772.81, 0.00 +158, 69.82, 782.23, 0.00 +159, 35.12, 383.21, 0.00 +160, -13.10, -139.35, 0.00 +161, -9.96, -103.51, 0.00 +162, -7.72, -78.42, 0.00 +163, -7.29, -72.50, 0.00 +164, -7.05, -68.73, 0.00 +165, -6.60, -63.13, 0.00 +166, -6.57, -61.71, 0.00 +167, -6.59, -60.74, 0.00 +168, -6.81, -61.72, 0.00 +169, -7.08, -63.08, 0.00 +170, -7.42, -65.08, 0.00 +171, -7.76, -67.01, 0.00 +172, -8.15, -69.40, 0.00 +173, -8.55, -71.76, 0.00 +174, -8.94, -73.94, 0.00 +175, -9.30, -75.91, 0.00 +176, -9.67, -77.93, 0.00 +177, -10.01, -79.65, 0.00 +178, -10.32, -81.15, 0.00 +179, -10.61, -82.44, 0.00 +180, -10.85, -83.37, 0.00 +181, -11.06, -84.05, 0.00 +182, -11.21, -84.33, 0.00 +183, -11.31, -84.26, 0.00 +184, -11.35, -83.81, 0.00 +185, -11.34, -82.98, 0.00 +186, -11.25, -81.65, 0.00 +187, -11.11, -80.01, 0.00 +188, -10.89, -77.90, 0.00 +189, -10.54, -74.91, 0.00 +190, -10.09, -71.22, 0.00 +191, -9.54, -66.99, 0.00 +192, -8.89, -62.12, 0.00 +193, -8.13, -56.59, 0.00 +194, -7.28, -50.53, 0.00 +195, -6.31, -43.67, 0.00 +196, -5.23, -36.08, 0.00 +197, -4.05, -27.89, 0.00 +198, -2.67, -18.38, 0.00 diff --git a/TestCases/py_wrapper/updated_moving_frame_NACA12/config.cfg b/TestCases/py_wrapper/updated_moving_frame_NACA12/config.cfg index 31d50306867..9d8753f511f 100644 --- a/TestCases/py_wrapper/updated_moving_frame_NACA12/config.cfg +++ b/TestCases/py_wrapper/updated_moving_frame_NACA12/config.cfg @@ -55,8 +55,8 @@ CFL_ADAPT= NO % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/py_wrapper/updated_moving_frame_NACA12/forces_0.csv.ref b/TestCases/py_wrapper/updated_moving_frame_NACA12/forces_0.csv.ref index 0f39252ba9a..1c87fcffcb6 100644 --- a/TestCases/py_wrapper/updated_moving_frame_NACA12/forces_0.csv.ref +++ b/TestCases/py_wrapper/updated_moving_frame_NACA12/forces_0.csv.ref @@ -1,200 +1,200 @@ -199, -0.96, -0.00, 0.00 -0, -2.88, 19.80, 0.00 -1, -4.08, 28.11, 0.00 -2, -5.13, 35.44, 0.00 -3, -6.05, 41.88, 0.00 -4, -6.85, 47.52, 0.00 -5, -7.49, 52.16, 0.00 -6, -8.03, 56.17, 0.00 -7, -8.44, 59.32, 0.00 -8, -8.75, 61.79, 0.00 -9, -8.93, 63.46, 0.00 -10, -9.03, 64.59, 0.00 -11, -9.03, 65.07, 0.00 -12, -8.95, 64.97, 0.00 -13, -8.78, 64.26, 0.00 -14, -8.54, 63.01, 0.00 -15, -8.22, 61.22, 0.00 -16, -7.83, 58.91, 0.00 -17, -7.39, 56.13, 0.00 -18, -6.87, 52.74, 0.00 -19, -6.30, 48.95, 0.00 -20, -5.67, 44.59, 0.00 -21, -5.01, 39.84, 0.00 -22, -4.30, 34.65, 0.00 -23, -3.56, 29.06, 0.00 -24, -2.79, 23.05, 0.00 -25, -1.98, 16.57, 0.00 -26, -1.15, 9.76, 0.00 -27, -0.29, 2.47, 0.00 -28, 0.56, -4.91, 0.00 -29, 1.43, -12.74, 0.00 -30, 2.26, -20.48, 0.00 -31, 3.11, -28.64, 0.00 -32, 3.92, -36.81, 0.00 -33, 4.73, -45.24, 0.00 -34, 5.51, -53.68, 0.00 -35, 6.26, -62.26, 0.00 -36, 6.99, -70.99, 0.00 -37, 7.67, -79.69, 0.00 -38, 8.31, -88.48, 0.00 -39, 8.89, -97.03, 0.00 -40, 9.43, -105.63, 0.00 -41, 9.85, -113.54, 0.00 -42, 10.26, -121.88, 0.00 -43, 10.54, -129.31, 0.00 -44, 10.77, -136.82, 0.00 -45, 10.78, -142.12, 0.00 -46, 10.74, -147.53, 0.00 -47, 10.54, -151.33, 0.00 -48, 10.38, -156.60, 0.00 -49, 9.75, -155.13, 0.00 -50, 8.45, -142.76, 0.00 -51, 6.40, -115.54, 0.00 -52, 9.86, -191.93, 0.00 -53, 24.75, -524.71, 0.00 -54, 26.02, -608.43, 0.00 -55, 21.64, -567.32, 0.00 -56, 18.59, -558.24, 0.00 -57, 15.69, -556.22, 0.00 -58, 12.54, -548.32, 0.00 -59, 9.29, -538.17, 0.00 -60, 6.01, -527.70, 0.00 -61, 2.70, -516.54, 0.00 -62, -0.62, -503.90, 0.00 -63, -3.93, -489.84, 0.00 -64, -7.19, -475.37, 0.00 -65, -10.40, -460.31, 0.00 -66, -13.51, -443.91, 0.00 -67, -16.52, -427.17, 0.00 -68, -19.37, -409.22, 0.00 -69, -22.09, -391.43, 0.00 -70, -24.59, -372.46, 0.00 -71, -26.96, -354.04, 0.00 -72, -29.02, -334.24, 0.00 -73, -30.98, -315.64, 0.00 -74, -32.47, -294.84, 0.00 -75, -33.84, -275.37, 0.00 -76, -34.68, -254.05, 0.00 -77, -35.53, -235.15, 0.00 -78, -35.70, -214.07, 0.00 -79, -35.83, -195.02, 0.00 -80, -35.05, -173.40, 0.00 -81, -34.19, -153.83, 0.00 -82, -32.26, -131.97, 0.00 -83, -30.00, -111.54, 0.00 -84, -26.57, -89.60, 0.00 -85, -22.26, -67.94, 0.00 -86, -16.65, -45.84, 0.00 -87, -10.42, -25.78, 0.00 -88, -1.99, -4.39, 0.00 -89, 7.81, 15.28, 0.00 -90, 17.06, 29.26, 0.00 -91, 27.28, 40.55, 0.00 -92, 36.43, 46.14, 0.00 -93, 50.49, 53.24, 0.00 -94, 63.17, 53.66, 0.00 -95, 73.70, 48.00, 0.00 -96, 73.02, 33.47, 0.00 -97, 67.53, 18.28, 0.00 -98, 54.75, 7.35, 0.00 -99, 17.20, -0.00, 0.00 -100, 52.60, -7.06, 0.00 -101, 93.59, -25.33, 0.00 -102, 62.72, -28.75, 0.00 -103, 27.14, -17.68, 0.00 -104, 23.11, -19.63, 0.00 -105, 5.43, -5.72, 0.00 -106, -0.12, 0.15, 0.00 -107, -12.46, 18.53, 0.00 -108, -19.25, 33.03, 0.00 -109, -25.52, 49.90, 0.00 -110, -31.57, 69.68, 0.00 -111, -35.49, 87.76, 0.00 -112, -39.31, 108.23, 0.00 -113, -41.08, 125.40, 0.00 -114, -43.50, 146.70, 0.00 -115, -44.37, 164.95, 0.00 -116, -45.79, 187.35, 0.00 -117, -46.14, 207.61, 0.00 -118, -46.53, 230.18, 0.00 -119, -46.07, 250.78, 0.00 -120, -45.67, 273.82, 0.00 -121, -44.43, 294.06, 0.00 -122, -43.29, 317.15, 0.00 -123, -41.64, 338.83, 0.00 -124, -39.78, 361.20, 0.00 -125, -37.54, 382.56, 0.00 -126, -35.17, 404.98, 0.00 -127, -32.45, 426.14, 0.00 -128, -29.56, 447.62, 0.00 -129, -26.45, 468.60, 0.00 -130, -23.16, 489.20, 0.00 -131, -19.70, 509.17, 0.00 -132, -16.09, 528.37, 0.00 -133, -12.37, 547.12, 0.00 -134, -8.55, 564.91, 0.00 -135, -4.66, 581.83, 0.00 -136, -0.74, 598.49, 0.00 -137, 3.21, 613.80, 0.00 -138, 7.16, 628.25, 0.00 -139, 11.09, 642.08, 0.00 -140, 14.98, 654.91, 0.00 -141, 18.80, 666.53, 0.00 -142, 22.56, 677.39, 0.00 -143, 26.23, 687.57, 0.00 -144, 29.78, 696.30, 0.00 -145, 33.20, 703.83, 0.00 -146, 36.50, 710.42, 0.00 -147, 39.65, 715.98, 0.00 -148, 42.62, 720.14, 0.00 -149, 45.50, 724.11, 0.00 -150, 48.13, 725.97, 0.00 -151, 50.35, 723.19, 0.00 -152, 54.49, 748.60, 0.00 -153, 50.92, 671.51, 0.00 -154, 6.40, 81.25, 0.00 -155, -0.48, -5.87, 0.00 -156, 2.99, 35.56, 0.00 -157, 3.29, 37.89, 0.00 -158, 3.41, 38.23, 0.00 -159, 3.70, 40.39, 0.00 -160, 3.68, 39.19, 0.00 -161, 3.67, 38.17, 0.00 -162, 3.42, 34.77, 0.00 -163, 3.16, 31.44, 0.00 -164, 2.74, 26.72, 0.00 -165, 2.33, 22.31, 0.00 -166, 1.78, 16.69, 0.00 -167, 1.24, 11.40, 0.00 -168, 0.60, 5.42, 0.00 -169, -0.01, -0.10, 0.00 -170, -0.70, -6.14, 0.00 -171, -1.32, -11.41, 0.00 -172, -2.03, -17.30, 0.00 -173, -2.66, -22.31, 0.00 -174, -3.36, -27.82, 0.00 -175, -3.98, -32.46, 0.00 -176, -4.65, -37.48, 0.00 -177, -5.24, -41.66, 0.00 -178, -5.86, -46.06, 0.00 -179, -6.39, -49.65, 0.00 -180, -6.93, -53.25, 0.00 -181, -7.36, -55.95, 0.00 -182, -7.80, -58.69, 0.00 -183, -8.13, -60.57, 0.00 -184, -8.45, -62.36, 0.00 -185, -8.68, -63.48, 0.00 -186, -8.84, -64.16, 0.00 -187, -8.92, -64.26, 0.00 -188, -8.92, -63.79, 0.00 -189, -8.83, -62.72, 0.00 -190, -8.64, -61.01, 0.00 -191, -8.33, -58.54, 0.00 -192, -7.92, -55.37, 0.00 -193, -7.37, -51.28, 0.00 -194, -6.72, -46.61, 0.00 -195, -5.92, -40.93, 0.00 -196, -4.99, -34.48, 0.00 -197, -3.97, -27.33, 0.00 -198, -2.78, -19.11, 0.00 +199, -0.98, -0.00, 0.00 +0, -2.89, 19.89, 0.00 +1, -4.12, 28.36, 0.00 +2, -5.17, 35.67, 0.00 +3, -6.10, 42.20, 0.00 +4, -6.93, 48.05, 0.00 +5, -7.63, 53.11, 0.00 +6, -8.21, 57.37, 0.00 +7, -8.68, 60.97, 0.00 +8, -8.99, 63.51, 0.00 +9, -9.20, 65.36, 0.00 +10, -9.28, 66.37, 0.00 +11, -9.27, 66.73, 0.00 +12, -9.17, 66.55, 0.00 +13, -8.99, 65.76, 0.00 +14, -8.76, 64.65, 0.00 +15, -8.46, 63.02, 0.00 +16, -8.12, 61.09, 0.00 +17, -7.73, 58.74, 0.00 +18, -7.26, 55.80, 0.00 +19, -6.76, 52.48, 0.00 +20, -6.17, 48.47, 0.00 +21, -5.53, 44.02, 0.00 +22, -4.86, 39.16, 0.00 +23, -4.13, 33.74, 0.00 +24, -3.43, 28.38, 0.00 +25, -2.68, 22.45, 0.00 +26, -1.99, 16.92, 0.00 +27, -1.26, 10.86, 0.00 +28, -0.62, 5.40, 0.00 +29, 0.05, -0.48, 0.00 +30, 0.57, -5.20, 0.00 +31, 1.09, -10.01, 0.00 +32, 1.48, -13.85, 0.00 +33, 1.88, -17.94, 0.00 +34, 2.18, -21.27, 0.00 +35, 2.56, -25.45, 0.00 +36, 2.72, -27.60, 0.00 +37, 2.84, -29.52, 0.00 +38, 2.54, -27.06, 0.00 +39, 2.39, -26.05, 0.00 +40, 2.12, -23.72, 0.00 +41, 2.85, -32.88, 0.00 +42, 0.07, -0.80, 0.00 +43, -7.64, 93.76, 0.00 +44, -15.56, 197.66, 0.00 +45, -18.11, 238.88, 0.00 +46, 4.57, -62.81, 0.00 +47, 28.46, -408.83, 0.00 +48, 30.15, -454.80, 0.00 +49, 29.55, -470.30, 0.00 +50, 27.36, -462.29, 0.00 +51, 25.32, -457.28, 0.00 +52, 23.08, -449.36, 0.00 +53, 21.91, -464.51, 0.00 +54, 21.44, -501.19, 0.00 +55, 21.98, -576.18, 0.00 +56, 20.44, -613.98, 0.00 +57, 16.27, -576.74, 0.00 +58, 12.57, -549.58, 0.00 +59, 9.29, -537.86, 0.00 +60, 6.03, -529.16, 0.00 +61, 2.72, -519.13, 0.00 +62, -0.62, -505.94, 0.00 +63, -3.93, -490.73, 0.00 +64, -7.20, -475.71, 0.00 +65, -10.38, -459.45, 0.00 +66, -13.47, -442.43, 0.00 +67, -16.41, -424.36, 0.00 +68, -19.21, -405.79, 0.00 +69, -21.81, -386.39, 0.00 +70, -24.21, -366.71, 0.00 +71, -26.37, -346.30, 0.00 +72, -28.28, -325.64, 0.00 +73, -29.91, -304.75, 0.00 +74, -31.21, -283.42, 0.00 +75, -32.28, -262.70, 0.00 +76, -32.88, -240.86, 0.00 +77, -33.29, -220.29, 0.00 +78, -33.20, -199.09, 0.00 +79, -33.11, -180.21, 0.00 +80, -32.42, -160.41, 0.00 +81, -32.04, -144.14, 0.00 +82, -30.93, -126.55, 0.00 +83, -30.26, -112.49, 0.00 +84, -28.67, -96.70, 0.00 +85, -26.72, -81.57, 0.00 +86, -23.77, -65.45, 0.00 +87, -19.10, -47.23, 0.00 +88, -13.13, -28.97, 0.00 +89, -4.87, -9.52, 0.00 +90, 5.12, 8.78, 0.00 +91, 16.89, 25.11, 0.00 +92, 29.83, 37.77, 0.00 +93, 43.55, 45.92, 0.00 +94, 58.79, 49.94, 0.00 +95, 71.13, 46.33, 0.00 +96, 80.33, 36.82, 0.00 +97, 91.25, 24.70, 0.00 +98, 89.60, 12.02, 0.00 +99, 52.39, -0.00, 0.00 +100, 121.03, -16.24, 0.00 +101, 165.10, -44.68, 0.00 +102, 144.64, -66.30, 0.00 +103, 117.07, -76.25, 0.00 +104, 94.88, -80.60, 0.00 +105, 66.02, -69.62, 0.00 +106, 47.83, -60.58, 0.00 +107, 28.23, -41.96, 0.00 +108, 15.85, -27.20, 0.00 +109, 3.13, -6.12, 0.00 +110, -5.71, 12.59, 0.00 +111, -14.69, 36.31, 0.00 +112, -21.31, 58.67, 0.00 +113, -28.22, 86.14, 0.00 +114, -33.21, 112.01, 0.00 +115, -38.21, 142.05, 0.00 +116, -41.32, 169.06, 0.00 +117, -44.19, 198.82, 0.00 +118, -45.47, 224.95, 0.00 +119, -46.71, 254.22, 0.00 +120, -46.59, 279.39, 0.00 +121, -46.26, 306.19, 0.00 +122, -45.07, 330.17, 0.00 +123, -43.64, 355.12, 0.00 +124, -41.58, 377.56, 0.00 +125, -39.33, 400.75, 0.00 +126, -36.72, 422.86, 0.00 +127, -33.87, 444.82, 0.00 +128, -30.76, 465.82, 0.00 +129, -27.43, 486.02, 0.00 +130, -23.94, 505.83, 0.00 +131, -20.30, 524.79, 0.00 +132, -16.54, 543.40, 0.00 +133, -12.68, 561.07, 0.00 +134, -8.75, 578.23, 0.00 +135, -4.76, 594.19, 0.00 +136, -0.75, 610.20, 0.00 +137, 3.27, 624.70, 0.00 +138, 7.28, 638.58, 0.00 +139, 11.25, 651.52, 0.00 +140, 15.19, 664.02, 0.00 +141, 19.03, 674.72, 0.00 +142, 22.82, 685.17, 0.00 +143, 26.50, 694.58, 0.00 +144, 30.07, 703.02, 0.00 +145, 33.49, 710.00, 0.00 +146, 36.80, 716.33, 0.00 +147, 39.96, 721.72, 0.00 +148, 42.96, 725.88, 0.00 +149, 45.80, 729.01, 0.00 +150, 48.40, 730.04, 0.00 +151, 50.69, 728.06, 0.00 +152, 53.19, 730.63, 0.00 +153, 53.67, 707.80, 0.00 +154, 40.89, 519.28, 0.00 +155, -10.41, -127.67, 0.00 +156, -9.92, -117.86, 0.00 +157, -0.17, -2.01, 0.00 +158, 0.20, 2.24, 0.00 +159, -0.45, -4.95, 0.00 +160, 0.03, 0.33, 0.00 +161, 0.43, 4.50, 0.00 +162, 0.61, 6.20, 0.00 +163, 0.63, 6.25, 0.00 +164, 0.56, 5.43, 0.00 +165, 0.40, 3.85, 0.00 +166, 0.18, 1.72, 0.00 +167, -0.12, -1.09, 0.00 +168, -0.49, -4.46, 0.00 +169, -0.97, -8.64, 0.00 +170, -1.49, -13.10, 0.00 +171, -2.10, -18.13, 0.00 +172, -2.71, -23.05, 0.00 +173, -3.37, -28.27, 0.00 +174, -4.02, -33.22, 0.00 +175, -4.70, -38.39, 0.00 +176, -5.37, -43.29, 0.00 +177, -6.05, -48.13, 0.00 +178, -6.69, -52.54, 0.00 +179, -7.31, -56.81, 0.00 +180, -7.88, -60.56, 0.00 +181, -8.40, -63.82, 0.00 +182, -8.85, -66.57, 0.00 +183, -9.18, -68.42, 0.00 +184, -9.47, -69.89, 0.00 +185, -9.62, -70.38, 0.00 +186, -9.71, -70.43, 0.00 +187, -9.68, -69.72, 0.00 +188, -9.58, -68.53, 0.00 +189, -9.42, -66.89, 0.00 +190, -9.15, -64.59, 0.00 +191, -8.81, -61.89, 0.00 +192, -8.34, -58.33, 0.00 +193, -7.78, -54.16, 0.00 +194, -7.09, -49.18, 0.00 +195, -6.25, -43.20, 0.00 +196, -5.26, -36.32, 0.00 +197, -4.13, -28.49, 0.00 +198, -2.86, -19.72, 0.00 diff --git a/TestCases/rans/flatplate/turb_SA_flatplate.cfg b/TestCases/rans/flatplate/turb_SA_flatplate.cfg index 3b1070ef6b1..6e13b39ebc7 100644 --- a/TestCases/rans/flatplate/turb_SA_flatplate.cfg +++ b/TestCases/rans/flatplate/turb_SA_flatplate.cfg @@ -45,11 +45,11 @@ MARKER_MONITORING= ( wall ) % ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% % NUM_METHOD_GRAD= GREEN_GAUSS -CFL_NUMBER= 100.0 +CFL_NUMBER= 1000.0 CFL_ADAPT= NO CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) -ITER= 99999 +ITER= 1000 % ----------------------- SLOPE LIMITER DEFINITION ----------------------------% % @@ -58,15 +58,23 @@ 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-3 +LINEAR_SOLVER_ITER= 10 + % -------------------------- MULTIGRID PARAMETERS -----------------------------% % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 +MG_IMPLICIT_LINES= YES % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % @@ -85,7 +93,7 @@ TIME_DISCRE_TURB= EULER_IMPLICIT % --------------------------- CONVERGENCE PARAMETERS --------------------------% % -CONV_RESIDUAL_MINVAL= -15 +CONV_RESIDUAL_MINVAL= -12 CONV_STARTITER= 10 CONV_CAUCHY_ELEMS= 100 CONV_CAUCHY_EPS= 1E-6 @@ -107,4 +115,4 @@ GRAD_OBJFUNC_FILENAME= of_grad SURFACE_FILENAME= surface_flow SURFACE_ADJ_FILENAME= surface_adjoint OUTPUT_WRT_FREQ= 1000 -SCREEN_OUTPUT= (INNER_ITER, RMS_DENSITY, RMS_NU_TILDE, LIFT, DRAG) +SCREEN_OUTPUT= (INNER_ITER, RMS_DENSITY, RMS_NU_TILDE, LIFT, DRAG, LINSOL_ITER,LINSOL_RESIDUAL) diff --git a/TestCases/rans/flatplate/turb_SA_flatplate_species.cfg b/TestCases/rans/flatplate/turb_SA_flatplate_species.cfg index b6ef385d7b7..44c9577e09c 100644 --- a/TestCases/rans/flatplate/turb_SA_flatplate_species.cfg +++ b/TestCases/rans/flatplate/turb_SA_flatplate_species.cfg @@ -79,8 +79,8 @@ SPECIES_CLIPPING_MAX= 1.0 % NUM_METHOD_GRAD= GREEN_GAUSS CFL_NUMBER= 100.0 -CFL_ADAPT= NO -CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) +CFL_ADAPT= YES +CFL_ADAPT_PARAM= ( 0.9, 1.1, 1.0, 1000.0, 1e-3 ) RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) ITER= 99999 @@ -100,12 +100,13 @@ LINEAR_SOLVER_ITER= 3 % -------------------------- MULTIGRID PARAMETERS -----------------------------% % MGLEVEL= 3 -MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4) +MGCYCLE= W_CYCLE +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 +MG_IMPLICIT_LINES= YES % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % @@ -123,7 +124,7 @@ SLOPE_LIMITER_TURB= VENKATAKRISHNAN TIME_DISCRE_TURB= EULER_IMPLICIT % --------------------------- CONVERGENCE PARAMETERS --------------------------% -CONV_RESIDUAL_MINVAL= -15 +CONV_RESIDUAL_MINVAL= -12 CONV_STARTITER= 10 CONV_CAUCHY_ELEMS= 100 CONV_CAUCHY_EPS= 1E-6 diff --git a/TestCases/rans/flatplate/turb_SST_flatplate.cfg b/TestCases/rans/flatplate/turb_SST_flatplate.cfg index b4e8e5ab7ef..ca64097dffd 100644 --- a/TestCases/rans/flatplate/turb_SST_flatplate.cfg +++ b/TestCases/rans/flatplate/turb_SST_flatplate.cfg @@ -45,11 +45,11 @@ MARKER_MONITORING= ( wall ) % ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% % NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES -CFL_NUMBER= 10.0 +CFL_NUMBER= 1000.0 CFL_ADAPT= NO CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) -EXT_ITER= 99999 +ITER= 10000 % ----------------------- SLOPE LIMITER DEFINITION ----------------------------% % @@ -62,11 +62,12 @@ SENS_REMOVE_SHARP= NO % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 +MG_IMPLICIT_LINES= YES % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % @@ -84,7 +85,7 @@ SLOPE_LIMITER_TURB= VENKATAKRISHNAN TIME_DISCRE_TURB= EULER_IMPLICIT % --------------------------- CONVERGENCE PARAMETERS --------------------------% -CONV_RESIDUAL_MINVAL= -15 +CONV_RESIDUAL_MINVAL= -12 CONV_STARTITER= 10 CONV_CAUCHY_ELEMS= 100 CONV_CAUCHY_EPS= 1E-6 diff --git a/TestCases/rans/naca0012/turb_NACA0012_sst_multigrid_restart.cfg b/TestCases/rans/naca0012/turb_NACA0012_sst_multigrid_restart.cfg index b718fa52ebf..9a0934b10d5 100644 --- a/TestCases/rans/naca0012/turb_NACA0012_sst_multigrid_restart.cfg +++ b/TestCases/rans/naca0012/turb_NACA0012_sst_multigrid_restart.cfg @@ -93,8 +93,8 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/rans/rae2822/turb_SA_RAE2822.cfg b/TestCases/rans/rae2822/turb_SA_RAE2822.cfg index 2157904ca34..44a935ad52b 100644 --- a/TestCases/rans/rae2822/turb_SA_RAE2822.cfg +++ b/TestCases/rans/rae2822/turb_SA_RAE2822.cfg @@ -41,9 +41,9 @@ MARKER_MONITORING= ( AIRFOIL ) % ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% % NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES -CFL_NUMBER= 10.0 +CFL_NUMBER= 1000.0 CFL_ADAPT= NO -CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) +CFL_ADAPT_PARAM= ( 0.9, 1.1, 1.0, 10000.0, 1.00 ) ITER= 99999 LINEAR_SOLVER= BCGSTAB LINEAR_SOLVER_ERROR= 1E-1 @@ -52,12 +52,13 @@ LINEAR_SOLVER_ITER= 3 % -------------------------- MULTIGRID PARAMETERS -----------------------------% % MGLEVEL= 3 -MGCYCLE= W_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MGCYCLE= V_CYCLE +MG_PRE_SMOOTH= ( 1, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 +MG_IMPLICIT_LINES= YES % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % @@ -104,8 +105,7 @@ GRAD_OBJFUNC_FILENAME= of_grad SURFACE_FILENAME= surface_flow SURFACE_ADJ_FILENAME= surface_adjoint OUTPUT_WRT_FREQ= 250 -SCREEN_OUTPUT= (INNER_ITER, RMS_DENSITY, RMS_NU_TILDE, LIFT, DRAG, TOTAL_HEATFLUX) - +SCREEN_OUTPUT= (INNER_ITER, RMS_DENSITY, RMS_NU_TILDE, LIFT, DRAG, AVG_CFL) % ------------------------ GRID DEFORMATION PARAMETERS ------------------------% % DV_KIND= FFD_SETTING diff --git a/TestCases/rans/rae2822/turb_SST_RAE2822.cfg b/TestCases/rans/rae2822/turb_SST_RAE2822.cfg index a1676c9e41e..3d786606872 100644 --- a/TestCases/rans/rae2822/turb_SST_RAE2822.cfg +++ b/TestCases/rans/rae2822/turb_SST_RAE2822.cfg @@ -44,24 +44,26 @@ MARKER_MONITORING= ( AIRFOIL ) % ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% % NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES -CFL_NUMBER= 10.0 +CFL_NUMBER= 100.0 CFL_ADAPT= NO -CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) +CFL_ADAPT_PARAM= ( 0.9, 1.1, 1.0, 100.0, 0.1 ) ITER= 99999 LINEAR_SOLVER= FGMRES LINEAR_SOLVER_PREC= LU_SGS LINEAR_SOLVER_ERROR= 1E-1 LINEAR_SOLVER_ITER= 3 + % -------------------------- MULTIGRID PARAMETERS -----------------------------% % MGLEVEL= 3 -MGCYCLE= W_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MGCYCLE= V_CYCLE +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 +MG_IMPLICIT_LINES= YES % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % @@ -72,11 +74,11 @@ TIME_DISCRE_FLOW= EULER_IMPLICIT % -------------------- TURBULENT NUMERICAL METHOD DEFINITION ------------------% % -CONV_NUM_METHOD_TURB= SCALAR_UPWIND +CONV_NUM_METHOD_TURB= BOUNDED_SCALAR MUSCL_TURB= NO SLOPE_LIMITER_TURB= VENKATAKRISHNAN TIME_DISCRE_TURB= EULER_IMPLICIT - +CFL_REDUCTION_TURB=0.5 % --------------------------- CONVERGENCE PARAMETERS --------------------------% CONV_RESIDUAL_MINVAL= -8 CONV_STARTITER= 10 @@ -100,4 +102,4 @@ GRAD_OBJFUNC_FILENAME= of_grad SURFACE_FILENAME= surface_flow SURFACE_ADJ_FILENAME= surface_adjoint OUTPUT_WRT_FREQ= 250 -SCREEN_OUTPUT = (INNER_ITER, RMS_DENSITY, RMS_TKE, RMS_DISSIPATION, LIFT, DRAG, TOTAL_HEATFLUX) +SCREEN_OUTPUT = (INNER_ITER, RMS_DENSITY, RMS_TKE, RMS_DISSIPATION, LIFT, DRAG, AVG_CFL) diff --git a/TestCases/rans/rae2822/turb_SST_SUST_RAE2822.cfg b/TestCases/rans/rae2822/turb_SST_SUST_RAE2822.cfg index 781ecd85a94..f628f665fcc 100644 --- a/TestCases/rans/rae2822/turb_SST_SUST_RAE2822.cfg +++ b/TestCases/rans/rae2822/turb_SST_SUST_RAE2822.cfg @@ -58,11 +58,12 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= W_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 +MG_IMPLICIT_LINES=YES % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % @@ -77,8 +78,10 @@ CONV_NUM_METHOD_TURB= SCALAR_UPWIND MUSCL_TURB= NO SLOPE_LIMITER_TURB= VENKATAKRISHNAN TIME_DISCRE_TURB= EULER_IMPLICIT +CFL_REDUCTION_TURB=0.5 % --------------------------- CONVERGENCE PARAMETERS --------------------------% +% CONV_RESIDUAL_MINVAL= -8 CONV_STARTITER= 10 CONV_CAUCHY_ELEMS= 100 diff --git a/TestCases/rotating/naca0012/rot_NACA0012.cfg b/TestCases/rotating/naca0012/rot_NACA0012.cfg index 53fcce6702a..6ed8754d72b 100644 --- a/TestCases/rotating/naca0012/rot_NACA0012.cfg +++ b/TestCases/rotating/naca0012/rot_NACA0012.cfg @@ -52,7 +52,7 @@ MARKER_DESIGNING = ( airfoil ) % ------------- COMMON PARAMETERS TO DEFINE THE NUMERICAL METHOD --------------% % NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES -CFL_NUMBER= 2.0 +CFL_NUMBER= 10 CFL_ADAPT= NO CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) @@ -69,8 +69,8 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 % lower damping, to keep from fast oscillations in residuals @@ -114,7 +114,7 @@ CONV_RESIDUAL_MINVAL= -10 CONV_STARTITER= 10 CONV_CAUCHY_ELEMS= 100 CONV_CAUCHY_EPS= 1E-6 -SCREEN_OUTPUT=(INNER_ITER, WALL_TIME, RMS_DENSITY, RMS_ENERGY, LIFT, DRAG) +SCREEN_OUTPUT=(INNER_ITER, WALL_TIME, RMS_DENSITY, RMS_ENERGY, LIFT, DRAG, LINSOL_ITER, LINSOL_RESIDUAL) % ------------------------- INPUT/OUTPUT INFORMATION --------------------------% % diff --git a/TestCases/serial_regression.py b/TestCases/serial_regression.py index 1479f3f11cc..ab1de7fe143 100755 --- a/TestCases/serial_regression.py +++ b/TestCases/serial_regression.py @@ -95,7 +95,7 @@ def main(): channel.cfg_dir = "euler/channel" channel.cfg_file = "inv_channel_RK.cfg" channel.test_iter = 10 - channel.test_vals = [-1.969337, 3.565024, 0.000242, 0.160624] + channel.test_vals = [-1.906687, 3.625653, -0.011054, 0.205254, 1.000000] test_list.append(channel) # NACA0012 @@ -103,7 +103,7 @@ def main(): naca0012.cfg_dir = "euler/naca0012" naca0012.cfg_file = "inv_NACA0012_Roe.cfg" naca0012.test_iter = 20 - naca0012.test_vals = [-4.489721, -3.937702, 0.293347, 0.025228] + naca0012.test_vals = [-4.032065, -3.525196, 0.273051, 0.009680] test_list.append(naca0012) # NACA0012 - FMG test @@ -111,7 +111,7 @@ def main(): naca0012_FMG.cfg_dir = "euler/naca0012" naca0012_FMG.cfg_file = "inv_NACA0012.cfg" naca0012_FMG.test_iter = 20 - naca0012_FMG.test_vals = [-3.880921, -3.284668, 0.176713, 0.044753] + naca0012_FMG.test_vals = [-4.160277, -3.553897, 0.296156, 0.016889] test_list.append(naca0012_FMG) # Supersonic wedge @@ -119,7 +119,7 @@ def main(): wedge.cfg_dir = "euler/wedge" wedge.cfg_file = "inv_wedge_HLLC.cfg" wedge.test_iter = 20 - wedge.test_vals = [-3.701409, 2.023011, -0.249531, 0.043953] + wedge.test_vals = [-4.399745, 1.331048, -0.249527, 0.043953] test_list.append(wedge) # ONERA M6 Wing @@ -127,7 +127,7 @@ def main(): oneram6.cfg_dir = "euler/oneram6" oneram6.cfg_file = "inv_ONERAM6.cfg" oneram6.test_iter = 10 - oneram6.test_vals = [-7.649980, -7.032700, 0.280803, 0.008625] + oneram6.test_vals = [-4.825465, -4.205219, 0.277033, 0.006614] oneram6.timeout = 9600 test_list.append(oneram6) @@ -136,7 +136,7 @@ def main(): fixedCL_naca0012.cfg_dir = "fixed_cl/naca0012" fixedCL_naca0012.cfg_file = "inv_NACA0012.cfg" fixedCL_naca0012.test_iter = 10 - fixedCL_naca0012.test_vals = [-3.949168, 1.584810, 0.301017, 0.019479] + fixedCL_naca0012.test_vals = [-3.886939, 1.644825, 0.300989, 0.019478] test_list.append(fixedCL_naca0012) # Polar sweep of the inviscid NACA0012 @@ -145,7 +145,7 @@ def main(): polar_naca0012.cfg_file = "inv_NACA0012.cfg" polar_naca0012.polar = True polar_naca0012.test_iter = 10 - polar_naca0012.test_vals = [-1.273417, 4.171509, -0.002852, 0.084424] + polar_naca0012.test_vals = [-1.311660, 4.165589, 0.000067, 0.113157] polar_naca0012.test_vals_aarch64 = [-1.063447, 4.401847, 0.000291, 0.031696] polar_naca0012.command = TestCase.Command(exec = "compute_polar.py", param = "-n 1 -i 11") # flaky test on arm64 @@ -176,7 +176,7 @@ def main(): flatplate.cfg_dir = "navierstokes/flatplate" flatplate.cfg_file = "lam_flatplate.cfg" flatplate.test_iter = 20 - flatplate.test_vals = [-5.499362, -0.019046, 0.002526, 0.011870, 2.361500, -2.349600, 0.000000, 0.000000] + flatplate.test_vals = [-5.623336, -0.144687, 0.001202, 0.028141, 2.361500, -2.333400, 0.000000, 0.000000] test_list.append(flatplate) # Laminar cylinder (steady) @@ -184,7 +184,7 @@ def main(): cylinder.cfg_dir = "navierstokes/cylinder" cylinder.cfg_file = "lam_cylinder.cfg" cylinder.test_iter = 25 - cylinder.test_vals = [-8.508933, -3.034987, -0.014846, 1.644215, 0.000000] + cylinder.test_vals = [-8.725123, -3.234819, -0.028022, 1.605527, 0.000000] test_list.append(cylinder) # Laminar cylinder (low Mach correction) @@ -192,7 +192,7 @@ def main(): cylinder_lowmach.cfg_dir = "navierstokes/cylinder" cylinder_lowmach.cfg_file = "cylinder_lowmach.cfg" cylinder_lowmach.test_iter = 25 - cylinder_lowmach.test_vals = [-6.453096, -0.991328, 0.722165, 66.048089, 0.000000] + cylinder_lowmach.test_vals = [-8.698687, -3.236566, 0.401347, 1.754864, 0.000000] test_list.append(cylinder_lowmach) # 2D Poiseuille flow (body force driven with periodic inlet / outlet) @@ -208,7 +208,7 @@ def main(): poiseuille_profile.cfg_dir = "navierstokes/poiseuille" poiseuille_profile.cfg_file = "profile_poiseuille.cfg" poiseuille_profile.test_iter = 10 - poiseuille_profile.test_vals = [-12.003753, -7.573597, -0.000000, 2.089953] + poiseuille_profile.test_vals = [-12.003115, -7.626023, -0.000000, 2.089953] poiseuille_profile.test_vals_aarch64 = [-12.009012, -7.262299, -0.000000, 2.089953] #last 4 columns test_list.append(poiseuille_profile) @@ -228,7 +228,7 @@ def main(): rae2822_sa.cfg_dir = "rans/rae2822" rae2822_sa.cfg_file = "turb_SA_RAE2822.cfg" rae2822_sa.test_iter = 20 - rae2822_sa.test_vals = [-2.187052, -5.333164, 0.382555, 0.077938, 0.000000] + rae2822_sa.test_vals = [-3.131221, -5.161756, 0.778275, 0.019566, 1000.000000] test_list.append(rae2822_sa) # RAE2822 SST @@ -236,7 +236,7 @@ def main(): rae2822_sst.cfg_dir = "rans/rae2822" rae2822_sst.cfg_file = "turb_SST_RAE2822.cfg" rae2822_sst.test_iter = 20 - rae2822_sst.test_vals = [-1.028038, 5.869011, 0.367576, 0.075890, 0.000000] + rae2822_sst.test_vals = [-1.745363, -1.484660, 5.883796, 0.579910, 0.017299, 100.000000] test_list.append(rae2822_sst) # RAE2822 SST_SUST @@ -244,7 +244,7 @@ def main(): rae2822_sst_sust.cfg_dir = "rans/rae2822" rae2822_sst_sust.cfg_file = "turb_SST_SUST_RAE2822.cfg" rae2822_sst_sust.test_iter = 20 - rae2822_sst_sust.test_vals = [-2.486848, 5.868998, 0.367576, 0.075890] + rae2822_sst_sust.test_vals = [-2.464319, 5.852571, 0.490309, 0.042521] test_list.append(rae2822_sst_sust) # Flat plate @@ -252,7 +252,7 @@ def main(): turb_flatplate.cfg_dir = "rans/flatplate" turb_flatplate.cfg_file = "turb_SA_flatplate.cfg" turb_flatplate.test_iter = 20 - turb_flatplate.test_vals = [-4.958115, -7.438257, -0.187473, 0.015056] + turb_flatplate.test_vals = [-5.286997, -6.483481, -0.187358, 0.003712, 10.000000, -2.181754] test_list.append(turb_flatplate) # FLAT PLATE, WALL FUNCTIONS, COMPRESSIBLE SST @@ -377,7 +377,7 @@ def main(): axi_rans_air_nozzle_species.cfg_dir = "axisymmetric_rans/air_nozzle" axi_rans_air_nozzle_species.cfg_file = "air_nozzle_species.cfg" axi_rans_air_nozzle_species.test_iter = 10 - axi_rans_air_nozzle_species.test_vals = [-1.690923, 3.877716, -2.932258, 5.754594, -3.130820, 0.0] + axi_rans_air_nozzle_species.test_vals = [-1.690665, 3.882506, -2.928702, 5.760933, -3.144560, 0.000000] axi_rans_air_nozzle_species.tol = 0.0001 test_list.append(axi_rans_air_nozzle_species) @@ -391,7 +391,7 @@ def main(): turb_naca0012_sst_restart_mg.cfg_file = "turb_NACA0012_sst_multigrid_restart.cfg" turb_naca0012_sst_restart_mg.test_iter = 50 turb_naca0012_sst_restart_mg.ntest_vals = 5 - turb_naca0012_sst_restart_mg.test_vals = [-6.610405, -5.081422, 0.810881, -0.008846, 0.077934] + turb_naca0012_sst_restart_mg.test_vals = [-6.570974, -5.081421, 0.810883, -0.008830, 0.077967] turb_naca0012_sst_restart_mg.timeout = 3200 turb_naca0012_sst_restart_mg.tol = 0.000001 test_list.append(turb_naca0012_sst_restart_mg) @@ -412,7 +412,7 @@ def main(): inc_euler_naca0012.cfg_dir = "incomp_euler/naca0012" inc_euler_naca0012.cfg_file = "incomp_NACA0012.cfg" inc_euler_naca0012.test_iter = 20 - inc_euler_naca0012.test_vals = [-5.988713, -5.020635, 0.522968, 0.008854] + inc_euler_naca0012.test_vals = [-6.814482, -6.001232, 0.531760, 0.008476] test_list.append(inc_euler_naca0012) # NACA0012 Hydrofoil, pressure-based @@ -428,7 +428,7 @@ def main(): inc_nozzle.cfg_dir = "incomp_euler/nozzle" inc_nozzle.cfg_file = "inv_nozzle.cfg" inc_nozzle.test_iter = 20 - inc_nozzle.test_vals = [-6.247282, -5.460332, -0.019426, 0.126862] + inc_nozzle.test_vals = [-6.331969, -5.586818, -0.024387, 0.126306] test_list.append(inc_nozzle) ############################# @@ -447,7 +447,7 @@ def main(): inc_lam_cylinder.cfg_dir = "incomp_navierstokes/cylinder" inc_lam_cylinder.cfg_file = "incomp_cylinder.cfg" inc_lam_cylinder.test_iter = 10 - inc_lam_cylinder.test_vals = [-4.161215, -3.573002, 0.019888, 4.945923] + inc_lam_cylinder.test_vals = [-4.809141, -5.026921, 0.000880, 3.118344] test_list.append(inc_lam_cylinder) # Laminar cylinder, pressure-based @@ -644,7 +644,7 @@ def main(): contadj_naca0012.cfg_dir = "cont_adj_euler/naca0012" contadj_naca0012.cfg_file = "inv_NACA0012.cfg" contadj_naca0012.test_iter = 5 - contadj_naca0012.test_vals = [-9.531733, -15.088205, -0.726250, 0.020280] + contadj_naca0012.test_vals = [-9.552105, -15.069398, -0.726250, 0.020280] contadj_naca0012.tol = 0.001 test_list.append(contadj_naca0012) @@ -653,7 +653,7 @@ def main(): contadj_oneram6.cfg_dir = "cont_adj_euler/oneram6" contadj_oneram6.cfg_file = "inv_ONERAM6.cfg" contadj_oneram6.test_iter = 10 - contadj_oneram6.test_vals = [-12.083706, -12.645329, -1.086100, 0.007556] + contadj_oneram6.test_vals = [-12.083324, -12.644564, -1.086100, 0.007556] test_list.append(contadj_oneram6) # Inviscid WEDGE: tests averaged outflow total pressure adjoint @@ -669,7 +669,7 @@ def main(): contadj_fixedCL_naca0012.cfg_dir = "fixed_cl/naca0012" contadj_fixedCL_naca0012.cfg_file = "inv_NACA0012_ContAdj.cfg" contadj_fixedCL_naca0012.test_iter = 100 - contadj_fixedCL_naca0012.test_vals = [1.378116, -4.047513, -0.030259, 0.003488] + contadj_fixedCL_naca0012.test_vals = [1.409148, -4.006889, -0.025392, 0.004170] test_list.append(contadj_fixedCL_naca0012) ################################### @@ -688,7 +688,7 @@ def main(): contadj_ns_cylinder.cfg_dir = "cont_adj_navierstokes/cylinder" contadj_ns_cylinder.cfg_file = "lam_cylinder.cfg" contadj_ns_cylinder.test_iter = 20 - contadj_ns_cylinder.test_vals = [-3.628460, -9.081344, 2.056700, -0.000000] + contadj_ns_cylinder.test_vals = [-3.634026, -9.089553, 2.056700, -0.000000] test_list.append(contadj_ns_cylinder) # Adjoint laminar naca0012 subsonic @@ -732,7 +732,7 @@ def main(): contadj_rans_rae2822.cfg_dir = "cont_adj_rans/rae2822" contadj_rans_rae2822.cfg_file = "turb_SA_RAE2822.cfg" contadj_rans_rae2822.test_iter = 20 - contadj_rans_rae2822.test_vals = [-5.399778, -10.904866, -0.212470, 0.005448] + contadj_rans_rae2822.test_vals = [-5.399078, -10.904106, -0.212470, 0.005448] test_list.append(contadj_rans_rae2822) ############################# @@ -810,7 +810,7 @@ def main(): rot_naca0012.cfg_dir = "rotating/naca0012" rot_naca0012.cfg_file = "rot_NACA0012.cfg" rot_naca0012.test_iter = 25 - rot_naca0012.test_vals = [-1.281672, 4.255371, -0.001082, 0.112631] + rot_naca0012.test_vals = [-1.242808, 4.266616, -0.022207, 0.084206, 2.000000, -1.252601] test_list.append(rot_naca0012) # Lid-driven cavity @@ -818,7 +818,7 @@ def main(): cavity.cfg_dir = "moving_wall/cavity" cavity.cfg_file = "lam_cavity.cfg" cavity.test_iter = 25 - cavity.test_vals = [-8.144051, -2.746565, 0.014954, 0.007011] + cavity.test_vals = [-8.032742, -2.589249, 0.015257, 0.007688] test_list.append(cavity) # Spinning cylinder @@ -826,7 +826,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.549394, -2.082578, 1.841595, 1.853229] + spinning_cylinder.test_vals = [-7.634797, -2.176937, 1.860210, 1.939647] test_list.append(spinning_cylinder) ###################################### @@ -847,7 +847,7 @@ def main(): sine_gust.cfg_dir = "gust" sine_gust.cfg_file = "inv_gust_NACA0012.cfg" sine_gust.test_iter = 5 - sine_gust.test_vals = [-1.977498, 3.481817, -0.010301, -0.004334] + sine_gust.test_vals = [-1.977498, 3.481817, -0.010871, -0.005083] sine_gust.unsteady = True test_list.append(sine_gust) @@ -856,7 +856,7 @@ def main(): aeroelastic.cfg_dir = "aeroelastic" aeroelastic.cfg_file = "aeroelastic_NACA64A010.cfg" aeroelastic.test_iter = 2 - aeroelastic.test_vals = [-1.876631, 4.021073, 0.081373, 0.027542, -0.001642, -0.000127, -1.133902] + aeroelastic.test_vals = [-1.876632, 4.021072, 0.080240, 0.027935, -0.001641, -0.000127, -1.133898] aeroelastic.unsteady = True test_list.append(aeroelastic) @@ -882,7 +882,7 @@ def main(): unst_pitching_naca64a010_rans.cfg_dir = "unsteady/pitching_naca64a010_rans" unst_pitching_naca64a010_rans.cfg_file = "turb_NACA64A010.cfg" unst_pitching_naca64a010_rans.test_iter = 2 - unst_pitching_naca64a010_rans.test_vals = [-1.299045, -3.951363, 0.010176, 0.008237] + unst_pitching_naca64a010_rans.test_vals = [-1.299045, -3.951331, 0.011098, 0.008241] unst_pitching_naca64a010_rans.unsteady = True test_list.append(unst_pitching_naca64a010_rans) # unsteady pitching NACA64A010, Euler @@ -890,7 +890,7 @@ def main(): unst_pitching_naca64a010_euler.cfg_dir = "unsteady/pitching_naca64a010_euler" unst_pitching_naca64a010_euler.cfg_file = "pitching_NACA64A010.cfg" unst_pitching_naca64a010_euler.test_iter = 2 - unst_pitching_naca64a010_euler.test_vals = [-1.186839, 4.280301, -0.039479, 0.000910] + unst_pitching_naca64a010_euler.test_vals = [-1.186839, 4.280301, -0.039724, 0.000927] unst_pitching_naca64a010_euler.unsteady = True test_list.append(unst_pitching_naca64a010_euler) # unsteady plunging NACA0012, Laminar NS @@ -898,7 +898,7 @@ def main(): unst_plunging_naca0012.cfg_dir = "unsteady/plunging_naca0012" unst_plunging_naca0012.cfg_file = "plunging_NACA0012.cfg" unst_plunging_naca0012.test_iter = 2 - unst_plunging_naca0012.test_vals = [-4.083462, 1.366757, -6.456450, -0.082788] + unst_plunging_naca0012.test_vals = [-4.083462, 1.366757, -3.455802, -0.097062] unst_plunging_naca0012.unsteady = True test_list.append(unst_plunging_naca0012) @@ -907,7 +907,7 @@ def main(): unst_deforming_naca0012.cfg_dir = "disc_adj_euler/naca0012_pitching_def" unst_deforming_naca0012.cfg_file = "inv_NACA0012_pitching_deform.cfg" unst_deforming_naca0012.test_iter = 5 - unst_deforming_naca0012.test_vals = [-3.665270, -3.794211, -3.716998, -3.148563] + unst_deforming_naca0012.test_vals = [-3.667005, -3.796733, -3.719112, -3.150401] unst_deforming_naca0012.unsteady = True test_list.append(unst_deforming_naca0012) @@ -920,7 +920,7 @@ def main(): ls89_sa.cfg_dir = "nicf/LS89" ls89_sa.cfg_file = "turb_SA_PR.cfg" ls89_sa.test_iter = 20 - ls89_sa.test_vals = [-5.072889, -13.410694, 0.181586, 0.432065] + ls89_sa.test_vals = [-5.041500, -13.379523, 0.179019, 0.420831] test_list.append(ls89_sa) # Rarefaction shock wave edge_VW @@ -928,7 +928,7 @@ def main(): edge_VW.cfg_dir = "nicf/edge" edge_VW.cfg_file = "edge_VW.cfg" edge_VW.test_iter = 20 - edge_VW.test_vals = [-2.807248, 3.393885, -0.000010, 0.000000] + edge_VW.test_vals = [-8.395792, -2.198370, -0.000009, 0.000000] test_list.append(edge_VW) # Rarefaction shock wave edge_PPR @@ -936,7 +936,7 @@ def main(): edge_PPR.cfg_dir = "nicf/edge" edge_PPR.cfg_file = "edge_PPR.cfg" edge_PPR.test_iter = 20 - edge_PPR.test_vals = [-12.342162, -6.169311, -0.000034, 0.000000] + edge_PPR.test_vals = [-12.584167, -6.372084, -0.000034, 0.000000] test_list.append(edge_PPR) @@ -1078,7 +1078,7 @@ def main(): bars_SST_2D.cfg_dir = "sliding_interface/bars_SST_2D" bars_SST_2D.cfg_file = "bars.cfg" bars_SST_2D.test_iter = 13 - bars_SST_2D.test_vals = [13.000000, -0.393225, -1.462251] + bars_SST_2D.test_vals = [13.000000, -0.456143, -1.541051] bars_SST_2D.multizone = True test_list.append(bars_SST_2D) @@ -1175,7 +1175,7 @@ def main(): airfoilRBF.cfg_dir = "fea_fsi/Airfoil_RBF" airfoilRBF.cfg_file = "config.cfg" airfoilRBF.test_iter = 1 - airfoilRBF.test_vals = [1.000000, 0.026697, -3.532043] + airfoilRBF.test_vals = [1.000000, 0.030557, -3.531052] airfoilRBF.tol = 0.0001 airfoilRBF.multizone = True test_list.append(airfoilRBF) @@ -1602,7 +1602,7 @@ def main(): opt_multiobj1surf_py.cfg_dir = "optimization_euler/multiobjective_wedge" opt_multiobj1surf_py.cfg_file = "inv_wedge_ROE_multiobj_1surf.cfg" opt_multiobj1surf_py.test_iter = 1 - opt_multiobj1surf_py.test_vals = [1.000000, 1.000000, 36.670510, 5.750360] + opt_multiobj1surf_py.test_vals = [1.000000, 1.000000, 36.586730, 5.593636] 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 @@ -1615,7 +1615,7 @@ def main(): opt_2surf1obj_py.cfg_dir = "optimization_euler/multiobjective_wedge" opt_2surf1obj_py.cfg_file = "inv_wedge_ROE_2surf_1obj.cfg" opt_2surf1obj_py.test_iter = 1 - opt_2surf1obj_py.test_vals = [1.000000, 1.000000, 2.005032, 0.000474] + opt_2surf1obj_py.test_vals = [1.000000, 1.000000, 2.005039, 0.000462] 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 @@ -1632,7 +1632,7 @@ def main(): pywrapper_naca0012.cfg_dir = "euler/naca0012" pywrapper_naca0012.cfg_file = "inv_NACA0012_Roe.cfg" pywrapper_naca0012.test_iter = 20 - pywrapper_naca0012.test_vals = [-4.489721, -3.937702, 0.293347, 0.025228] + pywrapper_naca0012.test_vals = [-4.032065, -3.525196, 0.273051, 0.009680] pywrapper_naca0012.command = TestCase.Command(exec = "SU2_CFD.py", param = "-f") pywrapper_naca0012.timeout = 1600 pywrapper_naca0012.tol = 0.00001 @@ -1688,7 +1688,7 @@ def main(): pywrapper_unsteadyCHT.cfg_dir = "py_wrapper/flatPlate_unsteady_CHT" pywrapper_unsteadyCHT.cfg_file = "unsteady_CHT_FlatPlate_Conf.cfg" pywrapper_unsteadyCHT.test_iter = 5 - pywrapper_unsteadyCHT.test_vals = [-1.614169, 2.260215, -0.019432, 0.203751] + pywrapper_unsteadyCHT.test_vals = [-1.614168, 2.259817, -0.009951, 0.169563] pywrapper_unsteadyCHT.command = TestCase.Command(exec = "python", param = "launch_unsteady_CHT_FlatPlate.py -f") pywrapper_unsteadyCHT.timeout = 1600 pywrapper_unsteadyCHT.tol = 0.00001 diff --git a/TestCases/serial_regression_AD.py b/TestCases/serial_regression_AD.py index 8c556a3eef1..8a027729440 100644 --- a/TestCases/serial_regression_AD.py +++ b/TestCases/serial_regression_AD.py @@ -108,7 +108,7 @@ def main(): discadj_incomp_NACA0012.cfg_dir = "disc_adj_incomp_euler/naca0012" discadj_incomp_NACA0012.cfg_file = "incomp_NACA0012_disc.cfg" discadj_incomp_NACA0012.test_iter = 20 - discadj_incomp_NACA0012.test_vals = [20.000000, -3.122056, -2.290799, 0.000000] + discadj_incomp_NACA0012.test_vals = [20.000000, -3.134640, -2.294875, 0.000000] test_list.append(discadj_incomp_NACA0012) ##################################### @@ -158,7 +158,7 @@ def main(): discadj_pitchingNACA0012.cfg_dir = "disc_adj_euler/naca0012_pitching" discadj_pitchingNACA0012.cfg_file = "inv_NACA0012_pitching.cfg" discadj_pitchingNACA0012.test_iter = 4 - discadj_pitchingNACA0012.test_vals = [-1.050429, -1.504333, -0.004852, 0.000013] + discadj_pitchingNACA0012.test_vals = [-1.057526, -1.512609, -0.004842, 0.000013] discadj_pitchingNACA0012.unsteady = True test_list.append(discadj_pitchingNACA0012) @@ -167,7 +167,7 @@ def main(): unst_deforming_naca0012.cfg_dir = "disc_adj_euler/naca0012_pitching_def" unst_deforming_naca0012.cfg_file = "inv_NACA0012_pitching_deform_ad.cfg" unst_deforming_naca0012.test_iter = 4 - unst_deforming_naca0012.test_vals = [-1.885968, -1.780392, 3890.100000, 0.000003] + unst_deforming_naca0012.test_vals = [-1.874283, -1.768562, 4274.000000, 0.000003] unst_deforming_naca0012.unsteady = True test_list.append(unst_deforming_naca0012) diff --git a/TestCases/sliding_interface/bars_SST_2D/bars.cfg b/TestCases/sliding_interface/bars_SST_2D/bars.cfg index 0c99e82fc00..1e460faa469 100644 --- a/TestCases/sliding_interface/bars_SST_2D/bars.cfg +++ b/TestCases/sliding_interface/bars_SST_2D/bars.cfg @@ -94,8 +94,8 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 diff --git a/TestCases/turbulence_models/sa/rae2822/turb_SA_BSL_RAE2822.cfg b/TestCases/turbulence_models/sa/rae2822/turb_SA_BSL_RAE2822.cfg index cdc080aca0f..92597f2d9e2 100644 --- a/TestCases/turbulence_models/sa/rae2822/turb_SA_BSL_RAE2822.cfg +++ b/TestCases/turbulence_models/sa/rae2822/turb_SA_BSL_RAE2822.cfg @@ -30,7 +30,7 @@ MARKER_MONITORING= ( AIRFOIL ) % ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% % NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES -CFL_NUMBER= 100 +CFL_NUMBER= 1000 CFL_ADAPT= NO ITER= 99999 LINEAR_SOLVER= BCGSTAB @@ -41,11 +41,12 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= W_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 +MG_IMPLICIT_LINES= YES % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % diff --git a/TestCases/turbulence_models/sa/rae2822/turb_SA_COMP_EDW_RAE2822.cfg b/TestCases/turbulence_models/sa/rae2822/turb_SA_COMP_EDW_RAE2822.cfg index ff13edb7145..3b0eaab261a 100644 --- a/TestCases/turbulence_models/sa/rae2822/turb_SA_COMP_EDW_RAE2822.cfg +++ b/TestCases/turbulence_models/sa/rae2822/turb_SA_COMP_EDW_RAE2822.cfg @@ -30,7 +30,7 @@ MARKER_MONITORING= ( AIRFOIL ) % ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% % NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES -CFL_NUMBER= 100.0 +CFL_NUMBER= 1000.0 CFL_ADAPT= NO ITER= 99999 LINEAR_SOLVER= BCGSTAB @@ -41,11 +41,13 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= W_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_SMOOTH_EARLY_EXIT= NO +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 +MG_IMPLICIT_LINES= YES % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % diff --git a/TestCases/turbulence_models/sa/rae2822/turb_SA_COMP_RAE2822.cfg b/TestCases/turbulence_models/sa/rae2822/turb_SA_COMP_RAE2822.cfg index 70f6f0cf4aa..e55cb5cde83 100644 --- a/TestCases/turbulence_models/sa/rae2822/turb_SA_COMP_RAE2822.cfg +++ b/TestCases/turbulence_models/sa/rae2822/turb_SA_COMP_RAE2822.cfg @@ -31,7 +31,7 @@ MARKER_MONITORING= ( AIRFOIL ) % ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% % NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES -CFL_NUMBER= 100.0 +CFL_NUMBER= 1000.0 CFL_ADAPT= NO ITER= 99999 LINEAR_SOLVER= BCGSTAB @@ -42,11 +42,12 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= W_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 +MG_IMPLICIT_LINES= YES % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % diff --git a/TestCases/turbulence_models/sa/rae2822/turb_SA_EDW_RAE2822.cfg b/TestCases/turbulence_models/sa/rae2822/turb_SA_EDW_RAE2822.cfg index a4dc42ff4ee..2a15e42a482 100644 --- a/TestCases/turbulence_models/sa/rae2822/turb_SA_EDW_RAE2822.cfg +++ b/TestCases/turbulence_models/sa/rae2822/turb_SA_EDW_RAE2822.cfg @@ -31,7 +31,7 @@ MARKER_MONITORING= ( AIRFOIL ) % ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% % NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES -CFL_NUMBER= 100.0 +CFL_NUMBER= 1000.0 CFL_ADAPT= NO ITER= 99999 LINEAR_SOLVER= BCGSTAB @@ -42,11 +42,12 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= W_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 +MG_IMPLICIT_LINES= YES % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % diff --git a/TestCases/turbulence_models/sa/rae2822/turb_SA_QCR_RAE2822.cfg b/TestCases/turbulence_models/sa/rae2822/turb_SA_QCR_RAE2822.cfg index 20d46b10b9b..70bf62d0f5b 100644 --- a/TestCases/turbulence_models/sa/rae2822/turb_SA_QCR_RAE2822.cfg +++ b/TestCases/turbulence_models/sa/rae2822/turb_SA_QCR_RAE2822.cfg @@ -31,7 +31,7 @@ MARKER_MONITORING= ( AIRFOIL ) % ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% % NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES -CFL_NUMBER= 100.0 +CFL_NUMBER= 1000.0 CFL_ADAPT= NO ITER= 99999 LINEAR_SOLVER= BCGSTAB @@ -42,11 +42,11 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= W_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) -MG_DAMP_RESTRICTION= 0.5 -MG_DAMP_PROLONGATION= 0.5 +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % @@ -61,7 +61,7 @@ TIME_DISCRE_TURB= EULER_IMPLICIT % --------------------------- CONVERGENCE PARAMETERS --------------------------% % -CONV_RESIDUAL_MINVAL= -10 +CONV_RESIDUAL_MINVAL= -08 CONV_STARTITER= 10 CONV_CAUCHY_ELEMS= 100 CONV_CAUCHY_EPS= 1E-6 diff --git a/TestCases/tutorials.py b/TestCases/tutorials.py index 664acf01cad..d59aad17bf9 100644 --- a/TestCases/tutorials.py +++ b/TestCases/tutorials.py @@ -187,7 +187,7 @@ def main(): tutorial_inv_bump.cfg_dir = "../Tutorials/compressible_flow/Inviscid_Bump" tutorial_inv_bump.cfg_file = "inv_channel.cfg" tutorial_inv_bump.test_iter = 0 - tutorial_inv_bump.test_vals = [-1.437425, 4.075857, 0.074137, 0.015325] + tutorial_inv_bump.test_vals = [-1.437425, 4.075857, 0.086038, 0.127546] test_list.append(tutorial_inv_bump) # Inviscid Wedge @@ -195,7 +195,7 @@ def main(): tutorial_inv_wedge.cfg_dir = "../Tutorials/compressible_flow/Inviscid_Wedge" tutorial_inv_wedge.cfg_file = "inv_wedge_HLLC.cfg" tutorial_inv_wedge.test_iter = 0 - tutorial_inv_wedge.test_vals = [-0.481460, 5.253008, -0.260109, 0.045753] + tutorial_inv_wedge.test_vals = [-0.481460, 5.253008, -0.215274, 0.037861] tutorial_inv_wedge.no_restart = True test_list.append(tutorial_inv_wedge) @@ -204,7 +204,7 @@ def main(): tutorial_inv_onera.cfg_dir = "../Tutorials/compressible_flow/Inviscid_ONERAM6" tutorial_inv_onera.cfg_file = "inv_ONERAM6.cfg" tutorial_inv_onera.test_iter = 0 - tutorial_inv_onera.test_vals = [-5.204928, -4.597762, 0.271120, 0.091313] + tutorial_inv_onera.test_vals = [-5.204928, -4.597762, 0.256743, 0.113097] tutorial_inv_onera.no_restart = True test_list.append(tutorial_inv_onera) @@ -213,7 +213,7 @@ def main(): tutorial_lam_cylinder.cfg_dir = "../Tutorials/compressible_flow/Laminar_Cylinder" tutorial_lam_cylinder.cfg_file = "lam_cylinder.cfg" tutorial_lam_cylinder.test_iter = 0 - tutorial_lam_cylinder.test_vals = [-6.162141, -0.699617, -0.085099, 31.790369] + tutorial_lam_cylinder.test_vals = [-6.162141, -0.699617, -0.080518, 43.028531] tutorial_lam_cylinder.no_restart = True test_list.append(tutorial_lam_cylinder) @@ -335,7 +335,7 @@ def main(): tutorial_design_inv_naca0012.cfg_dir = "../Tutorials/design/Inviscid_2D_Unconstrained_NACA0012" tutorial_design_inv_naca0012.cfg_file = "inv_NACA0012_basic.cfg" tutorial_design_inv_naca0012.test_iter = 0 - tutorial_design_inv_naca0012.test_vals = [-3.585391, -2.989014, 0.169476, 0.243426] + tutorial_design_inv_naca0012.test_vals = [-3.585391, -2.989014, 0.146155, 0.179374] tutorial_design_inv_naca0012.no_restart = True test_list.append(tutorial_design_inv_naca0012) diff --git a/TestCases/unsteady/plunging_naca0012/plunging_NACA0012.cfg b/TestCases/unsteady/plunging_naca0012/plunging_NACA0012.cfg index ed803dfc043..92a46396b9b 100644 --- a/TestCases/unsteady/plunging_naca0012/plunging_NACA0012.cfg +++ b/TestCases/unsteady/plunging_naca0012/plunging_NACA0012.cfg @@ -28,7 +28,7 @@ TIME_ITER= 100 MAX_TIME= 0.5888756403287397 % 10 periods: 0.5888756403287397 % -INNER_ITER= 50 +INNER_ITER= 100 % ----------------------- DYNAMIC MESH DEFINITION -----------------------------% % @@ -60,7 +60,7 @@ MARKER_MONITORING= ( airfoil ) % ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% % NUM_METHOD_GRAD= GREEN_GAUSS -CFL_NUMBER= 1.0 +CFL_NUMBER= 250.0 CFL_ADAPT= NO CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) @@ -83,11 +83,12 @@ LINEAR_SOLVER_ITER= 3 % MGLEVEL= 3 MGCYCLE= V_CYCLE -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) MG_DAMP_RESTRICTION= 0.5 MG_DAMP_PROLONGATION= 0.5 +MG_IMPLICIT_LINES= YES % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % @@ -99,7 +100,7 @@ TIME_DISCRE_FLOW= EULER_IMPLICIT % --------------------------- CONVERGENCE PARAMETERS --------------------------% % -CONV_RESIDUAL_MINVAL= -12 +CONV_RESIDUAL_MINVAL= -10 CONV_STARTITER= 1 CONV_CAUCHY_ELEMS= 100 @@ -120,6 +121,6 @@ GRAD_OBJFUNC_FILENAME= of_grad SURFACE_FILENAME= surface_flow SURFACE_ADJ_FILENAME= surface_adjoint SCREEN_OUTPUT= (TIME_ITER, INNER_ITER, RMS_DENSITY, RMS_ENERGY, LIFT, DRAG) -OUTPUT_WRT_FREQ= 1 +OUTPUT_WRT_FREQ= 100 READ_BINARY_RESTART= NO RESTART_ITER= 2 diff --git a/config_template.cfg b/config_template.cfg index 7fefa98aa6f..88533d33c68 100644 --- a/config_template.cfg +++ b/config_template.cfg @@ -1752,10 +1752,10 @@ MGLEVEL= 0 MGCYCLE= V_CYCLE % % Max. iterations for multi-grid pre-smoothing level -MG_PRE_SMOOTH= ( 4, 4, 4, 4 ) +MG_PRE_SMOOTH= ( 2, 2, 2, 2 ) % % Max. iterations for multi-grid post-smoothing level -MG_POST_SMOOTH= ( 4, 4, 4, 4 ) +MG_POST_SMOOTH= ( 2, 2, 2, 2 ) % % Jacobi implicit smoothing of the correction MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) @@ -1780,16 +1780,24 @@ MG_SMOOTH_COEFF= 1.25 % Print a compact per-cycle summary of smoothing iterations and residuals (NO, YES) MG_SMOOTH_OUTPUT= NO % -% Minimum number of control volumes on the coarsest multigrid level. -% Effectively limits the number of multigrid levels. +% Stop smoothing when current_rms >= previous_rms * this value. Values below 1.0 exit +% early on stagnation, 1.0 exits only when the defect grows, 0 disables the check +% (default 0.99) +MG_SMOOTH_STAGNATION_TOL= 0.99 +% +% Minimum number of control volumes on the coarsest multigrid level, counted over the +% whole level rather than per rank, so the hierarchy does not change with the number +% of MPI ranks. A level holding fewer control volumes than this is not created. MG_MIN_MESHSIZE= 500 % -% Enable agglomeration along implicit lines seeded from viscous walls (NO, YES) +% Pave the coarse grid with advancing fronts raised from boundaries that carry a +% stretched layer normal to themselves (NO, YES) MG_IMPLICIT_LINES= NO % -% Maximum nodes on a wall-normal implicit agglomeration line, including the wall seed. -% Increase to extend the line deeper into the boundary layer (default 20). -MG_IMPLICIT_LINES_MAX_LENGTH= 20 +% Per-level CFL scaling factors for the coarse multigrid levels. Entry i is the ratio +% CFL(i+1)/CFL(i). If fewer values than MGLEVEL are given the last one is repeated +% (default 0.25, i.e. a quarter of the CFL per level) +MG_CFL_SCALING= ( 0.25 ) % % Number of iterations spent on each mesh during the Full Multigrid (FMG) startup phase. After % this many iterations the solution is prolongated to the next finer mesh. It is also the length