2026-09-19 11:04:49 -04:00
#!/usr/bin/env python3
""" Summarize completed density-order audits without opening campaign artifacts.
The input is audit_density_order . py JSON with artifact_passed = true . Tables keep
zero , unavailable and uncertain observations distinct . Matplotlib is imported
only when a figure is requested ; - - self - test performs tiny arithmetic tests .
"""
from __future__ import annotations
import argparse
from collections import defaultdict
import csv
import hashlib
import json
import math
import os
from pathlib import Path
import unittest
def require ( condition , message ) :
if not condition :
raise ValueError ( message )
def finite ( value , label , nonnegative = False ) :
require ( isinstance ( value , ( int , float ) ) and not isinstance ( value , bool ) and math . isfinite ( value ) ,
" Missing/nonfinite " + label )
require ( not nonnegative or value > = 0 , " Negative " + label )
return value
def ratio ( numerator , denominator ) :
return numerator / denominator if numerator is not None and denominator not in ( None , 0 ) else None
def density_metrics ( case , key ) :
measure = case [ " measures " ] [ key ]
fine = measure [ " summary " ] [ " 30 " ]
error = case [ " unsliced_error_quadrature " ] [ key ]
q30 , q26 = error [ " 30 " ] , error [ " 26 " ]
for field in ( " negative_mass " , " negative_volume " , " negative_mass_fraction " , " negative_volume_fraction " ,
" negative_mass_uncertainty_scale " , " resolved_negative_intervals " , " uncertain_negative_intervals " ) :
finite ( fine [ field ] , field , True )
squared = q30 [ " eos_squared_integral " ]
if q30 [ " eos_defined_everywhere_sampled " ] :
finite ( squared , " q30 EOS squared integral " , True )
finite ( q30 [ " volume " ] , " q30 volume " , True )
require ( q30 [ " volume " ] > 0 , " Zero q30 volume " )
l2 , rms = math . sqrt ( squared ) , math . sqrt ( squared / q30 [ " volume " ] )
else :
require ( squared is None , " Undefined q30 EOS integral has a fabricated value " )
l2 = rms = None
if fine [ " negative_mass " ] == 0 :
classification = " zero_observed "
elif fine [ " resolved_negative_intervals " ] :
classification = " resolved_witnesses_present "
else :
classification = " uncertain_witnesses_only "
surface_h = measure [ " surface " ] . get ( " enthalpy " , { } )
witness_h = measure . get ( " negative_interval_witness_enthalpy " , { } )
return {
" negative_mass_over_abs_mass " : fine [ " negative_mass_fraction " ] ,
" negative_volume_fraction " : fine [ " negative_volume_fraction " ] ,
" negative_mass " : fine [ " negative_mass " ] , " mass_denominator " : abs ( finite ( fine [ " mass " ] , " mass " ) ) ,
" minimum_density_sliced " : finite ( fine [ " minimum_density " ] , " minimum density " ) ,
" negative_classification " : classification ,
" resolved_negative_intervals " : fine [ " resolved_negative_intervals " ] ,
" uncertain_negative_intervals " : fine [ " uncertain_negative_intervals " ] ,
" uncertain_negative_mass " : fine [ " uncertain_negative_mass " ] ,
" negative_mass_uncertainty_scale " : fine [ " negative_mass_uncertainty_scale " ] ,
" negative_mass_over_uncertainty_scale " : ratio ( fine [ " negative_mass " ] , fine [ " negative_mass_uncertainty_scale " ] ) ,
" negative_mass_q30_minus_q22 " : measure [ " negative_mass_q30_minus_q22 " ] ,
" negative_volume_q30_minus_q22 " : measure [ " negative_volume_q30_minus_q22 " ] ,
" eos_l2_q30 " : l2 , " eos_rms_q30 " : rms ,
" eos_squared_q26 " : q26 [ " eos_squared_integral " ] , " eos_squared_q30 " : squared ,
" eos_squared_q30_minus_q26 " : error [ " eos_squared_q30_minus_q26 " ] ,
" eos_squared_relative_q30_minus_q26 " : ratio ( error [ " eos_squared_q30_minus_q26 " ] , squared ) ,
" q30_negative_enthalpy_integration_nodes " : q30 [ " negative_enthalpy_samples " ] ,
" surface_minimum_enthalpy " : surface_h . get ( " minimum_enthalpy " ) ,
" surface_negative_enthalpy_samples " : surface_h . get ( " negative_enthalpy_samples " ) ,
" interval_witness_minimum_enthalpy " : witness_h . get ( " minimum_enthalpy " ) ,
" interval_negative_enthalpy_witnesses " : witness_h . get ( " negative_enthalpy_samples " ) }
2026-09-19 12:16:56 -04:00
def check_non_density_layouts ( records ) :
reference = { }
for ( campaign , name ) , ( _ , ( _ , mesh , case ) ) in records . items ( ) :
model = case [ " n " ] , case [ " J " ]
layout = { key : value for key , value in case [ " block_sizes " ] . items ( )
if key not in ( " value/density " , " residual/barotropic_closure " ) }
current = mesh , layout
if model in reference :
require ( current == reference [ model ] ,
f " Non-density layout or mesh changed for (n,J)= { model } : { campaign } / { name } " )
else :
reference [ model ] = current
2026-09-19 11:04:49 -04:00
def build_rows ( audits ) :
""" Deduplicate overlapping audited case records, never average repeat runs. """
records = { }
for audit_path , audit in audits :
require ( audit . get ( " artifact_passed " ) is True , " Refusing an incomplete/failed audit: " + audit_path )
for campaign , run in audit [ " campaigns " ] . items ( ) :
for name , case in run [ " cases " ] . items ( ) :
require ( case . get ( " artifact_passed " ) is True , " Case artifact audit failed: " + name )
key = campaign , name
payload = run [ " producer_commit " ] , run [ " mesh_sha256 " ] , case
if key in records :
require ( records [ key ] [ 1 ] == payload , " Overlapping audit records disagree: " + str ( key ) )
else :
records [ key ] = audit_path , payload
2026-09-19 12:16:56 -04:00
# Separate passing audits may never have seen the other density orders.
# Enforce their shared non-density discretization before deriving ratios.
check_non_density_layouts ( records )
2026-09-19 11:04:49 -04:00
frozen , coupled = [ ] , [ ]
for ( campaign , name ) , ( audit_path , ( commit , mesh , case ) ) in sorted ( records . items ( ) ) :
common = { " audit_json " : audit_path , " campaign " : campaign , " case " : name , " producer_commit " : commit ,
" mesh_sha256 " : mesh , " n " : case [ " n " ] , " J " : case [ " J " ] , " K " : case [ " K " ] ,
" source_density_degree " : case [ " density_degree " ] , " source_state_dofs " : case [ " state_size " ] }
if case [ " kind " ] == " frozen " :
for degree in ( 2 , 3 , 4 ) :
key = f " Q { degree } /eos_l2_q26 "
row = { * * common , " density_degree " : degree , " control " : " eos_l2_q26 " ,
" density_dofs " : case [ " projection " ] [ f " Q { degree } " ] [ " active_density_dofs " ] ,
* * density_metrics ( case , key ) }
frozen . append ( row )
else :
require ( case [ " kind " ] == " coupled " , " Unknown case kind " )
newton = case [ " newton " ]
require ( isinstance ( newton [ " converged " ] , bool ) , " Invalid convergence observation " )
initial = finite ( newton [ " initial_residual " ] , " initial residual " , True )
final = finite ( newton [ " final_residual " ] , " final residual " , True )
reduction = ratio ( final , initial )
row = { * * common , " density_degree " : case [ " density_degree " ] , " control " : " stored_density " ,
" density_dofs " : case [ " block_sizes " ] [ " value/density " ] , * * density_metrics ( case , f " Q { case [ ' density_degree ' ] } /stored_density " ) ,
" converged " : newton [ " converged " ] , " failure " : newton [ " failure " ] ,
" initial_residual " : initial , " final_residual " : final , " final_over_initial_residual " : reduction ,
" residual_reduction_percent " : 100 * ( 1 - reduction ) if reduction is not None else None ,
" nonlinear_threshold " : newton [ " threshold " ] , " accepted_steps " : newton [ " accepted_steps " ] ,
" iteration_records " : len ( newton [ " iterations " ] ) , " krylov_iterations " : newton [ " linear_iterations " ] ,
" newton_iteration_seconds " : finite ( newton [ " iteration_seconds " ] , " Newton time " , True ) ,
" linear_solve_seconds " : math . fsum ( finite ( r [ " linear_seconds " ] , " linear time " , True ) for r in newton [ " iterations " ] ) ,
" observer_seconds " : case [ " observer_timings " ] [ " observer_total " ] ,
" elapsed_seconds_including_observers " : case [ " run " ] [ " seconds " ] ,
" utc_minus_monotonic_seconds " : case [ " run " ] [ " utc_minus_monotonic_seconds " ] }
2026-09-19 11:15:28 -04:00
physical18 = case [ " physical " ] [ " 18 " ] [ " metrics " ]
# A bordered solve can meet its reported tolerance while the
# unbordered equations still carry the auxiliary border action.
for key in ( " normalized_unbordered_residual " , " central_border " , " normalized_border_action " ) :
row [ " final_ " + key ] = finite ( physical18 [ key ] , " final " + key , nonnegative = key != " central_border " )
2026-09-19 11:21:26 -04:00
line_search = case [ " line_search " ]
2026-09-19 12:46:04 -04:00
row [ " line_search_counts " ] = { key : line_search [ key ] for key in
( " total_trials " , " counts_by_source " , " counts_by_disposition " , " source_disposition_counts " ) }
2026-09-19 11:21:26 -04:00
for key in ( " pressure_force_rejections " , " residual_metric_rejections " ) :
row [ key ] = finite ( line_search [ key ] , key , True )
row [ " minimum_accepted_alpha " ] = line_search [ " minimum_accepted_alpha " ]
if row [ " minimum_accepted_alpha " ] is not None :
require ( 0 < finite ( row [ " minimum_accepted_alpha " ] , " minimum accepted alpha " ) < = 1 , " Invalid accepted step " )
2026-09-19 11:04:49 -04:00
for q in ( 14 , 18 ) :
physical = case [ " physical " ] [ str ( q ) ] [ " metrics " ]
for source , label in ( ( " enthalpy_virial_error " , " h_energy_virial " ) ,
( " enthalpy_force_virial_error " , " h_force_virial " ) ,
( " virial_error " , " density_energy_virial " ) ,
( " force_virial_error " , " density_force_virial " ) ) :
value = physical [ source ]
if value is not None :
finite ( value , source , True )
row [ f " { label } _q { q } " ] = value
row [ f " { label } _q { q } _within_1e5 " ] = value < = 1e-5 if value is not None else None
coupled . append ( row )
# Repeated same-model/same-degree runs require explicit selection upstream;
# their averaging would conceal convergence outcomes and timing variability.
seen = set ( )
for row in coupled :
key = row [ " case " ] , row [ " n " ] , row [ " J " ] , row [ " mesh_sha256 " ] , row [ " density_degree " ]
require ( key not in seen , " Duplicate coupled model/degree; select one audited run: " + str ( key ) )
seen . add ( key )
return frozen , coupled
2026-09-19 12:46:04 -04:00
def trial_stage_rows ( coupled ) :
table = [ ]
for row in coupled :
counts = row [ " line_search_counts " ]
total = 0
for stage in counts [ " source_disposition_counts " ] :
count = finite ( stage [ " count " ] , " stage count " , True )
require ( count > 0 and int ( count ) == count , " Invalid integer stage count " )
code = finite ( stage [ " disposition_code " ] , " disposition code " , True )
require ( int ( code ) == code and code < = 5 , " Invalid disposition code " )
total + = count
table . append ( { key : row [ key ] for key in ( " case " , " n " , " J " , " density_degree " , " campaign " ) } |
{ " source " : stage [ " source " ] , " disposition " : stage [ " disposition " ] , " disposition_code " : code ,
" rejected " : code != 0 , " count " : count } )
require ( total == counts [ " total_trials " ] , " Joint stage counts do not cover all recorded trials " )
return table
2026-09-19 11:04:49 -04:00
def comparisons ( frozen , coupled ) :
result = [ ]
for kind , table in ( ( " frozen " , frozen ) , ( " coupled " , coupled ) ) :
groups = defaultdict ( list )
for row in table :
key = ( row [ " campaign " ] , row [ " case " ] ) if kind == " frozen " else ( row [ " case " ] , row [ " n " ] , row [ " J " ] , row [ " mesh_sha256 " ] )
groups [ key ] . append ( row )
for group in groups . values ( ) :
baseline = next ( ( r for r in group if r [ " density_degree " ] == 2 ) , None )
if baseline is None :
continue
keys = [ " negative_mass_over_abs_mass " , " negative_volume_fraction " , " eos_l2_q30 " ]
if kind == " coupled " :
keys + = [ " newton_iteration_seconds " , " krylov_iterations " , " final_residual " , " h_energy_virial_q18 " , " h_force_virial_q18 " ]
for row in group :
if row [ " density_degree " ] != 2 :
result . append ( { " kind " : kind , " case " : row [ " case " ] , " n " : row [ " n " ] , " J " : row [ " J " ] ,
" baseline_campaign " : baseline [ " campaign " ] , " campaign " : row [ " campaign " ] ,
" density_degree " : row [ " density_degree " ] ,
* * { key + " _over_Q2 " : ratio ( row [ key ] , baseline [ key ] ) for key in keys } } )
return result
def write_csv ( path , table , fields = None ) :
fields = fields or list ( dict . fromkeys ( key for row in table for key in row ) )
with path . open ( " w " , newline = " " ) as stream :
if fields :
writer = csv . DictWriter ( stream , fieldnames = fields , extrasaction = " ignore " )
writer . writeheader ( )
writer . writerows ( table )
2026-09-19 12:06:37 -04:00
def plot_observation ( row , field , negative = False , log = True ) :
""" Keep unresolved sign measurements out of resolved convergence trends. """
value = row [ field ]
if value is None :
return None , " undefined "
finite ( value , " plotted " + field , log )
if log and value == 0 :
return None , " observed zero "
if negative and row [ " negative_classification " ] == " uncertain_witnesses_only " :
return None , f " uncertain-only observation { value : .6g } "
return value , None
2026-09-19 11:04:49 -04:00
def plot_figure ( frozen , coupled , output ) :
os . environ . setdefault ( " MPLCONFIGDIR " , str ( output / " matplotlib_cache " ) )
import matplotlib
matplotlib . use ( " Agg " )
import matplotlib . pyplot as plt
from matplotlib . lines import Line2D
plt . rcParams . update ( { " font.size " : 9 , " axes.spines.top " : False , " axes.spines.right " : False ,
" savefig.dpi " : 190 , " pdf.fonttype " : 42 } )
row_count = bool ( frozen ) + 2 * bool ( coupled )
require ( row_count > 0 , " No audited rows to plot " )
fig , axes = plt . subplots ( row_count , 3 , figsize = ( 13.8 , 3.9 * row_count + .7 ) , squeeze = False )
2026-09-19 12:06:37 -04:00
model_keys = sorted ( { ( row [ " n " ] , row [ " J " ] ) for row in [ * frozen , * coupled ] } )
colors = { key : plt . get_cmap ( " tab10 " ) ( index % 10 ) for index , key in enumerate ( model_keys ) }
2026-09-19 11:04:49 -04:00
def groups ( table , frozen_case ) :
result = defaultdict ( list )
for row in table :
key = ( row [ " campaign " ] , row [ " case " ] ) if frozen_case else ( row [ " case " ] , row [ " n " ] , row [ " J " ] , row [ " mesh_sha256 " ] )
result [ key ] . append ( row )
return [ sorted ( group , key = lambda r : r [ " density_degree " ] ) for group in result . values ( ) ]
def panel ( ax , grouped , field , title , ylabel , negative = False , log = True , second = None , legend = False ) :
annotations , positive = [ ] , False
2026-09-19 12:06:37 -04:00
for group in grouped :
color = colors [ ( group [ 0 ] [ " n " ] , group [ 0 ] [ " J " ] ) ]
2026-09-19 11:04:49 -04:00
label = group [ 0 ] [ " case " ]
x = [ r [ " density_degree " ] for r in group ]
series = [ ( field , " - " ) ] + ( [ ( second , " -- " ) ] if second else [ ] )
for metric , style in series :
values = [ ]
for row in group :
2026-09-19 12:06:37 -04:00
value , note = plot_observation ( row , metric , negative , log )
if note is not None :
annotations . append ( f " { label } Q { row [ ' density_degree ' ] } : { note } "
2026-09-19 11:04:49 -04:00
+ ( " (force) " if metric == second else " " ) )
2026-09-19 12:06:37 -04:00
# NaN breaks the line, so a tiny uncertain-only number
# cannot look like resolved orders-of-magnitude gain.
2026-09-19 11:04:49 -04:00
values . append ( math . nan )
continue
positive = True
values . append ( value )
not_converged = row . get ( " converged " ) is False
ax . plot ( row [ " density_degree " ] , value , marker = " x " if not_converged else " o " , markersize = 5 ,
2026-09-19 12:06:37 -04:00
color = color , markerfacecolor = color , linestyle = " none " )
2026-09-19 11:04:49 -04:00
ax . plot ( x , values , style , color = color , linewidth = 1.15 , label = label if metric == field else None )
if log and positive :
ax . set_yscale ( " log " )
if not positive :
2026-09-19 12:06:37 -04:00
ax . text ( .5 , .5 , " No positive values in trend " if log else " No finite values in trend " ,
2026-09-19 11:04:49 -04:00
ha = " center " , va = " center " , transform = ax . transAxes )
ax . set_xticks ( [ 2 , 3 , 4 ] , [ " Q2 " , " Q3 " , " Q4 " ] )
ax . set_xlim ( 1.85 , 4.15 )
ax . set ( title = title , ylabel = ylabel )
ax . grid ( alpha = .2 , which = " both " )
if annotations :
ax . text ( 0 , - .19 , " \n " . join ( annotations ) , fontsize = 6.5 , transform = ax . transAxes , va = " top " )
if legend :
ax . legend ( fontsize = 7 , loc = " best " )
if second :
handles = [ Line2D ( [ ] , [ ] , color = " .3 " , linestyle = " - " , label = " Energy virial " ) ,
Line2D ( [ ] , [ ] , color = " .3 " , linestyle = " -- " , label = " Force virial " ) ]
ax . legend ( handles = handles , fontsize = 7 )
ax . axhline ( 1e-5 , color = " .4 " , linestyle = " : " , linewidth = .9 )
row = 0
if frozen :
grouped = groups ( frozen , True )
panel ( axes [ row , 0 ] , grouped , " negative_mass_over_abs_mass " , " Frozen L2 projection: negative mass " , r " $M_- / |M|$ " , negative = True , legend = True )
panel ( axes [ row , 1 ] , grouped , " negative_volume_fraction " , " Frozen L2 projection: negative volume " , r " $V_- / V$ " , negative = True )
panel ( axes [ row , 2 ] , grouped , " eos_l2_q30 " , " Frozen L2 projection: EOS error " , r " $ \ | \ rho- \ rho_ { \ rm EOS}(h) \ |_ { L^2}$ (q30) " )
row + = 1
if coupled :
grouped = groups ( coupled , False )
panel ( axes [ row , 0 ] , grouped , " negative_mass_over_abs_mass " , " Coupled endpoint: negative mass " , r " $M_- / |M|$ " , negative = True , legend = True )
panel ( axes [ row , 1 ] , grouped , " eos_l2_q30 " , " Coupled endpoint: EOS error " , r " $ \ | \ rho- \ rho_ { \ rm EOS}(h) \ |_ { L^2}$ (q30) " )
panel ( axes [ row , 2 ] , grouped , " h_energy_virial_q18 " , " Coupled endpoint: P(h) virials " , " Absolute virial residual / |W| (q18) " , second = " h_force_virial_q18 " )
row + = 1
panel ( axes [ row , 0 ] , grouped , " final_over_initial_residual " , " Reported nonlinear residual reduction " , r " $ \ |F_ { \ rm final} \ | / \ |F_ { \ rm initial} \ |$ " )
panel ( axes [ row , 1 ] , grouped , " newton_iteration_seconds " , " Newton iteration cost " , " Seconds (excludes observer and setup) " , log = False )
panel ( axes [ row , 2 ] , grouped , " krylov_iterations " , " Total reported Krylov work " , " Iterations " , log = False )
fig . suptitle ( " Density approximation order — audited observations " , fontsize = 14 , y = .985 )
2026-09-19 12:06:37 -04:00
fig . text ( .025 , .018 , " Colors identify (n, J) consistently; × : nonlinear solve did not converge. Uncertain-only negatives, zeros and undefined values are listed below panels, never placed on a log floor. \n "
2026-09-19 11:04:49 -04:00
" Negative regions use root-sliced quadrature; EOS norms use unsliced q30. P(h) virials do not certify density-EOS validity. See CSV/JSON for all outcomes and timing scope. " , fontsize = 8 )
fig . subplots_adjust ( left = .075 , right = .985 , top = .92 if row_count == 1 else .95 , bottom = .15 if row_count == 1 else .085 ,
wspace = .35 , hspace = .72 )
fig . savefig ( output / " density_order_comparison.png " )
fig . savefig ( output / " density_order_comparison.pdf " )
plt . close ( fig )
class Tests ( unittest . TestCase ) :
2026-09-19 12:46:04 -04:00
def test_distinct_preparation_stage_counts ( self ) :
row = { " case " : " sample " , " n " : 3. , " J " : 0. , " density_degree " : 4 , " campaign " : " recorded " ,
" line_search_counts " : { " total_trials " : 4 , " source_disposition_counts " : [
{ " source " : " barotropic closure " , " disposition " : " inadmissible_state " , " disposition_code " : 1 , " count " : 2 } ,
{ " source " : " pressure force " , " disposition " : " inadmissible_state " , " disposition_code " : 1 , " count " : 1 } ,
{ " source " : " " , " disposition " : " accepted " , " disposition_code " : 0 , " count " : 1 } ] } }
table = trial_stage_rows ( [ row ] )
self . assertEqual ( { r [ " source " ] : r [ " count " ] for r in table } , { " barotropic closure " : 2 , " pressure force " : 1 , " " : 1 } )
self . assertTrue ( table [ 0 ] [ " rejected " ] )
self . assertFalse ( table [ - 1 ] [ " rejected " ] )
row [ " line_search_counts " ] [ " total_trials " ] = 5
with self . assertRaisesRegex ( ValueError , " cover all recorded trials " ) :
trial_stage_rows ( [ row ] )
2026-09-19 12:16:56 -04:00
def test_cross_audit_non_density_layout ( self ) :
def case ( density_size , gravity_size = 23 ) :
return { " n " : 1.5 , " J " : 0. , " block_sizes " : { " value/density " : density_size ,
" residual/barotropic_closure " : density_size , " value/gravity_potential " : gravity_size ,
" residual/poisson_balance " : gravity_size } }
records = { ( " q2 " , " sample " ) : ( " audit_q2.json " , ( " commit2 " , " mesh " , case ( 27 ) ) ) ,
( " q3 " , " sample " ) : ( " audit_q3.json " , ( " commit3 " , " mesh " , case ( 64 ) ) ) }
check_non_density_layouts ( records )
records [ ( " q3 " , " sample " ) ] = ( " audit_q3.json " , ( " commit3 " , " mesh " , case ( 64 , 24 ) ) )
with self . assertRaisesRegex ( ValueError , " Non-density layout " ) :
check_non_density_layouts ( records )
records [ ( " q3 " , " sample " ) ] = ( " audit_q3.json " , ( " commit3 " , " changed_mesh " , case ( 64 ) ) )
with self . assertRaisesRegex ( ValueError , " mesh changed " ) :
check_non_density_layouts ( records )
2026-09-19 12:06:37 -04:00
def test_uncertain_plot_observation_breaks_trend ( self ) :
row = { " negative_mass " : 1e-30 , " negative_classification " : " uncertain_witnesses_only " }
plotted , note = plot_observation ( row , " negative_mass " , negative = True )
self . assertIsNone ( plotted )
self . assertIn ( " 1e-30 " , note )
self . assertEqual ( row [ " negative_mass " ] , 1e-30 )
self . assertEqual ( plot_observation ( row , " negative_mass " , negative = False ) , ( 1e-30 , None ) )
row [ " negative_classification " ] = " resolved_witnesses_present "
self . assertEqual ( plot_observation ( row , " negative_mass " , negative = True ) , ( 1e-30 , None ) )
row [ " negative_mass " ] = 0.
self . assertEqual ( plot_observation ( row , " negative_mass " , negative = True ) , ( None , " observed zero " ) )
2026-09-19 11:04:49 -04:00
def test_zero_and_undefined_are_not_floored ( self ) :
fine = { k : 0. for k in ( " negative_mass " , " negative_volume " , " negative_mass_fraction " , " negative_volume_fraction " ,
" negative_mass_uncertainty_scale " , " resolved_negative_intervals " , " uncertain_negative_intervals " , " uncertain_negative_mass " ) }
fine . update ( mass = 1. , minimum_density = 0. )
measure = { " summary " : { " 30 " : fine } , " surface " : { } , " negative_mass_q30_minus_q22 " : 0. , " negative_volume_q30_minus_q22 " : 0. }
q = { " eos_squared_integral " : 0. , " eos_defined_everywhere_sampled " : True , " volume " : 1. , " negative_enthalpy_samples " : 0 }
error = { " 30 " : q , " 26 " : q . copy ( ) , " eos_squared_q30_minus_q26 " : 0. }
case = { " measures " : { " Q2/stored_density " : measure } , " unsliced_error_quadrature " : { " Q2/stored_density " : error } }
row = density_metrics ( case , " Q2/stored_density " )
self . assertEqual ( row [ " negative_classification " ] , " zero_observed " )
self . assertEqual ( row [ " eos_l2_q30 " ] , 0. )
self . assertIsNone ( row [ " negative_mass_over_uncertainty_scale " ] )
q . update ( eos_squared_integral = None , eos_defined_everywhere_sampled = False , negative_enthalpy_samples = 1 )
self . assertIsNone ( density_metrics ( case , " Q2/stored_density " ) [ " eos_l2_q30 " ] )
fine . update ( negative_mass = 1e-20 , negative_mass_fraction = 1e-20 , uncertain_negative_intervals = 1 )
self . assertEqual ( density_metrics ( case , " Q2/stored_density " ) [ " negative_classification " ] , " uncertain_witnesses_only " )
def test_failed_audit_rejected ( self ) :
with self . assertRaises ( ValueError ) :
build_rows ( [ ( " bad.json " , { " artifact_passed " : False } ) ] )
def test_zero_baseline_ratio_undefined ( self ) :
self . assertIsNone ( ratio ( 1. , 0. ) )
self . assertEqual ( ratio ( 0. , 1. ) , 0. )
self . assertIsNone ( ratio ( None , 1. ) )
def test_audited_coupled_outcome_keeps_iteration_cost ( self ) :
fine = { k : 0. for k in ( " negative_mass " , " negative_volume " , " negative_mass_fraction " , " negative_volume_fraction " ,
" negative_mass_uncertainty_scale " , " resolved_negative_intervals " , " uncertain_negative_intervals " , " uncertain_negative_mass " ) }
fine . update ( mass = 1. , minimum_density = 0. )
measure = { " summary " : { " 30 " : fine } , " surface " : { } , " negative_mass_q30_minus_q22 " : 0. , " negative_volume_q30_minus_q22 " : 0. }
q = { " eos_squared_integral " : 4e-8 , " eos_defined_everywhere_sampled " : True , " volume " : 1. , " negative_enthalpy_samples " : 0 }
metrics = { " enthalpy_virial_error " : 2e-6 , " enthalpy_force_virial_error " : 3e-5 ,
2026-09-19 11:15:28 -04:00
" normalized_unbordered_residual " : .04 , " central_border " : - .125 , " normalized_border_action " : .03 ,
2026-09-19 11:04:49 -04:00
" virial_error " : None , " force_virial_error " : None }
case = { " artifact_passed " : True , " kind " : " coupled " , " n " : 1.5 , " J " : 0. , " K " : 1. , " density_degree " : 2 ,
" state_size " : 50 , " block_sizes " : { " value/density " : 27 } ,
" measures " : { " Q2/stored_density " : measure } , " unsliced_error_quadrature " : { " Q2/stored_density " : {
" 30 " : q , " 26 " : q , " eos_squared_q30_minus_q26 " : 0. } } ,
" newton " : { " converged " : False , " failure " : " iteration limit " , " initial_residual " : .1 ,
" final_residual " : .01 , " threshold " : 1e-8 , " accepted_steps " : 1 , " linear_iterations " : 7 ,
" iteration_seconds " : 10. , " iterations " : [ { " linear_seconds " : 6. } ] } ,
" observer_timings " : { " observer_total " : 200. } , " run " : { " seconds " : 215. , " utc_minus_monotonic_seconds " : .01 } ,
2026-09-19 12:46:04 -04:00
" line_search " : { " pressure_force_rejections " : 4 , " residual_metric_rejections " : 1 , " minimum_accepted_alpha " : 1 / 32 ,
" total_trials " : 6 , " counts_by_source " : { " pressure force " : 4 , " residual metric " : 1 , " " : 1 } ,
" counts_by_disposition " : { " inadmissible_state " : 4 , " insufficient_decrease " : 1 , " accepted " : 1 } ,
" source_disposition_counts " : [
{ " source " : " pressure force " , " disposition " : " inadmissible_state " , " disposition_code " : 1 , " count " : 4 } ,
{ " source " : " residual metric " , " disposition " : " insufficient_decrease " , " disposition_code " : 4 , " count " : 1 } ,
{ " source " : " " , " disposition " : " accepted " , " disposition_code " : 0 , " count " : 1 } ] } ,
2026-09-19 11:04:49 -04:00
" physical " : { " 14 " : { " metrics " : metrics } , " 18 " : { " metrics " : metrics } } }
audit = { " artifact_passed " : True , " campaigns " : { " /recorded/campaign " : {
" producer_commit " : " test " , " mesh_sha256 " : " test " , " cases " : { " sample " : case } } } }
frozen , coupled = build_rows ( [ ( " test.json " , audit ) ] )
self . assertEqual ( frozen , [ ] )
row = coupled [ 0 ]
self . assertEqual ( row [ " newton_iteration_seconds " ] , 10. )
self . assertEqual ( row [ " observer_seconds " ] , 200. )
self . assertAlmostEqual ( row [ " residual_reduction_percent " ] , 90. )
self . assertFalse ( row [ " converged " ] )
self . assertTrue ( row [ " h_energy_virial_q18_within_1e5 " ] )
self . assertFalse ( row [ " h_force_virial_q18_within_1e5 " ] )
self . assertIsNone ( row [ " density_energy_virial_q18_within_1e5 " ] )
2026-09-19 11:15:28 -04:00
self . assertEqual ( row [ " final_normalized_unbordered_residual " ] , .04 )
self . assertEqual ( row [ " final_central_border " ] , - .125 )
self . assertEqual ( row [ " final_normalized_border_action " ] , .03 )
2026-09-19 11:21:26 -04:00
self . assertEqual ( row [ " pressure_force_rejections " ] , 4 )
self . assertEqual ( row [ " residual_metric_rejections " ] , 1 )
self . assertEqual ( row [ " minimum_accepted_alpha " ] , 1 / 32 )
2026-09-19 12:46:04 -04:00
self . assertEqual ( row [ " line_search_counts " ] , { key : case [ " line_search " ] [ key ] for key in
( " total_trials " , " counts_by_source " , " counts_by_disposition " , " source_disposition_counts " ) } )
2026-09-19 11:04:49 -04:00
def main ( ) :
parser = argparse . ArgumentParser ( description = __doc__ )
parser . add_argument ( " audits " , nargs = " * " , type = Path )
parser . add_argument ( " --output " , type = Path , help = " Fresh output directory " )
parser . add_argument ( " --tables-only " , action = " store_true " )
parser . add_argument ( " --self-test " , action = " store_true " )
args = parser . parse_args ( )
if args . self_test :
test = unittest . TextTestRunner ( verbosity = 2 ) . run ( unittest . defaultTestLoader . loadTestsFromTestCase ( Tests ) )
if not test . wasSuccessful ( ) :
raise SystemExit ( 1 )
if not args . audits :
return
if not args . audits or args . output is None :
parser . error ( " Supply completed audit JSON and --output " )
inputs = [ ( str ( path . resolve ( ) ) , json . loads ( path . read_text ( ) ) ) for path in args . audits ]
frozen , coupled = build_rows ( inputs )
require ( frozen or coupled , " No cases in input audits " )
relative = comparisons ( frozen , coupled )
2026-09-19 12:46:04 -04:00
stages = trial_stage_rows ( coupled )
2026-09-19 11:04:49 -04:00
args . output . mkdir ( parents = True , exist_ok = False )
write_csv ( args . output / " frozen_projection.csv " , frozen , [ " case " , " n " , " J " , " density_degree " , " density_dofs " ,
" negative_mass_over_abs_mass " , " negative_volume_fraction " , " negative_classification " , " negative_mass_over_uncertainty_scale " ,
" eos_l2_q30 " , " eos_rms_q30 " , " eos_squared_relative_q30_minus_q26 " , " negative_mass_q30_minus_q22 " ,
" surface_minimum_enthalpy " , " surface_negative_enthalpy_samples " ] )
write_csv ( args . output / " coupled_outcomes.csv " , coupled , [ " case " , " n " , " J " , " density_degree " , " source_state_dofs " , " density_dofs " ,
" converged " , " failure " , " accepted_steps " , " krylov_iterations " , " newton_iteration_seconds " , " linear_solve_seconds " ,
2026-09-19 11:21:26 -04:00
" pressure_force_rejections " , " residual_metric_rejections " , " minimum_accepted_alpha " ,
2026-09-19 11:04:49 -04:00
" initial_residual " , " final_residual " , " final_over_initial_residual " , " h_energy_virial_q18 " , " h_force_virial_q18 " ,
2026-09-19 11:15:28 -04:00
" final_normalized_unbordered_residual " , " final_central_border " , " final_normalized_border_action " ,
2026-09-19 11:04:49 -04:00
" h_energy_virial_q14 " , " h_force_virial_q14 " , " negative_mass_over_abs_mass " , " negative_volume_fraction " ,
" negative_classification " , " eos_l2_q30 " , " eos_rms_q30 " ] )
write_csv ( args . output / " relative_to_Q2.csv " , relative )
2026-09-19 12:46:04 -04:00
write_csv ( args . output / " trial_stages.csv " , stages ,
[ " case " , " n " , " J " , " density_degree " , " campaign " , " source " , " disposition " , " disposition_code " , " rejected " , " count " ] )
2026-09-19 11:04:49 -04:00
if not args . tables_only :
plot_figure ( frozen , coupled , args . output )
digest = lambda path : hashlib . sha256 ( path . read_bytes ( ) ) . hexdigest ( )
summary = { " schema " : " density_order_summary_v1 " , " generator_sha256 " : digest ( Path ( __file__ ) ) ,
" input_audit_sha256 " : { str ( path . resolve ( ) ) : digest ( path ) for path in args . audits } ,
" scope " : " Presentation of audited observations only; no campaign files reopened and no independent FEM work. " ,
2026-09-19 12:16:56 -04:00
" cross_order_layout_check " : " Mesh identity and all non-density block names/sizes match for every repeated (n,J), including records loaded from separate audits. " ,
2026-09-19 11:04:49 -04:00
" notes " : [ " Frozen controls are fixed-q26 L2 projections; EOS error norms use separate unsliced q30. " ,
" Negative-mass denominator is the absolute measured density mass, not a substituted exact target mass. " ,
" Uncertainty scales are reconstruction indicators, not rigorous bounds; zero observed negativity is not a global positivity certificate. " ,
" Newton seconds sum reported nonlinear-iteration times, excluding observer and setup costs; total elapsed time is kept separately. " ,
2026-09-19 11:15:28 -04:00
" Final unbordered residual, signed central border and normalized border action come from q18 physical diagnostics; bordered convergence does not imply that these vanish. " ,
2026-09-19 11:21:26 -04:00
" Pressure-force and residual-metric rejection counts retain the recorded stage distinction; residual-metric counts include any nonfinite metric failures as well as insufficient decrease. " ,
2026-09-19 12:46:04 -04:00
" All source/disposition counts, including accepted trials, are preserved in trial_stages.csv and JSON; preparation-stage counts alone do not establish where a candidate would fail if processing continued. " ,
2026-09-19 11:04:49 -04:00
" Ratios to Q2 compare recorded endpoints and do not imply equal convergence or error tolerances were attained. " ,
" Undefined values are null/blank; zero is kept exactly. No logarithmic plot floor is inserted. " ,
2026-09-19 12:06:37 -04:00
" Uncertain-only negative observations retain exact table values and appear as separate plot annotations; resolved trends do not connect through them. Colors are stable by (n,J). " ,
2026-09-19 11:04:49 -04:00
" P(h) virial milestones do not establish pointwise density validity; density-based virials are retained separately. " ] ,
2026-09-19 12:46:04 -04:00
" frozen_projection " : frozen , " coupled_outcomes " : coupled , " relative_to_Q2 " : relative , " trial_stages " : stages ,
2026-09-19 11:04:49 -04:00
" artifacts_sha256 " : { path . name : digest ( path ) for path in args . output . iterdir ( ) if path . is_file ( ) } }
( args . output / " summary.json " ) . write_text ( json . dumps ( summary , indent = 2 , allow_nan = False ) + " \n " )
print ( " Wrote " , args . output )
if __name__ == " __main__ " :
main ( )