Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/advanced/fastAerosol/src/FADetectorConstruction.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /examples/advanced/fastAerosol/src/FADetectorConstruction.cc (Version 11.3.0) and /examples/advanced/fastAerosol/src/FADetectorConstruction.cc (Version 11.2.2)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26                                                    26 
 27 // (adapted from B1DetectorConstruction)           27 // (adapted from B1DetectorConstruction)
 28 // Author: A.Knaian (ara@nklabs.com), N.MacFad     28 // Author: A.Knaian (ara@nklabs.com), N.MacFadden (natemacfadden@gmail.com)
 29                                                    29 
 30 #include "FADetectorConstruction.hh"               30 #include "FADetectorConstruction.hh"
 31 #include "FADetectorConstructionMessenger.hh"      31 #include "FADetectorConstructionMessenger.hh"
 32                                                    32 
 33 #include "G4RunManager.hh"                         33 #include "G4RunManager.hh"
 34 #include "G4NistManager.hh"                        34 #include "G4NistManager.hh"
 35                                                    35 
 36 #include "G4LogicalVolume.hh"                      36 #include "G4LogicalVolume.hh"
 37 #include "G4PVPlacement.hh"                        37 #include "G4PVPlacement.hh"
 38 #include "G4SystemOfUnits.hh"                      38 #include "G4SystemOfUnits.hh"
 39                                                    39 
 40 // shapes                                          40 // shapes
 41 #include "G4Box.hh"                                41 #include "G4Box.hh"
 42 #include "G4Cons.hh"                               42 #include "G4Cons.hh"
 43 #include "G4Orb.hh"                                43 #include "G4Orb.hh"
 44 #include "G4Sphere.hh"                             44 #include "G4Sphere.hh"
 45 #include "G4Trd.hh"                                45 #include "G4Trd.hh"
 46 #include "G4Tubs.hh"                               46 #include "G4Tubs.hh"
 47 #include "G4Ellipsoid.hh"                          47 #include "G4Ellipsoid.hh"
 48                                                    48 
 49 // to build FastAerosol cloud                      49 // to build FastAerosol cloud
 50 #include "FastAerosolSolid.hh"                     50 #include "FastAerosolSolid.hh"
 51                                                    51 
 52 // to build parameterised cloud                    52 // to build parameterised cloud
 53 #include "FACloudParameterisation.hh"              53 #include "FACloudParameterisation.hh"
 54 #include "G4PVParameterised.hh"                    54 #include "G4PVParameterised.hh"
 55 #include <fstream>                                 55 #include <fstream>
 56                                                    56 
 57 // step limits                                     57 // step limits
 58 #include "G4UserLimits.hh"                         58 #include "G4UserLimits.hh"
 59                                                    59 
 60 // visualization                                   60 // visualization
 61 #include "G4VisAttributes.hh"                      61 #include "G4VisAttributes.hh"
 62 #include "G4Colour.hh"                             62 #include "G4Colour.hh"
 63                                                    63 
 64 // to save distribution                            64 // to save distribution
 65 #include <sys/stat.h>                              65 #include <sys/stat.h>
 66 #include <ctime>                                   66 #include <ctime>    
 67 // for measuring FastAerosol droplet center po     67 // for measuring FastAerosol droplet center population time
 68                                                    68 
 69 DetectorConstruction::DetectorConstruction()       69 DetectorConstruction::DetectorConstruction()
 70 : G4VUserDetectorConstruction(),                   70 : G4VUserDetectorConstruction(),
 71 fScoringVolume(nullptr)                            71 fScoringVolume(nullptr)
 72 {                                                  72 { 
 73 fMessenger = new DetectorConstructionMessenger     73 fMessenger = new DetectorConstructionMessenger(this);
 74 }                                                  74 }
 75                                                    75 
 76 DetectorConstruction::~DetectorConstruction()      76 DetectorConstruction::~DetectorConstruction()
 77 {                                                  77 {
 78  delete fMessenger;                                78  delete fMessenger;
 79  delete fStepLimits;                               79  delete fStepLimits;
 80  delete fCloudShape;                               80  delete fCloudShape;
 81  delete fDropletShape;                             81  delete fDropletShape;
 82  delete fCloud;                                    82  delete fCloud;
 83 }                                                  83 }
 84                                                    84 
 85 G4VPhysicalVolume* DetectorConstruction::Const     85 G4VPhysicalVolume* DetectorConstruction::Construct()
 86 {                                                  86 {
 87  //                                                87  //
 88  // Check cloud build settings                     88  // Check cloud build settings
 89  //                                                89  //
 90  if (fFastAerosolCloud + fParameterisedCloud +     90  if (fFastAerosolCloud + fParameterisedCloud + fSmoothCloud > 1)
 91  {                                                 91  {
 92  std::ostringstream message;                       92  std::ostringstream message;
 93   message << "Must select at most one build ty     93   message << "Must select at most one build type! Selections:" << G4endl
 94     << "     fFastAerosolCloud = " << fFastAer     94     << "     fFastAerosolCloud = " << fFastAerosolCloud << G4endl
 95     << "     fParameterisedCloud = " << fParam     95     << "     fParameterisedCloud = " << fParameterisedCloud << G4endl
 96     << "     fSmoothCloud = " << fSmoothCloud      96     << "     fSmoothCloud = " << fSmoothCloud << G4endl;
 97      G4Exception("DetectorConstruction::Constr     97      G4Exception("DetectorConstruction::Construct()", "GeomSolids0002",
 98           FatalException, message);                98           FatalException, message);
 99   }                                                99   }
100  //                                               100  //
101  // Get nist material manager                     101  // Get nist material manager
102  //                                               102  //
103  G4NistManager* nist = G4NistManager::Instance    103  G4NistManager* nist = G4NistManager::Instance();
104  //                                               104  //
105  // Option to switch on/off checking of volume    105  // Option to switch on/off checking of volumes overlaps
106  //                                               106  //
107  G4bool checkOverlaps = false;                    107  G4bool checkOverlaps = false;
108  //                                               108  //
109  // Large scale geometry dimensions               109  // Large scale geometry dimensions
110  //                                               110  //
111  G4double cloud_sizeXY = 0.5*m;                   111  G4double cloud_sizeXY = 0.5*m;
112  G4double cloud_sizeZ = 5.0*m;                    112  G4double cloud_sizeZ = 5.0*m;
113                                                   113 
114  G4double world_sizeXY = 1.1*(cloud_sizeXY);      114  G4double world_sizeXY = 1.1*(cloud_sizeXY);
115  G4double world_sizeZ= 1.1*(cloud_sizeZ);         115  G4double world_sizeZ= 1.1*(cloud_sizeZ);
116  //                                               116  //
117  // Cloud shape                                   117  // Cloud shape
118  //                                               118  //
119  if (fCloudShapeStr == "box")                     119  if (fCloudShapeStr == "box")
120  {                                                120  {
121  G4cout << "Cloud shape = box" << G4endl;         121  G4cout << "Cloud shape = box" << G4endl;
122   fCloudShape = new G4Box("cloudShape", 0.5*cl    122   fCloudShape = new G4Box("cloudShape", 0.5*cloud_sizeXY, 0.5*cloud_sizeXY, 0.5*cloud_sizeZ);
123  }                                                123  }
124  else if (fCloudShapeStr == "ellipsoid")          124  else if (fCloudShapeStr == "ellipsoid")
125  {                                                125  {
126    G4cout << "Cloud shape = ellipsoid" << G4en    126    G4cout << "Cloud shape = ellipsoid" << G4endl;
127    fCloudShape = new G4Ellipsoid("cloudShape",    127    fCloudShape = new G4Ellipsoid("cloudShape", 0.5*cloud_sizeXY, 0.5*cloud_sizeXY, 0.5*cloud_sizeZ, 0, 0);
128  }                                                128  }
129  else if (fCloudShapeStr == "cylinder")           129  else if (fCloudShapeStr == "cylinder")
130  {                                                130  {
131  G4cout << "Cloud shape = cylinder" << G4endl;    131  G4cout << "Cloud shape = cylinder" << G4endl;
132   fCloudShape = new G4Tubs("cloudShape", 0.0,     132   fCloudShape = new G4Tubs("cloudShape", 0.0, 0.5*cloud_sizeXY, 0.5*cloud_sizeZ, 0, 360*deg);
133   }                                               133   }
134  else if (fCloudShapeStr == "pipe")               134  else if (fCloudShapeStr == "pipe")
135  {                                                135  {
136   G4cout << "Cloud shape = pipe" << G4endl;       136   G4cout << "Cloud shape = pipe" << G4endl;
137   fCloudShape = new G4Tubs("cloudShape", 0.25*    137   fCloudShape = new G4Tubs("cloudShape", 0.25*cloud_sizeXY, 0.5*cloud_sizeXY, 0.5*cloud_sizeZ, 0, 360.*deg);
138  }                                                138  }
139  else                                             139  else
140  {                                                140  {
141   std::ostringstream message;                     141   std::ostringstream message;
142   message << "Invalid cloud shape = " << fClou    142   message << "Invalid cloud shape = " << fCloudShapeStr << "!";
143   G4Exception("DetectorConstruction::Construct    143   G4Exception("DetectorConstruction::Construct()", "GeomSolids0002",
144   FatalException, message);                       144   FatalException, message);
145   }                                               145   }
146                                                   146 
147  //                                               147  //
148  // Droplet Shape                                 148  // Droplet Shape
149  //                                               149  //
150                                                   150 
151 // The difference in radii of the maximal sphe    151 // The difference in radii of the maximal sphere (centered at the origin) contained in the droplet and the minimal sphere (centered at the origin) containing the droplet
152  G4double sphericalUncertainty = 0.0;             152  G4double sphericalUncertainty = 0.0;
153  if (fDropletShapeStr == "sphere")                153  if (fDropletShapeStr == "sphere")
154  {                                                154  {
155   G4cout << "Droplet shape = sphere" << G4endl    155   G4cout << "Droplet shape = sphere" << G4endl;
156   fDropletShape = new G4Orb("dropletSV", fDrop    156   fDropletShape = new G4Orb("dropletSV", fDropletR);
157   sphericalUncertainty = 0.0;                     157   sphericalUncertainty = 0.0;
158  }                                                158  }
159  else if (fDropletShapeStr == "halfSphere")       159  else if (fDropletShapeStr == "halfSphere")
160  {                                                160  {
161   G4cout << "Droplet shape = halfSphere" << G4    161   G4cout << "Droplet shape = halfSphere" << G4endl;
162   fDropletShape = new G4Sphere("dropletSV", 0.    162   fDropletShape = new G4Sphere("dropletSV", 0.0, fDropletR,                 0.0, 180.*deg, 0.0, 180.*deg);
163   sphericalUncertainty = fDropletR;               163   sphericalUncertainty = fDropletR;
164  }                                                164  }
165  else if (fDropletShapeStr == "cylinder")         165  else if (fDropletShapeStr == "cylinder")
166  {                                                166  {
167   G4cout << "Droplet shape = cylinder" << G4en    167   G4cout << "Droplet shape = cylinder" << G4endl;
168   fDropletShape = new G4Tubs("dropletSV", 0, f    168   fDropletShape = new G4Tubs("dropletSV", 0, fDropletR/std::sqrt(3), fDropletR/std::sqrt(3), 0, 360.*deg);
169   sphericalUncertainty = fDropletR*(1-1/std::s    169   sphericalUncertainty = fDropletR*(1-1/std::sqrt(3));
170  }                                                170  }
171  else if (fDropletShapeStr == "box")              171  else if (fDropletShapeStr == "box")
172  {                                                172  {
173   G4cout << "Droplet shape = box" << G4endl;      173   G4cout << "Droplet shape = box" << G4endl;
174   fDropletShape = new G4Box("dropletSV", fDrop    174   fDropletShape = new G4Box("dropletSV", fDropletR/std::sqrt(3), fDropletR/std::sqrt(3), fDropletR/std::sqrt(3));
175   sphericalUncertainty = fDropletR*(1-1/std::s    175   sphericalUncertainty = fDropletR*(1-1/std::sqrt(3));
176  }                                                176  }
177  else                                             177  else
178  {                                                178  {
179   std::ostringstream message;                     179   std::ostringstream message;
180    message << "Invalid droplet shape = " << fC    180    message << "Invalid droplet shape = " << fCloudShapeStr << "!";
181     G4Exception("DetectorConstruction::Constru    181     G4Exception("DetectorConstruction::Construct()", "GeomSolids0002",
182           FatalException, message);               182           FatalException, message);
183   }                                               183   }
184                                                   184 
185 //                                                185 //
186 // Materials                                      186 // Materials
187 //                                                187 //
188 // Compute the density of air at 14 km using t    188 // Compute the density of air at 14 km using the Barometric formula
189 // see, e.g., https://en.wikipedia.org/wiki/De    189 // see, e.g., https://en.wikipedia.org/wiki/Density_of_air
190 G4double h = 14.0*km;                             190 G4double h = 14.0*km;
191 G4double p0 = 101325*hep_pascal;                  191 G4double p0 = 101325*hep_pascal;
192 G4double T0 = 288.15*kelvin;                      192 G4double T0 = 288.15*kelvin;
193 G4double grav = 9.80665*m/(s*s);                  193 G4double grav = 9.80665*m/(s*s);
194 G4double La = 0.0065*kelvin/m;                    194 G4double La = 0.0065*kelvin/m;
195 G4double R = 8.31447*joule/(mole*kelvin);         195 G4double R = 8.31447*joule/(mole*kelvin);
196 G4double M = 0.0289644*kg/mole;                   196 G4double M = 0.0289644*kg/mole;
197 G4double T = T0 - La*h;                           197 G4double T = T0 - La*h;
198 G4double p = p0*std::pow(1-La*h/T0,grav*M/(R*L    198 G4double p = p0*std::pow(1-La*h/T0,grav*M/(R*La));
199 G4double air_density = p*M/(R*T);                 199 G4double air_density = p*M/(R*T);
200                                                   200 
201 // make materials and set densities               201 // make materials and set densities
202 G4Material* air_mat = nist->BuildMaterialWithN    202 G4Material* air_mat = nist->BuildMaterialWithNewDensity("Atmosphere","G4_AIR",air_density);
203 G4Material* water_mat = nist->FindOrBuildMater    203 G4Material* water_mat = nist->FindOrBuildMaterial("G4_WATER");
204                                                   204 
205 G4double water_density = water_mat->GetDensity    205 G4double water_density = water_mat->GetDensity();
206 G4double ice_density = 0.9168*g/cm3;              206 G4double ice_density = 0.9168*g/cm3;
207                                                   207   
208 G4Material* ice_mat = new G4Material("Water ic    208 G4Material* ice_mat = new G4Material("Water ice ", ice_density, 1, kStateSolid, T, p);
209 ice_mat->AddMaterial(water_mat, 1.);              209 ice_mat->AddMaterial(water_mat, 1.);
210                                                   210 
211 //                                                211 //
212 // Droplets                                       212 // Droplets
213 //                                                213 //
214 G4double droplet_density = water_density;         214 G4double droplet_density = water_density;
215 G4Material* droplet_mat = water_mat;              215 G4Material* droplet_mat = water_mat;
216                                                   216 
217 G4double droplet_count = fDropletNumDens*(fClo    217 G4double droplet_count = fDropletNumDens*(fCloudShape->GetCubicVolume());
218                                                   218 
219 G4double droplet_volume = fDropletShape->GetCu    219 G4double droplet_volume = fDropletShape->GetCubicVolume();
220 G4double droplet_total_volume = droplet_count*    220 G4double droplet_total_volume = droplet_count*droplet_volume;
221                                                   221 
222 G4double droplet_total_mass =  droplet_total_v    222 G4double droplet_total_mass =  droplet_total_volume*droplet_density;
223                                                   223 
224 //                                                224 //
225 // Cloud macroscopic quantities                   225 // Cloud macroscopic quantities
226 //                                                226 //
227 G4double cloud_volume = fCloudShape->GetCubicV    227 G4double cloud_volume = fCloudShape->GetCubicVolume();
228 G4double cloud_air_volume = cloud_volume - dro    228 G4double cloud_air_volume = cloud_volume - droplet_total_volume;
229 G4double cloud_air_mass = air_density*cloud_ai    229 G4double cloud_air_mass = air_density*cloud_air_volume;
230                                                   230 
231 //                                                231 //
232 // Step limit                                     232 // Step limit
233 //                                                233 //
234 fStepLimits = new G4UserLimits(fStepLim);         234 fStepLimits = new G4UserLimits(fStepLim);
235                                                   235 
236 //                                                236 //
237 // Build world                                    237 // Build world
238 //                                                238 //
239 G4Box* solidWorld =new G4Box("World",//its nam    239 G4Box* solidWorld =new G4Box("World",//its name
240             0.5*world_sizeXY,//half x-span        240             0.5*world_sizeXY,//half x-span
241             0.5*world_sizeXY,//half y-span        241             0.5*world_sizeXY,//half y-span
242             0.5*world_sizeZ);//half z-span        242             0.5*world_sizeZ);//half z-span
243                                                   243 
244 G4LogicalVolume* logicWorld =                     244 G4LogicalVolume* logicWorld =            
245     new G4LogicalVolume(solidWorld, //its soli    245     new G4LogicalVolume(solidWorld, //its solid
246                         air_mat, //its materia    246                         air_mat, //its material
247                         "World");//its name       247                         "World");//its name
248                                                   248 
249 logicWorld->SetUserLimits(fStepLimits);           249 logicWorld->SetUserLimits(fStepLimits);
250                                                   250                    
251 G4VPhysicalVolume* physWorld = new G4PVPlaceme    251 G4VPhysicalVolume* physWorld = new G4PVPlacement(nullptr,//no rotation
252              G4ThreeVector(),//at (0,0,0)         252              G4ThreeVector(),//at (0,0,0)
253  logicWorld,//its logical volume                  253  logicWorld,//its logical volume
254  "World",//its name                               254  "World",//its name
255 nullptr,//its mothervolume                        255 nullptr,//its mothervolume
256 false,//no boolean operation                      256 false,//no boolean operation             
257 0, //copy number                                  257 0, //copy number
258 checkOverlaps); //overlaps checking               258 checkOverlaps); //overlaps checking
259                                                   259 
260 //                                                260 //
261 // Build cloud                                    261 // Build cloud
262 //                                                262 //
263 G4LogicalVolume* logicCloud;                      263 G4LogicalVolume* logicCloud;
264                                                   264 
265 // *******************************************    265 // **********************************************************
266 //                                                266 // 
267 // Build the cloud using the FastAerosol geome    267 // Build the cloud using the FastAerosol geometry class
268 //                                                268 // 
269 // *******************************************    269 // ***********************************************************
270                                                   270 
271 if (fFastAerosolCloud)                            271 if (fFastAerosolCloud) 
272 {                                                 272 {
273 G4cout << "\nFastAerosol geometry with n=" <<     273 G4cout << "\nFastAerosol geometry with n=" << fDropletNumDens*mm3 << "/mm3, r=" << fDropletR/mm << "mm spheres.\n" << G4endl;
274                                                   274     
275 fCloud = new FastAerosol("cloud",                 275 fCloud = new FastAerosol("cloud",                  fCloudShape,//cloud shape            
276 fDropletR, //bounding radius of droplets          276 fDropletR, //bounding radius of droplets
277                    fMinSpacing,//minimum spaci    277                    fMinSpacing,//minimum spacing between droplets
278                                  fDropletNumDe    278                                  fDropletNumDens, //approximate number of droplets in cloud
279                    sphericalUncertainty); //un    279                    sphericalUncertainty); //uncertainty in distance to droplet surface from outside using just droplet's origin as info
280 fCloud->SetDropletsPerVoxel(4);                   280 fCloud->SetDropletsPerVoxel(4);
281                                                   281 
282 FastAerosolSolid* solidCloud = new FastAerosol    282 FastAerosolSolid* solidCloud = new FastAerosolSolid("cloudSV",//its name                
283 fCloud, //its shape                               283 fCloud, //its shape
284 fDropletShape); //its droplets                    284 fDropletShape); //its droplets
285                                                   285 
286 solidCloud->SetStepLim(fStepLim);                 286 solidCloud->SetStepLim(fStepLim);
287 //FastAerosol can use step limit to speed calc    287 //FastAerosol can use step limit to speed calculations
288                                                   288 
289 logicCloud = new G4LogicalVolume(solidCloud,//    289 logicCloud = new G4LogicalVolume(solidCloud,//its solid
290                            droplet_mat,//its m    290                            droplet_mat,//its material
291         "cloudLV");//its name                     291         "cloudLV");//its name
292 logicCloud->SetUserLimits(fStepLimits);           292 logicCloud->SetUserLimits(fStepLimits);
293 logicCloud->SetVisAttributes(G4VisAttributes(G    293 logicCloud->SetVisAttributes(G4VisAttributes(G4Colour(0.0,0.0,1.0,0.4)));
294                                                   294 
295 new G4PVPlacement(nullptr, G4ThreeVector(), lo    295 new G4PVPlacement(nullptr, G4ThreeVector(), logicCloud,                 "cloudPV", //its name
296 logicWorld,//its mother volume                    296 logicWorld,//its mother volume
297 false, //no boolean operation                     297 false, //no boolean operation
298 0,//copy number                                   298 0,//copy number 
299 checkOverlaps);//overlaps checking                299 checkOverlaps);//overlaps checking
300                                                   300 
301 fCloud->SetSeed(fCloudSeed);                      301 fCloud->SetSeed(fCloudSeed);
302                                                   302 
303 // fPrePopulate = whether to populate all voxe    303 // fPrePopulate = whether to populate all voxels at the beginning or on the fly
304 if (fPrePopulate)                                 304 if (fPrePopulate) 
305 {                                                 305 {
306  // populate (proving it to the user by printi    306  // populate (proving it to the user by printing population reports)
307  clock_t t;                                       307  clock_t t;
308  t = clock();                                     308  t = clock();
309                                                   309 
310  G4cout << "\nBefore populating" << G4endl;       310  G4cout << "\nBefore populating" << G4endl;
311  G4cout <<   "=================" << G4endl;       311  G4cout <<   "=================" << G4endl;
312  fCloud->PrintPopulationReport();                 312  fCloud->PrintPopulationReport();
313  G4cout << "\nPopulating..." << G4endl;           313  G4cout << "\nPopulating..." << G4endl;
314  fCloud->PopulateAllGrids();                      314  fCloud->PopulateAllGrids();
315  G4cout << "\nAfter populating" << G4endl;        315  G4cout << "\nAfter populating" << G4endl;
316  G4cout <<   "================" << G4endl;        316  G4cout <<   "================" << G4endl;
317  fCloud->PrintPopulationReport();                 317  fCloud->PrintPopulationReport();
318  G4cout << G4endl;                                318  G4cout << G4endl;
319                                                   319 
320  t = clock() - t;                                 320  t = clock() - t;
321                                                   321 
322  G4cout << "\nThis took " << ((float)t)/CLOCKS    322  G4cout << "\nThis took " << ((float)t)/CLOCKS_PER_SEC << "s\n" << G4endl;
323                                                   323 
324  // make filename variables to save data          324  // make filename variables to save data
325  G4String rStr = std::to_string(fDropletR/mm);    325  G4String rStr = std::to_string(fDropletR/mm);
326  rStr.erase ( rStr.find_last_not_of('0') + 1,     326  rStr.erase ( rStr.find_last_not_of('0') + 1, std::string::npos );  // drop trailing 0
327  replace( rStr.begin(), rStr.end(), '.', 'p');    327  replace( rStr.begin(), rStr.end(), '.', 'p');
328  if (rStr.back() == 'p') { rStr.pop_back(); }     328  if (rStr.back() == 'p') { rStr.pop_back(); } // don't write "3p" for 3.0, just write "3"
329                                                   329 
330  // want to represent the number density as 1E    330  // want to represent the number density as 1E-ApB for some A, B
331 G4int order10 = (G4int) -round(10*std::log10(f    331 G4int order10 = (G4int) -round(10*std::log10(fDropletNumDens*mm3)); // gives 10x the exponent rounded to the int (10x so we get two decimals)
332 G4int leading = order10 / 10; // first number     332 G4int leading = order10 / 10; // first number
333 G4int trailing = order10 % 10;  // second numb    333 G4int trailing = order10 % 10;  // second number
334 G4String nStr = "1E-" + std::to_string(leading    334 G4String nStr = "1E-" + std::to_string(leading) + "p" + std::to_string(trailing);   
335                                                   335 
336 // save population time                           336 // save population time
337 std::ofstream file;                               337 std::ofstream file;
338 file.open("popTime_r" + rStr + "mm_n" + nStr +    338 file.open("popTime_r" + rStr + "mm_n" + nStr + "mm-3.csv");
339 file << ((float)t)/CLOCKS_PER_SEC;                339 file << ((float)t)/CLOCKS_PER_SEC;
340 file.close();                                     340 file.close();
341                                                   341 
342 // save distribution                              342 // save distribution
343 G4String fName = "distribution_r" + rStr + "mm    343 G4String fName = "distribution_r" + rStr + "mm_n" + nStr + "mm-3.csv";
344 fCloud->SaveToFile(fName);                        344 fCloud->SaveToFile(fName);
345  }                                                345  }
346 }                                                 346 }
347 // *******************************************    347 // **********************************************************
348 //                                                348 // 
349 // (For comparision/benchmarking) Build the cl    349 // (For comparision/benchmarking) Build the cloud using G4VParameterized (does not use FastAerosol)
350 //                                                350 // 
351 // *******************************************    351 // ***********************************************************
352 // the droplet positions for this cloud are th    352 // the droplet positions for this cloud are those saved in the "distribution" folder of our data
353 // this is to make comparable simulations betw    353 // this is to make comparable simulations between FastAerosol and parameterised clouds
354 // this requires that we first simulate FastAe    354 // this requires that we first simulate FastAerosol (pre-populated) to generate the positions
355                                                   355   
356 else if (fParameterisedCloud)                     356 else if (fParameterisedCloud)
357  {                                                357  {
358  G4cout << "\nParameterised geometry with n="     358  G4cout << "\nParameterised geometry with n=" << fDropletNumDens*mm3 << "/mm3 and r=" << fDropletR/mm << "mm spheres.\n" << G4endl;
359     std::vector<G4ThreeVector> positions;         359     std::vector<G4ThreeVector> positions;
360     G4double x,y,z;                               360     G4double x,y,z;
361                                                   361 
362  // load distribution file                        362  // load distribution file
363  G4String fName;                                  363  G4String fName;
364  G4String rStr = std::to_string(fDropletR/mm);    364  G4String rStr = std::to_string(fDropletR/mm);
365     rStr.erase ( rStr.find_last_not_of('0') +     365     rStr.erase ( rStr.find_last_not_of('0') + 1, std::string::npos ); // drop trailing 0
366     replace( rStr.begin(), rStr.end(), '.', 'p    366     replace( rStr.begin(), rStr.end(), '.', 'p');
367     if (rStr.back() == 'p') { rStr.pop_back();    367     if (rStr.back() == 'p') { rStr.pop_back(); }  // don't write "3p" for 3.0, just write "3"
368                                                   368 
369  // want to represent the number density as 1E    369  // want to represent the number density as 1E-ApB for some A, B
370  G4int order10 = (G4int) -round(10*std::log10(    370  G4int order10 = (G4int) -round(10*std::log10(fDropletNumDens*mm3));  // gives 10x the exponent rounded to the int (10x so we get two decimals)
371  G4int leading = order10 / 10;  // first numbe    371  G4int leading = order10 / 10;  // first number
372  G4int trailing = order10 % 10; // second numb    372  G4int trailing = order10 % 10; // second number
373  G4String nStr = "1E-" + std::to_string(leadin    373  G4String nStr = "1E-" + std::to_string(leading) + "p" + std::to_string(trailing);
374                                                   374 
375  fName = "distribution_r" + rStr + "mm_n" + nS    375  fName = "distribution_r" + rStr + "mm_n" + nStr + "mm-3.csv";
376  std::ifstream infile(fName);                     376  std::ifstream infile(fName);
377  std::string line;                                377  std::string line;
378                                                   378     
379  while (getline(infile,line)) {                   379  while (getline(infile,line)) {
380  std::istringstream stream(line);                 380  std::istringstream stream(line);
381  std::string field;                               381  std::string field;
382  getline(stream,field,','); x = stod(field)*mm    382  getline(stream,field,','); x = stod(field)*mm;
383  getline(stream,field,','); y = stod(field)*mm    383  getline(stream,field,','); y = stod(field)*mm;
384  getline(stream,field,','); z = stod(field)*mm    384  getline(stream,field,','); z = stod(field)*mm;
385                                                   385 
386  positions.push_back(G4ThreeVector(x,y,z));       386  positions.push_back(G4ThreeVector(x,y,z));
387     }                                             387     }
388                                                   388 
389  G4VPVParameterisation* cloudParam =              389  G4VPVParameterisation* cloudParam =
390       new CloudParameterisation(positions);       390       new CloudParameterisation(positions);
391                                                   391 
392  G4Box* cloudBounding = new G4Box("cloudBoundi    392  G4Box* cloudBounding = new G4Box("cloudBounding",//its name
393                       0.5*cloud_sizeXY,//half     393                       0.5*cloud_sizeXY,//half x-span
394           0.5*cloud_sizeXY, //half y-span         394           0.5*cloud_sizeXY, //half y-span
395           0.5*cloud_sizeZ); //half z-span         395           0.5*cloud_sizeZ); //half z-span
396                                                   396             
397  logicCloud = new G4LogicalVolume(cloudBoundin    397  logicCloud = new G4LogicalVolume(cloudBounding,  //its solid
398               air_mat,//its material              398               air_mat,//its material
399         "cloudLV");//its name                     399         "cloudLV");//its name
400                                                   400 
401  logicCloud->SetSmartless(fSmartless);            401  logicCloud->SetSmartless(fSmartless);
402  logicCloud->SetUserLimits(fStepLimits);          402  logicCloud->SetUserLimits(fStepLimits);
403  logicCloud->SetVisAttributes(G4VisAttributes(    403  logicCloud->SetVisAttributes(G4VisAttributes(false));
404                                                   404 
405  new G4PVPlacement(nullptr,//no rotation          405  new G4PVPlacement(nullptr,//no rotation
406        G4ThreeVector(),//at position              406        G4ThreeVector(),//at position
407        logicCloud,//its logical volume            407        logicCloud,//its logical volume
408        "cloudPV",//its name                       408        "cloudPV",//its name
409        logicWorld,  //its mothervolume            409        logicWorld,  //its mothervolume
410        false, //no boolean operation              410        false, //no boolean operation
411         0,//copy number                           411         0,//copy number
412        checkOverlaps);//overlaps checking         412        checkOverlaps);//overlaps checking
413                                                   413 
414  G4LogicalVolume* logicDroplet =                  414  G4LogicalVolume* logicDroplet = 
415       new G4LogicalVolume(fDropletShape,//its     415       new G4LogicalVolume(fDropletShape,//its solid
416       droplet_mat,//its material                  416       droplet_mat,//its material
417       "dropletLV");//its name                     417       "dropletLV");//its name
418                                                   418 
419  logicDroplet->SetUserLimits(fStepLimits);        419  logicDroplet->SetUserLimits(fStepLimits);
420                                                   420 
421  new G4PVParameterised("droplets",//its name      421  new G4PVParameterised("droplets",//its name
422       logicDroplet,//droplet logical volume       422       logicDroplet,//droplet logical volume
423       logicCloud,//mother logical volume          423       logicCloud,//mother logical volume    
424             kUndefined,//droplets placed along    424             kUndefined,//droplets placed along this axis
425             positions.size(),//number of dropl    425             positions.size(),//number of droplets
426              cloudParam);//the parametrisation    426              cloudParam);//the parametrisation 
427  }                                                427  }
428 // *******************************************    428 // **********************************************************
429 //                                                429 // 
430 // (For comparision/benchmarking) Simulate the    430 // (For comparision/benchmarking) Simulate the cloud by smearing droplets out into a single solid (does not use FastAerosol)
431 //                                                431 // 
432 // *******************************************    432 // ***********************************************************
433 else if (fSmoothCloud)                            433 else if (fSmoothCloud)  
434  {                                                434  {
435   G4cout << "\nSmooth geometry based on a clou    435   G4cout << "\nSmooth geometry based on a cloud of n=" << fDropletNumDens*mm3 << "/mm3 and r=" << fDropletR/mm << "mm spheres.\n" << G4endl;
436 // build cloud by smearing the droplets unifor    436 // build cloud by smearing the droplets uniformly across the cloud volume, for comparison/benchmarking purposes (does not use FastAerosol)
437 G4Material* cloud_mat = new G4Material("Cloud"    437 G4Material* cloud_mat = new G4Material("Cloud", (droplet_total_mass+cloud_air_mass)/cloud_volume, 2);
438                                                   438 
439 cloud_mat->AddMaterial(droplet_mat, droplet_to    439 cloud_mat->AddMaterial(droplet_mat, droplet_total_mass/(cloud_air_mass+droplet_total_mass));
440                                                   440 
441 cloud_mat->AddMaterial(air_mat, cloud_air_mass    441 cloud_mat->AddMaterial(air_mat, cloud_air_mass/(cloud_air_mass+droplet_total_mass));
442                                                   442               
443  logicCloud = new G4LogicalVolume(fCloudShape,    443  logicCloud = new G4LogicalVolume(fCloudShape,  //its solid
444           cloud_mat,  //its material              444           cloud_mat,  //its material
445           "cloudLV"); //its name                  445           "cloudLV"); //its name
446                                                   446 
447  logicCloud->SetUserLimits(fStepLimits);          447  logicCloud->SetUserLimits(fStepLimits);
448  logicCloud->SetVisAttributes(G4VisAttributes(    448  logicCloud->SetVisAttributes(G4VisAttributes(G4Colour(0.0,0.0,1.0,0.4)));
449                                                   449            
450  new G4PVPlacement(nullptr, //no rotation         450  new G4PVPlacement(nullptr, //no rotation
451        G4ThreeVector(), //at position             451        G4ThreeVector(), //at position
452        logicCloud,//its logical volume            452        logicCloud,//its logical volume
453        "cloudPV", //its name                      453        "cloudPV", //its name
454         logicWorld, //its mothervolume            454         logicWorld, //its mothervolume
455               false,  //no boolean operation      455               false,  //no boolean operation
456         0,//copy number                           456         0,//copy number
457         checkOverlaps); //overlaps checking       457         checkOverlaps); //overlaps checking
458  }                                                458  }
459  else                                             459  else
460  {                                                460  {
461  G4cout << "\nNo cloud.\n" << G4endl;             461  G4cout << "\nNo cloud.\n" << G4endl;
462  }                                                462  }  
463                                                   463 
464  //                                               464  //
465  // Build detector                                465  // Build detector
466  //                                               466  //
467  G4double detector_sizeXY = cloud_sizeXY;         467  G4double detector_sizeXY = cloud_sizeXY;
468  G4double detector_sizeZ = 0.05*m;                468  G4double detector_sizeZ = 0.05*m;
469  G4Material* detector_mat = nist->FindOrBuildM    469  G4Material* detector_mat = nist->FindOrBuildMaterial("G4_Al");
470  G4ThreeVector detector_pos = G4ThreeVector(0,    470  G4ThreeVector detector_pos = G4ThreeVector(0, 0, 0.5*1.05*cloud_sizeZ);
471                                                   471 
472  G4Box* soldDetector =  new G4Box("detectorSV"    472  G4Box* soldDetector =  new G4Box("detectorSV", //its name
473            0.5*detector_sizeXY, //half x-span     473            0.5*detector_sizeXY, //half x-span
474            0.5*detector_sizeXY, //half y-span     474            0.5*detector_sizeXY, //half y-span
475            0.5*detector_sizeZ); //half z-span     475            0.5*detector_sizeZ); //half z-span
476                                                   476             
477  G4LogicalVolume* logicDetector =                 477  G4LogicalVolume* logicDetector =            
478     new G4LogicalVolume(soldDetector, //its so    478     new G4LogicalVolume(soldDetector, //its solid
479             detector_mat, //its material          479             detector_mat, //its material
480             "detectorLV");  //its name            480             "detectorLV");  //its name
481                                                   481 
482  logicDetector->SetUserLimits(fStepLimits);       482  logicDetector->SetUserLimits(fStepLimits);
483                                                   483          
484  new G4PVPlacement(nullptr,//no rotation          484  new G4PVPlacement(nullptr,//no rotation
485        detector_pos,    //at position             485        detector_pos,    //at position
486        logicDetector,   //its logical volume      486        logicDetector,   //its logical volume
487        "detectorPV",    //its name                487        "detectorPV",    //its name
488              logicWorld,      //its mothervolu    488              logicWorld,      //its mothervolume
489        false,  //no boolean operation             489        false,  //no boolean operation
490       0,  //copy number                           490       0,  //copy number
491        checkOverlaps);    //overlaps checking     491        checkOverlaps);    //overlaps checking
492 //                                                492 //
493 // Scoring Volume                                 493 // Scoring Volume
494 //                                                494 //
495 fScoringVolume = logicDetector;                   495 fScoringVolume = logicDetector;
496                                                   496 
497 return physWorld;                                 497 return physWorld;
498 }                                                 498 }
499                                                   499 
500                                                   500