Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
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// $Id$
27//
28/////////////////////////////////////////////////////////////////////////////
29// Class Name: G4AdjointCrossSurfChecker
30// Author: L. Desorgher
31// Organisation: SpaceIT GmbH
32// Contract: ESA contract 21435/08/NL/AT
33// Customer: ESA/ESTEC
34/////////////////////////////////////////////////////////////////////////////
35
37#include "G4VSolid.hh"
38#include "G4VoxelLimits.hh"
39#include "G4AffineTransform.hh"
40#include "Randomize.hh"
41#include "G4VPhysicalVolume.hh"
44
45G4AdjointPosOnPhysVolGenerator* G4AdjointPosOnPhysVolGenerator::theInstance = 0;
46
47////////////////////////////////////////////////////
48//
50{
51 if(theInstance == 0) {
52 static G4AdjointPosOnPhysVolGenerator manager;
53 theInstance = &manager;
54 }
55 return theInstance;
56}
57
58////////////////////////////////////////////////////
59//
60G4AdjointPosOnPhysVolGenerator::~G4AdjointPosOnPhysVolGenerator()
61{
62}
63
64////////////////////////////////////////////////////
65//
66G4AdjointPosOnPhysVolGenerator::G4AdjointPosOnPhysVolGenerator()
67 : theSolid(0), thePhysicalVolume(0), NStat(1000000), epsilon(0.001),
68 UseSphere(true), ModelOfSurfaceSource("OnSolid"),
69 ExtSourceRadius(0.), ExtSourceDx(0.), ExtSourceDy(0.), ExtSourceDz(0.),
70 AreaOfExtSurfaceOfThePhysicalVolume(0.), CosThDirComparedToNormal(0.)
71{
72}
73
74/////////////////////////////////////////////////////////////////////////////////////////
75//
77{
78 thePhysicalVolume = 0;
79 theSolid =0;
81 for ( unsigned int i=0; i< thePhysVolStore->size();i++){
82 G4String vol_name =(*thePhysVolStore)[i]->GetName();
83 if (vol_name == ""){
84 vol_name = (*thePhysVolStore)[i]->GetLogicalVolume()->GetName();
85 }
86 if (vol_name == aName){
87 thePhysicalVolume = (*thePhysVolStore)[i];
88 }
89 }
90 if (thePhysicalVolume){
91 theSolid = thePhysicalVolume->GetLogicalVolume()->GetSolid();
92 ComputeTransformationFromPhysVolToWorld();
93 /*AreaOfExtSurfaceOfThePhysicalVolume=ComputeAreaOfExtSurface(1.e-3);
94 G4cout<<"Monte Carlo Estimate of the area of the external surface :"<<AreaOfExtSurfaceOfThePhysicalVolume/m/m<<" m2"<<std::endl;*/
95 }
96 else {
97 G4cout<<"The physical volume with name "<<aName<<" does not exist!!"<<std::endl;
98 G4cout<<"Before generating a source on an external surface of a volume you should select another physical volume"<<std::endl;
99 }
100 return thePhysicalVolume;
101}
102/////////////////////////////////////////////////////////////////////////////////////////
103//
105{
106 thePhysicalVolume = DefinePhysicalVolume(aName);
107}
108////////////////////////////////////////////////////
109//
111{
112 return ComputeAreaOfExtSurface(theSolid);
113}
114////////////////////////////////////////////////////
115//
117{
118 return ComputeAreaOfExtSurface(theSolid,NStats);
119}
120////////////////////////////////////////////////////
121//
123{
124 return ComputeAreaOfExtSurface(theSolid,eps);
125}
126////////////////////////////////////////////////////
127//
129{
130 return ComputeAreaOfExtSurface(aSolid,1.e-3);
131}
132////////////////////////////////////////////////////
133//
135{
136 if (ModelOfSurfaceSource == "OnSolid" ){
137 if (UseSphere){
138 return ComputeAreaOfExtSurfaceStartingFromSphere(aSolid,NStats);
139 }
140 else {
141 return ComputeAreaOfExtSurfaceStartingFromBox(aSolid,NStats);
142 }
143 }
144 else {
145 G4ThreeVector p,dir;
146 if (ModelOfSurfaceSource == "ExternalSphere" ) return GenerateAPositionOnASphereBoundary(aSolid, p,dir);
147 return GenerateAPositionOnABoxBoundary(aSolid, p,dir);
148 }
149}
150////////////////////////////////////////////////////
151//
153{
154 G4int Nstats = G4int(1./(eps*eps));
155 return ComputeAreaOfExtSurface(aSolid,Nstats);
156}
157////////////////////////////////////////////////////
159{
160 if (ModelOfSurfaceSource == "OnSolid" ){
161 GenerateAPositionOnASolidBoundary(aSolid, p,direction);
162 return;
163 }
164 if (ModelOfSurfaceSource == "ExternalSphere" ) {
165 GenerateAPositionOnASphereBoundary(aSolid, p, direction);
166 return;
167 }
168 GenerateAPositionOnABoxBoundary(aSolid, p, direction);
169 return;
170}
171////////////////////////////////////////////////////
173{
174 GenerateAPositionOnTheExtSurfaceOfASolid(theSolid,p,direction);
175}
176////////////////////////////////////////////////////
177//
178G4double G4AdjointPosOnPhysVolGenerator::ComputeAreaOfExtSurfaceStartingFromBox(G4VSolid* aSolid,G4int Nstat)
179{
180 G4double area=1.;
181 G4int i=0;
182 G4int j=0;
183 while (i<Nstat){
184 G4ThreeVector p, direction;
185 area = GenerateAPositionOnABoxBoundary( aSolid,p, direction);
186 G4double dist_to_in = aSolid->DistanceToIn(p,direction);
187 if (dist_to_in<kInfinity/2.) i++;
188 j++;
189 }
190 area=area*double(i)/double(j);
191 return area;
192}
193/////////////////////////////////////////////////////////////////////////////////////////
194//
195G4double G4AdjointPosOnPhysVolGenerator::ComputeAreaOfExtSurfaceStartingFromSphere(G4VSolid* aSolid,G4int Nstat)
196{
197 G4double area=1.;
198 G4int i=0;
199 G4int j=0;
200 while (i<Nstat){
201 G4ThreeVector p, direction;
202 area = GenerateAPositionOnASphereBoundary( aSolid,p, direction);
203 G4double dist_to_in = aSolid->DistanceToIn(p,direction);
204 if (dist_to_in<kInfinity/2.) i++;
205 j++;
206 }
207 area=area*double(i)/double(j);
208
209 return area;
210}
211/////////////////////////////////////////////////////////////////////////////////////////
212//
213void G4AdjointPosOnPhysVolGenerator::GenerateAPositionOnASolidBoundary(G4VSolid* aSolid,G4ThreeVector& p, G4ThreeVector& direction)
214{
215 G4bool find_pos =false;
216 while (!find_pos){
217 if (UseSphere) GenerateAPositionOnASphereBoundary( aSolid,p, direction);
218 else GenerateAPositionOnABoxBoundary( aSolid,p, direction);
219 G4double dist_to_in = aSolid->DistanceToIn(p,direction);
220 if (dist_to_in<kInfinity/2.) {
221 find_pos =true;
222 G4ThreeVector p1=p+ 0.99999*direction*dist_to_in;
223 G4ThreeVector norm =aSolid->SurfaceNormal(p1);
224 p+= 0.999999*direction*dist_to_in;
225 CosThDirComparedToNormal=direction.dot(-norm);
226 }
227 }
228}
229/////////////////////////////////////////////////////////////////////////////////////////
230//
231G4double G4AdjointPosOnPhysVolGenerator::GenerateAPositionOnASphereBoundary(G4VSolid* aSolid,G4ThreeVector& p, G4ThreeVector& direction)
232{
233 G4double minX,maxX,minY,maxY,minZ,maxZ;
234
235 // values needed for CalculateExtent signature
236
237 G4VoxelLimits limit; // Unlimited
238 G4AffineTransform origin;
239
240 // min max extents of pSolid along X,Y,Z
241
242 aSolid->CalculateExtent(kXAxis,limit,origin,minX,maxX);
243 aSolid->CalculateExtent(kYAxis,limit,origin,minY,maxY);
244 aSolid->CalculateExtent(kZAxis,limit,origin,minZ,maxZ);
245
246 G4ThreeVector center = G4ThreeVector((minX+maxX)/2.,(minY+maxY)/2.,(minZ+maxZ)/2.);
247
248 G4double dX=(maxX-minX)/2.;
249 G4double dY=(maxY-minY)/2.;
250 G4double dZ=(maxZ-minZ)/2.;
251 G4double scale=1.01;
252 G4double r=scale*std::sqrt(dX*dX+dY*dY+dZ*dZ);
253
254 G4double cos_th2 = G4UniformRand();
255 G4double theta = std::acos(std::sqrt(cos_th2));
256 G4double phi=G4UniformRand()*3.1415926*2;
257 direction.setRThetaPhi(1.,theta,phi);
258 direction=-direction;
259 G4double cos_th = (1.-2.*G4UniformRand());
260 theta = std::acos(cos_th);
261 if (G4UniformRand() <0.5) theta=3.1415926-theta;
262 phi=G4UniformRand()*3.1415926*2;
263 p.setRThetaPhi(r,theta,phi);
264 p+=center;
265 direction.rotateY(theta);
266 direction.rotateZ(phi);
267 return 4.*3.1415926*r*r;;
268}
269/////////////////////////////////////////////////////////////////////////////////////////
270//
271G4double G4AdjointPosOnPhysVolGenerator::GenerateAPositionOnABoxBoundary(G4VSolid* aSolid,G4ThreeVector& p, G4ThreeVector& direction)
272{
273
274 G4double ran_var,px,py,pz,minX,maxX,minY,maxY,minZ,maxZ;
275
276 // values needed for CalculateExtent signature
277
278 G4VoxelLimits limit; // Unlimited
279 G4AffineTransform origin;
280
281 // min max extents of pSolid along X,Y,Z
282
283 aSolid->CalculateExtent(kXAxis,limit,origin,minX,maxX);
284 aSolid->CalculateExtent(kYAxis,limit,origin,minY,maxY);
285 aSolid->CalculateExtent(kZAxis,limit,origin,minZ,maxZ);
286
287 G4double scale=.1;
288 minX-=scale*std::abs(minX);
289 minY-=scale*std::abs(minY);
290 minZ-=scale*std::abs(minZ);
291 maxX+=scale*std::abs(maxX);
292 maxY+=scale*std::abs(maxY);
293 maxZ+=scale*std::abs(maxZ);
294
295 G4double dX=(maxX-minX);
296 G4double dY=(maxY-minY);
297 G4double dZ=(maxZ-minZ);
298
299 G4double XY_prob=2.*dX*dY;
300 G4double YZ_prob=2.*dY*dZ;
301 G4double ZX_prob=2.*dZ*dX;
302 G4double area=XY_prob+YZ_prob+ZX_prob;
303 XY_prob/=area;
304 YZ_prob/=area;
305 ZX_prob/=area;
306
307 ran_var=G4UniformRand();
308 G4double cos_th2 = G4UniformRand();
309 G4double sth = std::sqrt(1.-cos_th2);
310 G4double cth = std::sqrt(cos_th2);
311 G4double phi=G4UniformRand()*3.1415926*2;
312 G4double dirX = sth*std::cos(phi);
313 G4double dirY = sth*std::sin(phi);
314 G4double dirZ = cth;
315 if (ran_var <=XY_prob){ //on the XY faces
316 G4double ran_var1=ran_var/XY_prob;
317 G4double ranX=ran_var1;
318 if (ran_var1<=0.5){
319 pz=minZ;
320 direction=G4ThreeVector(dirX,dirY,dirZ);
321 ranX=ran_var1*2.;
322 }
323 else{
324 pz=maxZ;
325 direction=-G4ThreeVector(dirX,dirY,dirZ);
326 ranX=(ran_var1-0.5)*2.;
327 }
328 G4double ranY=G4UniformRand();
329 px=minX+(maxX-minX)*ranX;
330 py=minY+(maxY-minY)*ranY;
331 }
332 else if (ran_var <=(XY_prob+YZ_prob)){ //on the YZ faces
333 G4double ran_var1=(ran_var-XY_prob)/YZ_prob;
334 G4double ranY=ran_var1;
335 if (ran_var1<=0.5){
336 px=minX;
337 direction=G4ThreeVector(dirZ,dirX,dirY);
338 ranY=ran_var1*2.;
339 }
340 else{
341 px=maxX;
342 direction=-G4ThreeVector(dirZ,dirX,dirY);
343 ranY=(ran_var1-0.5)*2.;
344 }
345 G4double ranZ=G4UniformRand();
346 py=minY+(maxY-minY)*ranY;
347 pz=minZ+(maxZ-minZ)*ranZ;
348
349 }
350 else{ //on the ZX faces
351 G4double ran_var1=(ran_var-XY_prob-YZ_prob)/ZX_prob;
352 G4double ranZ=ran_var1;
353 if (ran_var1<=0.5){
354 py=minY;
355 direction=G4ThreeVector(dirY,dirZ,dirX);
356 ranZ=ran_var1*2.;
357 }
358 else{
359 py=maxY;
360 direction=-G4ThreeVector(dirY,dirZ,dirX);
361 ranZ=(ran_var1-0.5)*2.;
362 }
363 G4double ranX=G4UniformRand();
364 px=minX+(maxX-minX)*ranX;
365 pz=minZ+(maxZ-minZ)*ranZ;
366 }
367
368 p=G4ThreeVector(px,py,pz);
369 return area;
370}
371/////////////////////////////////////////////////////////////////////////////////////////
372//
374{
375 if (!thePhysicalVolume) {
376 G4cout<<"Before generating a source on an external surface of volume you should select a physical volume"<<std::endl;
377 return;
378 };
380 p = theTransformationFromPhysVolToWorld.TransformPoint(p);
381 direction = theTransformationFromPhysVolToWorld.TransformAxis(direction);
382}
383/////////////////////////////////////////////////////////////////////////////////////////
384//
386 G4double& costh_to_normal)
387{
389 costh_to_normal = CosThDirComparedToNormal;
390}
391/////////////////////////////////////////////////////////////////////////////////////////
392//
393void G4AdjointPosOnPhysVolGenerator::ComputeTransformationFromPhysVolToWorld()
394{
395 G4VPhysicalVolume* daughter =thePhysicalVolume;
396 G4LogicalVolume* mother = thePhysicalVolume->GetMotherLogical();
397 theTransformationFromPhysVolToWorld = G4AffineTransform();
399 while (mother){
400 theTransformationFromPhysVolToWorld *=
402 for ( unsigned int i=0; i< thePhysVolStore->size();i++){
403 if ((*thePhysVolStore)[i]->GetLogicalVolume() == mother){
404 daughter = (*thePhysVolStore)[i];
405 mother =daughter->GetMotherLogical();
406 break;
407 };
408 }
409 }
410}
411
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
G4DLLIMPORT std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:53
Hep3Vector & rotateY(double)
Definition: ThreeVector.cc:134
Hep3Vector & rotateZ(double)
Definition: ThreeVector.cc:144
void setRThetaPhi(double r, double theta, double phi)
double dot(const Hep3Vector &) const
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 G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const =0
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const =0
@ kYAxis
Definition: geomdefs.hh:54
@ kXAxis
Definition: geomdefs.hh:54
@ kZAxis
Definition: geomdefs.hh:54