Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions Common/include/CConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1277,6 +1277,18 @@ class CConfig {
/*--- Additional flamelet solver options ---*/
FluidFlamelet_ParsedOptions flamelet_ParsedOptions; /*!< \brief Additional flamelet solver options */

/*--- Mesh adaptation options ---*/
bool Compute_Metric; /*!< \brief Determines if error estimation is taking place */
bool Normalize_Metric; /*!< \brief Determines if metric tensor normalization is taking place */
unsigned short Kind_Hessian_Method; /*!< \brief Numerical method for computation of Hessians. */
unsigned short nMetric_Sensor; /*!< \brief Number of sensors to use for adaptation. */
METRIC_SENSOR* Metric_Sensor; /*!< \brief Sensors to use for adaptation. */
unsigned short Metric_Norm; /*!< \brief Lp-norm for mesh adaptation */
unsigned long Metric_Complexity; /*!< \brief Constraint mesh complexity */
su2double Metric_Hmax, /*!< \brief Maximum cell size */
Metric_Hmin, /*!< \brief Minimum cell size */
Metric_ARmax; /*!< \brief Maximum cell aspect ratio */

/*!
* \brief Set the default values of config options not set in the config file using another config object.
* \param config - Config object to use the default values from.
Expand Down Expand Up @@ -10142,4 +10154,101 @@ class CConfig {
*/
const FluidFlamelet_ParsedOptions& GetFlameletParsedOptions() const { return flamelet_ParsedOptions; }

/*!
* \brief Check if a metric tensor field is being computed
* \return <code>TRUE<\code> if a metric tensor field is being computed
*/
bool GetCompute_Metric(void) const { return Compute_Metric; }

/*!
* \brief Check if metric tensor normalization is being carried out
* \return <code>TRUE<\code> if metric normalization is taking place
*/
bool GetNormalize_Metric(void) const { return Normalize_Metric; }

/*!
* \brief Get the kind of method for computation of Hessians used for anisotropy.
* \return Numerical method for computation of Hessians used for anisotropy.
*/
unsigned short GetKind_Hessian_Method(void) const { return Kind_Hessian_Method; }

/*!
* \brief Get adaptation sensor
*/
METRIC_SENSOR GetMetric_Sensor(unsigned short iSens) const { return Metric_Sensor[iSens]; }

/*!
* \brief Get corresponding string from metric sensor type
*/
string GetMetric_SensorString(unsigned short iSens) const {
string sensor_name;
switch (Metric_Sensor[iSens]) {
case METRIC_SENSOR::DENSITY:
sensor_name = "Density";
break;
case METRIC_SENSOR::MACH:
sensor_name = "Mach";
break;
case METRIC_SENSOR::PRESSURE:
sensor_name = "Pressure";
break;
case METRIC_SENSOR::TOTAL_PRESSURE:
sensor_name = "Total Pressure";
break;
case METRIC_SENSOR::TEMPERATURE:
sensor_name = "Temperature";
break;
case METRIC_SENSOR::TEMPERATURE_VE:
sensor_name = "Temperature_ve";
break;
case METRIC_SENSOR::ENERGY:
sensor_name = "Energy";
break;
case METRIC_SENSOR::ENERGY_VE:
sensor_name = "Energy_ve";
break;
case METRIC_SENSOR::GOAL:
sensor_name = "Goal";
break;
default:
SU2_MPI::Error("Unsupported metric sensor.", CURRENT_FUNCTION);
}

return sensor_name;
}

/*!
* \brief Get number of adaptation sensors
*/
unsigned short GetnMetric_Sensor(void) const { return nMetric_Sensor; }

/*!
* \brief Get adaptation norm value (Lp)
*/
unsigned short GetMetric_Norm(void) const { return Metric_Norm; }

/*!
* \brief Get maximum cell size
* \return Maximum cell size
*/
su2double GetMetric_Hmax(void) const { return Metric_Hmax; }

/*!
* \brief Get minimum cell size
* \return Minimum cell size
*/
su2double GetMetric_Hmin(void) const { return Metric_Hmin; }

/*!
* \brief Get maximum cell aspect ratio
* \return Maximum cell aspect ratio
*/
su2double GetMetric_ARmax(void) const { return Metric_ARmax; }

/*!
* \brief Get constraint complexity
* \return Mesh complexity
*/
unsigned long GetMetric_Complexity(void) const { return Metric_Complexity; }

};
30 changes: 30 additions & 0 deletions Common/include/option_structure.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2621,6 +2621,8 @@ enum PERIODIC_QUANTITIES {
PERIODIC_LIM_PRIM_1 , /*!< \brief Primitive limiter communication phase 1 of 2 (periodic only). */
PERIODIC_LIM_PRIM_2 , /*!< \brief Primitive limiter communication phase 2 of 2 (periodic only). */
PERIODIC_IMPLICIT , /*!< \brief Implicit update communication to ensure consistency across periodic boundaries. */
PERIODIC_GRAD_ADAPT , /*!< \brief Gradient vectors for anisotropic sizing metric (periodic only). */
PERIODIC_HESSIAN , /*!< \brief Hessian tensors for anisotropic sizing metric (periodic only). */
};

