Skip to content

Solar Irradiance

Simulating horizontal irradiance

We can simulate solar irradiance components using PVGIS!

To start with, let us check the interface of the irradiance commands:

pvgis irradiance --help
 Usage: pvgis irradiance [OPTIONS] COMMAND [ARGS]...                                                                    

 🌞 Calculate the solar irradiance incident on a solar surface                                                          

╭─ Options ────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --help          Show this message and exit.                                                                          │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Introduction ───────────────────────────────────────╮
│ introduction      A short primer on solar irradiance │
╰──────────────────────────────────────────────────────╯
╭─ External solar irradiance time series ─────────────────────────────────╮
│ global            ⸾ Calculate the global irradiance                     │
│ direct            ⇣ Calculate the direct irradiance                     │
│ diffuse           🗤 Calculate the diffuse irradiance                    │
│ ground-reflected  ⭞ Calculate the clear-sky ground reflected irradiance │
│ extraterrestrial  🌣 Calculate the extraterrestrial normal irradiance    │
╰─────────────────────────────────────────────────────────────────────────╯
╭─ Toolbox ──────────────────────────────────────────────────────────────────────╮
│ kato-bands        [⸾] Kato spectral bands limits and center wavelengths        │
│ reflectivity      ⦟ Calculate the reflectivity effect factor Yet not complete! │
│ limits            [⸾] Calculate physically possible irradiance limits          │
╰────────────────────────────────────────────────────────────────────────────────╯

We can simulate all components of solar radiation: direct, diffuse, reflected and global. Let us begin, however, with the global and direct components. These are, after all, the ones we will compare against the SARAH-3 satellite-based observations.

Global horizontal irradiance

As a first step, we can simulate the global horizontal irradiance over our location of interest and moment in time:

pvgis irradiance global horizontal \
    8.628 45.812 214 \
    '2024-01-27 12:00:00'
458.81427027377026
Consult the help text!

It's always a good idea to consult the help for a command. While effort has been given to keep the same order for the input parameters, not all commands share the exact same required positional parameters!

For the above command, we can get the help via:

pvgis irradiance global horizontal --help
 Usage: pvgis irradiance global horizontal [OPTIONS] {longitude} {latitude}                                             
                                           {elevation} [timestamps]                                                     

 Calculate the broadband global horizontal irradiance over a time series                                                

