refactor(nmNum): 统一渗透率基准单位为 mD

- 统一储层、诊断、自动拟合及属性插值的渗透率单位
- 调整渗透率默认值、拟合范围和参数配置
- 在 PEBI 求解器入口将 mD 转换为 D
- 移除储层参数面板对 D/d 单位歧义的特殊处理
feature/ReservoirPropertiesDlg-Refactoring-20260813
lh 5 days ago
parent efc590edc6
commit 8eebf98ba2

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -17,7 +17,7 @@
<ParaGroup Name="" Alias="储层参数">
<ParaItem Name="h" Alias="储层厚度" Unit="m" Default="10" Max="10000" Min="1e-05" Digit="6" Desc="reservoir thickness" />
<ParaItem Name="Pi" Alias="初始压力" Unit="MPa" Default="40" Max="500" Min="0.1" Digit="6" Desc="initial formation pressure" />
<ParaItem Name="K" Alias="渗透率" Unit="D" Default="0.025" Max="10" Min="0" Digit="6" Desc="permeability" />
<ParaItem Name="K" Alias="渗透率" Unit="mD" Default="25" Max="10000" Min="0" Digit="6" Desc="permeability" />
<ParaItem Name="phi" Alias="孔隙度" Unit="" Default="0.1" Max="1" Min="1e-05" Digit="6" Desc="porosity" />
<ParaItem Name="Bo" Alias="油体积系数" Unit="" Default="1.2" Max="10" Min="1e-06" Digit="6" Desc="oil formation volume factor" />
<ParaItem Name="Miuo" Alias="油相黏度" Unit="mPa.s" Default="0.5" Max="10000" Min="1e-06" Digit="6" Desc="oil viscosity" />
@ -95,7 +95,7 @@
<ParaItem Name="Result_W_C" Alias="井筒储集系数" Unit="m^3/MPa" Default="0" Max="1000" Min="0" Digit="6" Desc="result wellbore storage coefficient" />
<ParaItem Name="Result_Pi" Alias="初始地层压力" Unit="MPa" Default="40" Max="500" Min="0.1" Digit="6" Desc="result initial formation pressure" />
<ParaItem Name="Result_K" Alias="渗透率" Unit="D" Default="0.025" Max="10" Min="0" Digit="6" Desc="result permeability" />
<ParaItem Name="Result_K" Alias="渗透率" Unit="mD" Default="25" Max="10000" Min="0" Digit="6" Desc="result permeability" />
<ParaItem Name="Result_h" Alias="储层厚度" Unit="m" Default="10" Max="10000" Min="1e-05" Digit="6" Desc="result reservoir thickness" />
<ParaItem Name="Result_phi" Alias="孔隙度" Unit="" Default="0.1" Max="1" Min="1e-05" Digit="6" Desc="result porosity" />
<ParaItem Name="Result_Cti" Alias="综合压缩系数" Unit="1/MPa" Default="0.001" Max="10" Min="1e-30" Digit="10" Scientific="1" Desc="result total compressibility" />

@ -18,7 +18,7 @@
<ParaGroup Name="" Alias="Reservoir Parameters">
<ParaItem Name="h" Alias="Reservoir Thickness" Unit="m" Default="10" Max="10000" Min="1e-05" Digit="3" Desc="reservoir thickness" />
<ParaItem Name="Pi" Alias="Initial Pressure" Unit="MPa" Default="40" Max="500" Min="0.1" Digit="5" Desc="initial formation pressure" />
<ParaItem Name="K" Alias="Permeability" Unit="D" Default="0.025" Max="10" Min="0" Digit="6" Desc="permeability" />
<ParaItem Name="K" Alias="Permeability" Unit="mD" Default="25" Max="10000" Min="0" Digit="6" Desc="permeability" />
<ParaItem Name="phi" Alias="Porosity" Unit="" Default="0.1" Max="1" Min="1e-05" Digit="4" Desc="porosity" />
<ParaItem Name="Bo" Alias="Oil Formation Volume Factor" Unit="" Default="1.2" Max="10" Min="1e-06" Digit="6" Desc="oil formation volume factor" />
<ParaItem Name="Miuo" Alias="Oil Viscosity" Unit="mPa.s" Default="0.5" Max="10000" Min="1e-06" Digit="6" Desc="oil viscosity" />
@ -96,7 +96,7 @@
<ParaItem Name="Result_W_C" Alias="Wellbore Storage Coeff" Unit="m^3/MPa" Default="0" Max="1000" Min="0" Digit="6" Desc="result wellbore storage coefficient" />
<ParaItem Name="Result_Pi" Alias="Initial Formation Pressure" Unit="MPa" Default="40" Max="500" Min="0.1" Digit="6" Desc="result initial formation pressure" />
<ParaItem Name="Result_K" Alias="Permeability" Unit="D" Default="0.025" Max="10" Min="0" Digit="6" Desc="result permeability" />
<ParaItem Name="Result_K" Alias="Permeability" Unit="mD" Default="25" Max="10000" Min="0" Digit="6" Desc="result permeability" />
<ParaItem Name="Result_h" Alias="Reservoir Thickness" Unit="m" Default="10" Max="10000" Min="1e-05" Digit="6" Desc="result reservoir thickness" />
<ParaItem Name="Result_phi" Alias="Porosity" Unit="" Default="0.1" Max="1" Min="1e-05" Digit="6" Desc="result porosity" />
<ParaItem Name="Result_Cti" Alias="Total Compressibility" Unit="1/MPa" Default="0.001" Max="10" Min="1e-30" Digit="10" Scientific="1" Desc="result total compressibility" />

