api581-engine 0.1.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. api581/__init__.py +80 -0
  2. api581/_amine_tables.py +105 -0
  3. api581/_h2sh2_tables.py +161 -0
  4. api581/_slabx_worker.py +174 -0
  5. api581/_sulfidic_tables.py +517 -0
  6. api581/_sulfuric_tables.py +328 -0
  7. api581/acid_sour_water.py +238 -0
  8. api581/acscc_screening.py +88 -0
  9. api581/alkaline_sour_water.py +267 -0
  10. api581/amine_corrosion.py +277 -0
  11. api581/amine_screening.py +103 -0
  12. api581/api/__init__.py +4 -0
  13. api581/api/api520.py +88 -0
  14. api581/api/bundle.py +121 -0
  15. api581/api/consequence.py +102 -0
  16. api581/api/damage.py +1831 -0
  17. api581/api/dispersion.py +121 -0
  18. api581/api/effects.py +318 -0
  19. api581/api/events.py +96 -0
  20. api581/api/financial.py +115 -0
  21. api581/api/frequency.py +40 -0
  22. api581/api/inspection.py +96 -0
  23. api581/api/level1.py +238 -0
  24. api581/api/level2.py +74 -0
  25. api581/api/planning.py +17 -0
  26. api581/api/prd.py +190 -0
  27. api581/api/properties.py +130 -0
  28. api581/api/release.py +252 -0
  29. api581/api/reliability.py +40 -0
  30. api581/api/risk.py +71 -0
  31. api581/api/tank.py +490 -0
  32. api581/api520.py +205 -0
  33. api581/area_contribution.py +72 -0
  34. api581/blast.py +232 -0
  35. api581/brittle.py +205 -0
  36. api581/bundle.py +300 -0
  37. api581/catalog.py +442 -0
  38. api581/caustic_screening.py +103 -0
  39. api581/clad_thinning.py +146 -0
  40. api581/clscc_screening.py +55 -0
  41. api581/co2_corrosion.py +313 -0
  42. api581/co2_screening.py +205 -0
  43. api581/consequences.py +250 -0
  44. api581/contracts.py +1038 -0
  45. api581/cooling_selection.py +204 -0
  46. api581/cooling_water.py +305 -0
  47. api581/core.py +126 -0
  48. api581/corrosion_rate.py +38 -0
  49. api581/cost_tables.py +175 -0
  50. api581/cracking.py +74 -0
  51. api581/data/coverage.json +21361 -0
  52. api581/data/digital-twin.schema.json +538 -0
  53. api581/data/direct-test-queue.json +7 -0
  54. api581/data/native-engine-evidence.json +44 -0
  55. api581/data/python-api.schema.json +92706 -0
  56. api581/data/reference-fixture-evidence.json +2956 -0
  57. api581/data/scope-boundaries.schema.json +58 -0
  58. api581/data/software-test-evidence.json +4278 -0
  59. api581/data/standard-metadata.json +1328 -0
  60. api581/data/standard.schema.json +233 -0
  61. api581/data/supporting-text-review.json +1319 -0
  62. api581/digital_twin.py +491 -0
  63. api581/dispersion.py +45 -0
  64. api581/effects.py +232 -0
  65. api581/evaporation.py +181 -0
  66. api581/evidence.py +81 -0
  67. api581/external_corrosion.py +148 -0
  68. api581/external_cracking.py +63 -0
  69. api581/fatigue.py +56 -0
  70. api581/fireball.py +163 -0
  71. api581/flash_pool.py +111 -0
  72. api581/flash_solver.py +122 -0
  73. api581/groundwater.py +101 -0
  74. api581/h2sh2_corrosion.py +128 -0
  75. api581/hic_screened.py +89 -0
  76. api581/htha.py +45 -0
  77. api581/hydrochloric_acid.py +272 -0
  78. api581/hydrofluoric_acid.py +236 -0
  79. api581/ignition.py +204 -0
  80. api581/inspection_effectiveness.py +601 -0
  81. api581/jet_handoff.py +60 -0
  82. api581/level1.py +311 -0
  83. api581/level1_summary.py +35 -0
  84. api581/level1_toxic.py +313 -0
  85. api581/level1_type1.py +91 -0
  86. api581/level2_summary.py +237 -0
  87. api581/lining.py +173 -0
  88. api581/native_toxic.py +67 -0
  89. api581/outputs.py +5672 -0
  90. api581/oxidation.py +145 -0
  91. api581/pascc_screening.py +78 -0
  92. api581/physical_explosion.py +190 -0
  93. api581/pof.py +207 -0
  94. api581/pool_fire.py +273 -0
  95. api581/portfolio.py +68 -0
  96. api581/prd.py +204 -0
  97. api581/prd_consequences.py +245 -0
  98. api581/prd_history.py +44 -0
  99. api581/py.typed +0 -0
  100. api581/release.py +307 -0
  101. api581/representative_fluids.py +172 -0
  102. api581/result.py +50 -0
  103. api581/risk.py +191 -0
  104. api581/saturation.py +66 -0
  105. api581/scc_mechanisms.py +242 -0
  106. api581/schema.py +45 -0
  107. api581/slabx_adapter.py +261 -0
  108. api581/soil_corrosion.py +191 -0
  109. api581/source_partition.py +169 -0
  110. api581/spatial.py +87 -0
  111. api581/ssc_screening.py +77 -0
  112. api581/standard.py +281 -0
  113. api581/storage.py +42 -0
  114. api581/sulfidic_corrosion.py +197 -0
  115. api581/sulfuric_acid.py +209 -0
  116. api581/tank.py +260 -0
  117. api581/tank_corrosion.py +256 -0
  118. api581/tank_environment.py +186 -0
  119. api581/tank_financial.py +202 -0
  120. api581/tank_integrated.py +51 -0
  121. api581/tank_shell.py +141 -0
  122. api581/tank_source.py +152 -0
  123. api581/tank_thinning.py +204 -0
  124. api581/temper.py +105 -0
  125. api581/thinning.py +172 -0
  126. api581/thinning_conditions.py +212 -0
  127. api581/thinning_history.py +118 -0
  128. api581/thinning_selection.py +81 -0
  129. api581/thinning_type.py +34 -0
  130. api581/toxic_criteria.py +111 -0
  131. api581/toxic_level2.py +233 -0
  132. api581/two_phase_events.py +120 -0
  133. api581/workflow.py +42 -0
  134. api581_engine-0.1.4.dist-info/METADATA +419 -0
  135. api581_engine-0.1.4.dist-info/RECORD +139 -0
  136. api581_engine-0.1.4.dist-info/WHEEL +5 -0
  137. api581_engine-0.1.4.dist-info/licenses/LICENSE +161 -0
  138. api581_engine-0.1.4.dist-info/licenses/NOTICE.md +18 -0
  139. api581_engine-0.1.4.dist-info/top_level.txt +1 -0
