From 4b90566a773dcaae88769c8d467dbcbad95d33a8 Mon Sep 17 00:00:00 2001
From: Florian Schueltke <florian.schueltke@ilr.rwth-aachen.de>
Date: Wed, 19 Feb 2025 18:17:58 +0100
Subject: [PATCH 1/3] aerodynamic_analysis (schueltke):  - corrected wave drag
 calibration  - corrected function call of neutral point estimation with
 correct trimmed polar

---
 .../src/bwb/bwbDefaultStrategy.cpp            | 21 ++++++++-
 .../src/methods/waveDragMason.cpp             |  5 +--
 .../src/methods/waveDragMason.h               |  3 +-
 .../src/taw/tawDefaultStrategy.cpp            | 43 ++++++++++++-------
 4 files changed, 50 insertions(+), 22 deletions(-)

diff --git a/aerodynamic_analysis/src/bwb/bwbDefaultStrategy.cpp b/aerodynamic_analysis/src/bwb/bwbDefaultStrategy.cpp
index c6fd74b4..3255e85e 100644
--- a/aerodynamic_analysis/src/bwb/bwbDefaultStrategy.cpp
+++ b/aerodynamic_analysis/src/bwb/bwbDefaultStrategy.cpp
@@ -227,7 +227,26 @@ void bwbDefaultStrategy::calculateWaveDragMason(waveDragMason *myWaveDragMason)
                                             = myWaveDragMason->calculateWaveDrag(currentPolarSet.cleanPolars.at(polarID).Points.at(pointID),
                                                                                 currentPolarSet.cleanPolars.at(polarID).MachNumber,
                                                                                 0, 0, currentPolarSet.cleanPolars.at(polarID).PointsWing.at(pointID).yStations,
-                                                                                currentPolarSet.cleanPolars.at(polarID).PointsWing.at(pointID).Cl_distr, true);
+                                                                                currentPolarSet.cleanPolars.at(polarID).PointsWing.at(pointID).Cl_distr);
+        }
+        //calibration of wing wave drag if calibration is active
+        if (myWaveDragMason->doWaveDragMasonCalibration && currentPolarSet.cleanPolars.at(polarID).PointsWing.back().CD_wave > 0) { // check if polar has wave drag
+            for (size_t pointID(0); pointID < currentPolarSet.cleanPolars.at(polarID).Points.size(); ++pointID) {
+                currentPolarSet.cleanPolars.at(polarID).PointsWing.at(pointID).CD_wave += myWaveDragMason->calculateWaveDragCorrectionByCalibration(
+                    currentPolarSet.cleanPolars.at(polarID).PointsWing.at(pointID).CD_wave, currentPolarSet.cleanPolars.at(polarID).Points.at(pointID),
+                    currentPolarSet.cleanPolars.at(polarID).MachNumber);
+            }
+        }
+        //correction of wing wave drag and summation to total drag
+        for (size_t pointID(0); pointID < currentPolarSet.cleanPolars.at(polarID).Points.size(); ++pointID) {
+            //wing
+            currentPolarSet.cleanPolars.at(polarID).PointsWing.at(pointID).CD_wave +=
+                myWaveDragMason->calculateWaveDragCorrectionByDragCounts(myWaveDragMason->waveDragCtCorrForCalibrationWing);
+            //check negative wave drag due to correction
+            if (currentPolarSet.cleanPolars.at(polarID).PointsWing.at(pointID).CD_wave < 0.) { // Check if wing wave drag is negative due to calibration; if so, set to zero
+                currentPolarSet.cleanPolars.at(polarID).PointsWing.at(pointID).CD_wave = 0.;
+            }
+            //calculate total wave drag
             currentPolarSet.cleanPolars.at(polarID).Points.at(pointID).CD_wave = currentPolarSet.cleanPolars.at(polarID).PointsWing.at(pointID).CD_wave;
         }
     }
