Import Geant4 9.3.0 source tree
This commit is contained in:
@@ -0,0 +1,423 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4AdjointPosOnPhysVolGenerator.cc,v 1.2 2009/11/18 17:57:59 gcosmo Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Class Name: G4AdjointCrossSurfChecker
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "G4AdjointPosOnPhysVolGenerator.hh"
|
||||
#include "G4VSolid.hh"
|
||||
#include "G4VoxelLimits.hh"
|
||||
#include "G4AffineTransform.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4VPhysicalVolume.hh"
|
||||
#include "G4PhysicalVolumeStore.hh"
|
||||
#include "G4LogicalVolumeStore.hh"
|
||||
|
||||
G4AdjointPosOnPhysVolGenerator* G4AdjointPosOnPhysVolGenerator::theInstance = 0;
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointPosOnPhysVolGenerator* G4AdjointPosOnPhysVolGenerator::GetInstance()
|
||||
{
|
||||
if(theInstance == 0) {
|
||||
static G4AdjointPosOnPhysVolGenerator manager;
|
||||
theInstance = &manager;
|
||||
}
|
||||
return theInstance;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointPosOnPhysVolGenerator::~G4AdjointPosOnPhysVolGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointPosOnPhysVolGenerator::G4AdjointPosOnPhysVolGenerator()
|
||||
{
|
||||
theSolid=0;
|
||||
NStat =1000000;
|
||||
epsilon=0.001;
|
||||
ModelOfSurfaceSource = "OnSolid"; //OnSolid, ExternalSphere, ExternalBox
|
||||
thePhysicalVolume = 0;
|
||||
theTransformationFromPhysVolToWorld = G4AffineTransform();
|
||||
UseSphere =true;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4VPhysicalVolume* G4AdjointPosOnPhysVolGenerator::DefinePhysicalVolume(const G4String& aName)
|
||||
{
|
||||
thePhysicalVolume = 0;
|
||||
theSolid =0;
|
||||
G4PhysicalVolumeStore* thePhysVolStore =G4PhysicalVolumeStore::GetInstance();
|
||||
for ( unsigned int i=0; i< thePhysVolStore->size();i++){
|
||||
G4String vol_name =(*thePhysVolStore)[i]->GetName();
|
||||
if (vol_name == ""){
|
||||
vol_name = (*thePhysVolStore)[i]->GetLogicalVolume()->GetName();
|
||||
}
|
||||
if (vol_name == aName){
|
||||
thePhysicalVolume = (*thePhysVolStore)[i];
|
||||
}
|
||||
}
|
||||
if (thePhysicalVolume){
|
||||
theSolid = thePhysicalVolume->GetLogicalVolume()->GetSolid();
|
||||
ComputeTransformationFromPhysVolToWorld();
|
||||
/*AreaOfExtSurfaceOfThePhysicalVolume=ComputeAreaOfExtSurface(1.e-3);
|
||||
G4cout<<"Monte Carlo Estimate of the area of the external surface :"<<AreaOfExtSurfaceOfThePhysicalVolume/m/m<<" m2"<<std::endl;*/
|
||||
}
|
||||
else {
|
||||
G4cout<<"The physical volume with name "<<aName<<" does not exist!!"<<std::endl;
|
||||
G4cout<<"Before generating a source on an external surface of a volume you should select another physical volume"<<std::endl;
|
||||
}
|
||||
return thePhysicalVolume;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointPosOnPhysVolGenerator::DefinePhysicalVolume1(const G4String& aName)
|
||||
{
|
||||
thePhysicalVolume = DefinePhysicalVolume(aName);
|
||||
}
|
||||
////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointPosOnPhysVolGenerator::ComputeAreaOfExtSurface()
|
||||
{
|
||||
return ComputeAreaOfExtSurface(theSolid);
|
||||
}
|
||||
////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointPosOnPhysVolGenerator::ComputeAreaOfExtSurface(G4int NStat)
|
||||
{
|
||||
return ComputeAreaOfExtSurface(theSolid,NStat);
|
||||
}
|
||||
////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointPosOnPhysVolGenerator::ComputeAreaOfExtSurface(G4double epsilon)
|
||||
{
|
||||
return ComputeAreaOfExtSurface(theSolid,epsilon);
|
||||
}
|
||||
////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointPosOnPhysVolGenerator::ComputeAreaOfExtSurface(G4VSolid* aSolid)
|
||||
{
|
||||
return ComputeAreaOfExtSurface(aSolid,1.e-3);
|
||||
}
|
||||
////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointPosOnPhysVolGenerator::ComputeAreaOfExtSurface(G4VSolid* aSolid,G4int NStat)
|
||||
{
|
||||
if (ModelOfSurfaceSource == "OnSolid" ){
|
||||
if (UseSphere){
|
||||
return ComputeAreaOfExtSurfaceStartingFromSphere(aSolid,NStat);
|
||||
|
||||
}
|
||||
else {
|
||||
return ComputeAreaOfExtSurfaceStartingFromBox(aSolid,NStat);
|
||||
}
|
||||
}
|
||||
else {
|
||||
G4ThreeVector p,dir;
|
||||
if (ModelOfSurfaceSource == "ExternalSphere" ) return GenerateAPositionOnASphereBoundary(aSolid, p,dir);
|
||||
return GenerateAPositionOnABoxBoundary(aSolid, p,dir);
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointPosOnPhysVolGenerator::ComputeAreaOfExtSurface(G4VSolid* aSolid,G4double epsilon)
|
||||
{
|
||||
G4int Nstat = G4int(1./(epsilon*epsilon));
|
||||
return ComputeAreaOfExtSurface(aSolid,Nstat);
|
||||
}
|
||||
////////////////////////////////////////////////////
|
||||
void G4AdjointPosOnPhysVolGenerator::GenerateAPositionOnTheExtSurfaceOfASolid(G4VSolid* aSolid,G4ThreeVector& p, G4ThreeVector& direction)
|
||||
{
|
||||
G4double area;
|
||||
area =1.;
|
||||
if (ModelOfSurfaceSource == "OnSolid" ){
|
||||
return GenerateAPositionOnASolidBoundary(aSolid, p,direction);
|
||||
}
|
||||
if (ModelOfSurfaceSource == "ExternalSphere" ) {
|
||||
area = GenerateAPositionOnASphereBoundary(aSolid, p, direction);
|
||||
return;
|
||||
}
|
||||
area = GenerateAPositionOnABoxBoundary(aSolid, p, direction);
|
||||
return;
|
||||
}
|
||||
////////////////////////////////////////////////////
|
||||
void G4AdjointPosOnPhysVolGenerator::GenerateAPositionOnTheExtSurfaceOfTheSolid(G4ThreeVector& p, G4ThreeVector& direction)
|
||||
{
|
||||
GenerateAPositionOnTheExtSurfaceOfASolid(theSolid,p,direction);
|
||||
}
|
||||
////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointPosOnPhysVolGenerator::ComputeAreaOfExtSurfaceStartingFromBox(G4VSolid* aSolid,G4int Nstat)
|
||||
{
|
||||
G4double area=1.;
|
||||
G4int i=0;
|
||||
G4int j=0;
|
||||
while (i<Nstat){
|
||||
G4ThreeVector p, direction;
|
||||
area = GenerateAPositionOnABoxBoundary( aSolid,p, direction);
|
||||
G4double dist_to_in = aSolid->DistanceToIn(p,direction);
|
||||
if (dist_to_in<kInfinity/2.) i++;
|
||||
j++;
|
||||
}
|
||||
area=area*double(i)/double(j);
|
||||
return area;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointPosOnPhysVolGenerator::ComputeAreaOfExtSurfaceStartingFromSphere(G4VSolid* aSolid,G4int Nstat)
|
||||
{
|
||||
G4double area=1.;
|
||||
G4int i=0;
|
||||
G4int j=0;
|
||||
while (i<Nstat){
|
||||
G4ThreeVector p, direction;
|
||||
area = GenerateAPositionOnASphereBoundary( aSolid,p, direction);
|
||||
G4double dist_to_in = aSolid->DistanceToIn(p,direction);
|
||||
if (dist_to_in<kInfinity/2.) i++;
|
||||
j++;
|
||||
}
|
||||
area=area*double(i)/double(j);
|
||||
|
||||
return area;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointPosOnPhysVolGenerator::GenerateAPositionOnASolidBoundary(G4VSolid* aSolid,G4ThreeVector& p, G4ThreeVector& direction)
|
||||
{
|
||||
G4bool find_pos =false;
|
||||
G4double area=1.;
|
||||
while (!find_pos){
|
||||
if (UseSphere) area = GenerateAPositionOnASphereBoundary( aSolid,p, direction);
|
||||
else area = GenerateAPositionOnABoxBoundary( aSolid,p, direction);
|
||||
G4double dist_to_in = aSolid->DistanceToIn(p,direction);
|
||||
if (dist_to_in<kInfinity/2.) {
|
||||
find_pos =true;
|
||||
G4ThreeVector p1=p+ 0.99999*direction*dist_to_in;
|
||||
G4ThreeVector norm =aSolid->SurfaceNormal(p1);
|
||||
p+= 0.999999*direction*dist_to_in;
|
||||
CosThDirComparedToNormal=direction.dot(-norm);
|
||||
//std::cout<<CosThDirComparedToNormal<<std::endl;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointPosOnPhysVolGenerator::GenerateAPositionOnASphereBoundary(G4VSolid* aSolid,G4ThreeVector& p, G4ThreeVector& direction)
|
||||
{
|
||||
G4double minX,maxX,minY,maxY,minZ,maxZ;
|
||||
G4bool yesno;
|
||||
|
||||
// values needed for CalculateExtent signature
|
||||
|
||||
G4VoxelLimits limit; // Unlimited
|
||||
G4AffineTransform origin;
|
||||
|
||||
// min max extents of pSolid along X,Y,Z
|
||||
|
||||
yesno = aSolid->CalculateExtent(kXAxis,limit,origin,minX,maxX);
|
||||
yesno = aSolid->CalculateExtent(kYAxis,limit,origin,minY,maxY);
|
||||
yesno = aSolid->CalculateExtent(kZAxis,limit,origin,minZ,maxZ);
|
||||
|
||||
G4ThreeVector center = G4ThreeVector((minX+maxX)/2.,(minY+maxY)/2.,(minZ+maxZ)/2.);
|
||||
|
||||
G4double dX=(maxX-minX)/2.;
|
||||
G4double dY=(maxY-minY)/2.;
|
||||
G4double dZ=(maxZ-minZ)/2.;
|
||||
G4double scale=1.01;
|
||||
G4double r=scale*std::sqrt(dX*dX+dY*dY+dZ*dZ);
|
||||
|
||||
G4double cos_th2 = G4UniformRand();
|
||||
G4double theta = std::acos(std::sqrt(cos_th2));
|
||||
G4double phi=G4UniformRand()*3.1415926*2;
|
||||
direction.setRThetaPhi(1.,theta,phi);
|
||||
direction=-direction;
|
||||
G4double cos_th = (1.-2.*G4UniformRand());
|
||||
theta = std::acos(cos_th);
|
||||
if (G4UniformRand() <0.5) theta=3.1415926-theta;
|
||||
phi=G4UniformRand()*3.1415926*2;
|
||||
p.setRThetaPhi(r,theta,phi);
|
||||
p+=center;
|
||||
direction.rotateY(theta);
|
||||
direction.rotateZ(phi);
|
||||
return 4.*3.1415926*r*r;;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointPosOnPhysVolGenerator::GenerateAPositionOnABoxBoundary(G4VSolid* aSolid,G4ThreeVector& p, G4ThreeVector& direction)
|
||||
{
|
||||
|
||||
G4double ran_var,px,py,pz,minX,maxX,minY,maxY,minZ,maxZ;
|
||||
G4bool yesno;
|
||||
|
||||
// values needed for CalculateExtent signature
|
||||
|
||||
G4VoxelLimits limit; // Unlimited
|
||||
G4AffineTransform origin;
|
||||
|
||||
// min max extents of pSolid along X,Y,Z
|
||||
|
||||
yesno = aSolid->CalculateExtent(kXAxis,limit,origin,minX,maxX);
|
||||
yesno = aSolid->CalculateExtent(kYAxis,limit,origin,minY,maxY);
|
||||
yesno = aSolid->CalculateExtent(kZAxis,limit,origin,minZ,maxZ);
|
||||
|
||||
G4double scale=.1;
|
||||
minX-=scale*std::abs(minX);
|
||||
minY-=scale*std::abs(minY);
|
||||
minZ-=scale*std::abs(minZ);
|
||||
maxX+=scale*std::abs(maxX);
|
||||
maxY+=scale*std::abs(maxY);
|
||||
maxZ+=scale*std::abs(maxZ);
|
||||
|
||||
G4double dX=(maxX-minX);
|
||||
G4double dY=(maxY-minY);
|
||||
G4double dZ=(maxZ-minZ);
|
||||
|
||||
G4double XY_prob=2.*dX*dY;
|
||||
G4double YZ_prob=2.*dY*dZ;
|
||||
G4double ZX_prob=2.*dZ*dX;
|
||||
G4double area=XY_prob+YZ_prob+ZX_prob;
|
||||
XY_prob/=area;
|
||||
YZ_prob/=area;
|
||||
ZX_prob/=area;
|
||||
|
||||
ran_var=G4UniformRand();
|
||||
G4double cos_th2 = G4UniformRand();
|
||||
G4double sth = std::sqrt(1.-cos_th2);
|
||||
G4double cth = std::sqrt(cos_th2);
|
||||
G4double phi=G4UniformRand()*3.1415926*2;
|
||||
G4double dirX = sth*std::cos(phi);
|
||||
G4double dirY = sth*std::sin(phi);
|
||||
G4double dirZ = cth;
|
||||
if (ran_var <=XY_prob){ //on the XY faces
|
||||
G4double ran_var1=ran_var/XY_prob;
|
||||
G4double ranX=ran_var1;
|
||||
if (ran_var1<=0.5){
|
||||
pz=minZ;
|
||||
direction=G4ThreeVector(dirX,dirY,dirZ);
|
||||
ranX=ran_var1*2.;
|
||||
}
|
||||
else{
|
||||
pz=maxZ;
|
||||
direction=-G4ThreeVector(dirX,dirY,dirZ);
|
||||
ranX=(ran_var1-0.5)*2.;
|
||||
}
|
||||
G4double ranY=G4UniformRand();
|
||||
px=minX+(maxX-minX)*ranX;
|
||||
py=minY+(maxY-minY)*ranY;
|
||||
}
|
||||
else if (ran_var <=(XY_prob+YZ_prob)){ //on the YZ faces
|
||||
G4double ran_var1=(ran_var-XY_prob)/YZ_prob;
|
||||
G4double ranY=ran_var1;
|
||||
if (ran_var1<=0.5){
|
||||
px=minX;
|
||||
direction=G4ThreeVector(dirZ,dirX,dirY);
|
||||
ranY=ran_var1*2.;
|
||||
}
|
||||
else{
|
||||
px=maxX;
|
||||
direction=-G4ThreeVector(dirZ,dirX,dirY);
|
||||
ranY=(ran_var1-0.5)*2.;
|
||||
}
|
||||
G4double ranZ=G4UniformRand();
|
||||
py=minY+(maxY-minY)*ranY;
|
||||
pz=minZ+(maxZ-minZ)*ranZ;
|
||||
|
||||
}
|
||||
else{ //on the ZX faces
|
||||
G4double ran_var1=(ran_var-XY_prob-YZ_prob)/ZX_prob;
|
||||
G4double ranZ=ran_var1;
|
||||
if (ran_var1<=0.5){
|
||||
py=minY;
|
||||
direction=G4ThreeVector(dirY,dirZ,dirX);
|
||||
ranZ=ran_var1*2.;
|
||||
}
|
||||
else{
|
||||
py=maxY;
|
||||
direction=-G4ThreeVector(dirY,dirZ,dirX);
|
||||
ranZ=(ran_var1-0.5)*2.;
|
||||
}
|
||||
G4double ranX=G4UniformRand();
|
||||
px=minX+(maxX-minX)*ranX;
|
||||
pz=minZ+(maxZ-minZ)*ranZ;
|
||||
}
|
||||
|
||||
p=G4ThreeVector(px,py,pz);
|
||||
return area;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointPosOnPhysVolGenerator::GenerateAPositionOnTheExtSurfaceOfThePhysicalVolume(G4ThreeVector& p, G4ThreeVector& direction)
|
||||
{
|
||||
if (!thePhysicalVolume) {
|
||||
G4cout<<"Before generating a source on an external surface of volume you should select a physical volume"<<std::endl;
|
||||
return;
|
||||
};
|
||||
GenerateAPositionOnTheExtSurfaceOfTheSolid(p,direction);
|
||||
p = theTransformationFromPhysVolToWorld.TransformPoint(p);
|
||||
direction = theTransformationFromPhysVolToWorld.TransformAxis(direction);
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointPosOnPhysVolGenerator::GenerateAPositionOnTheExtSurfaceOfThePhysicalVolume(G4ThreeVector& p, G4ThreeVector& direction,
|
||||
G4double& costh_to_normal)
|
||||
{
|
||||
GenerateAPositionOnTheExtSurfaceOfThePhysicalVolume(p, direction);
|
||||
costh_to_normal = CosThDirComparedToNormal;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointPosOnPhysVolGenerator::ComputeTransformationFromPhysVolToWorld()
|
||||
{
|
||||
G4VPhysicalVolume* daughter =thePhysicalVolume;
|
||||
G4LogicalVolume* mother = thePhysicalVolume->GetMotherLogical();
|
||||
theTransformationFromPhysVolToWorld = G4AffineTransform();
|
||||
G4PhysicalVolumeStore* thePhysVolStore =G4PhysicalVolumeStore::GetInstance();
|
||||
while (mother){
|
||||
theTransformationFromPhysVolToWorld *=
|
||||
G4AffineTransform(daughter->GetFrameRotation(),daughter->GetObjectTranslation());
|
||||
for ( unsigned int i=0; i< thePhysVolStore->size();i++){
|
||||
if ((*thePhysVolStore)[i]->GetLogicalVolume() == mother){
|
||||
daughter = (*thePhysVolStore)[i];
|
||||
mother =daughter->GetMotherLogical();
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user