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