#ifndef NMCALCULATIONAUTOFITLM_H #define NMCALCULATIONAUTOFITLM_H #include #include #include #include #include #include #include #include "nmCalculation_global.h" class nmDataWellBase; // 双对数曲线误差分解。total 是 LM 候选接受和排序的唯一依据, // 其余诊断量用于有限差分灵敏度分析和信赖域选参。 struct AutoFitObjectiveBreakdownLM { bool valid; double total; double pressureLoss; double derivativeLoss; QVector residualVector; double verticalCommonBias; double verticalLoss; bool verticalReliable; double horizontalPhysicalShift; double horizontalLoss; bool horizontalReliable; bool registrationAmbiguous; double shapeLoss; double lateDerivativeSlopeBias; double lateDerivativeTrendLoss; bool lateDerivativeTrendReliable; double coverage; AutoFitObjectiveBreakdownLM() : valid(false) , total(1.0e10) , pressureLoss(std::numeric_limits::quiet_NaN()) , derivativeLoss(std::numeric_limits::quiet_NaN()) , verticalCommonBias(std::numeric_limits::quiet_NaN()) , verticalLoss(std::numeric_limits::quiet_NaN()) , verticalReliable(false) , horizontalPhysicalShift(std::numeric_limits::quiet_NaN()) , horizontalLoss(std::numeric_limits::quiet_NaN()) , horizontalReliable(false) , registrationAmbiguous(false) , shapeLoss(std::numeric_limits::quiet_NaN()) , lateDerivativeSlopeBias(std::numeric_limits::quiet_NaN()) , lateDerivativeTrendLoss(std::numeric_limits::quiet_NaN()) , lateDerivativeTrendReliable(false) , coverage(std::numeric_limits::quiet_NaN()) {} }; // 有限差分 + LM/信赖域拟合的停止原因。 enum StopReasonLM { LM_CONTINUE_OPTIMIZATION = 0, LM_TARGET_ACHIEVED = 1, LM_TRUE_CONVERGENCE = 2, LM_LOCAL_OPTIMUM = 3, LM_MAX_ITERATIONS = 4, LM_USER_STOPPED = 5, LM_CONSECUTIVE_FAILURES = 6, LM_OPTIMIZATION_FAILED = 7 }; class NMCALCULATION_EXPORT nmCalculationAutoFitLM : public QObject { Q_OBJECT public: explicit nmCalculationAutoFitLM(QObject* parent = 0); ~nmCalculationAutoFitLM(); void setTargetLogLogData(const QVector >& targetData); bool startAutoFitting(); void stopFitting(); QVector getBestSolution() const; double getBestFitness() const; AutoFitObjectiveBreakdownLM getLastObjectiveBreakdown() const; QString getLastError() const; bool isRunning() const; int getCurrentIteration() const; int getTotalEvaluations() const; void resetOptimizer(); void setTargetWellName(const QString& wellName); signals: void progressUpdated(int iteration, double bestFitness); void fittingFinished(bool success, const QString& message); void bestCurveUpdated(QVector > targetData, QVector > bestData, int iteration, double fitness); void logMessageGenerated(const QString& message); private: void initializeTemporaryDirectory(); void cleanupTemporaryDirectory(); bool removeDirectoryRecursively(const QString& path); void cleanupOldTemporaryDirectories(); bool loadAllConfigFromDataManager(); void loadOptimizationConfig(); void loadParameterBounds(); void extractUserInitialValues(); // 有限差分 + LM/信赖域核心算法。 StopReasonLM runTrustRegionFitting(); bool evaluateTrustRegionPoint(const QVector& parameters, double* fitness, AutoFitObjectiveBreakdownLM* breakdown, QVector >* curve, int* elapsedMs); double evaluateFitness(const QVector& parameters); void applyParametersToDataManager(const QVector& parameters); void updateReservoirParameters(const QVector& parameters); void updateWellParameters(const QVector& parameters); void updateWellToDataManager(nmDataWellBase* pWell); QVector > runSolver(); QVector > runSolverDll(); bool runFinalFullSolver(); void saveOptimizationResult(); void validateAndProtectFinalResult(); QString getStopReasonDescription(StopReasonLM reason) const; int getEnabledParameterCount() const; // LM 运行轨迹。 void initializeTraceFile(); void closeTraceFile(); void writeTraceHeader(); void writeTraceMetaFile(); void writeTraceRow(int iteration, int parameterIndex, const QString& phase, const QVector& parameters, double solverObjective, bool solverSuccess, int elapsedMs, const QString& decision, const AutoFitObjectiveBreakdownLM* objectiveBreakdown = nullptr); QVector buildTraceParameterVector(const QVector& selectedParameters) const; void emitRunSummary(bool success, StopReasonLM finalReason); bool validateParameters(const QVector& parameters) const; bool validateLogLogData(const QVector >& logLogData) const; bool validateInitialValues() const; bool validateSolverResult(const QVector >& result) const; double calculateLogLogCurveError(const QVector >& target, const QVector >& result) const; private: bool m_isRunning; bool m_shouldStop; int m_currentIteration; QString m_lastError; QVector m_initialValues; QVector m_globalBestPosition; double m_globalBestFitness; AutoFitObjectiveBreakdownLM m_globalBestObjectiveBreakdown; QVector > m_lastEvaluatedLogLogData; QVector > m_globalBestLogLogData; mutable AutoFitObjectiveBreakdownLM m_lastObjectiveBreakdown; QVector > m_userInitialLogLogData; AutoFitObjectiveBreakdownLM m_userInitialObjectiveBreakdown; // 参数索引:0 k,1 skin,2 wellboreC,3 phi,4 h,5 Ct, // 6 Cf,7 Swi,8 Dfc,9 fractureHalfLength。 QVector m_parameterSelected; QVector m_parameterLower; QVector m_parameterUpper; QVector m_enabledParamIndices; QVector > m_targetLogLogData; QString m_targetWellName; int m_maxIterations; double m_targetError; int m_totalEvaluations; int m_successfulEvaluations; volatile int m_evaluationInProgress; int m_consecutiveFailures; int m_maxConsecutiveFailures; QVector m_userInitialSolution; double m_userInitialFitness; bool m_hasValidUserSolution; QString m_tempDirectory; QString m_traceRunId; QString m_traceFilePath; QString m_traceMetaFilePath; QFile m_traceFile; }; #endif // NMCALCULATIONAUTOFITLM_H