danieljfarrell / pvtrace

Optical ray tracing for luminescent materials and spectral converter photovoltaic devices
Other
97 stars 94 forks source link

Validation script modifications #37

Closed jaydeshpande closed 3 years ago

jaydeshpande commented 3 years ago

https://core.ac.uk/download/pdf/76989828.pdf validating against fig 3.21


from pvtrace import *
import numpy as np
import matplotlib.pyplot as plt

def create_waveguide():
    # Simulation wavelength range
    x = np.arange(400, 801, dtype=np.float)

    # LSC plate size
    size = (l, w, d) = (4.8, 1.8, 0.260)  # cm

    # Make LSC model
    lsc = LSC(size, wavelength_range=x, n1=1.49)
    #lsc.add_solar_cell({'left', 'right', 'near', 'far'})

    # Use Fluro Red dye with peak absorption coefficient 11.39 cm-1
    lsc.add_luminophore(
        'Fluro Red',
        np.column_stack((x, fluro_red.absorption(x) * 11.387815)),  # cm-1
        np.column_stack((x, fluro_red.emission(x))),
        quantum_yield=0.95
    )

    # Include constant background absorption coefficient of 0.02 cm-1
    lsc.add_absorber(
        'PMMA',
        0.02 # cm-1
    )

    # This function returns an approximation of the lamp spectrum used in the experiment
    def lamp_spectrum(x):
        """ Fit to an experimentally measured lamp spectrum with long wavelength filter.
        """
        def g(x, a, p, w):
            return a * np.exp(-(((p - x) / w)**2 ))
        a1 = 0.53025700136646192
        p1 = 512.91400020614333
        w1 = 93.491838802960473
        a2 = 0.63578999789955015
        p2 = 577.63100003089369
        w2 = 66.031706473985736
        return g(x, a1, p1, w1) + g(x, a2, p2, w2)

    # Add a custon light
    lamp_dist = Distribution(x, lamp_spectrum(x))
    wavelength_callable = lambda : lamp_dist.sample(np.random.uniform())
    position_callable = lambda : rectangular_mask(l/2, w/2)
    lsc.add_light(
        "Oriel Lamp + Filter",
        (0.0, 0.0, 0.5 * d + 0.01),  # put close to top surface
        rotation=(np.radians(180), (1, 0, 0)),  # normal and into the top surface
        wavelength=wavelength_callable,  # wavelength delegate callable
        position=position_callable  # uniform surface illumination
    )
    return lsc
runs = {}
for i in range(10):
    lsc = create_waveguide()
    lsc.simulate(800, emit_method='full')
    counts = lsc._make_counts(lsc._df)
    opdt = 100*counts[['Solar Out', 'Luminescent Out']].sum(axis=1)/800
    runs[i] = opdt.to_list()
import pandas as pd 
combinedDat = pd.DataFrame.from_dict(runs, orient='index')
combinedDat.rename({0:'left', 1:'right', 2:'near', 3:'far', 4:'top', 5:'bottom'}, axis=1, inplace=True)
danieljfarrell commented 3 years ago

What was the change you made?

jaydeshpande commented 3 years ago

I suspect ... I changed too many things when I tried it the last time. For this script above:

Comparison below:

Surface Model Fraction (%)
Bottom Raytrace ICL 49.2537313
Bottom Raytrace ECL 49.8507463
Bottom Thermodynamic 50
Bottom PVtrace 50
Top Raytrace ICL 13.5820896
Top Raytrace ECL 13.5820896
Top Thermodynamic 13.7313433
Top PVtrace 13.95
Long Raytrace ICL 7.1641791
Long Raytrace ECL 7.01492537
Long Thermodynamic 7.01492537
Long PVtrace 7.03125
Short Raytrace ICL 6.56716418
Short Raytrace ECL 6.26865672
Short Thermodynamic 5.67164179
Short PVtrace 5.7875
jaydeshpande commented 3 years ago

By the way - I truly believe in the capability of PVTrace. I might do some pull requests with new additions if you are open to it!

I like how clean and easy to understand it is.

danieljfarrell commented 3 years ago

What features are you thinking of adding? I would certainly consider any pull requests. You want to make a proposal first so that it's definitely something I want to include in the project.

danieljfarrell commented 3 years ago

Thanks for preparing the script above and the table! Makes it very clear. In fact I was half way along doing this myself. This is why I isolated this on its own branch.

jaydeshpande commented 3 years ago

Sure! I will think about it a bit more - I will run the proposal by you. So far, I feel that the ability to import meshes would be the most welcome addition. I see that you have already created an issue about that. Would be great if we can import STL meshes.

btw, feel free to use the script above as a demo script in the next version if you'd like.

danieljfarrell commented 3 years ago

Yes, I will include the script above in the next release.

There is an example using an icosahedron mesh here. pvtrace can already import STL meshes using the Mesh geometry and trimesh.

jaydeshpande commented 3 years ago

Thanks! Those examples went under my radar. I will take a look.

danieljfarrell commented 3 years ago

Validation notebook has been added!

https://github.com/danieljfarrell/pvtrace/blob/dev/lsc-device/examples/Validation.ipynb

Thanks for your input in getting this completed.

danieljfarrell commented 3 years ago

See #37