G4AdjointCrossSurfChecker.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 // $Id: G4AdjointCrossSurfChecker.cc 67009 2013-01-29 16:00:21Z gcosmo $
00027 //
00029 //      Class Name:     G4AdjointCrossSurfChecker
00030 //      Author:         L. Desorgher
00031 //      Organisation:   SpaceIT GmbH
00032 //      Contract:       ESA contract 21435/08/NL/AT
00033 //      Customer:       ESA/ESTEC
00035 
00036 #include "G4AdjointCrossSurfChecker.hh"
00037 #include "G4PhysicalConstants.hh"
00038 #include "G4SystemOfUnits.hh"
00039 #include "G4Step.hh"
00040 #include "G4StepPoint.hh"
00041 #include "G4PhysicalVolumeStore.hh" 
00042 #include "G4VSolid.hh"
00043 #include "G4AffineTransform.hh"
00044 
00046 // 
00047 G4AdjointCrossSurfChecker* G4AdjointCrossSurfChecker::instance = 0;
00048 
00050 //
00051 G4AdjointCrossSurfChecker::G4AdjointCrossSurfChecker()
00052 {;
00053 }
00055 //
00056 G4AdjointCrossSurfChecker::~G4AdjointCrossSurfChecker()
00057 {
00058   delete instance;
00059 }
00061 //
00062 G4AdjointCrossSurfChecker* G4AdjointCrossSurfChecker::GetInstance()
00063 {
00064   if (!instance) instance = new G4AdjointCrossSurfChecker();
00065   return instance;
00066 }                 
00068 //
00069 G4bool G4AdjointCrossSurfChecker::CrossingASphere(const G4Step* aStep,G4double sphere_radius, G4ThreeVector sphere_center,G4ThreeVector& crossing_pos, G4double& cos_th , G4bool& GoingIn)
00070 {
00071   G4ThreeVector pos1=  aStep->GetPreStepPoint()->GetPosition() - sphere_center;
00072   G4ThreeVector pos2=  aStep->GetPostStepPoint()->GetPosition() - sphere_center;
00073   G4double r1= pos1.mag();
00074   G4double r2= pos2.mag();
00075   G4bool did_cross =false; 
00076   
00077   if (r1<=sphere_radius && r2>sphere_radius){
00078         did_cross=true;
00079         GoingIn=false;
00080   } 
00081   else if (r2<=sphere_radius && r1>sphere_radius){
00082         did_cross=true;
00083         GoingIn=true;
00084   }
00085 
00086   if (did_cross) { 
00087         
00088         G4ThreeVector dr=pos2-pos1;
00089         G4double r12 = r1*r1;
00090         G4double rdr = dr.mag();
00091         G4double a,b,c,d;
00092         a = rdr*rdr;
00093         b = 2.*pos1.dot(dr);
00094         c = r12-sphere_radius*sphere_radius;
00095         d=std::sqrt(b*b-4.*a*c);
00096         G4double l= (-b+d)/2./a;
00097         if (l > 1.) l=(-b-d)/2./a;
00098         crossing_pos=pos1+l*dr;
00099         cos_th = std::abs(dr.cosTheta(crossing_pos));
00100         
00101   
00102   }
00103   return did_cross;
00104 }
00106 //
00107 G4bool G4AdjointCrossSurfChecker::GoingInOrOutOfaVolume(const G4Step* aStep,const G4String& volume_name, G4double& , G4bool& GoingIn) //from external surface
00108 {
00109   G4bool step_at_boundary = (aStep->GetPostStepPoint()->GetStepStatus() == fGeomBoundary);
00110   G4bool did_cross =false;
00111   if (step_at_boundary){
00112         const G4VTouchable* postStepTouchable = aStep->GetPostStepPoint()->GetTouchable();
00113         const G4VTouchable* preStepTouchable = aStep->GetPreStepPoint()->GetTouchable();
00114         if (preStepTouchable && postStepTouchable && postStepTouchable->GetVolume() && preStepTouchable->GetVolume()){
00115                 G4String post_vol_name = postStepTouchable->GetVolume()->GetName();
00116                 G4String pre_vol_name = preStepTouchable->GetVolume()->GetName();
00117                 
00118                 if (post_vol_name == volume_name ){
00119                         GoingIn=true;
00120                         did_cross=true;
00121                 }
00122                 else if (pre_vol_name == volume_name){
00123                         GoingIn=false;
00124                         did_cross=true;
00125                         
00126                 }
00127                 
00128         } 
00129   }
00130   return did_cross;
00131   //still need to compute the cosine of the direction
00132 }
00134 //
00135 G4bool G4AdjointCrossSurfChecker::GoingInOrOutOfaVolumeByExtSurface(const G4Step* aStep,const G4String& volume_name, const G4String& mother_logical_vol_name, G4double& , G4bool& GoingIn) //from external surface
00136 {
00137   G4bool step_at_boundary = (aStep->GetPostStepPoint()->GetStepStatus() == fGeomBoundary);
00138   G4bool did_cross =false;
00139   if (step_at_boundary){
00140         const G4VTouchable* postStepTouchable = aStep->GetPostStepPoint()->GetTouchable();
00141         const G4VTouchable* preStepTouchable = aStep->GetPreStepPoint()->GetTouchable();
00142         if (preStepTouchable && postStepTouchable && postStepTouchable->GetVolume() && preStepTouchable->GetVolume()){
00143                 G4String post_vol_name = postStepTouchable->GetVolume()->GetName();
00144                 G4String post_log_vol_name = postStepTouchable->GetVolume()->GetLogicalVolume()->GetName();
00145                 G4String pre_vol_name = preStepTouchable->GetVolume()->GetName();
00146                 G4String pre_log_vol_name = preStepTouchable->GetVolume()->GetLogicalVolume()->GetName();
00147                 if (post_vol_name == volume_name && pre_log_vol_name ==  mother_logical_vol_name){
00148                         GoingIn=true;
00149                         did_cross=true;
00150                 }
00151                 else if (pre_vol_name == volume_name && post_log_vol_name ==  mother_logical_vol_name ){
00152                         GoingIn=false;
00153                         did_cross=true;
00154                         
00155                 }
00156                 
00157         } 
00158   }
00159   return did_cross;
00160   //still need to compute the cosine of the direction
00161 }
00163 //
00164 G4bool G4AdjointCrossSurfChecker::CrossingAGivenRegisteredSurface(const G4Step* aStep,const G4String& surface_name,G4ThreeVector& crossing_pos, G4double& cos_to_surface, G4bool& GoingIn)
00165 {
00166   G4int ind = FindRegisteredSurface(surface_name);
00167   G4bool did_cross = false;
00168   if (ind >=0){
00169         did_cross = CrossingAGivenRegisteredSurface(aStep, ind, crossing_pos,cos_to_surface, GoingIn);
00170   }
00171   return did_cross;
00172 }
00174 //
00175 G4bool G4AdjointCrossSurfChecker::CrossingAGivenRegisteredSurface(const G4Step* aStep, int ind,G4ThreeVector& crossing_pos,   G4double& cos_to_surface, G4bool& GoingIn)
00176 {
00177    G4String surf_type = ListOfSurfaceType[ind];
00178    G4double radius = ListOfSphereRadius[ind];
00179    G4ThreeVector  center = ListOfSphereCenter[ind];
00180    G4String vol1 = ListOfVol1Name[ind];
00181    G4String vol2 = ListOfVol2Name[ind];
00182         
00183    G4bool did_cross = false;    
00184    if (surf_type == "Sphere"){
00185         did_cross = CrossingASphere(aStep, radius, center,crossing_pos, cos_to_surface, GoingIn);
00186    }
00187    else if (surf_type == "ExternalSurfaceOfAVolume"){
00188   
00189         did_cross = GoingInOrOutOfaVolumeByExtSurface(aStep, vol1, vol2, cos_to_surface, GoingIn);
00190         crossing_pos= aStep->GetPostStepPoint()->GetPosition();
00191                 
00192    }
00193    else if (surf_type == "BoundaryBetweenTwoVolumes"){
00194         did_cross = CrossingAnInterfaceBetweenTwoVolumes(aStep, vol1, vol2,crossing_pos, cos_to_surface, GoingIn);
00195    }
00196    return did_cross;
00197         
00198   
00199 }
00201 //
00202 //
00203 G4bool G4AdjointCrossSurfChecker::CrossingOneOfTheRegisteredSurface(const G4Step* aStep,G4String& surface_name,G4ThreeVector& crossing_pos, G4double& cos_to_surface, G4bool& GoingIn)
00204 {
00205  for (size_t i=0;i <ListOfSurfaceName.size();i++){
00206         if (CrossingAGivenRegisteredSurface(aStep, int(i),crossing_pos,   cos_to_surface, GoingIn)){
00207                 surface_name = ListOfSurfaceName[i];
00208                 return true;
00209         }
00210  }
00211  return false;
00212 }
00214 //
00215 G4bool G4AdjointCrossSurfChecker::CrossingAnInterfaceBetweenTwoVolumes(const G4Step* aStep,const G4String& vol1_name,const G4String& vol2_name,G4ThreeVector& , G4double& , G4bool& GoingIn)
00216 {
00217   G4bool step_at_boundary = (aStep->GetPostStepPoint()->GetStepStatus() == fGeomBoundary);
00218   G4bool did_cross =false;
00219   if (step_at_boundary){
00220         const G4VTouchable* postStepTouchable = aStep->GetPostStepPoint()->GetTouchable();
00221         const G4VTouchable* preStepTouchable = aStep->GetPreStepPoint()->GetTouchable();
00222         if (preStepTouchable && postStepTouchable){
00223                 
00224                 G4String post_vol_name = postStepTouchable->GetVolume()->GetName();
00225                 if (post_vol_name =="") post_vol_name = postStepTouchable->GetVolume()->GetLogicalVolume()->GetName();
00226                 G4String pre_vol_name = preStepTouchable->GetVolume()->GetName();
00227                 if (pre_vol_name =="") pre_vol_name = preStepTouchable->GetVolume()->GetLogicalVolume()->GetName();
00228                 
00229                 
00230                 if ( pre_vol_name == vol1_name && post_vol_name == vol2_name){
00231                         GoingIn=true;
00232                         did_cross=true;
00233                 }
00234                 else if (pre_vol_name == vol2_name && post_vol_name == vol1_name){
00235                         GoingIn=false;
00236                         did_cross=true;
00237                 }
00238                 
00239         } 
00240   }
00241   return did_cross;
00242   //still need to compute the cosine of the direction
00243 }
00244 
00246 //   
00247 G4bool G4AdjointCrossSurfChecker::AddaSphericalSurface(const G4String& SurfaceName, G4double radius, G4ThreeVector pos, G4double& Area)
00248 {
00249   G4int ind = FindRegisteredSurface(SurfaceName);
00250   Area= 4.*pi*radius*radius;
00251   if (ind>=0) {
00252         ListOfSurfaceType[ind]="Sphere";
00253         ListOfSphereRadius[ind]=radius;
00254         ListOfSphereCenter[ind]=pos;
00255         ListOfVol1Name[ind]="";
00256         ListOfVol2Name[ind]="";
00257         AreaOfSurface[ind]=Area;
00258   }
00259   else {
00260         ListOfSurfaceName.push_back(SurfaceName);
00261         ListOfSurfaceType.push_back("Sphere");
00262         ListOfSphereRadius.push_back(radius);
00263         ListOfSphereCenter.push_back(pos);
00264         ListOfVol1Name.push_back("");
00265         ListOfVol2Name.push_back("");
00266         AreaOfSurface.push_back(Area);
00267   } 
00268   return true;
00269 }
00271 //   
00272 G4bool G4AdjointCrossSurfChecker::AddaSphericalSurfaceWithCenterAtTheCenterOfAVolume(const G4String& SurfaceName, G4double radius, const G4String& volume_name, G4ThreeVector & center, G4double& area)
00273 { 
00274  
00275   G4VPhysicalVolume*  thePhysicalVolume = 0;
00276   G4PhysicalVolumeStore* thePhysVolStore =G4PhysicalVolumeStore::GetInstance();
00277   for ( unsigned int i=0; i< thePhysVolStore->size();i++){
00278         if ((*thePhysVolStore)[i]->GetName() == volume_name){
00279                 thePhysicalVolume = (*thePhysVolStore)[i];
00280         };
00281         
00282   }
00283   if (thePhysicalVolume){
00284         G4VPhysicalVolume* daughter =thePhysicalVolume;
00285         G4LogicalVolume* mother = thePhysicalVolume->GetMotherLogical();
00286         G4AffineTransform theTransformationFromPhysVolToWorld = G4AffineTransform();
00287         while (mother){
00288                 theTransformationFromPhysVolToWorld *=
00289                 G4AffineTransform(daughter->GetFrameRotation(),daughter->GetObjectTranslation());
00290                 /*G4cout<<"Mother "<<mother->GetName()<<std::endl;
00291                 G4cout<<"Daughter "<<daughter->GetName()<<std::endl;
00292                 G4cout<<daughter->GetObjectTranslation()<<std::endl;
00293                 G4cout<<theTransformationFromPhysVolToWorld.NetTranslation()<<std::endl;*/
00294                 for ( unsigned int i=0; i< thePhysVolStore->size();i++){
00295                         if ((*thePhysVolStore)[i]->GetLogicalVolume() == mother){
00296                                 daughter = (*thePhysVolStore)[i];
00297                                 mother =daughter->GetMotherLogical();
00298                                 break;
00299                         };              
00300                 }
00301         
00302         }
00303         center = theTransformationFromPhysVolToWorld.NetTranslation();
00304         G4cout<<"Center of the spherical surface is at the position: "<<center/cm<<" cm"<<std::endl;
00305         
00306   }
00307   else {
00308         G4cout<<"The physical volume with name "<<volume_name<<" does not exist!!"<<std::endl;
00309         return false;
00310   }
00311   return AddaSphericalSurface(SurfaceName, radius, center, area);
00312 
00313 }
00315 //
00316 G4bool G4AdjointCrossSurfChecker::AddanExtSurfaceOfAvolume(const G4String& SurfaceName, const G4String& volume_name, G4double& Area)
00317 {
00318   G4int ind = FindRegisteredSurface(SurfaceName);
00319 
00320   G4VPhysicalVolume*  thePhysicalVolume = 0;
00321   G4PhysicalVolumeStore* thePhysVolStore =G4PhysicalVolumeStore::GetInstance();
00322   for ( unsigned int i=0; i< thePhysVolStore->size();i++){
00323         if ((*thePhysVolStore)[i]->GetName() == volume_name){
00324                 thePhysicalVolume = (*thePhysVolStore)[i];
00325         };
00326         
00327   }
00328   if (!thePhysicalVolume){
00329         G4cout<<"The physical volume with name "<<volume_name<<" does not exist!!"<<std::endl;
00330         return false;
00331   }     
00332   Area = thePhysicalVolume->GetLogicalVolume()->GetSolid()->GetSurfaceArea();
00333   G4String mother_vol_name = ""; 
00334   G4LogicalVolume* theMother = thePhysicalVolume->GetMotherLogical();
00335  
00336   if (theMother) mother_vol_name= theMother->GetName();
00337   if (ind>=0) {
00338         ListOfSurfaceType[ind]="ExternalSurfaceOfAVolume";
00339         ListOfSphereRadius[ind]=0.;
00340         ListOfSphereCenter[ind]=G4ThreeVector(0.,0.,0.);
00341         ListOfVol1Name[ind]=volume_name;
00342         ListOfVol2Name[ind]=mother_vol_name;
00343         AreaOfSurface[ind]=Area;
00344   }
00345   else {
00346         ListOfSurfaceName.push_back(SurfaceName);
00347         ListOfSurfaceType.push_back("ExternalSurfaceOfAVolume");
00348         ListOfSphereRadius.push_back(0.);
00349         ListOfSphereCenter.push_back(G4ThreeVector(0.,0.,0.));
00350         ListOfVol1Name.push_back(volume_name);
00351         ListOfVol2Name.push_back(mother_vol_name);
00352         AreaOfSurface.push_back(Area);
00353   }
00354   return true;
00355 }
00357 //
00358 G4bool G4AdjointCrossSurfChecker::AddanInterfaceBetweenTwoVolumes(const G4String& SurfaceName, const G4String& volume_name1, const G4String& volume_name2,G4double& Area)
00359 {
00360   G4int ind = FindRegisteredSurface(SurfaceName);
00361   Area=-1.; //the way to compute the surface is not known yet
00362   if (ind>=0) {
00363         ListOfSurfaceType[ind]="BoundaryBetweenTwoVolumes";
00364         ListOfSphereRadius[ind]=0.;
00365         ListOfSphereCenter[ind]=G4ThreeVector(0.,0.,0.);
00366         ListOfVol1Name[ind]=volume_name1;
00367         ListOfVol2Name[ind]=volume_name2;
00368         AreaOfSurface[ind]=Area;
00369         
00370   }
00371   else {
00372         ListOfSurfaceName.push_back(SurfaceName);
00373         ListOfSurfaceType.push_back("BoundaryBetweenTwoVolumes");
00374         ListOfSphereRadius.push_back(0.);
00375         ListOfSphereCenter.push_back(G4ThreeVector(0.,0.,0.));
00376         ListOfVol1Name.push_back(volume_name1);
00377         ListOfVol2Name.push_back(volume_name2);
00378         AreaOfSurface.push_back(Area);
00379   }
00380   return true;
00381 }
00383 //
00384 void G4AdjointCrossSurfChecker::ClearListOfSelectedSurface()
00385 {
00386   ListOfSurfaceName.clear();
00387   ListOfSurfaceType.clear();
00388   ListOfSphereRadius.clear();
00389   ListOfSphereCenter.clear();
00390   ListOfVol1Name.clear();
00391   ListOfVol2Name.clear();
00392 }
00394 //
00395 G4int G4AdjointCrossSurfChecker::FindRegisteredSurface(const G4String& name)
00396 {
00397  G4int ind=-1;
00398  for (size_t i = 0; i<ListOfSurfaceName.size();i++){
00399         if (name == ListOfSurfaceName[i]) {
00400                 ind = int (i);
00401                 return ind;
00402         }
00403  }
00404  return ind;
00405 }
00406 

Generated on Mon May 27 17:47:37 2013 for Geant4 by  doxygen 1.4.7