or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

atmosphere.mdbifacial.mdclearsky.mdiam.mdindex.mdinverter.mdiotools.mdirradiance.mdlosses.mdpvsystem.mdsolar-position.mdspectrum.mdtemperature.md

clearsky.mddocs/

0

# Clear Sky Models

1

2

Calculate clear sky irradiance using multiple models including Ineichen, Bird, Haurwitz, and simplified SOLIS. Clear sky models provide baseline irradiance estimates for system modeling, clear sky detection, and performance analysis.

3

4

## Capabilities

5

6

### Ineichen Clear Sky Model

7

8

The most commonly used clear sky model, recommended by the IEA Task 12 and WMO.

9

10

```python { .api }

11

def ineichen(apparent_zenith, airmass_absolute, linke_turbidity,

12

altitude=0, dni_extra=1366.1):

13

"""

14

Calculate clear sky irradiance using Ineichen model.

15

16

Parameters:

17

- apparent_zenith: numeric, apparent solar zenith angle in degrees

18

- airmass_absolute: numeric, absolute airmass

19

- linke_turbidity: numeric, Linke turbidity factor

20

- altitude: numeric, altitude above sea level in meters

21

- dni_extra: numeric, extraterrestrial direct normal irradiance (W/m^2)

22

23

Returns:

24

OrderedDict with keys:

25

- ghi: global horizontal irradiance (W/m^2)

26

- dni: direct normal irradiance (W/m^2)

27

- dhi: diffuse horizontal irradiance (W/m^2)

28

"""

29

```

30

31

### Bird Clear Sky Model

32

33

Physically-based clear sky model with detailed atmospheric parameter inputs.

34

35

```python { .api }

36

def bird(zenith, airmass_relative, aod380, aod500, precipitable_water,

37

ozone=0.3, pressure=101325.0, dni_extra=1366.1,

38

asymmetry=0.85, albedo=0.2):

39

"""

40

Calculate clear sky irradiance using Bird model.

41

42

Parameters:

43

- zenith: numeric, solar zenith angle in degrees

44

- airmass_relative: numeric, relative airmass

45

- aod380: numeric, aerosol optical depth at 380 nm

46

- aod500: numeric, aerosol optical depth at 500 nm

47

- precipitable_water: numeric, precipitable water in cm

48

- ozone: numeric, ozone in atm-cm

49

- pressure: numeric, atmospheric pressure in pascals

50

- dni_extra: numeric, extraterrestrial direct normal irradiance (W/m^2)

51

- asymmetry: numeric, aerosol asymmetry parameter

52

- albedo: numeric, ground albedo

53

54

Returns:

55

OrderedDict with keys:

56

- ghi: global horizontal irradiance (W/m^2)

57

- dni: direct normal irradiance (W/m^2)

58

- dhi: diffuse horizontal irradiance (W/m^2)

59

"""

60

```

61

62

### Haurwitz Clear Sky Model

63

64

Simple empirical clear sky model requiring only solar zenith angle.

65

66

```python { .api }

67

def haurwitz(apparent_zenith):

68

"""

69

Calculate clear sky GHI using Haurwitz model.

70

71

Parameters:

72

- apparent_zenith: numeric, apparent solar zenith angle in degrees

73

74

Returns:

75

numeric, global horizontal irradiance (W/m^2)

76

"""

77

```

78

79

### Simplified SOLIS Clear Sky Model

80

81

Simplified version of the SOLIS clear sky model.

82

83

```python { .api }

84

def simplified_solis(apparent_elevation, aod700=0.1, precipitable_water=1.0,

85

pressure=101325.0, dni_extra=1366.1):

86

"""

87

Calculate clear sky irradiance using simplified SOLIS model.

88

89

Parameters:

90

- apparent_elevation: numeric, apparent solar elevation angle in degrees

91

- aod700: numeric, aerosol optical depth at 700 nm

92

- precipitable_water: numeric, precipitable water in cm

93

- pressure: numeric, atmospheric pressure in pascals

94

- dni_extra: numeric, extraterrestrial direct normal irradiance (W/m^2)

95

96

Returns:

97

OrderedDict with keys:

98

- ghi: global horizontal irradiance (W/m^2)

99

- dni: direct normal irradiance (W/m^2)

100

- dhi: diffuse horizontal irradiance (W/m^2)

101

"""

102

```

103

104

### Linke Turbidity Lookup

105

106

Look up Linke turbidity values from monthly climatology database.

107

108

```python { .api }

109

def lookup_linke_turbidity(time, latitude, longitude, filepath=None,

110

interp_turbidity=True):

111

"""

112

Look up Linke turbidity values from climatology database.

113

114

Parameters:

115

- time: pandas.DatetimeIndex, times for lookup

116

- latitude: float, decimal degrees north

117

- longitude: float, decimal degrees east

118

- filepath: str, path to Linke turbidity file

119

- interp_turbidity: bool, interpolate turbidity values

120

121

Returns:

122

pandas.Series, Linke turbidity values

123

"""

124

```

