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/nmDataVerticalFracturedWell...

276 lines
12 KiB
C++

#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<nmDataPerforation*>& 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<QPointF> 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<QPointF> nmDataVerticalFracturedWell::getFracs() const {
return m_vecFracs;
}