If you've made it to post #8 (after doing all of the other 7 R manual entries!), then you are ready to become an **anusolar** R-package jedi master. Well, sort of - I mean, you'll be simulating PV system power output with the SPMQ function. That's pretty rad, right?

The basis for the SPMQ function, are the **Sandia Performance Model** and **Inverter Performance Model** created by the incredible folks at Sandia National Laboratories. These functions, while more than a decade old, still form the basis of modern PV simulation tools like **SAM, the NREL tool for simulating PV system performance. **

I review the modelling process that I've adopted for simulation PV system power output in my KPV paper (Engerer and Mills 2014), so read that manuscript in order to find out more about how **SPMQ** will work. I've also uploaded the two papers that outline the Sandia Performance and Inverter Models here: King et. al. 2004 and King et. al. 2007. The equations laid out in these reports make up the core functions in the SPMQ function R code.

### How do these models and this function work?

The general ideas behind both models is fairly simple. **Given several predictor variables, simulating PV module and inverter power output for a given value of radiation (and temperature and wind velocity) is possible**. These predictor variables are **empirical** coefficients, meaning that they are determined via testing of various PV module and inverter types. The coefficients are then stored in a library, which is published in each updated version of NREL's SAM model.

You can see the current version of the databases in the */code/rpkg/support/SPM/* directory. Where there are 4 files:

**SPMDb.csv,**the Sandia Module Database, for simulating a given PV module**SMD_Compare.csv,**identical in content to SPMDB.csv, but with maximum power point calculations added (PMP), and the table is sorted by this value to allow for easier selection of a matching module for your simulations. The original row number is in the left column and is the**$mm**variable described in**"3. Working with Data"**under**"Module Matching"****inv_lib.csv,**empirical coefficients for the inverter modelling, selected based on the row number in variable**$im**(again, see**"3. Working with Data"**under**"Inverter Matching"****)****inv_types.txt**, inverter names by row number in the database

There are **three things **that are required to simulate PV system performance:

- Radiation data
- Weather observations
- Metadata about the PV system

More specifically, **SPMQ** expects three objects:

**s,**a list object of radiation data, which includes:**$Egt, $Ebt, $Edt**- the three tilted components of radiation on plane of array surfaces**$ama, $aoir**- absolute air mass and angle of incidence (radians)

**swx**, weather observations of matching timesteps, including:**$tmp,**temperature in Celsius**$wsp**, wind speed in km/h

**ar,**metadata array which contains all of the PV metadata described in**3. Working with Data**.

### Let's start off by generating a clear sky curve for a solar PV system.

In this example, we'll work with data from Sydney, and a ramp event that James Bills identified in his honours thesis of the PV power output in the region. You can find the example code in */code/examples/syd.pvo.ramp_event.R*

**# load PV metadata for 500 PV sites in Sydney***syd = ar.in("SYD") *

**# load in some raw PV data***indf = read.pvo(syd,2013,11,22) # largest negative collective ramp from Bills 2015kwr = indf[,3:dim(indf)[2]] # trim off the timestamps, keep only power output*

**# grab the matching weather data, match it with the PV data ***wx = read.wx(syd,2013,11,22)swx = shrink.wx(wx,indf)*

**# solar geometry (R Manual Post #6)***sza = SZAQ(indf,syd)*

**# clear sky model (R Manual Post #7)***csm = CSMQ(sza,swx,'rest2',syd)*

**# simulate clear sky power output for PV systems***spm = SPMQ(csm,swx,syd)kwc = spm[,3:dim(spm)[2]] # trim off the timestamps, get PV estimates only*

The above code will load in the PV metadata for Sydney, bring in some raw PV power output data, as well as some weather observations (provided for station 66006 on required days only). This is all of the data we'll require **to run some PV system simulations for clear sky radiation**, and then use the simulated data in a simple analysis.

We'll use the time-stamped PV power output data as the input data frame to SZAQ, to get all of the solar geometry calculations we'll require. We pass the output of **SZAQ** to **CSMQ**, as we learned to do in the last post.

With the output from **CSMQ, **our clear sky radiation estimates, we can actually pass this straight into **SPMQ**, as it contains the appropriate radiation components, transposed to the plane of array surfaces of our PV systems.

We then execute **SPMQ** via:

*spm = SPMQ(csm,swx,syd)*

These are the **s, swx **and** ar **input data requirements detailed above.

After this step, we get data.frame object returned via spm, within which are **$gtms **and $**ltms **the UTC and local time, in the first two columns, followed by the simulated clear sky power output for all of the PV systems available in **syd**, our metadata object.

One good trick to learn, is to chop off of the first two timestamp columns, holding onto just the numerical data in* kwc* as shown above. This means that only the clear sky curves are now contained in *kwc*. Which is useful for calculations/analysis with the data.

### Let's Check Out Our Results

**# visualise clear sky example***n=8 # try some other numbers, but watch out for missing data/bad matches (raw data, no Quality Control!)plot(kwr[,n],typ='l',ylim=c(0,1.2))lines(kwc[,n],col='blue',lwd=2)*

What if we change the value of n? Let's try n= 20...

Ignoring the possible issues with our raw dataset, we can still have a bit of fun with the data from this particular day. There was actually a very significant negative ramp event that occurred over the Sydney CBD during this period. To analyse all of the data we can...

**# analyse the major ramp event!***plot(kwr[,1]~indf$ltms,typ='l',ylim=c(0,1.2))for(i in 2:50){lines(kwr[,i]~indf$ltms,col=i)}mndf = rowMeans(kwr,na.rm=T)lines(mndf~indf$ltms,lwd=3,col='black')*

Here is is useful to go into a bit more detail, connecting back to James' thesis. He analysed this event in a bit more detail, and what he found was very interesting:

There was a mega HUGE 94% drop in collective power output over an 85 minute period. But WHY? Don't forget, we need to connect these things back to the meteorology of the event. Look no further than the BoM radar imagery:

This event was triggered by some severe thunderstorm activity, with the power output reduction being connected to the anvil of these thunderstorms blowing downstream within a strongly sheared wind environment.

So here we can connect my two loves! Solar & Severe Storms.

Isn't science awesome?

Coming up next: Using **SPMQ** to get to** KPV calculations.**