feat(nmNum): 补充多井参数配置

- 为采样和拟合参数记录所属井,区分共享储层参数。

- 保存各井拟合勾选、初值与范围,兼容原单井配置。
feature/Sensitivity-20261012
lvjunjie 4 days ago
parent d581494c40
commit 56b93dd62c

@ -6,6 +6,20 @@
#include "nmDataAttribute.h" #include "nmDataAttribute.h"
#include <QVector> #include <QVector>
// 一项拟合未知量,参数类型仍沿用原来的六种;储层参数的井编码为空。
struct NM_DATA_EXPORT nmFitParameter
{
nmFitParameter() : type(0), selected(false), initial(0.0), lower(0.0), upper(0.0) {}
QString wellCode, wellName;
int type; // 0 k,1 Skin,2 C,3 phi,4 Dfc,5 裂缝半长。
bool selected;
double initial, lower, upper;
QString name() const;
QString code() const;
QString unit() const;
QString samplingKey() const;
};
class NM_DATA_EXPORT nmDataAutomaticFitting : public nmDataBase class NM_DATA_EXPORT nmDataAutomaticFitting : public nmDataBase
{ {
Q_OBJECT Q_OBJECT
@ -20,6 +34,11 @@ public:
// 实现 nmDataBase 的抽象方法:从 RapidJSON Value 反序列化数据到当前 C++ 对象 // 实现 nmDataBase 的抽象方法:从 RapidJSON Value 反序列化数据到当前 C++ 对象
virtual void FromJsonValue(const rapidjson::Value& jsonValue) override; virtual void FromJsonValue(const rapidjson::Value& jsonValue) override;
// 多井参数按表格顺序保存,旧项目无此列表时沿用原单井配置。
QVector<nmFitParameter>& getModelParameters();
const QVector<nmFitParameter>& getModelParameters() const;
bool hasSelectedParameters() const;
// Getter and Setter for permeabilityMax // Getter and Setter for permeabilityMax
nmDataAttribute& getPermeabilityMax(); nmDataAttribute& getPermeabilityMax();
void setPermeabilityMax(const nmDataAttribute& permeabilityMax); void setPermeabilityMax(const nmDataAttribute& permeabilityMax);
@ -97,6 +116,7 @@ public:
void setFractureHalfLengthSelected(bool selected); void setFractureHalfLengthSelected(bool selected);
private: private:
QVector<nmFitParameter> m_modelParameters;
// 参数最大值 // 参数最大值
nmDataAttribute m_permeabilityMax; nmDataAttribute m_permeabilityMax;
nmDataAttribute m_skinMax; nmDataAttribute m_skinMax;

@ -32,6 +32,10 @@ public:
QString m_varGroup; QString m_varGroup;
// 变量名称 // 变量名称
QString m_varName; QString m_varName;
// 井参数使用稳定井编码区分;空编码表示共用储层参数或旧版主井参数。
QString m_wellCode;
QString displayName() const;
QString parameterKey() const;
// 是否勾选 // 是否勾选
bool m_enabled; bool m_enabled;
// Mode 枚举 // Mode 枚举

@ -1,4 +1,6 @@
#include "nmDataAutomaticFitting.h" #include "nmDataAutomaticFitting.h"
#include <QCoreApplication>
#include <QtCore/qnumeric.h>
nmDataAutomaticFitting::nmDataAutomaticFitting() nmDataAutomaticFitting::nmDataAutomaticFitting()
{ {
@ -44,7 +46,8 @@ nmDataAutomaticFitting::nmDataAutomaticFitting(const nmDataAutomaticFitting& oth
nmDataAutomaticFitting& nmDataAutomaticFitting::operator=(const nmDataAutomaticFitting& other) nmDataAutomaticFitting& nmDataAutomaticFitting::operator=(const nmDataAutomaticFitting& other)
{ {
if (this != &other) { if (this != &other) {
// 复制参数选择标志 // 复制多井参数及原单井配置
m_modelParameters = other.m_modelParameters;
m_permeabilitySelected = other.m_permeabilitySelected; m_permeabilitySelected = other.m_permeabilitySelected;
m_skinSelected = other.m_skinSelected; m_skinSelected = other.m_skinSelected;
m_wellboreStorageSelected = other.m_wellboreStorageSelected; m_wellboreStorageSelected = other.m_wellboreStorageSelected;
@ -111,11 +114,51 @@ rapidjson::Value nmDataAutomaticFitting::ToJsonValue(rapidjson::Document::Alloca
fittingObject.AddMember("AlgorithmName", rapidjson::Value(m_algorithmName.toStdString().c_str(), allocator).Move(), allocator); fittingObject.AddMember("AlgorithmName", rapidjson::Value(m_algorithmName.toStdString().c_str(), allocator).Move(), allocator);
fittingObject.AddMember("SurrogateScreeningEnabled", m_surrogateScreeningEnabled, allocator); fittingObject.AddMember("SurrogateScreeningEnabled", m_surrogateScreeningEnabled, allocator);
// 多井配置仍存放在原自动拟合节点中,敏感性配置复用同一序列化。
rapidjson::Value parameters(rapidjson::kArrayType);
for(int i = 0; i < m_modelParameters.size(); ++i) {
const nmFitParameter& p = m_modelParameters[i];
rapidjson::Value item(rapidjson::kObjectType);
item.AddMember("WellCode", rapidjson::Value(p.wellCode.toUtf8().constData(), allocator).Move(), allocator);
item.AddMember("WellName", rapidjson::Value(p.wellName.toUtf8().constData(), allocator).Move(), allocator);
item.AddMember("Type", p.type, allocator);
item.AddMember("Selected", p.selected, allocator);
item.AddMember("Initial", p.initial, allocator);
item.AddMember("Lower", p.lower, allocator);
item.AddMember("Upper", p.upper, allocator);
parameters.PushBack(item, allocator);
}
fittingObject.AddMember("ModelParameters", parameters, allocator);
return fittingObject; return fittingObject;
} }
void nmDataAutomaticFitting::FromJsonValue(const rapidjson::Value& jsonValue) void nmDataAutomaticFitting::FromJsonValue(const rapidjson::Value& jsonValue)
{ {
// 缺失列表表示旧版单井设置;非法项不进入优化向量。
m_modelParameters.clear();
if(jsonValue.HasMember("ModelParameters") && jsonValue["ModelParameters"].IsArray()) {
const rapidjson::Value& items = jsonValue["ModelParameters"];
for(rapidjson::SizeType i = 0; i < items.Size(); ++i) {
const rapidjson::Value& item = items[i];
if(!item.IsObject() || !item.HasMember("Type") || !item["Type"].IsInt() ||
item["Type"].GetInt() < 0 || item["Type"].GetInt() > 5 ||
!item.HasMember("Initial") || !item["Initial"].IsNumber() ||
!item.HasMember("Lower") || !item["Lower"].IsNumber() ||
!item.HasMember("Upper") || !item["Upper"].IsNumber()) continue;
nmFitParameter p;
p.type = item["Type"].GetInt();
if(item.HasMember("WellCode") && item["WellCode"].IsString()) p.wellCode = QString::fromUtf8(item["WellCode"].GetString());
if(item.HasMember("WellName") && item["WellName"].IsString()) p.wellName = QString::fromUtf8(item["WellName"].GetString());
p.initial = item["Initial"].GetDouble();
p.lower = item["Lower"].GetDouble();
p.upper = item["Upper"].GetDouble();
if(!qIsFinite(p.initial) || !qIsFinite(p.lower) || !qIsFinite(p.upper) || p.lower > p.upper) continue;
p.selected = item.HasMember("Selected") && item["Selected"].IsBool() && item["Selected"].GetBool();
m_modelParameters.append(p);
}
}
// 反序列化参数选择标志 // 反序列化参数选择标志
if (jsonValue.HasMember("PermeabilitySelected") && jsonValue["PermeabilitySelected"].IsBool()) { if (jsonValue.HasMember("PermeabilitySelected") && jsonValue["PermeabilitySelected"].IsBool()) {
m_permeabilitySelected = jsonValue["PermeabilitySelected"].GetBool(); m_permeabilitySelected = jsonValue["PermeabilitySelected"].GetBool();
@ -268,3 +311,56 @@ void nmDataAutomaticFitting::setAlgorithmName(const QString& algorithmName) { m_
bool nmDataAutomaticFitting::getSurrogateScreeningEnabled() const { return m_surrogateScreeningEnabled; } bool nmDataAutomaticFitting::getSurrogateScreeningEnabled() const { return m_surrogateScreeningEnabled; }
void nmDataAutomaticFitting::setSurrogateScreeningEnabled(bool enabled) { m_surrogateScreeningEnabled = enabled; } void nmDataAutomaticFitting::setSurrogateScreeningEnabled(bool enabled) { m_surrogateScreeningEnabled = enabled; }
QString nmFitParameter::name() const
{
// 井参数携带井名,共用参数保持原名称和翻译。
const char* names[] = {"Permeability", "Skin", "Wellbore storage", "Porosity", "Fracture conductivity", "Fracture half length"};
const QString label = QCoreApplication::translate("nmWxAutomaticFitting", names[type]);
return wellCode.isEmpty() ? label : wellName + " / " + label;
}
QString nmFitParameter::code() const
{
// 结果面板继续使用已有 XML 参数编码。
const char* codes[] = {"K", "Skin", "C", "phi", "Dfc", "FractureHalfLength"};
return codes[type];
}
QString nmFitParameter::unit() const
{
// 与既有六参数的基准单位一致。
const char* units[] = {"mD", "", "m^3/MPa", "", "mD.m", "m"};
return units[type];
}
QString nmFitParameter::samplingKey() const
{
// 同井同参数才与敏感性采样互斥。
const QString names[] = {"k", "Skin", "C", QString(QChar(0x03c6)), "Dfc", "FractureHalfLength"};
return wellCode.isEmpty() ? names[type] : wellCode + "/" + names[type];
}
QVector<nmFitParameter>& nmDataAutomaticFitting::getModelParameters()
{
// 窗口在自己的配置副本上编辑。
return m_modelParameters;
}
const QVector<nmFitParameter>& nmDataAutomaticFitting::getModelParameters() const
{
// 后台计算只读取启动前冻结的设置。
return m_modelParameters;
}
bool nmDataAutomaticFitting::hasSelectedParameters() const
{
// 新配置检查完整多井列表,旧配置兼容原六个勾选标志。
if(!m_modelParameters.isEmpty()) {
for(int i = 0; i < m_modelParameters.size(); ++i)
if(m_modelParameters[i].selected) return true;
return false;
}
return m_permeabilitySelected || m_skinSelected || m_wellboreStorageSelected ||
m_porositySelected || m_fractureConductivitySelected || m_fractureHalfLengthSelected;
}

@ -277,6 +277,7 @@ rapidjson::Value nmDataSensitive::VariableSampling::ToJsonValue(
rapidjson::Document::AllocatorType& allocator) const rapidjson::Document::AllocatorType& allocator) const
{ {
rapidjson::Value obj(rapidjson::kObjectType); rapidjson::Value obj(rapidjson::kObjectType);
obj.AddMember("WellCode", rapidjson::Value(m_wellCode.toUtf8().constData(), allocator).Move(), allocator);
// 字符串字段 // 字符串字段
obj.AddMember("VarGroup", obj.AddMember("VarGroup",
@ -320,6 +321,8 @@ void nmDataSensitive::VariableSampling::FromJsonValue(const rapidjson::Value& js
{ {
// 旧文件未保存分布时保留默认状态,由分析窗口按模型值初始化。 // 旧文件未保存分布时保留默认状态,由分析窗口按模型值初始化。
*this = VariableSampling(); *this = VariableSampling();
m_wellCode = jsonValue.HasMember("WellCode") && jsonValue["WellCode"].IsString()
? QString::fromUtf8(jsonValue["WellCode"].GetString()) : QString();
if(jsonValue.HasMember("Distribution") && jsonValue["Distribution"].IsInt()) { if(jsonValue.HasMember("Distribution") && jsonValue["Distribution"].IsInt()) {
const int distribution = jsonValue["Distribution"].GetInt(); const int distribution = jsonValue["Distribution"].GetInt();
if(distribution >= NORMAL && distribution <= TRIANGULAR) if(distribution >= NORMAL && distribution <= TRIANGULAR)
@ -385,6 +388,18 @@ void nmDataSensitive::VariableSampling::setVarGroup(const QString& group)
} }
// varName // varName
QString nmDataSensitive::VariableSampling::displayName() const
{
// 预览与曲线标注同时显示井名,避免不同井的同名参数混淆。
return m_wellCode.isEmpty() ? m_varName : m_varGroup + " / " + m_varName;
}
QString nmDataSensitive::VariableSampling::parameterKey() const
{
// 参数互斥按所属井判断,共用储层参数仍只使用参数名。
return m_wellCode.isEmpty() ? m_varName : m_wellCode + "/" + m_varName;
}
QString nmDataSensitive::VariableSampling::getVarName() const QString nmDataSensitive::VariableSampling::getVarName() const
{ {
return m_varName; return m_varName;

Loading…
Cancel
Save