Geant4 9.6.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// $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