-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update to SPICE grid modelling #284
base: develop
Are you sure you want to change the base?
Conversation
We have refactored the netlist generation code to use model objects that generate a netlist. The netlist is solved using PySpice. This removes the need for code in Solcore to kick off a simulation and process the result using text parsing. I have not looked too closely, but parser code is usually quite brittle; changes to the net list can break it. Handing this over to PySpice improves the situation. A result object is passed around to helper functions to generate useful information such as the IV curve, maximum power point, voltages of the different layers, and electroluminescence prediction. The distributed model closely aligns with the methodology of Steiner et al. DOI:10.1002/pip.989, except for the absence of the perimeter recombination diode. This model lacks shunt resistances, but adding them could broaden its application beyond concentrator solar cells. This code is standalone; it uses basic Python types to define the solar cell's junction rather than using Solcore's Junction class. Future changes may want to alter this, but I'm uncertain about the value that Junction offers; it seems to resemble an OrderedDict. Perhaps this would unlock useful integration with other Solcore features. A nice feature of the code is a class for generating grid metalization patterns: GridPattern. This offers a general interface for subclassing, enabling the creation of various grid types. The user needs to implement a function called `draw()` and use the pixie-python drawing API to render the desired grid pattern. A HGridPattern subclass has been implemented here. This class offers some useful functionality, such as being able to save the grid pattern to an image file, which uses pillow (PIL). We have added a sparse example script. We have added a much more detailed Python Notebook file that guides the user through the entire process, from basic simulation to computing a concentration vs. efficiency plot.
The netlist is solved using PySpice in the latest code, this simplifies the code a bit and also allows this code to be moved out of solcore (at a later date, if wanted). The new GridPattern classes use a pixel drawing API from Pixie (pixie-python module)
Hi Dan, I will have a more detailed look later, but re: the tests, all the environments (Windows, macOS, Ubuntu) should have ngspice installed, see the workflow file. I assume this mean that SPICE is also installed? I should probably know this but I have never really used either of them so I don't really even know what the difference is... Looking up the error thrown in the Ubuntu tests gives me this. You can try modifying the workflow file to get the tests running on at least one operating system; then we can always exclude them from the others using an approach similar to that used in test/test_optics.py which skips tests relating to S4 if it's not installed. |
Hello developers and old friends!
I have made some changes to the SPICE Quasi3D code, particularly how the netlist is generated and executed. This was originally a refactor but things went ... a bit too far, you know how it is 😄. I have left the original code unchanged but added new modules in the
solcore/spice
directory.Please let me know what remains to be done before you will accept the pull-request. The unit tests I run are passing locally but I see they are failing on GitHub, I think because the environment does not have SPICE installed and one of the tests called the solver.
Standalone simple Python interface
This code is standalone; it uses basic Python types to define the solar cell's junction rather than using Solcore's Junction class. Future changes may want to alter this, but I'm uncertain about the value that Junction offers; it seems to resemble an OrderedDict. Perhaps this would unlock useful integration with other Solcore features? I am not familiar enough with Solcore to make a proper judgement call here, so please let be know what you think.
A comment in passing - When starting to develop this is was quite hard to read the code to see how the example code works. In the end I needed to run the code and spend a long time with a debugger trying to understand things. This is because the code is so dynamic. Originally I thought the
Junction
object did something, rather than just being a bucket for values. The plugin nature was another reason following the execution was a little tricky; for example, when solving a solar cell the solver that is used is determined at run time. I guess these are simply the pros and cons of Python and you can call them a feature too if you like.What I have tried to do with the code here is make it as readable as possible. I hope you can read the new files and get a feel for what the code does without running the new examples in the debugger.
A quick overview
You generate a netlist from a minimal number of inputs (keyword arguments are used here to specify resistivity and material parameters different from the default values),
The netlist is solved over the specified voltage range and voltage step,
This returns a result object that can be queried or simply passed to helper functions to extract useful information.
There are also helpful functions to plot this information,
We can access 3D grid of node voltages using,
and then plot the surface voltage distribution (bias_index is the voltage corresponding to the maximum power point),
You can also make electroluminescence predictions (using generalised Planck scaling of the voltage distribution),
Examples
For more examples, see,
solcore/examples/cpv_grid_spice_example.py
, short and sweep script that shows how to call the new codesolcore/examples/cpv_grid_spice_example.ipynb
, a much more detailed example with some discussion and ending in a script that uses solcore to calculate the short-circuit current of a solar cells and uses the new SPICE model to compute an efficiency verse concentration plot.PySpice
The netlist is solved using PySpice. This removes the need for code in Solcore to kick off a simulation and process the result using text parsing. I have not looked too closely at the solcore code, but usually text parsers are quite brittle; changes to the netlist, naming conventions etc. can break it etc. Handing this over to PySpice improves this situation because essentially a different project is maintaining that code for you.
It also integrates nicely with the way solcore specifies that SPICE path.
This adds one dependency.
Grid Pattern
I added an class called Grid Pattern that defines an interface/API for rendering any metallisation pattern for the front surface of the solar cell. Subclassing, enables the creation of various grid types. The user needs to implement a function called
draw()
and use the pixie-python drawing API to render the desired grid pattern. AHGridPattern
subclass has been implemented here. This class offers some useful functionality, such as being able to save the grid pattern to an image file, which uses pillow (PIL).This adds two dependences.
For example,
This uses the scheme that white = bus, grey = grid finger and black = no metal.
I think programmatic approach to grid generation might be quite useful in the future particularly if connecting it with optimisation algorithm to design metallisation.
Object orientated netlist construction
Take a look at
solcore/spice/model.py
and you will find objects for each sub-circuit in the distributed spice model: Metal, Bus, Device (junction), Diode (junction in the dark), Base, RearContact.Before constructing the netlist we first arrange these object in a 3D grid (a numpy array) to define the structure of the solar cell we want to solve. We then process the 3D array and generate the netlist.
A nice result of this approach is the ease connecting the distributed sub-circuits together without the use of "wires". Moreover, because the spatial arrangement is known a priori and objects represent neighbouring circuits it becomes easy to label all of the nodes in the 3D mesh.
Also, this approach is quite testable. Unit tests define the required node naming conventions for each object.
Solution result object
A result object is passed around to helper functions to generate useful information such as the IV curve, maximum power point, voltages of the different layers, and electroluminescence prediction.
Background
The model seems more or less the same. It follows the methodology of Steiner et al. DOI:10.1002/pip.989 ( I did not go to the trouble of adding the perimeter recombination diode). Note, this model lacks shunt resistances because it targets concentrator solar cells, but adding them could broaden its application, I can do that if needed.
Documentation
I have updated the documentation by editing the existing Quasi3D document. Hope this was OK?
Looking forward to hearing from you!
Dan