This issue tracks my work for [Google Summer of Code 2026](https://summerofcode.withgoogle.com/) on improving diffuse irradiance handling and optical loss modeling in pvlib. This project will be carried out under the supervision of @AdamRJensen and @ramaroesilva, and has two main goals: 1. Standardizing the outputs of diffuse transposition models 2. Extending `ModelChain` to support component-specific optical loss calculations, via component-specific incident angle modifiers (IAM) If you're interested, you can follow regular updates and discussions on my [blog](https://cbcrespo.github.io/). Official project description on the GSoC website [here](https://summerofcode.withgoogle.com/programs/2026/projects/vM390Eg2). # Motivation Currently, diffuse transposition models in `pvlib.irradiance` provide inconsistent outputs. Some models (e.g., Perez) can return individual components (circumsolar, isotropic, horizon), while others only return total diffuse irradiance. This was previously identified and discussed in issue #1553. This inconsistency limits the `ModelChain` workflow, which: - Applies a single angle of incidence (AOI) model - Uses one IAM value for total irradiance - Cannot distinguish between irradiance components. Since optical losses depend strongly on incidence angle, this reduces physical accuracy. # Proposed Changes ## Phase 1: Standardize diffuse component outputs - Introduce a consistent `return_components` parameter across all diffuse transposition models. PR #2527 has begun addressing this by modifying `irradiance.isotropic` to support this parameter, as previously implemented in `irradiance.perez`. - Ensure all models return: - Circumsolar - Isotropic - Horizon - Total diffuse irradiance - For models that lack explicit components, return zeros for missing components - Follow the structure used in `pvlib.irradiance.perez` ## Phase 2: Extend ModelChain for component-specific IAM - Consider plane-of-array (POA) components instead of global irradiance - Add use of component-specific IAM when calculating effective $G_{POA}$ - Allow users to pass a dictionary to `aoi_model`, specifying IAM model for each component - Maintain full backward compatibility My name is Carolina Crespo, I am a PhD student at the University of Lisbon working on firm power in Iberia using PyPSA-Eur. I am a regular user of pvlib, which I teach (although at a superficial level) to 1st-year Bachelors students. Any feedback on this plan will be very welcome, especially since this is my first time contributing to an open source project. Looking forward to getting started! # List of issues and PRs ## Phase 1 - Adding `return_components` to existing models, ensuring it returns only the components supported by the model: - #2775 - #2787 - #2788 - #2794 - #2800 - Minor details: - #2776 - #2783 - #2789 - #2801 - #2827 ## Phase 2 - Adding support for diffuse components and component-specific IAM calculations to the Array, PVSystem, and ModelChain classes: - #2811 - #2812 - #2845 - #2846 - #2847 - Minor details: - #2824 - Previous discussion of this in #1402 - #2828 - #2832 - #2837 - #2842