Sensitivity Analysis#
Overview#
The SensitivityAnalysis class provides high-level interface to sensitivity analyses on dimensionless coefficients in PyDASA, abstracting mathematical computations with symbolic and numerical modes. Identifies variables with significant impact on system behavior for parameter optimization and uncertainty quantification.
The SensitivityAnalysis simplifies sensitivity workflows through three core features:
Manages Instances: Handles multiple
Sensitivityobjects (one per coefficient) internally.Enables Modes: Performs symbolic differentiation (
SYM) or numerical sampling (NUM).Integrates Workflows: Accepts
AnalysisEngineoutputs directly for dimensional consistency.
Warning
Precondition: SensitivityAnalysis requires a completed dimensional analysis workflow. The analysis must provide:
Dimensional coefficients (from
AnalysisEngine.solve()orAnalysisEngine.run_analysis())Variable definitions with numerical bounds (
std_min,std_max,std_mean)Consistent schema across all components
Use the exact model from Dimensional Analysis as input to ensure proper configuration.
Reynolds Number (\(Re\)) Sensitivity Analysis Example#
This example demonstrates sensitivity analysis for the Reynolds number using the dimensional analysis workflow as precondition:
from pydasa import Variable, Schema, AnalysisEngine
from pydasa.dimensional.fundamental import Dimension
from pydasa.workflows.influence import SensitivityAnalysis
# ========================================================================
# STEP 1: Run Dimensional Analysis (Precondition)
# ========================================================================
# Define custom framework (T, M, L only)
custom_fdus = [
Dimension(_idx=0, _sym="T", _unit="s", _name="Time"),
Dimension(_idx=1, _sym="M", _unit="kg", _name="Mass"),
Dimension(_idx=2, _sym="L", _unit="m", _name="Length")
]
schema = Schema(_fwk="CUSTOM", _fdu_lt=custom_fdus)
# Define variables with numerical bounds for sensitivity analysis
variables = {
"\\rho": Variable(_name="Density",
_sym="\\rho",
_cat="IN",
_dims="M*L^-3",
_units="kg/m³",
_std_mean=1000.0,
_std_min=990.0,
_std_max=1020.0,
relevant=True,
_schema=schema),
"v": Variable(_name="Velocity",
_sym="v",
_cat="OUT",
_dims="L*T^-1",
_units="m/s",
_std_mean=5.0,
_std_min=1.0,
_std_max=6.0,
relevant=True,
_schema=schema),
"D": Variable(_name="Diameter",
_sym="D",
_cat="IN",
_dims="L",
_units="m",
_std_mean=0.05,
_std_min=0.04,
_std_max=0.06,
relevant=True,
_schema=schema),
"\\mu": Variable(_name="Viscosity",
_sym="\\mu",
_cat="IN",
_dims="M*L^-1*T^-1",
_units="Pa·s",
_std_mean=0.001002,
_std_min=0.0009,
_std_max=0.0011,
relevant=True,
_schema=schema),
"g": Variable(_name="Gravity",
_sym="g",
_cat="CTRL",
_dims="L*T^-2",
_units="m/s²",
_std_mean=9.81,
_std_min=9.80,
_std_max=9.82,
relevant=False,
_schema=schema) # Excluded from matrix
}
# Create and run dimensional analysis
engine = AnalysisEngine(_name="Reynolds Number Analysis",
_fwk="CUSTOM",
_schema=schema,
_variables=variables)
engine.create_matrix()
coefficients = engine.solve()
print(f"Dimensional analysis complete: {list(coefficients.keys())}")
# ========================================================================
# STEP 2: Perform Sensitivity Analysis
# ========================================================================
# Create sensitivity analysis workflow
sensitivity = SensitivityAnalysis(_name="Reynolds Sensitivity",
_fwk="CUSTOM",
_cat="SYM",
_schema=schema,
_variables=variables,
_coefficients=coefficients)
# Run symbolic sensitivity analysis at mean values
results = sensitivity.analyze_symbolic(val_type="mean")
# Display results for Reynolds number coefficient
re_key = "SEN_{\\Pi_{0}}"
print("\n=== Symbolic Sensitivity Analysis Results ===")
if re_key in results:
print(f"\nSensitivity for {re_key}:")
for var_sym, sensitivity_val in results[re_key].items():
if var_sym in variables:
var_name = variables[var_sym].name
else:
var_name = var_sym
print(f"\t∂π/∂{var_sym} ({var_name}): {sensitivity_val:+.4e}")
# ========================================================================
# STEP 3: Numerical Sensitivity (Alternative)
# ========================================================================
# Switch to numerical analysis mode
sensitivity.cat = "NUM"
# Run FAST (Fourier Amplitude Sensitivity Test)
numerical_results = sensitivity.analyze_numeric(n_samples=1000)
print("\n=== Numerical Sensitivity Analysis Results (FAST) ===")
for coeff_key, sens_data in numerical_results.items():
print(f"\nSensitivity for {coeff_key}:")
if "S1" in sens_data:
# First-order sensitivity indices
s1_indices = sens_data["S1"]
for i, var_sym in enumerate(sensitivity.variables.keys()):
if var_sym in variables:
var_name = variables[var_sym].name
else:
var_name = var_sym
# S1 is a list, access by index
# S1 represent the contribution of each input variable to the output variance
if i < len(s1_indices):
s1_val = s1_indices[i]
print(f"\tS1: [{var_sym}] ({var_name}): {s1_val:.4f}")
Displayed Capabilities#
In the example we appreciate the following PyDASA capabilities:
Requires Precondition: Needs a completed dimensional analysis with solved coefficients.
Creates Instances: Generates internal
Sensitivityobjects (one per coefficient) automatically.Switches Modes: Toggles
cat="SYM"for symbolic differentiation orcat="NUM"for numerical sampling (FAST).Extracts Bounds: Pulls
std_mean,std_min,std_maxfrom variables for evaluation.Quantifies Impacts: Computes partial derivatives (symbolic) or variance indices (numerical) per variable.
Identifies critical parameters affecting dimensionless behavior for experimental design and model refinement.