| """ |
| Custom power density calculation using efficiency model. |
| Calculates site-specific power density based on latitude and longitude. |
| """ |
|
|
| import os |
| import sys |
| from pathlib import Path |
| import numpy as np |
| from typing import Optional, Tuple |
|
|
| |
| EFFICIENCY_MODEL_PATH = Path(__file__).parent / "efficiency_model" |
|
|
| |
| DEFAULT_POWER_DENSITY = 0.18 |
| POWER_DENSITY_RANGE = (0.101, 0.17) |
|
|
|
|
| class EfficencyAwarePowerDensity: |
| """ |
| Calculate site-specific power density based on solar efficiency. |
| Uses the efficiency model to adjust power density for geographic location. |
| """ |
| |
| def __init__(self, efficiency_model=None): |
| """ |
| Initialize with optional pre-loaded efficiency model. |
| |
| Args: |
| efficiency_model: Optional pre-loaded SolarEnergyInterpolator instance |
| """ |
| self.interpolator = efficiency_model |
| self._load_interpolator() |
| |
| def _load_interpolator(self): |
| """Lazy load the efficiency model interpolator""" |
| if self.interpolator is not None: |
| return |
| |
| try: |
| |
| import sys |
| model_path_str = str(EFFICIENCY_MODEL_PATH) |
| if model_path_str not in sys.path: |
| sys.path.insert(0, model_path_str) |
| |
| |
| from efficiencyMap import SolarEnergyInterpolator |
| self.interpolator = SolarEnergyInterpolator(data_dir=model_path_str) |
| except Exception as e: |
| print(f"Warning: Could not load efficiency model: {str(e)}") |
| import traceback |
| traceback.print_exc() |
| self.interpolator = None |
| |
| def get_efficiency(self, latitude: float, longitude: float) -> float: |
| """ |
| Get solar efficiency for a location. |
| |
| Args: |
| latitude: Site latitude (-60 to 65) |
| longitude: Site longitude (-180 to 180) |
| |
| Returns: |
| float: Solar efficiency as percentage (0-100) or 0 if unavailable |
| """ |
| |
| if self.interpolator is None: |
| self._load_interpolator() |
| |
| if self.interpolator is None: |
| return 0 |
| |
| try: |
| efficiency = self.interpolator.get_solar_efficiency(latitude, longitude) |
| return float(efficiency) if efficiency and efficiency > 0 else 0 |
| except Exception as e: |
| print(f"Warning: Efficiency calculation failed for ({latitude}, {longitude}): {str(e)}") |
| return 0 |
| |
| def calculate_power_density(self, latitude: float, longitude: float, |
| baseline_density: float = DEFAULT_POWER_DENSITY) -> float: |
| """ |
| Calculate site-specific power density based on solar efficiency. |
| |
| High efficiency areas (e.g., deserts) → Higher power density |
| Low efficiency areas (e.g., cloudy regions) → Lower power density |
| |
| Args: |
| latitude: Site latitude |
| longitude: Site longitude |
| baseline_density: Baseline power density in kWp/m² (default: 0.18) |
| |
| Returns: |
| float: Site-specific power density in kWp/m² |
| """ |
| |
| efficiency = self.get_efficiency(latitude, longitude) |
| |
| if efficiency == 0: |
| |
| return baseline_density |
| |
| |
| adjusted_density = efficiency / 100.0 |
|
|
| |
| adjusted_density = np.clip(adjusted_density, POWER_DENSITY_RANGE[0], POWER_DENSITY_RANGE[1]) |
| |
| return round(adjusted_density, 4) |
| |
| def get_site_power_density_info(self, latitude: float, longitude: float, |
| baseline_density: float = DEFAULT_POWER_DENSITY) -> dict: |
| """ |
| Get comprehensive power density information for a site. |
| |
| Args: |
| latitude: Site latitude |
| longitude: Site longitude |
| baseline_density: Baseline power density |
| |
| Returns: |
| dict: Power density information including efficiency and adjusted value |
| """ |
| efficiency = self.get_efficiency(latitude, longitude) |
| adjusted_density = self.calculate_power_density(latitude, longitude, baseline_density) |
| |
| return { |
| 'efficiency_percent': efficiency, |
| 'baseline_density_kwp_m2': baseline_density, |
| 'adjusted_density_kwp_m2': adjusted_density, |
| 'density_adjustment_factor': adjusted_density / baseline_density if baseline_density > 0 else 1.0, |
| 'location': f"{latitude:.4f}°, {longitude:.4f}°" |
| } |
|
|
|
|
| |
| try: |
| power_density_calculator = EfficencyAwarePowerDensity() |
| except Exception as e: |
| print(f"Warning: Could not initialize power density calculator: {str(e)}") |
| power_density_calculator = None |
|
|
|
|
| def get_power_density_for_site(latitude: float, longitude: float, |
| baseline_density: float = DEFAULT_POWER_DENSITY) -> float: |
| """ |
| Convenience function to get power density for a site. |
| |
| Args: |
| latitude: Site latitude |
| longitude: Site longitude |
| baseline_density: Baseline power density (default: 0.18 kWp/m²) |
| |
| Returns: |
| float: Site-specific power density in kWp/m² |
| """ |
| |
| try: |
| calculator = EfficencyAwarePowerDensity() |
| return calculator.calculate_power_density(latitude, longitude, baseline_density) |
| except Exception as e: |
| print(f"Error calculating power density: {str(e)}") |
| return baseline_density |
|
|
|
|
| def get_power_density_info(latitude: float, longitude: float, |
| baseline_density: float = DEFAULT_POWER_DENSITY) -> dict: |
| """ |
| Convenience function to get detailed power density information. |
| |
| Args: |
| latitude: Site latitude |
| longitude: Site longitude |
| baseline_density: Baseline power density |
| |
| Returns: |
| dict: Detailed power density information |
| """ |
| |
| try: |
| calculator = EfficencyAwarePowerDensity() |
| return calculator.get_site_power_density_info(latitude, longitude, baseline_density) |
| except Exception as e: |
| print(f"Error getting power density info: {str(e)}") |
| return { |
| 'efficiency_percent': 0, |
| 'baseline_density_kwp_m2': baseline_density, |
| 'adjusted_density_kwp_m2': baseline_density, |
| 'density_adjustment_factor': 1.0, |
| 'location': f"{latitude:.4f}°, {longitude:.4f}°" |
| } |
|
|