"""
Retaining Wall Design Calculator - IS 456:2000
Main retaining wall design calculator that dispatches to specific retaining wall type calculators
based on user selection. Provides unified interface for all retaining wall design types.
"""
from typing import Any, Dict, Type
from pydantic import BaseModel, Field, field_validator
from ..base import BaseCalculator, CalculationError
from .retaining_wall import CantileverRetainingWallCalculator
class RetainingWallDesignInput(BaseModel):
"""Input parameters for retaining wall design with type selection"""
retaining_wall_type: str = Field(..., description="Type of retaining wall design")
design_parameters: Dict[str, Any] = Field(
..., description="Specific parameters for selected retaining wall type"
)
@field_validator("retaining_wall_type")
@classmethod
def validate_retaining_wall_type(cls, v: str) -> str:
valid_types = ["cantilever", "counterfort"]
if v not in valid_types:
raise ValueError(f"Invalid retaining wall type. Must be one of {valid_types}")
return v
class RetainingWallDesignOutput(BaseModel):
"""Output schema for retaining wall design results"""
retaining_wall_type: str = Field(..., description="Type of retaining wall designed")
design_results: Dict[str, Any] = Field(..., description="Specific design results")
calculation_summary: Dict[str, Any] = Field(..., description="Summary of key results")
[docs]
class RetainingWallDesignCalculator(BaseCalculator):
"""
Main Retaining Wall Design Calculator
Dispatches to specific retaining wall calculators based on type:
- Cantilever Retaining Wall
- Counterfort Retaining Wall (future implementation)
"""
[docs]
def __init__(self) -> None:
super().__init__(calculator_type="retaining_wall_design", version="1.0.0")
# Initialize sub-calculators
self.calculators = {
"cantilever": CantileverRetainingWallCalculator(),
# "counterfort": CounterfortRetainingWallCalculator(), # Future implementation
}
@property
def input_schema(self) -> Type[BaseModel]:
"""Return the input schema for validation"""
return RetainingWallDesignInput
@property
def output_schema(self) -> Type[BaseModel]:
"""Return the output schema for formatting"""
return RetainingWallDesignOutput
[docs]
def calculate(self, inputs: Dict[str, Any]) -> Dict[str, Any]:
"""Main calculation method that dispatches to appropriate calculator"""
try:
retaining_wall_type = inputs["retaining_wall_type"]
design_parameters = inputs["design_parameters"]
# Check if calculator is available
if retaining_wall_type not in self.calculators:
available_types = list(self.calculators.keys())
raise CalculationError(
f"Retaining wall type '{retaining_wall_type}' not implemented. "
f"Available types: {available_types}"
)
# Get the specific calculator
calculator = self.calculators[retaining_wall_type]
# Perform calculation using the specific calculator
results = calculator.calculate(design_parameters)
# Prepare unified output
unified_results = {
"retaining_wall_type": retaining_wall_type,
"design_results": results,
"calculation_summary": {
"calculator_used": calculator.calculator_type,
"calculator_version": calculator.version,
"design_status": results.get("status", "UNKNOWN"),
"stability_checks": {
"overturning": results.get("design_summary", {}).get("fos_overturning"),
"sliding": results.get("design_summary", {}).get("fos_sliding"),
"bearing": results.get("design_summary", {}).get("max_bearing_pressure"),
},
},
}
return unified_results
except Exception as e:
self.logger.error("Retaining wall design calculation failed", error=str(e))
raise CalculationError(f"Retaining wall design failed: {e!s}")
# Export the calculator class
__all__ = ["RetainingWallDesignCalculator"]