@ -19,6 +19,13 @@ class NMCALCULATION_EXPORT nmCalculationUtils {
static bool writeFile(const QStringList& content, const QString &filePath);
static QStringList readFile(const QString & filePath);
/**
* @brief 使西PEBI使西
* @param dPermeabilityMilliDarcy mD
* @return D
*/
static double milliDarcyToDarcy(double dPermeabilityMilliDarcy);
// 调用求解器Kriging接口对targetPoints中的坐标依次进行属性插值.
// measurementPoints与measurementValues按下标一一对应.
// 成功时outputValues与targetPoints数量相同且顺序一致失败时清空outputValues.

@ -1,4 +1,4 @@
#ifndef NMDATAATTRIBUTE_H
#ifndef NMDATAATTRIBUTE_H
#define NMDATAATTRIBUTE_H
#include <QString>
@ -15,7 +15,7 @@ enum UnitType {
UNIT_TYPE_LENGTH, // 长度m, cm, mm, in, ft, km等
UNIT_TYPE_CONDUCTIVITY, // 导流能力md.m, md.ft, m^3
UNIT_TYPE_PRESSURE, // 压力MPa, psia, Pa, kPa, bar等
UNIT_TYPE_PERMEABILITY, // 渗透率md, Darcy, m^2, cm^2等
UNIT_TYPE_PERMEABILITY, // 渗透率mD, D, m^2, cm^2等
UNIT_TYPE_ANGLE, // 角度o (degree), radian
UNIT_TYPE_FLOW_RATE_RECIPROCAL, // 流量倒数1/B/D, 1/m^3/D等
UNIT_TYPE_COMPRESSIBILITY, // 压缩系数m^3/MPa, bbl/psi等

@ -1,4 +1,4 @@
#ifndef NMDATABINARYTOOLS_H
#ifndef NMDATABINARYTOOLS_H
#define NMDATABINARYTOOLS_H
#include <QString>
@ -152,7 +152,7 @@ public:
double dt_Max; // 最大时间间隔
// 注意k, phi, h是每个网格单元一个值数量太大不保存基准值
// Python采样时根据 Base.k_ref 给所有单元赋相同值
double k_ref; // 渗透率参考值(用于采样)
double k_ref; // 渗透率参考值写入场景文件前已转换为D
double phi_ref; // 孔隙度参考值(用于采样)
double h_ref; // 厚度参考值(用于采样)
} Base;

@ -1,4 +1,4 @@
#include "nmCalculationDllPebiSolverTask.h"
#include "nmCalculationDllPebiSolverTask.h"
#include "singlePhaseSolver.h"
#include "zxLogInstance.h"
#include "nmDataAnalyzeManager.h"
@ -149,8 +149,11 @@ bool applyPropertyInterpolation(
solverValues->resize(interpolationValues.size());
for(int valueIndex = 0; valueIndex < interpolationValues.size(); ++valueIndex) {
// 插值数据已经使用求解器基准单位,结果可直接按网格顺序写入.
(*solverValues)[valueIndex] = interpolationValues[valueIndex];
// 属性插值数据层以mD保存渗透率在写入PEBI数组时转换为D。
(*solverValues)[valueIndex] = dataSet.property == "k"
? nmCalculationUtils::milliDarcyToDarcy(
interpolationValues[valueIndex])
: interpolationValues[valueIndex];
}
*propertyApplied = true;
}
@ -586,7 +589,11 @@ bool nmCalculationDllPebiSolverTask::execPebiMode()
p0.Base.Swi = pReservoirData->getSwi().getValue().toDouble(); // 初始含水饱和度
// 根据网格单元数设置每个单元的参数
size_t cellCount = pGridInstance->getGridOutput2().Trinodexy.size();
p0.Base.k = dVec1(cellCount, pReservoirData->getPermeability().getValue().toDouble());
// 数据层以mD保存渗透率PEBI输入数组要求使用D。
const double dPermeabilityDarcy =
nmCalculationUtils::milliDarcyToDarcy(
pReservoirData->getPermeability().getValue().toDouble());
p0.Base.k = dVec1(cellCount, dPermeabilityDarcy);
p0.Base.phi = dVec1(cellCount, pReservoirData->getPorosity().getValue().toDouble());
p0.Base.h = dVec1(cellCount, pReservoirData->getThickness().getValue().toDouble());
}

