fix(nmNum): 补齐 LM 拟合翻译并移除时间分段日志

feature/AutoFit-Optimize-20260914
lvjunjie 3 weeks ago
parent 90b6c5914a
commit 8f4e35a3ed

Binary file not shown.

@ -1056,6 +1056,38 @@ Reason: %1</source>
<source>Unknown reason</source> <source>Unknown reason</source>
<translation>未知原因</translation> <translation>未知原因</translation>
</message> </message>
<message>
<source>Failed to load configuration from data manager</source>
<translation>从数据管理器加载配置失败</translation>
</message>
<message>
<source>Auto fitting is already running</source>
<translation>自动拟合正在运行</translation>
</message>
<message>
<source>No parameters enabled for optimization</source>
<translation>未启用任何优化参数</translation>
</message>
<message>
<source>Target LogLog data is empty or insufficient</source>
<translation>目标双对数数据为空或不足</translation>
</message>
<message>
<source>Target LogLog data arrays have inconsistent sizes</source>
<translation>目标双对数数据数组长度不一致</translation>
</message>
<message>
<source>Failed to apply final parameters: %1</source>
<translation>应用最终参数失败:%1</translation>
</message>
<message>
<source>Failed to apply final parameters due to unknown error</source>
<translation>应用最终参数时发生未知错误</translation>
</message>
<message>
<source>Target well name is empty</source>
<translation>目标井名称为空</translation>
</message>
</context> </context>
<context> <context>
<name>nmCalculationSolver</name> <name>nmCalculationSolver</name>
@ -4017,6 +4049,14 @@ Supported types: Vertical, Vertical Fractured, and Horizontal Multi-Fractured We
<source>The minimum value of %1 must be greater than zero for automatic fitting.</source> <source>The minimum value of %1 must be greater than zero for automatic fitting.</source>
<translation>自动拟合时,%1 的最小值和初始值必须大于零。</translation> <translation>自动拟合时,%1 的最小值和初始值必须大于零。</translation>
</message> </message>
<message>
<source>Data manager is unavailable!</source>
<translation>数据管理器不可用!</translation>
</message>
<message>
<source>Gas pseudo-pressure data is unavailable or invalid.</source>
<translation>气体拟压力数据不可用或无效。</translation>
</message>
</context> </context>
<context> <context>
<name>nmWxAutomaticfitting</name> <name>nmWxAutomaticfitting</name>

@ -155,7 +155,6 @@ private:
const AutoFitObjectiveBreakdownLM* objectiveBreakdown = nullptr); const AutoFitObjectiveBreakdownLM* objectiveBreakdown = nullptr);
QVector<double> buildTraceParameterVector(const QVector<double>& selectedParameters) const; QVector<double> buildTraceParameterVector(const QVector<double>& selectedParameters) const;
void emitRunSummary(bool success, StopReasonLM finalReason); void emitRunSummary(bool success, StopReasonLM finalReason);
void emitTimeWindowDiagnostics(const AutoFitObjectiveBreakdownLM& breakdown);
bool validateParameters(const QVector<double>& parameters) const; bool validateParameters(const QVector<double>& parameters) const;
bool validateLogLogData(const QVector<QVector<double> >& logLogData) const; bool validateLogLogData(const QVector<QVector<double> >& logLogData) const;

