Вы находитесь на странице: 1из 45

Abstract

A luminescent solar concentrator is a window which concentrates optical photons for the purpose of generating electricity. This window can replace existing
windows, and provides an emission free, clean energy source.
The project is based on the use of Geant4, a toolkit used for the simulation
of particles through matter. This is used to model the emission of photons onto a
luminescent solar concentrator. The objective of this model is to find an optimum
design for the types of dye, concentration of dyes, and the dimensions of the window.
Dyes are modelled through the definition of their physical characteristics, namely
their emission and absorption spectra within the host material, PMMA. Montecarlo simulations are used to model the statistical variance based upon these two
spectra. Solar panels are modelled by the use of sensitive detectors. These output
individual photon trajectory information, and therefore can give information based
upon optimum dye type, photon energy and angle of photon incidence; giving the
maximum total incident photon energy.
This report outlines the code and techniques used to implement this scientific
model, and explains why some decisions were made. It explains why Geant4 was
selected, and the results gained from the simulations.

Contents
1

Introduction

Geant4
2.1 Monte-Carlo Methods . . . . . . . . . . . . . . . . . . . . . . .
2.1.1 Randomisation . . . . . . . . . . . . . . . . . . . . . .
2.2 Example N06 . . . . . . . . . . . . . . . . . . . . . . . . . . .

5
5
5
5

Photon source
3.1 Photon Origin . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2 Photon Energy Histogram . . . . . . . . . . . . . . . . . . . . .

7
7
8

Geometry
4.1 Solar Panels . . . . . . . . . . . . . . . . . . . . . . . . . . . .

10
12

Dyes
5.1 Absorption Length Calculations . . . . . . . . . . . . . . . . . .
5.2 Data Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

14
15
16

Run

18

Experiment
7.1 Geometrical Gain . . . . . . . . . . . . . . . . . . . . . . . . .
7.2 Testing Dye Type . . . . . . . . . . . . . . . . . . . . . . . . .
7.3 Concentration . . . . . . . . . . . . . . . . . . . . . . . . . . .

21
21
21
21

Results
8.1 Geometrical Gain . . . . . . . . . . . . . . . . . . . . . . . . .
8.2 Total Efficiency and Viewing Blur . . . . . . . . . . . . . . . . .
8.3 Concentration . . . . . . . . . . . . . . . . . . . . . . . . . . .

22
22
22
22

Discussion
9.1 Geometrical Gain . . . . . . . . . . . . . . . . . . . . . . . . .
9.2 Total Efficiency . . . . . . . . . . . . . . . . . . . . . . . . . .
9.3 Concentration . . . . . . . . . . . . . . . . . . . . . . . . . . .

24
24
24
24

10 Conclusion
10.1 Optimal Design . . . . . . . . . . . . . . . . . . . . . . . . . .
10.2 Practical Considerations . . . . . . . . . . . . . . . . . . . . . .

25
25
25

11 Model Limitations

26

12 Conclusion

27

13 Appendix

27

Introduction

The suns natural energy provides a way to gather clean, reliable, and a renewable
source of electrical power. The luminescent solar concentrator allows this energy to be
harnessed by large buildings with a low space real estate, and with minimal aesthetic
modifications.
The luminescent solar concentrator is based upon a dye which absorbs and re-emits
light at a different wavelength and in a different direction. The energy collected is deposited by photons which reach solar panels, which are installed at the sides of this
window. A luminescent solar concentrator concentrates the solar energy by collecting
light over a large area and directing it to a relatively small, in area, photovoltaic panel.

Figure 1: Cross-section of a luminescent solar concentrator. Blue dashed lines indicate


incoming sunlight. Red lines indicate emitted light to the photovoltaic cell to the side

The design parameters of a luminescent solar concentrator lie within the specifications
of the dye and of the LSC sheet. The type of dye, dye concentration, and alignment
the dyes are important. Specifically, the emission and absorbance spectra of the dyes
chosen. This is so that maximum energy can be absorbed from the suns spectra, as
well as reducing the total number of emitted photons being reabsorbed twice, and losing energy. The probability of re-emission is dependent on the quantum yield of the
chosen dye.

A double glazed array of 2 LSC windows, with different dyes is chosen so to maximise total cross-over absorption bandwidth spectra. This effectively doubles the total
bandwidth of the LSC, as well as doubling the absorbing surface area presented.
The host material chosen is PMMA. This is due to its transparent nature at frequencies of visible light, allowing the LSC to be used as a window.
The geometrical gain of the window is an important factor to consider for the optimisation of luminescent solar concentrators. A higher geometrical gain leads to a reduction
in cost per Watt of energy. This is due to the increase in inexpensive total surface area,
which collects more photons, rather than increasing expensive photovoltaics .
3

The computer simulation built for this project models a luminescent solar concentrator.
By using a model, the data can be collected, before doing physical tests with expensive
prototypes. The model provides easy methods which allows for the varying of concentration, type of dye and number and angle of photons. Whilst outputting individual
photon trajectory information, which provides information on the ratio of photons that
reach the photovoltaic cell to the total landing on the LSC. The model is sufficiently
lightweight to fire many photons and provides statistically sound results.
There are various loss mechanisms in a luminescent solar concentrator. Losses are
found through heat loss, photons being emitted at a smaller angle of incidence than
that of the total internal reflection, and photons being reabsorbed on their path into the
solar panel.
The model was built using Geant4, a platform used for the simulation of particles
through matter. This was chosen due to the predefined methods of wavelength shifting,
material definitions, tracking, detector response, visualisation and material interactions.
A pre-defined example, Example N06 was used as a starting point for this project.
This example provided the basis of having a volume contained within a universe, and a
suitable amount of physics lists and visualisations. This example was heavily modified
to add wavelength shifting properties, suitable detectors, multi-photon emission, data
input, data collection, and data manipulation.
The objectives of this report was to find the optimum dye type, dye concentration and
LSC dimensions before manufacturing physical products.
The results found that a double glazed LSC was most efficient. A dye concentration
of Rhodamine B was optimum at 0.44M ol/cm3 , with Crystal Violet in the 2nd LSC
sheet, at a concentration of 0.39M ol/cm3 . The geometrical gain was found to be best
the higher the value was. Therefore, the bigger the LSC, the more efficient this is.
Leading to the conclusion that an luminescent solar concentrator would be best used
on buildings with floor to ceiling windows

Geant4

Geant4 is a toolkit developed at CERN. It was selected due to it being designed specifically for the simulation and passage of particles through matter.[2] This therefore
means that many of the methods required for the physics and behaviours of particles as
they travel through matter are provided.
Geant4 is particularly useful in the fact that data can be output for individual photons.
This means that rather than only having an overall wattage, the behaviour of a photon
at any energy and direction can be traced, and therefore analysed. This is particularly
important for the optimisation of a luminescent solar concentrator, so that photons with
particular energies can be tracked.

2.1

Monte-Carlo Methods

Geant4, importantly, uses monte-carlo methods. This allows for the modelling of the
non-linear and statistical nature of the absorption and re-emission of photons in the
PMMA.

2.1.1

Randomisation

An initial seed[4] is input and serves as the basis for the resultant randomisation of an
entire run. During the progress of a run, the initial starting position and energy of a
photon is randomised within a desired limit. This is used to model the statical nature of
individual photons landing at a specific point on earth. This can be extended to varying
the angles and polarisation of photons, as well as their position and energy.
The statistical nature of the absorption within a dye is also taken account here. With a
statistical chance, based upon the molar extinction of when, or even if, that particular
photon will be absorbed. This is largely based upon the concentration and dye type that
is used.
The direction of the emitted photon is based randomly, whereas the energy of the photon is based upon the emission spectra, with arbitrary units defining the percentage
likelihood at any given energy level.
All these different factors combine to form a totally different, but statistically similar
output result. It was found that it required the run of 10,000 photons to get consistently,
statistically similar output results.

2.2

Example N06

The example N06 was used as a starting point to create the luminescent solar concentrator. This novice example provides the basic geometry, and universe structure in the

