Source code for api.app.calculators.concrete.retaining_wall_design

"""
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"]