Skip to content

Commit aa82242

Browse files
Merge branch 'develop' into feature/restart-missing-fields-2483
2 parents 0f864f9 + 732a85c commit aa82242

File tree

12 files changed

+62
-71
lines changed

12 files changed

+62
-71
lines changed

Common/include/option_structure.hpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -91,23 +91,23 @@ const unsigned int ZONE_0 = 0; /*!< \brief Definition of the first grid domain.
9191
const unsigned int ZONE_1 = 1; /*!< \brief Definition of the second grid domain. */
9292
const unsigned int INST_0 = 0; /*!< \brief Definition of the first instance per grid level. */
9393

94-
const su2double STANDARD_GRAVITY = 9.80665; /*!< \brief Acceleration due to gravity at surface of earth. */
95-
const su2double UNIVERSAL_GAS_CONSTANT = 8.3144598; /*!< \brief Universal gas constant in J/(mol*K) */
96-
const su2double BOLTZMANN_CONSTANT = 1.3806503E-23; /*!< \brief Boltzmann's constant [J K^-1] */
97-
const su2double AVOGAD_CONSTANT = 6.0221415E26; /*!< \brief Avogadro's constant, number of particles in one kmole. */
98-
const su2double FUND_ELEC_CHARGE_CGS = 4.8032047E-10; /*!< \brief Fundamental electric charge in CGS units, cm^(3/2) g^(1/2) s^(-1). */
94+
constexpr passivedouble STANDARD_GRAVITY = 9.80665; /*!< \brief Acceleration due to gravity at surface of earth. */
95+
constexpr passivedouble UNIVERSAL_GAS_CONSTANT = 8.3144598; /*!< \brief Universal gas constant in J/(mol*K) */
96+
constexpr passivedouble BOLTZMANN_CONSTANT = 1.3806503E-23; /*!< \brief Boltzmann's constant [J K^-1] */
97+
constexpr passivedouble AVOGAD_CONSTANT = 6.0221415E26; /*!< \brief Avogadro's constant, number of particles in one kmole. */
98+
constexpr passivedouble FUND_ELEC_CHARGE_CGS = 4.8032047E-10; /*!< \brief Fundamental electric charge in CGS units, cm^(3/2) g^(1/2) s^(-1). */
9999

100-
const su2double EPS = 1.0E-16; /*!< \brief Error scale. */
101-
const su2double TURB_EPS = 1.0E-16; /*!< \brief Turbulent Error scale. */
100+
constexpr passivedouble EPS = 1.0E-16; /*!< \brief Error scale. */
101+
constexpr passivedouble TURB_EPS = 1.0E-16; /*!< \brief Turbulent Error scale. */
102102

103-
const su2double ONE2 = 0.5; /*!< \brief One divided by two. */
104-
const su2double ONE3 = 1.0 / 3.0; /*!< \brief One divided by three. */
105-
const su2double TWO3 = 2.0 / 3.0; /*!< \brief Two divided by three. */
106-
const su2double FOUR3 = 4.0 / 3.0; /*!< \brief Four divided by three. */
103+
constexpr passivedouble ONE2 = 0.5; /*!< \brief One divided by two. */
104+
constexpr passivedouble ONE3 = 1.0 / 3.0; /*!< \brief One divided by three. */
105+
constexpr passivedouble TWO3 = 2.0 / 3.0; /*!< \brief Two divided by three. */
106+
constexpr passivedouble FOUR3 = 4.0 / 3.0; /*!< \brief Four divided by three. */
107107

108-
const su2double PI_NUMBER = 4.0 * atan(1.0); /*!< \brief Pi number. */
108+
constexpr passivedouble PI_NUMBER = 3.14159265358979323846; /*!< \brief Pi number (not using M_PI to avoid Windows issues). */
109109

110-
const su2double STEFAN_BOLTZMANN = 5.670367E-08; /*!< \brief Stefan-Boltzmann constant in W/(m^2*K^4). */
110+
constexpr passivedouble STEFAN_BOLTZMANN = 5.670367E-08; /*!< \brief Stefan-Boltzmann constant in W/(m^2*K^4). */
111111

