|
|
|
|
@ -470,6 +470,7 @@ nmCalculationAutoFitLM::nmCalculationAutoFitLM(QObject* parent)
|
|
|
|
|
: QObject(parent)
|
|
|
|
|
, m_isRunning(false)
|
|
|
|
|
, m_shouldStop(false)
|
|
|
|
|
, m_isFinalizing(false)
|
|
|
|
|
, m_currentIteration(0)
|
|
|
|
|
, m_globalBestFitness(1e10)
|
|
|
|
|
, m_maxIterations(100)
|
|
|
|
|
@ -568,6 +569,12 @@ void nmCalculationAutoFitLM::setTargetLogLogData(const QVector<QVector<double> >
|
|
|
|
|
|
|
|
|
|
void nmCalculationAutoFitLM::stopFitting()
|
|
|
|
|
{
|
|
|
|
|
if(m_isFinalizing) {
|
|
|
|
|
emit logMessageGenerated(
|
|
|
|
|
tr("The final full-field calculation is already running"));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 用户点击停止时只设置请求标志,让 LM 主循环和求解器等待逻辑自然退出。
|
|
|
|
|
if(m_isRunning) {
|
|
|
|
|
emit logMessageGenerated(tr("=== User Stop Request Received ==="));
|
|
|
|
|
@ -659,6 +666,7 @@ void nmCalculationAutoFitLM::resetOptimizer()
|
|
|
|
|
m_userInitialFitness = 1e10;
|
|
|
|
|
m_hasValidUserSolution = false;
|
|
|
|
|
m_traceMetaFilePath.clear();
|
|
|
|
|
m_isFinalizing = false;
|
|
|
|
|
|
|
|
|
|
DEBUG_OUT("LM optimizer reset");
|
|
|
|
|
}
|
|
|
|
|
@ -1132,6 +1140,7 @@ bool nmCalculationAutoFitLM::startAutoFitting()
|
|
|
|
|
}
|
|
|
|
|
m_isRunning = true;
|
|
|
|
|
m_shouldStop = false;
|
|
|
|
|
m_isFinalizing = false;
|
|
|
|
|
m_currentIteration = 0;
|
|
|
|
|
m_consecutiveFailures = 0;
|
|
|
|
|
m_initialValues = savedInitialValues;
|
|
|
|
|
@ -1213,7 +1222,8 @@ bool nmCalculationAutoFitLM::startAutoFitting()
|
|
|
|
|
&m_globalBestObjectiveBreakdown);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(m_globalBestFitness < m_targetError) {
|
|
|
|
|
if(finalReason != LM_USER_STOPPED &&
|
|
|
|
|
m_globalBestFitness < m_targetError) {
|
|
|
|
|
finalReason = LM_TARGET_ACHIEVED;
|
|
|
|
|
}
|
|
|
|
|
} catch(const std::exception& e) {
|
|
|
|
|
@ -1221,6 +1231,7 @@ bool nmCalculationAutoFitLM::startAutoFitting()
|
|
|
|
|
emit logMessageGenerated(tr("CRITICAL ERROR: %1").arg(e.what()));
|
|
|
|
|
closeTraceFile();
|
|
|
|
|
cleanupTemporaryDirectory();
|
|
|
|
|
m_isFinalizing = false;
|
|
|
|
|
m_isRunning = false;
|
|
|
|
|
emit fittingFinished(false, m_lastError);
|
|
|
|
|
return false;
|
|
|
|
|
@ -1229,16 +1240,21 @@ bool nmCalculationAutoFitLM::startAutoFitting()
|
|
|
|
|
emit logMessageGenerated(tr("CRITICAL ERROR: Unknown exception in automatic fitting"));
|
|
|
|
|
closeTraceFile();
|
|
|
|
|
cleanupTemporaryDirectory();
|
|
|
|
|
m_isFinalizing = false;
|
|
|
|
|
m_isRunning = false;
|
|
|
|
|
emit fittingFinished(false, m_lastError);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool finalFullSolverSucceeded = true;
|
|
|
|
|
// 只有最终完整求解实际执行并提交快照后才能置为成功。
|
|
|
|
|
bool finalFullSolverSucceeded = false;
|
|
|
|
|
bool finalFullSolverExecuted = false;
|
|
|
|
|
|
|
|
|
|
if(!m_globalBestPosition.isEmpty()) {
|
|
|
|
|
try {
|
|
|
|
|
// Stop 只结束优化迭代;从这里开始必须用当前最优参数生成并发布正式快照。
|
|
|
|
|
m_isFinalizing = true;
|
|
|
|
|
emit finalizingStarted();
|
|
|
|
|
emit logMessageGenerated(tr("Applying optimized parameters to model..."));
|
|
|
|
|
applyParametersToDataManager(m_globalBestPosition);
|
|
|
|
|
|
|
|
|
|
@ -1255,10 +1271,6 @@ bool nmCalculationAutoFitLM::startAutoFitting()
|
|
|
|
|
dataManager->invalidatePebiGrid();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(m_shouldStop) {
|
|
|
|
|
emit logMessageGenerated(
|
|
|
|
|
tr("Final full-field calculation skipped after user stop"));
|
|
|
|
|
} else {
|
|
|
|
|
emit logMessageGenerated(
|
|
|
|
|
tr("Running final full-field calculation with optimized parameters..."));
|
|
|
|
|
finalFullSolverExecuted = true;
|
|
|
|
|
@ -1267,18 +1279,12 @@ bool nmCalculationAutoFitLM::startAutoFitting()
|
|
|
|
|
if(finalFullSolverSucceeded) {
|
|
|
|
|
emit logMessageGenerated(
|
|
|
|
|
tr("Final full-field calculation completed successfully"));
|
|
|
|
|
} else if(m_shouldStop) {
|
|
|
|
|
finalFullSolverExecuted = false;
|
|
|
|
|
finalFullSolverSucceeded = true;
|
|
|
|
|
emit logMessageGenerated(
|
|
|
|
|
tr("Final full-field calculation stopped by user"));
|
|
|
|
|
} else {
|
|
|
|
|
m_lastError =
|
|
|
|
|
tr("Optimized parameters were found, but the final full-field calculation failed");
|
|
|
|
|
emit logMessageGenerated(
|
|
|
|
|
tr("ERROR: Final full-field calculation failed"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
saveOptimizationResult();
|
|
|
|
|
emit logMessageGenerated(tr("=== Optimization Results ==="));
|
|
|
|
|
@ -1317,6 +1323,7 @@ bool nmCalculationAutoFitLM::startAutoFitting()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_isFinalizing = false;
|
|
|
|
|
m_isRunning = false;
|
|
|
|
|
bool success = false;
|
|
|
|
|
QString message;
|
|
|
|
|
@ -1349,7 +1356,7 @@ bool nmCalculationAutoFitLM::startAutoFitting()
|
|
|
|
|
emit logMessageGenerated(tr("=== LM AUTOMATIC FITTING - MAX ITERATIONS ==="));
|
|
|
|
|
} else if(finalReason == LM_USER_STOPPED) {
|
|
|
|
|
success = true;
|
|
|
|
|
message = QString(tr("Best error: %1, Iterations: %2"))
|
|
|
|
|
message = QString(tr("Stopped by user. Best error: %1, Iterations: %2"))
|
|
|
|
|
.arg(m_globalBestFitness, 0, 'e', 4)
|
|
|
|
|
.arg(m_currentIteration + 1);
|
|
|
|
|
emit logMessageGenerated(tr("=== LM AUTOMATIC FITTING STOPPED BY USER ==="));
|
|
|
|
|
@ -4138,13 +4145,6 @@ bool nmCalculationAutoFitLM::runFinalFullSolver()
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(m_shouldStop) {
|
|
|
|
|
DEBUG_OUT("Final full-field solver terminated by user");
|
|
|
|
|
dllTask.terminate();
|
|
|
|
|
dllTask.wait(2000);
|
|
|
|
|
--m_evaluationInProgress;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(dllTask.isRunning()) {
|
|
|
|
|
|