|
|
|
|
@ -133,8 +133,13 @@ nmSubWndMain::nmSubWndMain(QWidget *parent, QString sExt) :
|
|
|
|
|
m_pPendingResultDataManager = nullptr;
|
|
|
|
|
m_pPendingResultFitting = nullptr;
|
|
|
|
|
m_bPendingResultWidgetRefresh = false;
|
|
|
|
|
m_bPendingResultCompletionMessage = false;
|
|
|
|
|
m_bPendingResultWindowReady = false;
|
|
|
|
|
m_nPendingResultPebiCount = -1;
|
|
|
|
|
m_nPendingResultSolveTimeMs = -1;
|
|
|
|
|
m_bSolverResultCompletionPending = false;
|
|
|
|
|
m_bPendingSolverSucceeded = false;
|
|
|
|
|
m_bPendingSolverInputChanged = false;
|
|
|
|
|
m_nPendingSolverPebiCount = -1;
|
|
|
|
|
m_nPendingSolverTimeMs = -1;
|
|
|
|
|
m_bSolverStartPending = false;
|
|
|
|
|
@ -1742,6 +1747,8 @@ void nmSubWndMain::continueSolverInputCapture()
|
|
|
|
|
if(!bSucceeded) {
|
|
|
|
|
nmCalculationDllPebiSolverTask* pTask = m_pSolverTask;
|
|
|
|
|
const bool bCancelled = pTask->wasCancelled();
|
|
|
|
|
const bool bInputChanged =
|
|
|
|
|
pTask->hasInputChanged(m_pSolverDataManager.data());
|
|
|
|
|
m_pSolverTask = nullptr;
|
|
|
|
|
if(pTask == s_pRunningSolverTask) {
|
|
|
|
|
s_pRunningSolverTask = nullptr;
|
|
|
|
|
@ -1761,7 +1768,7 @@ void nmSubWndMain::continueSolverInputCapture()
|
|
|
|
|
m_pSolverDataManager = nullptr;
|
|
|
|
|
m_pSolverFitting = nullptr;
|
|
|
|
|
} else {
|
|
|
|
|
scheduleSolverResultCompletion(false, -1, -1);
|
|
|
|
|
scheduleSolverResultCompletion(false, -1, -1, bInputChanged);
|
|
|
|
|
}
|
|
|
|
|
m_bSolverCancelRequested = false;
|
|
|
|
|
return;
|
|
|
|
|
@ -1923,7 +1930,7 @@ void nmSubWndMain::triggerToolBarAction(int index)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndMain::mergeAnaResultToFitting()
|
|
|
|
|
bool nmSubWndMain::mergeAnaResultToFitting()
|
|
|
|
|
{
|
|
|
|
|
//QMessageBox::information(this, tr("solver success"), tr("solver succeed!"));
|
|
|
|
|
|
|
|
|
|
@ -1938,14 +1945,14 @@ void nmSubWndMain::mergeAnaResultToFitting()
|
|
|
|
|
ZxMainWindow* pMainWnd1 = const_cast<ZxMainWindow*>(m_pMainWindow);
|
|
|
|
|
|
|
|
|
|
if(nullptr == pMainWnd1) {
|
|
|
|
|
return;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
iSubWndFitting* pSubWndFit = !m_pSolverFitting.isNull()
|
|
|
|
|
? m_pSolverFitting.data() : nmDataAnalyzeManager::getCurrentFitting();
|
|
|
|
|
Q_ASSERT(pSubWndFit != nullptr);
|
|
|
|
|
if(pSubWndFit == nullptr) {
|
|
|
|
|
return;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 历史压力数据
|
|
|
|
|
@ -1959,18 +1966,22 @@ void nmSubWndMain::mergeAnaResultToFitting()
|
|
|
|
|
? m_pSolverDataManager.data()
|
|
|
|
|
: nmDataAnalyzeManager::getCurrentInstance();
|
|
|
|
|
if(pInstance == nullptr) {
|
|
|
|
|
return;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 捕获的拟合窗口和数据管理器必须仍保持原来的映射关系。
|
|
|
|
|
if(nmDataAnalyzeManager::findManagerByFitting(pSubWndFit) != pInstance) {
|
|
|
|
|
return;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 新一轮主动刷新替代尚未执行的旧请求;已经投递的旧槽会检测标记并直接返回。
|
|
|
|
|
m_bPendingResultWidgetRefresh = false;
|
|
|
|
|
m_pPendingResultDataManager = nullptr;
|
|
|
|
|
m_pPendingResultFitting = nullptr;
|
|
|
|
|
m_bPendingResultCompletionMessage = false;
|
|
|
|
|
m_bPendingResultWindowReady = false;
|
|
|
|
|
m_nPendingResultPebiCount = -1;
|
|
|
|
|
m_nPendingResultSolveTimeMs = -1;
|
|
|
|
|
|
|
|
|
|
QVector<nmSolverWellRef> vecWellsOrder = pInstance->getSolverWellOrder();
|
|
|
|
|
QString sCurrentResultWellCode = pInstance->getCurrentResultWellCode();
|
|
|
|
|
@ -2006,7 +2017,7 @@ void nmSubWndMain::mergeAnaResultToFitting()
|
|
|
|
|
if(pInstance->getGridType() == NM_Grid_PEBI) {
|
|
|
|
|
pWellData = pInstance->findWellByCode(sCurrentResultWellCode);
|
|
|
|
|
if(pWellData == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
pInstance->setCurrentResultWellCode(sCurrentResultWellCode);
|
|
|
|
|
// 获取该井下存储的三条数据
|
|
|
|
|
@ -2040,7 +2051,7 @@ void nmSubWndMain::mergeAnaResultToFitting()
|
|
|
|
|
pSubWndFit->adjustFitSubPlotBy(tag, vecHistory, true, &errorMessage4);
|
|
|
|
|
|
|
|
|
|
if(pInstance->getGridType() != NM_Grid_PEBI) {
|
|
|
|
|
return;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// getFitSubRstWxOf(..., true) 会同步创建 iWxResult、挂入 MDI 并切换当前页。
|
|
|
|
|
@ -2051,33 +2062,33 @@ void nmSubWndMain::mergeAnaResultToFitting()
|
|
|
|
|
p3DWidget = pSubWndFit->getFitSubRstWxOf(
|
|
|
|
|
FSRT_Nm3D, true, &errorMessage);
|
|
|
|
|
if(p3DWidget == nullptr) {
|
|
|
|
|
return;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_pPendingResultDataManager = pInstance;
|
|
|
|
|
m_pPendingResultFitting = pSubWndFit;
|
|
|
|
|
m_bPendingResultWidgetRefresh = true;
|
|
|
|
|
return;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
populateResultWidgets(pSubWndFit, pInstance);
|
|
|
|
|
return populateResultWidgets(pSubWndFit, pInstance);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndMain::populateResultWidgets(
|
|
|
|
|
bool nmSubWndMain::populateResultWidgets(
|
|
|
|
|
iSubWndFitting* pSubWndFit,
|
|
|
|
|
nmDataAnalyzeManager* pDataManager)
|
|
|
|
|
{
|
|
|
|
|
if(pSubWndFit == nullptr || pDataManager == nullptr ||
|
|
|
|
|
pDataManager->getGridType() != NM_Grid_PEBI ||
|
|
|
|
|
nmDataAnalyzeManager::findManagerByFitting(pSubWndFit) != pDataManager) {
|
|
|
|
|
return;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString sErrorMessage;
|
|
|
|
|
QWidget* p3DWidget = pSubWndFit->getFitSubRstWxOf(
|
|
|
|
|
FSRT_Nm3D, true, &sErrorMessage);
|
|
|
|
|
if(p3DWidget == nullptr) {
|
|
|
|
|
return;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nmWxPostprocessingAnimationWidget* pVtkWidget =
|
|
|
|
|
@ -2106,7 +2117,7 @@ void nmSubWndMain::populateResultWidgets(
|
|
|
|
|
QWidget* pResultPage = pSubWndFit->getFitSubRstWxOf(
|
|
|
|
|
FSRT_NmRst, true, &sErrorMessage);
|
|
|
|
|
if(pResultPage == nullptr) {
|
|
|
|
|
return;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nmWxParaPropertyPebi* pResultWidget =
|
|
|
|
|
@ -2132,11 +2143,12 @@ void nmSubWndMain::populateResultWidgets(
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
pResultLayout->addWidget(pResultWidget);
|
|
|
|
|
return;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pResultWidget->setDataManager(pDataManager);
|
|
|
|
|
pResultWidget->rebuildResultParas();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndMain::schedulePendingResultWidgets()
|
|
|
|
|
@ -2158,7 +2170,33 @@ void nmSubWndMain::populatePendingResultWidgets()
|
|
|
|
|
m_pPendingResultDataManager = nullptr;
|
|
|
|
|
m_pPendingResultFitting = nullptr;
|
|
|
|
|
|
|
|
|
|
populateResultWidgets(pSubWndFit, pDataManager);
|
|
|
|
|
const bool bResultWindowReady =
|
|
|
|
|
populateResultWidgets(pSubWndFit, pDataManager);
|
|
|
|
|
if(m_bPendingResultCompletionMessage) {
|
|
|
|
|
m_bPendingResultWindowReady = bResultWindowReady;
|
|
|
|
|
QTimer::singleShot(
|
|
|
|
|
0,
|
|
|
|
|
this,
|
|
|
|
|
SLOT(showPendingSolverResultCompletion()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndMain::showPendingSolverResultCompletion()
|
|
|
|
|
{
|
|
|
|
|
if(!m_bPendingResultCompletionMessage) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const bool bResultWindowReady = m_bPendingResultWindowReady;
|
|
|
|
|
const int nPebiCount = m_nPendingResultPebiCount;
|
|
|
|
|
const int nSolveTimeMs = m_nPendingResultSolveTimeMs;
|
|
|
|
|
m_bPendingResultCompletionMessage = false;
|
|
|
|
|
m_bPendingResultWindowReady = false;
|
|
|
|
|
m_nPendingResultPebiCount = -1;
|
|
|
|
|
m_nPendingResultSolveTimeMs = -1;
|
|
|
|
|
showSolverResultCompletion(bResultWindowReady,
|
|
|
|
|
nPebiCount,
|
|
|
|
|
nSolveTimeMs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool nmSubWndMain::inithalfLog(QVector<QVector<double >> & vvecLogPreData, QVector<iCurveDesc>& vecDescs, bool isHistoryData)
|
|
|
|
|
@ -2373,24 +2411,27 @@ void nmSubWndMain::geoLayering()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndMain::on_calculationFinished(NM_Calculation_Result result)
|
|
|
|
|
bool nmSubWndMain::on_calculationFinished(NM_Calculation_Result result)
|
|
|
|
|
{
|
|
|
|
|
if(result == NM_Calculation_Result_Success) {
|
|
|
|
|
this->mergeAnaResultToFitting();
|
|
|
|
|
return this->mergeAnaResultToFitting();
|
|
|
|
|
} else {
|
|
|
|
|
// 如果失败,进度条其实没必要拉满了,直接提示错误
|
|
|
|
|
QMessageBox::warning(this, tr("solver error"), tr("solver failed!"));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndMain::scheduleSolverResultCompletion(
|
|
|
|
|
bool bSucceeded,
|
|
|
|
|
int nPebiCount,
|
|
|
|
|
int nSolveTimeMs)
|
|
|
|
|
int nSolveTimeMs,
|
|
|
|
|
bool bInputChanged)
|
|
|
|
|
{
|
|
|
|
|
s_pPendingSolverWindow = this;
|
|
|
|
|
m_bSolverResultCompletionPending = true;
|
|
|
|
|
m_bPendingSolverSucceeded = bSucceeded;
|
|
|
|
|
m_bPendingSolverInputChanged = bInputChanged;
|
|
|
|
|
m_nPendingSolverPebiCount = nPebiCount;
|
|
|
|
|
m_nPendingSolverTimeMs = nSolveTimeMs;
|
|
|
|
|
|
|
|
|
|
@ -2413,36 +2454,71 @@ void nmSubWndMain::completePendingSolverResult()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const bool bSucceeded = m_bPendingSolverSucceeded;
|
|
|
|
|
const bool bInputChanged = m_bPendingSolverInputChanged;
|
|
|
|
|
const int nPebiCount = m_nPendingSolverPebiCount;
|
|
|
|
|
const int nSolveTimeMs = m_nPendingSolverTimeMs;
|
|
|
|
|
m_bSolverResultCompletionPending = false;
|
|
|
|
|
m_bPendingSolverSucceeded = false;
|
|
|
|
|
m_bPendingSolverInputChanged = false;
|
|
|
|
|
m_nPendingSolverPebiCount = -1;
|
|
|
|
|
m_nPendingSolverTimeMs = -1;
|
|
|
|
|
|
|
|
|
|
on_calculationFinished(bSucceeded
|
|
|
|
|
? NM_Calculation_Result_Success
|
|
|
|
|
: NM_Calculation_Result_Fail);
|
|
|
|
|
bool bResultWindowReady = false;
|
|
|
|
|
if(bInputChanged) {
|
|
|
|
|
QMessageBox::warning(
|
|
|
|
|
this,
|
|
|
|
|
tr("Solver result discarded"),
|
|
|
|
|
tr("The input changed while the solver was preparing or running. "
|
|
|
|
|
"The outdated result was discarded."));
|
|
|
|
|
} else {
|
|
|
|
|
bResultWindowReady = 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));
|
|
|
|
|
if(bSucceeded && bResultWindowReady &&
|
|
|
|
|
m_bPendingResultWidgetRefresh) {
|
|
|
|
|
// 首次结果页尚未填充,最终提示必须等页面真实创建结果返回后再显示。
|
|
|
|
|
m_bPendingResultCompletionMessage = true;
|
|
|
|
|
m_nPendingResultPebiCount = nPebiCount;
|
|
|
|
|
m_nPendingResultSolveTimeMs = nSolveTimeMs;
|
|
|
|
|
} else if(bSucceeded) {
|
|
|
|
|
showSolverResultCompletion(bResultWindowReady,
|
|
|
|
|
nPebiCount,
|
|
|
|
|
nSolveTimeMs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 首次结果载体的填充必须在成功提示的模态事件循环完全退出后执行。
|
|
|
|
|
// 首次结果载体创建后再跨一个事件循环填充,避免 Qt 4.8 布局重入。
|
|
|
|
|
schedulePendingResultWidgets();
|
|
|
|
|
if(s_pPendingSolverWindow == this) {
|
|
|
|
|
s_pPendingSolverWindow = nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndMain::showSolverResultCompletion(
|
|
|
|
|
bool bResultWindowReady,
|
|
|
|
|
int nPebiCount,
|
|
|
|
|
int nSolveTimeMs)
|
|
|
|
|
{
|
|
|
|
|
if(bResultWindowReady && nPebiCount >= 0 && nSolveTimeMs >= 0) {
|
|
|
|
|
QMessageBox::information(this, tr("Solver completed"),
|
|
|
|
|
tr("Grid count: %1\nSolve time: %2 ms")
|
|
|
|
|
.arg(nPebiCount)
|
|
|
|
|
.arg(nSolveTimeMs));
|
|
|
|
|
} else if(!bResultWindowReady) {
|
|
|
|
|
QMessageBox::warning(
|
|
|
|
|
this,
|
|
|
|
|
tr("Result display error"),
|
|
|
|
|
tr("Solver completed and the results were committed, but the "
|
|
|
|
|
"result window could not be opened."));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndMain::on_solverTaskFinished(bool isSuccessed)
|
|
|
|
|
{
|
|
|
|
|
// 第一步:只接受当前窗口实际启动的任务,忽略已经失效的旧回调。
|
|
|
|
|
@ -2454,14 +2530,18 @@ void nmSubWndMain::on_solverTaskFinished(bool isSuccessed)
|
|
|
|
|
int nPebiCount = pTask != nullptr ? pTask->getPebiCount() : -1;
|
|
|
|
|
int nSolveTimeMs = pTask != nullptr ? pTask->getSolveTimeMs() : -1;
|
|
|
|
|
const bool bCancelled = pTask->wasCancelled();
|
|
|
|
|
bool bInputChanged = false;
|
|
|
|
|
// 后台线程只生成局部结果快照。回到主线程后先验证所属 DataManager 和
|
|
|
|
|
// 输入版本,再整体替换旧成果;提交失败与求解失败使用同一条错误路径。
|
|
|
|
|
// 输入版本,再整体替换旧成果;输入变化与真正的求解失败分别提示。
|
|
|
|
|
if(isSuccessed && !bCancelled) {
|
|
|
|
|
if(m_pProgressDlg != nullptr) {
|
|
|
|
|
m_pProgressDlg->setLabelText(tr("Committing results..."));
|
|
|
|
|
m_pProgressDlg->setRange(0, 0);
|
|
|
|
|
}
|
|
|
|
|
bInputChanged =
|
|
|
|
|
pTask->hasInputChanged(m_pSolverDataManager.data());
|
|
|
|
|
isSuccessed = pTask->commitResult(m_pSolverDataManager.data());
|
|
|
|
|
bInputChanged = !isSuccessed && bInputChanged;
|
|
|
|
|
} else if(bCancelled) {
|
|
|
|
|
isSuccessed = false;
|
|
|
|
|
}
|
|
|
|
|
@ -2483,7 +2563,8 @@ void nmSubWndMain::on_solverTaskFinished(bool isSuccessed)
|
|
|
|
|
} else {
|
|
|
|
|
scheduleSolverResultCompletion(isSuccessed,
|
|
|
|
|
nPebiCount,
|
|
|
|
|
nSolveTimeMs);
|
|
|
|
|
nSolveTimeMs,
|
|
|
|
|
bInputChanged);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|