@ -1,4 +1,4 @@
#include "nmCalculationPebiGrid.h"
#include "nmCalculationPebiGrid.h"
#include <Windows.h>
#include <QApplication>
#include <QDebug>
@ -1069,7 +1069,9 @@ bool nmCalculationPebiGrid::generateOutputPara()
scene.Base.Swi = pReservoirData->getSwi().getValue().toDouble();
// 保存参考值用于Python采样
scene.Base.k_ref = pReservoirData->getPermeability().getValue().toDouble();
// 训练场景最终会直接填入PEBI输入结构写文件前转换为求解器使用的D。
scene.Base.k_ref = nmCalculationUtils::milliDarcyToDarcy(
pReservoirData->getPermeability().getValue().toDouble());
scene.Base.phi_ref = pReservoirData->getPorosity().getValue().toDouble();
scene.Base.h_ref = pReservoirData->getThickness().getValue().toDouble();
}

@ -37,6 +37,12 @@ void setKrigingError(QString* errorMessage, const QString& message)
nmCalculationUtils::nmCalculationUtils() {
}
double nmCalculationUtils::milliDarcyToDarcy(double dPermeabilityMilliDarcy)
{
// PEBI输入结构使用D数据层统一使用mD因此仅在求解器边界换算。
return dPermeabilityMilliDarcy / 1000.0;
}
bool nmCalculationUtils::copyFileToDir(QString filePath, QString destDir) {
// 如果文件不存在,则退出
if(!QFile::exists(filePath)) {

@ -1,4 +1,4 @@
#include "nmDataAttribute.h"
#include "nmDataAttribute.h"
#include <QDebug>
@ -413,7 +413,8 @@ UnitType nmDataAttribute::detectUnitType(const QString& unit) {
}
// 渗透率单位
if (unit == "md" || unit == "Darcy" || unit == "m^2" || unit == "cm^2" || unit == "um^2") {
if (unit == "mD" || unit == "D" || unit == "md" || unit == "Darcy" ||
unit == "m^2" || unit == "cm^2" || unit == "um^2") {
return UNIT_TYPE_PERMEABILITY;
}
@ -578,9 +579,9 @@ double nmDataAttribute::convertPermeabilityUnit(double value, const QString& fro
// 统一转换为Darcy
double valueInDarcy = value;
if (fromUnit == "md") {
valueInDarcy = value / 1000.0; // 1 Darcy = 1000 md
} else if (fromUnit == "Darcy") {
if (fromUnit == "mD" || fromUnit == "md") {
valueInDarcy = value / 1000.0; // 1 D = 1000 mD
} else if (fromUnit == "D" || fromUnit == "Darcy") {
valueInDarcy = value;
} else if (fromUnit == "m^2") {
valueInDarcy = value * 9.869233e-13; // 1 m^2 = 9.869233e-13 Darcy
@ -593,9 +594,9 @@ double nmDataAttribute::convertPermeabilityUnit(double value, const QString& fro
}
// 从Darcy转换为目标单位
if (toUnit == "Darcy") {
if (toUnit == "D" || toUnit == "Darcy") {
return valueInDarcy;
} else if (toUnit == "md") {
} else if (toUnit == "mD" || toUnit == "md") {
return valueInDarcy * 1000.0;
} else if (toUnit == "m^2") {
return valueInDarcy / 9.869233e-13;

@ -13,7 +13,7 @@ nmDataAutomaticFitting::nmDataAutomaticFitting()
m_swiSelected = false; // 默认不选中
// 初始化参数最大值
m_permeabilityMax = nmDataAttribute("Permeability Max", 10.0, "D");
m_permeabilityMax = nmDataAttribute("Permeability Max", 10000.0, "mD");
m_skinMax = nmDataAttribute("Skin Max", 10.0, ""); // 100
m_wellboreStorageMax = nmDataAttribute("Wellbore Storage Max", 2.0, "m^3/MPa");
m_porosityMax = nmDataAttribute("Porosity Max", 0.5, ""); // 50%
@ -23,7 +23,7 @@ nmDataAutomaticFitting::nmDataAutomaticFitting()
m_swiMax = nmDataAttribute("Swi Max", 1.0, "");
// 初始化参数最小值
m_permeabilityMin = nmDataAttribute("Permeability Min", 0.001, "D");
m_permeabilityMin = nmDataAttribute("Permeability Min", 1.0, "mD");
m_skinMin = nmDataAttribute("Skin Min", -10.0, ""); // 允许负表皮
m_wellboreStorageMin = nmDataAttribute("Wellbore Storage Min", 1e-4, "m^3/MPa");
m_porosityMin = nmDataAttribute("Porosity Min", 0.01, ""); // 1%
@ -164,8 +164,8 @@ void nmDataAutomaticFitting::FromJsonValue(const rapidjson::Value& jsonValue)
// 反序列化参数最大值
if (jsonValue.HasMember("PermeabilityMax") && jsonValue["PermeabilityMax"].IsObject()) {
m_permeabilityMax.FromJsonValue(jsonValue["PermeabilityMax"]);
// 自动拟合上下限与求解器使用同一基准单位不按旧JSON单位文本换算
m_permeabilityMax.setUnit("D");
// 自动拟合上下限统一按数据层基准单位mD解释不兼容旧JSON的D数值
m_permeabilityMax.setUnit("mD");
}
if (jsonValue.HasMember("SkinMax") && jsonValue["SkinMax"].IsObject()) {
m_skinMax.FromJsonValue(jsonValue["SkinMax"]);
@ -192,7 +192,7 @@ void nmDataAutomaticFitting::FromJsonValue(const rapidjson::Value& jsonValue)
// 反序列化参数最小值
if (jsonValue.HasMember("PermeabilityMin") && jsonValue["PermeabilityMin"].IsObject()) {
m_permeabilityMin.FromJsonValue(jsonValue["PermeabilityMin"]);
m_permeabilityMin.setUnit("D");
m_permeabilityMin.setUnit("mD");
}
if (jsonValue.HasMember("SkinMin") && jsonValue["SkinMin"].IsObject()) {
m_skinMin.FromJsonValue(jsonValue["SkinMin"]);

@ -1,4 +1,4 @@
#include "nmDataDiagnostic.h"
#include "nmDataDiagnostic.h"
#include "nmDataWellBase.h"
#include "nmDataReservoir.h"
#include <QDebug>
@ -15,7 +15,7 @@ nmDataDiagnostic::nmDataDiagnostic()
{
m_diagnosticSkin = nmDataAttribute("Skin", 0.0, "");
m_diagnosticWellboreStorage = nmDataAttribute("Wellbore storage", 0.01, "m^3/MPa", UNIT_TYPE_COMPRESSIBILITY, QStringList(), QStringList() << "bbl/psi" << "m^3/bar" << "m^3/kPa" << "m^3/Pa" << "m^3.cm^2/kg" << "m^2" << "m^3/MPa");
m_diagnosticPermeability = nmDataAttribute("Permeability", 0.025, "md", UNIT_TYPE_PERMEABILITY, QStringList(), QStringList() << "md" << "Darcy" << "m^2" << "cm^2" << "um^2");
m_diagnosticPermeability = nmDataAttribute("Permeability", 25.0, "mD", UNIT_TYPE_PERMEABILITY, QStringList(), QStringList() << "mD" << "D" << "m^2" << "cm^2" << "um^2");
m_diagnosticTransmissibility = nmDataAttribute("Transmissibility", 1000.0, "md.m", UNIT_TYPE_CONDUCTIVITY, QStringList(), QStringList()<< "md.ft" << "md.m" << "m^3");
}
@ -258,7 +258,7 @@ void nmDataDiagnostic::calculateTransmissibility(const QVector<QVector<double>>&
DEBUG_OUT(QString("=== Transmissibility Analysis Result ==="));
DEBUG_OUT(QString("Selected method: %1").arg(selectedAnalysis->description));
DEBUG_OUT(QString("Transmissibility (kh): %1 md*m").arg(khValue, 0, 'f', 6));
DEBUG_OUT(QString("Transmissibility (kh): %1 mD*m").arg(khValue, 0, 'f', 6));
DEBUG_OUT(QString("Analysis time: %1 hr").arg(selectedAnalysis->avgTime, 0, 'f', 4));
DEBUG_OUT(QString("Derivative value used: %1 MPa").arg(selectedAnalysis->avgPressure, 0, 'f', 6));
} else {
@ -292,9 +292,9 @@ void nmDataDiagnostic::calculatePermeability(nmDataWellBase* pWell, nmDataReserv
m_diagnosticPermeability.setValue(kValue);
DEBUG_OUT(QString("=== Permeability Analysis Result ==="));
DEBUG_OUT(QString("Transmissibility (kh): %1 md*m").arg(khValue, 0, 'f', 6));
DEBUG_OUT(QString("Transmissibility (kh): %1 mD*m").arg(khValue, 0, 'f', 6));
DEBUG_OUT(QString("Reservoir thickness (h): %1 m").arg(thickness, 0, 'f', 2));
DEBUG_OUT(QString("Permeability (k): %1 md").arg(kValue, 0, 'f', 6));
DEBUG_OUT(QString("Permeability (k): %1 mD").arg(kValue, 0, 'f', 6));
}
//void nmDataDiagnostic::calculateSkin(const QVector<QVector<double>>& rawData,

@ -4,8 +4,8 @@
nmDataReservoir::nmDataReservoir() {
// 基础属性
m_initialPressure = nmDataAttribute("Initial Pressure",40.0, "MPa", UNIT_TYPE_PRESSURE, QStringList(), QStringList() << "psia" << "Pa" << "kPa" << "atm" << "bara" << "kg/cm^2" << "m" << "psig" << "bar" << "MPa" << "kPag");
// 求解器直接读取该数值内部基准单位固定为D显示换算由框架单位绑定器负责
m_permeability = nmDataAttribute("Permeability", 0.025, "D");
// 数据层基准单位固定为mD进入PEBI求解器前再统一转换为D
m_permeability = nmDataAttribute("Permeability", 25.0, "mD");
m_thickness = nmDataAttribute("Thickness", 10.0, "m", UNIT_TYPE_LENGTH, QStringList(), QStringList() << "ft" << "m" << "cm" << "mm" << "in" << "0.1 in" << "mile" << "km");
m_porosity = nmDataAttribute("Porosity", 0.1, "", UNIT_TYPE_DIMENSIONLESS, QStringList(), QStringList());
m_kxKy = nmDataAttribute("Kx/Ky", 1.0, "", UNIT_TYPE_DIMENSIONLESS, QStringList(), QStringList());
@ -41,7 +41,7 @@ nmDataReservoir::nmDataReservoir() {
void nmDataReservoir::resetToDefaults()
{
m_permeability.setValue(0.025);
m_permeability.setValue(25.0);
m_transmissibility.setValue(1000.0);
}
@ -148,8 +148,8 @@ void nmDataReservoir::FromJsonValue(const rapidjson::Value& jsonValue)
}
if (jsonValue.HasMember("Permeability") && jsonValue["Permeability"].IsObject()) {
m_permeability.FromJsonValue(jsonValue["Permeability"]);
// JSON中的单位文本不参与兼容换算读取后的内部单位始终按求解器标准固定为D。
m_permeability.setUnit("D");
// JSON中的单位文本不参与兼容换算读取后的数据层单位始终固定为mD。
m_permeability.setUnit("mD");
}
if (jsonValue.HasMember("Thickness") && jsonValue["Thickness"].IsObject()) {
m_thickness.FromJsonValue(jsonValue["Thickness"]);
@ -244,7 +244,7 @@ bool nmDataReservoir::_parseData(VecVariant vec, int& n) {
m_reservoirType = nmDataAttribute("Reservoir Type", vec[n++].toString(), "");
m_Bo = nmDataAttribute("Bo", vec[n++].toString(), "");
m_Miuo = nmDataAttribute("Miuo", vec[n++].toString(), "mPa.s");
m_permeability = nmDataAttribute("Permeability", vec[n++].toString(), "D");
m_permeability = nmDataAttribute("Permeability", vec[n++].toString(), "mD");
m_thickness = nmDataAttribute("Thickness", vec[n++].toString(), "m");
m_porosity = nmDataAttribute("Porosity", vec[n++].toString(), "");
m_Ct = nmDataAttribute("Ct", vec[n++].toString(), "1/MPa");
@ -284,8 +284,8 @@ void nmDataReservoir::onDeserialize(ZxSerializer* ser) {
ser->read("ReservoirType", tempValue); m_reservoirType = nmDataAttribute("Reservoir Type", tempValue, "");
ser->read("Bo", tempValue); m_Bo = nmDataAttribute("Bo", tempValue, "");
ser->read("Miuo", tempValue); m_Miuo = nmDataAttribute("Miuo", tempValue, "mPa.s");
// 序列化格式只保存数值,读取时明确按求解器基准单位D解释。
ser->read("Permeability", tempValue); m_permeability = nmDataAttribute("Permeability", tempValue, "D");
// 序列化格式只保存数值,读取时明确按数据层基准单位mD解释。
ser->read("Permeability", tempValue); m_permeability = nmDataAttribute("Permeability", tempValue, "mD");
ser->read("Thickness", tempValue); m_thickness = nmDataAttribute("Thickness", tempValue, "m");
ser->read("Porosity", tempValue); m_porosity = nmDataAttribute("Porosity", tempValue, "");
ser->read("Ct", tempValue); m_Ct = nmDataAttribute("Ct", tempValue, "1/MPa");

@ -242,9 +242,9 @@ nmWxAutomaticFitting::nmWxAutomaticFitting(QWidget *parent)
solverModelType == SMT_Water_ConstPvt ||
solverModelType == SMT_Water_VariablePvt;
if(isOilOrWaterSinglePhase) {
reservoirData.getPermeability().setValue(2.5e-2);
automaticFittingData.getPermeabilityMin().setValue(1.0e-3);
automaticFittingData.getPermeabilityMax().setValue(10.0);
reservoirData.getPermeability().setValue(25.0);
automaticFittingData.getPermeabilityMin().setValue(1.0);
automaticFittingData.getPermeabilityMax().setValue(10000.0);
automaticFittingData.getSkinMin().setValue(-10.0);
automaticFittingData.getSkinMax().setValue(10.0);
automaticFittingData.getWellboreStorageMin().setValue(1.0e-4);
@ -271,13 +271,13 @@ nmWxAutomaticFitting::nmWxAutomaticFitting(QWidget *parent)
// 气单相变化 PVT 使用 T5 数据集对应的初始值和拟合范围。
if(solverModelType == SMT_Gas_VariablePvt) {
reservoirData.getPermeability().setValue(5.5e-6);
reservoirData.getPermeability().setValue(5.5e-3);
reservoirData.getPorosity().setValue(3.5e-2);
reservoirData.getThickness().setValue(8.0);
reservoirData.getCf().setValue(3.0e-4);
automaticFittingData.getPermeabilityMin().setValue(4.5e-6);
automaticFittingData.getPermeabilityMax().setValue(6.2e-6);
automaticFittingData.getPermeabilityMin().setValue(4.5e-3);
automaticFittingData.getPermeabilityMax().setValue(6.2e-3);
automaticFittingData.getSkinMin().setValue(0.0);
automaticFittingData.getSkinMax().setValue(4.5);
automaticFittingData.getWellboreStorageMin().setValue(5.0e-5);
@ -408,7 +408,7 @@ void nmWxAutomaticFitting::setupParameterTable()
m_parameterTable->setItem(0, 2, new QTableWidgetItem(QString::number(automaticFittingData.getPermeabilityMin().getValue().toDouble())));
m_parameterTable->setItem(0, 3, new QTableWidgetItem(QString::number(reservoirData.getPermeability().getValue().toDouble())));
m_parameterTable->setItem(0, 4, new QTableWidgetItem(QString::number(automaticFittingData.getPermeabilityMax().getValue().toDouble())));
m_parameterTable->setItem(0, 5, new QTableWidgetItem(tr("D")));
m_parameterTable->setItem(0, 5, new QTableWidgetItem(tr("mD")));
// 表皮系数 (Skin)
m_parameterTable->setItem(1, 0, new QTableWidgetItem("2"));

@ -1,4 +1,4 @@
#include "nmWxPropertyInterpolationDlg.h"
#include "nmWxPropertyInterpolationDlg.h"
#include <QAbstractItemView>
#include <QApplication>
@ -47,9 +47,9 @@ namespace
// 表格第0行保留给单位实际测点从第1行开始.
const int POINT_UNIT_ROW = 0;
const int FIRST_POINT_ROW = 1;
// 坐标和厚度以m保存渗透率以D保存但默认使用mD显示.
// 坐标和厚度以m保存渗透率统一以mD保存和显示。
const char* LENGTH_BASE_UNIT = "m";
const char* PERMEABILITY_BASE_UNIT = "D";
const char* PERMEABILITY_BASE_UNIT = "mD";
const char* PERMEABILITY_DISPLAY_UNIT = "mD";
// 使用独立翻译上下文,便于统一维护对话框文本.
@ -92,9 +92,7 @@ QString defaultPropertyDisplayUnit(const QString& property)
QString unitGroupLookupUnit(const QString& unit)
{
// D与时间单位d仅大小写不同使用唯一的mD定位渗透率单位组.
return unit == PERMEABILITY_BASE_UNIT ?
QString(PERMEABILITY_DISPLAY_UNIT) : unit;
return unit;
}
bool convertUnitValue(double sourceValue,

@ -4,7 +4,6 @@
#include "nmReservoirPropertiesSession.h"
#include "nmReservoirParameterPage.h"
#include "iUnitGroup.h"
#include "iUnitHelper.h"
#include "iUnitWxBinder.h"
#include "mModuleDefines.h"
#include "ZxBaseUtil.h"
@ -310,47 +309,9 @@ bool nmWxReservoirPropertiesEditor::bindUnitField(
QComboBox* pUnitComboBox,
const QString& sBaseParameterId)
{
// 第一步:仍由框架绑定器读取参数定义、范围和常规单位组。
if (!bindUnitPairWxs(pLineEdit, pUnitComboBox,
sBaseParameterId, false))
{
return false;
}
// 第二步单位帮助器对单位名执行了不区分大小写的匹配D可能先命中
// 时间组中的d。渗透率以mD这个无歧义单位定位正确单位组
// 但基准单位仍明确保持为求解器使用的D。
if (sBaseParameterId == QString::fromLatin1("K"))
{
iUnitGroup* pPermeabilityGroup =
iUnitHelper::getUnitGroupByUnit(
QString::fromLatin1("mD"));
zxBindWxPair* pBindPair = m_pUnitBinder != nullptr
? m_pUnitBinder->getWxPairOf(pLineEdit) : nullptr;
if (pPermeabilityGroup == nullptr || pBindPair == nullptr ||
pPermeabilityGroup->m_sType.compare(
QString::fromLatin1("permeability"),
Qt::CaseInsensitive) != 0 ||
pPermeabilityGroup->indexOf(
QString::fromLatin1("D")) < 0)
{
return false;
}
// 第三步:替换错误单位组并重建单位选项。后续数值设置、切换、
// 范围校验和基准值读取继续全部通过框架绑定器完成。
pBindPair->isUpdating = true;
pBindPair->pUnitGroup = pPermeabilityGroup;
pBindPair->sBaseUnit = QString::fromLatin1("D");
pUnitComboBox->clear();
pUnitComboBox->addItems(pPermeabilityGroup->getAllUnitNames());
int nBaseUnitIndex = pUnitComboBox->findText(
QString::fromLatin1("D"),
Qt::MatchExactly | Qt::MatchCaseSensitive);
pUnitComboBox->setCurrentIndex(nBaseUnitIndex);
pBindPair->isUpdating = false;
}
return true;
// 参数XML已统一使用无歧义的mD作为渗透率基准单位所有字段直接复用框架绑定器。
return bindUnitPairWxs(pLineEdit, pUnitComboBox,
sBaseParameterId, false);
}
void nmWxReservoirPropertiesEditor::setUnitBaseValue(

Loading…
Cancel
Save