Skip to content
Merged
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
62 changes: 38 additions & 24 deletions Common/src/geometry/CGeometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -792,15 +792,20 @@ void CGeometry::PreprocessPeriodicComms(CGeometry* geometry, CConfig* config) {
nPoint_Send_All[0] = 0;
int* nPoint_Recv_All = new int[size + 1];
nPoint_Recv_All[0] = 0;
int* nPoint_Flag = new int[size];

for (iRank = 0; iRank < size; iRank++) {
nPoint_Send_All[iRank] = 0;
nPoint_Recv_All[iRank] = 0;
nPoint_Flag[iRank] = -1;
}
nPoint_Send_All[size] = 0;
nPoint_Recv_All[size] = 0;
/*--- Store a set of unique (point, marker) pairs per destination rank. ---*/
using PointMarkerPair = std::pair<unsigned long, unsigned long>;

auto pairHash = [](const PointMarkerPair& p) -> std::size_t {
// Use the golden ratio constant and bit mixing to generate pair hash
std::size_t h1 = std::hash<unsigned long>{}(p.first);
std::size_t h2 = std::hash<unsigned long>{}(p.second);

return h1 ^ (h2 + 0x9e3779b9 + (h1 << 6) + (h1 >> 2));
};

using PointMarkerSet = std::unordered_set<PointMarkerPair, decltype(pairHash)>;
std::vector<PointMarkerSet> Points_Send_All(size, PointMarkerSet(0, pairHash));

/*--- Loop through all of our periodic markers and track
our sends with each rank. ---*/
Expand All @@ -821,19 +826,17 @@ void CGeometry::PreprocessPeriodicComms(CGeometry* geometry, CConfig* config) {

iRank = static_cast<int>(geometry->vertex[iMarker][iVertex]->GetDonorProcessor());

/*--- If we have not visited this point last, increment our
number of points that must be sent to a particular proc. ---*/

if ((nPoint_Flag[iRank] != static_cast<int>(iPoint))) {
nPoint_Flag[iRank] = static_cast<int>(iPoint);
nPoint_Send_All[iRank + 1] += 1;
}
/*--- Store the (point, marker) pair in the set for the destination rank. ---*/
Points_Send_All[iRank].insert(std::make_pair(iPoint, static_cast<unsigned long>(iMarker)));
}
}
}
}

delete[] nPoint_Flag;
for (iRank = 0; iRank < size; iRank++) {
nPoint_Send_All[iRank + 1] = Points_Send_All[iRank].size();
nPoint_Recv_All[iRank + 1] = 0;
}

/*--- Communicate the number of points to be sent/recv'd amongst
all processors. After this communication, each proc knows how
Expand Down Expand Up @@ -943,11 +946,15 @@ void CGeometry::PreprocessPeriodicComms(CGeometry* geometry, CConfig* config) {
auto* idSend = new unsigned long[nPoint_PeriodicSend[nPeriodicSend] * nPackets];
for (iSend = 0; iSend < nPoint_PeriodicSend[nPeriodicSend] * nPackets; iSend++) idSend[iSend] = 0;

/*--- Re-use set of unique points per destination rank. ---*/
for (iRank = 0; iRank < size; iRank++) Points_Send_All[iRank].clear();

/*--- Build the lists of local index and periodic marker index values. ---*/