@ -981,7 +981,6 @@ void nmCalculationAutoFitLM::emitRunSummary(bool success, StopReasonLM finalReas
.arg(m_totalEvaluations) .arg(m_totalEvaluations)
.arg(m_successfulEvaluations) .arg(m_successfulEvaluations)
.arg(m_totalEvaluations - m_successfulEvaluations)); .arg(m_totalEvaluations - m_successfulEvaluations));
emitTimeWindowDiagnostics(m_globalBestObjectiveBreakdown);
if(!m_traceFilePath.isEmpty()) { if(!m_traceFilePath.isEmpty()) {
emit logMessageGenerated(tr("Artifacts: trace=%1").arg(m_traceFilePath)); emit logMessageGenerated(tr("Artifacts: trace=%1").arg(m_traceFilePath));
@ -991,26 +990,6 @@ void nmCalculationAutoFitLM::emitRunSummary(bool success, StopReasonLM finalReas
} }
} }
void nmCalculationAutoFitLM::emitTimeWindowDiagnostics(
const AutoFitObjectiveBreakdownLM& breakdown)
{
// 只汇报有效工作点;能量占比说明各时间段对全局误差的贡献。
if(!breakdown.valid) {
return;
}
const double totalEnergy = breakdown.total * breakdown.total;
for(int k = 0; k < breakdown.timeWindows.size(); ++k) {
const AutoFitTimeWindowLM& window = breakdown.timeWindows[k];
const double percentage = totalEnergy > 0.0
? 100.0 * window.energy / totalEnergy : 0.0;
emit logMessageGenerated(
tr("Time window %1 [%2, %3]: RMS=%4, energy=%5 (%6%)")
.arg(k + 1).arg(window.timeMin, 0, 'g', 6)
.arg(window.timeMax, 0, 'g', 6).arg(window.rmsError, 0, 'e', 4)
.arg(window.energy, 0, 'e', 4).arg(percentage, 0, 'f', 1));
}
}
QVector<double> nmCalculationAutoFitLM::buildTraceParameterVector(const QVector<double>& selectedParameters) const QVector<double> nmCalculationAutoFitLM::buildTraceParameterVector(const QVector<double>& selectedParameters) const
{ {
// 将 LM 内部使用的“启用参数向量”还原成完整 7 维参数向量。 // 将 LM 内部使用的“启用参数向量”还原成完整 7 维参数向量。
@ -1077,7 +1056,7 @@ bool nmCalculationAutoFitLM::loadAllConfigFromDataManager()
extractUserInitialValues(); // 直接提取初始值,无需条件判断 extractUserInitialValues(); // 直接提取初始值,无需条件判断
return true; return true;
} catch(...) { } catch(...) {
m_lastError = "Failed to load configuration from data manager"; m_lastError = tr("Failed to load configuration from data manager");
return false; return false;
} }
} }
@ -1160,7 +1139,7 @@ bool nmCalculationAutoFitLM::startAutoFitting()
StopReasonLM finalReason = LM_CONTINUE_OPTIMIZATION; StopReasonLM finalReason = LM_CONTINUE_OPTIMIZATION;
if(m_isRunning) { if(m_isRunning) {
m_lastError = "Auto fitting is already running"; m_lastError = tr("Auto fitting is already running");
return false; return false;
} }
@ -1175,26 +1154,26 @@ bool nmCalculationAutoFitLM::startAutoFitting()
emit logMessageGenerated(tr("Enabled parameters count: %1").arg(enabledParams)); emit logMessageGenerated(tr("Enabled parameters count: %1").arg(enabledParams));
if(enabledParams == 0) { if(enabledParams == 0) {
m_lastError = "No parameters enabled for optimization"; m_lastError = tr("No parameters enabled for optimization");
emit logMessageGenerated(tr("ERROR: No parameters enabled for optimization")); emit logMessageGenerated(tr("ERROR: No parameters enabled for optimization"));
return false; return false;
} }
if(m_targetLogLogData.size() < 3) { if(m_targetLogLogData.size() < 3) {
m_lastError = "Target LogLog data is empty or insufficient"; m_lastError = tr("Target LogLog data is empty or insufficient");
emit logMessageGenerated(tr("ERROR: Target LogLog data is empty or insufficient")); emit logMessageGenerated(tr("ERROR: Target LogLog data is empty or insufficient"));
return false; return false;
} }
if(m_targetLogLogData[0].size() != m_targetLogLogData[1].size() || if(m_targetLogLogData[0].size() != m_targetLogLogData[1].size() ||
m_targetLogLogData[0].size() != m_targetLogLogData[2].size()) { m_targetLogLogData[0].size() != m_targetLogLogData[2].size()) {
m_lastError = "Target LogLog data arrays have inconsistent sizes"; m_lastError = tr("Target LogLog data arrays have inconsistent sizes");
emit logMessageGenerated(tr("ERROR: Target LogLog data arrays have inconsistent sizes")); emit logMessageGenerated(tr("ERROR: Target LogLog data arrays have inconsistent sizes"));
return false; return false;
} }
if(m_targetWellName.isEmpty()) { if(m_targetWellName.isEmpty()) {
m_lastError = "Target well name is empty"; m_lastError = tr("Target well name is empty");
emit logMessageGenerated(tr("ERROR: Target well name is empty")); emit logMessageGenerated(tr("ERROR: Target well name is empty"));
return false; return false;
} }
@ -1258,7 +1237,6 @@ bool nmCalculationAutoFitLM::startAutoFitting()
m_globalBestLogLogData, m_globalBestLogLogData,
0, 0,
m_globalBestFitness); m_globalBestFitness);
emitTimeWindowDiagnostics(m_globalBestObjectiveBreakdown);
} else { } else {
m_hasValidUserSolution = false; m_hasValidUserSolution = false;
emit logMessageGenerated(tr("Initial solution evaluation failed")); emit logMessageGenerated(tr("Initial solution evaluation failed"));
@ -1388,12 +1366,12 @@ bool nmCalculationAutoFitLM::startAutoFitting()
} }
} catch(const std::exception& e) { } catch(const std::exception& e) {
finalFullSolverSucceeded = false; finalFullSolverSucceeded = false;
m_lastError = QString("Failed to apply final parameters: %1").arg(e.what()); m_lastError = tr("Failed to apply final parameters: %1").arg(e.what());
emit logMessageGenerated( emit logMessageGenerated(
tr("ERROR: Failed to apply final parameters: %1").arg(e.what())); tr("ERROR: Failed to apply final parameters: %1").arg(e.what()));
} catch(...) { } catch(...) {
finalFullSolverSucceeded = false; finalFullSolverSucceeded = false;
m_lastError = "Failed to apply final parameters due to unknown error"; m_lastError = tr("Failed to apply final parameters due to unknown error");
emit logMessageGenerated( emit logMessageGenerated(
tr("ERROR: Unknown error applying final parameters")); tr("ERROR: Unknown error applying final parameters"));
} }
@ -1683,7 +1661,6 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting()
m_globalBestFitness = evaluation.fitness; m_globalBestFitness = evaluation.fitness;
m_globalBestObjectiveBreakdown = evaluation.breakdown; m_globalBestObjectiveBreakdown = evaluation.breakdown;
m_globalBestLogLogData = evaluation.curve; m_globalBestLogLogData = evaluation.curve;
emitTimeWindowDiagnostics(evaluation.breakdown);
emit bestCurveUpdated(m_targetLogLogData, emit bestCurveUpdated(m_targetLogLogData,
m_globalBestLogLogData, m_globalBestLogLogData,
m_currentIteration + 1, m_currentIteration + 1,
@ -3960,11 +3937,6 @@ double nmCalculationAutoFitLM::calculateLogLogCurveError(
m_comparisonTimeMin = overlapMinX; m_comparisonTimeMin = overlapMinX;
m_comparisonTimeMax = overlapMaxX; m_comparisonTimeMax = overlapMaxX;
writeTraceMetaFile(); writeTraceMetaFile();
emit logMessageGenerated(
tr("Fixed LM comparison time range: [%1, %2]; %3 windows, %4% overlap")
.arg(overlapMinX, 0, 'g', 8).arg(overlapMaxX, 0, 'g', 8)
.arg(kAutoFitTimeWindowCount)
.arg(kAutoFitTimeWindowOverlapRatio * 100.0, 0, 'f', 0));
} }
} }
m_lastObjectiveBreakdown = breakdown; m_lastObjectiveBreakdown = breakdown;

Loading…
Cancel
Save