|
|
|
@ -721,8 +721,8 @@ void nmCalculationAutoFitPSO::setTargetLogLogData(const QVector<QVector<double>
|
|
|
|
void nmCalculationAutoFitPSO::stopFitting()
|
|
|
|
void nmCalculationAutoFitPSO::stopFitting()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// 用户点击停止时走这里。停止策略是“请求式停止”:
|
|
|
|
// 用户点击停止时走这里。停止策略是“请求式停止”:
|
|
|
|
// 先置 m_shouldStop,让主循环/求解器等待逻辑自然退出;短时间内还在评价时再重置计数。
|
|
|
|
// 只置 m_shouldStop,让主循环/求解器等待逻辑退出并自行维护任务计数。
|
|
|
|
// 这样可以减少 DLL 任务被硬中断导致的数据状态残留。
|
|
|
|
// 不在这里清理临时目录或强制清零计数,避免与正在返回的 DLL 任务竞争。
|
|
|
|
if(m_simulationMode && m_simulationTimer) {
|
|
|
|
if(m_simulationMode && m_simulationTimer) {
|
|
|
|
m_simulationTimer->stop();
|
|
|
|
m_simulationTimer->stop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -736,25 +736,28 @@ void nmCalculationAutoFitPSO::stopFitting()
|
|
|
|
|
|
|
|
|
|
|
|
m_shouldStop = true;
|
|
|
|
m_shouldStop = true;
|
|
|
|
|
|
|
|
|
|
|
|
// 等待当前评估完成,缩短超时时间
|
|
|
|
if(m_simulationMode) {
|
|
|
|
|
|
|
|
m_isRunning = false;
|
|
|
|
|
|
|
|
closeTraceFile();
|
|
|
|
|
|
|
|
cleanupTemporaryDirectory();
|
|
|
|
|
|
|
|
emit logMessageGenerated(tr("PSO simulation stop request processed"));
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 给当前评价一个短暂的自然退出时间。若仍在运行,
|
|
|
|
|
|
|
|
// runSolverDll() 会在下一个等待周期检查 m_shouldStop 并结束任务。
|
|
|
|
int waitCount = 0;
|
|
|
|
int waitCount = 0;
|
|
|
|
|
|
|
|
|
|
|
|
while(m_evaluationInProgress > 0 && waitCount < 30) { // 减少等待时间
|
|
|
|
while(m_evaluationInProgress > 0 && waitCount < 30) {
|
|
|
|
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 50);
|
|
|
|
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 50);
|
|
|
|
msleep(50);
|
|
|
|
msleep(50);
|
|
|
|
waitCount++;
|
|
|
|
waitCount++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 超时时强制重置
|
|
|
|
|
|
|
|
if(m_evaluationInProgress > 0) {
|
|
|
|
if(m_evaluationInProgress > 0) {
|
|
|
|
DEBUG_OUT("Force resetting evaluation counter");
|
|
|
|
emit logMessageGenerated(tr("Waiting for current solver evaluation to stop..."));
|
|
|
|
emit logMessageGenerated(tr("Force stopping current evaluation..."));
|
|
|
|
|
|
|
|
m_evaluationInProgress = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 确保运行标志被清除
|
|
|
|
|
|
|
|
m_isRunning = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
emit logMessageGenerated(tr("PSO optimization stop request processed"));
|
|
|
|
emit logMessageGenerated(tr("PSO optimization stop request processed"));
|
|
|
|
DEBUG_OUT("Stop request processed");
|
|
|
|
DEBUG_OUT("Stop request processed");
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
@ -762,8 +765,6 @@ void nmCalculationAutoFitPSO::stopFitting()
|
|
|
|
emit logMessageGenerated(tr("Stop request received but optimization is not running"));
|
|
|
|
emit logMessageGenerated(tr("Stop request received but optimization is not running"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
closeTraceFile();
|
|
|
|
|
|
|
|
cleanupTemporaryDirectory();
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool nmCalculationAutoFitPSO::isRunning() const
|
|
|
|
bool nmCalculationAutoFitPSO::isRunning() const
|
|
|
|
@ -2903,6 +2904,15 @@ bool nmCalculationAutoFitPSO::startAutoFitting()
|
|
|
|
|
|
|
|
|
|
|
|
emit logMessageGenerated(tr("Target data validation passed (%1 data points)").arg(m_targetLogLogData[0].size()));
|
|
|
|
emit logMessageGenerated(tr("Target data validation passed (%1 data points)").arg(m_targetLogLogData[0].size()));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(m_targetWellName.isEmpty()) {
|
|
|
|
|
|
|
|
m_lastError = "Target well name is empty";
|
|
|
|
|
|
|
|
emit logMessageGenerated(tr("ERROR: Target well name is empty"));
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
emit logMessageGenerated(tr("Particle evaluation mode: solve all wells, retain target well '%1' only")
|
|
|
|
|
|
|
|
.arg(m_targetWellName));
|
|
|
|
|
|
|
|
|
|
|
|
// 使用保存的初始值进行精英保护。resetOptimizer() 会清空部分运行状态,
|
|
|
|
// 使用保存的初始值进行精英保护。resetOptimizer() 会清空部分运行状态,
|
|
|
|
// 所以先把用户当前模型参数缓存下来,后面再恢复用于初始解评价和粒子初始化。
|
|
|
|
// 所以先把用户当前模型参数缓存下来,后面再恢复用于初始解评价和粒子初始化。
|
|
|
|
QVector<double> savedInitialValues = m_initialValues;
|
|
|
|
QVector<double> savedInitialValues = m_initialValues;
|
|
|
|
@ -3286,13 +3296,37 @@ bool nmCalculationAutoFitPSO::startAutoFitting()
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_isRunning = false;
|
|
|
|
bool finalFullSolverSucceeded = true;
|
|
|
|
|
|
|
|
bool finalFullSolverExecuted = false;
|
|
|
|
|
|
|
|
|
|
|
|
// 应用最终参数
|
|
|
|
// 应用最终参数
|
|
|
|
if(!m_globalBestPosition.isEmpty()) {
|
|
|
|
if(!m_globalBestPosition.isEmpty()) {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
emit logMessageGenerated(tr("Applying optimized parameters to model..."));
|
|
|
|
emit logMessageGenerated(tr("Applying optimized parameters to model..."));
|
|
|
|
applyParametersToDataManager(m_globalBestPosition);
|
|
|
|
applyParametersToDataManager(m_globalBestPosition);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(m_shouldStop) {
|
|
|
|
|
|
|
|
// 手动停止优先保持快速返回,仅写回已确认的最优参数。
|
|
|
|
|
|
|
|
emit logMessageGenerated(tr("Final full-field calculation skipped after user stop"));
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// 粒子阶段只保留目标井临时曲线。正常结束后用最优参数完整计算一次,
|
|
|
|
|
|
|
|
// 将全部井曲线和网格压力场写回项目,该次不计入 PSO 粒子评价数。
|
|
|
|
|
|
|
|
emit logMessageGenerated(tr("Running final full-field calculation with optimized parameters..."));
|
|
|
|
|
|
|
|
finalFullSolverExecuted = true;
|
|
|
|
|
|
|
|
finalFullSolverSucceeded = runFinalFullSolver();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 {
|
|
|
|
|
|
|
|
emit logMessageGenerated(tr("ERROR: Final full-field calculation failed"));
|
|
|
|
|
|
|
|
m_lastError = tr("Optimized parameters were found, but the final full-field calculation failed");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
saveOptimizationResult();
|
|
|
|
saveOptimizationResult();
|
|
|
|
|
|
|
|
|
|
|
|
// 输出最终优化结果
|
|
|
|
// 输出最终优化结果
|
|
|
|
@ -3311,16 +3345,24 @@ bool nmCalculationAutoFitPSO::startAutoFitting()
|
|
|
|
|
|
|
|
|
|
|
|
emit logMessageGenerated(finalParams);
|
|
|
|
emit logMessageGenerated(finalParams);
|
|
|
|
|
|
|
|
|
|
|
|
emit logMessageGenerated(tr("Parameters applied successfully to data manager"));
|
|
|
|
if(finalFullSolverExecuted && finalFullSolverSucceeded) {
|
|
|
|
|
|
|
|
emit logMessageGenerated(tr("Parameters and full-field results applied successfully to data manager"));
|
|
|
|
|
|
|
|
} else if(!finalFullSolverExecuted) {
|
|
|
|
|
|
|
|
emit logMessageGenerated(tr("Optimized parameters applied to data manager"));
|
|
|
|
|
|
|
|
}
|
|
|
|
} catch(const std::exception& e) {
|
|
|
|
} catch(const std::exception& e) {
|
|
|
|
|
|
|
|
finalFullSolverSucceeded = false;
|
|
|
|
emit logMessageGenerated(tr("ERROR: Failed to apply final parameters: %1").arg(e.what()));
|
|
|
|
emit logMessageGenerated(tr("ERROR: Failed to apply final parameters: %1").arg(e.what()));
|
|
|
|
m_lastError = QString("Failed to apply final parameters: %1").arg(e.what());
|
|
|
|
m_lastError = QString("Failed to apply final parameters: %1").arg(e.what());
|
|
|
|
} catch(...) {
|
|
|
|
} catch(...) {
|
|
|
|
|
|
|
|
finalFullSolverSucceeded = false;
|
|
|
|
emit logMessageGenerated(tr("ERROR: Unknown error applying final parameters"));
|
|
|
|
emit logMessageGenerated(tr("ERROR: Unknown error applying final parameters"));
|
|
|
|
m_lastError = "Failed to apply final parameters due to unknown error";
|
|
|
|
m_lastError = "Failed to apply final parameters due to unknown error";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m_isRunning = false;
|
|
|
|
|
|
|
|
|
|
|
|
// 判断系统确定最终结果
|
|
|
|
// 判断系统确定最终结果
|
|
|
|
bool success;
|
|
|
|
bool success;
|
|
|
|
QString message;
|
|
|
|
QString message;
|
|
|
|
@ -3363,6 +3405,11 @@ bool nmCalculationAutoFitPSO::startAutoFitting()
|
|
|
|
emit logMessageGenerated(tr("=== PSO OPTIMIZATION - UNKNOWN END ==="));
|
|
|
|
emit logMessageGenerated(tr("=== PSO OPTIMIZATION - UNKNOWN END ==="));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!finalFullSolverSucceeded) {
|
|
|
|
|
|
|
|
success = false;
|
|
|
|
|
|
|
|
message = m_lastError;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
emitRunSummary(success, finalReason);
|
|
|
|
emitRunSummary(success, finalReason);
|
|
|
|
|
|
|
|
|
|
|
|
// 先发送最终进度更新,确保进度条达到100%
|
|
|
|
// 先发送最终进度更新,确保进度条达到100%
|
|
|
|
@ -3961,7 +4008,7 @@ double nmCalculationAutoFitPSO::evaluateFitness(const QVector<double>& parameter
|
|
|
|
// 1. 校验粒子参数是否在用户设置的上下界和基本物理范围内;
|
|
|
|
// 1. 校验粒子参数是否在用户设置的上下界和基本物理范围内;
|
|
|
|
// 2. 将参数写入 DataManager 的储层/目标井对象;
|
|
|
|
// 2. 将参数写入 DataManager 的储层/目标井对象;
|
|
|
|
// 3. 调用真实数值求解器,生成模拟结果;
|
|
|
|
// 3. 调用真实数值求解器,生成模拟结果;
|
|
|
|
// 4. 从目标井读取模拟后的 result log-log 曲线;
|
|
|
|
// 4. 从本次求解任务读取目标井 result log-log 曲线;
|
|
|
|
// 5. 与目标 history log-log 曲线计算误差,误差越小代表拟合越好。
|
|
|
|
// 5. 与目标 history log-log 曲线计算误差,误差越小代表拟合越好。
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// 返回 1e10 表示该粒子评价失败或结果不可用。PSO 会把它当成很差的解。
|
|
|
|
// 返回 1e10 表示该粒子评价失败或结果不可用。PSO 会把它当成很差的解。
|
|
|
|
@ -4122,24 +4169,11 @@ double nmCalculationAutoFitPSO::evaluateFitness(const QVector<double>& parameter
|
|
|
|
return 1e10;
|
|
|
|
return 1e10;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 5. 获取 LogLog 数据。runSolver() 会更新 DataManager 中目标井的计算结果,
|
|
|
|
// 5. 获取 LogLog 数据。runSolverDll() 直接从求解任务复制目标井曲线,
|
|
|
|
// 这里再从目标井读取 resultLogLogData 作为模拟曲线。
|
|
|
|
// 不再依赖 DataManager 中可能被其它井或上一粒子改写的共享结果。
|
|
|
|
QVector<QVector<double>> resultLogLogData;
|
|
|
|
QVector<QVector<double>> resultLogLogData = m_lastEvaluatedLogLogData;
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
nmDataWellBase* pTargetWell = dataManager->findWellByName(m_targetWellName);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!pTargetWell) {
|
|
|
|
|
|
|
|
DEBUG_OUT(QString("%1: Call #%2 - Target well '%3' NOT FOUND")
|
|
|
|
|
|
|
|
.arg(funcName).arg(callCount).arg(m_targetWellName));
|
|
|
|
|
|
|
|
return 1e10;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DEBUG_OUT(QString("%1: Call #%2 - Target well found: %3")
|
|
|
|
|
|
|
|
.arg(funcName).arg(callCount).arg(m_targetWellName));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
resultLogLogData = pTargetWell->getResultLogLog();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!validateLogLogData(resultLogLogData)) {
|
|
|
|
if(!validateLogLogData(resultLogLogData)) {
|
|
|
|
DEBUG_OUT(QString("%1: Call #%2 - LogLog data VALIDATION FAILED")
|
|
|
|
DEBUG_OUT(QString("%1: Call #%2 - LogLog data VALIDATION FAILED")
|
|
|
|
.arg(funcName).arg(callCount));
|
|
|
|
.arg(funcName).arg(callCount));
|
|
|
|
@ -5145,7 +5179,7 @@ QVector<QVector<double>> nmCalculationAutoFitPSO::runSolverDll()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// DLL 求解器路径。
|
|
|
|
// DLL 求解器路径。
|
|
|
|
// 这个函数负责把当前 DataManager 中的项目状态交给底层数值求解器,
|
|
|
|
// 这个函数负责把当前 DataManager 中的项目状态交给底层数值求解器,
|
|
|
|
// 并让目标井生成 result log-log 数据。evaluateFitness() 后续会从目标井读取该结果。
|
|
|
|
// 数值求解仍包含全部计算井,以保留井间干扰;后处理只提取目标井曲线。
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// 如果这里失败,通常需要优先检查:HX_NWTM.dll、license、网格/井数据是否完整、
|
|
|
|
// 如果这里失败,通常需要优先检查:HX_NWTM.dll、license、网格/井数据是否完整、
|
|
|
|
// 目标井是否存在,以及 DataManager 中刚写入的参数是否导致求解器异常。
|
|
|
|
// 目标井是否存在,以及 DataManager 中刚写入的参数是否导致求解器异常。
|
|
|
|
@ -5157,6 +5191,7 @@ QVector<QVector<double>> nmCalculationAutoFitPSO::runSolverDll()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
++m_evaluationInProgress;
|
|
|
|
++m_evaluationInProgress;
|
|
|
|
|
|
|
|
m_lastEvaluatedLogLogData.clear();
|
|
|
|
QVector<QVector<double>> result;
|
|
|
|
QVector<QVector<double>> result;
|
|
|
|
nmCalculationDllPebiSolverTask* dllTask = nullptr;
|
|
|
|
nmCalculationDllPebiSolverTask* dllTask = nullptr;
|
|
|
|
|
|
|
|
|
|
|
|
@ -5164,6 +5199,15 @@ QVector<QVector<double>> nmCalculationAutoFitPSO::runSolverDll()
|
|
|
|
DEBUG_OUT("Creating DLL solver task");
|
|
|
|
DEBUG_OUT("Creating DLL solver task");
|
|
|
|
dllTask = new nmCalculationDllPebiSolverTask(m_tempDirectory);
|
|
|
|
dllTask = new nmCalculationDllPebiSolverTask(m_tempDirectory);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(m_targetWellName.isEmpty()) {
|
|
|
|
|
|
|
|
DEBUG_OUT("Target well name is empty - target-only solver cannot start");
|
|
|
|
|
|
|
|
delete dllTask;
|
|
|
|
|
|
|
|
--m_evaluationInProgress;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dllTask->setAutoFitTargetWell(m_targetWellName);
|
|
|
|
|
|
|
|
|
|
|
|
if(m_shouldStop) {
|
|
|
|
if(m_shouldStop) {
|
|
|
|
DEBUG_OUT("Should stop - cleaning up and returning empty result");
|
|
|
|
DEBUG_OUT("Should stop - cleaning up and returning empty result");
|
|
|
|
delete dllTask;
|
|
|
|
delete dllTask;
|
|
|
|
@ -5223,22 +5267,9 @@ QVector<QVector<double>> nmCalculationAutoFitPSO::runSolverDll()
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 验证结果数据是否已更新。DLL 任务会把结果写回 DataManager 中的目标井对象。
|
|
|
|
// 任务结束后复制其局部结果,删除任务前不再持有任务内部引用。
|
|
|
|
nmDataAnalyzeManager* dataManager = nmDataAnalyzeManager::getCurrentInstance();
|
|
|
|
QVector<QVector<double>> pressureResult = dllTask->getAutoFitResultPressure();
|
|
|
|
//QVector<nmDataWellBase*> wells = dataManager->getWellDataList();
|
|
|
|
QVector<QVector<double>> logLogResult = dllTask->getAutoFitResultLogLog();
|
|
|
|
nmDataWellBase* pTargetWell = dataManager->findWellByName(m_targetWellName);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!pTargetWell) {
|
|
|
|
|
|
|
|
DEBUG_OUT("No wells found in data manager after DLL execution");
|
|
|
|
|
|
|
|
delete dllTask;
|
|
|
|
|
|
|
|
--m_evaluationInProgress;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 验证结果数据。evaluateFitness() 最终用的是 logLogResult,
|
|
|
|
|
|
|
|
// 但这里返回 pressureResult 给 validateSolverResult() 做基本求解成功判断。
|
|
|
|
|
|
|
|
QVector<QVector<double>> pressureResult = pTargetWell->getResultPressure();
|
|
|
|
|
|
|
|
QVector<QVector<double>> logLogResult = pTargetWell->getResultLogLog();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DEBUG_OUT(QString("DLL result verification - Pressure arrays: %1, LogLog arrays: %2")
|
|
|
|
DEBUG_OUT(QString("DLL result verification - Pressure arrays: %1, LogLog arrays: %2")
|
|
|
|
.arg(pressureResult.size()).arg(logLogResult.size()));
|
|
|
|
.arg(pressureResult.size()).arg(logLogResult.size()));
|
|
|
|
@ -5257,8 +5288,12 @@ QVector<QVector<double>> nmCalculationAutoFitPSO::runSolverDll()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 数据有效性检查
|
|
|
|
// 数据有效性检查
|
|
|
|
if(pressureResult.size() >= 2 && pressureResult[0].size() > 0 && pressureResult[1].size() > 0) {
|
|
|
|
if(pressureResult.size() >= 2
|
|
|
|
|
|
|
|
&& pressureResult[0].size() > 0
|
|
|
|
|
|
|
|
&& pressureResult[1].size() > 0
|
|
|
|
|
|
|
|
&& validateLogLogData(logLogResult)) {
|
|
|
|
result = pressureResult;
|
|
|
|
result = pressureResult;
|
|
|
|
|
|
|
|
m_lastEvaluatedLogLogData = logLogResult;
|
|
|
|
DEBUG_OUT(QString("Got DLL solver result: %1 points").arg(result[0].size()));
|
|
|
|
DEBUG_OUT(QString("Got DLL solver result: %1 points").arg(result[0].size()));
|
|
|
|
m_consecutiveFailures = 0;
|
|
|
|
m_consecutiveFailures = 0;
|
|
|
|
|
|
|
|
|
|
|
|
@ -5326,6 +5361,58 @@ QVector<QVector<double>> nmCalculationAutoFitPSO::runSolverDll()
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool nmCalculationAutoFitPSO::runFinalFullSolver()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// 不设置目标井名,任务按原完整模式保存全部井和网格结果。
|
|
|
|
|
|
|
|
if(m_evaluationInProgress > 0) {
|
|
|
|
|
|
|
|
DEBUG_OUT("Cannot start final full-field solver while another evaluation is running");
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
++m_evaluationInProgress;
|
|
|
|
|
|
|
|
nmCalculationDllPebiSolverTask dllTask(m_tempDirectory);
|
|
|
|
|
|
|
|
dllTask.start();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const int maxWait = 3600000;
|
|
|
|
|
|
|
|
const int checkInterval = 50;
|
|
|
|
|
|
|
|
QTime waitTimer;
|
|
|
|
|
|
|
|
waitTimer.start();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while(waitTimer.elapsed() < maxWait) {
|
|
|
|
|
|
|
|
if(dllTask.wait(checkInterval)) {
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 最终完整计算可能持续较长时间,此处需处理停止按钮事件。
|
|
|
|
|
|
|
|
QApplication::processEvents(QEventLoop::AllEvents, checkInterval);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!dllTask.isRunning()) {
|
|
|
|
|
|
|
|
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()) {
|
|
|
|
|
|
|
|
DEBUG_OUT("Final full-field solver timeout, terminating task");
|
|
|
|
|
|
|
|
dllTask.terminate();
|
|
|
|
|
|
|
|
dllTask.wait(2000);
|
|
|
|
|
|
|
|
--m_evaluationInProgress;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dllTask.wait();
|
|
|
|
|
|
|
|
const bool succeeded = dllTask.wasSuccessful();
|
|
|
|
|
|
|
|
--m_evaluationInProgress;
|
|
|
|
|
|
|
|
return succeeded;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//QVector<QVector<double>> nmCalculationAutoFitPSO::runSolverExe()
|
|
|
|
//QVector<QVector<double>> nmCalculationAutoFitPSO::runSolverExe()
|
|
|
|
//{
|
|
|
|
//{
|
|
|
|
// DEBUG_OUT("SOLVER EXE START");
|
|
|
|
// DEBUG_OUT("SOLVER EXE START");
|
|
|
|
|