#include "nmDataVerticalFracturedWell.h" #include "ZxBaseUtil.h" #include "nmDataAnalyzeManager.h" #include "nmDataReservoir.h" nmDataVerticalFracturedWell::nmDataVerticalFracturedWell() : nmDataVerticalWell() { m_pReservoir = nmDataAnalyzeManager::getCurrentInstance()->getReservoirData(); m_fractureModel = nmDataAttribute("Fracture model", "Finite conductivity", "", UNIT_TYPE_DIMENSIONLESS, QStringList() << "Infinite conductivity", QStringList()); m_dFc = nmDataAttribute("dFc", 1000.0, "md.m", UNIT_TYPE_CONDUCTIVITY, QStringList(), QStringList() << "md.ft" << "md.m" << "m^3"); m_fractureHalfLength = nmDataAttribute("Fracture half length", 20.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() , "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", 0.0000, "o", UNIT_TYPE_ANGLE, QStringList(), QStringList() << "o" << "radian"); // 垂直裂缝井 m_eWellType = NM_WELL_MODEL::Vertical_Fractured_Well; this->connectAttributeSignals(); } // 拷贝构造函数 nmDataVerticalFracturedWell::nmDataVerticalFracturedWell(const nmDataVerticalFracturedWell& other) : nmDataVerticalWell(other) { *this = other; // 使用赋值运算符实现 this->connectAttributeSignals(); } // 赋值运算符 nmDataVerticalFracturedWell& nmDataVerticalFracturedWell::operator=(const nmDataVerticalFracturedWell& other) { if (this != &other) { nmDataVerticalWell::operator=(other); m_fractureModel = other.m_fractureModel; m_dFc = other.m_dFc; 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_vecFracs = other.m_vecFracs; } return *this; } nmDataWellBase* nmDataVerticalFracturedWell::clone() const { return new nmDataVerticalFracturedWell(*this); } // 序列化 nmDataVerticalFracturedWell 为 RapidJSON Value rapidjson::Value nmDataVerticalFracturedWell::ToJsonValue(rapidjson::Document::AllocatorType& allocator) const { // 序列化直井参数 rapidjson::Value verticalFractureWellObject = nmDataVerticalWell::ToJsonValue(allocator); // 序列化 nmDataAttribute 类型的成员 // 调用 nmDataAttribute 自身的 ToJsonValue 方法进行递归序列化 verticalFractureWellObject.AddMember("FractureModel", m_fractureModel.ToJsonValue(allocator), allocator); verticalFractureWellObject.AddMember("dFc", m_dFc.ToJsonValue(allocator), allocator); verticalFractureWellObject.AddMember("FractureHalfLength", m_fractureHalfLength.ToJsonValue(allocator), allocator); verticalFractureWellObject.AddMember("FractureHeight", m_fractureHeight.ToJsonValue(allocator), allocator); verticalFractureWellObject.AddMember("FractureMidPointHeight", m_fractureMidPointHeight.ToJsonValue(allocator), allocator); verticalFractureWellObject.AddMember("Width", m_width.ToJsonValue(allocator), allocator); verticalFractureWellObject.AddMember("FractureAngle", m_fractureAngle.ToJsonValue(allocator), allocator); return verticalFractureWellObject; // 返回序列化后的 RapidJSON Value } // 从 RapidJSON Value 反序列化数据到 nmDataVerticalFracturedWell void nmDataVerticalFracturedWell::FromJsonValue(const rapidjson::Value& jsonValue) { // 反序列化直井参数 nmDataVerticalWell::FromJsonValue(jsonValue); // 反序列化 nmDataAttribute 类型的成员 // 调用 nmDataAttribute 自身的 FromJsonValue 方法进行递归反序列化 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("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"]); } // 计算裂缝相关信息 this->setFracs(); } void nmDataVerticalFracturedWell::connectAttributeSignals() { // 基础井位置 connect(&this->getX(), SIGNAL(sigValueChanged()), this, SLOT(onFractureAttributeChanged())); connect(&this->getY(), SIGNAL(sigValueChanged()), this, SLOT(onFractureAttributeChanged())); // 垂直裂缝井属性 connect(&m_fractureModel, SIGNAL(sigValueChanged()), this, SIGNAL(sigWellDataChanged())); connect(&m_dFc, SIGNAL(sigValueChanged()), this, SIGNAL(sigWellDataChanged())); 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())); } void nmDataVerticalFracturedWell::getPerforationAllowedMdRange(nmDataPerforation* pPerfToValidate, double& dUpperAllowedMd, double& dLowerAllowedMd) { // 1. 获取裂缝和储层边界数据 double dFractureHeight = getFractureHeight().getValue().toDouble(); double dFractureMidPointHeight = getFractureMidPointHeight().getValue().toDouble(); // 从数据中心获取储层的最大底部MD double dMaxReservoirBottom = nmDataAnalyzeManager::getCurrentInstance()->getMaxLayerBottom(); // 根据你提供的逻辑,将相对高度转换为绝对MD值 // fractureMidPointMd = 储层底部MD - 裂缝中点高度 double dFractureMidPointMd = dMaxReservoirBottom - dFractureMidPointHeight; // 计算裂缝的上下MD范围 double dFractureTopMd = dFractureMidPointMd - dFractureHeight / 2.0; double dFractureBottomMd = dFractureMidPointMd + dFractureHeight / 2.0; // 初始化允许范围为裂缝的MD范围 dUpperAllowedMd = dFractureTopMd; dLowerAllowedMd = dFractureBottomMd; // 2. 获取当前正在操作的射孔段的当前MD值 double dCurrentPerfMdStart = pPerfToValidate->getMdStart().getValue().toDouble(); double dCurrentPerfMdEnd = pPerfToValidate->getMdEnd().getValue().toDouble(); // 3. 遍历所有射孔段,找到与当前射孔段相邻的上下边界 QVector& vecAllPerforations = getPerforations(); foreach(nmDataPerforation* pOtherPerf, vecAllPerforations) { if(pOtherPerf == pPerfToValidate) { continue; // 跳过当前正在操作的射孔段本身 } double dOtherStart = pOtherPerf->getMdStart().getValue().toDouble(); double dOtherEnd = pOtherPerf->getMdEnd().getValue().toDouble(); // 检查在当前射孔段上方的其他射孔段 // 如果 pOtherPerf 的结束MD 小于或等于当前射孔段的起始MD (考虑容差) if(dOtherEnd <= dCurrentPerfMdStart + DBL_EPSILON) { dUpperAllowedMd = std::max(dUpperAllowedMd, dOtherEnd); } // 检查在当前射孔段下方的其他射孔段 // 如果 pOtherPerf 的起始MD 大于或等于当前射孔段的结束MD (考虑容差) else if(dOtherStart >= dCurrentPerfMdEnd - DBL_EPSILON) { dLowerAllowedMd = std::min(dLowerAllowedMd, dOtherStart); } } // 4. 最后,确保计算出的范围不超出井筒的物理范围 double dWellboreTopMd = getBottomholeMD().getValue().toDouble(); double dWellboreBottomMd = dWellboreTopMd + getWellLength().getValue().toDouble(); dUpperAllowedMd = std::max(dUpperAllowedMd, dWellboreTopMd); dLowerAllowedMd = std::min(dLowerAllowedMd, dWellboreBottomMd); } void nmDataVerticalFracturedWell::onFractureAttributeChanged() { this->setFracs(); // 重新计算裂缝点 emit sigWellDataChanged(); // 发送井数据改变的通用信号 } void nmDataVerticalFracturedWell::setFractureModel(const nmDataAttribute& attr) { m_fractureModel = attr; } void nmDataVerticalFracturedWell::setFractureHalfLength(const nmDataAttribute& attr) { m_fractureHalfLength = attr; } void nmDataVerticalFracturedWell::setFractureHeight(const nmDataAttribute& attr) { m_fractureHeight = attr; } void nmDataVerticalFracturedWell::setFractureMidPointHeight(const nmDataAttribute& attr) { m_fractureMidPointHeight = attr; } void nmDataVerticalFracturedWell::setWidth(const nmDataAttribute& attr) { m_width = attr; } void nmDataVerticalFracturedWell::setFractureAngle(const nmDataAttribute& attr) { m_fractureAngle = attr; } nmDataAttribute& nmDataVerticalFracturedWell::getFractureModel() { return m_fractureModel; } nmDataAttribute& nmDataVerticalFracturedWell::getFractureHalfLength() { return m_fractureHalfLength; } nmDataAttribute& nmDataVerticalFracturedWell::getFractureHeight() { return m_fractureHeight; } nmDataAttribute& nmDataVerticalFracturedWell::getFractureMidPointHeight() { return m_fractureMidPointHeight; } nmDataAttribute& nmDataVerticalFracturedWell::getWidth() { return m_width; } nmDataAttribute& nmDataVerticalFracturedWell::getFractureAngle() { return m_fractureAngle; } void nmDataVerticalFracturedWell::setDfc(const nmDataAttribute& attr) { m_dFc = attr; } nmDataAttribute& nmDataVerticalFracturedWell::getDfc() { return m_dFc; } void nmDataVerticalFracturedWell::setFracs() { QVector vFracPoints; // 井的位置 double x = this->getX().getValue().toDouble(); double y = this->getY().getValue().toDouble(); // 获取裂缝半长 double halfLength = this->getFractureHalfLength().getValue().toDouble(); // 获取裂缝角度(单位:度) double fractureAngle = this->getFractureAngle().getValue().toDouble(); // 将角度从度转换为弧度 double angleRad = fractureAngle * M_PI / 180.0; // M_PI 是 π 的值,表示 180 度 // 计算裂缝的两点坐标 double leftX = x - halfLength * cos(angleRad); // 使用余弦计算水平分量 double leftY = y - halfLength * sin(angleRad); // 使用正弦计算垂直分量 double rightX = x + halfLength * cos(angleRad); double rightY = y + halfLength * sin(angleRad); QPointF leftP(leftX, leftY); QPointF rightP(rightX, rightY); vFracPoints.append(leftP); vFracPoints.append(rightP); m_vecFracs.clear(); m_vecFracs = vFracPoints; // 发送井数据改变信号 //emit sigWellDataChanged(); } QVector nmDataVerticalFracturedWell::getFracs() const { return m_vecFracs; }