Skip to content

Commit f4f327c

Browse files
authored
fix symmetry shared node (#2719)
* fix symmetry shared node
1 parent d136052 commit f4f327c

File tree

5 files changed

+62
-23
lines changed

5 files changed

+62
-23
lines changed

Common/src/geometry/CGeometry.cpp

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2468,6 +2468,9 @@ su2double CGeometry::GetSurfaceArea(const CConfig* config, unsigned short val_ma
24682468
}
24692469

24702470
void CGeometry::ComputeModifiedSymmetryNormals(const CConfig* config) {
2471+
const su2double MIN_AREA = 1e-12; // minimum area to consider a normal valid
2472+
const su2double PARALLEL_TOLERANCE = 0.001; // min. angle between symm. planes to consider them non-parallel.
2473+
24712474
/* Check how many symmetry planes there are and use the first (lowest ID) as the basis to orthogonalize against.
24722475
* All nodes that are shared by multiple symmetries have to get a corrected normal. */
24732476

@@ -2558,6 +2561,8 @@ void CGeometry::ComputeModifiedSymmetryNormals(const CConfig* config) {
25582561
/*--- Loop over previous symmetries and if this point shares them, make this normal orthogonal to them.
25592562
* It's ok if we normalize merged normals against themselves, we get 0 area and this becomes a no-op. ---*/
25602563

2564+
std::vector<size_t> parallelMarkers; // Track markers with nearly-parallel normals
2565+
25612566
for (size_t j = 0; j < i; ++j) {
25622567
const auto jMarker = symMarkers[j];
25632568
const auto jVertex = nodes->GetVertex(iPoint, jMarker);
@@ -2567,14 +2572,48 @@ void CGeometry::ComputeModifiedSymmetryNormals(const CConfig* config) {
25672572
GetNormal(jMarker, jVertex, jNormal);
25682573

25692574
const su2double proj = GeometryToolbox::DotProduct(int(MAXNDIM), jNormal.data(), iNormal.data());
2575+
const su2double angleDiff = std::abs(1.0 - std::abs(proj));
2576+
2577+
// Check if normals are nearly parallel (within ~2.5 degrees)
2578+
// cos(2.5°) ≈ 0.999, so (1 - cos(2.5°)) ≈ 0.001
2579+
if (angleDiff < PARALLEL_TOLERANCE) {
2580+
// These normals are nearly parallel - average them instead of orthogonalizing
2581+
parallelMarkers.push_back(j);
2582+
for (auto iDim = 0ul; iDim < MAXNDIM; ++iDim) iNormal[iDim] += jNormal[iDim];
2583+
continue;
2584+
}
2585+
25702586
for (auto iDim = 0ul; iDim < MAXNDIM; ++iDim) iNormal[iDim] -= proj * jNormal[iDim];
25712587
}
25722588

2589+
/*--- If we found parallel markers, average and store the result for all involved markers ---*/
2590+
if (!parallelMarkers.empty()) {
2591+
// Normalize the averaged normal
2592+
const su2double avgArea = GeometryToolbox::Norm(int(MAXNDIM), iNormal.data());
2593+
if (avgArea > MIN_AREA) {
2594+
for (auto iDim = 0ul; iDim < MAXNDIM; ++iDim) iNormal[iDim] /= avgArea;
2595+
2596+
// Store the averaged normal for the current marker
2597+
symmetryNormals[iMarker][iVertex] = iNormal;
2598+
2599+
// Also update all parallel markers with the same averaged normal
2600+
for (const auto j : parallelMarkers) {
2601+
const auto jMarker = symMarkers[j];
2602+
const auto jVertex = nodes->GetVertex(iPoint, jMarker);
2603+
if (jVertex >= 0) {
2604+
symmetryNormals[jMarker][jVertex] = iNormal;
2605+
}
2606+
}
2607+
}
2608+
continue; // Skip the normal orthogonalization path below
2609+
}
2610+
25732611
/*--- Normalize. If the norm is close to zero it means the normal is a linear combination of previous
25742612
* normals, in this case we don't need to store the corrected normal, using the original in the gradient
25752613
* correction will have no effect since previous corrections will remove components in this direction). ---*/
25762614
const su2double area = GeometryToolbox::Norm(int(MAXNDIM), iNormal.data());
2577-
if (area > 1e-12) {
2615+
2616+
if (area > MIN_AREA) {
25782617
for (auto iDim = 0ul; iDim < MAXNDIM; ++iDim) iNormal[iDim] /= area;
25792618
symmetryNormals[iMarker][iVertex] = iNormal;
25802619
}
@@ -2591,16 +2630,14 @@ void CGeometry::ComputeSurfStraightness(const CConfig* config, bool print_on_scr
25912630
string Local_TagBound, Global_TagBound;
25922631

25932632
vector<su2double> Normal(nDim), UnitNormal(nDim), RefUnitNormal(nDim);
2594-
25952633
/*--- Assume now that this boundary marker is straight. As soon as one
2596-
AreaElement is found that is not aligend with a Reference then it is
2597-
certain that the boundary marker is not straight and one can stop
2598-
searching. Another possibility is that this process doesn't own
2634+
AreaElement is found that is not aligned with a Reference then it
2635+
is certain that the boundary marker is not straight and one can
2636+
stop searching. Another possibility is that this process doesn't own
25992637
any nodes of that boundary, in that case we also have to assume the
2600-
boundary is straight.
2601-
Any boundary type other than SYMMETRY_PLANE or EULER_WALL gets
2602-
the value false (or see cases specified in the conditional below)
2603-
which could be wrong. ---*/
2638+
boundary is straight. Any boundary type other than SYMMETRY_PLANE or
2639+
EULER_WALL gets the value false (or see cases specified in the
2640+
conditional below) which could be wrong. ---*/
26042641
boundIsStraight.resize(nMarker);
26052642
fill(boundIsStraight.begin(), boundIsStraight.end(), true);
26062643

@@ -3902,11 +3939,13 @@ void CGeometry::ColorMGLevels(unsigned short nMGLevels, const CGeometry* const*
39023939
for (auto step = 0u; step < iMesh; ++step) {
39033940
auto coarseMesh = geometry[iMesh - 1 - step];
39043941
if (step)
3905-
for (auto iPoint = 0ul; iPoint < coarseMesh->GetnPoint(); ++iPoint)
3942+
for (auto iPoint = 0ul; iPoint < coarseMesh->GetnPoint(); ++iPoint) {
39063943
CoarseGridColor_(iPoint, step) = CoarseGridColor_(coarseMesh->nodes->GetParent_CV(iPoint), step - 1);
3944+
}
39073945
else
3908-
for (auto iPoint = 0ul; iPoint < coarseMesh->GetnPoint(); ++iPoint)
3946+
for (auto iPoint = 0ul; iPoint < coarseMesh->GetnPoint(); ++iPoint) {
39093947
CoarseGridColor_(iPoint, step) = color[coarseMesh->nodes->GetParent_CV(iPoint)];
3948+
}
39103949
}
39113950
}
39123951
}
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
INDEX GRAD
2-
0 -4.570880175564371e-04
3-
1 -2.401474104649833e-04
4-
2 -9.134741714239637e-05
5-
3 -1.628103592186675e-05
6-
4 -1.741046982337274e-05
7-
5 -9.462481735830197e-05
8-
6 -2.452469745130044e-04
9-
7 -4.635498256044697e-04
2+
0 -4.570880019852262e-04
3+
1 -2.401473990776599e-04
4+
2 -9.134741024986813e-05
5+
3 -1.628103377709482e-05
6+
4 -1.741047267006423e-05
7+
5 -9.462482550045010e-05
8+
6 -2.452469883016078e-04
9+
7 -4.635498453796528e-04

TestCases/parallel_regression.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1526,7 +1526,7 @@ def main():
15261526
pywrapper_deformingBump.cfg_dir = "py_wrapper/deforming_bump_in_channel"
15271527
pywrapper_deformingBump.cfg_file = "config.cfg"
15281528
pywrapper_deformingBump.test_iter = 1
1529-
pywrapper_deformingBump.test_vals = [0.500000, 0.000000, -2.811520, -1.603562, -2.074259, 2.424289, 7.616891, -0.205655]
1529+
pywrapper_deformingBump.test_vals = [0.500000, 0.000000, -2.556309, -1.270839, -2.350590, 2.606851, 8.002480, -0.300272]
15301530
pywrapper_deformingBump.command = TestCase.Command("mpirun -np 2", "python", "run.py")
15311531
pywrapper_deformingBump.unsteady = True
15321532
test_list.append(pywrapper_deformingBump)

TestCases/parallel_regression_AD.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,8 @@ def main():
276276
discadj_fsi2.cfg_dir = "disc_adj_fsi/Airfoil_2d"
277277
discadj_fsi2.cfg_file = "config.cfg"
278278
discadj_fsi2.test_iter = 8
279-
discadj_fsi2.test_vals = [-4.772768, 0.916597, -3.863369, 0.295450, 3.839800]
280-
discadj_fsi2.test_vals_aarch64 = [-4.773008, 0.916312, -3.863369, 0.295450, 3.841200]
279+
discadj_fsi2.test_vals = [-4.772641, 0.917601, -3.863369, 0.295450, 3.839800]
280+
discadj_fsi2.test_vals_aarch64 = [-4.772641, 0.917601, -3.863369, 0.295450, 3.839800]
281281
discadj_fsi2.tol = 0.00001
282282
test_list.append(discadj_fsi2)
283283

TestCases/tutorials.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ def main():
292292
tutorial_nicfd_nozzle_pinn.cfg_dir = "../Tutorials/compressible_flow/NICFD_nozzle/PhysicsInformed"
293293
tutorial_nicfd_nozzle_pinn.cfg_file = "config_NICFD_PINN.cfg"
294294
tutorial_nicfd_nozzle_pinn.test_iter = 20
295-
tutorial_nicfd_nozzle_pinn.test_vals = [-3.181747, -1.638856, -1.277037, 2.445964, -11.759632]
295+
tutorial_nicfd_nozzle_pinn.test_vals = [-2.728179, -0.849337, -1.224542, 2.898995, -11.420290]
296296
tutorial_nicfd_nozzle_pinn.no_restart = True
297297
test_list.append(tutorial_nicfd_nozzle_pinn)
298298

0 commit comments

Comments
 (0)