form of a water tank containing air bubbles. It also provided the necessary visualisation, some of the physics and optical processes, and the interactivity.
Many of the features such as Cerenkov Radiation, and scintillation were removed, with
new ones added, such as wavelength shifting which allowed for the modelling of the
behaviour of dyes. [5]

Photon source

A photon source is defined in the file generalparticlesource.cc. This replaced the particlegun.cc class, and allowed for the easy, customisable definition
of number of primary source particles in a single run. It also made it easier to define
energy distribution histograms, and angles of incidence for these primary source particles. The characteristics of this particle source are not hard-coded, rather, input within
the marco file, sun.mac[1]

3.1

Photon Origin

The origin of the photons are defined within a macro file. The placing of photons is
decided at random, within a defined, 6x6m square surface. This is placed at 4.5m above
the centre of the LSC. The angles of emission, location generated, direction and energy
characteristics can be randomised or defined by altering the code found in Listing 1.
Listing 1: Emission Surface Definitions
1
2
3
4
5
6
7
8
9
10
11
12
13

/gps/particle opticalphoton # Define particle tape as optical\leftarrow \rhook


photon
/gps/pos/type Plane # Emission surface is plane
/gps/pos/shape Square # Shape of plane is square
/gps/pos/centre 0. 9. 0. m # Centre placed 9m above centre
/gps/pos/rot1 1. 0. 0.
/gps/pos/rot2 0. 0. 1. # Rotation vectors placed to be \leftarrow \rhook
parallel to LSC
/gps/pos/halfz 3. m # Size of square to be 6x6m
/gps/pos/halfx 3. m
/gps/pos/halfy 3. m
/gps/direction 0. -1. 0. # Direction to be normal to LSC
/gps/ang/type planar

3.2

Photon Energy Histogram

The input energy histogram used is based upon the spectra of energy measured of the
sun at normal irradiance, nearly parallel (0.5 deg divergent cone) radiation on surface
with a normal tracking of the sun, excluding scattered sky and reflected ground radiation [3]. The spectrum selected is an industry standard for the testing of solar panels
and is known as ASTMG173, based upon AM1.5.

Figure 2: ASTMG173 suns energy spectra, measured normal irradiance, nearly parallel (0.5 deg divergent cone) radiation on surface with a normal tracking of the sun,
excluding scattered sky and reflected ground radiation

This spectra was selected as it closely, and accurately matches the spectra of light
hitting the LSC in the simulations, due to the normal trajectory of each photon onto the
window. It is important to accurately model the energy spectra of the sun so that an
accurate output energy data can be collected based upon the absorption and emission
spectra of the photons.

This spectra is input manually with the macrofile shown in listing 2.


Listing 2: Photon Energy Historgram Definition
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# Energy definitions
/gps/ene/type User # Histogram type user defined
/gps/hist/type energy # Link histogram to energy definitions
/gps/hist/point 350255 0.0000 # Single point of histogram
/gps/hist/point 353975 0.0000 # Wavelength in eV & power in\leftarrow \rhook
arbitrary units
/gps/hist/point 357694 0.0000
/gps/hist/point 361414 0.0000
/gps/hist/point 365133 0.0000
/gps/hist/point 368853 0.0001
/gps/hist/point 372572 0.0006
/gps/hist/point 376292 0.0048
/gps/hist/point 380012 0.0116
/gps/hist/point 383731 0.0237
/gps/hist/point 387451 0.0538
/gps/hist/point 391170 0.0648
...

The number of photons in this specific run can be defined through the last line, run/beamOn x,
where x is the number of photons emitted.

Geometry

PMMA (Polymethyl methacrylate) was chosen as the base material for the luminescent solar concentrator. PMMA is a transparent thermoplastic, and is often used as a
shatter-proof alternative to glass. In addition to this, PMMA is both cheap and easy to
handle.
Within Geant4, the geometry is divided into two important sections. Firstly, materials must be defined. For this model only air, and PMMA are required , defining the
universe, and LSC respectively. The dyes are defined as a physics process within the
PMMA slabs.
Materials are added through the definition of their chemical properties, where air is
defined by the addition of 2 hydrogen, and an oxygen atom, shown in listing 3, and the
respective atoms for PMMA, shown in listing 4.
Listing 3: Definition of water
1
2
3

4
5
6
7
8

// Water
//
G4Element* H = new G4Element("Hydrogen", "H", z=1 , a=1.01*\leftarrow \rhook
g/mole); //Define new Geant4 element called Hydrogen and\leftarrow \rhook
setting molar mass as 1.01g/mole
G4Material* Water = new G4Material("Water", density= 1.0*g/\leftarrow \rhook
cm3, nelements=2);
//Define new material by its density and number of elemtns
Water->AddElement(H, 2); //add 2 hydrogen
Water->AddElement(O, 1); //add single oxygen atom

Listing 4: Definition of PMMA


1
2
3
4
5
6
7
8
9
10
11
12
13
14

G4Element* elC = new G4Element("Carbon", "C", 6., 12.01*g\leftarrow \rhook


/mole);
G4Element* elO = new G4Element("Oxygen" ,"O" ,8.,16.00*g/\leftarrow \rhook
mole);
G4Element* elH = new G4Element("Hydrogen","H",1., 1.0079*\leftarrow \rhook
g/mole);
const G4int Cl_Num = 2; //25;
G4double Energy_levels[Cl_Num] = {0.5*eV, 10.0*eV};
G4Material* PMMA = new G4Material("PMMA",1.18*g/cm3, 3); \leftarrow \rhook
// PMMA has formula C5O2H8
PMMA->AddElement(elC, 5);
PMMA->AddElement(elO, 2);
PMMA->AddElement(elH, 8);
//PMMA Refractive Index
G4double PMMA_RIndex[nEnt] = {1.4893, 1.4899};

10

15
16
17
18
19
20
21
22
23
24
25
26

//PMMA Absorbption Length


G4double PMMA_AbsLen[nEnt] = {1*m, 1*m};
G4MaterialPropertiesTable* myMPT5 = new \leftarrow \rhook
G4MaterialPropertiesTable();

G4MaterialPropertiesTable* PMMA_mt = new \leftarrow \rhook


G4MaterialPropertiesTable();
myMPT5->AddProperty("RINDEX",Energy_levels,PMMA_RINDEX,\leftarrow \rhook
Cl_Num);
//set refrective index
myMPT5->AddProperty("ABSLENGTH",Energy_levels,PMMA_ABSL,\leftarrow \rhook
Cl_Num);//Set absorption length for all energies
PMMA->SetMaterialPropertiesTable(myMPT5); //adds \leftarrow \rhook
properties to PMMA material

The physical characteristics of the PMMA are defined by adding the refractive indexes[6],
and its absorption length properties. These properties are fixed at the levels of energies
used.
The physical volumes are created by creating a box and defining its dimensions, this is
shown in line 8 in listing 5. This box must be filled with either air or PMMA; creating
a logical volume, which is shown in line 13. Lastly, this box must then be placed in the
universe creating a physical volume, with the definition of its position, shown in line
13. This is repeated for creating any volume.
Listing 5: Geometry definitions of universe and world in Geant4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

expHall_x = expHall_y = expHall_z = 10.0*m;


tank_x
tank_y
tank_z

=
=
=

5*m;
100*mm;
5.0*m;

G4Box* expHall_box = new G4Box("World",expHall_x,expHall_y,\leftarrow \rhook


expHall_z);
//Definition of universe
G4LogicalVolume* expHall_log
= new G4LogicalVolume(expHall_box,Air,"World",0,0,0);
//Fill universe with air
G4VPhysicalVolume* expHall_phys
= new G4PVPlacement(0,G4ThreeVector(),expHall_log,"World"\leftarrow \rhook
,0,false,0);
//Place universe at centre
// The First Luminescent Solar Concentrator
//

11

19
20
21
22
23
24
25
26

G4Box* waterTank_box = new G4Box("Tank",tank_x,tank_y,\leftarrow \rhook


tank_z);
G4LogicalVolume* waterTank_log
= new G4LogicalVolume(waterTank_box,Water,"Tank",0,0,0);
G4VPhysicalVolume* waterTank_phys
= new G4PVPlacement(0,G4ThreeVector(),waterTank_log,"Tank",
expHall_log,false,0);

