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/Include/nmNum/nmCalculation/nmPebiGridDiagnostics.h

76 lines
4.4 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.

#ifndef NM_PEBI_GRID_DIAGNOSTICS_H
#define NM_PEBI_GRID_DIAGNOSTICS_H
#include "pch.h"
#include <QCoreApplication>
#include <QString>
#include <QtCore/qnumeric.h>
// 网格失败提示辅助函数:检查输入并生成可翻译的简短原因,不修改输入、不写日志。
// 调用方负责将返回的原因交给框架日志或界面显示。
namespace nmPebiGridDiagnostics {
// 翻译用户可见提示;原文仍保留翻译标记,便于更新中英文语言文件。
inline QString text(const char* source)
{
// 本文件不是 QObject 类,用固定翻译上下文与界面的 tr() 保持相同翻译机制。
// 调用处用 QT_TRANSLATE_NOOP 标记原文,供 Qt 4.8 的 lupdate 提取;本函数负责运行时翻译。
return QCoreApplication::translate("nmPebiGridDiagnostics", source);
}
// 保留双精度数值的有效信息,避免很小的井半径在提示中被格式化成零。
inline QString number(double value)
{
return QString::number(value, 'g', 17);
}
// 只拦截可以确定无效的输入,不人为规定“井半径必须大于 0.1 m”。
// 同一真实井径可能因坐标量级、网格尺度不同而成功或失败,不能擅自修改物理参数。
// 返回首个发现的问题;空字符串仅表示通过这些基础检查,不保证算法一定成功。
inline QString validate(const HX_NWTM_GRID_INPUT& input)
{
// 先检查网格维数和尺度,避免将不支持的维数或无效步长传给算法库。
if(input.D != 2)
return text(QT_TRANSLATE_NOOP("nmPebiGridDiagnostics", "Only two-dimensional grid input is supported."));
if(!qIsFinite(input.GridControl) || input.GridControl <= 0.0)
return text(QT_TRANSLATE_NOOP("nmPebiGridDiagnostics", "Grid spacing must be finite and greater than zero (current value: %1)."))
.arg(number(input.GridControl));
if(input.Boundary.size() < 3)
return text(QT_TRANSLATE_NOOP("nmPebiGridDiagnostics", "The boundary must contain at least three edges."));
// 每条边至少包含起点和终点的平面坐标;这里不检查整个边界是否闭合或自交。
for(size_t i = 0; i < input.Boundary.size(); ++i) {
const dVec1& edge = input.Boundary[i];
if(edge.size() < 4 || !qIsFinite(edge[0]) || !qIsFinite(edge[1]) ||
!qIsFinite(edge[2]) || !qIsFinite(edge[3]))
return text(QT_TRANSLATE_NOOP("nmPebiGridDiagnostics", "Boundary edge %1 has missing or non-finite coordinates.")).arg(i + 1);
// 捕获边界时当前程序会对坐标取整,原本相邻的点也可能因此重合。
if(edge[0] == edge[2] && edge[1] == edge[3])
return text(QT_TRANSLATE_NOOP("nmPebiGridDiagnostics", "Boundary edge %1 has zero length. Check coincident points and coordinate rounding.")).arg(i + 1);
}
// 直井数据前三项依次为横坐标、纵坐标、井半径;与算法库约定一致,单位为米。
for(size_t i = 0; i < input.VerticalWell.size(); ++i) {
const dVec1& well = input.VerticalWell[i];
if(well.size() < 3 || !qIsFinite(well[0]) || !qIsFinite(well[1]) || !qIsFinite(well[2]))
return text(QT_TRANSLATE_NOOP("nmPebiGridDiagnostics", "Vertical well %1 has missing or non-finite coordinates/radius.")).arg(i + 1);
if(well[2] <= 0.0)
return text(QT_TRANSLATE_NOOP("nmPebiGridDiagnostics", "Vertical well %1 has invalid radius %2 m; it must be greater than zero."))
.arg(i + 1).arg(number(well[2]));
// 这里判断实际浮点分辨能力:加上半径仍得到同一坐标,才能确定半径无法表达。
// 普通正井径即使偏小也允许提交 DLL,避免把算法敏感性误判为输入错误。
if(well[0] + well[2] == well[0] || well[1] + well[2] == well[1])
return text(QT_TRANSLATE_NOOP("nmPebiGridDiagnostics", "Vertical well %1: radius %2 m is too small to represent at coordinates (%3, %4) m."))
.arg(i + 1).arg(number(well[2])).arg(number(well[0])).arg(number(well[1]));
}
return QString();
}
// 算法失败且无法确定根因时附加通用建议,不把建议当成已经确认的失败原因。
inline QString failureHint()
{
// DLL 没有给出具体原因时,只提供排查方向,不将小井径直接判定为错误。
return text(QT_TRANSLATE_NOOP("nmPebiGridDiagnostics", "Check whether the well radius is too small, and check grid spacing and geometry positions."));
}
}
#endif