@@ -0,0 +1,103 @@
1
+ """Amine SCC screening; susceptibility remains separately qualified."""
2
+ from typing import Literal
3
+ from pydantic import Field
4
+ from .core import Model, Positive, NonNegative, calculation, ensure
5
+ from .scc_mechanisms import Assessment, InspectionCounts, assess
6
+
7
+
8
+ class AmineCrackingScreen(Model):
9
+ material: Literal['carbon_steel','low_alloy_steel','other_material']
10
+ acid_gas_treating_amine_present: bool
11
+ screening_basis: str = Field(min_length=1)
12
+
13
+
14
+ @calculation('damage/amine-cracking-screening','Any-concentration acid-gas-treating amine SCC material screen',AmineCrackingScreen,
15
+ ['Part2 §7.3; PDF p179'],limitations=[
16
+ 'Carbon/low-alloy steel with acid-gas-treating amines in any concentration requires susceptibility evaluation. No concentration, normal-temperature, amine-type, rich-service or PWHT exclusion is inferred. Lean/rich/fresh composition, actual metal temperature, heat tracing, steam-out and other cracking mechanisms require separate evaluation. Screen-out is outside this procedure, not overall immunity or DF0.'])
17
+ def amine_cracking_screening(x):
18
+ ensure(bool(x.screening_basis.strip()),'Qualified material and acid-gas-treating amine exposure basis required')
19
+ material=x.material!='other_material'
20
+ return {'evaluate_amine_cracking':material and x.acid_gas_treating_amine_present,
21
+ 'screening_reason':'evaluate' if material and x.acid_gas_treating_amine_present else
22
+ 'outside_material_scope' if not material else 'treating_amine_absent'}
23
+
24
+
25
+ class ScreenedAmineCracking(Model):
26
+ screening: AmineCrackingScreen
27
+ cracking: Assessment
28
+ susceptibility_and_inspection_basis: str = Field(min_length=1)
29
+
30
+
31
+ @calculation('damage/amine-cracking-screened-assessment','Screened amine exposure through qualified SCC susceptibility and DF',ScreenedAmineCracking,
32
+ ['Part2 §§7.3,7.5-7.6; Table7.2,Table6.3; eq(2.26); PDF pp179-181'],
33
+ origin='amine_material_exposure_screen_to_supplied_susceptibility_df',limitations=[
34
+ 'Supplied susceptibility must be independently qualified using Figure7.1 or expert assessment; this API does not implement the figure or predict from amine chemistry. Screening must pass; no synthetic zero DF on screen-out. Confirmed cracking forces High; unrepaired cracks require FFS. Inspection grade/count and time since qualifying A/B/C clear/repaired inspection follow section7.6.3 and remain externally qualified. Existing six-equivalent-inspection support is retained; no all-mechanism assessment.'])
35
+ def amine_cracking_screened_assessment(x):
36
+ ensure(not x.cracking.unrepaired_cracks,'Unrepaired amine cracks require separate FFS evaluation','ffs_required')
37
+ ensure(bool(x.susceptibility_and_inspection_basis.strip()),'Amine susceptibility and mechanism-specific inspection basis required')
38
+ screen=amine_cracking_screening(x.screening)
39
+ ensure(screen['evaluate_amine_cracking'],'Amine material/exposure screen not met','amine_outside_screen')
40
+ return {**screen,**assess('amine',x.cracking)}
41
+
42
+
43
+ class AmineFigure(Model):
44
+ confirmed_cracking: bool
45
+ unrepaired_cracks: bool
46
+ stress_relieved: bool
47
+ solution: Literal['fresh','rich','lean','lean_and_rich']
48
+ amine_group: Literal['mea_or_dipa','dea','other_treating_amine']
49
+ maximum_metal_temperature_k: Positive
50
+ heat_traced: bool
51
+ steamed_out_before_water_flush: bool
52
+ applicability_basis: str = Field(min_length=1)
53
+
54
+
55
+ @calculation('damage/amine-figure-susceptibility','Figure7.1 amine cracking susceptibility',AmineFigure,
56
+ ['Part2 Figure7.1,Table7.1; PDF pp182-183'],limitations=[
57
+ 'Literal Fahrenheit flowchart thresholds100/140/180F converted exactly to kelvin.100..180 and140..180 include endpoints after the prior >180 test. Both lean/rich exposure routes lean per Table7.1. Other treating amines follow the printed not-MEA/DIPA/not-DEA branch; mixtures spanning groups require independent qualification, not automatic worst-group selection. Actual maximum metal temperature, heat tracing, steam-out before flushing and effective stress relief require qualification. Confirmed cracks forceHigh before stress relief/composition; unrepaired cracks require FFS. Not an amine corrosion-rate model or automatic chemical speciation/PWHT validation.'])
58
+ def amine_figure_susceptibility(x):
59
+ ensure(not x.unrepaired_cracks,'Unrepaired amine cracks require separate FFS evaluation','ffs_required')
60
+ ensure(bool(x.applicability_basis.strip()),'Qualified amine composition, actual metal temperature and fabrication basis required')
61
+ if x.confirmed_cracking:
62
+ level,branch='high','confirmed_cracking'
63
+ elif x.stress_relieved:
64
+ level,branch='none','stress_relieved'
65
+ elif x.solution in ('fresh','rich'):
66
+ level,branch='none','not_exposed_to_lean_amine'
67
+ else:
68
+ # Compare in kelvin to avoid back-conversion roundoff at printed endpoints.
69
+ t=x.maximum_metal_temperature_k
70
+ f100,f140,f180=((f-32)*5/9+273.15 for f in (100.,140.,180.))
71
+ heated=x.heat_traced or x.steamed_out_before_water_flush
72
+ if x.amine_group=='mea_or_dipa':
73
+ level='high' if t>f180 else 'medium' if t>=f100 or heated else 'low'
74
+ elif x.amine_group=='dea':
75
+ level='medium' if t>f180 else 'low' if t>=f140 or heated else 'none'
76
+ else:
77
+ level='low' if t>f180 or heated else 'none'
78
+ branch=x.amine_group+'_lean'
79
+ return {'susceptibility':level,'decision_branch':branch,
80
+ 'lean_exposure_selected':x.solution in ('lean','lean_and_rich')}
81
+
82
+
83
+ class FigureAmineAssessment(Model):
84
+ screening: AmineCrackingScreen
85
+ service: AmineFigure
86
+ years_since_qualifying_inspection: NonNegative
87
+ inspections: InspectionCounts
88
+ inspection_basis: str = Field(min_length=1)
89
+
90
+
91
+ @calculation('damage/amine-figure-assessment','Figure7.1 susceptibility through amine SCC DF',FigureAmineAssessment,
92
+ ['Part2 §7.6.3,Figure7.1,Tables7.2/6.3,eq(2.26); PDF pp180,182-183'],
93
+ origin='amine_flowchart_to_existing_scc_df',limitations=[
94
+ 'Material/exposure screen, Figure7.1 service declarations and mechanism-specific qualifying inspection age/count require qualification. Reuses existing SVI, equivalent inspection and age escalation, with maximum supported equivalent count6. Rich/fresh none applies only to this amine SCC mechanism, not SSC/HIC/SOHIC or other damage. No whole-component risk, FFS or automatic inspection grading.'])
95
+ def amine_figure_assessment(x):
96
+ selected=amine_figure_susceptibility(x.service)
97
+ ensure(bool(x.inspection_basis.strip()),'Amine-specific qualifying inspection period and effectiveness basis required')
98
+ screen=amine_cracking_screening(x.screening)
99
+ ensure(screen['evaluate_amine_cracking'],'Amine material/exposure screen not met','amine_outside_screen')
100
+ result=assess('amine',Assessment(susceptibility=selected['susceptibility'],confirmed_cracking=x.service.confirmed_cracking,
101
+ unrepaired_cracks=x.service.unrepaired_cracks,years_since_qualifying_inspection=x.years_since_qualifying_inspection,
102
+ inspections=x.inspections))
103
+ return {**screen,**selected,**result}
api581/api/__init__.py ADDED
@@ -0,0 +1,4 @@
1
+ """Typed public Python APIs grouped by engineering domain."""
2
+ from . import api520, bundle, consequence, damage, dispersion, effects, events, financial, frequency, inspection, level1, level2, planning, prd, properties, release, reliability, risk, tank
3
+
4
+ __all__ = ['api520', 'bundle', 'consequence', 'damage', 'dispersion', 'effects', 'events', 'financial', 'frequency', 'inspection', 'level1', 'level2', 'planning', 'prd', 'properties', 'release', 'reliability', 'risk', 'tank']
api581/api/api520.py ADDED
@@ -0,0 +1,88 @@
1
+ """Public api520 calculations. Inputs and outputs use named SI units.
2
+ Generated by scripts/build_python_api.py; inspect the request model for fields.
3
+ """
4
+ from ..core import Context
5
+ from ..result import CalculationResult, calculate
6
+
7
+
8
+ from ..api520 import CriticalRatio as CriticalPressureRatioInput
9
+ from ..outputs import Api520CriticalPressureRatioOutput as CriticalPressureRatioOutput
10
+
11
+ def critical_pressure_ratio(inputs: CriticalPressureRatioInput, *, context: Context | None = None) -> CalculationResult[CriticalPressureRatioOutput]:
12
+ 'API 520 critical-flow pressure ratio'
13
+ return calculate('api520/critical-pressure-ratio', inputs, output_type=CriticalPressureRatioOutput, context=context)
14
+
15
+
16
+ from ..api520 import FlowCoefficient as FlowCoefficientCInput
17
+ from ..outputs import Api520FlowCoefficientCOutput as FlowCoefficientCOutput
18
+
19
+ def flow_coefficient_c(inputs: FlowCoefficientCInput, *, context: Context | None = None) -> CalculationResult[FlowCoefficientCOutput]:
20
+ 'API 520 gas/vapor flow coefficient C'
21
+ return calculate('api520/flow-coefficient-c', inputs, output_type=FlowCoefficientCOutput, context=context)
22
+
23
+
24
+ from ..api520 import RelievingPressure as RelievingPressureInput
25
+ from ..outputs import Api520RelievingPressureOutput as RelievingPressureOutput
26
+
27
+ def relieving_pressure(inputs: RelievingPressureInput, *, context: Context | None = None) -> CalculationResult[RelievingPressureOutput]:
28
+ 'API 520 relieving pressure'
29
+ return calculate('api520/relieving-pressure', inputs, output_type=RelievingPressureOutput, context=context)
30
+
31
+
32
+ from ..api520 import GasCriticalArea as GasCriticalAreaInput
33
+ from ..outputs import Api520GasCriticalAreaOutput as GasCriticalAreaOutput
34
+
35
+ def gas_critical_area(inputs: GasCriticalAreaInput, *, context: Context | None = None) -> CalculationResult[GasCriticalAreaOutput]:
36
+ 'API 520 critical gas/vapor effective area'
37
+ return calculate('api520/gas-critical-area', inputs, output_type=GasCriticalAreaOutput, context=context)
38
+
39
+
40
+ from ..api520 import GasSubcriticalArea as GasSubcriticalAreaInput
41
+ from ..outputs import Api520GasSubcriticalAreaOutput as GasSubcriticalAreaOutput
42
+
43
+ def gas_subcritical_area(inputs: GasSubcriticalAreaInput, *, context: Context | None = None) -> CalculationResult[GasSubcriticalAreaOutput]:
44
+ 'API 520 subcritical gas/vapor effective area'
45
+ return calculate('api520/gas-subcritical-area', inputs, output_type=GasSubcriticalAreaOutput, context=context)
46
+
47
+
48
+ from ..api520 import LiquidArea as LiquidAreaInput
49
+ from ..outputs import Api520LiquidAreaOutput as LiquidAreaOutput
50
+
51
+ def liquid_area(inputs: LiquidAreaInput, *, context: Context | None = None) -> CalculationResult[LiquidAreaOutput]:
52
+ 'API 520 liquid relief effective area'
53
+ return calculate('api520/liquid-area', inputs, output_type=LiquidAreaOutput, context=context)
54
+
55
+
56
+ from ..api520 import ViscosityFactor as LiquidViscosityFactorInput
57
+ from ..outputs import Api520LiquidViscosityFactorOutput as LiquidViscosityFactorOutput
58
+
59
+ def liquid_viscosity_factor(inputs: LiquidViscosityFactorInput, *, context: Context | None = None) -> CalculationResult[LiquidViscosityFactorOutput]:
60
+ 'API 520 liquid viscosity correction Kv'
61
+ return calculate('api520/liquid-viscosity-factor', inputs, output_type=LiquidViscosityFactorOutput, context=context)
62
+
63
+
64
+ from ..api520 import GasCriticalCapacity as GasCriticalCapacityInput
65
+ from ..outputs import Api520GasCriticalCapacityOutput as GasCriticalCapacityOutput
66
+
67
+ def gas_critical_capacity(inputs: GasCriticalCapacityInput, *, context: Context | None = None) -> CalculationResult[GasCriticalCapacityOutput]:
68
+ 'API 520 critical gas/vapor mass capacity'
69
+ return calculate('api520/gas-critical-capacity', inputs, output_type=GasCriticalCapacityOutput, context=context)
70
+
71
+
72
+ from ..api520 import GasSubcriticalCapacity as GasSubcriticalCapacityInput
73
+ from ..outputs import Api520GasSubcriticalCapacityOutput as GasSubcriticalCapacityOutput
74
+
75
+ def gas_subcritical_capacity(inputs: GasSubcriticalCapacityInput, *, context: Context | None = None) -> CalculationResult[GasSubcriticalCapacityOutput]:
76
+ 'API 520 subcritical gas/vapor mass capacity'
77
+ return calculate('api520/gas-subcritical-capacity', inputs, output_type=GasSubcriticalCapacityOutput, context=context)
78
+
79
+
80
+ from ..api520 import LiquidCapacity as LiquidCapacityInput
81
+ from ..outputs import Api520LiquidCapacityOutput as LiquidCapacityOutput
82
+
83
+ def liquid_capacity(inputs: LiquidCapacityInput, *, context: Context | None = None) -> CalculationResult[LiquidCapacityOutput]:
84
+ 'API 520 liquid relief volumetric capacity'
85
+ return calculate('api520/liquid-capacity', inputs, output_type=LiquidCapacityOutput, context=context)
86
+
87
+
88
+ __all__ = ['critical_pressure_ratio', 'CriticalPressureRatioInput', 'CriticalPressureRatioOutput', 'flow_coefficient_c', 'FlowCoefficientCInput', 'FlowCoefficientCOutput', 'relieving_pressure', 'RelievingPressureInput', 'RelievingPressureOutput', 'gas_critical_area', 'GasCriticalAreaInput', 'GasCriticalAreaOutput', 'gas_subcritical_area', 'GasSubcriticalAreaInput', 'GasSubcriticalAreaOutput', 'liquid_area', 'LiquidAreaInput', 'LiquidAreaOutput', 'liquid_viscosity_factor', 'LiquidViscosityFactorInput', 'LiquidViscosityFactorOutput', 'gas_critical_capacity', 'GasCriticalCapacityInput', 'GasCriticalCapacityOutput', 'gas_subcritical_capacity', 'GasSubcriticalCapacityInput', 'GasSubcriticalCapacityOutput', 'liquid_capacity', 'LiquidCapacityInput', 'LiquidCapacityOutput']
api581/api/bundle.py ADDED
@@ -0,0 +1,121 @@
1
+ """Public bundle calculations. Inputs and outputs use named SI units.
2
+ Generated by scripts/build_python_api.py; inspect the request model for fields.
3
+ """
4
+ from ..core import Context
5
+ from ..result import CalculationResult, calculate
6
+
7
+ from ..bundle import LifeRecord as LifeRecordInput
8
+
9
+ from ..bundle import BundleHistory as WeibayesHistoryInput
10
+ from ..outputs import BundleWeibayesHistoryOutput as WeibayesHistoryOutput
11
+
12
+ def weibayes_history(inputs: WeibayesHistoryInput, *, context: Context | None = None) -> CalculationResult[WeibayesHistoryOutput]:
13
+ 'Fixed-shape bundle Weibayes life estimate'
14
+ return calculate('bundle/weibayes-history', inputs, output_type=WeibayesHistoryOutput, context=context)
15
+
16
+
17
+ from ..bundle import BundleConditionUpdate as ConditionUpdateInput
18
+ from ..outputs import BundleConditionUpdateOutput as ConditionUpdateOutput
19
+
20
+ def condition_update(inputs: ConditionUpdateInput, *, context: Context | None = None) -> CalculationResult[ConditionUpdateOutput]:
21
+ 'Add inspection-predicted bundle failure point'
22
+ return calculate('bundle/condition-update', inputs, output_type=ConditionUpdateOutput, context=context)
23
+
24
+
25
+ from ..bundle import BundleThicknessLife as ThicknessLifeInput
26
+ from ..outputs import BundleThicknessLifeOutput as ThicknessLifeOutput
27
+
28
+ def thickness_life(inputs: ThicknessLifeInput, *, context: Context | None = None) -> CalculationResult[ThicknessLifeOutput]:
29
+ 'Inspection-based tube thinning and predicted life'
30
+ return calculate('bundle/thickness-life', inputs, output_type=ThicknessLifeOutput, context=context)
31
+
32
+
33
+ from ..bundle import BundleEstimatedLife as EstimatedLifeInput
34
+ from ..outputs import BundleEstimatedLifeOutput as EstimatedLifeOutput
35
+
36
+ def estimated_life(inputs: EstimatedLifeInput, *, context: Context | None = None) -> CalculationResult[EstimatedLifeOutput]:
37
+ 'Predicted bundle life from estimated remaining life'
38
+ return calculate('bundle/estimated-life', inputs, output_type=EstimatedLifeOutput, context=context)
39
+
40
+
41
+ from ..bundle import BundleLifeExtension as LifeExtensionInput
42
+ from ..outputs import BundleLifeExtensionOutput as LifeExtensionOutput
43
+
44
+ def life_extension(inputs: LifeExtensionInput, *, context: Context | None = None) -> CalculationResult[LifeExtensionOutput]:
45
+ 'Effective bundle age after life-extension action'
46
+ return calculate('bundle/life-extension', inputs, output_type=LifeExtensionOutput, context=context)
47
+
48
+
49
+ from ..bundle import BundleConsequence as ConsequenceInput
50
+ from ..outputs import BundleConsequenceOutput as ConsequenceOutput
51
+
52
+ def consequence(inputs: ConsequenceInput, *, context: Context | None = None) -> CalculationResult[ConsequenceOutput]:
53
+ 'Bundle failure or planned replacement financial consequence'
54
+ return calculate('bundle/consequence', inputs, output_type=ConsequenceOutput, context=context)
55
+
56
+
57
+ from ..bundle import BundleRisk as RiskInput
58
+ from ..outputs import BundleRiskOutput as RiskOutput
59
+
60
+ def risk(inputs: RiskInput, *, context: Context | None = None) -> CalculationResult[RiskOutput]:
61
+ 'Bundle unreliability-weighted consequence'
62
+ return calculate('bundle/risk', inputs, output_type=RiskOutput, context=context)
63
+
64
+
65
+ from ..bundle import BundleTarget as TargetAgeInput
66
+ from ..outputs import BundleTargetAgeOutput as TargetAgeOutput
67
+
68
+ def target_age(inputs: TargetAgeInput, *, context: Context | None = None) -> CalculationResult[TargetAgeOutput]:
69
+ 'Bundle age at owner probability-weighted risk target'
70
+ return calculate('bundle/target-age', inputs, output_type=TargetAgeOutput, context=context)
71
+
72
+
73
+ from ..bundle import BundleDeferral as DeferralDecisionInput
74
+ from ..outputs import BundleDeferralDecisionOutput as DeferralDecisionOutput
75
+
76
+ def deferral_decision(inputs: DeferralDecisionInput, *, context: Context | None = None) -> CalculationResult[DeferralDecisionOutput]:
77
+ 'Conditional incremental risk and inspection/replacement economics'
78
+ return calculate('bundle/deferral-decision', inputs, output_type=DeferralDecisionOutput, context=context)
79
+
80
+
81
+ from ..bundle import BundleReplacement as ReplacementOptimizationInput
82
+ from ..outputs import BundleReplacementOptimizationOutput as ReplacementOptimizationOutput
83
+
84
+ def replacement_optimization(inputs: ReplacementOptimizationInput, *, context: Context | None = None) -> CalculationResult[ReplacementOptimizationOutput]:
85
+ 'Bundle planned-replacement grid cost optimization'
86
+ return calculate('bundle/replacement-optimization', inputs, output_type=ReplacementOptimizationOutput, context=context)
87
+
88
+
89
+ from ..bundle import BundleMaterial as MaterialFactorInput
90
+ from ..outputs import BundleMaterialFactorOutput as MaterialFactorOutput
91
+
92
+ def material_factor(inputs: MaterialFactorInput, *, context: Context | None = None) -> CalculationResult[MaterialFactorOutput]:
93
+ 'Bundle replacement material cost factor'
94
+ return calculate('bundle/material-factor', inputs, output_type=MaterialFactorOutput, context=context)
95
+
96
+
97
+ from ..bundle import BundleReplacementCost as ReplacementCostInput
98
+ from ..outputs import BundleReplacementCostOutput as ReplacementCostOutput
99
+
100
+ def replacement_cost(inputs: ReplacementCostInput, *, context: Context | None = None) -> CalculationResult[ReplacementCostOutput]:
101
+ 'Volume/material-scaled bundle replacement cost'
102
+ return calculate('bundle/replacement-cost', inputs, output_type=ReplacementCostOutput, context=context)
103
+
104
+
105
+ from ..bundle import BundleExtensionFactor as LifeExtensionFactorInput
106
+ from ..outputs import BundleLifeExtensionFactorOutput as LifeExtensionFactorOutput
107
+
108
+ def life_extension_factor(inputs: LifeExtensionFactorInput, *, context: Context | None = None) -> CalculationResult[LifeExtensionFactorOutput]:
109
+ 'Suggested bundle life-extension action factor'
110
+ return calculate('bundle/life-extension-factor', inputs, output_type=LifeExtensionFactorOutput, context=context)
111
+
112
+
113
+ from ..bundle import BundleCategories as CategoriesInput
114
+ from ..outputs import BundleCategoriesOutput as CategoriesOutput
115
+
116
+ def categories(inputs: CategoriesInput, *, context: Context | None = None) -> CalculationResult[CategoriesOutput]:
117
+ 'Bundle probability and financial consequence categories'
118
+ return calculate('bundle/categories', inputs, output_type=CategoriesOutput, context=context)
119
+
120
+
121
+ __all__ = ['LifeRecordInput', 'weibayes_history', 'WeibayesHistoryInput', 'WeibayesHistoryOutput', 'condition_update', 'ConditionUpdateInput', 'ConditionUpdateOutput', 'thickness_life', 'ThicknessLifeInput', 'ThicknessLifeOutput', 'estimated_life', 'EstimatedLifeInput', 'EstimatedLifeOutput', 'life_extension', 'LifeExtensionInput', 'LifeExtensionOutput', 'consequence', 'ConsequenceInput', 'ConsequenceOutput', 'risk', 'RiskInput', 'RiskOutput', 'target_age', 'TargetAgeInput', 'TargetAgeOutput', 'deferral_decision', 'DeferralDecisionInput', 'DeferralDecisionOutput', 'replacement_optimization', 'ReplacementOptimizationInput', 'ReplacementOptimizationOutput', 'material_factor', 'MaterialFactorInput', 'MaterialFactorOutput', 'replacement_cost', 'ReplacementCostInput', 'ReplacementCostOutput', 'life_extension_factor', 'LifeExtensionFactorInput', 'LifeExtensionFactorOutput', 'categories', 'CategoriesInput', 'CategoriesOutput']
@@ -0,0 +1,102 @@
1
+ """Public consequence calculations. Inputs and outputs use named SI units.
2
+ Generated by scripts/build_python_api.py; inspect the request model for fields.
3
+ """
4
+ from ..core import Context
5
+ from ..result import CalculationResult, calculate
6
+
7
+ from ..toxic_criteria import CriterionCandidate as CriterionCandidateInput
8
+ from ..consequences import HoleValue as HoleValueInput
9
+ from ..physical_explosion import NfntFrequencyCase as NfntFrequencyCaseInput
10
+ from ..risk import Outcome as OutcomeInput
11
+ from ..toxic_level2 import ToxicCloudArea as ToxicCloudAreaInput
12
+ from ..toxic_level2 import ToxicFrequencyCase as ToxicFrequencyCaseInput
13
+
14
+ from ..effects import EmpiricalArea as PowerLawAreaInput
15
+ from ..outputs import ConsequencePowerLawAreaOutput as PowerLawAreaOutput
16
+
17
+ def power_law_area(inputs: PowerLawAreaInput, *, context: Context | None = None) -> CalculationResult[PowerLawAreaOutput]:
18
+ 'Level 1 consequence power-law primitive'
19
+ return calculate('consequence/power-law-area', inputs, output_type=PowerLawAreaOutput, context=context)
20
+
21
+
22
+ from ..risk import Consequences as ExpectedInput
23
+ from ..outputs import ConsequenceExpectedOutput as ExpectedOutput
24
+
25
+ def expected(inputs: ExpectedInput, *, context: Context | None = None) -> CalculationResult[ExpectedOutput]:
26
+ 'Conditional event-weighted consequence'
27
+ return calculate('consequence/expected', inputs, output_type=ExpectedOutput, context=context)
28
+
29
+
30
+ from ..risk import Financial as FinancialTotalInput
31
+ from ..outputs import ConsequenceFinancialTotalOutput as FinancialTotalOutput
32
+
33
+ def financial_total(inputs: FinancialTotalInput, *, context: Context | None = None) -> CalculationResult[FinancialTotalOutput]:
34
+ 'Sum non-overlapping financial consequence categories'
35
+ return calculate('consequence/financial-total', inputs, output_type=FinancialTotalOutput, context=context)
36
+
37
+
38
+ from ..consequences import FinalArea as FinalAreaInput
39
+ from ..outputs import ConsequenceFinalAreaOutput as FinalAreaOutput
40
+
41
+ def final_area(inputs: FinalAreaInput, *, context: Context | None = None) -> CalculationResult[FinalAreaOutput]:
42
+ 'Final Level 1 consequence areas'
43
+ return calculate('consequence/final-area', inputs, output_type=FinalAreaOutput, context=context)
44
+
45
+
46
+ from ..consequences import Weighted as HoleWeightedInput
47
+ from ..outputs import ConsequenceHoleWeightedOutput as HoleWeightedOutput
48
+
49
+ def hole_weighted(inputs: HoleWeightedInput, *, context: Context | None = None) -> CalculationResult[HoleWeightedOutput]:
50
+ 'Generic-frequency weighted four-hole consequence'
51
+ return calculate('consequence/hole-weighted', inputs, output_type=HoleWeightedOutput, context=context)
52
+
53
+
54
+ from ..physical_explosion import NfntCase as Level2NfntCaseInput
55
+ from ..outputs import ConsequenceLevel2NfntCaseOutput as Level2NfntCaseOutput
56
+
57
+ def level2_nfnt_case(inputs: Level2NfntCaseInput, *, context: Context | None = None) -> CalculationResult[Level2NfntCaseOutput]:
58
+ 'Level2 NFNT maximum areas and non-ignition weighting'
59
+ return calculate('consequence/level2-nfnt-case', inputs, output_type=Level2NfntCaseOutput, context=context)
60
+
61
+
62
+ from ..physical_explosion import NfntSummary as Level2NfntSummaryInput
63
+ from ..outputs import ConsequenceLevel2NfntSummaryOutput as Level2NfntSummaryOutput
64
+
65
+ def level2_nfnt_summary(inputs: Level2NfntSummaryInput, *, context: Context | None = None) -> CalculationResult[Level2NfntSummaryOutput]:
66
+ 'Four-hole Level2 NFNT GFF-weighted final areas'
67
+ return calculate('consequence/level2-nfnt-summary', inputs, output_type=Level2NfntSummaryOutput, context=context)
68
+
69
+
70
+ from ..toxic_level2 import MixtureLimit as ToxicMixtureLimitInput
71
+ from ..outputs import ConsequenceToxicMixtureLimitOutput as ToxicMixtureLimitOutput
72
+
73
+ def toxic_mixture_limit(inputs: ToxicMixtureLimitInput, *, context: Context | None = None) -> CalculationResult[ToxicMixtureLimitOutput]:
74
+ 'Homogeneous mixture cloud toxic concentration criterion'
75
+ return calculate('consequence/toxic-mixture-limit', inputs, output_type=ToxicMixtureLimitOutput, context=context)
76
+
77
+
78
+ from ..toxic_level2 import ToxicCase as Level2ToxicCaseInput
79
+ from ..outputs import ConsequenceLevel2ToxicCaseOutput as Level2ToxicCaseOutput
80
+
81
+ def level2_toxic_case(inputs: Level2ToxicCaseInput, *, context: Context | None = None) -> CalculationResult[Level2ToxicCaseOutput]:
82
+ 'Selected toxic cloud footprints to conditional toxic consequence'
83
+ return calculate('consequence/level2-toxic-case', inputs, output_type=Level2ToxicCaseOutput, context=context)
84
+
85
+
86
+ from ..toxic_level2 import ToxicSummary as Level2ToxicSummaryInput
87
+ from ..outputs import ConsequenceLevel2ToxicSummaryOutput as Level2ToxicSummaryOutput
88
+
89
+ def level2_toxic_summary(inputs: Level2ToxicSummaryInput, *, context: Context | None = None) -> CalculationResult[Level2ToxicSummaryOutput]:
90
+ 'Four-hole GFF-weighted Level2 toxic consequence'
91
+ return calculate('consequence/level2-toxic-summary', inputs, output_type=Level2ToxicSummaryOutput, context=context)
92
+
93
+
94
+ from ..toxic_criteria import ToxicCriterion as SelectToxicCriterionInput
95
+ from ..outputs import ConsequenceSelectToxicCriterionOutput as SelectToxicCriterionOutput
96
+
97
+ def select_toxic_criterion(inputs: SelectToxicCriterionInput, *, context: Context | None = None) -> CalculationResult[SelectToxicCriterionOutput]:
98
+ 'Select duration-matched toxic criterion by API581 priority'
99
+ return calculate('consequence/select-toxic-criterion', inputs, output_type=SelectToxicCriterionOutput, context=context)
100
+
101
+
102
+ __all__ = ['CriterionCandidateInput', 'HoleValueInput', 'NfntFrequencyCaseInput', 'OutcomeInput', 'ToxicCloudAreaInput', 'ToxicFrequencyCaseInput', 'power_law_area', 'PowerLawAreaInput', 'PowerLawAreaOutput', 'expected', 'ExpectedInput', 'ExpectedOutput', 'financial_total', 'FinancialTotalInput', 'FinancialTotalOutput', 'final_area', 'FinalAreaInput', 'FinalAreaOutput', 'hole_weighted', 'HoleWeightedInput', 'HoleWeightedOutput', 'level2_nfnt_case', 'Level2NfntCaseInput', 'Level2NfntCaseOutput', 'level2_nfnt_summary', 'Level2NfntSummaryInput', 'Level2NfntSummaryOutput', 'toxic_mixture_limit', 'ToxicMixtureLimitInput', 'ToxicMixtureLimitOutput', 'level2_toxic_case', 'Level2ToxicCaseInput', 'Level2ToxicCaseOutput', 'level2_toxic_summary', 'Level2ToxicSummaryInput', 'Level2ToxicSummaryOutput', 'select_toxic_criterion', 'SelectToxicCriterionInput', 'SelectToxicCriterionOutput']