|
|
|
|
@ -65,6 +65,7 @@
|
|
|
|
|
|
|
|
|
|
#include "iSubWndFitting.h"
|
|
|
|
|
#include "iGuiPlotPF.h"
|
|
|
|
|
#include "iGuiPlotTableHelper.h"
|
|
|
|
|
#include "iGuiPlot.h"
|
|
|
|
|
#include "ZxObjCurveFlow.h"
|
|
|
|
|
#include "iAnalRun.h"
|
|
|
|
|
@ -1873,6 +1874,7 @@ void nmSubWndMain::onShowSensitiveResults()
|
|
|
|
|
nmDataAnalyzeManager* manager = m_pResultRefreshDataManager.data();
|
|
|
|
|
iSubWndFitting* fitting = m_pResultRefreshFitting.data();
|
|
|
|
|
if(!manager || !fitting || !manager->getSensitiveData()) return;
|
|
|
|
|
updateSensitiveHistoryPlot();
|
|
|
|
|
QSharedPointer<nmDataSensitive::BatchResult> result = manager->getSensitiveData()->getResults();
|
|
|
|
|
iGuiPlot* plot = fitting->getPlotByTag(s_Tag_ChartSensitivity);
|
|
|
|
|
if(result.isNull()) {
|
|
|
|
|
@ -1987,6 +1989,106 @@ void nmSubWndMain::onShowSensitiveResults()
|
|
|
|
|
if(sender() == manager) fitting->setModified(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndMain::updateSensitiveHistoryPlot()
|
|
|
|
|
{
|
|
|
|
|
// 复用框架的上下压力/流量控件,作为同一分析页面中的独立 MDI 子窗口。
|
|
|
|
|
iSubWndFitting* fitting = m_pResultRefreshFitting.data();
|
|
|
|
|
nmDataAnalyzeManager* manager = m_pResultRefreshDataManager.data();
|
|
|
|
|
if(!fitting || !fitting->m_pMdiArea || !manager || !manager->getSensitiveData()) return;
|
|
|
|
|
ZxMdiArea* area = fitting->m_pMdiArea;
|
|
|
|
|
QMdiSubWindow* window = area->findChild<QMdiSubWindow*>("nmSensitivityHistory");
|
|
|
|
|
const QSharedPointer<nmDataSensitive::BatchResult> batch = manager->getSensitiveData()->getResults();
|
|
|
|
|
if(batch.isNull()) {
|
|
|
|
|
// 新模型丢弃旧批次时一并销毁窗口,曲线和撤销记录不再残留。
|
|
|
|
|
if(window) {
|
|
|
|
|
area->removeSubWindow(window);
|
|
|
|
|
delete window;
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const bool created = window == nullptr;
|
|
|
|
|
if(created) {
|
|
|
|
|
// PF 继承对话框,用普通页面承载,关闭子窗口时不进入其对话框关闭流程。
|
|
|
|
|
QWidget* page = new QWidget;
|
|
|
|
|
QVBoxLayout* layout = new QVBoxLayout(page);
|
|
|
|
|
layout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
iGuiPlotPF* history = new iGuiPlotPF(s_Tag_HIST_PF, true, true, page);
|
|
|
|
|
history->setWindowFlags(Qt::Widget);
|
|
|
|
|
history->initUI(tr("Sensitivity history plot"));
|
|
|
|
|
history->setTableHelperVisible(false);
|
|
|
|
|
layout->addWidget(history);
|
|
|
|
|
window = area->addSubWindow(page);
|
|
|
|
|
window->setObjectName("nmSensitivityHistory");
|
|
|
|
|
window->setWindowTitle(tr("Sensitivity history plot"));
|
|
|
|
|
window->setAttribute(Qt::WA_DeleteOnClose, false);
|
|
|
|
|
}
|
|
|
|
|
iGuiPlotPF* history = window->findChild<iGuiPlotPF*>();
|
|
|
|
|
QVector<iCurveDesc> curves;
|
|
|
|
|
// 基准压力、实测压力和流量均取成功求解快照,未求解的参数或制度编辑不参与绘图。
|
|
|
|
|
const QSharedPointer<const nmPebiResultSnapshot> snapshot = manager->getPebiResultSnapshot();
|
|
|
|
|
for(int i = 0; !snapshot.isNull() && i < snapshot->getWellCount(); ++i) {
|
|
|
|
|
const nmPebiResultWellSnapshot* well = snapshot->getWellAt(i);
|
|
|
|
|
if(well->m_sWellCode != batch->m_sWellCode) continue;
|
|
|
|
|
QVector<QVector<double> > measured = well->m_oCurves.m_vecHistoryPressure;
|
|
|
|
|
QVector<QVector<double> > base = well->m_oCurves.m_vecResultPressure;
|
|
|
|
|
if(measured.size() == 2) initPreHistory(measured, curves, true);
|
|
|
|
|
if(base.size() == 2) {
|
|
|
|
|
initPreHistory(base, curves, false);
|
|
|
|
|
curves.last().m_sCurveName = nmWxSensitive::tr("Base model - Pressure");
|
|
|
|
|
}
|
|
|
|
|
const QVector<double>* rates = resultReferenceRatesOf(well);
|
|
|
|
|
if(rates && rates->size() == well->m_vecFlowDurations.size()) {
|
|
|
|
|
iCurveDesc flow;
|
|
|
|
|
flow.m_oCurveType = POT_CurveFlow;
|
|
|
|
|
flow.m_sCurveName = s_HistorySouce_CurveF;
|
|
|
|
|
flow.m_bLineVisible = true;
|
|
|
|
|
flow.m_bPointVisible = false;
|
|
|
|
|
flow.m_oPen.setColor(Qt::red);
|
|
|
|
|
// 与普通历史图一致,流量使用段时长并保留框架的首行占位点。
|
|
|
|
|
flow.m_vecX = well->m_vecFlowDurations;
|
|
|
|
|
flow.m_vecY = *rates;
|
|
|
|
|
flow.m_vecX.prepend(0.0);
|
|
|
|
|
flow.m_vecY.prepend(0.0);
|
|
|
|
|
curves.append(flow);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
for(size_t i = 0; i < batch->m_runs.size(); ++i) {
|
|
|
|
|
const nmDataSensitive::RunResult& run = batch->m_runs[i];
|
|
|
|
|
if(!run.m_bSucceeded || run.m_bCancelled || !run.m_bVisible || run.m_vecPressure.size() != 2) continue;
|
|
|
|
|
QVector<QVector<double> > pressure = run.m_vecPressure;
|
|
|
|
|
initPreHistory(pressure, curves, false);
|
|
|
|
|
curves.last().m_sCurveName = nmWxSensitive::tr("Run %1 - Pressure").arg(run.m_nRunIndex + 1);
|
|
|
|
|
curves.last().m_oPen.setColor(QColor::fromHsv(int((run.m_nRunIndex % 360) * 137 % 360), 190, 190));
|
|
|
|
|
}
|
|
|
|
|
// 框架不会删除本次未传入的曲线,刷新前清除旧图元,保证 Results 勾选同步生效。
|
|
|
|
|
iGuiPlot* plots[] = {history->m_pWxPlotP, history->m_pWxPlotF};
|
|
|
|
|
for(int i = 0; i < 2; ++i) {
|
|
|
|
|
iGuiPlot* plot = plots[i];
|
|
|
|
|
for(int j = plot->m_pPlot->getObjCount() - 1; j >= 0; --j)
|
|
|
|
|
if(qobject_cast<ZxObjCurve*>(plot->m_pPlot->getObjByIndex(j))) plot->m_pPlot->removeObjByIndex(j);
|
|
|
|
|
plot->clearUndoStack();
|
|
|
|
|
plot->setDropEnabled(false);
|
|
|
|
|
plot->setAxisXYLog(false, 0);
|
|
|
|
|
plot->setAxisXYLog(false, 1);
|
|
|
|
|
// PF 的统一分配面向普通历史曲线;多组结果直接交给对应的上下绘图控件。
|
|
|
|
|
QVector<iCurveDesc> data;
|
|
|
|
|
for(int j = 0; j < curves.size(); ++j)
|
|
|
|
|
if((curves[j].m_oCurveType == POT_CurveFlow) == (i == 1)) data.append(curves[j]);
|
|
|
|
|
plot->setCurveData(data);
|
|
|
|
|
plot->runUpdate();
|
|
|
|
|
plot->setReadOnly(true);
|
|
|
|
|
plot->freshAxisScales(true, true);
|
|
|
|
|
}
|
|
|
|
|
const bool restore = window->isHidden();
|
|
|
|
|
history->show();
|
|
|
|
|
window->widget()->show();
|
|
|
|
|
window->show();
|
|
|
|
|
// 历史图只显示曲线,隐藏框架默认的空数据表侧栏。
|
|
|
|
|
history->m_pTableHelper->hide();
|
|
|
|
|
if(created || restore) area->relayoutSubWnds();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndMain::startSolverTask()
|
|
|
|
|
{
|
|
|
|
|
if(!m_bSolverStartPending) {
|
|
|
|
|
|