125

126

### Clear Sky Detection

127

128

Detect clear sky conditions from measured irradiance data.

129

130

```python { .api }

131

def detect_clearsky(measured, clearsky, times=None, infer_limits=False,

132

window_length=10, mean_diff=75, max_diff=75,

133

lower_line_length=-5, upper_line_length=10,

134

var_diff=0.005, slope_dev=8, max_iterations=20,

135

return_components=False):

136

"""

137

Detect clear sky conditions from measured vs. clear sky irradiance.

138

139

Parameters:

140

- measured: pandas.Series or DataFrame, measured irradiance

141

- clearsky: pandas.Series or DataFrame, clear sky irradiance

142

- times: pandas.DatetimeIndex, timestamps

143

- infer_limits: bool, infer detection limits from data

144

- window_length: int, window length for moving statistics

145

- mean_diff: numeric, mean difference threshold

146

- max_diff: numeric, maximum difference threshold

147

- lower_line_length: numeric, lower line length parameter

148

- upper_line_length: numeric, upper line length parameter

149

- var_diff: numeric, variance difference threshold

150

- slope_dev: numeric, slope deviation threshold

151

- max_iterations: int, maximum number of iterations

152

- return_components: bool, return intermediate results

153

154

Returns:

155

pandas.Series or tuple, clear sky mask and optional components

156

"""

157

```

158

159

## Usage Examples

160

161

### Basic Ineichen Clear Sky Calculation

162

163

```python

164

import pvlib

165

from pvlib import clearsky, solarposition, atmosphere

166

import pandas as pd

167

168

# Location and time

169

lat, lon = 40.0583, -74.4057 # Princeton, NJ

170

times = pd.date_range('2023-06-21', periods=24, freq='H', tz='US/Eastern')

171

172

# Solar position

173

solar_pos = solarposition.get_solarposition(times, lat, lon)

174

175

# Atmospheric parameters

176

airmass = atmosphere.get_relative_airmass(solar_pos['zenith'])

177

airmass_abs = atmosphere.get_absolute_airmass(airmass)

178

179

# Look up Linke turbidity (or use typical value)

180

linke_turbidity = 3.0 # Typical value for mid-latitudes

181

182

# Calculate clear sky irradiance

183

clear_sky = clearsky.ineichen(

184

apparent_zenith=solar_pos['apparent_zenith'],

185

airmass_absolute=airmass_abs,

186

linke_turbidity=linke_turbidity

187

)

188

189

print("Time, GHI, DNI, DHI")

190

for i in range(8, 16): # Show daytime hours

191

time_str = times[i].strftime('%H:%M')

192

ghi = clear_sky['ghi'].iloc[i]

193

dni = clear_sky['dni'].iloc[i]

194

dhi = clear_sky['dhi'].iloc[i]

195

print(f"{time_str}, {ghi:.0f}, {dni:.0f}, {dhi:.0f}")

196

```

197

198

### Bird Clear Sky Model with Detailed Atmospheric Parameters

199

200

```python

201

import pvlib

202

from pvlib import clearsky, solarposition, atmosphere

203

import pandas as pd

204

205

# Location and conditions

206

lat, lon = 35.05, -106.54 # Albuquerque, NM (high altitude, dry)

207

times = pd.date_range('2023-06-21 12:00', periods=1, tz='US/Mountain')

208

209

# Solar position

210

solar_pos = solarposition.get_solarposition(times, lat, lon, altitude=1619)

211

zenith = solar_pos['zenith'].iloc[0]

212

213

# Atmospheric parameters for high altitude, dry location

214

airmass_rel = atmosphere.get_relative_airmass(zenith)

215

aod380 = 0.1 # Low aerosol loading

216

aod500 = 0.05

217

precipitable_water = 0.8 # Low water vapor

218

ozone = 0.25 # Typical ozone

219

pressure = atmosphere.alt2pres(1619) # Pressure at altitude

220

221

# Calculate clear sky irradiance

222

clear_sky = clearsky.bird(

223

zenith=zenith,

224

airmass_relative=airmass_rel,

225

aod380=aod380,

226

aod500=aod500,

227

precipitable_water=precipitable_water,

228

ozone=ozone,

229

pressure=pressure

230

)

231

232

print(f"Bird clear sky model results:")

233

print(f"GHI: {clear_sky['ghi']:.0f} W/m²")

234

print(f"DNI: {clear_sky['dni']:.0f} W/m²")

235

print(f"DHI: {clear_sky['dhi']:.0f} W/m²")

236

```

237

238

### Comparing Clear Sky Models

239

240

