From fdf4a10f4c6065788b1449fd0a5f818816706018 Mon Sep 17 00:00:00 2001 From: lvjunjie Date: Thu, 16 Jul 2026 10:49:21 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=AF=AF=E5=B7=AE=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nmCalculation/nmCalculationAutoFitPSO.h | 2 +- .../nmCalculation/nmCalculationAutoFitPSO.cpp | 43 ++++++++----------- 2 files changed, 18 insertions(+), 27 deletions(-) diff --git a/Include/nmNum/nmCalculation/nmCalculationAutoFitPSO.h b/Include/nmNum/nmCalculation/nmCalculationAutoFitPSO.h index 2b1ccfb..4a29ca7 100644 --- a/Include/nmNum/nmCalculation/nmCalculationAutoFitPSO.h +++ b/Include/nmNum/nmCalculation/nmCalculationAutoFitPSO.h @@ -261,7 +261,7 @@ private: double calculateCurveError(const QVector& curve1, const QVector& curve2) const; double calculateLogLogCurveError(const QVector >& target, const QVector >& result) const; - double calculateWeightedPointError(double target, double result, double timeWeight) const; + double calculatePointError(double target, double result) const; private: // ===== 运行状态 ===== diff --git a/Src/nmNum/nmCalculation/nmCalculationAutoFitPSO.cpp b/Src/nmNum/nmCalculation/nmCalculationAutoFitPSO.cpp index af09bd3..13c55b8 100644 --- a/Src/nmNum/nmCalculation/nmCalculationAutoFitPSO.cpp +++ b/Src/nmNum/nmCalculation/nmCalculationAutoFitPSO.cpp @@ -4529,7 +4529,7 @@ double nmCalculationAutoFitPSO::calculateCurveError( const QVector& curve1, const QVector& curve2) const { // 两条已经对齐到同一 X 网格的曲线误差。 - // 使用“相对误差为主、绝对误差为辅”的点误差,并对极端值做保护。 + // 点误差保持无量纲,避免油水压力和气井拟压力因数值尺度不同而不可比。 if(curve1.size() != curve2.size() || curve1.isEmpty()) { return 1e10; } @@ -4550,7 +4550,6 @@ double nmCalculationAutoFitPSO::calculateCurveError( } double totalError = 0.0; - double totalWeight = 0.0; int validPoints = 0; for(int i = 0; i < curve1.size(); ++i) { @@ -4562,33 +4561,16 @@ double nmCalculationAutoFitPSO::calculateCurveError( continue; } - // 自适应权重:Y 值越大权重越小,避免大幅值段完全主导误差。 - double weightFactor = qMin(100.0, qAbs(y1) * 0.01); - double weight = 1.0 / (1.0 + weightFactor); - - // 相对误差和绝对误差的组合 - 添加数值保护 - double yMax = qMax(qAbs(y1), qAbs(y2)); - yMax = qMax(1e-12, yMax); // 防止除零 - - double relativeError = qAbs(y1 - y2) / yMax; - double absoluteError = qAbs(y1 - y2); - - // 限制误差值避免爆炸 - relativeError = qMin(1e6, relativeError); - absoluteError = qMin(1e6, absoluteError); - - // 误差组合:相对误差为主,绝对误差为辅 - double pointError = 0.7 * relativeError + 0.3 * absoluteError; + double pointError = calculatePointError(y1, y2); if(isFiniteNumber(pointError) && pointError < 1e10) { - totalError += weight * pointError * pointError; - totalWeight += weight; + totalError += pointError * pointError; validPoints++; } } - if(totalWeight > 0 && validPoints > 0) { - double result = sqrt(totalError / totalWeight); + if(validPoints > 0) { + double result = sqrt(totalError / validPoints); // 最终检查 if(!isFiniteNumber(result)) { @@ -4775,8 +4757,7 @@ double nmCalculationAutoFitPSO::calculateLogLogCurveError( } } -double nmCalculationAutoFitPSO::calculateWeightedPointError( - double target, double result, double timeWeight) const +double nmCalculationAutoFitPSO::calculatePointError(double target, double result) const { if(!isFiniteNumber(target) || !isFiniteNumber(result)) { return 1e10; @@ -4792,7 +4773,6 @@ double nmCalculationAutoFitPSO::calculateWeightedPointError( double relativeError = qAbs(target - result) / qMax(1e-10, yMax); // 组合误差:对数误差占 70%,线性误差占 30%。 - // timeWeight 当前没有参与最终公式,保留参数是为了后续按时间段加权扩展。 return 0.7 * logError + 0.3 * relativeError; } @@ -4867,6 +4847,17 @@ QVector> nmCalculationAutoFitPSO::runSolverDll() return result; } + // 线程结束后检查真实执行结果,防止失败时复用上一粒子的旧曲线。 + dllTask->wait(); + if(!dllTask->wasSuccessful()) { + DEBUG_OUT("DLL solver task reported failure"); + delete dllTask; + dllTask = nullptr; + --m_evaluationInProgress; + m_consecutiveFailures++; + return result; + } + // 验证结果数据是否已更新。DLL 任务会把结果写回 DataManager 中的目标井对象。 nmDataAnalyzeManager* dataManager = nmDataAnalyzeManager::getCurrentInstance(); //QVector wells = dataManager->getWellDataList();