/*!
Expand Down Expand Up @@ -2652,6 +2654,8 @@ enum class MPI_QUANTITIES {
MESH_DISPLACEMENTS , /*!< \brief Mesh displacements at the interface. */
SOLUTION_TIME_N , /*!< \brief Solution at time n. */
SOLUTION_TIME_N1 , /*!< \brief Solution at time n-1. */
GRADIENT_ADAPT , /*!< \brief Gradient vectors for anisotropic sizing metric tensor. */
HESSIAN , /*!< \brief Hessian tensors for anisotropic sizing metric tensor. */
};

/*!
Expand Down Expand Up @@ -2797,6 +2801,32 @@ static const MapType<std::string, ENUM_SOBOLEV_MODUS> Sobolev_Modus_Map = {
MakePair("ONLY_GRADIENT", ENUM_SOBOLEV_MODUS::ONLY_GRAD)
};

/*!
* \brief Types of sensors for anisotropic metric
*/
enum class METRIC_SENSOR {
DENSITY, /*!< \brief Density feature-based metric. */
MACH, /*!< \brief Mach feature-based metric. */
PRESSURE, /*!< \brief Pressure feature-based metric. */
TOTAL_PRESSURE, /*!< \brief Total pressure feature-based metric. */
TEMPERATURE, /*!< \brief Temperature feature-based metric. */
TEMPERATURE_VE, /*!< \brief Vibrational/electronic temperature feature-based metric. */
ENERGY, /*!< \brief Energy feature-based metric. */
ENERGY_VE, /*!< \brief Vibrational/electronic energy feature-based metric. */
GOAL, /*!< \brief Goal-oriented metric. */
};
static const MapType<std::string, METRIC_SENSOR> Metric_Sensor_Map = {
MakePair("DENSITY", METRIC_SENSOR::DENSITY)
MakePair("MACH", METRIC_SENSOR::MACH)
MakePair("PRESSURE", METRIC_SENSOR::PRESSURE)
MakePair("TOTAL_PRESSURE", METRIC_SENSOR::TOTAL_PRESSURE)
MakePair("TEMPERATURE", METRIC_SENSOR::TEMPERATURE)
MakePair("TEMPERATURE_VE", METRIC_SENSOR::TEMPERATURE_VE)
MakePair("ENERGY", METRIC_SENSOR::ENERGY)
MakePair("ENERGY_VE", METRIC_SENSOR::ENERGY_VE)
MakePair("GOAL", METRIC_SENSOR::GOAL)
};

/*!
* \brief Type of mesh deformation
*/
Expand Down
103 changes: 103 additions & 0 deletions Common/src/CConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3034,6 +3034,55 @@
/*!\brief ROM_SAVE_FREQ \n DESCRIPTION: How often to save snapshots for unsteady problems.*/
addUnsignedShortOption("ROM_SAVE_FREQ", rom_save_freq, 1);

/*--- options that are used for mesh adaptation ---*/
/*!\par CONFIG_CATEGORY:Adaptation Options \ingroup Config*/