diff --git a/aerodynamic_analysis/src/methods/waveDragMason.cpp b/aerodynamic_analysis/src/methods/waveDragMason.cpp
index 87f264ab..51a24ddd 100644
--- a/aerodynamic_analysis/src/methods/waveDragMason.cpp
+++ b/aerodynamic_analysis/src/methods/waveDragMason.cpp
@@ -97,7 +97,7 @@ waveDragMason::waveDragMason(const std::shared_ptr<RuntimeIO>& rtIO, const waveD
 }
 
 double waveDragMason::calculateWaveDrag(const PolarPoint& aPolarPoint, const double aMachNumber, size_t liftingSurfaceIndex, const double chordWiseSweepPosition,
-                                        const std::vector<double>& spanStations, const std::vector<double>& Cl_distribution, const bool doCorrection) {
+                                        const std::vector<double>& spanStations, const std::vector<double>& Cl_distribution) {
     // consistency check
     if (spanStations.size() != Cl_distribution.size()) {
             stringstream errorMessage;
@@ -174,9 +174,6 @@ double waveDragMason::calculateWaveDrag(const PolarPoint& aPolarPoint, const dou
     }
     // double the drag to account for the whole wing
     C_DWaveTotal = 2. * std::accumulate(C_DWaveSegment.begin(), C_DWaveSegment.end(), 0.0) / liftingSurfaceRefArea;
-    if (doCorrection) {
-        C_DWaveTotal += calculateWaveDragCorrectionByCalibration(C_DWaveTotal, aPolarPoint, aMachNumber);
-    }
     return C_DWaveTotal;
 }
 
diff --git a/aerodynamic_analysis/src/methods/waveDragMason.h b/aerodynamic_analysis/src/methods/waveDragMason.h
index c2b6ef99..72870dbd 100644
--- a/aerodynamic_analysis/src/methods/waveDragMason.h
+++ b/aerodynamic_analysis/src/methods/waveDragMason.h
@@ -72,10 +72,9 @@ class waveDragMason{
      *  \param liftingSurfaceIndex the index of the lifting surface, which gets calculated
      *  \param spanStations vector of span coordinates of the wing corresponding to the lift points
      *  \param Cl_distribution vector of lift coefficients corresponding to the span station coordinates
-     *  \param doCorrection switch do enable CL based calibraiton
      */
     double calculateWaveDrag(const PolarPoint& aPolarPoint, const double machNumber, size_t liftingSurfaceIndex, const double chordWiseSweepPosition,
-                                const std::vector<double>& spanStations, const std::vector<double>& Cl_distribution, const bool doCorrection);
+                                const std::vector<double>& spanStations, const std::vector<double>& Cl_distribution);
     /** \brief Function calculates the wave drag correction for a polar point using a clibration function
      *  \details this function should only be used for wing and not for stabilizer
      *  \param waveDragBeforeCorrection the value of the uncorrected wave drag point
diff --git a/aerodynamic_analysis/src/taw/tawDefaultStrategy.cpp b/aerodynamic_analysis/src/taw/tawDefaultStrategy.cpp
index 23532b5a..4da20902 100644
--- a/aerodynamic_analysis/src/taw/tawDefaultStrategy.cpp
+++ b/aerodynamic_analysis/src/taw/tawDefaultStrategy.cpp
@@ -390,30 +390,43 @@ void tawDefaultStrategy::calculateWaveDragMason(waveDragMason *myWaveDragMason)
             sweepPosition = 0.5;
         }
         for (size_t pointID(0); pointID < currentPolarSet.cleanPolars.at(polarID).Points.size(); ++pointID) {
-            // wave drag wing
+            // wave drag wing (uncorrected; correction will be applied afterwards)
             currentPolarSet.cleanPolars.at(polarID).PointsWing.at(pointID).CD_wave
                                             = myWaveDragMason->calculateWaveDrag(currentPolarSet.cleanPolars.at(polarID).Points.at(pointID),
                                                                                 currentPolarSet.cleanPolars.at(polarID).MachNumber,
                                                                                 0, sweepPosition, currentPolarSet.cleanPolars.at(polarID).PointsWing.at(pointID).yStations,
-                                                                                currentPolarSet.cleanPolars.at(polarID).PointsWing.at(pointID).Cl_distr,
-                                                                                myWaveDragMason->doWaveDragMasonCalibration)
-                                            + myWaveDragMason->calculateWaveDragCorrectionByDragCounts(myWaveDragMason->waveDragCtCorrForCalibrationWing);
-            if (currentPolarSet.cleanPolars.at(polarID).PointsWing.at(pointID).CD_wave < 0.) { // Check if drag is negative due to calibration; if so, set to zero
-                currentPolarSet.cleanPolars.at(polarID).PointsWing.at(pointID).CD_wave = 0.;
-            }
-            // wave drag stabilizer
+                                                                                currentPolarSet.cleanPolars.at(polarID).PointsWing.at(pointID).Cl_distr);
+            // wave drag stabilizer (uncorrected; no calibration needed/assumed for stabilizer)
             currentPolarSet.cleanPolars.at(polarID).PointsStab.at(pointID).CD_wave
                                             = myWaveDragMason->calculateWaveDrag(currentPolarSet.cleanPolars.at(polarID).Points.at(pointID),
                                                                                 currentPolarSet.cleanPolars.at(polarID).MachNumber,
                                                                                 1, sweepPosition, currentPolarSet.cleanPolars.at(polarID).PointsStab.at(pointID).yStations,
-                                                                                currentPolarSet.cleanPolars.at(polarID).PointsStab.at(pointID).Cl_distr,
-                                                                                false)
-                                            + myWaveDragMason->calculateWaveDragCorrectionByDragCounts(myWaveDragMason->waveDragCtCorrForCalibrationStabilizer);
-            if (currentPolarSet.cleanPolars.at(polarID).PointsStab.at(pointID).CD_wave < 0.) { // Check if drag is negative due to calibration; if so, set to zero
+                                                                                currentPolarSet.cleanPolars.at(polarID).PointsStab.at(pointID).Cl_distr);
+        }
+        //calibration of wing wave drag if calibration is active
+        if (myWaveDragMason->doWaveDragMasonCalibration && currentPolarSet.cleanPolars.at(polarID).PointsWing.back().CD_wave > 0) { // check if polar has wave drag
+            for (size_t pointID(0); pointID < currentPolarSet.cleanPolars.at(polarID).Points.size(); ++pointID) {
+                currentPolarSet.cleanPolars.at(polarID).PointsWing.at(pointID).CD_wave += myWaveDragMason->calculateWaveDragCorrectionByCalibration(
+                    currentPolarSet.cleanPolars.at(polarID).PointsWing.at(pointID).CD_wave, currentPolarSet.cleanPolars.at(polarID).Points.at(pointID),
+                    currentPolarSet.cleanPolars.at(polarID).MachNumber);
+            }
+        }
+        //correction of wing and stabilizer wave drag and summation to total drag
+        for (size_t pointID(0); pointID < currentPolarSet.cleanPolars.at(polarID).Points.size(); ++pointID) {
+            //wing
+            currentPolarSet.cleanPolars.at(polarID).PointsWing.at(pointID).CD_wave +=
+                myWaveDragMason->calculateWaveDragCorrectionByDragCounts(myWaveDragMason->waveDragCtCorrForCalibrationWing);
+            //stabilizer
+            currentPolarSet.cleanPolars.at(polarID).PointsStab.at(pointID).CD_wave +=
+                myWaveDragMason->calculateWaveDragCorrectionByDragCounts(myWaveDragMason->waveDragCtCorrForCalibrationStabilizer);
+            //check negative wave drag due to correction
+            if (currentPolarSet.cleanPolars.at(polarID).PointsWing.at(pointID).CD_wave < 0.) { // Check if wing wave drag is negative due to calibration; if so, set to zero
+                currentPolarSet.cleanPolars.at(polarID).PointsWing.at(pointID).CD_wave = 0.;
+            }
+            if (currentPolarSet.cleanPolars.at(polarID).PointsStab.at(pointID).CD_wave < 0.) { // Check if stabilizer wave drag is negative due to calibration; if so, set to zero
                 currentPolarSet.cleanPolars.at(polarID).PointsStab.at(pointID).CD_wave = 0.;
             }
-
-            // total wave drag
+            //calculate total wave drag
             currentPolarSet.cleanPolars.at(polarID).Points.at(pointID).CD_wave = currentPolarSet.cleanPolars.at(polarID).PointsWing.at(pointID).CD_wave
                                                                                + currentPolarSet.cleanPolars.at(polarID).PointsStab.at(pointID).CD_wave;
         }
@@ -983,7 +996,7 @@ void tawDefaultStrategy::setReferenceValues() {
     data_->span.set_value(geom2::measure::span(liftingSurfaces.at(0)));
     data_->MAC.set_value(geom2::measure::mean_aerodynamic_chord(liftingSurfaces.at(0)));
     data_->S_ref.set_value(geom2::measure::reference_area(liftingSurfaces.at(0)));
-    data_->neutral_point_xCoordinate.set_value(getNeutralPointXposition(getTrimmedCruisePolar(polarDataCGMap.at(0).at(0).cleanPolars, data_->initialCruiseMachNumber),
+    data_->neutral_point_xCoordinate.set_value(getNeutralPointXposition(getTrimmedCruisePolar(polarDataTrimMap.at(0).cleanPolars, data_->initialCruiseMachNumber),
                                                                         data_->MAC.value(), CoGPositions["design"].xCoordinate));
 }
 
-- 
GitLab


From b29d4178544a7aa341d65330302f6850109eea55 Mon Sep 17 00:00:00 2001
From: Florian Schueltke <florian.schueltke@ilr.rwth-aachen.de>
Date: Wed, 19 Feb 2025 20:25:39 +0100
Subject: [PATCH 2/3] aerodynamic_analysis (schueltke):  - updated
 calculateWaveDragCorrectionByCalibration function; output should not change,
 only clean up

---
 aerodynamic_analysis/src/methods/waveDragMason.cpp | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/aerodynamic_analysis/src/methods/waveDragMason.cpp b/aerodynamic_analysis/src/methods/waveDragMason.cpp
index 51a24ddd..82e1c672 100644
--- a/aerodynamic_analysis/src/methods/waveDragMason.cpp
+++ b/aerodynamic_analysis/src/methods/waveDragMason.cpp
@@ -178,15 +178,10 @@ double waveDragMason::calculateWaveDrag(const PolarPoint& aPolarPoint, const dou
 }
 
 double waveDragMason::calculateWaveDragCorrectionByCalibration(const double& waveDragBeforeCorrection, const PolarPoint& aPolarPoint, const double& aMachNumber) {
-    double totalWaveDragCorrection(0.);
     /* Drag calibration. First introduced in commit [4eab519c2] based on experimental data in [Lam2010], 23.06.2010. After several changes, 
        the current definition and values in config are from Risse, commit [2ec91580] on 02.08.2015. Especially for wave drag calibration, the values should be used 
        carefully, as they usually only fit to one specific airfoil family and, thus, k-factor. */    
-    totalWaveDragCorrection = CLFact * pow(aMachNumber * aPolarPoint.CL, CLExp);
-    if (aMachNumber >= 0.5) {
-        totalWaveDragCorrection = CLFact * pow(aMachNumber * aPolarPoint.CL, CLExp);
-    }
-    return totalWaveDragCorrection;
+    return CLFact * pow(aMachNumber * aPolarPoint.CL, CLExp);
 }
 
 double waveDragMason::calculateWaveDragCorrectionByDragCounts(const double& waveDragCtCorrForCalibration) {
-- 
GitLab


From e485dfa443c74d5033e6c59bfa83d61e4c64be66 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20Sch=C3=BCltke?=
 <florian.schueltke@ilr.rwth-aachen.de>
Date: Thu, 20 Feb 2025 15:22:09 +0100
Subject: [PATCH 3/3] reverted change as discussed --> to be clarified for
 final release

---
 aerodynamic_analysis/src/taw/tawDefaultStrategy.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/aerodynamic_analysis/src/taw/tawDefaultStrategy.cpp b/aerodynamic_analysis/src/taw/tawDefaultStrategy.cpp
index 4da20902..91708daf 100644
--- a/aerodynamic_analysis/src/taw/tawDefaultStrategy.cpp
+++ b/aerodynamic_analysis/src/taw/tawDefaultStrategy.cpp
@@ -996,7 +996,7 @@ void tawDefaultStrategy::setReferenceValues() {
     data_->span.set_value(geom2::measure::span(liftingSurfaces.at(0)));
     data_->MAC.set_value(geom2::measure::mean_aerodynamic_chord(liftingSurfaces.at(0)));
     data_->S_ref.set_value(geom2::measure::reference_area(liftingSurfaces.at(0)));
-    data_->neutral_point_xCoordinate.set_value(getNeutralPointXposition(getTrimmedCruisePolar(polarDataTrimMap.at(0).cleanPolars, data_->initialCruiseMachNumber),
+    data_->neutral_point_xCoordinate.set_value(getNeutralPointXposition(getTrimmedCruisePolar(polarDataCGMap.at(0).at(0).cleanPolars, data_->initialCruiseMachNumber),
                                                                         data_->MAC.value(), CoGPositions["design"].xCoordinate));
 }
 
-- 
GitLab