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++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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