pvlib / pvlib-python

A set of documented functions for simulating the performance of photovoltaic energy systems.
https://pvlib-python.readthedocs.io
BSD 3-Clause "New" or "Revised" License
1.19k stars 1k forks source link

PVSystem setup with different arrays - how to reproduce an actual system #1633

Open kimcholi opened 1 year ago

kimcholi commented 1 year ago

Hey hey,

I am currently working with PVlib to do a solar energy estimation of an actual setup. This will be done by comparing the modelled power outputs with the measured power outputs of the system. For this, I have two different setups where I was wondering if you can help me with writing the correct system description for the setup. The setup can be seen in the attachment. It has two different inverters but the same modules, all having the same tilt but different orientation angles as can be seen in the code below. Inverter 1 has two strings: one with in total 9 modules in a row and another one with in total 6 modules in a row. Inverter 2 has two strings with 6 modules each.

After I imported all libraries and necessary imports (including inverters, modules, weather data) I started describing the system, see below. My difficulty is that I don’t know how to properly reproduce the actual setup within the code to model the power output.

times = pd.date_range('', '', closed='left', freq='H', tz=tz)

loc_1 = pvlib.location.Location(latitude , longitude, tz = [times.tz](http://times.tz/))
loc_2 = pvlib.location.Location(latitude, longitude, tz = [times.tz](http://times.tz/))

solar_position_1 = loc_1.get_solarposition(times)
solar_position_2 = loc_2.get_solarposition(times)

tilt = 90 #as they are all wall-mounted

#azimuth North facing
azimutht_ne1 = 48
azimuth_ne2 = 24
azimuth_n = 360
azimuth_nw1 = 336
azimuth_nw2 = 312

#mount 
mount_ne1 = FixedMount(tilt, azimuth_ne1)
mount_ne2 = FixedMount(tilt, azimuth_ne2)
mount_n = FixedMount(tilt, azimuth_n)
mount_nw1 = FixedMount(tilt, azimuth_nw1)
mount_nw2 = FixedMount(tilt, azimuth_nw2)

#azimuth South facing
azimuth_sw1 = 241
azimuth_sw2 = 217
azimuth_s1 = 191
azimuth_s2 = 168
azimuth_se1 = 144
azimuth_se2 = 120

#mount 
mount_sw1 = FixedMount(tilt, azimuth_sw1)
mount_sw2 = FixedMount(tilt, azimuth_sw2)
mount_s1 = FixedMount(tilt, azimuth_s1)
mount_s2 = FixedMount(tilt, azimuth_s2)
mount_se1 = FixedMount(tilt, azimuth_se1)
mount_se2 = FixedMount(tilt, azimuth_se2)

array_kwargs_1 = dict(module_parameters, temperature_model_parameters, modules_per_string = 3, strings = 1)
array_kwargs_2 = dict(module_parameters, temperature_model_parameters, modules_per_string = 2, strings = 1)

array_ne1 = Array(mount_ne1, name ='NE1', **array_kwargs_1)
array_ne2 = Array(mount_ne2, name ='NE2', **array_kwargs_1)
array_n = Array(mount_n, name ='N', **array_kwargs_1)
array_nw1 = Array(mount_nw1, name ='NW1', **array_kwargs_1)
array_nw2 = Array(mount_nw2, name ='NW2', **array_kwargs_1)

array_sw1 = Array(mount_sw1, name ='SW1', **array_kwargs_2)
array_sw2 = Array(mount_sw2, name ='SW2', **array_kwargs_2)
array_s1 = Array(mount_s1, name ='S1', **array_kwargs_2)
array_s2 = Array(mount_s2, name ='S2', **array_kwargs_2)
array_se1 = Array(mount_se1, name ='SE1', **array_kwargs_2)
array_se2 = Array(mount_se2, name ='SE2', **array_kwargs_2)

arrays_1_1 = [array_ne1, array_ne2]
arrays_1_2 = [array_n, array_nw1, array_nw2]
arrays_1 = [arrays_1_1, arrays_1_2]
arrays_2_1 = [array_sg64_sw1, array_sg64_sw2, array_sg64_s1]
arrays_2_2 = [array_sg64_s2, array_sg64_se1, array_sg64_se2]
arrays_2 = [arrays_2_1, arrays_2_2]

#PVsystem of arrays 
system_1 = PVSystem(arrays = arrays_1, inverter_parameters = inverter_1, strings_per_inverter=2)
system_2 = PVSystem(arrays = arrays_2, inverter_parameters = inverter_2, strings_per_inverter=2)

As stated in the PVlib docs forpvlib.pvsystem.PVSystem():

The class supports basic system topologies consisting of:

For the setup with Inverter 1 we have once N=6 and once N=9 but M=2. How do I implement NxM in the code of the system description? For the setup with Inverter 2 it would be N=6 and M=2 and from this point of view easy to implement. But how do I feed into the system which 6 modules are connected in series? I tried to do two arrays who represent one string each but how do I feed this information exactly to PVlib? Is anyone familiar with this issue and can help me out?

Thank you very much, I would appreciate it. setup_PVsystem.pdf

cwhanse commented 1 year ago

@kimcholi according to the attached pdf, the system has two inverters, and each inverter has two Array inputs. Within each Array there are groups of modules at different orientations. As of the current release, pvlib doesn't support an Array with several orientations; all modules in an Array are at the same orientation and tilt.

So in your code, after the Arrays are defined (array_ne1, etc.) you would have to do the following:

  1. calculate DC output for each Array
  2. combine DC output for Arrays connected in series to get DC voltage and DC power. pvlib doesn't have a function to add I-V curves in series; somewhere I have code that I could provide if desired. (@pvlib/pvlib-core this is why I'm leaving this as an issue, rather than asking to move it to a discussion)
  3. input the combined DC to one of the multi-input inverter models, e.g., pvlib.inverters.sapm_multi
kimcholi commented 1 year ago

Thank you very much for the explanation @cwhanse. I will implement this in my model but will still keep this issue open in case another problem is coming up while I am doing so.

cwhanse commented 1 year ago

You are welcome @kimcholi

We use Issues to track items that require changes in pvlib itself (a request for a function to add series-connected I-V curves qualifies so I'm leaving this Issue open for now).

If you have usage questions, please open a Discussion, or ask on the pvlib google group or stackoverflow.

kimcholi commented 1 year ago

I actually would take up your offer for the code to add I-V curves @cwhanse. This would then be the step to combine the DC outputs for arrays connected in series, right? I have calculated each DC output for each array and would move on to the next step now for which I believe your code would be very helpful. Cheers :)

kimcholi commented 1 year ago

@cwhanse just one more clarification that I am not going down the wrong path. If I have a setup like like in the png-file, then I can go along with pvlib.pvsystem.PVSystem() and use the arrays as a parameter (as long as an array has the same orientation), right? And then I can run it with pvlib.modelchain.ModelChain.run_model()

circuitdiagram
cwhanse commented 1 year ago

@kimcholi As long as modules in an Array have the same orientation, and the Arrays are parallel inputs to the inverter, then yes I think you can use a ModelChain to execute this.

kimcholi commented 1 year ago

Thank you @cwhanse. Do you end up finding the code for the array setup with different orientations? I believe this could be a great help for me to model the setup.