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++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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;
}