You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/Src/nmNum/nmSubWxs/nmWxWellboreStorageCalculat...

332 lines
12 KiB
C++

#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) : iDlgBase(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));
}
}
}