[17]:
%matplotlib inline
%load_ext autoreload
%autoreload 2
The autoreload extension is already loaded. To reload it, use:
%reload_ext autoreload
[18]:
import math
import numpy as np
import matplotlib.pyplot as plt
from helpr.api import CrackEvolutionAnalysis
from helpr.physics.pipe import Pipe
from helpr.physics.crack_initiation import DefectSpecification
from helpr.physics.environment import EnvironmentSpecification
from helpr.physics.material import MaterialSpecification
from helpr.physics.stress_state import InternalAxialHoopStress
from helpr.physics.crack_growth import CrackGrowth, get_design_curve
from helpr.physics.life_assessment import LifeAssessment
from helpr.physics.fracture import calculate_failure_assessment
from helpr.utilities.unit_conversion import convert_psi_to_mpa, convert_in_to_m
from helpr.utilities.plots import generate_pipe_life_assessment_plot
from helpr.utilities.postprocessing import calc_pipe_life_criteria, report_single_pipe_life_criteria_results, report_single_cycle_evolution
from probabilistic.capabilities.uncertainty_definitions import DeterministicCharacterization
Single Deterministic Pipeline Lifetime Evaluation
Problem Specification
Geometry
[19]:
pipe_outer_diameter = convert_in_to_m(36) # 36 inch outer diameter
wall_thickness = convert_in_to_m(0.406) # 0.406 inch wall thickness
Material Properties
[20]:
yield_strength = convert_psi_to_mpa(52_000) # material yield strength of 52_000 psi
fracture_resistance = 55 # fracture resistance (toughness) MPa m1/2
Operating Conditions
[21]:
max_pressure = convert_psi_to_mpa(840) # maximum pressure during oscillation MPa
min_pressure = convert_psi_to_mpa(638) # minimum pressure during oscillation (or R = 0.75)
temperature = 293 # K -> temperature of gas degrees C
volume_fraction_h2 = 1 # % mole fraction H2 in natural gas blend
Initial Crack Dimensions
[22]:
flaw_depth = 25 # flaw 25% through pipe thickness
flaw_length = convert_in_to_m(1.575) # width of initial crack/flaw, m
Physics Modeling Choices
[23]:
stress_intensity_method = 'anderson' # Stress intensity factor method used
surface = 'inside'
Modular Analysis
Create Pipe Object
[24]:
pipe_module = Pipe(outer_diameter=pipe_outer_diameter,
wall_thickness=wall_thickness)
Specify Pipe Material Properties
[25]:
material_module = MaterialSpecification(yield_strength=yield_strength,
fracture_resistance=fracture_resistance)
Specify Defect
[26]:
defect_module = DefectSpecification(flaw_depth=flaw_depth,
flaw_length=flaw_length,
surface=surface)
Specify Pipe Gaseous Environment
[27]:
environment_module = EnvironmentSpecification(max_pressure=max_pressure,
min_pressure=min_pressure,
temperature=temperature,
volume_fraction_h2=volume_fraction_h2)
Determine Stress Environment on Pipe
[28]:
stress_module = InternalAxialHoopStress(pipe=pipe_module,
environment=environment_module,
material=material_module,
defect=defect_module,
stress_intensity_method=stress_intensity_method)
/Users/bbschro/Development/helpr/src/helpr/physics/stress_state.py:521: UserWarning: Inner Radius / wall thickness exceeds bounds 5 <= R_i/t <= 20, R_i/t = 43.33497536945812, violating Anderson solution limits.
wr.warn('Inner Radius / wall thickness exceeds bounds ' +
Specify Crack Growth Model
[29]:
crack_growth_module = CrackGrowth(environment=environment_module,
growth_model_specification={'model_name': 'code_case_2938'})
Evolve Cracks Over Cycles to Failure
[30]:
pipe_evaluation = LifeAssessment(pipe_specification=pipe_module,
stress_state=stress_module,
crack_growth=crack_growth_module,
delta_c_rule='proportional')
load_cycling = pipe_evaluation.calc_life_assessment(max_cycles=math.inf, cycle_step=None)
Postprocess QoIs (life criteria)
[31]:
input_parameter_values = {'flaw_depth': [flaw_depth],
'max_pressure': [max_pressure],
'min_pressure': [min_pressure],
'temperature': [temperature],
'volume_fraction_h2': [volume_fraction_h2],
'outer_diameter': [pipe_outer_diameter],
'wall_thickness': [wall_thickness],
'yield_strength': [yield_strength],
'fracture_resistance': [fracture_resistance],
'flaw_length': [flaw_length]}
calculate_failure_assessment(input_parameter_values,
[load_cycling],
[stress_module],
fad_type='simple')
life_criteria = calc_pipe_life_criteria(cycle_results=load_cycling,
pipe=pipe_module,
material=material_module)
Plot QoI
[32]:
specific_life_criteria_result = report_single_pipe_life_criteria_results(life_criteria, pipe_index=0)
specific_load_cycling = report_single_cycle_evolution(load_cycling, pipe_index=0)
generate_pipe_life_assessment_plot(specific_load_cycling, specific_life_criteria_result, pipe_name='Test Pipe')
plt.savefig('./Figures/deterministic_crack_growth.png', format='png', dpi=300)
Cycles to a(crit) Cycles to 25% a(crit) Cycles to 1/2 Nc \
Total cycles 5669.412446 1.000000 2834.706223
a/t 0.333509 0.083377 0.270803
Cycles to FAD line
Total cycles 4872.658604
a/t 0.302642
Interact with Modular Analysis Through API
Specify Problem, Initiate Crack, and Evolve Crack to Failure
[33]:
analysis = CrackEvolutionAnalysis(outer_diameter=DeterministicCharacterization(name='outer_diameter', value=pipe_outer_diameter),
wall_thickness=DeterministicCharacterization(name='wall_thickness', value=wall_thickness),
flaw_depth=DeterministicCharacterization(name='flaw_depth', value=flaw_depth),
max_pressure=DeterministicCharacterization(name='max_pressure', value=max_pressure),
min_pressure=DeterministicCharacterization(name='min_pressure', value=min_pressure),
temperature=DeterministicCharacterization(name='temperature', value=temperature),
volume_fraction_h2=DeterministicCharacterization(name='volume_fraction_h2', value=volume_fraction_h2),
yield_strength=DeterministicCharacterization(name='yield_strength', value=yield_strength),
fracture_resistance=DeterministicCharacterization(name='fracture_resistance', value=fracture_resistance),
flaw_length=DeterministicCharacterization(name='flaw_length', value=flaw_length),
stress_intensity_method=stress_intensity_method,
surface=surface,
fad_type='simple',
cycle_step=1)
analysis.perform_study()
/Users/bbschro/Development/helpr/src/helpr/physics/stress_state.py:521: UserWarning: Inner Radius / wall thickness exceeds bounds 5 <= R_i/t <= 20, R_i/t = 43.33497536945812, violating Anderson solution limits.
wr.warn('Inner Radius / wall thickness exceeds bounds ' +
Postprocess and Plot QoI
[34]:
analysis.postprocess_single_crack_results()
_, _ = analysis.get_design_curve_plot()
plt.savefig('./Figures/deterministic_crack_growth_rate.png', format='png', dpi=300)
_, _ = analysis.assemble_failure_assessment_diagram()
Cycles to a(crit) Cycles to 25% a(crit) Cycles to 1/2 Nc \
Total cycles 5702.066633 1.000000 2851.033316
a/t 0.333509 0.083377 0.270839
Cycles to FAD line
Total cycles 4898.324240
a/t 0.302642
[35]:
analysis.save_results()
[35]:
'Results/date_30_03_2026_time_16_31/'