ii = 0;
jj = 0;
for (iSend = 0; iSend < nPeriodicSend; iSend++) {
int destRank = Neighbors_PeriodicSend[iSend];
for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) {
if (config->GetMarker_All_KindBC(iMarker) == PERIODIC_BOUNDARY) {
iPeriodic = config->GetMarker_All_PerBound(iMarker);
Expand All @@ -969,14 +976,21 @@ void CGeometry::PreprocessPeriodicComms(CGeometry* geometry, CConfig* config) {
index on the matching periodic point and the periodic marker
index to be communicated to the recv rank. ---*/

if (iRank == Neighbors_PeriodicSend[iSend]) {
Local_Point_PeriodicSend[ii] = iPoint;
Local_Marker_PeriodicSend[ii] = static_cast<unsigned long>(iMarker);
jj = ii * nPackets;
idSend[jj] = geometry->vertex[iMarker][iVertex]->GetDonorPoint();
jj++;
idSend[jj] = static_cast<unsigned long>(iPeriodic);
ii++;
if (iRank == destRank) {
/*--- Check if we have already added this (point, marker) pair
for this destination rank. Use the result if insert(), which is
a pair whose second element is success. ---*/
const auto pointMarkerPair = std::make_pair(iPoint, static_cast<unsigned long>(iMarker));
const auto insertResult = Points_Send_All[destRank].insert(pointMarkerPair);
if (insertResult.second) {
Local_Point_PeriodicSend[ii] = iPoint;
Local_Marker_PeriodicSend[ii] = static_cast<unsigned long>(iMarker);
jj = ii * nPackets;
idSend[jj] = geometry->vertex[iMarker][iVertex]->GetDonorPoint();
jj++;
idSend[jj] = static_cast<unsigned long>(iPeriodic);
ii++;
}
}
}
}
Expand Down
89 changes: 89 additions & 0 deletions TestCases/mms/fvm_euler/inv_mms_vortex.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% SU2 configuration file %
% Case description: Isentropic vortex (FVM) %
% Author: Brian Munguía %
% Date: 2025.25.06 %
% File Version 8.2.0 "Harrier" %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------%
%
KIND_VERIFICATION_SOLUTION= INVISCID_VORTEX
SOLVER= EULER
MATH_PROBLEM= DIRECT
RESTART_SOL= NO

% ----------- COMPRESSIBLE AND INCOMPRESSIBLE FREE-STREAM DEFINITION ----------%
%
MACH_NUMBER= 0.5
AOA= 45.0
FREESTREAM_DENSITY= 1.0
FREESTREAM_PRESSURE= 1.0
FREESTREAM_TEMPERATURE= 1.0

% -------------- COMPRESSIBLE AND INCOMPRESSIBLE FLUID CONSTANTS --------------%
%
FLUID_MODEL= IDEAL_GAS
GAMMA_VALUE= 1.4
GAS_CONSTANT= 1.0

% ---------------------- REFERENCE VALUE DEFINITION ---------------------------%
%
REF_ORIGIN_MOMENT_X= 0.00
REF_ORIGIN_MOMENT_Y= 0.00
REF_ORIGIN_MOMENT_Z= 0.00
REF_AREA= 1.0
REF_DIMENSIONALIZATION= DIMENSIONAL

% ------------------------- UNSTEADY SIMULATION -------------------------------%
%
TIME_DOMAIN= YES
TIME_MARCHING= TIME_STEPPING
TIME_STEP= 2.0e-3
MAX_TIME= 50.0

% -------------------- BOUNDARY CONDITION DEFINITION --------------------------%
%
MARKER_PERIODIC= ( PeriodicBottom, PeriodicTop, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 0.0, \
PeriodicLeft, PeriodicRight, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0 )

% ------------- COMMON PARAMETERS TO DEFINE THE NUMERICAL METHOD --------------%
%
CFL_NUMBER= 0.2
TIME_ITER= 50
RK_ALPHA_COEFF= ( 0.666667, 0.666667, 1.0 )

% ------------------ FLOW NUMERICAL METHOD DEFINITION ----------------------%
%
CONV_NUM_METHOD_FLOW= ROE
MUSCL_FLOW= YES
SLOPE_LIMITER_FLOW= NONE
TIME_DISCRE_FLOW= EULER_IMPLICIT

% --------------------------- CONVERGENCE PARAMETERS --------------------------%
%
CONV_RESIDUAL_MINVAL= -15
CONV_STARTITER= 10
CONV_CAUCHY_ELEMS= 100
CONV_CAUCHY_EPS= 1E-6

% ------------------------- INPUT/OUTPUT INFORMATION --------------------------%
%
MESH_FILENAME= TriAdapt.su2
MESH_FORMAT= SU2
MESH_OUT_FILENAME= mesh_out.su2
SOLUTION_FILENAME= solution_flow.dat
SOLUTION_ADJ_FILENAME= solution_adj.dat
TABULAR_FORMAT= CSV
CONV_FILENAME= history
RESTART_FILENAME= restart_flow.dat
RESTART_ADJ_FILENAME= restart_adj.dat
VOLUME_FILENAME= flow
VOLUME_ADJ_FILENAME= adjoint
GRAD_OBJFUNC_FILENAME= of_grad.dat
SURFACE_FILENAME= surface_flow
SURFACE_ADJ_FILENAME= surface_adjoint
OUTPUT_WRT_FREQ= 50
SCREEN_OUTPUT= (TIME_ITER, RMS_DENSITY, RMS_ENERGY, LIFT, DRAG)
9 changes: 9 additions & 0 deletions TestCases/parallel_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -1479,6 +1479,15 @@ def main():
### Method of Manufactured Solutions (MMS) ###
##############################################

# FVM, compressible, euler (periodic isentropic vortex)
mms_fvm_vortex = TestCase('mms_fvm_vortex')
mms_fvm_vortex.cfg_dir = "mms/fvm_euler"
mms_fvm_vortex.cfg_file = "inv_mms_vortex.cfg"
mms_fvm_vortex.test_iter = 10
mms_fvm_vortex.test_vals = [-5.704300, -4.848072, 0.000000, 0.000000]
mms_fvm_vortex.unsteady = True
test_list.append(mms_fvm_vortex)

# FVM, compressible, laminar N-S
mms_fvm_ns = TestCase('mms_fvm_ns')
mms_fvm_ns.cfg_dir = "mms/fvm_navierstokes"
Expand Down
9 changes: 9 additions & 0 deletions TestCases/serial_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -1129,6 +1129,15 @@ def main():
### Method of Manufactured Solutions (MMS) ###
##############################################

# FVM, compressible, euler (periodic isentropic vortex)
mms_fvm_vortex = TestCase('mms_fvm_vortex')
mms_fvm_vortex.cfg_dir = "mms/fvm_euler"
mms_fvm_vortex.cfg_file = "inv_mms_vortex.cfg"
mms_fvm_vortex.test_iter = 10
mms_fvm_vortex.test_vals = [-5.704300, -4.848072, 0.000000, 0.000000]
mms_fvm_vortex.unsteady = True
test_list.append(mms_fvm_vortex)

# FVM, compressible, laminar N-S
mms_fvm_ns = TestCase('mms_fvm_ns')
mms_fvm_ns.cfg_dir = "mms/fvm_navierstokes"
Expand Down