[1]:
%matplotlib inline
%load_ext autoreload
%autoreload 2
[2]:
import matplotlib.pyplot as plt

from helpr.api import CrackEvolutionAnalysis
from helpr.utilities.unit_conversion import convert_in_to_m, convert_psi_to_mpa

from probabilistic.capabilities.uncertainty_definitions import DeterministicCharacterization, TruncatedLognormalDistribution

Advanced User Options

Specify Common User Inputs

[3]:
# Pipe dimensions
outer_diameter = DeterministicCharacterization(name='outer_diameter', value=convert_in_to_m(36))
wall_thickness = DeterministicCharacterization(name='wall_thickness', value=convert_in_to_m(0.406))
# Gas environment
max_pressure = DeterministicCharacterization(name='max_pressure', value=convert_psi_to_mpa(840))
min_pressure = DeterministicCharacterization(name='min_pressure', value=convert_psi_to_mpa(638))
temperature = DeterministicCharacterization(name='temperature', value=293)
volume_fraction_h2 = DeterministicCharacterization(name='volume_fraction_h2', value=1)
# Pipe material properties
yield_strength = DeterministicCharacterization(name='yield_strength', value=convert_psi_to_mpa(52_000))
fracture_resistance = DeterministicCharacterization(name='fracture_resistance', value=55)
# Flaw geometry
flaw_depth = DeterministicCharacterization(name='flaw_depth', value=25)
flaw_length = DeterministicCharacterization(name='flaw_length', value=convert_in_to_m(1.575))

Varying Crack Width Growth Assumption

[4]:
# Fixed model assumptions
stress_intensity_method='api'
surface='inside'

analysis_prop = \
    CrackEvolutionAnalysis(outer_diameter=outer_diameter,
                           wall_thickness=wall_thickness,
                           max_pressure=max_pressure,
                           min_pressure=min_pressure,
                           temperature=temperature,
                           volume_fraction_h2=volume_fraction_h2,
                           yield_strength=yield_strength,
                           fracture_resistance=fracture_resistance,
                           flaw_depth=flaw_depth,
                           flaw_length=flaw_length,
                           stress_intensity_method=stress_intensity_method,
                           surface=surface,
                           delta_c_rule='proportional')
analysis_prop.perform_study()

analysis_fix = CrackEvolutionAnalysis(outer_diameter=outer_diameter,
                                  wall_thickness=wall_thickness,
                                  max_pressure=max_pressure,
                                  min_pressure=min_pressure,
                                  temperature=temperature,
                                  volume_fraction_h2=volume_fraction_h2,
                                  yield_strength=yield_strength,
                                  fracture_resistance=fracture_resistance,
                                  flaw_depth=flaw_depth,
                                  flaw_length=flaw_length,
                                  stress_intensity_method=stress_intensity_method,
                                  surface=surface,
                                  delta_c_rule='fixed')
analysis_fix.perform_study()

analysis_ind = CrackEvolutionAnalysis(outer_diameter=outer_diameter,
                                  wall_thickness=wall_thickness,
                                  max_pressure=max_pressure,
                                  min_pressure=min_pressure,
                                  temperature=temperature,
                                  volume_fraction_h2=volume_fraction_h2,
                                  yield_strength=yield_strength,
                                  fracture_resistance=fracture_resistance,
                                  flaw_depth=flaw_depth,
                                  flaw_length=flaw_length,
                                  stress_intensity_method=stress_intensity_method,
                                  surface=surface,
                                  delta_c_rule='independent')
