Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer << 3 // * DISCLAIMER * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th << 5 // * The following disclaimer summarizes all the specific disclaimers * 6 // * the Geant4 Collaboration. It is provided << 6 // * of contributors to this software. The specific disclaimers,which * 7 // * conditions of the Geant4 Software License << 7 // * govern, are listed with their locations in: * 8 // * LICENSE and available at http://cern.ch/ << 8 // * http://cern.ch/geant4/license * 9 // * include a list of copyright holders. << 10 // * 9 // * * 11 // * Neither the authors of this software syst 10 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 11 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 12 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 13 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file << 14 // * use. * 16 // * for the full disclaimer and the limitatio << 17 // * 15 // * * 18 // * This code implementation is the result << 16 // * This code implementation is the intellectual property of the * 19 // * technical work of the GEANT4 collaboratio << 17 // * GEANT4 collaboration. * 20 // * By using, copying, modifying or distri << 18 // * By copying, distributing or modifying the Program (or any work * 21 // * any work based on the software) you ag << 19 // * based on the Program) you indicate your acceptance of this * 22 // * use in resulting scientific publicati << 20 // * statement, and all its terms. * 23 // * acceptance of all terms of the Geant4 Sof << 24 // ******************************************* 21 // ******************************************************************** 25 // 22 // 26 // class G4GeomTestVolume implementation << 27 // 23 // 28 // Author: G.Cosmo, CERN << 24 // $Id: G4GeomTestVolume.cc,v 1.4 2004/12/02 09:31:23 gcosmo Exp $ >> 25 // GEANT4 tag $Name: geant4-07-01 $ >> 26 // >> 27 // -------------------------------------------------------------------- >> 28 // GEANT 4 class source file >> 29 // >> 30 // G4GeomTestVolume >> 31 // >> 32 // Author: D.C.Williams, UCSC (davidw@scipp.ucsc.edu) 29 // ------------------------------------------- 33 // -------------------------------------------------------------------- 30 << 31 #include <queue> << 32 #include <set> << 33 34 34 #include "G4GeomTestVolume.hh" 35 #include "G4GeomTestVolume.hh" 35 #include "G4PhysicalConstants.hh" << 36 >> 37 #include "G4GeomTestLogger.hh" >> 38 #include "G4GeomTestVolPoint.hh" >> 39 #include "G4GeomTestSegment.hh" >> 40 36 #include "G4VPhysicalVolume.hh" 41 #include "G4VPhysicalVolume.hh" 37 #include "G4LogicalVolume.hh" 42 #include "G4LogicalVolume.hh" 38 #include "G4VSolid.hh" 43 #include "G4VSolid.hh" 39 44 >> 45 #include <vector> >> 46 #include <set> >> 47 #include <algorithm> >> 48 #include <iomanip> >> 49 40 // 50 // 41 // Constructor 51 // Constructor 42 // 52 // 43 G4GeomTestVolume::G4GeomTestVolume( G4VPhysica << 53 G4GeomTestVolume::G4GeomTestVolume( const G4VPhysicalVolume *theTarget, 44 G4double t << 54 G4GeomTestLogger *theLogger, 45 G4int numb << 55 G4double theTolerance ) 46 G4bool the << 56 : target(theTarget), 47 : target(theTarget), tolerance(theTolerance) << 57 logger(theLogger), 48 resolution(numberOfPoints), verbosity(theV << 58 tolerance(theTolerance), >> 59 extent(theTarget->GetLogicalVolume()->GetSolid()->GetExtent()) 49 {;} 60 {;} 50 61 51 // 62 // 52 // Destructor 63 // Destructor 53 // 64 // 54 G4GeomTestVolume::~G4GeomTestVolume() {;} 65 G4GeomTestVolume::~G4GeomTestVolume() {;} 55 66 56 // 67 // 57 // Get error tolerance 68 // Get error tolerance 58 // 69 // 59 G4double G4GeomTestVolume::GetTolerance() cons 70 G4double G4GeomTestVolume::GetTolerance() const 60 { 71 { 61 return tolerance; 72 return tolerance; 62 } 73 } 63 74 64 // 75 // 65 // Set error tolerance 76 // Set error tolerance 66 // 77 // 67 void G4GeomTestVolume::SetTolerance(G4double t << 78 void G4GeomTestVolume::SetTolerance(G4double val) 68 { 79 { 69 tolerance = tol; << 80 tolerance = val; 70 } 81 } 71 82 72 // 83 // 73 // Get number of points to check (resolution) << 84 // TestCartGridXYZ 74 // 85 // 75 G4int G4GeomTestVolume::GetResolution() const << 86 void G4GeomTestVolume::TestCartGridXYZ( G4int nx, G4int ny, G4int nz ) 76 { 87 { 77 return resolution; << 88 TestCartGridX( ny, nz ); >> 89 TestCartGridY( nz, nx ); >> 90 TestCartGridZ( nx, ny ); 78 } 91 } 79 92 80 // 93 // 81 // Set number of points to check (resolution) << 94 // TestCartGridX 82 // 95 // 83 void G4GeomTestVolume::SetResolution(G4int np) << 96 void G4GeomTestVolume::TestCartGridX( G4int ny, G4int nz ) 84 { 97 { 85 resolution = np; << 98 TestCartGrid( G4ThreeVector(0,1,0), G4ThreeVector(0,0,1), >> 99 G4ThreeVector(1,0,0), ny, nz ); 86 } 100 } 87 101 88 // 102 // 89 // Get verbosity << 103 // TestCartGridY 90 // 104 // 91 G4bool G4GeomTestVolume::GetVerbosity() const << 105 void G4GeomTestVolume::TestCartGridY( G4int nz, G4int nx ) 92 { 106 { 93 return verbosity; << 107 TestCartGrid( G4ThreeVector(0,0,1), G4ThreeVector(1,0,0), >> 108 G4ThreeVector(0,1,0), nz, nx ); 94 } 109 } 95 110 96 // 111 // 97 // Set verbosity << 112 // TestCartGridZ 98 // 113 // 99 void G4GeomTestVolume::SetVerbosity(G4bool ver << 114 void G4GeomTestVolume::TestCartGridZ( G4int nx, G4int ny ) 100 { 115 { 101 verbosity = verb; << 116 TestCartGrid( G4ThreeVector(1,0,0), G4ThreeVector(0,1,0), >> 117 G4ThreeVector(0,0,1), nx, ny ); 102 } 118 } 103 119 104 // 120 // 105 // Get errors reporting threshold << 121 // TestRecursiveCartGrid 106 // 122 // 107 G4int G4GeomTestVolume::GetErrorsThreshold() c << 123 void G4GeomTestVolume::TestRecursiveCartGrid( G4int nx, G4int ny, G4int nz, >> 124 G4int slevel, G4int depth ) 108 { 125 { 109 return maxErr; << 126 // If reached requested level of depth (i.e. set to 0), exit. >> 127 // If not depth specified (i.e. set to -1), visit the whole tree. >> 128 // If requested initial level of depth is not zero, visit from beginning >> 129 // >> 130 if (depth == 0) return; >> 131 if (depth != -1) depth--; >> 132 if (slevel != 0) slevel--; >> 133 >> 134 // >> 135 // As long as we aren't a replica and we reached the requested >> 136 // initial level of depth, test ourselves >> 137 // >> 138 if ( (!target->IsReplicated()) && (slevel==0) ) >> 139 { >> 140 TestCartGridXYZ( nx, ny, nz ); >> 141 ReportErrors(); >> 142 } >> 143 >> 144 // >> 145 // Loop over unique daughters >> 146 // >> 147 std::set<const G4LogicalVolume *> tested; >> 148 >> 149 const G4LogicalVolume *logical = target->GetLogicalVolume(); >> 150 G4int nDaughter = logical->GetNoDaughters(); >> 151 G4int iDaughter; >> 152 for( iDaughter=0; iDaughter<nDaughter; ++iDaughter ) >> 153 { >> 154 const G4VPhysicalVolume *daughter = >> 155 logical->GetDaughter(iDaughter); >> 156 const G4LogicalVolume *daughterLogical = >> 157 daughter->GetLogicalVolume(); >> 158 >> 159 // >> 160 // Skip empty daughters >> 161 // >> 162 if (daughterLogical->GetNoDaughters() == 0) continue; >> 163 >> 164 // >> 165 // Tested already? >> 166 // >> 167 std::pair<std::set<const G4LogicalVolume *>::iterator,G4bool> >> 168 there = tested.insert(daughterLogical); >> 169 if (!there.second) continue; >> 170 >> 171 // >> 172 // Recurse >> 173 // >> 174 G4GeomTestVolume vTest( daughter, logger, tolerance ); >> 175 vTest.TestRecursiveCartGrid( nx,ny,nz,slevel,depth ); >> 176 } 110 } 177 } 111 178 112 // 179 // 113 // Set maximum number of errors to report << 180 // TestRecursiveCylinder 114 // 181 // 115 void G4GeomTestVolume::SetErrorsThreshold(G4in << 182 void >> 183 G4GeomTestVolume::TestRecursiveCylinder( G4int nPhi, G4int nZ, G4int nRho, >> 184 G4double fracZ, G4double fracRho, >> 185 G4bool usePhi, >> 186 G4int slevel, G4int depth ) 116 { 187 { 117 maxErr = max; << 188 // If reached requested level of depth (i.e. set to 0), exit. >> 189 // If not depth specified (i.e. set to -1), visit the whole tree. >> 190 // If requested initial level of depth is not zero, visit from beginning >> 191 // >> 192 if (depth == 0) return; >> 193 if (depth != -1) depth--; >> 194 if (slevel != 0) slevel--; >> 195 >> 196 // >> 197 // As long as we aren't a replica and we reached the requested >> 198 // initial level of depth, test ourselves >> 199 // >> 200 if ( (!target->IsReplicated()) && (slevel==0) ) >> 201 { >> 202 TestCylinder( nPhi, nZ, nRho, fracZ, fracRho, usePhi ); >> 203 ReportErrors(); >> 204 } >> 205 >> 206 // >> 207 // Loop over unique daughters >> 208 // >> 209 std::set<const G4LogicalVolume *> tested; >> 210 >> 211 const G4LogicalVolume *logical = target->GetLogicalVolume(); >> 212 G4int nDaughter = logical->GetNoDaughters(); >> 213 G4int iDaughter; >> 214 for( iDaughter=0; iDaughter<nDaughter; ++iDaughter ) >> 215 { >> 216 const G4VPhysicalVolume *daughter = >> 217 logical->GetDaughter(iDaughter); >> 218 const G4LogicalVolume *daughterLogical = >> 219 daughter->GetLogicalVolume(); >> 220 >> 221 // >> 222 // Skip empty daughters >> 223 // >> 224 if (daughterLogical->GetNoDaughters() == 0) continue; >> 225 >> 226 // >> 227 // Tested already? >> 228 // >> 229 std::pair<std::set<const G4LogicalVolume *>::iterator,G4bool> >> 230 there = tested.insert(daughterLogical); >> 231 if (!there.second) continue; >> 232 >> 233 // >> 234 // Recurse >> 235 // >> 236 G4GeomTestVolume vTest( daughter, logger, tolerance ); >> 237 vTest.TestRecursiveCylinder( nPhi, nZ, nRho, >> 238 fracZ, fracRho, usePhi, >> 239 slevel, depth ); >> 240 } 118 } 241 } 119 242 120 // 243 // 121 // Test overlap in tree << 244 // TestCylinder 122 // 245 // 123 void G4GeomTestVolume::TestOverlapInTree() con << 246 void G4GeomTestVolume::TestCylinder( G4int nPhi, G4int nZ, G4int nRho, >> 247 G4double fracZ, G4double fracRho, >> 248 G4bool usePhi ) 124 { 249 { 125 std::queue<G4VPhysicalVolume*> volumes; << 250 // 126 std::set<G4LogicalVolume*> checked; << 251 // Get size of our volume 127 << 252 // 128 volumes.push(target); << 253 G4double xMax = std::max(extent.GetXmax(),-extent.GetXmin()); 129 while (!volumes.empty()) << 254 G4double yMax = std::max(extent.GetYmax(),-extent.GetYmin()); >> 255 G4double rhoMax = std::sqrt(xMax*xMax + yMax*yMax); >> 256 >> 257 G4double zMax = extent.GetZmax(); >> 258 G4double zMin = extent.GetZmin(); >> 259 G4double zHalfLength = 0.5*(zMax-zMin); >> 260 G4double z0 = 0.5*(zMax+zMin); >> 261 >> 262 // >> 263 // Loop over phi >> 264 // >> 265 G4double deltaPhi = 2*pi/G4double(nPhi); >> 266 >> 267 G4double phi = 0; >> 268 G4int iPhi = nPhi; >> 269 if ((iPhi&1) == 0) iPhi++; // Also use odd number phi slices >> 270 do 130 { 271 { 131 G4VPhysicalVolume* current = volumes.front << 272 G4double cosPhi = std::cos(phi); 132 volumes.pop(); << 273 G4double sinPhi = std::sin(phi); 133 << 274 134 // check overlaps for daughters << 275 // 135 G4LogicalVolume* logical = current->GetLog << 276 // Loop over rho 136 std::size_t ndaughters = logical->GetNoDau << 277 // 137 for (std::size_t i=0; i<ndaughters; ++i) << 278 G4double rho = rhoMax; 138 { << 279 G4int iRho = nRho; 139 G4VPhysicalVolume* daughter = logical->G << 280 do 140 daughter->CheckOverlaps(resolution, tole << 141 } << 142 << 143 // append the queue of volumes << 144 G4LogicalVolume* previousLogical = nullptr << 145 for (std::size_t i=0; i<ndaughters; ++i) << 146 { 281 { 147 G4VPhysicalVolume* daughter = logical->G << 282 G4ThreeVector p(rho*cosPhi,rho*sinPhi,0); 148 G4LogicalVolume* daughterLogical = daugh << 283 static G4ThreeVector v(0,0,1); 149 if (daughterLogical->GetNoDaughters() == << 284 150 G4bool found = (daughterLogical == previ << 285 TestOneLine( p, v ); 151 if (!found) { found = (checked.find(daug << 286 152 if (!found) << 287 if (usePhi) 153 { << 154 checked.emplace(daughterLogical); << 155 previousLogical = daughterLogical; << 156 volumes.push(daughter); << 157 } << 158 else << 159 { 288 { 160 if (verbosity) << 289 // >> 290 // Loop over z >> 291 // >> 292 G4ThreeVector v(sinPhi,-cosPhi,0); >> 293 >> 294 G4double zScale = 1.0; >> 295 G4int iZ=nZ; >> 296 do 161 { 297 { 162 G4cout << "Checking overlaps in tree << 298 p.setZ( z0 + zScale*zHalfLength ); 163 << " (" << daughterLogical->G << 299 TestOneLine(p,v); 164 << " is omitted, to avoid dup << 300 p.setZ( z0 - zScale*zHalfLength ); 165 } << 301 TestOneLine(p,v); >> 302 } while( zScale *= fracZ, --iZ ); 166 } 303 } >> 304 } while( rho *= fracRho, --iRho ); >> 305 >> 306 // >> 307 // Loop over z >> 308 // >> 309 G4ThreeVector p(0,0,0); >> 310 G4ThreeVector v(cosPhi,sinPhi,0); >> 311 >> 312 G4double zScale = 1.0; >> 313 G4int iZ=nZ; >> 314 do >> 315 { >> 316 p.setZ( z0 + zScale*zHalfLength ); >> 317 >> 318 TestOneLine(p,v); >> 319 >> 320 p.setZ( z0 - zScale*zHalfLength ); >> 321 >> 322 TestOneLine(p,v); >> 323 } while( zScale *= fracZ, --iZ ); >> 324 >> 325 } while( phi += deltaPhi, --iPhi ); >> 326 } >> 327 >> 328 // >> 329 // TestCartGrid >> 330 // >> 331 void G4GeomTestVolume::TestCartGrid( const G4ThreeVector &theG1, >> 332 const G4ThreeVector &theG2, >> 333 const G4ThreeVector &theV, >> 334 G4int n1, G4int n2 ) >> 335 { >> 336 if (n1 <= 0 || n2 <= 0) >> 337 G4Exception( "G4GeomTestVolume::TestCartGrid()", "WrongArgumentValue", >> 338 FatalException, "Arguments n1 and n2 must be >= 1" ); >> 339 >> 340 G4ThreeVector xMin( extent.GetXmin(), extent.GetYmin(), >> 341 extent.GetZmin() ); >> 342 G4ThreeVector xMax( extent.GetXmax(), extent.GetYmax(), >> 343 extent.GetZmax() ); >> 344 >> 345 G4ThreeVector g1(theG1.unit()); >> 346 G4ThreeVector g2(theG2.unit()); >> 347 G4ThreeVector v(theV.unit()); >> 348 >> 349 G4double gMin1 = g1.dot(xMin); >> 350 G4double gMax1 = g1.dot(xMax); >> 351 >> 352 G4double gMin2 = g2.dot(xMin); >> 353 G4double gMax2 = g2.dot(xMax); >> 354 >> 355 G4double delta1 = (gMax1-gMin1)/G4double(n1); >> 356 G4double delta2 = (gMax2-gMin2)/G4double(n2); >> 357 >> 358 G4int i1, i2; >> 359 >> 360 for(i1=0;i1<=n1;++i1) >> 361 { >> 362 G4ThreeVector p1 = (gMin1 + G4double(i1)*delta1)*g1; >> 363 >> 364 for(i2=0;i2<=n2;++i2) >> 365 { >> 366 G4ThreeVector p2 = (gMin2 + G4double(i2)*delta2)*g2; >> 367 >> 368 TestOneLine( p1+p2, v ); 167 } 369 } 168 } 370 } 169 } << 371 } 170 372 171 // 373 // 172 // TestRecursiveOverlap << 374 // TestRecursiveLine 173 // 375 // 174 void G4GeomTestVolume::TestRecursiveOverlap( G << 376 void >> 377 G4GeomTestVolume::TestRecursiveLine( const G4ThreeVector& p, >> 378 const G4ThreeVector& v, >> 379 G4int slevel, G4int depth ) 175 { 380 { 176 // If reached requested level of depth (i.e. 381 // If reached requested level of depth (i.e. set to 0), exit. 177 // If not depth specified (i.e. set to -1), 382 // If not depth specified (i.e. set to -1), visit the whole tree. 178 // If requested initial level of depth is no 383 // If requested initial level of depth is not zero, visit from beginning 179 // 384 // 180 if (depth == 0) { return; } << 385 if (depth == 0) return; 181 if (depth != -1) { depth--; } << 386 if (depth != -1) depth--; 182 if (slevel != 0) { slevel--; } << 387 if (slevel != 0) slevel--; 183 388 184 // 389 // 185 // As long as we reached the requested << 390 // As long as we aren't a replica and we reached the requested 186 // initial level of depth, test ourselves 391 // initial level of depth, test ourselves 187 // 392 // 188 if ( slevel==0 ) << 393 if ( (!target->IsReplicated()) && (slevel==0) ) 189 { 394 { 190 target->CheckOverlaps(resolution, toleranc << 395 TestOneLine( p, v ); >> 396 ReportErrors(); 191 } 397 } 192 398 193 // 399 // 194 // Loop over unique daughters 400 // Loop over unique daughters 195 // 401 // 196 std::set<const G4LogicalVolume *> tested; 402 std::set<const G4LogicalVolume *> tested; 197 403 198 const G4LogicalVolume *logical = target->Get 404 const G4LogicalVolume *logical = target->GetLogicalVolume(); 199 auto nDaughter = (G4int)logical->GetNoDaugh << 405 G4int nDaughter = logical->GetNoDaughters(); 200 for( auto iDaughter=0; iDaughter<nDaughter; << 406 G4int iDaughter; >> 407 for( iDaughter=0; iDaughter<nDaughter; ++iDaughter ) 201 { 408 { 202 G4VPhysicalVolume *daughter = logical->Get << 409 const G4VPhysicalVolume *daughter = >> 410 logical->GetDaughter(iDaughter); >> 411 const G4LogicalVolume *daughterLogical = >> 412 daughter->GetLogicalVolume(); 203 413 >> 414 // >> 415 // Skip empty daughters >> 416 // >> 417 if (daughterLogical->GetNoDaughters() == 0) continue; >> 418 >> 419 // 204 // Tested already? 420 // Tested already? 205 // 421 // 206 // const G4LogicalVolume *daughterLogical << 422 std::pair<std::set<const G4LogicalVolume *>::iterator,G4bool> 207 // daughter->GetLogicalVolume(); << 423 there = tested.insert(daughterLogical); 208 // std::pair<std::set<const G4LogicalVolum << 424 if (!there.second) continue; 209 // there = tested.insert(daughterLog << 210 // if (!there.second) continue; << 211 425 212 // 426 // 213 // Recurse 427 // Recurse 214 // 428 // 215 G4GeomTestVolume vTest( daughter, toleranc << 429 G4GeomTestVolume vTest( daughter, logger, tolerance ); 216 vTest.SetErrorsThreshold(maxErr); << 430 vTest.TestRecursiveLine( p, v, slevel, depth ); 217 vTest.TestRecursiveOverlap( slevel,depth ) << 218 } 431 } >> 432 } >> 433 >> 434 // >> 435 // TestOneLine >> 436 // >> 437 // Test geometry consistency along a single line >> 438 // >> 439 void G4GeomTestVolume::TestOneLine( const G4ThreeVector &p, >> 440 const G4ThreeVector &v ) >> 441 { >> 442 // >> 443 // Keep track of intersection points >> 444 // >> 445 std::vector<G4GeomTestVolPoint> points; >> 446 >> 447 // >> 448 // Calculate intersections with the mother volume >> 449 // >> 450 G4GeomTestSegment targetSegment( target->GetLogicalVolume()->GetSolid(), >> 451 p, v, logger ); >> 452 >> 453 // >> 454 // Add them to our list >> 455 // >> 456 G4int n = targetSegment.GetNumberPoints(); >> 457 G4int i; >> 458 for(i=0;i<n;++i) >> 459 { >> 460 points.push_back( G4GeomTestVolPoint( targetSegment.GetPoint(i), -1 ) ); >> 461 } >> 462 >> 463 // >> 464 // Loop over daughter volumes >> 465 // >> 466 const G4LogicalVolume *logical = target->GetLogicalVolume(); >> 467 G4int nDaughter = logical->GetNoDaughters(); >> 468 G4int iDaughter; >> 469 for( iDaughter=0; iDaughter<nDaughter; ++iDaughter) >> 470 { >> 471 const G4VPhysicalVolume *daughter = >> 472 logical->GetDaughter(iDaughter); >> 473 >> 474 // >> 475 // Convert coordinates to daughter local coordinates >> 476 // >> 477 const G4RotationMatrix *rotation = daughter->GetFrameRotation(); >> 478 const G4ThreeVector &translation = daughter->GetFrameTranslation(); >> 479 >> 480 G4ThreeVector pLocal = translation + p; >> 481 G4ThreeVector vLocal = v; >> 482 >> 483 if (rotation) >> 484 { >> 485 pLocal = (*rotation)*pLocal; >> 486 vLocal = (*rotation)*vLocal; >> 487 } >> 488 >> 489 // >> 490 // Find intersections >> 491 // >> 492 G4GeomTestSegment >> 493 daughterSegment( daughter->GetLogicalVolume()->GetSolid(), >> 494 pLocal, vLocal, logger ); >> 495 >> 496 // >> 497 // Add them to the list >> 498 // >> 499 G4int n = daughterSegment.GetNumberPoints(); >> 500 G4int i; >> 501 for(i=0;i<n;++i) >> 502 { >> 503 points.push_back( G4GeomTestVolPoint( daughterSegment.GetPoint(i), >> 504 iDaughter, translation, rotation ) ); >> 505 } >> 506 } >> 507 >> 508 // >> 509 // Now sort the list of intersection points >> 510 // >> 511 std::sort( points.begin(), points.end() ); >> 512 >> 513 // >> 514 // Search for problems: >> 515 // 1. Overlap daughters will be indicated by intersecting >> 516 // points that lie within another daughter >> 517 // 2. Daughter extending outside the mother will be >> 518 // indicated by intersecting points outside the mother >> 519 // >> 520 // The search method is always looking forward when >> 521 // resolving discrepencies due to roundoff error. Once >> 522 // one instance of a daughter intersection is analyzed, >> 523 // it is removed from further consideration >> 524 // >> 525 n = points.size(); >> 526 >> 527 // >> 528 // Set true if this point has been analyzed >> 529 // >> 530 std::vector<G4bool> checked( n, false ); >> 531 >> 532 for(i=0;i<n;++i) >> 533 { >> 534 if (checked[i]) continue; >> 535 >> 536 G4int iDaug = points[i].GetDaughterIndex(); >> 537 if (iDaug < 0) continue; >> 538 >> 539 // >> 540 // Intersection found. Find matching pair. >> 541 // >> 542 G4double iS = points[i].GetDistance(); >> 543 G4int j = i; >> 544 while(++j<n) >> 545 { >> 546 if (iDaug == points[j].GetDaughterIndex()) break; >> 547 } >> 548 if (j>=n) >> 549 { >> 550 // >> 551 // Unmatched? This shouldn't happen >> 552 // >> 553 logger->SolidProblem( logical->GetDaughter(iDaug)-> >> 554 GetLogicalVolume()->GetSolid(), >> 555 "Unmatched intersection point", >> 556 points[i].GetPosition() ); >> 557 continue; >> 558 } >> 559 >> 560 checked[j] = true; >> 561 >> 562 G4double jS = points[j].GetDistance(); >> 563 >> 564 // >> 565 // Otherwise, we could have a problem >> 566 // >> 567 G4int k = i; >> 568 while(++k<j) >> 569 { >> 570 if (checked[k]) continue; >> 571 >> 572 G4bool kEntering = points[k].Entering(); >> 573 G4double kS = points[k].GetDistance(); >> 574 >> 575 >> 576 // >> 577 // Problem found: catagorize >> 578 // >> 579 G4int kDaug = points[k].GetDaughterIndex(); >> 580 if (kDaug < 0) >> 581 { >> 582 // >> 583 // Ignore small overshoots if they are within tolerance >> 584 // >> 585 if (kS-iS < tolerance && kEntering ) continue; >> 586 if (jS-kS < tolerance && (!kEntering)) continue; >> 587 >> 588 // >> 589 // We appear to extend outside the mother volume >> 590 // >> 591 std::map<G4long,G4GeomTestOvershootList>::iterator overshoot = >> 592 overshoots.find(iDaug); >> 593 if (overshoot == overshoots.end()) >> 594 { >> 595 std::pair<std::map<G4long,G4GeomTestOvershootList>::iterator,G4bool> >> 596 result = >> 597 overshoots.insert( std::pair<const G4long,G4GeomTestOvershootList> >> 598 (iDaug,G4GeomTestOvershootList(target,iDaug)) ); >> 599 assert(result.second); >> 600 overshoot = result.first; >> 601 } >> 602 >> 603 if (kEntering) >> 604 (*overshoot).second.AddError( points[i].GetPosition(), >> 605 points[k].GetPosition() ); >> 606 else >> 607 (*overshoot).second.AddError( points[k].GetPosition(), >> 608 points[j].GetPosition() ); >> 609 } >> 610 else >> 611 { >> 612 // >> 613 // Ignore small overlaps if they are within tolerance >> 614 // >> 615 if (kS-iS < tolerance && (!kEntering)) continue; >> 616 if (jS-kS < tolerance && kEntering ) continue; >> 617 >> 618 // >> 619 // We appear to overlap with another daughter >> 620 // >> 621 G4long key = iDaug < kDaug ? >> 622 (iDaug*nDaughter + kDaug) : (kDaug*nDaughter + iDaug); >> 623 >> 624 std::map<G4long,G4GeomTestOverlapList>::iterator overlap = >> 625 overlaps.find(key); >> 626 if (overlap == overlaps.end()) >> 627 { >> 628 std::pair<std::map<G4long,G4GeomTestOverlapList>::iterator,G4bool> >> 629 result = >> 630 overlaps.insert( std::pair<const G4long,G4GeomTestOverlapList> >> 631 (key,G4GeomTestOverlapList(target,iDaug,kDaug)) ); >> 632 assert(result.second); >> 633 overlap = result.first; >> 634 } >> 635 >> 636 if (points[k].Entering()) >> 637 (*overlap).second.AddError( points[k].GetPosition(), >> 638 points[j].GetPosition() ); >> 639 else >> 640 (*overlap).second.AddError( points[i].GetPosition(), >> 641 points[k].GetPosition() ); >> 642 } >> 643 } >> 644 } >> 645 } >> 646 >> 647 // >> 648 // ReportErrors >> 649 // >> 650 void G4GeomTestVolume::ReportErrors() >> 651 { >> 652 // >> 653 // Report overshoots >> 654 // >> 655 if (overshoots.empty()) >> 656 logger->NoProblem("GeomTest: no daughter volume extending outside mother detected."); >> 657 else >> 658 { >> 659 std::map<G4long,G4GeomTestOvershootList>::iterator overshoot = >> 660 overshoots.begin(); >> 661 while( overshoot != overshoots.end() ) >> 662 { >> 663 logger->OvershootingDaughter( &(*overshoot).second ); >> 664 ++overshoot; >> 665 } >> 666 } >> 667 >> 668 // >> 669 // Report overlaps >> 670 // >> 671 if (overlaps.empty()) >> 672 logger->NoProblem("GeomTest: no overlapping daughters detected."); >> 673 else >> 674 { >> 675 std::map<G4long,G4GeomTestOverlapList>::iterator overlap = >> 676 overlaps.begin(); >> 677 while( overlap != overlaps.end() ) >> 678 { >> 679 logger->OverlappingDaughters( &(*overlap).second ); >> 680 ++overlap; >> 681 } >> 682 } >> 683 } >> 684 >> 685 // >> 686 // ClearErrors >> 687 // >> 688 void G4GeomTestVolume::ClearErrors() >> 689 { >> 690 overshoots.clear(); >> 691 overlaps.clear(); 219 } 692 } 220 693