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/nmData/nmDataHorizontalFracturedWe...

371 lines
17 KiB
C++

#include "nmDataHorizontalFracturedWell.h"
#include "nmDataAnalyzeManager.h"
#include "nmDataReservoir.h"
nmDataHorizontalFracturedWell::nmDataHorizontalFracturedWell() : nmDataHorizontalWell() {
m_pReservoir = nmDataAnalyzeManager::getCurrentInstance()->getReservoirData();
double horizontalSectionLength = 200.0;
m_wellLength.setValue(horizontalSectionLength);
m_dLastWellLength = horizontalSectionLength;
m_modelingType = nmDataAttribute("Modeling type", "Simple", "", UNIT_TYPE_DIMENSIONLESS, QStringList() << "Simple" << "SRVB" << "Trilinear" << "Complex", QStringList());
m_fractureModel = nmDataAttribute("Fracture model", "Infinite conductivity", "", UNIT_TYPE_DIMENSIONLESS, QStringList() << "Infinite conductivity" << "Finite conductivity", QStringList());
m_dFc = nmDataAttribute("dFc", 1000, "md.m", UNIT_TYPE_CONDUCTIVITY, QStringList(), QStringList() << "md.ft" << "md.m" << "m^3");
m_numberOfFractures = nmDataAttribute("Number of fractures", 15, "", UNIT_TYPE_DIMENSIONLESS, QStringList(), QStringList());
m_fractureHalfLength = nmDataAttribute("Fracture half length", 50.0, "m", UNIT_TYPE_LENGTH, QStringList(), QStringList() << "ft" << "m" << "cm" << "mm" << "in" << "0.1 in" << "mile" << "km");
m_fractureHeight = nmDataAttribute("Fracture height", m_pReservoir->getThickness().getValue().toDouble(), "m", UNIT_TYPE_LENGTH, QStringList(), QStringList() << "ft" << "m" << "cm" << "mm" << "in" << "0.1 in" << "mile" << "km");
m_fractureMidPointHeight = nmDataAttribute("Fracture mid-point height", (m_fractureHeight.getValue().toDouble())/2, "m", UNIT_TYPE_LENGTH, QStringList(), QStringList() << "ft" << "m" << "cm" << "mm" << "in" << "0.1 in" << "mile" << "km");
m_width = nmDataAttribute("Width", 0.00328084, "m", UNIT_TYPE_LENGTH, QStringList(), QStringList() << "ft" << "m" << "cm" << "mm" << "in" << "0.1 in" << "mile" << "km");
m_fractureAngle = nmDataAttribute("Fracture angle", 90.0000, "o", UNIT_TYPE_ANGLE, QStringList(), QStringList() << "o" << "radian");
m_stimulatedZonesAroundFracture = nmDataAttribute("Stimulated zones around fracture", "true", "", UNIT_TYPE_DIMENSIONLESS, QStringList(), QStringList());
m_stimulationRadius = nmDataAttribute("Stimulation radius", 30.0000, "m", UNIT_TYPE_LENGTH, QStringList(), QStringList() << "ft" << "m" << "cm" << "mm" << "in" << "0.1 in" << "mile" << "km");
m_permeabilityMultiplier = nmDataAttribute("Permeability multiplier", 5.000000, "", UNIT_TYPE_DIMENSIONLESS, QStringList(), QStringList());
m_porosityMultiplier = nmDataAttribute("Porosity multiplier", 5.00000, "", UNIT_TYPE_DIMENSIONLESS, QStringList(), QStringList());
// 多段压裂水平井
m_eWellType = NM_WELL_MODEL::Horizontal_Fractured_Well;
// 释放所有射孔段对象
qDeleteAll(m_vecPerforations);
m_vecPerforations.clear();
// 重新定义属于多段压裂水平井的第一条射孔段
nmDataPerforation* defaultPerforation = new nmDataPerforation();
defaultPerforation->getMdStart().setValue(m_bottomholeMD.getValue().toDouble() + 150.0);
defaultPerforation->getMdEnd().setValue(m_bottomholeMD.getValue().toDouble() + m_wellLength.getValue().toDouble() + 150.0);
m_vecPerforations.append(defaultPerforation); // 添加指针
this->connectAttributeSignals();
}
// 拷贝构造函数
nmDataHorizontalFracturedWell::nmDataHorizontalFracturedWell(const nmDataHorizontalFracturedWell& other)
: nmDataHorizontalWell(other)
{
*this = other; // 使用赋值运算符实现
this->connectAttributeSignals();
}
// 赋值运算符
nmDataHorizontalFracturedWell& nmDataHorizontalFracturedWell::operator=(const nmDataHorizontalFracturedWell& other) {
if (this != &other) {
nmDataHorizontalWell::operator=(other);
m_modelingType = other.m_modelingType;
m_fractureModel = other.m_fractureModel;
m_dFc = other.m_dFc;
m_numberOfFractures = other.m_numberOfFractures;
m_fractureHalfLength = other.m_fractureHalfLength;
m_fractureHeight = other.m_fractureHeight;
m_fractureMidPointHeight = other.m_fractureMidPointHeight;
m_width = other.m_width;
m_fractureAngle = other.m_fractureAngle;
m_stimulatedZonesAroundFracture = other.m_stimulatedZonesAroundFracture;
m_stimulationRadius = other.m_stimulationRadius;
m_permeabilityMultiplier = other.m_permeabilityMultiplier;
m_porosityMultiplier = other.m_porosityMultiplier;
m_vecFracs = other.m_vecFracs;
m_fractureMds = other.m_fractureMds;
}
return *this;
}
nmDataWellBase* nmDataHorizontalFracturedWell::clone() const {
return new nmDataHorizontalFracturedWell(*this);
}
// 序列化 nmDataHorizontalFracturedWell 为 RapidJSON Value
rapidjson::Value nmDataHorizontalFracturedWell::ToJsonValue(rapidjson::Document::AllocatorType& allocator) const
{
// 序列化水平井参数
rapidjson::Value horizontalFractureWellObject = nmDataHorizontalWell::ToJsonValue(allocator);
// 序列化 nmDataAttribute 类型的成员
// 调用 nmDataAttribute 自身的 ToJsonValue 方法进行递归序列化
horizontalFractureWellObject.AddMember("ModelingType", m_modelingType.ToJsonValue(allocator), allocator);
horizontalFractureWellObject.AddMember("FractureModel", m_fractureModel.ToJsonValue(allocator), allocator);
horizontalFractureWellObject.AddMember("dFc", m_dFc.ToJsonValue(allocator), allocator);
horizontalFractureWellObject.AddMember("NumberOfFractures", m_numberOfFractures.ToJsonValue(allocator), allocator);
horizontalFractureWellObject.AddMember("FractureHalfLength", m_fractureHalfLength.ToJsonValue(allocator), allocator);
horizontalFractureWellObject.AddMember("FractureHeight", m_fractureHeight.ToJsonValue(allocator), allocator);
horizontalFractureWellObject.AddMember("FractureMidPointHeight", m_fractureMidPointHeight.ToJsonValue(allocator), allocator);
horizontalFractureWellObject.AddMember("Width", m_width.ToJsonValue(allocator), allocator);
horizontalFractureWellObject.AddMember("FractureAngle", m_fractureAngle.ToJsonValue(allocator), allocator);
horizontalFractureWellObject.AddMember("StimulatedZonesAroundFracture", m_stimulatedZonesAroundFracture.ToJsonValue(allocator), allocator);
horizontalFractureWellObject.AddMember("StimulationRadius", m_stimulationRadius.ToJsonValue(allocator), allocator);
horizontalFractureWellObject.AddMember("PermeabilityMultiplier", m_permeabilityMultiplier.ToJsonValue(allocator), allocator);
horizontalFractureWellObject.AddMember("PorosityMultiplier", m_porosityMultiplier.ToJsonValue(allocator), allocator);
return horizontalFractureWellObject; // 返回序列化后的 RapidJSON Value
}
// 从 RapidJSON Value 反序列化数据到 nmDataHorizontalFracturedWell
void nmDataHorizontalFracturedWell::FromJsonValue(const rapidjson::Value& jsonValue)
{
// 反序列化水平井参数
nmDataHorizontalWell::FromJsonValue(jsonValue);
// 反序列化 nmDataAttribute 类型的成员
// 调用 nmDataAttribute 自身的 FromJsonValue 方法进行递归反序列化
if (jsonValue.HasMember("ModelingType") && jsonValue["ModelingType"].IsObject()) {
m_modelingType.FromJsonValue(jsonValue["ModelingType"]);
}
if (jsonValue.HasMember("FractureModel") && jsonValue["FractureModel"].IsObject()) {
m_fractureModel.FromJsonValue(jsonValue["FractureModel"]);
}
if (jsonValue.HasMember("dFc") && jsonValue["dFc"].IsObject()) {
m_dFc.FromJsonValue(jsonValue["dFc"]);
}
if (jsonValue.HasMember("NumberOfFractures") && jsonValue["NumberOfFractures"].IsObject()) {
m_numberOfFractures.FromJsonValue(jsonValue["NumberOfFractures"]);
}
if (jsonValue.HasMember("FractureHalfLength") && jsonValue["FractureHalfLength"].IsObject()) {
m_fractureHalfLength.FromJsonValue(jsonValue["FractureHalfLength"]);
}
if (jsonValue.HasMember("FractureHeight") && jsonValue["FractureHeight"].IsObject()) {
m_fractureHeight.FromJsonValue(jsonValue["FractureHeight"]);
}
if (jsonValue.HasMember("FractureMidPointHeight") && jsonValue["FractureMidPointHeight"].IsObject()) {
m_fractureMidPointHeight.FromJsonValue(jsonValue["FractureMidPointHeight"]);
}
if (jsonValue.HasMember("Width") && jsonValue["Width"].IsObject()) {
m_width.FromJsonValue(jsonValue["Width"]);
}
if (jsonValue.HasMember("FractureAngle") && jsonValue["FractureAngle"].IsObject()) {
m_fractureAngle.FromJsonValue(jsonValue["FractureAngle"]);
}
if (jsonValue.HasMember("StimulatedZonesAroundFracture") && jsonValue["StimulatedZonesAroundFracture"].IsObject()) {
m_stimulatedZonesAroundFracture.FromJsonValue(jsonValue["StimulatedZonesAroundFracture"]);
}
if (jsonValue.HasMember("StimulationRadius") && jsonValue["StimulationRadius"].IsObject()) {
m_stimulationRadius.FromJsonValue(jsonValue["StimulationRadius"]);
}
if (jsonValue.HasMember("PermeabilityMultiplier") && jsonValue["PermeabilityMultiplier"].IsObject()) {
m_permeabilityMultiplier.FromJsonValue(jsonValue["PermeabilityMultiplier"]);
}
if (jsonValue.HasMember("PorosityMultiplier") && jsonValue["PorosityMultiplier"].IsObject()) {
m_porosityMultiplier.FromJsonValue(jsonValue["PorosityMultiplier"]);
}
// 计算裂缝相关信息
this->setFracs();
}
void nmDataHorizontalFracturedWell::connectAttributeSignals() {
// 基础井位置
connect(&this->getX(), SIGNAL(sigValueChanged()), this, SLOT(onFractureAttributeChanged()));
connect(&this->getY(), SIGNAL(sigValueChanged()), this, SLOT(onFractureAttributeChanged()));
connect(&this->getWellLength(), SIGNAL(sigValueChanged()), this, SLOT(onFractureAttributeChanged()));
connect(&this->getDrainAngle(), SIGNAL(sigValueChanged()), this, SLOT(onFractureAttributeChanged()));
// 多段压裂水平井属性
connect(&m_modelingType, SIGNAL(sigValueChanged()), this, SIGNAL(sigWellDataChanged()));
connect(&m_fractureModel, SIGNAL(sigValueChanged()), this, SIGNAL(sigWellDataChanged()));
connect(&m_dFc, SIGNAL(sigValueChanged()), this, SIGNAL(sigWellDataChanged()));
connect(&m_numberOfFractures, SIGNAL(sigValueChanged()), this, SLOT(onFractureAttributeChanged()));
connect(&m_fractureHalfLength, SIGNAL(sigValueChanged()), this, SLOT(onFractureAttributeChanged()));
connect(&m_fractureHeight, SIGNAL(sigValueChanged()), this, SLOT(onFractureAttributeChanged()));
connect(&m_fractureMidPointHeight, SIGNAL(sigValueChanged()), this, SLOT(onFractureAttributeChanged()));
connect(&m_width, SIGNAL(sigValueChanged()), this, SLOT(onFractureAttributeChanged()));
connect(&m_fractureAngle, SIGNAL(sigValueChanged()), this, SLOT(onFractureAttributeChanged()));
connect(&m_stimulatedZonesAroundFracture, SIGNAL(sigValueChanged()), this, SIGNAL(sigWellDataChanged()));
connect(&m_stimulationRadius, SIGNAL(sigValueChanged()), this, SIGNAL(sigWellDataChanged()));
connect(&m_permeabilityMultiplier, SIGNAL(sigValueChanged()), this, SIGNAL(sigWellDataChanged()));
connect(&m_porosityMultiplier, SIGNAL(sigValueChanged()), this, SIGNAL(sigWellDataChanged()));
}
void nmDataHorizontalFracturedWell::getPerforationAllowedMdRange(nmDataPerforation* pPerfToValidate,
double& dUpperAllowedMd,
double& dLowerAllowedMd)
{
// 直接调用父类的实现
nmDataHorizontalWell::getPerforationAllowedMdRange(pPerfToValidate, dUpperAllowedMd, dLowerAllowedMd);
}
void nmDataHorizontalFracturedWell::onFractureAttributeChanged() {
this->setFracs(); // 重新计算裂缝点
emit sigWellDataChanged(); // 发送井数据改变的通用信号
}
void nmDataHorizontalFracturedWell::setModelingType(const nmDataAttribute& attr) {
m_modelingType = attr;
}
void nmDataHorizontalFracturedWell::setFractureModel(const nmDataAttribute& attr) {
m_fractureModel = attr;
}
void nmDataHorizontalFracturedWell::setNumberOfFractures(const nmDataAttribute& attr) {
m_numberOfFractures = attr;
}
void nmDataHorizontalFracturedWell::setFractureHalfLength(const nmDataAttribute& attr) {
m_fractureHalfLength = attr;
}
void nmDataHorizontalFracturedWell::setFractureHeight(const nmDataAttribute& attr) {
m_fractureHeight = attr;
}
void nmDataHorizontalFracturedWell::setFractureMidPointHeight(const nmDataAttribute& attr) {
m_fractureMidPointHeight = attr;
}
void nmDataHorizontalFracturedWell::setWidth(const nmDataAttribute& attr) {
m_width = attr;
}
void nmDataHorizontalFracturedWell::setFractureAngle(const nmDataAttribute& attr) {
m_fractureAngle = attr;
}
void nmDataHorizontalFracturedWell::setStimulatedZonesAroundFracture(const nmDataAttribute& attr) {
m_stimulatedZonesAroundFracture = attr;
}
void nmDataHorizontalFracturedWell::setStimulationRadius(const nmDataAttribute& attr) {
m_stimulationRadius = attr;
}
void nmDataHorizontalFracturedWell::setPermeabilityMultiplier(const nmDataAttribute& attr) {
m_permeabilityMultiplier = attr;
}
void nmDataHorizontalFracturedWell::setPorosityMultiplier(const nmDataAttribute& attr) {
m_porosityMultiplier = attr;
}
void nmDataHorizontalFracturedWell::setFracs() {
m_vecFracs.clear(); // 清空旧的俯视图裂缝数据
m_fractureMds.clear(); // 清空旧的裂缝测深数据
QVector<QPair<QPointF, QPointF>> vecFractures;
// 井的位置
double wellX = this->getX().getValue().toDouble();
double wellY = this->getY().getValue().toDouble();
// 获取裂缝半长
double halfLength = this->getFractureHalfLength().getValue().toDouble();
// 获取裂缝数量
int fracturedNum = this->getNumberOfFractures().getValue().toInt();
// 获取井长
double wellLength = this->getWellLength().getValue().toDouble(); // 确保这里获取的是 double 值
// 获取井的排水角度与X轴的夹角通常是度
double drainAngleDegrees = this->getDrainAngle().getValue().toDouble();
// 将井的排水角度从度转换为弧度
double drainAngleRad = drainAngleDegrees * M_PI / 180.0; // 使用标准的 M_PI 常量
// 获取裂缝相对于井筒的“相对角度”(度)
// 根据你的图片,这个角度是裂缝与井筒轴线的夹角。
double dFractureRelativeAngleDegrees = this->getFractureAngle().getValue().toDouble();
// 将裂缝的相对角度从度转换为弧度
double fractureRelativeAngleRad = dFractureRelativeAngleDegrees * M_PI / 180.0;
// 确保至少有两个裂缝(端点的两个)
if (fracturedNum < 2) {
fracturedNum = 2;
}
// 计算相邻裂缝之间的间隔比例
double intervalRatio = 1.0 / (fracturedNum - 1);
// 绘制裂缝
for (int i = 0; i < fracturedNum; ++i) {
// 计算当前裂缝交点在井线上的测深(裂缝到井口的距离)
double currentFractureMD = i * intervalRatio * wellLength;
m_fractureMds.append(currentFractureMD + wellX); // 将MD存储起来这里需要考虑井口起点
// 计算裂缝中心点在世界坐标系中的X, Y 坐标
// 裂缝中心点沿着井筒方向延伸
double fracCenterX = wellX + currentFractureMD * cos(drainAngleRad);
double fracCenterY = wellY + currentFractureMD * sin(drainAngleRad);
// 计算裂缝在世界坐标系中的**绝对角度**(弧度)
// 现在,绝对角度就是井筒方向加上裂缝的相对角度
double fractureAbsoluteAngleRad = drainAngleRad + fractureRelativeAngleRad;
// 计算裂缝端点的偏移量
double dx_frac = halfLength * cos(fractureAbsoluteAngleRad);
double dy_frac = halfLength * sin(fractureAbsoluteAngleRad);
// 计算裂缝的两点坐标
QPointF startPoint(fracCenterX - dx_frac, fracCenterY - dy_frac);
QPointF endPoint(fracCenterX + dx_frac, fracCenterY + dy_frac);
QPair<QPointF, QPointF> frac;
frac.first = startPoint;
frac.second = endPoint;
vecFractures.push_back(frac);
}
m_vecFracs = vecFractures;
}
nmDataAttribute& nmDataHorizontalFracturedWell::getModelingType() {
return m_modelingType;
}
nmDataAttribute& nmDataHorizontalFracturedWell::getFractureModel() {
return m_fractureModel;
}
nmDataAttribute& nmDataHorizontalFracturedWell::getNumberOfFractures() {
return m_numberOfFractures;
}
nmDataAttribute& nmDataHorizontalFracturedWell::getFractureHalfLength() {
return m_fractureHalfLength;
}
nmDataAttribute& nmDataHorizontalFracturedWell::getFractureHeight() {
return m_fractureHeight;
}
nmDataAttribute& nmDataHorizontalFracturedWell::getFractureMidPointHeight() {
return m_fractureMidPointHeight;
}
nmDataAttribute& nmDataHorizontalFracturedWell::getWidth() {
return m_width;
}
nmDataAttribute& nmDataHorizontalFracturedWell::getFractureAngle() {
return m_fractureAngle;
}
nmDataAttribute& nmDataHorizontalFracturedWell::getStimulatedZonesAroundFracture() {
return m_stimulatedZonesAroundFracture;
}
nmDataAttribute& nmDataHorizontalFracturedWell::getStimulationRadius() {
return m_stimulationRadius;
}
nmDataAttribute& nmDataHorizontalFracturedWell::getPermeabilityMultiplier() {
return m_permeabilityMultiplier;
}
nmDataAttribute& nmDataHorizontalFracturedWell::getPorosityMultiplier() {
return m_porosityMultiplier;
}
void nmDataHorizontalFracturedWell::setDfc(const nmDataAttribute& attr) {
m_dFc = attr;
}
nmDataAttribute& nmDataHorizontalFracturedWell::getDfc() {
return m_dFc;
}
QVector<QPair<QPointF, QPointF>>& nmDataHorizontalFracturedWell::getFracs(){
return m_vecFracs;
}
// 新增:获取裂缝测深列表的实现
QVector<double> nmDataHorizontalFracturedWell::getFractureMds() const {
return m_fractureMds;
}