Repository navigation
Diffuse components with Klucher #2794
Description
Is your feature request related to a problem? Please describe.
As part of my GSoC 2026 project, I am adding support for return_components to all diffuse transposition models in pvlib, which currently is supported by some models (e.g. perez) but not others (e.g. klucher). While some models provide separable components, klucher does not, because its component terms are multiplicatively coupled.
Describe the solution you'd like
Separating the transposed diffuse irradiance into sky diffuse, circumsolar and horizon brightening components under a proportional allocation assumption (detailed below) which, of course, should be clearly documented.
Describe alternatives you've considered
Not supporting diffuse components for this model, and having return_components=True return a dictionary (in order to keep consistency with other models) returning a single value, the total diffuse irradiance.
Additional context
The following is the expression for total diffuse irradiance via klucher:
If we consider (as identified by Loutzenhiser et al.):
- Isotropic:
$I = \frac{1 + \cos\beta}{2}$ - Horizon brightening:
$h = F' \sin^3\left(\frac{\beta}{2}\right)$ - Circumsolar:
$c = F' \cos^2\theta \sin^3\theta_z$
Then we can simplify the full expression into:
That
And the full expression then becomes:
Thus enabling the separation of components.
I would like feedback on whether this decomposition is acceptable for inclusion in pvlib, or whether klucher should instead not expose component breakdowns at all (i.e., return_components is still used to maintain consistency with other models, but returns a dict with only total irradiance for this model).
Activity
cwhanse commentedon Jun 23, 2026
I'm moderately opposed to altering the
klucherfunction to return circumsolar and horizon components not described in the reference:#2527 (comment)
If we want a version of
klucherthat returns these components, the proportional approach seems as good as any. But that's essentially a new diffuse component model and should have its own reference and name.adriesse commentedon Jun 23, 2026
I think if we're on a path to allowing a variable number of components there is less motivation to do this split in the code. It could be described in the Notes section or demonstrated in an example, or indeed it could be considered as a new model.
cbcrespo commentedon Jun 26, 2026
To add to the discussion: I did a small sensitivity analysis of the size of this$hc$ term when compared to the total diffuse irradiance, and to the circumsolar and horizon components. Here the components are calculated via the proportional split. This is for a location near Lisbon and two systems: 30º south, and vertical west-facing.
adriesse commentedon Jun 29, 2026
That's an interesting perspective, @cbcrespo . I am not sure these fractions tell the whole story though. I guess the first question is, what do we want to show (and maybe to whom)? Perhaps a comparison of the components between this and one or more other models that produce the same components give some confidence that the values don't go haywire. You could probably turn it into a poster for PVSEC, if you want.
cbcrespo commentedon Jun 30, 2026
I agree that it doesn't tell the whole story @adriesse. I also wanted to share the following plot (same location, tilted system):
My takeaway from these two is that the$hc$ term isn't necessarily the problem. This term will be small most of the time (although maybe a bit more relevant for the vertical system) and therefore however we choose to split it may not be of great importance. But the fact that the scale of the circumsolar component differs significantly from the other models to me hints that maybe this forced separation of components indeed doesn't hold a clear physical meaning. But I'm curious to hear everyone's thoughts on this.
AdamRJensen commentedon Jul 1, 2026
@kandersolar and @wholmgren Could you weigh in on this.
adriesse commentedon Jul 1, 2026
@cbcrespo It is interesting to see how small the horizon brightening contribution is. I suspect that one of the reasons for the difference it the datasets that the various authors had available to develop their models.
The partitioning was proposed as a way to have all models return the same set of components, but this is no longer the goal. As I said before, it could be described in the Notes section or demonstrated in an example, or indeed it could be considered as a new model.
If the partitioning is not done for Klucher, we just need to find a suitable name for the combined anisotropic component, like maybe "poa_anisotropic".
ramaroesilva commentedon Jul 1, 2026
hi all, really nice discussion here.
my two cents on the general situation:
since
klucheris not that much of a default option for transposing (#goperez), the number of potential modellers wanting this splitting is modest when compared to the target users who are using modelchain without diffuse IAM.this doesn't mean we shouldn't keep discussing this and eventually reach to a consensus and resulting PR, but for now I would:
klucheras the only non-splittable algorithm for now, which would allow @cbcrespo to have a real example to make sure that her modifications are compatible with such casesramaroesilva commentedon Jul 1, 2026
about @adriesse suggestion of isotropic/anisotropic components, since for now
klucheris the only "problematic" case, I would first do a mapping for algorithms not yet implemented in pvlib before proposing a solution (to avoid ad-hoc). this would also require some reflection on the advantages IAM-wise, since this anisotropic component would still have to consider isotropic/horizon/circumsolar optical losses.cbcrespo commentedon Jul 1, 2026
@adriesse as @ramaroesilva mentioned, I'm not sure how one would address an anisotropic component in terms of IAM calculations - which is part of the next step of my GSoC project, but also one of the main motivations behind diffuse components support.
Regardless, I am in favour of leaving this on standby for now. Ultimately I think I am leaning towards not having
klucherreturn diffuse components at all, which would either mean thatreturn_componentsis not supported, or that it returns a dictionary with only the total diffuse - which, in my opinion, is an argument against removing the total diffuse from the output dict, as has been suggested by some.markcampanelli commentedon Jul 1, 2026
@cbcrespo As an aside, I am curious how often the "total sky diffuse" of Klucher well matches that of Perez?
wholmgren commentedon Jul 2, 2026
@AdamRJensen in this case I think we're proposing too large of a deviation from the source material for
klucher. I am fine with a new functionklucher_proportional_componentsand this issue as the reference, though I am sure that'll be rejected.AdamRJensen commentedon Jul 3, 2026
@cbcrespo I think this is outside the scope of your GSoC project. I suggest that you do not support Klucher in your further work and close the PR and this discussion.
Great work though 🥳