@ -1212,9 +1212,9 @@ void nmCalculationAutoFitLM::writeTraceMetaFile()
QTextStream out ( & metaFile ) ;
out < < " { \n " ;
out < < " \" schema_version \" : 29 ,\n " ;
out < < " \" schema_version \" : 30 ,\n " ;
out < < " \" strategy \" : \" permeability_height_then_shape_then_joint_lm \" , \n " ;
out < < " \" height_acceptance \" : \" reliable_vertical_loss_decrease; no_shape_ loss_constraint\" , \n " ;
out < < " \" height_acceptance \" : \" reliable_vertical_loss_decrease; no_shape_ or_total_ loss_constraint\" , \n " ;
out < < " \" shape_priority \" : \" storage_then_skin_then_shape_without_wellbore_then_optional_wellbore_recheck \" , \n " ;
out < < " \" shape_metric \" : \" pressure_and_derivative_log_slopes_81_points_lag_8 \" , \n " ;
out < < " \" early_parallel_metric \" : \" pressure_and_derivative_log_slopes_first_window_81_points_lag_8 \" , \n " ;
@ -1225,7 +1225,7 @@ void nmCalculationAutoFitLM::writeTraceMetaFile()
out < < " \" early_initial_expansion_policy \" : \" before_first_accepted_shape_improvement; if_shape_worsens_double_coordinate_step_from_unchanged_base_up_to_parameter_bound; retain_base_on_failure \" , \n " ;
out < < " \" early_wellbore_acceptance \" : \" locked_gap_direction_and_early_shape_decrease \" , \n " ;
out < < " \" early_wellbore_total_constraint \" : false, \n " ;
out < < " \" shape_stage_total_ tolerance\" : \" max(0.02, 25% of stage entry total) \" ,\n " ;
out < < " \" shape_stage_total_ constraint\" : false ,\n " ;
out < < " \" shape_wellbore_parameters_frozen \" : true, \n " ;
out < < " \" shape_sensitivity_refresh \" : \" full Jacobian at joint shape entry and stagnation confirmation \" , \n " ;
out < < " \" shape_expansion_policy \" : \" one expansion per reliable shape direction, up to 2x when actual rho exceeds 0.75; retain ordinary step on failure \" , \n " ;
@ -1234,7 +1234,7 @@ void nmCalculationAutoFitLM::writeTraceMetaFile()
out < < " \" shape_round_improvement_threshold \" : \" max(0.0001, 1% of round entry shape loss) \" , \n " ;
out < < " \" iteration_count_scope \" : \" max_iterations applies to total-stage LM; trace iteration remains cumulative \" , \n " ;
out < < " \" wellbore_recheck_trigger \" : \" early loss exceeds initial early-stage exit by max(0.0001, 10%) \" , \n " ;
out < < " \" wellbore_recheck_acceptance \" : \" early decrease with fixed entry total and shape limits, each max(0.0001, 5%)\" , \n " ;
out < < " \" wellbore_recheck_acceptance \" : \" early decrease with fixed entry shape limit max(0.0001, 5%); no_total_loss_constraint \" , \n " ;
out < < " \" wellbore_recheck_budget \" : \" once when early shape degrades; each wellbore parameter stops after 2 ineffective steps, independent of total-stage budget \" , \n " ;
out < < " \" total_stage_shape_constraint \" : false, \n " ;
out < < " \" total_parameter_selection \" : \" all_valid_free_columns \" , \n " ;
@ -2154,7 +2154,7 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting()
int heightStagnation = 0 ;
double heightScale = 1.0 ;
double heightSlope = - 1.0 ;
if ( permeabilityColumn > = 0 & & current . fitness > = m_targetError ) {
if ( permeabilityColumn > = 0 ) {
emit logMessageGenerated ( tr ( " LM stage 1: align curve height using permeability only (up to %1 evaluations). " )
. arg ( heightBudget ) ) ;
for ( int trial = 0 ; trial < heightBudget & & processPauseAndStop ( ) ; + + trial ) {
@ -2211,9 +2211,8 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting()
if ( m_shouldStop ) return LM_USER_STOPPED ;
// 第二阶段不按迭代比例截断;普通形状按完整搜索轮次判断是否仍有显著改善。
// 井储、表皮保持冻结,总误差上限仍固定于普通形状阶段入口。
bool shapeStage = current . fitness > = m_targetError ;
double shapeValueLimit = current . fitness + qMax ( 0.02 , 0.25 * current . fitness ) ;
// 普通形状调整冻结井储、表皮,只按形状验收;总误差达标只在第三阶段判断。
bool shapeStage = true ;
bool jointShapeStarted = false ;
double shapeRoundBaseline = current . breakdown . shapeLoss ;
int shapeRoundNumber = 0 ;
@ -2230,7 +2229,6 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting()
bool wellboreRecheck = false ;
bool wellboreRecheckDone = false ;
double earlyWellboreBaseline = current . breakdown . earlyParallelLoss ;
double recheckTotalLimit = 0.0 ;
double recheckShapeLimit = 0.0 ;
// 先井储、再表皮;回检沿用相同顺序和前期指标,不回到形状阶段反复循环。
bool earlyShapeStage = shapeStage & & wellboreParameterCount > 0 ;
@ -2270,11 +2268,10 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting()
const int column = m_enabledParamIndices . indexOf ( earlyShapeParameter ) ;
return earlyGapDirection * ( point . coordinates [ column ] - base . coordinates [ column ] ) > 0.0 & &
point . breakdown . earlyParallelLoss < base . breakdown . earlyParallelLoss & &
( ! wellboreRecheck | | ( point . fitness < = recheckTotalLimit & &
point . breakdown . shapeLoss < = recheckShapeLimit ) ) ;
( ! wellboreRecheck | | point . breakdown . shapeLoss < = recheckShapeLimit ) ;
}
return shapeStage
? point . breakdown . shapeLoss < base . breakdown . shapeLoss & & point . fitness < = shapeValueLimit
? point . breakdown . shapeLoss < base . breakdown . shapeLoss
// 预调整结束后恢复原 LM: 有效候选只按整体误差下降接受。
: point . fitness < base . fitness ;
} ;
@ -2408,7 +2405,7 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting()
initialEarlyGapBias = trustRegionEarlyGapBias ( current . breakdown ) ;
earlyGapDirection = trustRegionEarlyGapDirection ( initialEarlyGapBias ) ;
earlyShapeHasImproved = false ;
recheckTotalLimit = current . fitness + qMax ( 1.0e-4 , 0.05 * current . fitness ) ;
// 回检只约束形状:允许总误差上升,但保护其他参数已调好的整体形状。
recheckShapeLimit = current . breakdown . shapeLoss + qMax ( 1.0e-4 , 0.05 * current . breakdown . shapeLoss ) ;
effectiveImprovementBaseline = current . breakdown . earlyParallelLoss ;
// 其他参数已改变,回检入口重测形状灵敏度,方向由本轮初始间距重新确定。
@ -2416,9 +2413,9 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting()
reuseSensitivityForNextStage ( ) ;
rebuildRequested = true ;
rebuildReason = QT_TR_NOOP ( " new sensitivity for wellbore recheck " ) ;
emit logMessageGenerated ( tr ( " Wellbore recheck: early error=%1, total limit=%2, shape limit=%3 ." )
emit logMessageGenerated ( tr ( " Wellbore recheck: early shape error=%1, shape limit=%2 ." )
. arg ( current . breakdown . earlyParallelLoss , 0 , ' g ' , 6 )
. arg ( recheck TotalLimit, 0 , ' g ' , 6 ) . arg ( recheck ShapeLimit, 0 , ' g ' , 6 ) ) ;
. arg ( recheck ShapeLimit, 0 , ' g ' , 6 ) ) ;
writeTraceRow ( m_currentIteration , - 1 , " stage_switch " , current . parameters , current . fitness ,
true , 0 , " shape_to_wellbore_recheck " , & current . breakdown ) ;
announceEarlyGapDirection ( ) ;
@ -2451,8 +2448,6 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting()
return ;
}
effectiveImprovementBaseline = current . breakdown . shapeLoss ;
// 井储、表皮可使总误差上升;联合形状阶段从当前工作点建立固定上限。
shapeValueLimit = current . fitness + qMax ( 0.02 , 0.25 * current . fitness ) ;
reuseSensitivityForNextStage ( ) ;
emit logMessageGenerated ( tr ( " Shape fitting continues with storage and skin fixed; a conditional wellbore recheck follows. " ) ) ;
writeTraceRow ( m_currentIteration , - 1 , " stage_switch " , current . parameters , current . fitness ,
@ -2733,8 +2728,9 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting()
& current . breakdown ) ;
emit logMessageGenerated (
( earlyShapeStage ? tr ( " Sensitivity probe accepted: early shape error=%1 " )
: tr ( " Sensitivity probe accepted: total error=%1 " ) )
. arg ( earlyShapeStage ? current . breakdown . earlyParallelLoss : current . fitness , 0 , ' e ' , 4 ) ) ;
: ( shapeStage ? tr ( " Sensitivity probe accepted: shape error=%1 " )
: tr ( " Sensitivity probe accepted: total error=%1 " ) ) )
. arg ( stageError ( current ) , 0 , ' e ' , 4 ) ) ;
} else {
restoreEvaluationState ( current ) ;
}
@ -2819,11 +2815,6 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting()
: LM_LOCAL_OPTIMUM ;
break ;
}
if ( shapeStage & & ! earlyShapeStage & & current . fitness < m_targetError ) {
finishShapeStage ( tr ( " total target reached during shape fitting " ) ) ;
- - iteration ;
continue ;
}
if ( ! shapeStage & & current . fitness < m_targetError ) {
promoteSampling ( true ) ;
stopReason = LM_TARGET_ACHIEVED ;
@ -2956,37 +2947,6 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting()
: buildTrustRegionFisherStep ( stepInformation , columns , current . coordinates ,
damping , trustRadius , minimumCoordinateStep , & step , & reduction ) ;
if ( ! stepBuilt ) continue ;
// 仅联合形状阶段预测总误差上限;井储、表皮步长不受总误差裁剪。
if ( shapeStage & & ! earlyShapeStage ) {
auto predictedGuard = [ & ] ( double scale ) - > double {
double energy = 0.0 ;
for ( int row = 0 ; row < current . breakdown . residualVector . size ( ) ; + + row ) {
double value = current . breakdown . residualVector [ row ] ;
for ( int column = 0 ; column < dimensions ; + + column )
value + = scale * jacobian [ row ] [ column ] * step [ column ] ;
energy + = value * value ;
}
return qSqrt ( energy ) ;
} ;
const double currentGuard = predictedGuard ( 0.0 ) ;
const double predictedLimit = currentGuard + 0.9 * qMax ( 0.0 , shapeValueLimit - currentGuard ) ;
if ( predictedGuard ( 1.0 ) > predictedLimit ) {
double low = 0.0 , high = 1.0 ;
for ( int search = 0 ; search < 32 ; + + search ) {
const double middle = 0.5 * ( low + high ) ;
if ( predictedGuard ( middle ) < = predictedLimit ) low = middle ;
else high = middle ;
}
const double stepScale = low ;
for ( int column = 0 ; column < dimensions ; + + column ) step [ column ] * = stepScale ;
if ( qSqrt ( trustRegionSquaredNorm ( step ) ) < minimumCoordinateStep ) continue ;
reduction = - trustRegionDotProduct ( stepInformation . gradient , step ) ;
for ( int a = 0 ; a < dimensions ; + + a )
for ( int b = 0 ; b < dimensions ; + + b )
reduction - = 0.5 * step [ a ] * stepInformation . matrix [ a ] [ b ] * step [ b ] ;
if ( ! isFiniteNumber ( reduction ) | | reduction < = 1.0e-14 ) continue ;
}
}
const double tolerance = 1.0e-12 * qMax ( predictedReduction , reduction ) ;
if ( selectedColumns . isEmpty ( ) | | reduction > predictedReduction + tolerance | |
( qAbs ( reduction - predictedReduction ) < = tolerance & &
@ -3141,7 +3101,7 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting()
}
// 普通形状步真实表现可靠时,沿同一联合方向最多扩步试算一次,不区分参数类型。
// 扩步 仍须通过固定总误差上限且优于原步 ,否则保留原候选。
// 扩步 只按整体形状验收,优于原步才替换 ,否则保留原候选。
if ( shapeStage & & ! earlyShapeStage & & acceptable ( candidate , current ) & & processPauseAndStop ( ) ) {
const double ordinaryEnergy = 0.5 * trustRegionSquaredNorm ( objectiveResidual ) ;
const double ordinaryReduction = ordinaryEnergy - 0.5 * trustRegionSquaredNorm ( candidate . breakdown . shapeResiduals ) ;
@ -3286,7 +3246,7 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting()
. arg ( iteration + 1 )
. arg ( componentDisplayName )
. arg ( selectedColumns . size ( ) )
. arg ( earlyShapeStage ? candidate . breakdown . earlyParallelLoss : candidate . fitness , 0 , ' e ' , 4 )
. arg ( stageError( candidate ) , 0 , ' e ' , 4 )
. arg ( accepted ? tr ( " accepted " ) : tr ( " rejected " ) ) ) ;
emit progressUpdated ( shapeStage ? - 1 : totalIterations , m_globalBestFitness ) ;
@ -3306,9 +3266,6 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting()
if ( stopReason = = LM_LOCAL_OPTIMUM | | samplingRefreshFailed ) break ;
}
if ( shapeStage & & ! earlyShapeStage & & current . fitness < m_targetError ) {
finishShapeStage ( tr ( " total target reached during shape fitting " ) ) ;
}
if ( ! shapeStage & & current . fitness < m_targetError ) {
promoteSampling ( true ) ;
stopReason = LM_TARGET_ACHIEVED ;
@ -3337,7 +3294,7 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting()
return LM_USER_STOPPED ;
}
if ( samplingRefreshFailed ) return LM_OPTIMIZATION_FAILED ;
if ( current . fitness < m_targetError ) {
if ( ! shapeStage & & current . fitness < m_targetError ) {
promoteSampling ( true ) ;
return samplingRefreshFailed ? LM_OPTIMIZATION_FAILED : LM_TARGET_ACHIEVED ;
}