analysis_ind.perform_study()
/Users/bbschro/Development/helpr/src/helpr/utilities/postprocessing.py:363: UserWarning: Kmax + Kres did not reach fracture resistance for at least one crack, setting a_crit/t = 0.8 for such cracks
  wr.warn('Kmax + Kres did not reach fracture resistance for at least one crack, ' +
/Users/bbschro/Development/helpr/src/helpr/utilities/postprocessing.py:363: UserWarning: Kmax + Kres did not reach fracture resistance for at least one crack, setting a_crit/t = 0.8 for such cracks
  wr.warn('Kmax + Kres did not reach fracture resistance for at least one crack, ' +
[5]:
fig, ax1 = plt.subplots(figsize=(4,4))
ax2 = ax1.twinx()

ax1.plot([], [], color='gray', linestyle='-', label='proportional')
ax1.plot([], [], color='gray', linestyle='--', label='fixed')
ax1.plot([], [], color='gray', linestyle=':', label='independent')

ax1.plot(analysis_prop.nominal_load_cycling[0]['Total cycles'],
         analysis_prop.nominal_load_cycling[0]['a (m)'],
         'r-')
ax2.plot(analysis_prop.nominal_load_cycling[0]['Total cycles'],
         analysis_prop.nominal_load_cycling[0]['c (m)'],
         'b-')
ax1.plot(analysis_fix.nominal_load_cycling[0]['Total cycles'],
         analysis_fix.nominal_load_cycling[0]['a (m)'],
         'r--')
ax2.plot(analysis_fix.nominal_load_cycling[0]['Total cycles'],
         analysis_fix.nominal_load_cycling[0]['c (m)'],
         'b--')
ax1.plot(analysis_ind.nominal_load_cycling[0]['Total cycles'],
         analysis_ind.nominal_load_cycling[0]['a (m)'],
         'r:')
ax2.plot(analysis_ind.nominal_load_cycling[0]['Total cycles'],
         analysis_ind.nominal_load_cycling[0]['c (m)'],
         'b:')

ax1.set_xlabel('Total cycles')
ax1.set_ylabel('a (m)', color='r')
ax2.set_ylabel('c (m)', color='b')

ax1.legend(loc=0, title='c growth assumption')
plt.grid(color='gray', alpha=0.3, linestyle='--')
_images/demo_advanced_user_options_7_0.png
[6]:
fig, ax1 = plt.subplots(figsize=(4,4))
ax2 = ax1.twinx()
ax1.plot([], [], color='gray', linestyle='-', label='proportional')
ax1.plot(analysis_prop.nominal_load_cycling[0]['Total cycles'],
         analysis_prop.nominal_load_cycling[0]['a (m)'],
         'r-')
ax2.plot(analysis_prop.nominal_load_cycling[0]['Total cycles'],
         analysis_prop.nominal_load_cycling[0]['c (m)'],
         'b-')
ax1.set_xlabel('Total cycles')
ax1.set_ylabel('a (m)', color='r')
ax2.set_ylabel('c (m)', color='b')

ax1.legend(loc=0, title='c growth assumption')
plt.grid(color='gray', alpha=0.3, linestyle='--')
_images/demo_advanced_user_options_8_0.png
[7]:
fig, ax1 = plt.subplots(figsize=(4,4))
ax2 = ax1.twinx()
ax1.plot([], [], color='gray', linestyle='--', label='fixed')
ax1.plot(analysis_fix.nominal_load_cycling[0]['Total cycles'],
         analysis_fix.nominal_load_cycling[0]['a (m)'],
         'r--')
ax2.plot(analysis_fix.nominal_load_cycling[0]['Total cycles'],
         analysis_fix.nominal_load_cycling[0]['c (m)'],
         'b--')
ax1.set_xlabel('Total cycles')
ax1.set_ylabel('a (m)', color='r')
ax2.set_ylabel('c (m)', color='b')

ax1.legend(loc=0, title='c growth assumption')
plt.grid(color='gray', alpha=0.3, linestyle='--')
_images/demo_advanced_user_options_9_0.png
[8]:
fig, ax1 = plt.subplots(figsize=(4,4))
ax2 = ax1.twinx()
ax1.plot([], [], color='gray', linestyle=':', label='independent')
ax1.plot(analysis_ind.nominal_load_cycling[0]['Total cycles'],
         analysis_ind.nominal_load_cycling[0]['a (m)'],
         'r:')
ax2.plot(analysis_ind.nominal_load_cycling[0]['Total cycles'],
         analysis_ind.nominal_load_cycling[0]['c (m)'],
         'b:')
ax1.set_xlabel('Total cycles')
ax1.set_ylabel('a (m)', color='r')
ax2.set_ylabel('c (m)', color='b')

ax1.legend(loc=0, title='c growth assumption')
plt.grid(color='gray', alpha=0.3, linestyle='--')
_images/demo_advanced_user_options_10_0.png

Varying Stress Intensity Factor Method

[9]:
# Fixed model assumptions
delta_c_rule='proportional'

analysis_and = CrackEvolutionAnalysis(outer_diameter=outer_diameter,
                                  wall_thickness=wall_thickness,
                                  max_pressure=max_pressure,
                                  min_pressure=min_pressure,
                                  temperature=temperature,
                                  volume_fraction_h2=volume_fraction_h2,
                                  yield_strength=yield_strength,
                                  fracture_resistance=fracture_resistance,
                                  flaw_depth=flaw_depth,
                                  flaw_length=flaw_length,
                                  stress_intensity_method='anderson',
                                  surface='inside',
                                  delta_c_rule=delta_c_rule)
analysis_and.perform_study()

analysis_api_in = CrackEvolutionAnalysis(outer_diameter=outer_diameter,
                                  wall_thickness=wall_thickness,
                                  max_pressure=max_pressure,
                                  min_pressure=min_pressure,
                                  temperature=temperature,
                                  volume_fraction_h2=volume_fraction_h2,
                                  yield_strength=yield_strength,
                                  fracture_resistance=fracture_resistance,
                                  flaw_depth=flaw_depth,
                                  flaw_length=flaw_length,
                                  stress_intensity_method='api',
                                  surface='inside',
                                  delta_c_rule=delta_c_rule)
analysis_api_in.perform_study()

analysis_api_out = CrackEvolutionAnalysis(outer_diameter=outer_diameter,
                                  wall_thickness=wall_thickness,
                                  max_pressure=max_pressure,
                                  min_pressure=min_pressure,
                                  temperature=temperature,
                                  volume_fraction_h2=volume_fraction_h2,
                                  yield_strength=yield_strength,
                                  fracture_resistance=fracture_resistance,
                                  flaw_depth=flaw_depth,
                                  flaw_length=flaw_length,
                                  stress_intensity_method='api',
                                  surface='outside',
                                  delta_c_rule=delta_c_rule)
analysis_api_out.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 ' +
[10]:
fig, ax1 = plt.subplots(figsize=(4,4))
ax2 = ax1.twinx()

ax1.plot([], [], color='gray', linestyle='-', label='Anderson')
ax1.plot([], [], color='gray', linestyle='--', label='API internal')
ax1.plot([], [], color='gray', linestyle=':', label='API external')

ax1.plot(analysis_and.nominal_load_cycling[0]['Total cycles'],
         analysis_and.nominal_load_cycling[0]['a (m)'],
         'r-')
ax2.plot(analysis_and.nominal_load_cycling[0]['Total cycles'],
         analysis_and.nominal_load_cycling[0]['Kmax (MPa m^1/2)'],
         'b-')
ax1.plot(analysis_api_in.nominal_load_cycling[0]['Total cycles'],
         analysis_api_in.nominal_load_cycling[0]['a (m)'],
         'r--')
ax2.plot(analysis_api_in.nominal_load_cycling[0]['Total cycles'],
         analysis_api_in.nominal_load_cycling[0]['Kmax (MPa m^1/2)'],
         'b--')
ax1.plot(analysis_api_out.nominal_load_cycling[0]['Total cycles'],
         analysis_api_out.nominal_load_cycling[0]['a (m)'],
         'r:')
ax2.plot(analysis_api_out.nominal_load_cycling[0]['Total cycles'],
         analysis_api_out.nominal_load_cycling[0]['Kmax (MPa m^1/2)'],
         'b:')

ax1.set_xlabel('Total cycles')
ax1.set_ylabel('a (m)', color='r')
ax2.set_ylabel(r'Kmax (MPa m$^{1/2}$)', color='b')

ax1.legend(loc=0, title='K Solution assumption')
plt.grid(color='gray', alpha=0.3, linestyle='--')
_images/demo_advanced_user_options_13_0.png

Compare Crack Evolution in terms of a/t vs cycles

[11]:
stress_intensity_method = 'anderson'
surface = 'inside'
delta_c_rule = 'proportional'

analysis_aovert = CrackEvolutionAnalysis(outer_diameter=outer_diameter,
                                  wall_thickness=wall_thickness,
                                  max_pressure=max_pressure,
                                  min_pressure=min_pressure,
                                  temperature=temperature,
                                  volume_fraction_h2=volume_fraction_h2,
                                  yield_strength=yield_strength,
                                  fracture_resistance=fracture_resistance,
                                  flaw_depth=flaw_depth,
                                  flaw_length=flaw_length,
                                  stress_intensity_method=stress_intensity_method,
                                  surface=surface,
                                  delta_c_rule=delta_c_rule)
analysis_aovert.perform_study()

analysis_cycles = CrackEvolutionAnalysis(outer_diameter=outer_diameter,
                                  wall_thickness=wall_thickness,
                                  max_pressure=max_pressure,
                                  min_pressure=min_pressure,
                                  temperature=temperature,
                                  volume_fraction_h2=volume_fraction_h2,
                                  yield_strength=yield_strength,
                                  fracture_resistance=fracture_resistance,
                                  flaw_depth=flaw_depth,
                                  flaw_length=flaw_length,
                                  stress_intensity_method=stress_intensity_method,
                                  surface=surface,
                                  delta_c_rule=delta_c_rule,
                                  cycle_step=1)
analysis_cycles.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 ' +
[12]:
fig, ax1 = plt.subplots(figsize=(4,4))
ax1.plot(analysis_aovert.nominal_load_cycling[0]['Total cycles'],
         analysis_aovert.nominal_load_cycling[0]['a/t'],
         'r-', label='a/t')
ax1.plot(analysis_aovert.nominal_life_criteria['Cycles to a(crit)'][0],
         analysis_aovert.nominal_life_criteria['Cycles to a(crit)'][1],
         'r*')

ax1.plot(analysis_cycles.nominal_load_cycling[0]['Total cycles'],
         analysis_cycles.nominal_load_cycling[0]['a/t'],
         'b--', label='cycles')
ax1.plot(analysis_cycles.nominal_life_criteria['Cycles to a(crit)'][0],
         analysis_cycles.nominal_life_criteria['Cycles to a(crit)'][1],
         'b.')

ax1.set_xlabel('Total cycles')
ax1.set_ylabel('a/t')

ax1.legend(loc=0, title='Differential of')
plt.grid(color='gray', alpha=0.3, linestyle='--')
_images/demo_advanced_user_options_16_0.png
[13]:
flaw_depth = TruncatedLognormalDistribution(name='flaw_depth',
                                            uncertainty_type='aleatory',
                                            nominal_value=25,
                                            mu=3.2,
                                            sigma=.17,
                                            upper_bound=80,
                                            lower_bound=0.001) # initial flaw depth, % wall thickness


stress_intensity_method = 'anderson'
surface = 'inside'
delta_c_rule = 'proportional'
samples = 50
sample_type = 'lhs'
[14]:
%%time

analysis_aovert_prob = CrackEvolutionAnalysis(outer_diameter=outer_diameter,
                                  wall_thickness=wall_thickness,
                                  max_pressure=max_pressure,
                                  min_pressure=min_pressure,
                                  temperature=temperature,
                                  volume_fraction_h2=volume_fraction_h2,
                                  yield_strength=yield_strength,
                                  fracture_resistance=fracture_resistance,
                                  flaw_depth=flaw_depth,
                                  flaw_length=flaw_length,
                                  stress_intensity_method=stress_intensity_method,
                                  surface=surface,
                                  delta_c_rule=delta_c_rule,
                                  aleatory_samples=samples,
                                  sample_type=sample_type,
                                  random_seed=1234,
                                  max_cycles=2e4)
analysis_aovert_prob.perform_study()
CPU times: user 41.9 ms, sys: 54.8 ms, total: 96.7 ms
Wall time: 2.34 s
/Users/bbschro/Development/helpr/src/helpr/utilities/postprocessing.py:359: UserWarning: Cycles to a_crit not reached for at least one crack, setting a_crit = Nan for such cracks
  wr.warn('Cycles to a_crit not reached for at least one crack, ' +
[15]:
%%time

analysis_cycles_prob = CrackEvolutionAnalysis(outer_diameter=outer_diameter,
                                  wall_thickness=wall_thickness,
                                  max_pressure=max_pressure,
                                  min_pressure=min_pressure,
                                  temperature=temperature,
                                  volume_fraction_h2=volume_fraction_h2,
                                  yield_strength=yield_strength,
                                  fracture_resistance=fracture_resistance,
                                  flaw_depth=flaw_depth,
                                  flaw_length=flaw_length,
                                  stress_intensity_method=stress_intensity_method,
                                  surface=surface,
                                  delta_c_rule=delta_c_rule,
                                  cycle_step=1,
                                  aleatory_samples=samples,
                                  sample_type=sample_type,
                                  random_seed=1234,
                                  max_cycles=2e4)
analysis_cycles_prob.perform_study()
CPU times: user 466 ms, sys: 112 ms, total: 577 ms
Wall time: 3.4 s
[16]:
fig, ax1 = plt.subplots(figsize=(6,4))

plt.plot([], [], 'r-', label='a/t')
plt.plot([], [], 'b--', label='cycles')
for i in range(samples):
    ax1.plot(analysis_aovert_prob.load_cycling[i]['Total cycles'],
             analysis_aovert_prob.load_cycling[i]['a/t'],
             'r-')
    ax1.plot(analysis_cycles_prob.load_cycling[i]['Total cycles'],
             analysis_cycles_prob.load_cycling[i]['a/t'],
             'b--')

ax1.plot(analysis_aovert_prob.life_criteria['Cycles to a(crit)'][0],
        analysis_aovert_prob.life_criteria['Cycles to a(crit)'][1],
        'r*')
ax1.plot(analysis_cycles_prob.life_criteria['Cycles to a(crit)'][0],
        analysis_cycles_prob.life_criteria['Cycles to a(crit)'][1],
        'b.')

ax1.set_xlabel('Total cycles')
ax1.set_ylabel('a/t')

ax1.legend(loc=0, title='Differential of')
plt.grid(color='gray', alpha=0.3, linestyle='--')
_images/demo_advanced_user_options_20_0.png