/*!\brief COMPUTE_METRIC \n DESCRIPTION: Compute a metric tensor field */
addBoolOption("COMPUTE_METRIC", Compute_Metric, false);
/*!\brief NORMALIZE_METRIC \n DESCRIPTION: Normalize the metric tensor */
addBoolOption("NORMALIZE_METRIC", Normalize_Metric, true);
/*!\brief NUM_METHOD_HESS \n DESCRIPTION: Numerical method for Hessian computation \n OPTIONS: See \link Gradient_Map \endlink. \n DEFAULT: GREEN_GAUSS. \ingroup Config*/
addEnumOption("NUM_METHOD_HESS", Kind_Hessian_Method, Gradient_Map, GREEN_GAUSS);

/*!\brief METRIC_SENSOR \n DESCRIPTION: Sensors for mesh adaptation */
addEnumListOption("METRIC_SENSOR", nMetric_Sensor, Metric_Sensor, Metric_Sensor_Map);
/*!\brief METRIC_NORM \n DESCRIPTION: Lp-norm for mesh adaptation */
addUnsignedShortOption("METRIC_NORM", Metric_Norm, 2);
/*!\brief METRIC_COMPLEXITY \n DESCRIPTION: Constraint mesh complexity */
addUnsignedLongOption("METRIC_COMPLEXITY", Metric_Complexity, 10000);

/*!\brief METRIC_HMAX \n DESCRIPTION: Constraint maximum cell size */
addDoubleOption("METRIC_HMAX", Metric_Hmax, 10.0);
/*!\brief METRIC_HMIN \n DESCRIPTION: Constraint minimum cell size */
addDoubleOption("METRIC_HMIN", Metric_Hmin, 1.0E-8);
/*!\brief METRIC_ARMAX \n DESCRIPTION: Constraint maximum cell aspect ratio */
addDoubleOption("METRIC_ARMAX", Metric_ARmax, 1.0E6);

/*!\brief ADAP_ITER \n DESCRIPTION: Mesh adaptation inner iterations per complexity */
addPythonOption("ADAP_ITER");
/*!\brief ADAP_COMPLEXITIES \n DESCRIPTION: List of constraint (target) mesh complexities for mesh convergence study */
addPythonOption("ADAP_COMPLEXITIES");
/*!\brief ADAP_FLOW_ITERS \n DESCRIPTION: Primal solver iterations at each target complexity */
addPythonOption("ADAP_FLOW_ITERS");
/*!\brief ADAP_ADJ_ITERS \n DESCRIPTION: Adjoint solver iterations at each target complexity */
addPythonOption("ADAP_ADJ_ITERS");
/*!\brief ADAP_FLOW_CFLS \n DESCRIPTION: Primal solver CFL number at each target complexity */
addPythonOption("ADAP_FLOW_CFLS");
/*!\brief ADAP_ADJ_CFLS \n DESCRIPTION: Adjoint solver CFL number at each target complexity */
addPythonOption("ADAP_ADJ_CFLS");
/*!\brief ADAP_RESIDUAL_REDUCTIONS \n DESCRIPTION: Residual reduction at each target complexity */
addPythonOption("ADAP_RESIDUAL_REDUCTIONS");
/*!\brief ADAP_HMAXS \n DESCRIPTION: Maximum cell size at each target complexity */
addPythonOption("ADAP_HMAXS");
/*!\brief ADAP_HMINS \n DESCRIPTION: Minimum cell size at each target complexity */
addPythonOption("ADAP_HMINS");
/*!\brief ADAP_HGRAD \n DESCRIPTION: Size gradation smoothing parameter */
addPythonOption("ADAP_HGRAD");
/*!\brief ADAP_HAUSD \n DESCRIPTION: Hausdorff distance parameter for surface remeshing */
addPythonOption("ADAP_HAUSD");
/*!\brief ADAP_ANGLE \n DESCRIPTION: Sharp angle detection parameter for surface remeshing */
addPythonOption("ADAP_ANGLE");

/* END_CONFIG_OPTIONS */

}
Expand Down Expand Up @@ -5752,6 +5801,36 @@
SU2_MPI::Error("BOUNDED_SCALAR discretization can only be used for incompressible problems.", CURRENT_FUNCTION);
}

