|
|
#include "nmWxWellboreStorageCalculator.h"
|
|
|
|
|
|
#include <QStackedWidget>
|
|
|
#include <QRadioButton>
|
|
|
#include <QButtonGroup>
|
|
|
#include <QLabel>
|
|
|
#include <QLineEdit>
|
|
|
#include <QPushButton>
|
|
|
#include <QComboBox>
|
|
|
#include <QVBoxLayout>
|
|
|
#include <QGridLayout>
|
|
|
#include <QGroupBox>
|
|
|
#include <QCoreApplication>
|
|
|
|
|
|
#include "nmWxWellboreStorageCalculatorVolume.h"
|
|
|
#include "nmWxWellboreStorageCalculatorTubingData.h"
|
|
|
|
|
|
nmWxWellboreStorageCalculator::nmWxWellboreStorageCalculator(QWidget *parent) : QDialog(parent)
|
|
|
{
|
|
|
this->initUI();
|
|
|
this->initConnections();
|
|
|
|
|
|
// 默认选中第一个模式
|
|
|
m_pModeButtonGroup->button(0)->setChecked(true);
|
|
|
m_pStackedWidget->setCurrentIndex(0);
|
|
|
|
|
|
// 默认计算第一种模式
|
|
|
calculateWellboreStorage(0);
|
|
|
|
|
|
m_pTestedVolumeDialog = nullptr;
|
|
|
m_pTubingDataDialog = nullptr;
|
|
|
}
|
|
|
|
|
|
nmWxWellboreStorageCalculator::~nmWxWellboreStorageCalculator()
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
void nmWxWellboreStorageCalculator::initUI()
|
|
|
{
|
|
|
setWindowTitle(tr("Wellbore Storage Calculator"));
|
|
|
// 设置一个稍大的固定窗口尺寸,以容纳所有组件并保持对齐
|
|
|
setFixedSize(500, 320);
|
|
|
|
|
|
// 1. 创建模式选择的单选按钮和分组
|
|
|
m_pClosedChamberRadio = new QRadioButton(tr("Closed chamber"));
|
|
|
m_pChangingLiquidLevelRadio = new QRadioButton(tr("Changing liquid level"));
|
|
|
m_pModeButtonGroup = new QButtonGroup(this);
|
|
|
m_pModeButtonGroup->addButton(m_pClosedChamberRadio, 0);
|
|
|
m_pModeButtonGroup->addButton(m_pChangingLiquidLevelRadio, 1);
|
|
|
|
|
|
m_pModeGroupBox = new QGroupBox(tr("Calculation Mode"));
|
|
|
QVBoxLayout* modeLayout = new QVBoxLayout;
|
|
|
modeLayout->addWidget(m_pClosedChamberRadio);
|
|
|
modeLayout->addWidget(m_pChangingLiquidLevelRadio);
|
|
|
m_pModeGroupBox->setLayout(modeLayout);
|
|
|
|
|
|
// 2. 创建用于切换页面的 QStackedWidget 和两个页面
|
|
|
m_pStackedWidget = new QStackedWidget(this);
|
|
|
m_pClosedChamberPage = new QWidget;
|
|
|
m_pChangingLiquidLevelPage = new QWidget;
|
|
|
|
|
|
// 3. 为密闭井筒页面布局
|
|
|
m_pTestedVolumeLabel = new QLabel(tr("Tested volume:"));
|
|
|
m_pTestedVolumeEdit = new QLineEdit;
|
|
|
m_pTestedVolumeUnitCombo = new QComboBox;
|
|
|
m_pTestedVolumeEdit->setValidator(new QDoubleValidator(this));
|
|
|
// 设置默认值和单位
|
|
|
m_pTestedVolumeEdit->setText("0.317975");
|
|
|
m_pTestedVolumeUnitCombo->addItem(tr("m^3"));
|
|
|
//m_pTestedVolumeUnitCombo->addItem(tr("ft^3"));
|
|
|
//m_pTestedVolumeUnitCombo->addItem(tr("bbl"));
|
|
|
|
|
|
// 创建密闭井筒模式下的计算按钮
|
|
|
m_pClosedChamberCalculateButton = new QPushButton();
|
|
|
|
|
|
QString sIconDir = QCoreApplication::applicationDirPath();
|
|
|
sIconDir = sIconDir.section('/', 0, -2); // 获取上一级目录
|
|
|
sIconDir += "/Res/Icon/";
|
|
|
|
|
|
m_pClosedChamberCalculateButton->setIcon(QIcon(sIconDir + "NmWellboreStorageCalculator.png"));
|
|
|
m_pClosedChamberCalculateButton->setIconSize(QSize(32, 32));
|
|
|
m_pClosedChamberCalculateButton->setFixedSize(34, 34);
|
|
|
|
|
|
m_pFluidCompressibilityLabel = new QLabel(tr("Fluid compressibility:"));
|
|
|
m_pFluidCompressibilityEdit = new QLineEdit;
|
|
|
m_pFluidCompressibilityUnitCombo = new QComboBox;
|
|
|
m_pFluidCompressibilityEdit->setValidator(new QDoubleValidator(this));
|
|
|
// 设置默认值和单位
|
|
|
m_pFluidCompressibilityEdit->setText("0.725189");
|
|
|
m_pFluidCompressibilityUnitCombo->addItem(tr("1/Mpa"));
|
|
|
//m_pFluidCompressibilityUnitCombo->addItem(tr("1/psi"));
|
|
|
|
|
|
m_pClosedChamberLayout = new QGridLayout;
|
|
|
// 为列设置拉伸因子以保持对齐和宽度一致
|
|
|
m_pClosedChamberLayout->setColumnStretch(0, 1); // Label列
|
|
|
m_pClosedChamberLayout->setColumnStretch(1, 2); // LineEdit列
|
|
|
m_pClosedChamberLayout->setColumnStretch(2, 1); // ComboBox列
|
|
|
m_pClosedChamberLayout->setColumnStretch(3, 1); // Button列
|
|
|
|
|
|
m_pClosedChamberLayout->addWidget(m_pTestedVolumeLabel, 0, 0);
|
|
|
m_pClosedChamberLayout->addWidget(m_pTestedVolumeEdit, 0, 1);
|
|
|
m_pClosedChamberLayout->addWidget(m_pTestedVolumeUnitCombo, 0, 2);
|
|
|
// 将计算按钮添加到第一行第三列
|
|
|
m_pClosedChamberLayout->addWidget(m_pClosedChamberCalculateButton, 0, 3, Qt::AlignRight);
|
|
|
|
|
|
m_pClosedChamberLayout->addWidget(m_pFluidCompressibilityLabel, 1, 0);
|
|
|
m_pClosedChamberLayout->addWidget(m_pFluidCompressibilityEdit, 1, 1);
|
|
|
m_pClosedChamberLayout->addWidget(m_pFluidCompressibilityUnitCombo, 1, 2);
|
|
|
m_pClosedChamberPage->setLayout(m_pClosedChamberLayout);
|
|
|
|
|
|
// 4. 为液面变化页面布局
|
|
|
m_pTubingIdLabel = new QLabel(tr("Tubing I.D.:"));
|
|
|
m_pTubingIdEdit = new QLineEdit;
|
|
|
m_pTubingIdUnitCombo = new QComboBox;
|
|
|
m_pTubingIdEdit->setValidator(new QDoubleValidator(this));
|
|
|
// 设置默认值和单位
|
|
|
m_pTubingIdEdit->setText("0.09144");
|
|
|
m_pTubingIdUnitCombo->addItem(tr("m"));
|
|
|
//m_pTubingIdUnitCombo->addItem(tr("ft"));
|
|
|
//m_pTubingIdUnitCombo->addItem(tr("in"));
|
|
|
|
|
|
// 创建液面变化模式下的计算按钮
|
|
|
m_pChangingLiquidLevelCalculateButton = new QPushButton();
|
|
|
|
|
|
m_pChangingLiquidLevelCalculateButton->setIcon(QIcon(sIconDir + "NmWellboreStorageCalculator.png"));
|
|
|
m_pChangingLiquidLevelCalculateButton->setIconSize(QSize(32, 32));
|
|
|
m_pChangingLiquidLevelCalculateButton->setFixedSize(34, 34);
|
|
|
|
|
|
m_pFluidDensityLabel = new QLabel(tr("Fluid density:"));
|
|
|
m_pFluidDensityEdit = new QLineEdit;
|
|
|
m_pFluidDensityUnitCombo = new QComboBox;
|
|
|
m_pFluidDensityEdit->setValidator(new QDoubleValidator(this));
|
|
|
// 设置默认值和单位
|
|
|
m_pFluidDensityEdit->setText("1000.00");
|
|
|
m_pFluidDensityUnitCombo->addItem(tr("kg/m^3"));
|
|
|
//m_pFluidDensityUnitCombo->addItem(tr("lb/ft^3"));
|
|
|
//m_pFluidDensityUnitCombo->addItem(tr("lb/bbl"));
|
|
|
|
|
|
m_pChangingLiquidLevelLayout = new QGridLayout;
|
|
|
// 为列设置拉伸因子以保持对齐和宽度一致
|
|
|
m_pChangingLiquidLevelLayout->setColumnStretch(0, 1); // Label列
|
|
|
m_pChangingLiquidLevelLayout->setColumnStretch(1, 2); // LineEdit列
|
|
|
m_pChangingLiquidLevelLayout->setColumnStretch(2, 1); // ComboBox列
|
|
|
m_pChangingLiquidLevelLayout->setColumnStretch(3, 1); // Button列
|
|
|
|
|
|
m_pChangingLiquidLevelLayout->addWidget(m_pTubingIdLabel, 0, 0);
|
|
|
m_pChangingLiquidLevelLayout->addWidget(m_pTubingIdEdit, 0, 1);
|
|
|
m_pChangingLiquidLevelLayout->addWidget(m_pTubingIdUnitCombo, 0, 2);
|
|
|
// 将计算按钮添加到第一行第三列
|
|
|
m_pChangingLiquidLevelLayout->addWidget(m_pChangingLiquidLevelCalculateButton, 0, 3, Qt::AlignRight);
|
|
|
|
|
|
m_pChangingLiquidLevelLayout->addWidget(m_pFluidDensityLabel, 1, 0);
|
|
|
m_pChangingLiquidLevelLayout->addWidget(m_pFluidDensityEdit, 1, 1);
|
|
|
m_pChangingLiquidLevelLayout->addWidget(m_pFluidDensityUnitCombo, 1, 2);
|
|
|
m_pChangingLiquidLevelPage->setLayout(m_pChangingLiquidLevelLayout);
|
|
|
|
|
|
m_pStackedWidget->addWidget(m_pClosedChamberPage);
|
|
|
m_pStackedWidget->addWidget(m_pChangingLiquidLevelPage);
|
|
|
|
|
|
// 5. 创建公共部分和按钮
|
|
|
m_pWellboreStorageLabel = new QLabel(tr("Wellbore storage:"));
|
|
|
m_pWellboreStorageEdit = new QLineEdit;
|
|
|
m_pWellboreStorageEdit->setReadOnly(true);
|
|
|
m_pWellboreStorageUnitCombo = new QComboBox;
|
|
|
// 井筒储集系数的默认单位
|
|
|
m_pWellboreStorageUnitCombo->addItem(tr("m^3/Mpa"));
|
|
|
//m_pWellboreStorageUnitCombo->addItem(tr("bbl/psi"));
|
|
|
|
|
|
m_pRefreshButton = new QPushButton();
|
|
|
|
|
|
m_pRefreshButton->setIcon(QIcon(sIconDir + "NmWellboreStorageRefresh.png"));
|
|
|
m_pRefreshButton->setIconSize(QSize(32, 32));
|
|
|
m_pRefreshButton->setFixedSize(34, 34);
|
|
|
|
|
|
m_pOkButton = new QPushButton(tr("OK"));
|
|
|
m_pCancelButton = new QPushButton(tr("Cancel"));
|
|
|
|
|
|
QHBoxLayout* buttonLayout = new QHBoxLayout;
|
|
|
buttonLayout->addStretch();
|
|
|
buttonLayout->addWidget(m_pOkButton);
|
|
|
buttonLayout->addWidget(m_pCancelButton);
|
|
|
|
|
|
// 6. 主布局
|
|
|
m_pMainLayout = new QVBoxLayout(this);
|
|
|
m_pMainLayout->addWidget(m_pModeGroupBox);
|
|
|
m_pMainLayout->addWidget(m_pStackedWidget);
|
|
|
|
|
|
QGridLayout* commonLayout = new QGridLayout;
|
|
|
// 为列设置拉伸因子以保持对齐和宽度一致
|
|
|
// commonLayout->setColumnStretch(0, 1);
|
|
|
// commonLayout->setColumnStretch(1, 2);
|
|
|
// commonLayout->setColumnStretch(2, 1);
|
|
|
// commonLayout->setColumnStretch(3, 1);
|
|
|
|
|
|
commonLayout->addWidget(m_pWellboreStorageLabel, 0, 0);
|
|
|
commonLayout->addWidget(m_pWellboreStorageEdit, 0, 1);
|
|
|
commonLayout->addWidget(m_pWellboreStorageUnitCombo, 0, 2);
|
|
|
commonLayout->addWidget(m_pRefreshButton, 0, 3);
|
|
|
m_pMainLayout->addLayout(commonLayout);
|
|
|
|
|
|
m_pMainLayout->addLayout(buttonLayout);
|
|
|
}
|
|
|
|
|
|
void nmWxWellboreStorageCalculator::initConnections()
|
|
|
{
|
|
|
// 连接模式按钮组的信号到槽,实现页面切换
|
|
|
connect(m_pModeButtonGroup, SIGNAL(buttonClicked(int)),
|
|
|
this, SLOT(onModeChanged(int)));
|
|
|
|
|
|
// 连接两个计算按钮到各自的槽函数
|
|
|
connect(m_pClosedChamberCalculateButton, SIGNAL(clicked()),
|
|
|
this, SLOT(onClosedChamberCalculateClicked()));
|
|
|
connect(m_pChangingLiquidLevelCalculateButton, SIGNAL(clicked()),
|
|
|
this, SLOT(onChangingLiquidLevelCalculateClicked()));
|
|
|
|
|
|
// 连接刷新按钮
|
|
|
connect(m_pRefreshButton, SIGNAL(clicked()),
|
|
|
this, SLOT(onRefreshWellboreStorageClicked()));
|
|
|
|
|
|
// 连接OK和Cancel按钮
|
|
|
connect(m_pOkButton, SIGNAL(clicked()), this, SLOT(accept()));
|
|
|
connect(m_pCancelButton, SIGNAL(clicked()), this, SLOT(reject()));
|
|
|
}
|
|
|
|
|
|
// 实现槽函数
|
|
|
void nmWxWellboreStorageCalculator::onModeChanged(int id)
|
|
|
{
|
|
|
// 根据按钮的ID来切换 QStackedWidget 的页面
|
|
|
m_pStackedWidget->setCurrentIndex(id);
|
|
|
}
|
|
|
|
|
|
void nmWxWellboreStorageCalculator::onRefreshWellboreStorageClicked()
|
|
|
{
|
|
|
// 根据当前显示的页面,触发相应的计算
|
|
|
int currentMode = m_pStackedWidget->currentIndex();
|
|
|
calculateWellboreStorage(currentMode);
|
|
|
}
|
|
|
|
|
|
void nmWxWellboreStorageCalculator::calculateWellboreStorage(int mode)
|
|
|
{
|
|
|
double wellboreStorage = 0.0;
|
|
|
bool ok = false;
|
|
|
|
|
|
// 计算常数
|
|
|
const double G = 9.80665; // 重力加速度,m/s^2
|
|
|
const double MPA_TO_PA = 1.0e6; // 1 MPa = 10^6 Pa
|
|
|
|
|
|
if (mode == 0) // 密闭井筒模式,输入单位为 m^3 和 1/Mpa
|
|
|
{
|
|
|
double testedVolume = m_pTestedVolumeEdit->text().toDouble(&ok);
|
|
|
if (!ok) { return; }
|
|
|
|
|
|
double fluidCompressibility = m_pFluidCompressibilityEdit->text().toDouble(&ok);
|
|
|
if (!ok) { return; }
|
|
|
|
|
|
// C = V_test * C_f
|
|
|
// V_test 单位: m^3
|
|
|
// C_f 单位: 1/Mpa
|
|
|
wellboreStorage = testedVolume * fluidCompressibility;
|
|
|
}
|
|
|
else if (mode == 1) // 液面变化模式,输入单位为 m 和 kg/m^3
|
|
|
{
|
|
|
double tubingId = m_pTubingIdEdit->text().toDouble(&ok);
|
|
|
if (!ok) { return; }
|
|
|
|
|
|
double fluidDensity = m_pFluidDensityEdit->text().toDouble(&ok);
|
|
|
if (!ok || fluidDensity == 0) { return; }
|
|
|
|
|
|
// 计算井筒截面积 A,单位 m^2
|
|
|
const double PI = acos(-1.0);
|
|
|
double wellboreArea = PI * pow(tubingId / 2.0, 2.0);
|
|
|
|
|
|
// C = A / (rho * g),结果单位为 m^3/Pa
|
|
|
double storageInPa = wellboreArea / (fluidDensity * G);
|
|
|
|
|
|
// 将结果从 m^3/Pa 转换为 m^3/Mpa
|
|
|
wellboreStorage = storageInPa * MPA_TO_PA;
|
|
|
}
|
|
|
|
|
|
m_pWellboreStorageEdit->setText(QString::number(wellboreStorage));
|
|
|
}
|
|
|
|
|
|
double nmWxWellboreStorageCalculator::getWellboreStorageValue() const
|
|
|
{
|
|
|
bool ok;
|
|
|
double value = m_pWellboreStorageEdit->text().toDouble(&ok);
|
|
|
if (ok && value >= 0) {
|
|
|
return value;
|
|
|
}
|
|
|
// 如果转换失败,返回-1
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
void nmWxWellboreStorageCalculator::onClosedChamberCalculateClicked()
|
|
|
{
|
|
|
if (!m_pTestedVolumeDialog) {
|
|
|
// 创建对话框实例,并指定父对象为 this
|
|
|
m_pTestedVolumeDialog = new nmWxWellboreStorageCalculatorVolume(this);
|
|
|
}
|
|
|
|
|
|
// 以模态对话框方式运行
|
|
|
if (m_pTestedVolumeDialog->exec() == QDialog::Accepted) {
|
|
|
// 获取计算后的井筒储集系数
|
|
|
double dV = m_pTestedVolumeDialog->getCalculatedVolume();
|
|
|
if (dV != -1)
|
|
|
{
|
|
|
// 应用到测试体积的值
|
|
|
m_pTestedVolumeEdit->setText(QString::number(dV));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void nmWxWellboreStorageCalculator::onChangingLiquidLevelCalculateClicked()
|
|
|
{
|
|
|
if (!m_pTubingDataDialog) {
|
|
|
// 创建对话框实例,并指定父对象为 this
|
|
|
m_pTubingDataDialog = new nmWxWellboreStorageCalculatorTubingData(this);
|
|
|
}
|
|
|
|
|
|
// 以模态对话框方式运行
|
|
|
if (m_pTubingDataDialog->exec() == QDialog::Accepted) {
|
|
|
// 获取选中的油管规格
|
|
|
double dSlectedTubingID = m_pTubingDataDialog->getSelectedTubingID();
|
|
|
|
|
|
// 检查值是否有效,然后更新主界面的输入框
|
|
|
if (dSlectedTubingID != -1.0) {
|
|
|
m_pTubingIdEdit->setText(QString::number(dSlectedTubingID));
|
|
|
}
|
|
|
}
|
|
|
}
|