4.1

Solar Panels

The solar panels in this project are defined as rectangles that surround the main PMMA
slab. These slabs are filled with PMMA, as to not interfere with the trajectory of the
photons, but record individual photon tracks, energy deposits, and momentum.
The method chosen is a sensitive detector, as this allows for the tracking of individual photons, rather than an overall energy deposit. This property is added to these
PMMA filled volumes. Upon hitting the solar panels, the photons are instantly killed
and the following event is run.
Listing 6: Sensitive Detector assignment to PMMA Solar Panels and data output
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

18

ExN06SD* sd = new ExN06SD(SDname = "ExN06SD");


//Definition of Sensitive Detector
G4SDManager* SDman = G4SDManager::GetSDMpointer();
SDman->AddNewDetector( sd ); //Register sensitive detector \leftarrow \rhook
to sensitive detector manager
solarPanel_log->SetSensitiveDetector(sd); //Register \leftarrow \rhook
sensitive detector to solar panels logical volume
for ( int i = 0 ; i < n_hit; i++){
G4ThreeVector position = (*HC)[i]->GetPosition();//Fetch\leftarrow \rhook
position and energy data
G4double
energy
= (*HC)[i]->GetEnergy();
G4cout << "---- Hit # " << i << G4endl;
G4cout << " Position " << position/cm << " [cm]"//\leftarrow \rhook
Print data for each hit inside solar panel
G4cout << " Energy
" << energy/eV
<< " [keV]"
myfile.open ("/home/zceeh46/Desktop/G4/N06/output.txt",\leftarrow \rhook
ios::app);//Output to .txt file
myfile << energy << " " << position << endl;
panelCounter++;
myfile << "Percentage of photons hitting solar panel: "\leftarrow \rhook
<<100-((totalPanel-panelCounter)*100/totalPanel) << "\leftarrow \rhook
%"<< endl;
myfile.close();

12

The position hit, and energy deposited of each photon is then printed to a text file called
output. A counter is used to store the total number of photons hitting the solar panels.
This number is divided by the total input to give a total photon input to total photons
hitting the solar panels as a percentage. demonstrated in line 17 of Listing 6.

A second set of sensitive detectors are placed above and below the PMMA glass. These
are made of air, and thus do not interact with the photons on their paths. These are used
to count the total input photons, and to compare the positions of a photon at input and
output. This is useful to determine the total number of photons diverged from their
original path whilst in the LSC, and therefore determine the total visible blur.

Figure 3: Detected LED power vs drive current

13

Dyes

The dyes selected for testing were Rhodamine B and Crystal Violet. The reason for
selecting these two dyes is due to their emission and absorption spectra. One dye is
placed in either plane of the double glazed solar luminescent solar concentrator. For
these two particular dyes, the absorption spectra peaks correspond to the natural peaks
of the suns spectra. This is demonstrated in figure 4.
The overall effect of this is an effective doubling of the total energy bandwidth presented by the luminescent solar concentrator. A secondary, beneficial effect is a matching of the emission spectra and absorption spectra of the Rhodamine B and Crystal
Violet respectively. This helps by reabsorbing photons in the Crystal Violet LSC sheet
which have been emitted by the Rhodamine B.

Figure 4: Suns emission spectra with Rhodamine B absorption spectra on left, and
Crystal Violet absorption spectra on right

The implementation of the dyes is done by the addition of physical properties to the
PMMA material, rather than the addition of a physical dye. This allows for the reduction in computational time and resources required, rather than implementing hundreds
of thousands of dyes.
Listing 7: Wavelength Shifting Code Snippet
1
2
3
4

#include "G4OpWLS.hh"
private:
G4OpWLS* theWLSProcess; //Create pointer to theWLSProcess

14

5
6

7
8
9
10
11

myMPT5->AddProperty("WLSABSLENGTH", PhotonEnergyIn1, \leftarrow \rhook


PhotonAbsorb1, nEntriesEmiss1)
->SetSpline(true); //Add data about photon energy, \leftarrow \rhook
absorption length in cm, and total number of data \leftarrow \rhook
points
myMPT5->AddProperty("WLSCOMPONENT", PhotonEnergyOut1, \leftarrow \rhook
PhotonEmiss1, nEntriesEmiss1)->SetSpline(true);
//Add data about photon energy, photon emission probability, \leftarrow \rhook
and total number of data points
myMPT5->AddConstProperty("WLSTIMECONSTANT",5*ns);
//Set time between absorption and emission of photon

The physics process: WLSABSLENGTH maps a 1 for 1 value of energy to total length
travelled in the PMMA, before being absorbed. Whereas for emission, the WLSCOMPONENT
physics process is based upon chance, where arbitrary units are used to base a certain
probability that that energy will be emitted.
The values used are based upon the data available in the PhotochemCAD package,
version 2.1a.[7][8]

5.1

Absorption Length Calculations

The values for absorption are given in the molar extinction, which is a measurement of
how much a chemical absorbs light for a particular energy. This is an intrinsic property
of the chemical.
The length that a photon of a particular energy will travel in is found with the use
of the Beer-Lambert Law:
T = 10 - \sigma lc

(1)

Where T = T ransmission, \sigma =Molar Extinction, and c =Concentration


The thickness of the LSC is chosen to be 4mm, a standard size for a double glazed
window. Therefore, the concentration required to have the highest chance of being
absorbed at the peak molar extinction, for Rhodamine B, at wavelength=541nm is given
by:
1
C=
(2)
\sigma \lambda l
Where L=4mm, \sigma = 105, 100, and \lambda = 541nm.
So:
1
C=
= 0.44M ol/cm3
(3)
105100 \times 5.41 \times 10 - 5 \times 0.4
This concentration is then set as the overall concentration of dye in the LSC. The value
of molar extinction is varied to give values of absorption length, and input into Geant4.
Table 1 illustrates a few examples of this.

15

Wavelength (nm)
500
520
560
600

Molar Extinction (cm - 1 /M )


28289
49751
40672
0

Absorption Length (cm)


1.607
0.878
0.998
\infty

Table 1: Wavelength and respective Absorption Length at 0.44M ol/cm3

5.2

Data Input

A method was written to automatically grab data from a text file, and input this as
an array for the wavelength shifting properties. This allows for the rapid changing of
different dye types, by only having to change the name of the input text file.
Listing 8: getData method which returns string integer as a double
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

vector<G4double> getData(string fileName)


{
//1-demensional \leftarrow \rhook

vector<G4double> dbl_line;
vector
G4double dbl_temp;
store value

//temp double to \leftarrow \rhook

string line; //temporarily contains data from file


string location = "/home/zceeh46/Desktop/G4/N06/data/";
location.append(fileName);
ifstream myfile("/home/zceeh46/Desktop/G4/N06/data/\leftarrow \rhook
Rhodamine_absorption.txt");
if (myfile.is_open()){
//open file
G4cout << "File Opened"<< endl;
while(getline(myfile,line))
//extract \leftarrow \rhook
from myfile and stores in line
{
istringstream linestream(line);
//\leftarrow \rhook
construct istringstream object
string item;
while(getline(linestream,item, ))
//\leftarrow \rhook
stores lines of linestream in item
{
stringstream ss(item);
ss >> dbl_temp;
dbl_line.push_back(dbl_temp);
}
}
myfile.close();
}else

16

28
29
30

G4cout << "Cant open file"<< endl;


return dbl_line;
}

This method is then returned into an array, and the data is sorted to separate wavelength
and molar extinction data. This method is shown in listing 9. The methods have two
checks, checking both the size of the value, assuring that it is within the expected range,
but also whether it is on the left or right hand side of the table, which dictates the data
type.
Listing 9: Sorting methods
1
2
3
4
5

6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25

vector<G4double> Wavelength(vector<G4double>& dbl_line){


vector<G4double> wavelength;
int hi = dbl_line.size();
for(int n = 0; n <hi; n++){ //For loop until end of file
if( dbl_line[n] > 200 && dbl_line[n] < 1000 n % 1 =\leftarrow \rhook
1){ //if value is between 200 and 1000 then is a \leftarrow \rhook
wavelength value and n is odd
wavelength.push_back(dbl_line[n]); //add value \leftarrow \rhook
to end of vector
}
}
return wavelength;
}
vector<G4double> absorption(vector<G4double>& dbl_line){
vector<G4double> power;
int hi = dbl_line.size();
for(int n = 0; n <hi; n++){
if( dbl_line[n] < 200 || dbl_line[n] > 1000 && n % 1\leftarrow \rhook
= 0){ //if bigger than 1000 or smaller than 200 \leftarrow \rhook
and n is even
if(dbl_line[n]>0){
power.push_back(dbl_line[n]);
}else{
power.push_back(0.000000001); //if negative \leftarrow \rhook
number
}
}
}
return power;
}

17

Run

An entire run begins at the top, where the photons emanate from on a random point on
a square plane. These photons then travel down, through the first detector unaffected,
and into the PMMA block with wavelength shifting properties. Based upon the energy
of the photon, the photon either passes through unhindered or is absorbed.

Figure 5: 10 emitted Photons. LSC Sheets are two shown in centre

If the photon is absorbed it is re-emitted 5ns later in a random direction. The photon,
depending on the angle of incidence on the surface of the LSC will either by reflected
back into the LSC, or exit. These two events can be seen in figure 5, where one photon
is guided out to the solar panel, and the other is internally reflected a few times before
exiting and passing through the 2nd LSC sheet.
18

The data output for this run is shown in listing 10. The output data shows the energy
deposited at the solar panel in meV, and the location of the hit. The 2nd value is the
percentage of photons hitting the solar panel at that hit. So, in this run, shown in figure
5, the 6th photon hit the solar panel.
Listing 10: Solar Panel Sensitive Detector Output
1
2

259277 (-5000,0.413444,1615.64)
Total Number of Photons Hitting Solar Panel: 16$%$

A second output is given by the detectors which are placed above and below the LSC,
shown in listing 11.
Listing 11: Above and Below LSC Sensitive Detectors
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

----- Hit Number: 0


in counter: 1
out counter: 1
Percentage of particles passing unaffected: 100%
----- Hit Number: 1
in counter: 2
out counter: 2
Percentage of particles passing unaffected: 100%
----- Hit Number: 2
in counter: 3
out counter: 3
Percentage of particles passing unaffected: 100%
----- Hit Number: 3
in counter: 4
out counter: 3
Percentage of particles passing unaffected: 75%
----- Hit Number: 4
in counter: 5
out counter: 4
Percentage of particles passing unaffected: 80%
----- Hit Number: 5
in counter: 6
out counter: 5
Percentage of particles passing unaffected: 84%
----- Hit Number: 6
in counter: 7
out counter: 5
Percentage of particles passing unaffected: 72%
----- Hit Number: 7

19

37
38
39
40
41
42
43
44
45
46
47
48
49

in counter: 8
out counter: 6
Percentage of particles passing unaffected: 75%
----- Hit Number: 8
in counter: 9
out counter: 7
Percentage of particles passing unaffected: 78%
----- Hit Number: 9
in counter: 10
out counter: 8
Percentage of particles passing unaffected: 80%

This is generated by listing 6 and displays the number of particles that pass through
unaffected. Here the value is 80\% because the run has 2 photons which do not pass
straight through. Therefore, for this run, the view out of the LSC would be 20\% darker.

20

7
7.1

Experiment
Geometrical Gain

For this section the selection of dyes was kept constant, with Rhodamine B and a Crystal Violet sheets being used respectively. The size of the square where photons are
emitted from is kept constant, but the dimensions of the windows are changed. The
thickness is kept at 4mm, but the width and length are increased. This therefore increases the total area of the window facing the sun, and the solar panel area is increased
by a relatively small amount. This therefore means that the gain, given by equation 4,
increases.

Geometrical Gain =

Area of surace
Area of solar panel

(4)

The total energy deposited by all photons is then measured and plotted with respect to
geometrical gain. This is repeated 3 times, and an average is taken.

7.2

Testing Dye Type

Here the dye types were varied, with the independent variable being the dye types.
Mixtures of Rhodamine B + Rhodamine B, Rhodamine B + Crystal Violet, and Crystal
Violet + Crystal Violet were tested.
The number of photons emitted was kept at 1,000, and an average was taken. The concentration of each dye was selected by using equation 3, and kept constant throughout.
The size of geometrical gain was also kept constant, at 150, with a constant solar panel
and surface area.

7.3

Concentration

The concentration of the Rhodamine B + Rhodamine B selection was varied, whilst


keeping all other variables constant.
This required a redeclaration of the absorption length matrix for each run. However
this was a relatively simple process, and only required a small change in the equation.

21

8
8.1

Results
Geometrical Gain

The Geometrical Gain was, as expected, found to increase the total energy deposited.
There is a linear relationship between increasing geometrical gain and energy deposited
from 75 to around 200 geometrical gain. After this, the increase in energy deposited is
not as large.

Figure 6: Energy deposited in eV versus Geometrical gain

8.2

Total Efficiency and Viewing Blur

It is shown in figure 7 that the most efficient combination of dyes, as expected, is Rhodamine B and Crystal Violet. The least efficient is a single plane of Rhodamine B. Of
the double glazed arrangement and having the same dye type, Rhodamine B + Rhodamine B was slightly more efficient than the double Crystal Violet arrangement.
The inverse of these results are true for the total blur seen through the screen. The red
bars show that for a single plane of Rhodamine B, the percentage of unaffected dyes
was much bigger, than the most efficient energy collecting combination, Rhodamine B
+ Crystal violet. The two double selections of Rhodamine B and Crystal Violet came
in the middle, with Rhodamine B

8.3

Concentration

The results shown in figure 8, show that the ideal concentration is at around the calculated value of 44M ol/cm3 , with a large increase in efficiency leading up to this point,
22

Figure 7: Histogram showing the efficiency of the different kinds of dye types with
respect to total spectra input. Red bars show total percentage of unaffected photons

and a gradual decline after this point.

Figure 8: Scatter graph showing the effect of varying concentration

23

9
9.1

Discussion
Geometrical Gain

The total output for geometrical gain increases due to the higher surface area, and therefore the total number of photons hitting the surface increases. The fact that the total
surface area of the solar panel only increases by a much smaller amount is irrelevant
due to the fact that it is the window surface area which collects the photon
This leads to the point of where the bigger the geometrical gain, the higher the GBP per
energy collected (/W ) ratio is. This is due to the much higher cost of the solar panel
semiconductor material, compared to the PMMA/Dye mixture.
The thickness of the windows was not changed at 4mm due to 4mm being the standard
thickness of windows for safety. However, if this were to be reduced it would reduce the
total cost of the windows, however may have an affect on the total number of photons
reaching the windows based upon the changing optimum concentration.

9.2

Total Efficiency

The total efficiency is highest when mixing Rhodamine B and Crystal Violet. This is
due to the overlapping of peak absorption bandwidths. Rhodamine B has a peak bandwidth of about 60nm, between 500nm and 560nm. Whereas Crystal Violet has a peak
bandwidth of about 80nm, between the wavelengths of 540nm and 620nm. Thus the
total peak bandwidth of the LSC is essentially extended to 500-620nm, a 120nm bandwidth. Compared to the original 60nm, which approximately doubles the total intake
of photons.
The lowest efficiency is with a single layer of rhodamine B. This is due to the fact that
the photon spends, overall, half the time in the LSC as it passes through only a single
sheet. The total peak bandwidth is also half the size of the double layered LSC.
This remains true for the double glazed windows, but which contains only a single dye
type. The peak bandwidth remains lower, however the amount of time, and therefore
chance of a photon being absorbed in the LSC is increased.
It is also true that in the Rhodamine B + Crystal Violet arrangement the emission spectra of the Rhodamine B matches that of the Crystal violet. Therefore, emitted photons from the Rhodamine B are reabsorbed in the Crystal Violet. In addition to this,
the emitted photons are statistically less likely to be absorbed by the same dye twice,
therefore allowing a photon to reach the solar panel without being absorbed again.

9.3

Concentration

The concentrations optimum level was found to be at 0.44M ol/cm3 . Before this, there
are not enough dyes, for there to be a significant likelihood of a dye being absorbed.

24

Therefore, the majority of photons pass straight on through without being absorbed.
After the optimal point, dyes began to be reabsorbed once emitted, and therefore did
not reach the solar panels, rather, being emitted at an angle greater than that of the
angle of total internal reflection, and thus passing out of the LSC.

10
10.1

Conclusion
Optimal Design

The optimal design based upon these results is found to be a double glazed window,
containing first Rhodamine B and Crystal Violet. The concentration for Rhodamine
B should be 0.44M ol/cm3 and that of Crystal Violet is found to be 0.39 (based upon
calculations shown in equation 3).
There may well be different combinations of dyes that perform better than those chosen, however for the purpose of this project only the two chosen were tested for reasons
of time.
The geometrical gain, ideally, should be as high as possible. Therefore, it would be
recommended that an LSC be installed in large buildings with floor to ceiling sized
windows, to make the most return in energy for money spent. The total return on
smaller windows, found in houses for instance, would not be signficant enough to warrant the use of LSCs. Rather, solar panels on the roof of the buildings may be a more
feasible option.

10.2

Practical Considerations

For a luminescent solar concentrator to exist it must be more cost effective than solar
panels. Therefore, the cost of the device must be lower, and the area exposed to the sun
must be greater, as to gather enough energy. This, as previously discussed, would be
feasible on a large building, in which its main space real estate runs along the side of
the building, rather than on the top.
The lifetime of these windows must also outlast that of normal windows. This would
mean that the cost of replacing normal windows would reduce the total cost of investing in luminescent solar concentrators.
It is also important that the view from within the window is not darkened or blurred so
that the outside is visible by a subject from the inside.
There are also safety implications in terms of the windows being hardened to deal
with impacts, high winds, and natural disasters. This must also be considered with the
storage and transport of electricity across the building.

25

11

Model Limitations

In real life, once a photon is absorbed, there is a chance that the photon is not remitted
at all . This is known as the quantum efficiency, and its value varies with dye type.
This model has no way of implementing a quantum efficiency, as there was no method
written within geant4 that could do this. It would be possible, with more time, to implement this into the model. This would enhance the overall reliability of the model,
however the time taken would have meant not implementing other, vital methods.
In real life, photons are not emitted radially. Rather, in a certain direction. This is not
shown in the program due to time constraints.
Finally, the effect of time degradation of the product is not taken into account, and
therefore it is not possible to see what would happen after a certain amount of time, left
in a built environment.

26

12

Conclusion

The work done by this model paves the way for a physical model to be created, at near
optimum specifications. It allows for many different combinations of variables to be
ignored. Fine tuning of the specifications can be done with the physical products.
In way of personal contribution, I brought together many different methods, and created methods of my own, to create this model. I provided methods to rapidly test
any dye types, allowing for a quick and easy narrowing down of the huge quantity of
different types to be used. The model is very realistic due to the incorporation of the
ASTMG173 spectra, having four solar panels on all sides, the modelling of screen blur,
and the data output.
The initial objectives were met well, with optimal designs of geometrical gain, total
efficiency and concentration. If I had more time I would have been able to test more
dye types, add in a quantum efficiency method, and vary the emission direction from
dyes.

27

13

Appendix

Listing 12: Class which draws a circle at incidence points (absorbption/emissions and
meeting at boundaries) - ExN06CounterHit.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

////////////////////////////////////////////////
//
// Class Name: ExN06CounterHit
// Created by: Geant4 Example Code
// First Accessed: 20/10/14
// Modified by: Alex Kell
//
////////////////////////////////////////////////
#include
#include
#include
#include
#include

"ExN06CounterHit.hh"
"G4VVisManager.hh"
"G4Circle.hh"
"G4Colour.hh"
"G4VisAttributes.hh"

G4Allocator<ExN06CounterHit> ExN06CounterAllocator;
ExN06CounterHit::ExN06CounterHit()
{;}
ExN06CounterHit::ExN06CounterHit()
{;}
G4int ExN06CounterHit::operator==(const ExN06CounterHit &\leftarrow \rhook
right) const
{
return (this==&right) ? 1 : 0;
}
void ExN06CounterHit::Draw()
{
G4VVisManager* pVVisManager = G4VVisManager::\leftarrow \rhook
GetConcreteInstance();
if(pVVisManager)
{
G4Circle circle(position);
circle.SetScreenSize(10.04);
circle.SetFillStyle(G4Circle::filled);
G4Colour colour(0.,0.,1.); //Place circle at incidence \leftarrow \rhook
point
G4VisAttributes attribs(colour);
circle.SetVisAttributes(attribs);
pVVisManager->Draw(circle);
}
}

28

43
44
45

void ExN06CounterHit::Print()
{;}

Listing 13: ExN06CounterSD.cc - Process and receive data from hits class [9]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

/////////////////////////////////////////
//
// Class Name: ExN06CounterSD
// Created by: Alex Kell
// First Accessed: 20/01/14
//
//
/////////////////////////////////////////
#include
#include
#include
#include
#include
#include

"ExN06CounterSD.hh"
"ExN06Hit.hh"
"G4Step.hh"
"G4Track.hh"
"G4HCofThisEvent.hh"
"G4TouchableHistory.hh"

ExN06CounterSD::ExN06CounterSD(G4String name)
:G4VSensitiveDetector(name)
{
G4String HCname;
collectionName.insert(HCname="counterCollection"); //Name \leftarrow \rhook
of Hit Counter
HCID = -1;
}
ExN06CounterSD::ExN06CounterSD(){;}
void ExN06CounterSD::Initialize(G4HCofThisEvent* HCE)
{
//Begin collection of hits data
counterCollection = new ExN06CounterCollection
(SensitiveDetectorName,collectionName\leftarrow \rhook
[0]);
if(HCID<0)
{ HCID = GetCollectionID(0); }
//Set to zero if no data
HCE->AddHitsCollection(HCID,counterCollection);
}
G4bool ExN06CounterSD::ProcessHits(G4Step* aStep, \leftarrow \rhook
G4TouchableHistory*)
{
//At hit return following information
G4StepPoint* preStep = aStep->GetPreStepPoint();
G4TouchableHistory* touchable = (G4TouchableHistory*)(\leftarrow \rhook
preStep->GetTouchable());

29

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

// Ensure counting incoming tracks only.


if ( preStep->GetStepStatus() == fGeomBoundary ){
ExN06CounterHit* newHit = new ExN06CounterHit();
newHit->SetStripNo( touchable->GetReplicaNumber(0) );
newHit->SetPosition( aStep->GetPreStepPoint()->\leftarrow \rhook
GetPosition() );//Fetch Position data
newHit->SetMomentum( aStep->GetPreStepPoint()->\leftarrow \rhook
GetMomentum() );
newHit->SetEnergy( aStep->GetPreStepPoint()->\leftarrow \rhook
GetTotalEnergy() );
newHit->SetParticle( aStep->GetTrack()->GetDefinition() )\leftarrow \rhook
;
counterCollection->insert( newHit );
}
return true;
}
void
{;}
void
{;}
void
{;}
void
{;}

ExN06CounterSD::EndOfEvent(G4HCofThisEvent*)
ExN06CounterSD::clear()
ExN06CounterSD::DrawAll()
ExN06CounterSD::PrintAll()

30

Listing 14: ExN06PhysicsList.cc - Contains all code for physics processes occuring to
photons. The wavelength shifting process was added her
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

/////////////////////////////////////////
//
// Class Name: ExN06PhysicsList
// Created by: Geant4 ExampleN06
// First Accessed: 20/01/14
// Modified by: Alex Kell
// Code from: WLSExample Geant4
//
/////////////////////////////////////////
#include "globals.hh"
#include "ExN06PhysicsList.hh"
#include "ExN06PhysicsListMessenger.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTypes.hh"
#include "G4ParticleTable.hh"
#include "G4ProcessManager.hh"
#include
#include
#include
#include
#include
#include

"G4Cerenkov.hh"
"G4Scintillation.hh"
"G4OpAbsorption.hh"
"G4OpRayleigh.hh"
"G4OpMieHG.hh"
"G4OpBoundaryProcess.hh"

#include "G4LossTableManager.hh"
#include "G4EmSaturation.hh"
#include "G4OpWLS.hh" //optical photon wavelength shifting
#include "WLSOpticalPhysics.hh"
#include "G4OpticalPhoton.hh"
ExN06PhysicsList::ExN06PhysicsList() : G4VUserPhysicsList()
{
theCerenkovProcess
= NULL;
theScintillationProcess
= NULL;
theAbsorptionProcess
= NULL;
theRayleighScatteringProcess = NULL;
theMieHGScatteringProcess
= NULL;
theBoundaryProcess
= NULL;
theWLSProcess
= NULL; //addition of WLS \leftarrow \rhook
physics process
pMessenger = new ExN06PhysicsListMessenger(this);
SetVerboseLevel(0);
}

31

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

ExN06PhysicsList::ExN06PhysicsList() { delete pMessenger;}


void
{
//
//
//

ExN06PhysicsList::ConstructParticle()

In this method, static member functions should be called


for all particles which you want to use.
This ensures that objects of these particle types will \leftarrow \rhook
be
// created in the program.
ConstructBosons();
ConstructLeptons();
ConstructMesons();
ConstructBaryons();
G4OpticalPhoton::OpticalPhotonDefinition();

void ExN06PhysicsList::ConstructBosons()
{
// pseudo-particles
G4Geantino::GeantinoDefinition();
G4ChargedGeantino::ChargedGeantinoDefinition();
// gamma
G4Gamma::GammaDefinition();
// optical photon
G4OpticalPhoton::OpticalPhotonDefinition();
}
void ExN06PhysicsList::ConstructLeptons()
{
// leptons
// e+/G4Electron::ElectronDefinition();
G4Positron::PositronDefinition();
// mu+/G4MuonPlus::MuonPlusDefinition();
G4MuonMinus::MuonMinusDefinition();
// nu_e
G4NeutrinoE::NeutrinoEDefinition();
G4AntiNeutrinoE::AntiNeutrinoEDefinition();
// nu_mu
G4NeutrinoMu::NeutrinoMuDefinition();
G4AntiNeutrinoMu::AntiNeutrinoMuDefinition();
}

32

96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

void ExN06PhysicsList::ConstructMesons()
{
// mesons
G4PionPlus::PionPlusDefinition();
G4PionMinus::PionMinusDefinition();
G4PionZero::PionZeroDefinition();
}
void ExN06PhysicsList::ConstructBaryons()
{
// barions
G4Proton::ProtonDefinition();
G4AntiProton::AntiProtonDefinition();
G4Neutron::NeutronDefinition();
G4AntiNeutron::AntiNeutronDefinition();
}
void ExN06PhysicsList::ConstructProcess()
{
AddTransportation();
ConstructGeneral();
ConstructEM();
ConstructOp();
}
#include "G4Decay.hh"
void ExN06PhysicsList::ConstructGeneral()
{
// Add Decay Process
G4Decay* theDecayProcess = new G4Decay();
theParticleIterator->reset();
while( (*theParticleIterator)() ){
G4ParticleDefinition* particle = theParticleIterator->\leftarrow \rhook
value();
G4ProcessManager* pmanager = particle->GetProcessManager\leftarrow \rhook
();
if (theDecayProcess->IsApplicable(*particle)) {
pmanager ->AddProcess(theDecayProcess);
// set ordering for PostStepDoIt and AtRestDoIt
pmanager ->SetProcessOrdering(theDecayProcess, \leftarrow \rhook
idxPostStep);
pmanager ->SetProcessOrdering(theDecayProcess, \leftarrow \rhook
idxAtRest);
}
}
}
#include "G4ComptonScattering.hh"
#include "G4GammaConversion.hh"

33

142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

#include "G4PhotoElectricEffect.hh"
#include "G4eMultipleScattering.hh"
#include "G4MuMultipleScattering.hh"
#include "G4hMultipleScattering.hh"
#include "G4eIonisation.hh"
#include "G4eBremsstrahlung.hh"
#include "G4eplusAnnihilation.hh"
#include "G4MuIonisation.hh"
#include "G4MuBremsstrahlung.hh"
#include "G4MuPairProduction.hh"
#include "G4hIonisation.hh"
void ExN06PhysicsList::ConstructEM()
{
theParticleIterator->reset();
while( (*theParticleIterator)() ){
G4ParticleDefinition* particle = theParticleIterator->\leftarrow \rhook
value();
G4ProcessManager* pmanager = particle->GetProcessManager\leftarrow \rhook
();
G4String particleName = particle->GetParticleName();
if (particleName == "gamma") {
// gamma
// Construct processes for gamma
pmanager->AddDiscreteProcess(new G4GammaConversion());
pmanager->AddDiscreteProcess(new G4ComptonScattering())\leftarrow \rhook
;
pmanager->AddDiscreteProcess(new G4PhotoElectricEffect\leftarrow \rhook
());
} else if (particleName == "e-") {
//electron
// Construct processes for electron
pmanager->AddProcess(new G4eMultipleScattering(),-1, 1,\leftarrow \rhook
1);
pmanager->AddProcess(new G4eIonisation(),
-1, 2, \leftarrow \rhook
2);
pmanager->AddProcess(new G4eBremsstrahlung(),
-1, 3, \leftarrow \rhook
3);
} else if (particleName == "e+") {
//positron
// Construct processes for positron
pmanager->AddProcess(new G4eMultipleScattering(),-1, 1,\leftarrow \rhook
1);

34

pmanager->AddProcess(new G4eIonisation(),
-1, 2, \leftarrow \rhook
2);
pmanager->AddProcess(new G4eBremsstrahlung(),
-1, 3, \leftarrow \rhook
3);
pmanager->AddProcess(new G4eplusAnnihilation(), 0,-1, \leftarrow \rhook
4);

184
185
186
187
188
189
190
191
192

} else if( particleName == "mu+" ||


particleName == "mu-"
) {
//muon
// Construct processes for muon
pmanager->AddProcess(new G4MuMultipleScattering(),-1, 1,\leftarrow \rhook
1);
pmanager->AddProcess(new G4MuIonisation(),
-1, 2, \leftarrow \rhook
2);
pmanager->AddProcess(new G4MuBremsstrahlung(), -1, 3, \leftarrow \rhook
3);
pmanager->AddProcess(new G4MuPairProduction(), -1, 4, \leftarrow \rhook
4);

193
194
195
196
197
198
199

} else {
if ((particle->GetPDGCharge() != 0.0) &&
(particle->GetParticleName() != "chargedgeantino"))\leftarrow \rhook
{
// all others charged particles except geantino
pmanager->AddProcess(new G4hMultipleScattering()\leftarrow \rhook
,-1,1,1);
pmanager->AddProcess(new G4hIonisation(),
\leftarrow \rhook
-1,2,2);
}
}

200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222

}
}
void ExN06PhysicsList::ConstructOp()
{
theCerenkovProcess
= new
theScintillationProcess
= new
Scintillation");
theAbsorptionProcess
= new
theRayleighScatteringProcess = new
theMieHGScatteringProcess
= new
theBoundaryProcess
= new
theWLSProcess
= new
//
//
//

G4Cerenkov("Cerenkov");
G4Scintillation("\leftarrow \rhook
G4OpAbsorption();
G4OpRayleigh();
G4OpMieHG();
G4OpBoundaryProcess();
G4OpWLS("OpWLS");

theCerenkovProcess->DumpPhysicsTable();
theScintillationProcess->DumpPhysicsTable();
theRayleighScatteringProcess->DumpPhysicsTable();
SetVerbose(1);

35

223
224
225
226
227
228
229
230
231
232
233

theCerenkovProcess->SetMaxNumPhotonsPerStep(20);
theCerenkovProcess->SetMaxBetaChangePerStep(10.0);
theCerenkovProcess->SetTrackSecondariesFirst(true);
theScintillationProcess->SetScintillationYieldFactor(1.);
theScintillationProcess->SetTrackSecondariesFirst(true);
// Use Birks Correction in the Scintillation process
G4EmSaturation* emSaturation = G4LossTableManager::Instance\leftarrow \rhook
()->EmSaturation();
theScintillationProcess->AddSaturation(emSaturation);

234
235
236
237
238

theParticleIterator->reset();
while( (*theParticleIterator)() ){
G4ParticleDefinition* particle = theParticleIterator->\leftarrow \rhook
value();
G4ProcessManager* pmanager = particle->GetProcessManager\leftarrow \rhook
();
G4String particleName = particle->GetParticleName();
if (theCerenkovProcess->IsApplicable(*particle)) {
pmanager->AddProcess(theCerenkovProcess);
pmanager->SetProcessOrdering(theCerenkovProcess,\leftarrow \rhook
idxPostStep);
}
if (theScintillationProcess->IsApplicable(*particle)) {
pmanager->AddProcess(theScintillationProcess);
pmanager->SetProcessOrderingToLast(\leftarrow \rhook
theScintillationProcess, idxAtRest);
pmanager->SetProcessOrderingToLast(\leftarrow \rhook
theScintillationProcess, idxPostStep);
}
if (particleName == "opticalphoton") {
G4cout << " AddDiscreteProcess to OpticalPhoton " << \leftarrow \rhook
G4endl;
pmanager->AddDiscreteProcess(theAbsorptionProcess);
pmanager->AddDiscreteProcess(\leftarrow \rhook
theRayleighScatteringProcess);
pmanager->AddDiscreteProcess(theMieHGScatteringProcess)\leftarrow \rhook
;
pmanager->AddDiscreteProcess(theBoundaryProcess);
pmanager->AddDiscreteProcess(theWLSProcess);
}
}

239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263

}
void ExN06PhysicsList::SetVerbose(G4int verbose)
{
theCerenkovProcess->SetVerboseLevel(verbose);

36

264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287

theScintillationProcess->SetVerboseLevel(verbose);
theAbsorptionProcess->SetVerboseLevel(verbose);
theRayleighScatteringProcess->SetVerboseLevel(verbose);
theMieHGScatteringProcess->SetVerboseLevel(verbose);
theBoundaryProcess->SetVerboseLevel(verbose);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo\leftarrow \rhook
........oooOO0OOooo......
void ExN06PhysicsList::SetNbOfPhotonsCerenkov(G4int MaxNumber\leftarrow \rhook
)
{
theCerenkovProcess->SetMaxNumPhotonsPerStep(MaxNumber);
}
void ExN06PhysicsList::SetCuts()
{
// " G4VUserPhysicsList::SetCutsWithDefault" method sets
//
the default cut value for all particle types
//
SetCutsWithDefault();
if (verboseLevel>0) DumpCutValuesTable();
}

Listing 15: ExN06PrimaryGeneratorAction.cc - Creates photon gun at run up, ready to


be accessed for photon emission [1]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

/////////////////////////////////////////
//
// Class Name: ExN06PrimaryGeneratorAction.cc
// Created by: University of Southampton (ESA contract)
// First Accessed: 20/01/14
// Modified by: Alex Kell
//
/////////////////////////////////////////
#include "ExN06PrimaryGeneratorAction.hh"
#include "ExN06PrimaryGeneratorMessenger.hh"
#include "Randomize.hh"
#include
#include
#include
#include
#include

"G4Event.hh"
"G4GeneralParticleSource.hh"
"G4ParticleTable.hh"
"G4ParticleDefinition.hh"
"G4SystemOfUnits.hh"

#include <iostream>

37

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

#include <fstream>
#include <string>
using namespace std;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo\leftarrow \rhook
........oooOO0OOooo......
ExN06PrimaryGeneratorAction::ExN06PrimaryGeneratorAction()
{
//G4int n_particle = 1;
particleGun = new G4GeneralParticleSource();
//create a messenger for this class
gunMessenger = new ExN06PrimaryGeneratorMessenger(this);
//At entire program run, clear output.txt for new run \leftarrow \rhook
information
ofstream myfile;
myfile.open ("/home/zceeh46/Desktop/G4/N06/output.txt",ios\leftarrow \rhook
::trunc);
myfile.close();
ofstream myfile1;
myfile1.open ("/home/zceeh46/Desktop/G4/N06/inputCounter.\leftarrow \rhook
txt",ios::trunc);
myfile1.close();
}
ExN06PrimaryGeneratorAction::ExN06PrimaryGeneratorAction()
{
delete particleGun;
delete gunMessenger;
}
void ExN06PrimaryGeneratorAction::GeneratePrimaries(G4Event* \leftarrow \rhook
anEvent)
{
particleGun->GeneratePrimaryVertex(anEvent);
}
void ExN06PrimaryGeneratorAction::SetOptPhotonPolar()
{
G4double angle = G4UniformRand() * 360.0*deg;
SetOptPhotonPolar(angle);
}
void ExN06PrimaryGeneratorAction::SetOptPhotonPolar(G4double \leftarrow \rhook
angle)
{

38

if (particleGun->GetParticleDefinition()->GetParticleName() \leftarrow \rhook


!= "opticalphoton")
{
G4cout << "--> warning from PrimaryGeneratorAction::\leftarrow \rhook
SetOptPhotonPolar() :"
"the particleGun is not an opticalphoton" << \leftarrow \rhook
G4endl;
return;
}

65
66
67
68
69
70
71
72
73

G4ThreeVector normal (1., 0., 0.);


G4ThreeVector kphoton = particleGun->\leftarrow \rhook
GetParticleMomentumDirection();
G4ThreeVector product = normal.cross(kphoton);
G4double modul2
= product*product;

74
75
76
77
78
79
80
81
82
83

G4ThreeVector e_perpend (0., 0., 1.);


if (modul2 > 0.) e_perpend = (1./std::sqrt(modul2))*product;
G4ThreeVector e_paralle
= e_perpend.cross(kphoton);
G4ThreeVector polar = std::cos(angle)*e_paralle + std::sin(\leftarrow \rhook
angle)*e_perpend;
particleGun->SetParticlePolarization(polar);
}

Listing 16: ExN06Run.cc - Stores and allows access to hitcount data during run [10]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

/////////////////////////////////////////
//
// Class Name: ExN06Run
// Created by: Alex Kell
// First Accessed: 12/02/14
// With Reference To:
JST CREST/
//
/////////////////////////////////////////
#include
#include
#include
#include

"../include/ExN06Run.hh"
"../include/G4Event.hh"
"../include/G4HCofThisEvent.hh"
"../include/G4SDManager.hh"

using namespace std;


ExN06Run::ExN06Run()
{
G4String detName[1] = {"MFDetName"}; //name of detector
G4String primNameSum[1] = {"totalEDep"}; //Name of output
G4SDManager* SDMan = G4SDManager::GetSDMpointer();
G4String fullName;

39

24
25
26
27
28
29

size_t i,j;
for(i=0;i<1;i++)
{
for(j=0;j<1;j++)
{
fullName = detName[i]+"/"+primNameSum[j]; //Fetch \leftarrow \rhook
detector name and output variable
colIDSum[i][j] = SDMan->GetCollectionID(fullName); //\leftarrow \rhook
Get collection ID
}
}

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

}
ExN06Run::ExN06Run()
{;}
void ExN06Run::RecordEvent(const G4Event* evt)
{
G4HCofThisEvent* HCE = evt->GetHCofThisEvent(); //Get HC
if(!HCE) return;
numberOfEvent++; //Total number of hits within detector
size_t i,j;
for(i=0;i<1;i++)
{
for(j=0;j<1;j++)
{
G4THitsMap<G4double>* evtMap = (G4THitsMap<G4double\leftarrow \rhook
>*)(HCE->GetHC(colIDSum[i][j]));
mapSum[i][j] += *evtMap; //Get pointer of stored data\leftarrow \rhook
in HC
for(j=0;j<1;j++)
{
std::map<G4int,G4double*>::iterator itr = evtMap->\leftarrow \rhook
GetMap()->begin();
for(; itr != evtMap->GetMap()->end(); itr++)
{
G4int key = (itr->first);
G4double val = *(itr->second); //Hold data in val
G4double* mapP = mapSum[i][j][key];
if( mapP && (val>*mapP) ) continue;
mapSum[i][j].set(key,val);
}
}
}
}
}
G4double ExN06Run::GetTotal(const G4THitsMap<G4double> &map) \leftarrow \rhook
const
{

40

68
69
70
71
72
73

G4double tot = 0.;


std::map<G4int,G4double*>::iterator itr = map.GetMap()->\leftarrow \rhook
begin();
for(; itr != map.GetMap()->end(); itr++)
{ tot += *(itr->second); }
return tot;
}

Listing 17: ExN06SD.cc Sensitive Detector Class storing hit data of whole run
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

/////////////////////////////////////////
//
// Class Name: ExN06SD.cc
// Created by: Alex Kell
// First Accessed: 17/01/14
// With Reference To:
JST CREST/
//
/////////////////////////////////////////
#include
#include
#include
#include
#include
#include

"ExN06SD.hh"
"ExN06Hit.hh"
"G4Step.hh"
"G4Track.hh"
"G4HCofThisEvent.hh"
"G4TouchableHistory.hh"

ExN06SD::ExN06SD(G4String name)
:G4VSensitiveDetector(name)
{
G4String HCname;
collectionName.insert(HCname="hitsCollection");
HCID = -1;
}
ExN06SD::ExN06SD(){;}
void ExN06SD::Initialize(G4HCofThisEvent* HCE)
{
hitsCollection = new ExN06HitsCollection
(SensitiveDetectorName,collectionName\leftarrow \rhook
[0]);
if(HCID<0)
{ HCID = GetCollectionID(0); }
HCE->AddHitsCollection(HCID,hitsCollection);
}
G4bool ExN06SD::ProcessHits(G4Step* aStep, G4TouchableHistory\leftarrow \rhook
*)

41

39
40
41
42

{
G4StepPoint* preStep = aStep->GetPreStepPoint();
G4TouchableHistory* touchable = (G4TouchableHistory*)(\leftarrow \rhook
preStep->GetTouchable());

43
44
45
46
47
48

// Ensure counting incoming tracks only.


if ( preStep->GetStepStatus() == fGeomBoundary ){
ExN06Hit* newHit = new ExN06Hit();
newHit->SetStripNo( touchable->GetReplicaNumber(0) );
newHit->SetPosition( aStep->GetPreStepPoint()->\leftarrow \rhook
GetPosition() );
newHit->SetMomentum( aStep->GetPreStepPoint()->\leftarrow \rhook
GetMomentum() );
newHit->SetEnergy( aStep->GetPreStepPoint()->\leftarrow \rhook
GetTotalEnergy() );
newHit->SetParticle( aStep->GetTrack()->GetDefinition() )\leftarrow \rhook
;
hitsCollection->insert( newHit );
}
return true;

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

}
void ExN06SD::EndOfEvent(G4HCofThisEvent*)
{;}
void ExN06SD::clear()
{;}
void ExN06SD::DrawAll()
{;}
void ExN06SD::PrintAll()
{;}

Listing 18: grabData.hh Include class which provides the methods for sorting and
fetching the data from text files
1
2
3
4
5
6
7
8
9
10
11
12

/////////////////////////////////////////
//
// Class Name: ExN06SD.cc
// Created by: Alex Kell
// First Accessed: 17/01/14
//
/////////////////////////////////////////
#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
#include <string>

42

13
14
15
16
17
18
19
20
21
22
23

#include "globals.hh"
using namespace std;
#ifndef grabData_h
#define grabData_h
vector<G4double> getData(string fileName)
{

24
25
26
27
28
29
30

//temp double to \leftarrow \rhook

string line; //temporarily contains data from file


string location = "/home/zceeh46/Desktop/G4/N06/data/";
location.append(fileName);
ifstream myfile("/home/zceeh46/Desktop/G4/N06/data/\leftarrow \rhook
Rhodamine_absorption.txt");

31
32
33
34

if (myfile.is_open()){
//open file
G4cout << "File Opened"<< endl;
while(getline(myfile,line))
//extract \leftarrow \rhook
from myfile and stores in line
{
istringstream linestream(line);
//\leftarrow \rhook
construct istringstream object
string item;
while(getline(linestream,item, ))
//\leftarrow \rhook
stores lines of linestream in item
{
stringstream ss(item);
ss >> dbl_temp;
dbl_line.push_back(dbl_temp);
}
}
myfile.close();

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

//1-demensional \leftarrow \rhook

vector<G4double> dbl_line;
vector
G4double dbl_temp;
store value

}else{
G4cout << "Cant open file"<< endl;
}
return dbl_line;
}
vector<G4double> Wavelength(vector<G4double>& dbl_line){
vector<G4double> wavelength;
int hi = dbl_line.size();

43

57
58

for(int n = 0; n <hi; n++){ //For loop until end of file


if( dbl_line[n] > 200 && dbl_line[n] < 1000 n % 1 =\leftarrow \rhook
1){ //if value is between 200 and 1000 then is a \leftarrow \rhook
wavelength value and n is odd
wavelength.push_back(dbl_line[n]); //add value \leftarrow \rhook
to end of vector
}
}
return wavelength;

59
60
61
62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77
78
79

}
vector<G4double> absorption(vector<G4double>& dbl_line){
vector<G4double> power;
int hi = dbl_line.size();
for(int n = 0; n <hi; n++){
if( dbl_line[n] < 200 || dbl_line[n] > 1000 && n % 1\leftarrow \rhook
= 0){ //if bigger than 1000 or smaller than 200 \leftarrow \rhook
and n is even
if(dbl_line[n]>0){
power.push_back(dbl_line[n]);
}else{
power.push_back(0.000000001); //if negative \leftarrow \rhook
number
}
}
}
return power;
}
#endif /* grabData_h */

44

References
[1] First developed (2000) University of Southampton (ESA contract), maintained and
upgraded by QinetiQ and ESA, http://reat.space.qinetiq.com/gps
[2] Allison, J.; Amako, K.; Apostolakis, J.; Araujo, H.; Arce Dubois, P.; Asai, M.;
Barrand, G.; Capra, R. et al. (2006). Geant4 developments and applications.
IEEE Transactions on Nuclear Science 53: 270. Bibcode:2006ITNS...53..270A.
doi:10.1109/TNS.2006.869826
[3] Renewable Resource Data Center (RReDC) - NREL, Solar Spectral Irradiance: ASTM G-173, [online], 08-02-2014, Available from World Web Web:
http://rredc.nrel.gov/solar/spectra/am1.5/ASTMG173/ASTMG173.html
[4] Sawilowsky, Shlomo S.; Fahoome, Gail C. (2003). Statistics via Monte Carlo Simulation with Fortran. Rochester Hills, MI: JMASM.
[5] K.
Amako
(KEK).
(2002).
9.1
Novice
Example.
Available:
http://geant4.web.cern.ch/geant4/G4UsersDocuments/UsersGuides/ForApplicationDeveloper/
html/Examples/NoviceCodes.html Last accessed 21st March 2014.
[6] Mikhail
Polyanskiy
.
(2008).
Refractive
Index
of
PMMA
(Acrylic
Glass)
[Plastics].
Available:
http://http://refractiveindex.info/legacy/?group=PLASTICSmaterial=PMMA.
Last accessed 21st Feb 2014.
[7] Scott
Prahl.
(2012).
Rhodamine
B.
http://omlc.ogi.edu/spectra/PhotochemCAD/html/009.html.
Last
12th March 2014

Available:
Accessed

[8] Scott
Prahl.
(2012).
Rhodamine
B.
http://omlc.ogi.edu/spectra/PhotochemCAD/html/049.html.
Last
12th March 2014

Available:
Accessed

[9] Makoto Asai. National Accelerator Laboratory. Scoring 2. Available:


geant4.slac.stanford.edu/SLACTutorial09/Scoring2.pptx . Last Accessed:
20/03/2014
[10] M Asai (SLAC). JST CREST/. Created: 17-19 Oct, 2007 @ RCNS. Available: http://www-geant4.kek.jp/g4users/g4tut07/docs/SensitiveDetector.pdf. Last
Accessed: 23/02/2014

45

Вам также может понравиться