╭─ Arguments ──────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ *    longitude      <float range>  Longitude in decimal degrees ranging in [-180, 360]. If ranging in [0, 360],      │
│                                    consider the `--convert-longitude-360` option.                                    │
│                                    [required]                                                                        │
│ *    latitude       <float range>  Latitude in decimal degrees ranging in [-90, 90] [required]                       │
│ *    elevation      <float range>  Topographical elevation [required]                                                │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Timestamps ─────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│   timestamps      <parse_timestamp_series>  Quoted date-time strings of data to extract from series, example:        │
│                                             '2112-12-21, 2112-12-21 12:21:21, 2112-12-21 21:12:12''                  │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --resample-large-series      --no-resample-large-series           [default: no-resample-large-series]                │
│ --log                    -l                                <int>  Enable logging [default: 0]                        │
│ --help                                                            Show this message and exit.                        │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Timestamps ─────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --start-time,--st                                   <parse_timestamp>  Start timestamp of the period. Overrides the  │
│                                                                        `timestamps` parameter!                       │
│ --periods                                           <int>              Number of timestamps to generate              │
│ --frequency                                         <str>              A common date/time frequency unit optionally  │
│                                                                        with a multiples number, such as H(hourly),   │
│                                                                        min(utely), S(econdly), D(aily), W(eekly),    │
│                                                                        M(onth end), Y(early) or 30min. See Pandas    │
│                                                                        time series offset aliases.                   │
│ --end-time,--et                                     <parse_timestamp>  End timestamp of the period. Overrides the    │
│                                                                        `timestamps` parameter!                       │
│ --timezone,--tz,--zone                              <parse_timezone>   Timezone (e.g., 'Europe/Athens'). Use the     │
│                                                                        system's time zone via the `--local` option.  │
│ --random-timestamps       --no-random-timestamps                       Generate a random date, time and timezone to  │
│                                                                        demonstrate calculation                       │
│                                                                        [default: no-random-timestamps]               │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Atmospheric properties ─────────────────────────────────────────────────────────────────────────────────────────────╮
│ --linke-turbidity-factor-s…                                  <parse_linke_turbidity_fac  Ratio of total to Rayleigh  │
│                                                              tor_series>                 optical depth measuring     │
│                                                                                          atmospheric turbidity       │
│                                                                                          [default: 2]                │
│ --apply-atmospheric-refrac…    --no-apply-atmospheric-re…                                Correct solar azimuth and   │
│                                                                                          altitude angles for         │
│                                                                                          atmospheric refraction      │
│                                                                                          [default:                   │
│                                                                                          apply-atmospheric-refracti… │
│ --refracted-solar-zenith                                     <float>                     Refracted solar zenith      │
│                                                                                          angle (in radians) for sun  │
│                                                                                          -rise and -set events       │
│                                                                                          [default:                   │
│                                                                                          1.5853349194640094]         │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Advanced ───────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --apply-reflectivity-factor    --no-apply-reflectivity-factor      Apply angular loss function                       │
│                                                                    [default: apply-reflectivity-factor]              │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Solar position ─────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --solar-position-model,--position-m…        <all|noaa|hofierka|jenco|pvlib|pys  Model to calculate solar position    │
│                                             olar|skyfield|suncalc>              [default: NOAA]                      │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Solar time ─────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --solar-time-model        <all|milne1921|noaa|pvgis|pvlib|skyfield>  Model to calculate solar time [default: NOAA]   │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Earth orbit ────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --solar-constant                        <float range> [x>=1360]  Top-of-Atmosphere mean solar electromagnetic        │
│                                                                  radiation (W/m-2) 1 au (astronomical unit) away     │
│                                                                  from the Sun.                                       │
│                                                                  [default: 1360.8]                                   │
│ --perigee-offset                        <float>                  Perigee offset [default: 0.048869]                  │
│ --eccentricity-correction-factor        <float>                  Eccentricity correction factor [default: 0.03344]   │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ > Input : < Output ─────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --angle-output-units  -aou      <str>   Angular units for solar geometry calculations (degrees or radians). ⚠ Under  │
│                                         development                                                                  │
│                                         [default: radians]                                                           │
│ --rounding-places     -r        <int>   Number of digits to round results to [default: 3]                            │
│ --csv                           <path>  CSV output filename                                                          │
│ --verbose             -v        <int>   Show details while executing commands [default: 0]                           │
│ --index,--idx         -i                Index rows in output table (meaningful with at least 1x -v)                  │
│ --quiet                                 Do not print out the output                                                  │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Data processing ────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --dtype                <str>  Data type [default: float32]                                                           │
│ --array-backend        <str>  Array backend [default: numpy]                                                         │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Statistics ─────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --statistics    --no-statistics           Calculate and display summary statistics [default: no-statistics]          │
│ --groupby                          <str>  Group statistics, ex. M or 3h. A number and date/time unit : (Y)ear,       │
│                                           (S)eason, (M)onth, (D)ay, (W)eek, (h)our. See Xarray's group-by            │
│                                           operations.                                                                │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Plotting ───────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --uniplot                    --no-uniplot             Plot the PV power output time series in the terminal           │
│                                                       [default: no-uniplot]                                          │
│ --terminal-width-fraction                    <float>  Fraction of number of columns of the current terminal, ex. 0.9 │
│                                                       [default: 0.9]                                                 │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Metadata ───────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --fingerprint,--fp                       Fingerprint the output time series                                          │
│ --metadata            --no-metadata      Print command metadata [default: no-metadata]                               │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

We can see how this simulated quantity breaks down in its sub-components too:

pvgis irradiance global horizontal \
    8.628 45.812 214 \
    '2024-01-27 12:00:00' \
    -vvv
      Global Irradiance & relevant components in-plane irradiance series W/m² (1/3)      

  Time                  ⭳ Global Horizontal Irradiance   ⭳ Direct Horizontal Irradiance  
 ─────────────────────────────────────────────────────────────────────────────────────── 
  2024-01-27 12:00:00   458.814                          405.941                         

  ⅀ / μ                                                  405.941                         

                Global Irradiance & relevant components in-plane irradiance series W/m² (2/3)                

  Time                  ⭳ Diffuse Horizontal Irradiance   ⦜ Extraterrestrial Normal Irradiance   ⦩ Altitude  
 ─────────────────────────────────────────────────────────────────────────────────────────────────────────── 
  2024-01-27 12:00:00   52.874                            1402.449                               0.442       

  ⅀ / μ                 52.874                                                                               

 Global Irradiance & relevant components 
  in-plane irradiance series W/m² (3/3)  

  Time                  Linke Turbidity  
 ─────────────────────────────────────── 
  2024-01-27 12:00:00   2.0              

  ⅀ / μ                                  

╭────────────────────────────────────────────────────────╮ ╭─────────────────────────────────────╮
│ Angular units ㎭ radians                               │ │  ⭳  Horizontal  ⅀  N-ary Summation  │
│ Location  Longitude, Latitude = 0.151, 0.8Zone : UTC,  │ │  ⦜  Normal      μ  Mean             │
│ Algorithms  Radiation model: Hofierka 2002             │ │  ⦩  Altitude                        │
╰──────────────────────────────────────────── Reference ─╯ ╰──────────────────────────── Legend ─╯

Direct horizontal irradiance

We will get the same simulated direct horizontal estimation by using the direct horizontal commands:

pvgis irradiance direct horizontal \
    8.628 45.812 214 \
    '2024-01-27 12:00:00'
405.94052

Diffuse horizontal irradiance

The diffuse component is the difference between global and direct. As with the previous command examples, we can derive the diffuse horizontal component via:

pvgis irradiance diffuse horizontal \
    8.628 45.812 214 \
    '2024-01-27 12:00:00'
52.873749033535866

Satellite observations of solar irradiance

Instead of relying on the model, let's read-in observations of solar irradiance from the SARAH-3 data collection:

SARAH-3 SIS

  • Read the SIS component from SARAH-3:
pvgis series select \
    data/sample_sarah3_sis_over_esti.nc \
    8.628 45.812 \
    '2024-01-27 12:00:00' \
    --neighbor-lookup nearest \
    --mask-and-scale \
    -v
 Selected  
   data    


 ───────── 
  436.000  



╭───────────────────────────────────────────────────╮
│ Location  Longitude ϑ, Latitude ϕ = 8.628, 45.812 │
│ Legend: Center Wavelengths (nm)                   │
╰───────────────────────────────────────────────────╯

SARAH-3 SID

  • Read the SID component from SARAH-3:
pvgis series select \
    data/sample_sarah3_sid_over_esti.nc \
    8.628 45.812 \
    --neighbor-lookup nearest \
    -v \
    --mask-and-scale \
    '2024-01-27 12:00:00'
 Selected  
   data    


 ───────── 
  371.000  



╭───────────────────────────────────────────────────╮
│ Location  Longitude ϑ, Latitude ϕ = 8.628, 45.812 │
│ Legend: Center Wavelengths (nm)                   │
╰───────────────────────────────────────────────────╯

Optional and required parameters

The latter command differs from the one before in that the order of the optional and required input parameters is not the same. The message here is that : indeed, we can mix the order of optional parameters in-between as long as we keep strictly the order of the required ones, as indicated in the help section of a command.

Just run pvgis series select and read the help text.

Indeed, the simulated values differ from the satellite-based observations retrieved from the SARAH-3 datasets. Aren't they close enough? We need to keep in mind that a series of assumptions and simplifications are part of the solar radiation model.

Direct normal irradiance

In estimating the photovoltaic power output, the solar radiation component with the greatest impact, is the direct normal irradiance. From the theory, we know that:

$$ \operatorname{DNI} = \frac{\operatorname{SID}}{\cos\!\left(\theta_{z}\right)} $$
  1. First, let's get the zenith angle in radians
pvgis position zenith \
    8.628 45.812 \
    '2024-01-17 12:00:00'
       Solar Zenith Series        

  Time                  ⦭ Zenith  
 ──────────────────────────────── 
  2024-01-17 12:00:00   1.168     

╭────────────────────────────────────────────────────────────────╮
│ ⏳ Start Time     ⏱ Frequency       ⌛ End Time       Timezone │
│ 2024-01-17 12:00  Single timestamp  2024-01-17 12:00  UTC      │
╰────────────────────────────────────────────────────────────────╯
╭─────────────────────────────────────────────────────────╮       
│ Position  longitude, latitude = 0.151, 0.8, Unitless    │       
│ Algorithms  Timing : NOAA, Zone : UTC, Positioning : NA │       
╰───────────────────────────────────────────── Reference ─╯       
╭─────────────╮                                                   
│  ⦭  Zenith  │                                                   
│             │                                                   
╰──── Legend ─╯                                                   
  1. Next, open a Python interpreter

    python 
    
  2. Set the direct horizontal irradiance reported in SARAH-3 and the zenith angle calculated previously

    >>> sid = 371.00000
    >>> solar_zenith_angle = 1.168
    
  3. Calculate the DNI using simple Python

    >>> from math import cos
    >>> print(f'DNI = {sid / cos(solar_zenith_angle)}')
    

    DNI = 946.4469113172491

Let's compare with PVGIS' model:

pvgis irradiance direct normal '2024-01-27 12:00:00'
981.2508072334045

I guess we can assume the model in the new software is close and not wildly out of range!

Horizontal irradiance

If we simulate also the Direct Horizontal Component, it should be close to the SARAH-3 observation.

Is it? Let's find out...

pvgis irradiance direct horizontal 8.628 45.812 214 '2024-01-27 12:00:00'
405.94052

Note

Isn't this close enough to 371?

Inclined irradiance

Next, the simulated direct inclined component:

pvgis irradiance direct inclined \
    8.628 45.812 214 180 45 \
    '2024-01-27 12:00:00'
887.26764

And the simulated global inclined component is:

pvgis irradiance global inclined \
    8.628 45.812 210 180 45 \
    '2024-01-27 12:00:00'
995.90466

Analytically, the above figure is broken down to its inclined components as:

pvgis irradiance global inclined \
    8.628 45.812 210 180 45 \
    '2024-01-27 12:00:00' \
    -vvv
  Global Inclined Irradiance & relevant components in-plane irradiance series W/m²   
                                        (1/3)                                        

  Time                  ∡ Global Inclined Irradiance   ∡ Direct Inclined Irradiance  
 ─────────────────────────────────────────────────────────────────────────────────── 
  2024-01-27 12:00:00   995.905                        887.152                       

  ⅀ / μ                 995.905                        887.152                       

            Global Inclined Irradiance & relevant components in-plane irradiance series W/m² (2/3)            

  Time                  ∡ Diffuse Inclined Irradiance   ∡ Ground Reflected Inclined Irradiance   ☂  In shade  
 ──────────────────────────────────────────────────────────────────────────────────────────────────────────── 
  2024-01-27 12:00:00   96.26                           12.493                                   False        

  ⅀ / μ                 96.26                           12.493                                                

 Global Inclined Irradiance & relevant components 
      in-plane irradiance series W/m² (3/3)       

  Time                  ☉ ⛰ Sun-Horizon Position  
 ──────────────────────────────────────────────── 
  2024-01-27 12:00:00   Above                     

  ⅀ / μ                                           

╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Angular units ㎭ radians                                                                                             │
│ Location  Longitude, Latitude = 0.151, 0.8, Elevation: 210.0 m                                                       │
│ Position  Surface Orientation: 3.142, Surface Tilt: 0.785                                                            │
│ Definitions  Zone : UTC, Incidence angle: Sun-Vector-to-Surface-Plane, Sun-Horizon Positions: Above, Low angle,      │
│ Below, Shading states: Sunlit, Potentially-sunlit, In-shade,                                                         │
│ Algorithms  Radiation model: Hofierka 2002, Timing : NOAA, Positioning : NOAA, Incidence : Iqbal,                    │
│ Constants Solar constant : 1360.8, Perigee : 0.048869, Eccentricity : 0.03344                                        │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────── Reference ─╯
╭───────────────────────────────╮                                                                                       
│  ∡  Tilt             μ  Mean  │                                                                                       
│  ☂  In shade                  │                                                                                       
│  ☉  Sun                       │                                                                                       
│  ⛰  Horizon                   │                                                                                       
│  -  Loss                      │                                                                                       
│  ⅀  N-ary Summation           │                                                                                       
╰────────────────────── Legend ─╯                                                                                       

Default orientation and tilt angles

The default values for the orientation and tilt angles of a solar surface are (currently) set to 180 and 45 degrees respectively. Hence, we'd get the same result if we

pvgis irradiance global horizontal \
    8.628 45.812 214 \
    '2014-01-27 12:00:00'
459.17260983213276

Extra information

If we read the SIS and SID SARAH-3 components to get the Global Inclined Irradiance:

pvgis irradiance global inclined \
    8.628 45.812 210 180 45 \
    '2024-01-27 12:00:00' \
    --global-horizontal-irradiance data/sample_sarah3_sis_over_esti.nc \
    --direct-horizontal-irradiance data/sample_sarah3_sid_over_esti.nc \
    --neighbor-lookup nearest
936.30347
  • The diffuse inclined component here uses, of course, SARAH-3 SIS and SID and it is calculated using the command:
pvgis irradiance diffuse inclined \
    8.628 45.812 210 180 45 \
    '2024-01-27 12:00:00' \
    --global-horizontal-irradiance data/sample_sarah3_sis_over_esti.nc \
    --direct-horizontal-irradiance data/sample_sarah3_sid_over_esti.nc \
    --neighbor-lookup nearest
113.53201

From normal to horizontal irradiance

\[ \mathrm{DHI} = \mathrm{DNI} \cdot \sin(\alpha_{\mathrm{solar}}) \]
pvgis position altitude \
    8.628 45.812 \
    '2024-01-17 12:00:00'
       Solar Altitude Series        

  Time                  ⦩ Altitude  
 ────────────────────────────────── 
  2024-01-17 12:00:00   0.403       

╭────────────────────────────────────────────────────────────────╮
│ ⏳ Start Time     ⏱ Frequency       ⌛ End Time       Timezone │
│ 2024-01-17 12:00  Single timestamp  2024-01-17 12:00  UTC      │
╰────────────────────────────────────────────────────────────────╯
╭─────────────────────────────────────────────────────────╮       
│ Position  longitude, latitude = 0.151, 0.8, Unitless    │       
│ Algorithms  Timing : NOAA, Zone : UTC, Positioning : NA │       
╰───────────────────────────────────────────── Reference ─╯       
╭───────────────╮                                                 
│  ⦩  Altitude  │                                                 
│               │                                                 
╰────── Legend ─╯                                                 

For verification!

>>> from math import sin
>>> dni = 946.446
>>> altitude = 0.403
>>> print(dni * sin(altitude))

371.1769734282379