/*--- Checks for mesh adaptation ---*/
if (Compute_Metric) {
/*--- Check that config is valid for requested sensor ---*/
for (auto iSensor = 0; iSensor < nMetric_Sensor; iSensor++) {
/*--- TODO: If using GOAL, it must be the only sensor and the discrete adjoint must be used ---*/
/*--- For now, goal-oriented adaptation is unsupported ---*/
if (Metric_Sensor[iSensor] == METRIC_SENSOR::GOAL) {
SU2_MPI::Error("Adaptation sensor GOAL not yet supported.", CURRENT_FUNCTION);
}

if (Kind_Solver == MAIN_SOLVER::NEMO_EULER || Kind_Solver == MAIN_SOLVER::NEMO_NAVIER_STOKES) {
if (Metric_Sensor[iSensor] == METRIC_SENSOR::DENSITY || Metric_Sensor[iSensor] == METRIC_SENSOR::TOTAL_PRESSURE)
SU2_MPI::Error(string("Adaptation sensor ") + GetMetric_SensorString(iSensor) + string(" not available for NEMO problems."), CURRENT_FUNCTION);
}
if (Kind_Solver != MAIN_SOLVER::NEMO_EULER && Kind_Solver != MAIN_SOLVER::NEMO_NAVIER_STOKES) {
if (Metric_Sensor[iSensor] == METRIC_SENSOR::TEMPERATURE_VE || Metric_Sensor[iSensor] == METRIC_SENSOR::ENERGY_VE)
SU2_MPI::Error(string("Adaptation sensor ") + GetMetric_SensorString(iSensor) + string(" not available for non-NEMO problems."), CURRENT_FUNCTION);
}
if (Kind_Solver == MAIN_SOLVER::INC_EULER || Kind_Solver == MAIN_SOLVER::INC_NAVIER_STOKES || Kind_Solver == MAIN_SOLVER::INC_RANS) {
if (Metric_Sensor[iSensor] == METRIC_SENSOR::MACH)
SU2_MPI::Error(string("Adaptation sensor ") + GetMetric_SensorString(iSensor) + string(" not available for INC problems."), CURRENT_FUNCTION);
}
}

/*--- Only GG Hessians for now ---*/
if (Kind_Hessian_Method != GREEN_GAUSS) {
SU2_MPI::Error("NUM_METHOD_HESS must be GREEN_GAUSS.", CURRENT_FUNCTION);
}
}

}

void CConfig::SetMarkers(SU2_COMPONENT val_software) {
Expand Down Expand Up @@ -7925,6 +8004,30 @@
cout << "Actuator disk BEM method propeller data read from file: " << GetBEM_prop_filename() << endl;
}
}

if (val_software == SU2_COMPONENT::SU2_CFD || val_software == SU2_COMPONENT::SU2_SOL) {
if (Compute_Metric) {
cout << endl <<"---------------- Mesh Adaptation Information ( Zone " << iZone << " ) -----------------" << endl;
cout << "Adaptation sensor(s): ";
for (auto iSensor = 0; iSensor < nMetric_Sensor; iSensor++) {
cout << GetMetric_SensorString(iSensor);
if (iSensor < nMetric_Sensor - 1 ) cout << ", ";
}
cout << endl;
switch (Kind_Hessian_Method) {
case GREEN_GAUSS: cout << "Hessian for adaptive metric: Green-Gauss." << endl; break;
}
Comment on lines +8017 to +8019

Check notice

Code scanning / CodeQL

No trivial switch statements Note

This switch statement should either handle more cases, or be rewritten as an if statement.
if (Normalize_Metric) {
cout << "Target complexity: " << Metric_Complexity << endl;
cout << "Lp norm: " << Metric_Norm << endl;
cout << "Min. edge length: " << Metric_Hmin << endl;
cout << "Max. edge length: " << Metric_Hmax << endl;
}
else {
cout << "Output unnormalized metric field." << endl;
}
}
}
}

bool CConfig::TokenizeString(string & str, string & option_name,
Expand Down
5 changes: 5 additions & 0 deletions SU2_CFD/include/drivers/CSinglezoneDriver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,9 @@ class CSinglezoneDriver : public CDriver {
*/
bool Monitor(unsigned long TimeIter) override;

/*!
* \brief Perform all steps to compute the metric tensor.
*/
virtual void ComputeMetricField();

};
Loading
Loading