```python

241

import pvlib

242

from pvlib import clearsky, solarposition, atmosphere

243

import pandas as pd

244

import matplotlib.pyplot as plt

245

246

# Location and time

247

lat, lon = 40.0583, -74.4057

248

times = pd.date_range('2023-06-21 06:00', '2023-06-21 18:00',

249

freq='H', tz='US/Eastern')

250

251

# Solar position and atmospheric parameters

252

solar_pos = solarposition.get_solarposition(times, lat, lon)

253

airmass_rel = atmosphere.get_relative_airmass(solar_pos['zenith'])

254

airmass_abs = atmosphere.get_absolute_airmass(airmass_rel)

255

256

# Model comparisons

257

results = {}

258

259

# Ineichen model

260

results['Ineichen'] = clearsky.ineichen(

261

solar_pos['apparent_zenith'], airmass_abs, linke_turbidity=3.0

262

)

263

264

# Haurwitz model (GHI only)

265

results['Haurwitz'] = {'ghi': clearsky.haurwitz(solar_pos['apparent_zenith'])}

266

267

# Simplified SOLIS model

268

results['SOLIS'] = clearsky.simplified_solis(

269

solar_pos['apparent_elevation'],

270

aod700=0.1,

271

precipitable_water=1.5

272

)

273

274

# Print comparison at solar noon

275

noon_idx = 12

276

print("Clear sky model comparison at solar noon:")

277

print(f"{'Model':<10} {'GHI':<6} {'DNI':<6} {'DHI':<6}")

278

for model_name, data in results.items():

279

ghi = data['ghi'].iloc[noon_idx] if hasattr(data['ghi'], 'iloc') else data['ghi'][noon_idx]

280

dni = data.get('dni', [0]*len(times))

281

dhi = data.get('dhi', [0]*len(times))

282

if hasattr(dni, 'iloc'):

283

dni_val = dni.iloc[noon_idx]

284

dhi_val = dhi.iloc[noon_idx]

285

else:

286

dni_val = dni[noon_idx]

287

dhi_val = dhi[noon_idx]

288

print(f"{model_name:<10} {ghi:<6.0f} {dni_val:<6.0f} {dhi_val:<6.0f}")

289

```

290

291

### Clear Sky Detection

292

293

```python

294

import pvlib

295

from pvlib import clearsky, solarposition, atmosphere

296

import pandas as pd

297

import numpy as np

298

299

# Generate synthetic clear sky and measured data

300

lat, lon = 40.0583, -74.4057

301

times = pd.date_range('2023-06-21', periods=24, freq='H', tz='US/Eastern')

302

303

# Solar position and clear sky

304

solar_pos = solarposition.get_solarposition(times, lat, lon)

305

airmass_abs = atmosphere.get_absolute_airmass(

306

atmosphere.get_relative_airmass(solar_pos['zenith'])

307

)

308

clear_sky = clearsky.ineichen(

309

solar_pos['apparent_zenith'], airmass_abs, linke_turbidity=3.0

310

)

311

312

# Create synthetic measured data with some cloudy periods

313

np.random.seed(42)

314

measured_ghi = clear_sky['ghi'].copy()

315

# Add some clouds (reduce irradiance) for certain hours

316

cloudy_hours = [9, 10, 14, 15]

317

for hour in cloudy_hours:

318

measured_ghi.iloc[hour] *= 0.3 + 0.4 * np.random.random()

319

320

# Detect clear sky periods

321

clear_mask = clearsky.detect_clearsky(

322

measured=measured_ghi,

323

clearsky=clear_sky['ghi'],

324

times=times

325

)

326

327

print("Clear sky detection results:")

328

print("Hour, Measured GHI, Clear Sky GHI, Clear Sky?")

329

for i in range(8, 17): # Daytime hours

330

hour = times[i].hour

331

measured = measured_ghi.iloc[i]

332

clear = clear_sky['ghi'].iloc[i]

333

is_clear = clear_mask.iloc[i]

334

print(f"{hour:2d}:00, {measured:6.0f}, {clear:6.0f}, {is_clear}")

335

```

336

337

### Location-Specific Linke Turbidity

338

339

```python

340

import pvlib

341

from pvlib import clearsky

342

import pandas as pd

343

344

# Multiple locations with different turbidity characteristics

345

locations = [

346

{'name': 'Rural', 'lat': 45.0, 'lon': -100.0}, # Clean rural

347

{'name': 'Urban', 'lat': 40.7, 'lon': -74.0}, # Urban pollution

348

{'name': 'Desert', 'lat': 25.0, 'lon': 55.0}, # Desert dust

349

]

350

351

times = pd.date_range('2023-01-01', '2023-12-31', freq='MS')

352

353

print("Monthly Linke turbidity values:")

354

print(f"{'Month':<10}", end='')

355

for loc in locations:

356

print(f"{loc['name']:<8}", end='')

357

print()

358

359

for i, time in enumerate(times):

360

print(f"{time.strftime('%b'):<10}", end='')

361

for loc in locations:

362

try:

363

lt = clearsky.lookup_linke_turbidity(

364

pd.DatetimeIndex([time]),

365

loc['lat'],

366

loc['lon']

367

)

368

print(f"{lt.iloc[0]:<8.2f}", end='')

369

except:

370

print(f"{'N/A':<8}", end='')

371

print()

372

```