|
|
|
|
@ -130,6 +130,13 @@ nmSubWndMain::nmSubWndMain(QWidget *parent, QString sExt) :
|
|
|
|
|
m_pSolverTask = nullptr;
|
|
|
|
|
m_pSolverDataManager = nullptr;
|
|
|
|
|
m_pSolverFitting = nullptr;
|
|
|
|
|
m_pPendingResultDataManager = nullptr;
|
|
|
|
|
m_pPendingResultFitting = nullptr;
|
|
|
|
|
m_bPendingResultWidgetRefresh = false;
|
|
|
|
|
m_bSolverResultCompletionPending = false;
|
|
|
|
|
m_bPendingSolverSucceeded = false;
|
|
|
|
|
m_nPendingSolverPebiCount = -1;
|
|
|
|
|
m_nPendingSolverTimeMs = -1;
|
|
|
|
|
m_bSolverStartPending = false;
|
|
|
|
|
m_bSolverCancelRequested = false;
|
|
|
|
|
m_pPlotToolBar = nullptr;
|
|
|
|
|
@ -486,6 +493,7 @@ bool nmSubWndMain::runCmdBy(QString sName, QString sID)
|
|
|
|
|
|
|
|
|
|
case 5117:
|
|
|
|
|
this->mergeAnaResultToFitting();
|
|
|
|
|
this->schedulePendingResultWidgets();
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
case 5121:
|
|
|
|
|
@ -1523,15 +1531,20 @@ void nmSubWndMain::generationMesh()
|
|
|
|
|
void nmSubWndMain::solveAndAnalyze()
|
|
|
|
|
{
|
|
|
|
|
if(!s_pPendingSolverWindow.isNull() ||
|
|
|
|
|
!s_pRunningSolverTask.isNull()) {
|
|
|
|
|
!s_pRunningSolverTask.isNull() ||
|
|
|
|
|
m_bSolverResultCompletionPending) {
|
|
|
|
|
QMessageBox::information(this, tr("solver error"), tr("task is running!"));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 强制清理旧的(以防万一上次没删掉)
|
|
|
|
|
// Qt 4.8 下复用已经隐藏的进度框,避免窗口析构触发主界面重绘重入。
|
|
|
|
|
if (m_pProgressDlg != nullptr) {
|
|
|
|
|
delete m_pProgressDlg;
|
|
|
|
|
m_pProgressDlg = nullptr;
|
|
|
|
|
m_pProgressDlg->reset();
|
|
|
|
|
QPushButton* pCancelButton =
|
|
|
|
|
m_pProgressDlg->findChild<QPushButton*>();
|
|
|
|
|
if(pCancelButton != nullptr) {
|
|
|
|
|
pCancelButton->setEnabled(true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 新一次启动前清空旧上下文;后续所有检查通过后再成对写入。
|
|
|
|
|
@ -1645,9 +1658,9 @@ void nmSubWndMain::solveAndAnalyze()
|
|
|
|
|
0,
|
|
|
|
|
getMainWindow());
|
|
|
|
|
m_pProgressDlg->setWindowTitle(tr("Solver Progress"));
|
|
|
|
|
// 后台只读取任务值快照;应用级模态仍用于阻止重复启动、切换成果等会让
|
|
|
|
|
// 用户误判当前计算归属的操作,数据安全不再依赖该对话框冻结界面。
|
|
|
|
|
m_pProgressDlg->setWindowModality(Qt::ApplicationModal);
|
|
|
|
|
// 保持 8 月 25 日前的稳定行为。任务和输入快照负责数据安全,进度框不参与
|
|
|
|
|
// 全局窗口阻塞,避免首次创建结果窗口时进入 Qt 4.8 模态布局重入。
|
|
|
|
|
m_pProgressDlg->setWindowModality(Qt::NonModal);
|
|
|
|
|
|
|
|
|
|
// 某些系统下,对话框右上角的关闭按钮可能仍存
|
|
|
|
|
// 使用 WindowFlags 彻底禁用关闭按钮
|
|
|
|
|
@ -1684,8 +1697,7 @@ void nmSubWndMain::startSolverTask()
|
|
|
|
|
s_pPendingSolverWindow = nullptr;
|
|
|
|
|
}
|
|
|
|
|
if(m_pProgressDlg != nullptr) {
|
|
|
|
|
m_pProgressDlg->deleteLater();
|
|
|
|
|
m_pProgressDlg = nullptr;
|
|
|
|
|
m_pProgressDlg->hide();
|
|
|
|
|
}
|
|
|
|
|
m_pSolverDataManager = nullptr;
|
|
|
|
|
m_pSolverFitting = nullptr;
|
|
|
|
|
@ -1705,9 +1717,11 @@ void nmSubWndMain::startSolverTask()
|
|
|
|
|
true);
|
|
|
|
|
s_pRunningSolverTask = m_pSolverTask;
|
|
|
|
|
connect(m_pSolverTask, SIGNAL(sig_calculateDone(bool)),
|
|
|
|
|
this, SLOT(on_solverTaskFinished(bool)));
|
|
|
|
|
this, SLOT(on_solverTaskFinished(bool)),
|
|
|
|
|
Qt::QueuedConnection);
|
|
|
|
|
connect(m_pSolverTask, SIGNAL(sigStageChanged(QString,int,int)),
|
|
|
|
|
this, SLOT(onSolverStageChanged(QString,int,int)));
|
|
|
|
|
this, SLOT(onSolverStageChanged(QString,int,int)),
|
|
|
|
|
Qt::QueuedConnection);
|
|
|
|
|
// 给 Windows 一次完成首帧绘制的机会;后续每个事件循环只捕获一口井。
|
|
|
|
|
QTimer::singleShot(20, this, SLOT(continueSolverInputCapture()));
|
|
|
|
|
}
|
|
|
|
|
@ -1741,13 +1755,14 @@ void nmSubWndMain::continueSolverInputCapture()
|
|
|
|
|
pTask->deleteLater();
|
|
|
|
|
|
|
|
|
|
if(bCancelled) {
|
|
|
|
|
delete m_pProgressDlg;
|
|
|
|
|
m_pProgressDlg = nullptr;
|
|
|
|
|
if(m_pProgressDlg != nullptr) {
|
|
|
|
|
m_pProgressDlg->hide();
|
|
|
|
|
}
|
|
|
|
|
m_pSolverDataManager = nullptr;
|
|
|
|
|
m_pSolverFitting = nullptr;
|
|
|
|
|
} else {
|
|
|
|
|
on_calculationFinished(NM_Calculation_Result_Fail);
|
|
|
|
|
scheduleSolverResultCompletion(false, -1, -1);
|
|
|
|
|
}
|
|
|
|
|
m_pSolverDataManager = nullptr;
|
|
|
|
|
m_pSolverFitting = nullptr;
|
|
|
|
|
m_bSolverCancelRequested = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@ -1805,11 +1820,7 @@ void nmSubWndMain::onSolverCancelRequested()
|
|
|
|
|
disconnect(pTask, nullptr, this, nullptr);
|
|
|
|
|
pTask->deleteLater();
|
|
|
|
|
}
|
|
|
|
|
// canceled() 由进度框自身发出,延迟释放避免在信号调用栈内销毁发送者。
|
|
|
|
|
if(m_pProgressDlg != nullptr) {
|
|
|
|
|
m_pProgressDlg->deleteLater();
|
|
|
|
|
}
|
|
|
|
|
m_pProgressDlg = nullptr;
|
|
|
|
|
// QProgressDialog::cancel() 已隐藏窗口;保留对象供下一次求解复用。
|
|
|
|
|
m_pSolverDataManager = nullptr;
|
|
|
|
|
m_pSolverFitting = nullptr;
|
|
|
|
|
m_bSolverCancelRequested = false;
|
|
|
|
|
@ -1956,6 +1967,11 @@ void nmSubWndMain::mergeAnaResultToFitting()
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 新一轮主动刷新替代尚未执行的旧请求;已经投递的旧槽会检测标记并直接返回。
|
|
|
|
|
m_bPendingResultWidgetRefresh = false;
|
|
|
|
|
m_pPendingResultDataManager = nullptr;
|
|
|
|
|
m_pPendingResultFitting = nullptr;
|
|
|
|
|
|
|
|
|
|
QVector<nmSolverWellRef> vecWellsOrder = pInstance->getSolverWellOrder();
|
|
|
|
|
QString sCurrentResultWellCode = pInstance->getCurrentResultWellCode();
|
|
|
|
|
|
|
|
|
|
@ -2023,69 +2039,126 @@ void nmSubWndMain::mergeAnaResultToFitting()
|
|
|
|
|
QString errorMessage4;
|
|
|
|
|
pSubWndFit->adjustFitSubPlotBy(tag, vecHistory, true, &errorMessage4);
|
|
|
|
|
|
|
|
|
|
QWidget* widget1 = pSubWndFit->getFitSubRstWxOf(FSRT_Nm3D, true, &errorMessage);
|
|
|
|
|
if(widget1 == nullptr || pInstance->getGridType() != NM_Grid_PEBI) {
|
|
|
|
|
if(pInstance->getGridType() != NM_Grid_PEBI) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// getFitSubRstWxOf(..., true) 会同步创建 iWxResult、挂入 MDI 并切换当前页。
|
|
|
|
|
// 首次创建时只建立外层载体,待本轮 show/resize/layout 事件结束后再填充内容。
|
|
|
|
|
QWidget* p3DWidget = pSubWndFit->getFitSubRstWxOf(
|
|
|
|
|
FSRT_Nm3D, false, &errorMessage);
|
|
|
|
|
if(p3DWidget == nullptr) {
|
|
|
|
|
p3DWidget = pSubWndFit->getFitSubRstWxOf(
|
|
|
|
|
FSRT_Nm3D, true, &errorMessage);
|
|
|
|
|
if(p3DWidget == nullptr) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_pPendingResultDataManager = pInstance;
|
|
|
|
|
m_pPendingResultFitting = pSubWndFit;
|
|
|
|
|
m_bPendingResultWidgetRefresh = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
populateResultWidgets(pSubWndFit, pInstance);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndMain::populateResultWidgets(
|
|
|
|
|
iSubWndFitting* pSubWndFit,
|
|
|
|
|
nmDataAnalyzeManager* pDataManager)
|
|
|
|
|
{
|
|
|
|
|
if(pSubWndFit == nullptr || pDataManager == nullptr ||
|
|
|
|
|
pDataManager->getGridType() != NM_Grid_PEBI ||
|
|
|
|
|
nmDataAnalyzeManager::findManagerByFitting(pSubWndFit) != pDataManager) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString sErrorMessage;
|
|
|
|
|
QWidget* p3DWidget = pSubWndFit->getFitSubRstWxOf(
|
|
|
|
|
FSRT_Nm3D, true, &sErrorMessage);
|
|
|
|
|
if(p3DWidget == nullptr) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nmWxPostprocessingAnimationWidget* vtkWidget =
|
|
|
|
|
widget1->findChild<nmWxPostprocessingAnimationWidget*>();
|
|
|
|
|
if(vtkWidget != nullptr) {
|
|
|
|
|
nmWxPostprocessingAnimationWidget* pVtkWidget =
|
|
|
|
|
p3DWidget->findChild<nmWxPostprocessingAnimationWidget*>();
|
|
|
|
|
if(pVtkWidget != nullptr) {
|
|
|
|
|
// 复用既有渲染窗口和 VTK 管道,只切换本轮已整体提交的数据。
|
|
|
|
|
vtkWidget->refreshResult();
|
|
|
|
|
pVtkWidget->refreshResult();
|
|
|
|
|
} else {
|
|
|
|
|
vtkWidget = new nmWxPostprocessingAnimationWidget(NULL, pInstance);
|
|
|
|
|
QLayout* layout1 = widget1->layout();
|
|
|
|
|
if(layout1) {
|
|
|
|
|
QLayoutItem* item;
|
|
|
|
|
while((item = layout1->takeAt(0))) {
|
|
|
|
|
if(item->widget()) {
|
|
|
|
|
delete item->widget();
|
|
|
|
|
pVtkWidget = new nmWxPostprocessingAnimationWidget(NULL, pDataManager);
|
|
|
|
|
QLayout* p3DLayout = p3DWidget->layout();
|
|
|
|
|
if(p3DLayout == nullptr) {
|
|
|
|
|
p3DLayout = new QVBoxLayout(p3DWidget);
|
|
|
|
|
} else {
|
|
|
|
|
QLayoutItem* pItem = nullptr;
|
|
|
|
|
while((pItem = p3DLayout->takeAt(0)) != nullptr) {
|
|
|
|
|
if(pItem->widget() != nullptr) {
|
|
|
|
|
delete pItem->widget();
|
|
|
|
|
}
|
|
|
|
|
delete item;
|
|
|
|
|
delete pItem;
|
|
|
|
|
}
|
|
|
|
|
delete layout1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
widget1->setLayout(nullptr);
|
|
|
|
|
QVBoxLayout* newLayout1 = new QVBoxLayout(widget1);
|
|
|
|
|
newLayout1->addWidget(vtkWidget);
|
|
|
|
|
widget1->setLayout(newLayout1);
|
|
|
|
|
p3DLayout->addWidget(pVtkWidget);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 结果参数界面
|
|
|
|
|
QWidget* widget2 = pSubWndFit->getFitSubRstWxOf(FSRT_NmRst, true, &errorMessage);
|
|
|
|
|
if(widget2 == nullptr) {
|
|
|
|
|
QWidget* pResultPage = pSubWndFit->getFitSubRstWxOf(
|
|
|
|
|
FSRT_NmRst, true, &sErrorMessage);
|
|
|
|
|
if(pResultPage == nullptr) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nmWxParaPropertyPebi* resultWidget =
|
|
|
|
|
widget2->findChild<nmWxParaPropertyPebi*>();
|
|
|
|
|
if(resultWidget == nullptr) {
|
|
|
|
|
nmWxParaPropertyPebi* pResultWidget =
|
|
|
|
|
pResultPage->findChild<nmWxParaPropertyPebi*>();
|
|
|
|
|
if(pResultWidget == nullptr) {
|
|
|
|
|
// 与左侧共用属性面板类,结果区使用独立实例和只读参数列表。
|
|
|
|
|
resultWidget = new nmWxParaPropertyPebi;
|
|
|
|
|
resultWidget->initUI();
|
|
|
|
|
|
|
|
|
|
QLayout* layout2 = widget2->layout();
|
|
|
|
|
if(layout2) {
|
|
|
|
|
QLayoutItem* item;
|
|
|
|
|
while((item = layout2->takeAt(0))) {
|
|
|
|
|
if(item->widget()) {
|
|
|
|
|
delete item->widget();
|
|
|
|
|
pResultWidget = new nmWxParaPropertyPebi;
|
|
|
|
|
pResultWidget->initUI();
|
|
|
|
|
pResultWidget->setDataManager(pDataManager);
|
|
|
|
|
// 保持 8 月 24 日版本的稳定顺序:离屏完成参数构建后再加入可见布局。
|
|
|
|
|
pResultWidget->rebuildResultParas();
|
|
|
|
|
|
|
|
|
|
QLayout* pResultLayout = pResultPage->layout();
|
|
|
|
|
if(pResultLayout == nullptr) {
|
|
|
|
|
pResultLayout = new QVBoxLayout(pResultPage);
|
|
|
|
|
} else {
|
|
|
|
|
QLayoutItem* pItem = nullptr;
|
|
|
|
|
while((pItem = pResultLayout->takeAt(0)) != nullptr) {
|
|
|
|
|
if(pItem->widget() != nullptr) {
|
|
|
|
|
delete pItem->widget();
|
|
|
|
|
}
|
|
|
|
|
delete item;
|
|
|
|
|
delete pItem;
|
|
|
|
|
}
|
|
|
|
|
delete layout2;
|
|
|
|
|
}
|
|
|
|
|
widget2->setLayout(nullptr);
|
|
|
|
|
QVBoxLayout* newLayout2 = new QVBoxLayout(widget2);
|
|
|
|
|
newLayout2->addWidget(resultWidget);
|
|
|
|
|
widget2->setLayout(newLayout2);
|
|
|
|
|
pResultLayout->addWidget(pResultWidget);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resultWidget->setDataManager(pInstance);
|
|
|
|
|
resultWidget->rebuildResultParas();
|
|
|
|
|
pResultWidget->setDataManager(pDataManager);
|
|
|
|
|
pResultWidget->rebuildResultParas();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndMain::schedulePendingResultWidgets()
|
|
|
|
|
{
|
|
|
|
|
if(m_bPendingResultWidgetRefresh) {
|
|
|
|
|
QTimer::singleShot(0, this, SLOT(populatePendingResultWidgets()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndMain::populatePendingResultWidgets()
|
|
|
|
|
{
|
|
|
|
|
if(!m_bPendingResultWidgetRefresh) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
iSubWndFitting* pSubWndFit = m_pPendingResultFitting.data();
|
|
|
|
|
nmDataAnalyzeManager* pDataManager = m_pPendingResultDataManager.data();
|
|
|
|
|
m_bPendingResultWidgetRefresh = false;
|
|
|
|
|
m_pPendingResultDataManager = nullptr;
|
|
|
|
|
m_pPendingResultFitting = nullptr;
|
|
|
|
|
|
|
|
|
|
populateResultWidgets(pSubWndFit, pDataManager);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool nmSubWndMain::inithalfLog(QVector<QVector<double >> & vvecLogPreData, QVector<iCurveDesc>& vecDescs, bool isHistoryData)
|
|
|
|
|
@ -2302,24 +2375,72 @@ void nmSubWndMain::geoLayering()
|
|
|
|
|
|
|
|
|
|
void nmSubWndMain::on_calculationFinished(NM_Calculation_Result result)
|
|
|
|
|
{
|
|
|
|
|
// 结果提交成功后仍保留进度框,直到曲线和结果页刷新全部完成。
|
|
|
|
|
if (m_pProgressDlg) {
|
|
|
|
|
m_pProgressDlg->setLabelText(tr("Updating result views..."));
|
|
|
|
|
m_pProgressDlg->setRange(0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(result == NM_Calculation_Result_Success) {
|
|
|
|
|
this->mergeAnaResultToFitting();
|
|
|
|
|
} else {
|
|
|
|
|
// 如果失败,进度条其实没必要拉满了,直接提示错误
|
|
|
|
|
QMessageBox::warning(this, tr("solver error"), tr("solver failed!"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_pProgressDlg != nullptr) {
|
|
|
|
|
delete m_pProgressDlg;
|
|
|
|
|
m_pProgressDlg = nullptr;
|
|
|
|
|
void nmSubWndMain::scheduleSolverResultCompletion(
|
|
|
|
|
bool bSucceeded,
|
|
|
|
|
int nPebiCount,
|
|
|
|
|
int nSolveTimeMs)
|
|
|
|
|
{
|
|
|
|
|
s_pPendingSolverWindow = this;
|
|
|
|
|
m_bSolverResultCompletionPending = true;
|
|
|
|
|
m_bPendingSolverSucceeded = bSucceeded;
|
|
|
|
|
m_nPendingSolverPebiCount = nPebiCount;
|
|
|
|
|
m_nPendingSolverTimeMs = nSolveTimeMs;
|
|
|
|
|
|
|
|
|
|
// 当前完成信号栈只登记后续工作;隐藏和结果刷新各占一轮独立事件。
|
|
|
|
|
QTimer::singleShot(0, this, SLOT(dismissPendingSolverProgress()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndMain::dismissPendingSolverProgress()
|
|
|
|
|
{
|
|
|
|
|
if(m_pProgressDlg != nullptr) {
|
|
|
|
|
m_pProgressDlg->hide();
|
|
|
|
|
}
|
|
|
|
|
QTimer::singleShot(0, this, SLOT(completePendingSolverResult()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndMain::completePendingSolverResult()
|
|
|
|
|
{
|
|
|
|
|
if(!m_bSolverResultCompletionPending) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const bool bSucceeded = m_bPendingSolverSucceeded;
|
|
|
|
|
const int nPebiCount = m_nPendingSolverPebiCount;
|
|
|
|
|
const int nSolveTimeMs = m_nPendingSolverTimeMs;
|
|
|
|
|
m_bSolverResultCompletionPending = false;
|
|
|
|
|
m_bPendingSolverSucceeded = false;
|
|
|
|
|
m_nPendingSolverPebiCount = -1;
|
|
|
|
|
m_nPendingSolverTimeMs = -1;
|
|
|
|
|
|
|
|
|
|
on_calculationFinished(bSucceeded
|
|
|
|
|
? NM_Calculation_Result_Success
|
|
|
|
|
: NM_Calculation_Result_Fail);
|
|
|
|
|
|
|
|
|
|
// mergeAnaResultToFitting() 已使用完启动时捕获的上下文。
|
|
|
|
|
m_pSolverDataManager = nullptr;
|
|
|
|
|
m_pSolverFitting = nullptr;
|
|
|
|
|
m_bSolverCancelRequested = false;
|
|
|
|
|
|
|
|
|
|
if(bSucceeded && nPebiCount >= 0 && nSolveTimeMs >= 0) {
|
|
|
|
|
QMessageBox::information(this, tr("Solver completed"),
|
|
|
|
|
tr("Grid count: %1\nSolve time: %2 ms")
|
|
|
|
|
.arg(nPebiCount)
|
|
|
|
|
.arg(nSolveTimeMs));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 首次结果载体的填充必须在成功提示的模态事件循环完全退出后执行。
|
|
|
|
|
schedulePendingResultWidgets();
|
|
|
|
|
if(s_pPendingSolverWindow == this) {
|
|
|
|
|
s_pPendingSolverWindow = nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndMain::on_solverTaskFinished(bool isSuccessed)
|
|
|
|
|
@ -2353,25 +2474,16 @@ void nmSubWndMain::on_solverTaskFinished(bool isSuccessed)
|
|
|
|
|
|
|
|
|
|
// 第二步:停止不属于失败,也不允许触发结果提交或覆盖旧成果。
|
|
|
|
|
if(bCancelled) {
|
|
|
|
|
delete m_pProgressDlg;
|
|
|
|
|
m_pProgressDlg = nullptr;
|
|
|
|
|
if(m_pProgressDlg != nullptr) {
|
|
|
|
|
m_pProgressDlg->hide();
|
|
|
|
|
}
|
|
|
|
|
m_pSolverDataManager = nullptr;
|
|
|
|
|
m_pSolverFitting = nullptr;
|
|
|
|
|
m_bSolverCancelRequested = false;
|
|
|
|
|
} else {
|
|
|
|
|
NM_Calculation_Result result = isSuccessed
|
|
|
|
|
? NM_Calculation_Result_Success
|
|
|
|
|
: NM_Calculation_Result_Fail;
|
|
|
|
|
this->on_calculationFinished(result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 第三步:结果处理结束后释放非拥有型上下文引用。
|
|
|
|
|
m_pSolverDataManager = nullptr;
|
|
|
|
|
m_pSolverFitting = nullptr;
|
|
|
|
|
m_bSolverCancelRequested = false;
|
|
|
|
|
|
|
|
|
|
if(isSuccessed && nPebiCount >= 0 && nSolveTimeMs >= 0) {
|
|
|
|
|
QMessageBox::information(this, tr("Solver completed"),
|
|
|
|
|
tr("Grid count: %1\nSolve time: %2 ms")
|
|
|
|
|
.arg(nPebiCount)
|
|
|
|
|
.arg(nSolveTimeMs));
|
|
|
|
|
scheduleSolverResultCompletion(isSuccessed,
|
|
|
|
|
nPebiCount,
|
|
|
|
|
nSolveTimeMs);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|