// // ******************************************************************** // * 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. * // ******************************************************************** // #include #include #include "globals.hh" #include "geomdefs.hh" #include "G4PhysicalConstants.hh" #include "G4SystemOfUnits.hh" #include "G4TwoVector.hh" #include "G4ThreeVector.hh" #include "G4ExtrudedSolid.hh" #include "G4Polyhedra.hh" #include "G4TessellatedSolid.hh" #include "G4TriangularFacet.hh" #include "G4QuadrangularFacet.hh" #include "G4Timer.hh" #include "Randomize.hh" //////////////////////////////////////////////////////////////////////// // // Declare auxiliary routines G4ThreeVector RandomDirection(G4double cosTheta); //////////////////////////////////////////////////////////////////////// // // Declare auxiliary routines G4ThreeVector PointOnPrism(G4int nsect, G4double sphi, G4double dphi, G4double rmax, G4double rmin, G4double dz); G4TessellatedSolid* CreatePrism(G4int nsect, G4double sphi, G4double dphi, G4double rmax, G4double rmin, G4double dz); //////////////////////////////////////////////////////////////////////// // // Declare bench routines void Check_Inside (G4VSolid* t1, const std::vector& pp, G4int NLOOP, EInside in); void Check_SurfaceNormal(G4VSolid* t1, const std::vector& pp, G4int NLOOP); void Check_SafetyToIn (G4VSolid* t1, const std::vector& pp, G4int NLOOP); void Check_SafetyToOut (G4VSolid* t1, const std::vector& pp, G4int NLOOP); void Check_DistanceToIn (G4VSolid* t1, const G4ThreeVector& p, const std::vector& vv, G4int NLOOP); void Check_DistanceToOut(G4VSolid* t1, const std::vector& pp, const std::vector& vv, G4bool calcNorm, G4int NLOOP); //////////////////////////////////////////////////////////////////////// // // Main int main() { G4cout << "*********************************************************************" << G4endl; G4cout << "* *" << G4endl; G4cout << "* This benchmark measures the performance of the navigation methods *" << G4endl; G4cout << "* for concave and convex right prisms defined as G4ExtrudedSolid, *" << G4endl; G4cout << "* G4TesselatedSolid and G4Polyhedra *" << G4endl; G4cout << "* *" << G4endl; G4cout << "* Convex prism Non-convex prism *" << G4endl; G4cout << "* (hexagonal prism) (half of a hollow hexagonal prism) *" << G4endl; G4cout << "* *" << G4endl; G4cout << "* . . *" << G4endl; G4cout << "* ....... ...| *" << G4endl; G4cout << "* ............. ......| *" << G4endl; G4cout << "* |...............| |...... *" << G4endl; G4cout << "* |...............| |...| *" << G4endl; G4cout << "* |...............| |...| *" << G4endl; G4cout << "* |...............| |...... *" << G4endl; G4cout << "* ............. .....| *" << G4endl; G4cout << "* ....... ...| *" << G4endl; G4cout << "* . . *" << G4endl; G4cout << "* *" << G4endl; G4cout << "*********************************************************************" << G4endl; // Set number of calls G4int NLOOP = 1000000; G4int NMIL = NLOOP/1000000; G4cout << "\n Number of calls : "<< NMIL << " 000 000" << G4endl; // Select solids to test: 0 - omit, 1 - test G4int ifxtru1 = 1, iftess1 = 1, ifpoly1 = 1; // convex prisms G4int ifxtru2 = 1, iftess2 = 1, ifpoly2 = 1; // non-convex prisms // Define number of random points const G4int NP = 100000; // Set auxiliary coeffifients G4double ksur = 1e-12, kin = 0.5, kout = 2.; // Generate random points for convex (hexagonal) prism G4int nsect1; G4double sphi1,dphi1,rmax1,rmin1,dz1; std::vector prism1_Surface(NP); std::vector prism1_Inside(NP); std::vector prism1_Outside(NP); for (G4int i=0; i prism2_Surface(NP); std::vector prism2_Inside(NP); std::vector prism2_Outside(NP); for (G4int i=0; i polygon1(nsect1); G4double ang1 = dphi1/nsect1; for (G4int i=0; i polygon2(nvert); G4double ang2 = dphi2/nsect2; for (G4int i=0; i vecInCone(NP); std::vector vecOnSphere(NP); for (int i=0; iGetPointOnSurface()*(1.0 + k*ksur); if (poly2->Inside(p) != kSurface) G4cout << "==== POINT is not on surface !!! " << G4endl; for (G4int j=0; j<1000; ++j) { G4ThreeVector v = RandomDirection(-1); G4double dxtru = xtru2->DistanceToIn(p,v); G4double dtess = tess2->DistanceToIn(p,v); G4double dpoly = poly2->DistanceToIn(p,v); /* if (std::abs(dpoly-dtess) > ERR) G4cout << "=== DistTo IN : poly - tess : " << dpoly << " , " << dtess << " , " << std::abs(dpoly-dtess) << G4endl; if (std::abs(dpoly-dxtru) > ERR) G4cout << "=== DistTo IN : poly - xtru : " << dpoly << " , " << dxtru << " , " << std::abs(dpoly-dxtru) << " p,v = " << p << v << G4endl; */ dxtru = xtru2->DistanceToOut(p,v); dtess = tess2->DistanceToOut(p,v); dpoly = poly2->DistanceToOut(p,v); /* if (std::abs(dpoly-dtess) > ERR) G4cout << "=== DistTo OUT : poly - tess : " << dpoly << " , " << dtess << " , " << std::abs(dpoly-dtess) << G4endl; if (std::abs(dpoly-dxtru) > ERR) G4cout << "=== DistTo OUT : poly - xtru : " << dpoly << " , " << dxtru << " , " << std::abs(dpoly-dxtru) << G4endl; */ } } G4cout << "================ END Test on Consistency" << G4endl; // Mesure time of Inside(p) // G4cout << "\n Inside(p)\n" << G4endl; if (ifxtru1) { G4cout << "****** Time test for G4ExtrudedSolid::Inside(p) - Convex prism ******" << G4endl; G4cout << " Points Inside "; Check_Inside(xtru1, prism1_Inside, NLOOP, kInside); G4cout << " Points on Surface "; Check_Inside(xtru1, prism1_Surface, NLOOP, kSurface); G4cout << " Points Outside "; Check_Inside(xtru1, prism1_Outside, NLOOP, kOutside); } if (iftess1) { G4cout << "****** Time test for G4TessellatedSolid::Inside(p) - Convex prism ******" << G4endl; G4cout << " Points Inside "; Check_Inside(tess1, prism1_Inside, NLOOP, kInside); G4cout << " Points on Surface "; Check_Inside(tess1, prism1_Surface, NLOOP, kSurface); G4cout << " Points Outside "; Check_Inside(tess1, prism1_Outside, NLOOP, kOutside); } if (ifpoly1) { G4cout << "****** Time test for G4Polyhedra::Inside(p) - Convex prism ******" << G4endl; G4cout << " Points Inside "; Check_Inside(poly1, prism1_Inside, NLOOP, kInside); G4cout << " Points on Surface "; Check_Inside(poly1, prism1_Surface, NLOOP, kSurface); G4cout << " Points Outside "; Check_Inside(poly1, prism1_Outside, NLOOP, kOutside); } G4cout << G4endl; if (ifxtru2) { G4cout << "****** Time test for G4ExtrudedSolid::Inside(p) - Non-convex prism ******" << G4endl; G4cout << " Points Inside "; Check_Inside(xtru2, prism2_Inside, NLOOP, kInside); G4cout << " Points on Surface "; Check_Inside(xtru2, prism2_Surface, NLOOP, kSurface); G4cout << " Points Outside "; Check_Inside(xtru2, prism2_Outside, NLOOP, kOutside); } if (iftess2) { G4cout << "****** Time test for G4TessellatedSolid::Inside(p) - Non-convex prism ******" << G4endl; G4cout << " Points Inside "; Check_Inside(tess2, prism2_Inside, NLOOP, kInside); G4cout << " Points on Surface "; Check_Inside(tess2, prism2_Surface, NLOOP, kSurface); G4cout << " Points Outside "; Check_Inside(tess2, prism2_Outside, NLOOP, kOutside); } if (ifpoly2) { G4cout << "****** Time test for G4Polyhedra::Inside(p) - Non-convex prism ******" << G4endl; G4cout << " Points Inside "; Check_Inside(poly2, prism2_Inside, NLOOP, kInside); G4cout << " Points on Surface "; Check_Inside(poly2, prism2_Surface, NLOOP, kSurface); G4cout << " Points Outside "; Check_Inside(poly2, prism2_Outside, NLOOP, kOutside); } // Mesure time of SurfaceNormal(p) // G4cout << "\n SurfaceNormal(p)\n" << G4endl; if (ifxtru1) { G4cout << "****** Time test for G4ExtrudedSolid::SurfaceNormal(p) - Convex prism ******" << G4endl; G4cout << " Points on Surface "; Check_SurfaceNormal(xtru1, prism1_Surface, NLOOP); } if (iftess1) { G4cout << "****** Time test for G4TessellatedSolid::SurfaceNormal(p) - Convex prism ******" << G4endl; G4cout << " Points on Surface "; Check_SurfaceNormal(tess1, prism1_Surface, NLOOP); } if (ifpoly1) { G4cout << "****** Time test for G4Polyhedra::SurfaceNormal(p) - Convex prism ******" << G4endl; G4cout << " Points on Surface "; Check_SurfaceNormal(poly1, prism1_Surface, NLOOP); } G4cout << G4endl; if (ifxtru2) { G4cout << "****** Time test for G4ExtrudedSolid::SurfaceNormal(p) - Non-convex prism ******" << G4endl; G4cout << " Points on Surface "; Check_SurfaceNormal(xtru2, prism2_Surface, NLOOP); } if (iftess2) { G4cout << "****** Time test for G4TessellatedSolid::SurfaceNormal(p) - Non-convex prism ******" << G4endl; G4cout << " Points on Surface "; Check_SurfaceNormal(tess2, prism2_Surface, NLOOP); } if (ifpoly2) { G4cout << "****** Time test for G4Polyhedra::SurfaceNormal(p) - Non-convex prism ******" << G4endl; G4cout << " Points on Surface "; Check_SurfaceNormal(poly2, prism2_Surface, NLOOP); } // Mesure time of DistanceToIn(p) // G4cout << "\n SafetyToIn(p)\n" << G4endl; if (ifxtru1) { G4cout << "****** Time test for G4ExtrudedSolid::DistanceToIn(p) - Convex prism ******" << G4endl; G4cout << " Points on Surface "; Check_SafetyToIn(xtru1, prism1_Surface, NLOOP); G4cout << " Points Outside "; Check_SafetyToIn(xtru1, prism1_Outside, NLOOP); } if (iftess1) { G4cout << "****** Time test for G4TessellatedSolid::DistanceToIn(p) - Convex prism ******" << G4endl; G4cout << " Points on Surface "; Check_SafetyToIn(tess1, prism1_Surface, NLOOP); G4cout << " Points Outside "; Check_SafetyToIn(tess1, prism1_Outside, NLOOP); } if (ifpoly1) { G4cout << "****** Time test for G4Polyhedra::DistanceToIn(p) - Convex prism ******" << G4endl; G4cout << " Points on Surface "; Check_SafetyToIn(poly1, prism1_Surface, NLOOP); G4cout << " Points Outside "; Check_SafetyToIn(poly1, prism1_Outside, NLOOP); } G4cout << G4endl; if (ifxtru2) { G4cout << "****** Time test for G4ExtrudedSolid::DistanceToIn(p) - Non-convex prism ******" << G4endl; G4cout << " Points on Surface "; Check_SafetyToIn(xtru2, prism2_Surface, NLOOP); G4cout << " Points Outside "; Check_SafetyToIn(xtru2, prism2_Outside, NLOOP); } if (iftess2) { G4cout << "****** Time test for G4TessellatedSolid::DistanceToIn(p) - Non-convex prism ******" << G4endl; G4cout << " Points on Surface "; Check_SafetyToIn(tess2, prism2_Surface, NLOOP); G4cout << " Points Outside "; Check_SafetyToIn(tess2, prism2_Outside, NLOOP); } if (ifpoly2) { G4cout << "****** Time test for G4Polyhedra::DistanceToIn(p) - Non-convex prism ******" << G4endl; G4cout << " Points on Surface "; Check_SafetyToIn(poly2, prism2_Surface, NLOOP); G4cout << " Points Outside "; Check_SafetyToIn(poly2, prism2_Outside, NLOOP); } // Mesure time of DistanceToOut(p) // G4cout << "\n SafetyToOut(p)\n" << G4endl; if (ifxtru1) { G4cout << "****** Time test for G4ExtrudedSolid::DistanceToOut(p) - Convex prism ******" << G4endl; G4cout << " Points Inside "; Check_SafetyToOut(xtru1, prism1_Inside, NLOOP); G4cout << " Points on Surface "; Check_SafetyToOut(xtru1, prism1_Surface, NLOOP); } if (iftess1) { G4cout << "****** Time test for G4TessellatedSolid::DistanceToOut(p) - Convex prism ******" << G4endl; G4cout << " Points Inside "; Check_SafetyToOut(tess1, prism1_Inside, NLOOP); G4cout << " Points on Surface "; Check_SafetyToOut(tess1, prism1_Surface, NLOOP); } if (ifpoly1) { G4cout << "****** Time test for G4Polyhedra::DistanceToOut(p) - Convex prism ******" << G4endl; G4cout << " Points Inside "; Check_SafetyToOut(poly1, prism1_Inside, NLOOP); G4cout << " Points on Surface "; Check_SafetyToOut(poly1, prism1_Surface, NLOOP); } G4cout << G4endl; if (ifxtru2) { G4cout << "****** Time test for G4ExtrudedSolid::DistanceToOut(p) - Non-convex prism ******" << G4endl; G4cout << " Points Inside "; Check_SafetyToOut(xtru2, prism2_Inside, NLOOP); G4cout << " Points on Surface "; Check_SafetyToOut(xtru2, prism2_Surface, NLOOP); } if (iftess2) { G4cout << "****** Time test for G4TessellatedSolid::DistanceToOut(p) - Non-convex prism ******" << G4endl; G4cout << " Points Inside "; Check_SafetyToOut(tess2, prism2_Inside, NLOOP); G4cout << " Points on Surface "; Check_SafetyToOut(tess2, prism2_Surface, NLOOP); } if (ifpoly2) { G4cout << "****** Time test for G4Polyhedra::DistanceToOut(p) - Non-convex prism ******" << G4endl; G4cout << " Points Inside "; Check_SafetyToOut(poly2, prism2_Inside, NLOOP); G4cout << " Points on Surface "; Check_SafetyToOut(poly2, prism2_Surface, NLOOP); } // Mesure time of DistanceToIn(p,v) // G4cout << "\n DistanceToIn(p,v)\n" << G4endl; if (ifxtru1) { G4cout << "****** Time test for G4ExtrudedSolid::DistanceToIn(p,v) - Convex prism ******" << G4endl; G4cout << " DistanceToIn "; Check_DistanceToIn(xtru1, p1, vecInCone, NLOOP); } if (iftess1) { G4cout << "****** Time test for G4TessellatedSolid::DistanceToIn(p,v) - Convex prism ******" << G4endl; G4cout << " DistanceToIn "; Check_DistanceToIn(tess1, p1, vecInCone, NLOOP); } if (ifpoly1) { G4cout << "****** Time test for G4Polyhedra::DistanceToIn(p,v) - Convex prism ******" << G4endl; G4cout << " DistanceToIn "; Check_DistanceToIn(poly1, p1, vecInCone, NLOOP); } G4cout << G4endl; if (ifxtru2) { G4cout << "****** Time test for G4ExtrudedSolid::DistanceToIn(p,v) - Non-convex prism ******" << G4endl; G4cout << " DistanceToIn "; Check_DistanceToIn(xtru2, p2, vecInCone, NLOOP); } if (iftess2) { G4cout << "****** Time test for G4TessellatedSolid::DistanceToIn(p,v) - Non-convex prism ******" << G4endl; G4cout << " DistanceToIn "; Check_DistanceToIn(tess2, p2, vecInCone, NLOOP); } if (ifpoly2) { G4cout << "****** Time test for G4Polyhedra::DistanceToIn(p,v) - Non-convex prism ******" << G4endl; G4cout << " DistanceToIn "; Check_DistanceToIn(poly2, p2, vecInCone, NLOOP); } // Mesure time of DistanceToOut(p,v) without calculation of Normal // G4cout << "\n DistanceToOut(p,v) without calculation of Normal\n" << G4endl; if (ifxtru1) { G4cout << "****** Time test for G4ExtrudedSolid::DistanceToOut(p,v) - Convex prism ******" << G4endl; G4cout << " Points Inside "; Check_DistanceToOut(xtru1, prism1_Inside, vecOnSphere, false, NLOOP); G4cout << " Points on Surface "; Check_DistanceToOut(xtru1, prism1_Surface, vecOnSphere, false, NLOOP); } if (iftess1) { G4cout << "****** Time test for G4TessellatedSolid::DistanceToOut(p,v) - Convex prism ******" << G4endl; G4cout << " Points Inside "; Check_DistanceToOut(tess1, prism1_Inside, vecOnSphere, false, NLOOP); G4cout << " Points on Surface "; Check_DistanceToOut(tess1, prism1_Surface, vecOnSphere, false, NLOOP); } if (ifpoly1) { G4cout << "****** Time test for G4Polyhedra::DistanceToOut(p,v) - Convex prism ******" << G4endl; G4cout << " Points Inside "; Check_DistanceToOut(poly1, prism1_Inside, vecOnSphere, false, NLOOP); G4cout << " Points on Surface "; Check_DistanceToOut(poly1, prism1_Surface, vecOnSphere, false, NLOOP); } G4cout << G4endl; if (ifxtru2) { G4cout << "****** Time test for G4ExtrudedSolid::DistanceToOut(p,v) - Non-convex prism ******" << G4endl; G4cout << " Points Inside "; Check_DistanceToOut(xtru2, prism2_Inside, vecOnSphere, false, NLOOP); G4cout << " Points on Surface "; Check_DistanceToOut(xtru2, prism2_Surface, vecOnSphere, false, NLOOP); } if (iftess2) { G4cout << "****** Time test for G4TessellatedSolid::DistanceToOut(p,v) - Non-convex prism ******" << G4endl; G4cout << " Points Inside "; Check_DistanceToOut(tess2, prism2_Inside, vecOnSphere, false, NLOOP); G4cout << " Points on Surface "; Check_DistanceToOut(tess2, prism2_Surface, vecOnSphere, false, NLOOP); } if (ifpoly2) { G4cout << "****** Time test for G4Polyhedra::DistanceToOut(p,v) - Non-convex prism ******" << G4endl; G4cout << " Points Inside "; Check_DistanceToOut(poly2, prism2_Inside, vecOnSphere, false, NLOOP); G4cout << " Points on Surface "; Check_DistanceToOut(poly2, prism2_Surface, vecOnSphere, false, NLOOP); } // Mesure time of DistanceToOut(p,v) with calculation of Normal // G4cout << "\n DistanceToOut(p,v) with calculation of Normal\n" << G4endl; if (ifxtru1) { G4cout << "****** Time test for G4ExtrudedSolid::DistanceToOut(p,v) - Convex prism ******" << G4endl; G4cout << " Points Inside "; Check_DistanceToOut(xtru1, prism1_Inside, vecOnSphere, true, NLOOP); G4cout << " Points on Surface "; Check_DistanceToOut(xtru1, prism1_Surface, vecOnSphere, true, NLOOP); } if (iftess1) { G4cout << "****** Time test for G4TessellatedSolid::DistanceToOut(p,v) - Convex prism ******" << G4endl; G4cout << " Points Inside "; Check_DistanceToOut(tess1, prism1_Inside, vecOnSphere, true, NLOOP); G4cout << " Points on Surface "; Check_DistanceToOut(tess1, prism1_Surface, vecOnSphere, true, NLOOP); } if (ifpoly1) { G4cout << "****** Time test for G4Polyhedra::DistanceToOut(p,v) - Convex prism ******" << G4endl; G4cout << " Points Inside "; Check_DistanceToOut(poly1, prism1_Inside, vecOnSphere, true, NLOOP); G4cout << " Points on Surface "; Check_DistanceToOut(poly1, prism1_Surface, vecOnSphere, true, NLOOP); } G4cout << G4endl; if (ifxtru2) { G4cout << "****** Time test for G4ExtrudedSolid::DistanceToOut(p,v) - Non-convex prism ******" << G4endl; G4cout << " Points Inside "; Check_DistanceToOut(xtru2, prism2_Inside, vecOnSphere, true, NLOOP); G4cout << " Points on Surface "; Check_DistanceToOut(xtru2, prism2_Surface, vecOnSphere, true, NLOOP); } if (iftess2) { G4cout << "****** Time test for G4TessellatedSolid::DistanceToOut(p,v) - Non-convex prism ******" << G4endl; G4cout << " Points Inside "; Check_DistanceToOut(tess2, prism2_Inside, vecOnSphere, true, NLOOP); G4cout << " Points on Surface "; Check_DistanceToOut(tess2, prism2_Surface, vecOnSphere, true, NLOOP); } if (ifpoly2) { G4cout << "****** Time test for G4Polyhedra::DistanceToOut(p,v) - Non-convex prism ******" << G4endl; G4cout << " Points Inside "; Check_DistanceToOut(poly2, prism2_Inside, vecOnSphere, true, NLOOP); G4cout << " Points on Surface "; Check_DistanceToOut(poly2, prism2_Surface, vecOnSphere, true, NLOOP); } return 0; } //////////////////////////////////////////////////////////////////////// // // Check Inside void Check_Inside(G4VSolid* t1, const std::vector& pp, G4int NLOOP, EInside in) { G4Timer time; clock_t t; G4int NP = pp.size(); // Check points // t = clock(); //time.Start(); G4int n = 0, k = 0; for(int i=0; i<(NLOOP/20); ++i) { if (t1->Inside(pp[k++]) != in) { ++n; } if (t1->Inside(pp[k++]) != in) { ++n; } if (t1->Inside(pp[k++]) != in) { ++n; } if (t1->Inside(pp[k++]) != in) { ++n; } if (t1->Inside(pp[k++]) != in) { ++n; } if (t1->Inside(pp[k++]) != in) { ++n; } if (t1->Inside(pp[k++]) != in) { ++n; } if (t1->Inside(pp[k++]) != in) { ++n; } if (t1->Inside(pp[k++]) != in) { ++n; } if (t1->Inside(pp[k++]) != in) { ++n; } if (k >= NP) k = 0; if (t1->Inside(pp[k++]) != in) { ++n; } if (t1->Inside(pp[k++]) != in) { ++n; } if (t1->Inside(pp[k++]) != in) { ++n; } if (t1->Inside(pp[k++]) != in) { ++n; } if (t1->Inside(pp[k++]) != in) { ++n; } if (t1->Inside(pp[k++]) != in) { ++n; } if (t1->Inside(pp[k++]) != in) { ++n; } if (t1->Inside(pp[k++]) != in) { ++n; } if (t1->Inside(pp[k++]) != in) { ++n; } if (t1->Inside(pp[k++]) != in) { ++n; } if (k >= NP) k = 0; } t = clock() - t; G4cout <<" "<< n <<" inconsistencies"; G4cout <<" Time: "<< (double)t/CLOCKS_PER_SEC << " sec" << G4endl; } //////////////////////////////////////////////////////////////////////// // // Check SurfaceNormal(p) void Check_SurfaceNormal(G4VSolid* t1, const std::vector& pp, G4int NLOOP) { G4Timer time; clock_t t; G4int NP = pp.size(); // Check points // G4ThreeVector norm[20]; t = clock(); //time.Start(); G4int k = 0; for(int i=0; i<(NLOOP/20); i++) { norm[0] = t1->SurfaceNormal(pp[k++]); norm[1] = t1->SurfaceNormal(pp[k++]); norm[2] = t1->SurfaceNormal(pp[k++]); norm[3] = t1->SurfaceNormal(pp[k++]); norm[4] = t1->SurfaceNormal(pp[k++]); norm[5] = t1->SurfaceNormal(pp[k++]); norm[6] = t1->SurfaceNormal(pp[k++]); norm[7] = t1->SurfaceNormal(pp[k++]); norm[8] = t1->SurfaceNormal(pp[k++]); norm[9] = t1->SurfaceNormal(pp[k++]); if (k >= NP) k = 0; norm[10] = t1->SurfaceNormal(pp[k++]); norm[11] = t1->SurfaceNormal(pp[k++]); norm[12] = t1->SurfaceNormal(pp[k++]); norm[13] = t1->SurfaceNormal(pp[k++]); norm[14] = t1->SurfaceNormal(pp[k++]); norm[15] = t1->SurfaceNormal(pp[k++]); norm[16] = t1->SurfaceNormal(pp[k++]); norm[17] = t1->SurfaceNormal(pp[k++]); norm[18] = t1->SurfaceNormal(pp[k++]); norm[19] = t1->SurfaceNormal(pp[k++]); if (k >= NP) k = 0; } t = clock() - t; //time.Stop(); G4cout <<" "; G4cout <<" Time: "<< (double)t/CLOCKS_PER_SEC << " sec" << G4endl; } //////////////////////////////////////////////////////////////////////// // // Check DistanceToIn(p) void Check_SafetyToIn(G4VSolid* t1, const std::vector& pp,G4int NLOOP) { G4Timer time; clock_t t; G4int NP = pp.size(); // Check points // t = clock(); //time.Start(); G4int n = 0, k = 0; for(int i=0; i<(NLOOP/20); ++i) { if (t1->DistanceToIn(pp[k++]) < 0) { ++n; } if (t1->DistanceToIn(pp[k++]) < 0) { ++n; } if (t1->DistanceToIn(pp[k++]) < 0) { ++n; } if (t1->DistanceToIn(pp[k++]) < 0) { ++n; } if (t1->DistanceToIn(pp[k++]) < 0) { ++n; } if (t1->DistanceToIn(pp[k++]) < 0) { ++n; } if (t1->DistanceToIn(pp[k++]) < 0) { ++n; } if (t1->DistanceToIn(pp[k++]) < 0) { ++n; } if (t1->DistanceToIn(pp[k++]) < 0) { ++n; } if (t1->DistanceToIn(pp[k++]) < 0) { ++n; } if (k >= NP) k = 0; if (t1->DistanceToIn(pp[k++]) < 0) { ++n; } if (t1->DistanceToIn(pp[k++]) < 0) { ++n; } if (t1->DistanceToIn(pp[k++]) < 0) { ++n; } if (t1->DistanceToIn(pp[k++]) < 0) { ++n; } if (t1->DistanceToIn(pp[k++]) < 0) { ++n; } if (t1->DistanceToIn(pp[k++]) < 0) { ++n; } if (t1->DistanceToIn(pp[k++]) < 0) { ++n; } if (t1->DistanceToIn(pp[k++]) < 0) { ++n; } if (t1->DistanceToIn(pp[k++]) < 0) { ++n; } if (t1->DistanceToIn(pp[k++]) < 0) { ++n; } if (k >= NP) k = 0; } t = clock() - t; //time.Stop(); G4cout <<" "<< n <<" negative distances"; G4cout <<" Time: "<< (double)t/CLOCKS_PER_SEC << " sec" << G4endl; } //////////////////////////////////////////////////////////////////////// // // Check SafetyToOut(p) void Check_SafetyToOut(G4VSolid* t1, const std::vector& pp, G4int NLOOP) { G4Timer time; clock_t t; G4int NP = pp.size(); // Check points // t = clock(); //time.Start(); G4int n = 0, k = 0; for(int i=0; i<(NLOOP/20); i++) { if (t1->DistanceToOut(pp[k++]) < 0) { ++n; } if (t1->DistanceToOut(pp[k++]) < 0) { ++n; } if (t1->DistanceToOut(pp[k++]) < 0) { ++n; } if (t1->DistanceToOut(pp[k++]) < 0) { ++n; } if (t1->DistanceToOut(pp[k++]) < 0) { ++n; } if (t1->DistanceToOut(pp[k++]) < 0) { ++n; } if (t1->DistanceToOut(pp[k++]) < 0) { ++n; } if (t1->DistanceToOut(pp[k++]) < 0) { ++n; } if (t1->DistanceToOut(pp[k++]) < 0) { ++n; } if (t1->DistanceToOut(pp[k++]) < 0) { ++n; } if (k >= NP) k = 0; if (t1->DistanceToOut(pp[k++]) < 0) { ++n; } if (t1->DistanceToOut(pp[k++]) < 0) { ++n; } if (t1->DistanceToOut(pp[k++]) < 0) { ++n; } if (t1->DistanceToOut(pp[k++]) < 0) { ++n; } if (t1->DistanceToOut(pp[k++]) < 0) { ++n; } if (t1->DistanceToOut(pp[k++]) < 0) { ++n; } if (t1->DistanceToOut(pp[k++]) < 0) { ++n; } if (t1->DistanceToOut(pp[k++]) < 0) { ++n; } if (t1->DistanceToOut(pp[k++]) < 0) { ++n; } if (t1->DistanceToOut(pp[k++]) < 0) { ++n; } if (k >= NP) k = 0; } t = clock() - t; //time.Stop(); G4cout <<" "<< n <<" negative distances"; G4cout <<" Time: "<< (double)t/CLOCKS_PER_SEC << " sec" << G4endl; } //////////////////////////////////////////////////////////////////////// // // Check DistanceToIn(p,v) void Check_DistanceToIn(G4VSolid* t1, const G4ThreeVector& p, const std::vector& v, G4int NLOOP) { G4Timer time; clock_t t; G4int NP = v.size(); t = clock(); //time.Start(); G4int n = 0, k = 0; for(int i=0; i<(NLOOP/20); i++) { if (t1->DistanceToIn(p,v[k++]) == kInfinity) { ++n; } if (t1->DistanceToIn(p,v[k++]) == kInfinity) { ++n; } if (t1->DistanceToIn(p,v[k++]) == kInfinity) { ++n; } if (t1->DistanceToIn(p,v[k++]) == kInfinity) { ++n; } if (t1->DistanceToIn(p,v[k++]) == kInfinity) { ++n; } if (t1->DistanceToIn(p,v[k++]) == kInfinity) { ++n; } if (t1->DistanceToIn(p,v[k++]) == kInfinity) { ++n; } if (t1->DistanceToIn(p,v[k++]) == kInfinity) { ++n; } if (t1->DistanceToIn(p,v[k++]) == kInfinity) { ++n; } if (t1->DistanceToIn(p,v[k++]) == kInfinity) { ++n; } if (k >= NP) k = 0; if (t1->DistanceToIn(p,v[k++]) == kInfinity) { ++n; } if (t1->DistanceToIn(p,v[k++]) == kInfinity) { ++n; } if (t1->DistanceToIn(p,v[k++]) == kInfinity) { ++n; } if (t1->DistanceToIn(p,v[k++]) == kInfinity) { ++n; } if (t1->DistanceToIn(p,v[k++]) == kInfinity) { ++n; } if (t1->DistanceToIn(p,v[k++]) == kInfinity) { ++n; } if (t1->DistanceToIn(p,v[k++]) == kInfinity) { ++n; } if (t1->DistanceToIn(p,v[k++]) == kInfinity) { ++n; } if (t1->DistanceToIn(p,v[k++]) == kInfinity) { ++n; } if (t1->DistanceToIn(p,v[k++]) == kInfinity) { ++n; } if (k >= NP) k = 0; } t = clock() - t; //time.Stop(); G4cout <<" "<< n <<" kInfinity (no hit)"; G4cout <<" Time: "<< (double)t/CLOCKS_PER_SEC << " sec" << G4endl; } //////////////////////////////////////////////////////////////////////// // // Check DistanceToOut(p,v) void Check_DistanceToOut(G4VSolid* t1, const std::vector& p, const std::vector& vv, G4bool calcNorm, G4int NLOOP) { G4Timer time; clock_t t; G4int NP = p.size(); std::vector v(NP); for (G4int i=0; iDistanceToOut(p[k],v[k],true,&trueNorm,&norm) == 0) { ++n; }; ++k; if (trueNorm) ++ntrue; if (t1->DistanceToOut(p[k],v[k],true,&trueNorm,&norm) == 0) { ++n; }; ++k; if (trueNorm) ++ntrue; if (t1->DistanceToOut(p[k],v[k],true,&trueNorm,&norm) == 0) { ++n; }; ++k; if (trueNorm) ++ntrue; if (t1->DistanceToOut(p[k],v[k],true,&trueNorm,&norm) == 0) { ++n; }; ++k; if (trueNorm) ++ntrue; if (t1->DistanceToOut(p[k],v[k],true,&trueNorm,&norm) == 0) { ++n; }; ++k; if (trueNorm) ++ntrue; if (t1->DistanceToOut(p[k],v[k],true,&trueNorm,&norm) == 0) { ++n; }; ++k; if (trueNorm) ++ntrue; if (t1->DistanceToOut(p[k],v[k],true,&trueNorm,&norm) == 0) { ++n; }; ++k; if (trueNorm) ++ntrue; if (t1->DistanceToOut(p[k],v[k],true,&trueNorm,&norm) == 0) { ++n; }; ++k; if (trueNorm) ++ntrue; if (t1->DistanceToOut(p[k],v[k],true,&trueNorm,&norm) == 0) { ++n; }; ++k; if (trueNorm) ++ntrue; if (t1->DistanceToOut(p[k],v[k],true,&trueNorm,&norm) == 0) { ++n; }; ++k; if (trueNorm) ++ntrue; if (k >= NP) k = 0; if (t1->DistanceToOut(p[k],v[k],true,&trueNorm,&norm) == 0) { ++n; }; ++k; if (trueNorm) ++ntrue; if (t1->DistanceToOut(p[k],v[k],true,&trueNorm,&norm) == 0) { ++n; }; ++k; if (trueNorm) ++ntrue; if (t1->DistanceToOut(p[k],v[k],true,&trueNorm,&norm) == 0) { ++n; }; ++k; if (trueNorm) ++ntrue; if (t1->DistanceToOut(p[k],v[k],true,&trueNorm,&norm) == 0) { ++n; }; ++k; if (trueNorm) ++ntrue; if (t1->DistanceToOut(p[k],v[k],true,&trueNorm,&norm) == 0) { ++n; }; ++k; if (trueNorm) ++ntrue; if (t1->DistanceToOut(p[k],v[k],true,&trueNorm,&norm) == 0) { ++n; }; ++k; if (trueNorm) ++ntrue; if (t1->DistanceToOut(p[k],v[k],true,&trueNorm,&norm) == 0) { ++n; }; ++k; if (trueNorm) ++ntrue; if (t1->DistanceToOut(p[k],v[k],true,&trueNorm,&norm) == 0) { ++n; }; ++k; if (trueNorm) ++ntrue; if (t1->DistanceToOut(p[k],v[k],true,&trueNorm,&norm) == 0) { ++n; }; ++k; if (trueNorm) ++ntrue; if (t1->DistanceToOut(p[k],v[k],true,&trueNorm,&norm) == 0) { ++n; }; ++k; if (trueNorm) ++ntrue; if (k >= NP) k = 0; } t = clock() - t; //time.Stop(); } else { t = clock(); //time.Start(); for(int i=0; i<(NLOOP/20); i++) { if (t1->DistanceToOut(p[k],v[k]) == 0) { ++n; }; ++k; if (t1->DistanceToOut(p[k],v[k]) == 0) { ++n; }; ++k; if (t1->DistanceToOut(p[k],v[k]) == 0) { ++n; }; ++k; if (t1->DistanceToOut(p[k],v[k]) == 0) { ++n; }; ++k; if (t1->DistanceToOut(p[k],v[k]) == 0) { ++n; }; ++k; if (t1->DistanceToOut(p[k],v[k]) == 0) { ++n; }; ++k; if (t1->DistanceToOut(p[k],v[k]) == 0) { ++n; }; ++k; if (t1->DistanceToOut(p[k],v[k]) == 0) { ++n; }; ++k; if (t1->DistanceToOut(p[k],v[k]) == 0) { ++n; }; ++k; if (t1->DistanceToOut(p[k],v[k]) == 0) { ++n; }; ++k; if (k >= NP) k = 0; if (t1->DistanceToOut(p[k],v[k]) == 0) { ++n; }; ++k; if (t1->DistanceToOut(p[k],v[k]) == 0) { ++n; }; ++k; if (t1->DistanceToOut(p[k],v[k]) == 0) { ++n; }; ++k; if (t1->DistanceToOut(p[k],v[k]) == 0) { ++n; }; ++k; if (t1->DistanceToOut(p[k],v[k]) == 0) { ++n; }; ++k; if (t1->DistanceToOut(p[k],v[k]) == 0) { ++n; }; ++k; if (t1->DistanceToOut(p[k],v[k]) == 0) { ++n; }; ++k; if (t1->DistanceToOut(p[k],v[k]) == 0) { ++n; }; ++k; if (t1->DistanceToOut(p[k],v[k]) == 0) { ++n; }; ++k; if (t1->DistanceToOut(p[k],v[k]) == 0) { ++n; }; ++k; if (k >= NP) k = 0; } t = clock() - t; //time.Stop(); } G4cout <<" "<< n <<" zero distances" << "; trueNorm = "<< ntrue; G4cout <<" Time: "<< (double)t/CLOCKS_PER_SEC << " sec" << G4endl; } //////////////////////////////////////////////////////////////////////// // // Generate random unit vector within cone G4ThreeVector RandomDirection(G4double cosTheta) { G4double z = (1. - cosTheta)*G4UniformRand() + cosTheta; G4double rho = std::sqrt((1.+z)*(1.-z)); G4double phi = CLHEP::twopi*G4UniformRand(); return G4ThreeVector(rho*std::cos(phi), rho*std::sin(phi), z); } //////////////////////////////////////////////////////////////////////// // // Generate random point on the surface of a right prism G4ThreeVector PointOnPrism(G4int nsect, G4double sphi, G4double dphi, G4double rmax, G4double rmin, G4double dz) { // Set vertices // std::vector baseRmaxA; std::vector baseRminA; std::vector baseRmaxB; std::vector baseRminB; G4double ang = dphi/nsect; for (G4int i=0; i s1) p0 = p2; G4double u = G4UniformRand(); G4double v = G4UniformRand(); if (u + v > 1.) { u = 1. - u; v = 1. - v; } p = (1.-u-v)*p0 + u*p1 + v*p3; break; } case 3: // base at +dz { G4double s1 = lmin*(hmax-hmin); G4double s2 = lmax*(hmax-hmin); G4int i = nsect*G4UniformRand(); G4ThreeVector p0 = baseRminB[i]; G4ThreeVector p1 = baseRminB[i+1]; G4ThreeVector p2 = baseRmaxB[i+1]; G4ThreeVector p3 = baseRmaxB[i]; if ((s1+s2)*G4UniformRand() > s1) p0 = p2; G4double u = G4UniformRand(); G4double v = G4UniformRand(); if (u + v > 1.) { u = 1. - u; v = 1. - v; } p = (1.-u-v)*p0 + u*p1 + v*p3; break; } case 4: // surface at phi cut { if (G4UniformRand() < 0.5) { G4ThreeVector v1 = baseRmaxA[0] - baseRminA[0]; G4ThreeVector v2(0,0,2*dz); p = baseRminA[0] + v1*G4UniformRand() + v2*G4UniformRand(); } else { G4ThreeVector v1 = baseRmaxA[nsect] - baseRminA[nsect]; G4ThreeVector v2(0,0,2*dz); p = baseRminA[nsect] + v1*G4UniformRand() + v2*G4UniformRand(); } break; } } return p; } //////////////////////////////////////////////////////////////////////// // // Create tesselated solid for regular right prism G4TessellatedSolid* CreatePrism(G4int nsect, G4double sphi, G4double dphi, G4double rmax, G4double rmin, G4double dz) { // Set vertices // std::vector baseRmaxA; std::vector baseRminA; std::vector baseRmaxB; std::vector baseRminB; G4double ang = dphi/nsect; for (G4int i=0; i faces; for (G4int i=0; i 0) { faces.push_back(new G4TriangularFacet(baseRminA[i],baseRminA[i+1],baseRmaxA[i+1],ABSOLUTE)); } } // Set base at +dz // for (G4int i=0; i 0) { faces.push_back(new G4TriangularFacet(baseRminB[i],baseRmaxB[i+1],baseRminB[i+1],ABSOLUTE)); } } // Set external lateral surface // for (G4int i=0; i 0) { for (G4int i=0; iAddFacet(faces[i]); } solid->SetSolidClosed(true); return solid; }