Source code for pysubsea.pipe_soil_interaction_tools

"""
This module provides classes and functions for calculating the capacity of soils using various
models for a given pipe and soil configuration.

**Features:**

- The `PSI` class implements soil capacity calculations for different pipe and soil properties,
  supporting vectorized and model-based approaches.
- Designed for use in subsea pipeline and riser engineering, but general enough for any
  pipe-soil interaction analysis.
- All calculations are vectorized using NumPy for efficiency and flexibility.

.. raw:: html

   <hr style="height:6px; background-color:#888; border:none; margin:1.5em 0;" />

"""

import numpy as np

[docs] class PSI: # pylint: disable=too-many-arguments """ Class for calculating the capacity of soils using various models for a given pipe and soil configuration. Parameters ---------- diameter : float, optional Diameter of the pipe. surface_roughness : str, optional Surface roughness of the pipe ('Smooth' or 'Rough'). density : float, optional Density of the soil. surcharge_on_seabed : float, optional Stress or surcharge at the elevation of the seabed. burial_depth : float, optional Depth of burial. """ def __init__( self, *, total_outer_diameter=0.0, surface_roughness=None, density=0.0, surcharge_on_seabed=0.0, burial_depth=0.0 ): """ Initialize a PipeSoilInteraction object with pipe and soil properties. """ self.total_outer_diameter = np.asarray(total_outer_diameter, dtype = float) self.surface_roughness = np.asarray(surface_roughness, dtype = object) self.density = np.asarray(density, dtype = float) self.surcharge_on_seabed = np.asarray(surcharge_on_seabed, dtype = float) self.burial_depth = np.asarray(burial_depth, dtype = float)
[docs] def downward_undrained_model1(self): # pylint: disable=too-many-locals """ Calculate the vertical bearing capacity of soil using the downward undrained model. Returns ------- depth_arrays : np.ndarray Array of depth arrays for each total_outer_diameter value. vertical_bearing_capacity_arrays : np.ndarray Array of vertical bearing capacity arrays for each total_outer_diameter value. Examples -------- >>> psi = PSI( ... total_outer_diameter=[0.2731], ... surface_roughness=['Smooth'], ... density=[1000.0], ... surcharge_on_seabed=[100], ... burial_depth=[1.0] ... ) >>> psi.downward_undrained_model1() (array([[0. , 0.005, ... 0.995, 1. ]]), array([[ 0. , 920.50185636, ... 7141.92857341, 7163.61163085]])) """ depth_arrays = [] vertical_bearing_capacity_arrays = [] for i, outer_diameter in enumerate(self.total_outer_diameter): # Access corresponding values for other attributes using the index `i` surface_roughness = self.surface_roughness[i] density = self.density[i] surcharge_on_seabed = self.surcharge_on_seabed[i] burial_depth = self.burial_depth[i] # Generate depth array depth = np.linspace(0.005, 1, 200) # Calculate width using vectorized operations width = np.where( depth < outer_diameter / 2, 2 * np.sqrt(np.maximum(outer_diameter * depth - depth ** 2, 0)), outer_diameter ) # Calculate undrained shear strength using vectorized operations undrained_shear_strength = np.where( depth < outer_diameter / 2 * (1 - np.sqrt(2) / 2.), 0.0, depth + outer_diameter / 2 * (np.sqrt(2) - 1) - width / 2 ) initial_shear_strength = surcharge_on_seabed + density * undrained_shear_strength friction_factor = np.divide(np.multiply(density, width), initial_shear_strength) friction_factor_reference = np.linspace(0, 16, 17) if surface_roughness == 'Smooth': friction_factor_values = np.array( [1.00, 1.12, 1.19, 1.24, 1.28, 1.31, 1.34, 1.36, 1.38, 1.39, 1.40, 1.41, 1.42, 1.43, 1.44, 1.445, 1.45] ) else: friction_factor_values = np.array( [1.00, 1.23, 1.36, 1.44, 1.50, 1.55, 1.59, 1.61, 1.64, 1.66, 1.67, 1.69, 1.70, 1.71, 1.72, 1.730, 1.74] ) interpolated_friction_factor = np.interp( friction_factor, friction_factor_reference, friction_factor_values ) vertical_bearing_capacity = interpolated_friction_factor * ( 5.14 * initial_shear_strength + density * width / 4 + density * 9.807 * burial_depth ) * width average_shear_strength_1 = (surcharge_on_seabed + initial_shear_strength) / 2.0 average_shear_strength_2 = vertical_bearing_capacity / width / 5.14 depth_correction_factor = 0.3 * average_shear_strength_1 / average_shear_strength_2 * \ np.arctan2(undrained_shear_strength, width) bearing_capacity_modifier = np.where( depth < outer_diameter / 2, np.arcsin(width / outer_diameter) * outer_diameter ** 2 / 4 + width * outer_diameter / 4 * np.cos(np.arcsin(width / outer_diameter)), np.pi * outer_diameter ** 2 / 8 + outer_diameter * (depth - outer_diameter / 2) ) vertical_bearing_capacity = ( vertical_bearing_capacity * (1 + depth_correction_factor) + density * 9.807 * bearing_capacity_modifier ) # Append depth and vertical_bearing_capacity arrays for this outer_diameter depth_arrays.append(np.append(0, depth)) vertical_bearing_capacity_arrays.append(np.append(0, vertical_bearing_capacity)) # Convert lists to NumPy arrays depth_arrays = np.array(depth_arrays) vertical_bearing_capacity_arrays = np.array(vertical_bearing_capacity_arrays) return depth_arrays, vertical_bearing_capacity_arrays