Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4AdjointPosOnPhysVolGenerator.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// G4AdjointPosOnPhysVolGenerator class implementation
27//
28// Author: L. Desorgher, SpaceIT GmbH - 01.06.2006
29// Contract: ESA contract 21435/08/NL/AT
30// Customer: ESA/ESTEC
31// --------------------------------------------------------------------
32
34#include "G4VSolid.hh"
35#include "G4VoxelLimits.hh"
36#include "G4AffineTransform.hh"
37#include "Randomize.hh"
38#include "G4VPhysicalVolume.hh"
41
43G4AdjointPosOnPhysVolGenerator::theInstance = nullptr;
44
45// --------------------------------------------------------------------
46//
48{
49 if(theInstance == nullptr)
50 {
51 theInstance = new G4AdjointPosOnPhysVolGenerator;
52 }
53 return theInstance;
54}
55
56// --------------------------------------------------------------------
57//
58G4AdjointPosOnPhysVolGenerator::~G4AdjointPosOnPhysVolGenerator()
59{
60}
61
62////////////////////////////////////////////////////
63//
64G4AdjointPosOnPhysVolGenerator::G4AdjointPosOnPhysVolGenerator()
65 : UseSphere(true), ModelOfSurfaceSource("OnSolid"),
66 AreaOfExtSurfaceOfThePhysicalVolume(0.), CosThDirComparedToNormal(0.)
67{
68}
69
70// --------------------------------------------------------------------
71//
74{
75 thePhysicalVolume = nullptr;
76 theSolid = nullptr;
78 for ( unsigned int i=0; i< thePhysVolStore->size(); ++i )
79 {
80 G4String vol_name =(*thePhysVolStore)[i]->GetName();
81 if (vol_name == "")
82 {
83 vol_name = (*thePhysVolStore)[i]->GetLogicalVolume()->GetName();
84 }
85 if (vol_name == aName)
86 {
87 thePhysicalVolume = (*thePhysVolStore)[i];
88 }
89 }
90 if (thePhysicalVolume != nullptr)
91 {
92 theSolid = thePhysicalVolume->GetLogicalVolume()->GetSolid();
93 ComputeTransformationFromPhysVolToWorld();
94 }
95 else
96 {
97 G4cout << "The physical volume with name " << aName
98 << " does not exist!!" << G4endl;
99 G4cout << "Before generating a source on an external surface " << G4endl
100 << "of a volume you should select another physical volume."
101 << G4endl;
102 }
103 return thePhysicalVolume;
104}
105
106// --------------------------------------------------------------------
107//
108void
110{
111 thePhysicalVolume = DefinePhysicalVolume(aName);
112}
113
114// --------------------------------------------------------------------
115//
117{
118 return ComputeAreaOfExtSurface(theSolid);
119}
120
121// --------------------------------------------------------------------
122//
124{
125 return ComputeAreaOfExtSurface(theSolid,NStats);
126}
127
128// --------------------------------------------------------------------
129//
131{
132 return ComputeAreaOfExtSurface(theSolid,eps);
133}
134
135// --------------------------------------------------------------------
136//
139{
140 return ComputeAreaOfExtSurface(aSolid,1.e-3);
141}
142
143// --------------------------------------------------------------------
144//
147 G4int NStats)
148{
149 if (ModelOfSurfaceSource == "OnSolid")
150 {
151 if (UseSphere)
152 {
153 return ComputeAreaOfExtSurfaceStartingFromSphere(aSolid,NStats);
154 }
155 else
156 {
157 return ComputeAreaOfExtSurfaceStartingFromBox(aSolid,NStats);
158 }
159 }
160 else
161 {
162 G4ThreeVector p, dir;
163 if (ModelOfSurfaceSource == "ExternalSphere")
164 {
165 return GenerateAPositionOnASphereBoundary(aSolid, p,dir);
166 }
167 return GenerateAPositionOnABoxBoundary(aSolid, p,dir);
168 }
169}
170
171// --------------------------------------------------------------------
172//
175 G4double eps)
176{
177 G4int Nstats = G4int(1./(eps*eps));
178 return ComputeAreaOfExtSurface(aSolid,Nstats);
179}
180
181// --------------------------------------------------------------------
182//
185 G4ThreeVector& direction)
186{
187 if (ModelOfSurfaceSource == "OnSolid")
188 {
189 GenerateAPositionOnASolidBoundary(aSolid, p,direction);
190 return;
191 }
192 if (ModelOfSurfaceSource == "ExternalSphere")
193 {
194 GenerateAPositionOnASphereBoundary(aSolid, p, direction);
195 return;
196 }
197 GenerateAPositionOnABoxBoundary(aSolid, p, direction);
198 return;
199}
200
201// --------------------------------------------------------------------
202//
205 G4ThreeVector& direction)
206{
207 GenerateAPositionOnTheExtSurfaceOfASolid(theSolid,p,direction);
208}
209
210// --------------------------------------------------------------------
211//
212G4double G4AdjointPosOnPhysVolGenerator::
213ComputeAreaOfExtSurfaceStartingFromBox(G4VSolid* aSolid, G4int Nstat)
214{
215 if ( Nstat <= 0 ) { return 0.; }
216 G4double area=1.;
217 G4int i=0, j=0;
218 while (i<Nstat)
219 {
220 G4ThreeVector p, direction;
221 area = GenerateAPositionOnABoxBoundary( aSolid,p, direction);
222 G4double dist_to_in = aSolid->DistanceToIn(p,direction);
223 if (dist_to_in<kInfinity/2.) { ++i; }
224 ++j;
225 }
226 area=area*G4double(i)/G4double(j);
227 return area;
228}
229
230// --------------------------------------------------------------------
231//
232G4double G4AdjointPosOnPhysVolGenerator::
233ComputeAreaOfExtSurfaceStartingFromSphere(G4VSolid* aSolid, G4int Nstat)
234{
235 if ( Nstat <= 0 ) { return 0.; }
236 G4double area=1.;
237 G4int i=0, j=0;
238 while (i<Nstat)
239 {
240 G4ThreeVector p, direction;
241 area = GenerateAPositionOnASphereBoundary( aSolid,p, direction);
242 G4double dist_to_in = aSolid->DistanceToIn(p,direction);
243 if (dist_to_in<kInfinity/2.) { ++i; }
244 ++j;
245 }
246 area=area*G4double(i)/G4double(j);
247 return area;
248}
249
250// --------------------------------------------------------------------
251//
252void G4AdjointPosOnPhysVolGenerator::
253GenerateAPositionOnASolidBoundary(G4VSolid* aSolid, G4ThreeVector& p,
254 G4ThreeVector& direction)
255{
256 G4bool find_pos = false;
257 while (!find_pos)
258 {
259 if (UseSphere)
260 {
261 GenerateAPositionOnASphereBoundary( aSolid,p, direction );
262 }
263 else
264 {
265 GenerateAPositionOnABoxBoundary( aSolid,p, direction);
266 }
267 G4double dist_to_in = aSolid->DistanceToIn(p,direction);
268 if (dist_to_in<kInfinity/2.)
269 {
270 find_pos = true;
271 p += 0.999999*direction*dist_to_in;
272 }
273 }
274}
275
276// --------------------------------------------------------------------
277//
278G4double G4AdjointPosOnPhysVolGenerator::
279GenerateAPositionOnASphereBoundary(G4VSolid* aSolid, G4ThreeVector& p,
280 G4ThreeVector& direction)
281{
282 G4double minX,maxX,minY,maxY,minZ,maxZ;
283
284 // values needed for CalculateExtent signature
285
286 G4VoxelLimits limit; // Unlimited
287 G4AffineTransform origin;
288
289 // min max extents of pSolid along X,Y,Z
290
291 aSolid->CalculateExtent(kXAxis,limit,origin,minX,maxX);
292 aSolid->CalculateExtent(kYAxis,limit,origin,minY,maxY);
293 aSolid->CalculateExtent(kZAxis,limit,origin,minZ,maxZ);
294
295 G4ThreeVector center = G4ThreeVector((minX+maxX)/2.,
296 (minY+maxY)/2.,
297 (minZ+maxZ)/2.);
298 G4double dX=(maxX-minX)/2.;
299 G4double dY=(maxY-minY)/2.;
300 G4double dZ=(maxZ-minZ)/2.;
301 G4double scale=1.01;
302 G4double r=scale*std::sqrt(dX*dX+dY*dY+dZ*dZ);
303
304 G4double cos_th2 = G4UniformRand();
305 G4double theta = std::acos(std::sqrt(cos_th2));
306 G4double phi=G4UniformRand()*CLHEP::twopi;
307 direction.setRThetaPhi(1.,theta,phi);
308 direction=-direction;
309 G4double cos_th = (1.-2.*G4UniformRand());
310 theta = std::acos(cos_th);
311 if (G4UniformRand() < 0.5) { theta=CLHEP::pi-theta; }
312 phi=G4UniformRand()*CLHEP::twopi;
313 p.setRThetaPhi(r,theta,phi);
314 p+=center;
315 direction.rotateY(theta);
316 direction.rotateZ(phi);
317 return 4.*CLHEP::pi*r*r;;
318}
319
320// --------------------------------------------------------------------
321//
322G4double G4AdjointPosOnPhysVolGenerator::
323GenerateAPositionOnABoxBoundary(G4VSolid* aSolid, G4ThreeVector& p,
324 G4ThreeVector& direction)
325{
326
327 G4double ran_var,px,py,pz,minX,maxX,minY,maxY,minZ,maxZ;
328
329 // values needed for CalculateExtent signature
330
331 G4VoxelLimits limit; // Unlimited
332 G4AffineTransform origin;
333
334 // min max extents of pSolid along X,Y,Z
335
336 aSolid->CalculateExtent(kXAxis,limit,origin,minX,maxX);
337 aSolid->CalculateExtent(kYAxis,limit,origin,minY,maxY);
338 aSolid->CalculateExtent(kZAxis,limit,origin,minZ,maxZ);
339
340 G4double scale=.1;
341 minX-=scale*std::abs(minX);
342 minY-=scale*std::abs(minY);
343 minZ-=scale*std::abs(minZ);
344 maxX+=scale*std::abs(maxX);
345 maxY+=scale*std::abs(maxY);
346 maxZ+=scale*std::abs(maxZ);
347
348 G4double dX=(maxX-minX);
349 G4double dY=(maxY-minY);
350 G4double dZ=(maxZ-minZ);
351
352 G4double XY_prob=2.*dX*dY;
353 G4double YZ_prob=2.*dY*dZ;
354 G4double ZX_prob=2.*dZ*dX;
355 G4double area=XY_prob+YZ_prob+ZX_prob;
356 XY_prob/=area;
357 YZ_prob/=area;
358 ZX_prob/=area;
359
360 ran_var=G4UniformRand();
361 G4double cos_th2 = G4UniformRand();
362 G4double sth = std::sqrt(1.-cos_th2);
363 G4double cth = std::sqrt(cos_th2);
364 G4double phi = G4UniformRand()*CLHEP::twopi;
365 G4double dirX = sth*std::cos(phi);
366 G4double dirY = sth*std::sin(phi);
367 G4double dirZ = cth;
368 if (ran_var <=XY_prob) // on the XY faces
369 {
370 G4double ran_var1=ran_var/XY_prob;
371 G4double ranX=ran_var1;
372 if (ran_var1<=0.5)
373 {
374 pz=minZ;
375 direction=G4ThreeVector(dirX,dirY,dirZ);
376 ranX=ran_var1*2.;
377 }
378 else
379 {
380 pz=maxZ;
381 direction=-G4ThreeVector(dirX,dirY,dirZ);
382 ranX=(ran_var1-0.5)*2.;
383 }
384 G4double ranY=G4UniformRand();
385 px=minX+(maxX-minX)*ranX;
386 py=minY+(maxY-minY)*ranY;
387 }
388 else if (ran_var <=(XY_prob+YZ_prob)) // on the YZ faces
389 {
390 G4double ran_var1=(ran_var-XY_prob)/YZ_prob;
391 G4double ranY=ran_var1;
392 if (ran_var1<=0.5)
393 {
394 px=minX;
395 direction=G4ThreeVector(dirZ,dirX,dirY);
396 ranY=ran_var1*2.;
397 }
398 else
399 {
400 px=maxX;
401 direction=-G4ThreeVector(dirZ,dirX,dirY);
402 ranY=(ran_var1-0.5)*2.;
403 }
404 G4double ranZ=G4UniformRand();
405 py=minY+(maxY-minY)*ranY;
406 pz=minZ+(maxZ-minZ)*ranZ;
407 }
408 else // on the ZX faces
409 {
410 G4double ran_var1=(ran_var-XY_prob-YZ_prob)/ZX_prob;
411 G4double ranZ=ran_var1;
412 if (ran_var1<=0.5)
413 {
414 py=minY;
415 direction=G4ThreeVector(dirY,dirZ,dirX);
416 ranZ=ran_var1*2.;
417 }
418 else
419 {
420 py=maxY;
421 direction=-G4ThreeVector(dirY,dirZ,dirX);
422 ranZ=(ran_var1-0.5)*2.;
423 }
424 G4double ranX=G4UniformRand();
425 px=minX+(maxX-minX)*ranX;
426 pz=minZ+(maxZ-minZ)*ranZ;
427 }
428
429 p=G4ThreeVector(px,py,pz);
430 return area;
431}
432
433// --------------------------------------------------------------------
434//
437 G4ThreeVector& direction)
438{
439 if (thePhysicalVolume == nullptr)
440 {
441 G4cout << "Before generating a source on an external surface" << G4endl
442 << "of volume you should select a physical volume" << G4endl;
443 return;
444 }
446 p = theTransformationFromPhysVolToWorld.TransformPoint(p);
447 direction = theTransformationFromPhysVolToWorld.TransformAxis(direction);
448}
449
450// --------------------------------------------------------------------
451//
454 G4ThreeVector& direction,
455 G4double& costh_to_normal)
456{
458 costh_to_normal = CosThDirComparedToNormal;
459}
460
461// --------------------------------------------------------------------
462//
463void G4AdjointPosOnPhysVolGenerator::ComputeTransformationFromPhysVolToWorld()
464{
465 G4VPhysicalVolume* daughter = thePhysicalVolume;
466 G4LogicalVolume* mother = thePhysicalVolume->GetMotherLogical();
467 theTransformationFromPhysVolToWorld = G4AffineTransform();
469 while (mother != nullptr)
470 {
471 theTransformationFromPhysVolToWorld *=
473 daughter->GetObjectTranslation());
474 for ( unsigned int i=0; i<thePhysVolStore->size(); ++i )
475 {
476 if ((*thePhysVolStore)[i]->GetLogicalVolume() == mother)
477 {
478 daughter = (*thePhysVolStore)[i];
479 mother = daughter->GetMotherLogical();
480 break;
481 }
482 }
483 }
484}
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:52
Hep3Vector & rotateY(double)
Definition: ThreeVector.cc:97
Hep3Vector & rotateZ(double)
Definition: ThreeVector.cc:107
void setRThetaPhi(double r, double theta, double phi)
void GenerateAPositionOnTheExtSurfaceOfTheSolid(G4ThreeVector &p, G4ThreeVector &direction)
void GenerateAPositionOnTheExtSurfaceOfThePhysicalVolume(G4ThreeVector &p, G4ThreeVector &direction)
G4VPhysicalVolume * DefinePhysicalVolume(const G4String &aName)
void DefinePhysicalVolume1(const G4String &aName)
void GenerateAPositionOnTheExtSurfaceOfASolid(G4VSolid *aSolid, G4ThreeVector &p, G4ThreeVector &direction)
static G4AdjointPosOnPhysVolGenerator * GetInstance()
G4ThreeVector TransformPoint(const G4ThreeVector &vec) const
G4ThreeVector TransformAxis(const G4ThreeVector &axis) const
G4VSolid * GetSolid() const
static G4PhysicalVolumeStore * GetInstance()
G4LogicalVolume * GetMotherLogical() const
G4LogicalVolume * GetLogicalVolume() const
const G4RotationMatrix * GetFrameRotation() const
G4ThreeVector GetObjectTranslation() const
virtual G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const =0
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const =0
@ kYAxis
Definition: geomdefs.hh:56
@ kXAxis
Definition: geomdefs.hh:55
@ kZAxis
Definition: geomdefs.hh:57
#define G4ThreadLocal
Definition: tls.hh:77