Geant4 11.1.1
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//
60{
61 thePhysicalVolume = nullptr;
62 theSolid = nullptr;
64 for ( unsigned int i=0; i< thePhysVolStore->size(); ++i )
65 {
66 G4String vol_name =(*thePhysVolStore)[i]->GetName();
67 if (vol_name.empty())
68 {
69 vol_name = (*thePhysVolStore)[i]->GetLogicalVolume()->GetName();
70 }
71 if (vol_name == aName)
72 {
73 thePhysicalVolume = (*thePhysVolStore)[i];
74 }
75 }
76 if (thePhysicalVolume != nullptr)
77 {
78 theSolid = thePhysicalVolume->GetLogicalVolume()->GetSolid();
79 ComputeTransformationFromPhysVolToWorld();
80 }
81 else
82 {
83 G4cout << "The physical volume with name " << aName
84 << " does not exist!!" << G4endl;
85 G4cout << "Before generating a source on an external surface " << G4endl
86 << "of a volume you should select another physical volume."
87 << G4endl;
88 }
89 return thePhysicalVolume;
90}
91
92// --------------------------------------------------------------------
93//
94void
96{
97 thePhysicalVolume = DefinePhysicalVolume(aName);
98}
99
100// --------------------------------------------------------------------
101//
103{
104 return ComputeAreaOfExtSurface(theSolid);
105}
106
107// --------------------------------------------------------------------
108//
110{
111 return ComputeAreaOfExtSurface(theSolid,NStats);
112}
113
114// --------------------------------------------------------------------
115//
117{
118 return ComputeAreaOfExtSurface(theSolid,eps);
119}
120
121// --------------------------------------------------------------------
122//
125{
126 return ComputeAreaOfExtSurface(aSolid,1.e-3);
127}
128
129// --------------------------------------------------------------------
130//
133 G4int NStats)
134{
135 if (ModelOfSurfaceSource == "OnSolid")
136 {
137 if (UseSphere)
138 {
139 return ComputeAreaOfExtSurfaceStartingFromSphere(aSolid,NStats);
140 }
141
142 return ComputeAreaOfExtSurfaceStartingFromBox(aSolid,NStats);
143 }
144
145 G4ThreeVector p, dir;
146 if (ModelOfSurfaceSource == "ExternalSphere")
147 {
148 return GenerateAPositionOnASphereBoundary(aSolid, p,dir);
149 }
150
151 return GenerateAPositionOnABoxBoundary(aSolid, p,dir);
152}
153
154// --------------------------------------------------------------------
155//
158 G4double eps)
159{
160 G4int Nstats = G4int(1./(eps*eps));
161 return ComputeAreaOfExtSurface(aSolid,Nstats);
162}
163
164// --------------------------------------------------------------------
165//
168 G4ThreeVector& direction)
169{
170 if (ModelOfSurfaceSource == "OnSolid")
171 {
172 GenerateAPositionOnASolidBoundary(aSolid, p,direction);
173 return;
174 }
175 if (ModelOfSurfaceSource == "ExternalSphere")
176 {
177 GenerateAPositionOnASphereBoundary(aSolid, p, direction);
178 return;
179 }
180 GenerateAPositionOnABoxBoundary(aSolid, p, direction);
181 return;
182}
183
184// --------------------------------------------------------------------
185//
188 G4ThreeVector& direction)
189{
190 GenerateAPositionOnTheExtSurfaceOfASolid(theSolid,p,direction);
191}
192
193// --------------------------------------------------------------------
194//
195G4double G4AdjointPosOnPhysVolGenerator::
196ComputeAreaOfExtSurfaceStartingFromBox(G4VSolid* aSolid, G4int Nstat)
197{
198 if ( Nstat <= 0 ) { return 0.; }
199 G4double area=1.;
200 G4int i=0, j=0;
201 while (i<Nstat)
202 {
203 G4ThreeVector p, direction;
204 area = GenerateAPositionOnABoxBoundary( aSolid,p, direction);
205 G4double dist_to_in = aSolid->DistanceToIn(p,direction);
206 if (dist_to_in<kInfinity/2.) { ++i; }
207 ++j;
208 }
209 area=area*G4double(i)/G4double(j);
210 return area;
211}
212
213// --------------------------------------------------------------------
214//
215G4double G4AdjointPosOnPhysVolGenerator::
216ComputeAreaOfExtSurfaceStartingFromSphere(G4VSolid* aSolid, G4int Nstat)
217{
218 if ( Nstat <= 0 ) { return 0.; }
219 G4double area=1.;
220 G4int i=0, j=0;
221 while (i<Nstat)
222 {
223 G4ThreeVector p, direction;
224 area = GenerateAPositionOnASphereBoundary( aSolid,p, direction);
225 G4double dist_to_in = aSolid->DistanceToIn(p,direction);
226 if (dist_to_in<kInfinity/2.) { ++i; }
227 ++j;
228 }
229 area=area*G4double(i)/G4double(j);
230 return area;
231}
232
233// --------------------------------------------------------------------
234//
235void G4AdjointPosOnPhysVolGenerator::
236GenerateAPositionOnASolidBoundary(G4VSolid* aSolid, G4ThreeVector& p,
237 G4ThreeVector& direction)
238{
239 G4bool find_pos = false;
240 while (!find_pos)
241 {
242 if (UseSphere)
243 {
244 GenerateAPositionOnASphereBoundary( aSolid,p, direction );
245 }
246 else
247 {
248 GenerateAPositionOnABoxBoundary( aSolid,p, direction);
249 }
250 G4double dist_to_in = aSolid->DistanceToIn(p,direction);
251 if (dist_to_in<kInfinity/2.)
252 {
253 find_pos = true;
254 p += 0.999999*direction*dist_to_in;
255 }
256 }
257}
258
259// --------------------------------------------------------------------
260//
261G4double G4AdjointPosOnPhysVolGenerator::
262GenerateAPositionOnASphereBoundary(G4VSolid* aSolid, G4ThreeVector& p,
263 G4ThreeVector& direction)
264{
265 G4double minX,maxX,minY,maxY,minZ,maxZ;
266
267 // values needed for CalculateExtent signature
268
269 G4VoxelLimits limit; // Unlimited
270 G4AffineTransform origin;
271
272 // min max extents of pSolid along X,Y,Z
273
274 aSolid->CalculateExtent(kXAxis,limit,origin,minX,maxX);
275 aSolid->CalculateExtent(kYAxis,limit,origin,minY,maxY);
276 aSolid->CalculateExtent(kZAxis,limit,origin,minZ,maxZ);
277
278 G4ThreeVector center = G4ThreeVector((minX+maxX)/2.,
279 (minY+maxY)/2.,
280 (minZ+maxZ)/2.);
281 G4double dX=(maxX-minX)/2.;
282 G4double dY=(maxY-minY)/2.;
283 G4double dZ=(maxZ-minZ)/2.;
284 G4double scale=1.01;
285 G4double r=scale*std::sqrt(dX*dX+dY*dY+dZ*dZ);
286
287 G4double cos_th2 = G4UniformRand();
288 G4double theta = std::acos(std::sqrt(cos_th2));
289 G4double phi=G4UniformRand()*CLHEP::twopi;
290 direction.setRThetaPhi(1.,theta,phi);
291 direction=-direction;
292 G4double cos_th = (1.-2.*G4UniformRand());
293 theta = std::acos(cos_th);
294 if (G4UniformRand() < 0.5) { theta=CLHEP::pi-theta; }
295 phi=G4UniformRand()*CLHEP::twopi;
296 p.setRThetaPhi(r,theta,phi);
297 p+=center;
298 direction.rotateY(theta);
299 direction.rotateZ(phi);
300 return 4.*CLHEP::pi*r*r;;
301}
302
303// --------------------------------------------------------------------
304//
305G4double G4AdjointPosOnPhysVolGenerator::
306GenerateAPositionOnABoxBoundary(G4VSolid* aSolid, G4ThreeVector& p,
307 G4ThreeVector& direction)
308{
309
310 G4double ran_var,px,py,pz,minX,maxX,minY,maxY,minZ,maxZ;
311
312 // values needed for CalculateExtent signature
313
314 G4VoxelLimits limit; // Unlimited
315 G4AffineTransform origin;
316
317 // min max extents of pSolid along X,Y,Z
318
319 aSolid->CalculateExtent(kXAxis,limit,origin,minX,maxX);
320 aSolid->CalculateExtent(kYAxis,limit,origin,minY,maxY);
321 aSolid->CalculateExtent(kZAxis,limit,origin,minZ,maxZ);
322
323 G4double scale=.1;
324 minX-=scale*std::abs(minX);
325 minY-=scale*std::abs(minY);
326 minZ-=scale*std::abs(minZ);
327 maxX+=scale*std::abs(maxX);
328 maxY+=scale*std::abs(maxY);
329 maxZ+=scale*std::abs(maxZ);
330
331 G4double dX=(maxX-minX);
332 G4double dY=(maxY-minY);
333 G4double dZ=(maxZ-minZ);
334
335 G4double XY_prob=2.*dX*dY;
336 G4double YZ_prob=2.*dY*dZ;
337 G4double ZX_prob=2.*dZ*dX;
338 G4double area=XY_prob+YZ_prob+ZX_prob;
339 XY_prob/=area;
340 YZ_prob/=area;
341 ZX_prob/=area;
342
343 ran_var=G4UniformRand();
344 G4double cos_th2 = G4UniformRand();
345 G4double sth = std::sqrt(1.-cos_th2);
346 G4double cth = std::sqrt(cos_th2);
347 G4double phi = G4UniformRand()*CLHEP::twopi;
348 G4double dirX = sth*std::cos(phi);
349 G4double dirY = sth*std::sin(phi);
350 G4double dirZ = cth;
351 if (ran_var <=XY_prob) // on the XY faces
352 {
353 G4double ran_var1=ran_var/XY_prob;
354 G4double ranX=ran_var1;
355 if (ran_var1<=0.5)
356 {
357 pz=minZ;
358 direction=G4ThreeVector(dirX,dirY,dirZ);
359 ranX=ran_var1*2.;
360 }
361 else
362 {
363 pz=maxZ;
364 direction=-G4ThreeVector(dirX,dirY,dirZ);
365 ranX=(ran_var1-0.5)*2.;
366 }
367 G4double ranY=G4UniformRand();
368 px=minX+(maxX-minX)*ranX;
369 py=minY+(maxY-minY)*ranY;
370 }
371 else if (ran_var <=(XY_prob+YZ_prob)) // on the YZ faces
372 {
373 G4double ran_var1=(ran_var-XY_prob)/YZ_prob;
374 G4double ranY=ran_var1;
375 if (ran_var1<=0.5)
376 {
377 px=minX;
378 direction=G4ThreeVector(dirZ,dirX,dirY);
379 ranY=ran_var1*2.;
380 }
381 else
382 {
383 px=maxX;
384 direction=-G4ThreeVector(dirZ,dirX,dirY);
385 ranY=(ran_var1-0.5)*2.;
386 }
387 G4double ranZ=G4UniformRand();
388 py=minY+(maxY-minY)*ranY;
389 pz=minZ+(maxZ-minZ)*ranZ;
390 }
391 else // on the ZX faces
392 {
393 G4double ran_var1=(ran_var-XY_prob-YZ_prob)/ZX_prob;
394 G4double ranZ=ran_var1;
395 if (ran_var1<=0.5)
396 {
397 py=minY;
398 direction=G4ThreeVector(dirY,dirZ,dirX);
399 ranZ=ran_var1*2.;
400 }
401 else
402 {
403 py=maxY;
404 direction=-G4ThreeVector(dirY,dirZ,dirX);
405 ranZ=(ran_var1-0.5)*2.;
406 }
407 G4double ranX=G4UniformRand();
408 px=minX+(maxX-minX)*ranX;
409 pz=minZ+(maxZ-minZ)*ranZ;
410 }
411
412 p=G4ThreeVector(px,py,pz);
413 return area;
414}
415
416// --------------------------------------------------------------------
417//
420 G4ThreeVector& direction)
421{
422 if (thePhysicalVolume == nullptr)
423 {
424 G4cout << "Before generating a source on an external surface" << G4endl
425 << "of volume you should select a physical volume" << G4endl;
426 return;
427 }
429 p = theTransformationFromPhysVolToWorld.TransformPoint(p);
430 direction = theTransformationFromPhysVolToWorld.TransformAxis(direction);
431}
432
433// --------------------------------------------------------------------
434//
437 G4ThreeVector& direction,
438 G4double& costh_to_normal)
439{
441 costh_to_normal = CosThDirComparedToNormal;
442}
443
444// --------------------------------------------------------------------
445//
446void G4AdjointPosOnPhysVolGenerator::ComputeTransformationFromPhysVolToWorld()
447{
448 G4VPhysicalVolume* daughter = thePhysicalVolume;
449 G4LogicalVolume* mother = thePhysicalVolume->GetMotherLogical();
450 theTransformationFromPhysVolToWorld = G4AffineTransform();
452 while (mother != nullptr)
453 {
454 theTransformationFromPhysVolToWorld *=
456 daughter->GetObjectTranslation());
457 for ( unsigned int i=0; i<thePhysVolStore->size(); ++i )
458 {
459 if ((*thePhysVolStore)[i]->GetLogicalVolume() == mother)
460 {
461 daughter = (*thePhysVolStore)[i];
462 mother = daughter->GetMotherLogical();
463 break;
464 }
465 }
466 }
467}
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