112112
const int MASTER_NODE = 0; /*!< \brief Master node for MPI parallelization. */
113113
const int SINGLE_NODE = 1; /*!< \brief There is only a node in the MPI parallelization. */
@@ -195,7 +195,7 @@ const int SU2_CONN_SIZE = 10; /*!< \brief Size of the connectivity array that
195195
that we read from a mesh file in the format [[globalID vtkType n0 n1 n2 n3 n4 n5 n6 n7 n8]. */
196196
const int SU2_CONN_SKIP = 2; /*!< \brief Offset to skip the globalID and VTK type at the start of the element connectivity list for each CGNS element. */
197197

198-
const su2double COLORING_EFF_THRESH = 0.875; /*!< \brief Below this value fallback strategies are used instead. */
198+
constexpr passivedouble COLORING_EFF_THRESH = 0.875; /*!< \brief Below this value fallback strategies are used instead. */
199199

200200
/*--- All temperature polynomial fits for the fluid models currently
201201
assume a quartic form (5 coefficients). For example,

SU2_CFD/include/numerics_simd/flow/convection/common.hpp

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@
3434

3535
/*!
3636
* \brief Blended difference for U-MUSCL reconstruction.
37-
* \param[in] grad_proj - Gradient projection at point i: dot(grad_i, vector_ij).
37+
* \param[in] gradProj - Gradient projection at point i: dot(grad_i, vector_ij).
3838
* \param[in] delta - Centered difference: V_j - V_i.
3939
* \param[in] kappa - Blending parameter.
4040
* \return Blended difference for reconstruction from point i.
4141
*/
42-
FORCEINLINE Double umusclProjection(Double grad_proj,
42+
FORCEINLINE Double umusclProjection(Double gradProj,
4343
Double delta,
4444
Double kappa) {
4545
/*-------------------------------------------------------------------*/
@@ -51,7 +51,7 @@ FORCEINLINE Double umusclProjection(Double grad_proj,
5151
/*--- To maintain proper scaling for edge limiters, the result of ---*/
5252
/*--- this function is 0.5 * dV_ij^kap. ---*/
5353
/*-------------------------------------------------------------------*/
54-
return (1.0 - kappa) * grad_proj + kappa * delta;
54+
return (1.0 - kappa) * gradProj + kappa * delta;
5555
}
5656

5757
/*!
@@ -62,7 +62,7 @@ FORCEINLINE Double umusclProjection(Double grad_proj,
6262
* \param[in] delta - Centered difference: V_j - V_i.
6363
* \param[in] iVar - Variable index.
6464
* \param[in] kappa - Blending coefficient.
65-
* \param[in] relax - Newton-Krylov relaxation.
65+
* \param[in] umusclRamp - MUSCL 1st-2nd order ramp times Newton-Krylov relaxation.
6666
* \return Variable reconstructed from point i.
6767
*/
6868
template<class GradType, size_t nDim>
@@ -71,10 +71,9 @@ FORCEINLINE Double musclReconstruction(const GradType& grad,
7171
const Double delta,
7272
size_t iVar,
7373
Double kappa,
74-
Double relax,
75-
Double ramp_val) {
74+
Double umusclRamp) {
7675
const Double proj = dot(grad[iVar], vector_ij);
77-
return ramp_val * relax * umusclProjection(proj, delta, kappa);
76+
return umusclRamp * umusclProjection(proj, delta, kappa);
7877
}
7978

8079
/*!
@@ -87,8 +86,7 @@ FORCEINLINE void musclUnlimited(Int iPoint,
8786
const Gradient_t& gradient,
8887
CPair<VarType>& V,
8988
Double kappa,
90-
Double relax,
91-
Double ramp_val) {
89+
Double umusclRamp) {
9290
constexpr auto nVarGrad = nVarGrad_ > 0 ? nVarGrad_ : VarType::nVar;
9391

9492
auto grad_i = gatherVariables<nVarGrad,nDim>(iPoint, gradient);
@@ -99,8 +97,8 @@ FORCEINLINE void musclUnlimited(Int iPoint,
9997
const Double delta_ij = V.j.all(iVar) - V.i.all(iVar);
10098

10199
/*--- U-MUSCL reconstructed variables ---*/
102-
const Double proj_i = musclReconstruction(grad_i, vector_ij, delta_ij, iVar, kappa, relax, ramp_val);
103-
const Double proj_j = musclReconstruction(grad_j, vector_ij, delta_ij, iVar, kappa, relax, ramp_val);
100+
const Double proj_i = musclReconstruction(grad_i, vector_ij, delta_ij, iVar, kappa, umusclRamp);
101+
const Double proj_j = musclReconstruction(grad_j, vector_ij, delta_ij, iVar, kappa, umusclRamp);
104102

105103
/*--- Apply reconstruction: V_L = V_i + 0.5 * dV_ij^kap ---*/
106104
V.i.all(iVar) += 0.5 * proj_i;
@@ -119,8 +117,7 @@ FORCEINLINE void musclPointLimited(Int iPoint,
119117
const Gradient_t& gradient,
120118
CPair<VarType>& V,
121119
Double kappa,
122-
Double relax,
123-
Double ramp_val) {
120+
Double umusclRamp) {
124121
constexpr auto nVarGrad = nVarGrad_ > 0 ? nVarGrad_ : VarType::nVar;
125122

126123
auto lim_i = gatherVariables<nVarGrad>(iPoint, limiter);
@@ -134,8 +131,8 @@ FORCEINLINE void musclPointLimited(Int iPoint,
134131
const Double delta_ij = V.j.all(iVar) - V.i.all(iVar);
135132

136133
/*--- U-MUSCL reconstructed variables ---*/
137-
const Double proj_i = musclReconstruction(grad_i, vector_ij, delta_ij, iVar, kappa, relax, ramp_val);
138-
const Double proj_j = musclReconstruction(grad_j, vector_ij, delta_ij, iVar, kappa, relax, ramp_val);
134+
const Double proj_i = musclReconstruction(grad_i, vector_ij, delta_ij, iVar, kappa, umusclRamp);
135+
const Double proj_j = musclReconstruction(grad_j, vector_ij, delta_ij, iVar, kappa, umusclRamp);
139136

140137
/*--- Apply reconstruction: V_L = V_i + 0.5 * lim * dV_ij^kap ---*/
141138
V.i.all(iVar) += 0.5 * lim_i(iVar) * proj_i;
@@ -153,8 +150,7 @@ FORCEINLINE void musclEdgeLimited(Int iPoint,
153150
const Gradient_t& gradient,
154151
CPair<VarType>& V,
155152
Double kappa,
156-
Double relax,
157-
Double ramp_val) {
153+
Double umusclRamp) {
158154
constexpr auto nVarGrad = nVarGrad_ > 0 ? nVarGrad_ : VarType::nVar;
159155

160156
auto grad_i = gatherVariables<nVarGrad,nDim>(iPoint, gradient);
@@ -166,8 +162,8 @@ FORCEINLINE void musclEdgeLimited(Int iPoint,
166162
const Double delta_ij_2 = pow(delta_ij, 2) + 1e-6;
167163

168164
/*--- U-MUSCL reconstructed variables ---*/
169-
const Double proj_i = musclReconstruction(grad_i, vector_ij, delta_ij, iVar, kappa, relax, ramp_val);
170-
const Double proj_j = musclReconstruction(grad_j, vector_ij, delta_ij, iVar, kappa, relax, ramp_val);
165+
const Double proj_i = musclReconstruction(grad_i, vector_ij, delta_ij, iVar, kappa, umusclRamp);
166+
const Double proj_j = musclReconstruction(grad_j, vector_ij, delta_ij, iVar, kappa, umusclRamp);
171167

172168
/// TODO: Customize the limiter function.
173169
const Double lim_i = (delta_ij_2 + proj_i*delta_ij) / (pow(proj_i,2) + delta_ij_2);
@@ -187,7 +183,7 @@ FORCEINLINE void musclEdgeLimited(Int iPoint,
187183
* \param[in] gasConst - Specific gas constant.
188184
* \param[in] muscl - If true, reconstruct, else simply fetch.
189185
* \param[in] kappa - Blending coefficient for MUSCL reconstruction.
190-
* \param[in] relax - Newton-Krylov relaxation.
186+
* \param[in] umusclRamp - MUSCL 1st-2nd order ramp times Newton-Krylov relaxation.
191187
* \param[in] limiterType - Type of flux limiter.
192188
* \param[in] V1st - Pair of compressible flow primitives for nodes i,j.
193189
* \param[in] vector_ij - Distance vector from i to j.
@@ -200,12 +196,11 @@ FORCEINLINE CPair<ReconVarType> reconstructPrimitives(Int iEdge, Int iPoint, Int
200196
const su2double& gasConst,
201197
bool muscl,
202198
const su2double& kappa,
203-
const su2double& relax,
199+
const su2double& umusclRamp,
204200
LIMITER limiterType,
205201
const CPair<PrimVarType>& V1st,
206202
const VectorDbl<nDim>& vector_ij,
207-
const VariableType& solution,
208-
const su2double& ramp_val) {
203+
const VariableType& solution) {
209204
static_assert(ReconVarType::nVar <= PrimVarType::nVar);
210205

211206
const auto& gradients = solution.GetGradient_Reconstruction();
@@ -223,13 +218,13 @@ FORCEINLINE CPair<ReconVarType> reconstructPrimitives(Int iEdge, Int iPoint, Int
223218
constexpr auto nVarGrad = ReconVarType::nVar - 2;
224219
switch (limiterType) {
225220
case LIMITER::NONE:
226-
musclUnlimited<nVarGrad>(iPoint, jPoint, vector_ij, gradients, V, kappa, relax, ramp_val);
221+
musclUnlimited<nVarGrad>(iPoint, jPoint, vector_ij, gradients, V, kappa, umusclRamp);
227222
break;
228223
case LIMITER::VAN_ALBADA_EDGE:
229-
musclEdgeLimited<nVarGrad>(iPoint, jPoint, vector_ij, gradients, V, kappa, relax, ramp_val);
224+
musclEdgeLimited<nVarGrad>(iPoint, jPoint, vector_ij, gradients, V, kappa, umusclRamp);
230225
break;
231226
default:
232-
musclPointLimited<nVarGrad>(iPoint, jPoint, vector_ij, limiters, gradients, V, kappa, relax, ramp_val);
227+
musclPointLimited<nVarGrad>(iPoint, jPoint, vector_ij, limiters, gradients, V, kappa, umusclRamp);
233228
break;
234229
}
235230
/*--- Recompute density using the reconstructed pressure and temperature. ---*/

SU2_CFD/include/numerics_simd/flow/convection/roe.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class CRoeBase : public Base {
9898
AD::StartPreacc();
9999

100100
const bool implicit = (config.GetKind_TimeIntScheme() == EULER_IMPLICIT);
101-
const auto nkRelax = config.GetNewtonKrylovRelaxation();
101+
const su2double umusclRamp = config.GetMUSCLRampValue() * config.GetNewtonKrylovRelaxation();
102102
const auto& solution = static_cast<const CEulerVariable&>(solution_);
103103

104104
const auto iPoint = geometry.edges->GetNode(iEdge,0);
@@ -123,7 +123,7 @@ class CRoeBase : public Base {
123123

124124
/*--- Recompute density and enthalpy instead of reconstructing. ---*/
125125
auto V = reconstructPrimitives<CCompressiblePrimitives<nDim,nPrimVarGrad> >(
126-
iEdge, iPoint, jPoint, gamma, gasConst, muscl, umusclKappa, nkRelax, typeLimiter, V1st, vector_ij, solution, config.GetMUSCLRampValue());
126+
iEdge, iPoint, jPoint, gamma, gasConst, muscl, umusclKappa, umusclRamp, typeLimiter, V1st, vector_ij, solution);
127127

128128
/*--- Compute conservative variables. ---*/
129129

SU2_CFD/include/solvers/CScalarSolver.inl

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ void CScalarSolver<VariableType>::Upwind_Residual(CGeometry* geometry, CSolver**
145145
/*--- U-MUSCL reconstruction ---*/
146146
const su2double kappa = config->GetMUSCL_Kappa();
147147
const su2double kappaFlow = config->GetMUSCL_Kappa_Flow();
148+
const su2double musclRamp = config->GetMUSCLRampValue();
148149

149150
auto* flowNodes = su2staticcast_p<CFlowVariable*>(solver_container[FLOW_SOL]->GetNodes());
150151
const auto& edgeMassFluxes = *(solver_container[FLOW_SOL]->GetEdgeMassFluxes());
@@ -222,8 +223,8 @@ void CScalarSolver<VariableType>::Upwind_Residual(CGeometry* geometry, CSolver**
222223
for (auto iVar = 0u; iVar < solver_container[FLOW_SOL]->GetnPrimVarGrad(); iVar++) {
223224
const su2double V_ij = V_j[iVar] - V_i[iVar];
224225

225-
su2double Project_Grad_i = MUSCL_Reconstruction(Gradient_i[iVar], Vector_ij, V_ij, kappaFlow, config->GetMUSCLRampValue());
226-
su2double Project_Grad_j = MUSCL_Reconstruction(Gradient_j[iVar], Vector_ij, V_ij, kappaFlow, config->GetMUSCLRampValue());
226+
su2double Project_Grad_i = MUSCL_Reconstruction(Gradient_i[iVar], Vector_ij, V_ij, kappaFlow, musclRamp);
227+
su2double Project_Grad_j = MUSCL_Reconstruction(Gradient_j[iVar], Vector_ij, V_ij, kappaFlow, musclRamp);
227228

228229
if (limiterFlow) {
229230
Project_Grad_i *= Limiter_i[iVar];
@@ -251,8 +252,8 @@ void CScalarSolver<VariableType>::Upwind_Residual(CGeometry* geometry, CSolver**
251252
for (auto iVar = 0u; iVar < nVar; iVar++) {
252253
const su2double U_ij = Scalar_j[iVar] - Scalar_i[iVar];
253254

254-
su2double Project_Grad_i = MUSCL_Reconstruction(Gradient_i[iVar], Vector_ij, U_ij, kappa, config->GetMUSCLRampValue());
255-
su2double Project_Grad_j = MUSCL_Reconstruction(Gradient_j[iVar], Vector_ij, U_ij, kappa, config->GetMUSCLRampValue());
255+
su2double Project_Grad_i = MUSCL_Reconstruction(Gradient_i[iVar], Vector_ij, U_ij, kappa, musclRamp);
256+
su2double Project_Grad_j = MUSCL_Reconstruction(Gradient_j[iVar], Vector_ij, U_ij, kappa, musclRamp);
256257

257258
if (limiter) {
258259
Project_Grad_i *= Limiter_i[iVar];

SU2_CFD/include/solvers/CSolver.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -587,10 +587,11 @@ class CSolver {
587587
* \param[in] vector_ij - Distance vector.
588588
* \param[in] delta_ij - Centered difference.
589589
* \param[in] kappa - Blending coefficient for U-MUSCL reconstruction.
590-
* \param[in] ramp_val - Value of the ramp
590+
* \param[in] ramp_val - Value of the 1st-2nd order MUSCL ramp.
591591
* \return - Projected variable.
592592
*/
593-
inline su2double MUSCL_Reconstruction(const su2double* grad, const su2double* vector_ij, su2double delta_ij, su2double kappa, su2double ramp_val) {
593+
FORCEINLINE su2double MUSCL_Reconstruction(const su2double* grad, const su2double* vector_ij, su2double delta_ij,
594+
su2double kappa, su2double ramp_val) const {
594595
su2double project_grad = GeometryToolbox::DotProduct(nDim, grad, vector_ij);
595596
return ramp_val * LimiterHelpers<>::umusclProjection(project_grad, delta_ij, kappa);
596597
}

SU2_CFD/src/integration/CNewtonIntegration.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -184,15 +184,11 @@ void CNewtonIntegration::MultiGrid_Iteration(CGeometry ****geometry_, CSolver **
184184

185185
if (!setup) { Setup(); setup = true; }
186186

187-
// Ramp from 1st to 2nd order during the startup.
188-
su2double baseNkRelaxation = 1;
189-
if (startupPeriod && startupIters > 0 && !config->GetRestart()) {
190-
baseNkRelaxation = su2double(startupIters - iter) / startupIters;
191-
}
192-
config->SetNewtonKrylovRelaxation(baseNkRelaxation);
187+
/*--- Remove NK relaxation to compute the current residual. ---*/
188+
config->SetNewtonKrylovRelaxation(1.0);
193189

194-
// When using NK relaxation (not fully 2nd order Jacobian products) we need an additional
195-
// residual evaluation that is used as the reference for finite differences.
190+
/*--- When using NK relaxation (not fully 2nd order Jacobian products) we need an additional
191+
* residual evaluation that is used as the reference for finite differences. ---*/
196192
LinSysRes0 = (!startupPeriod && nkRelaxation < 1) ? &LinSysResRelax : &LinSysRes;
197193

198194
SU2_OMP_PARALLEL_(if(solvers[FLOW_SOL]->GetHasHybridParallel())) {

SU2_CFD/src/iteration/CFluidIteration.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ void CFluidIteration::UpdateRamp(CGeometry**** geometry_container, CConfig** con
348348
config->SetMUSCLRampValue(std::pow(std::min<double>(1.0, iterFrac), RampMUSCLParam.RampMUSCLPower));
349349
break;
350350
case MUSCL_RAMP_TYPE::SMOOTH_FUNCTION:
351-
config->SetMUSCLRampValue(std::pow((0.5 * (1 - cos(M_PI * std::min(1.0, iterFrac)))), RampMUSCLParam.RampMUSCLPower));
351+
config->SetMUSCLRampValue(std::pow((0.5 * (1 - cos(PI_NUMBER * std::min(1.0, iterFrac)))), RampMUSCLParam.RampMUSCLPower));
352352
break;
353353
default:
354354
break;

SU2_CFD/src/solvers/CEulerSolver.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,7 +1799,6 @@ void CEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_contain
17991799
}
18001800

18011801
const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT);
1802-
const su2double nkRelax = config->GetNewtonKrylovRelaxation();
18031802

18041803
const bool roe_turkel = (config->GetKind_Upwind_Flow() == UPWIND::TURKEL);
18051804
const auto kind_dissipation = config->GetKind_RoeLowDiss();
@@ -1809,6 +1808,7 @@ void CEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_contain
18091808
const bool van_albada = (config->GetKind_SlopeLimit_Flow() == LIMITER::VAN_ALBADA_EDGE);
18101809

18111810
const su2double kappa = config->GetMUSCL_Kappa_Flow();
1811+
const su2double musclRamp = config->GetMUSCLRampValue() * config->GetNewtonKrylovRelaxation();
18121812

18131813
/*--- Non-physical counter. ---*/
18141814
unsigned long counter_local = 0;
@@ -1886,8 +1886,8 @@ void CEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_contain
18861886
for (auto iVar = 0u; iVar < nPrimVarGrad; iVar++) {
18871887
const su2double V_ij = V_j[iVar] - V_i[iVar];
18881888

1889-
const su2double Project_Grad_i = nkRelax * MUSCL_Reconstruction(Gradient_i[iVar], Vector_ij, V_ij, kappa, config->GetMUSCLRampValue());
1890-
const su2double Project_Grad_j = nkRelax * MUSCL_Reconstruction(Gradient_j[iVar], Vector_ij, V_ij, kappa, config->GetMUSCLRampValue());
1889+
const su2double Project_Grad_i = MUSCL_Reconstruction(Gradient_i[iVar], Vector_ij, V_ij, kappa, musclRamp);
1890+
const su2double Project_Grad_j = MUSCL_Reconstruction(Gradient_j[iVar], Vector_ij, V_ij, kappa, musclRamp);
18911891

18921892
su2double lim_i = 1.0;
18931893
su2double lim_j = 1.0;

0 commit comments

Comments
 (0)