Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // >> 26 // >> 27 // $Id: G4PVPlacement.cc,v 1.16 2007/04/11 07:56:38 gcosmo Exp $ >> 28 // GEANT4 tag $Name: geant4-08-03-patch-01 $ >> 29 // >> 30 // 26 // class G4PVPlacement Implementation 31 // class G4PVPlacement Implementation 27 // 32 // 28 // 24.07.95 P.Kent, First non-stub version. << 29 // ------------------------------------------- 33 // ---------------------------------------------------------------------- 30 34 31 #include "G4PVPlacement.hh" 35 #include "G4PVPlacement.hh" 32 #include "G4AffineTransform.hh" 36 #include "G4AffineTransform.hh" 33 #include "G4UnitsTable.hh" 37 #include "G4UnitsTable.hh" 34 #include "G4LogicalVolume.hh" 38 #include "G4LogicalVolume.hh" 35 #include "G4VSolid.hh" 39 #include "G4VSolid.hh" 36 40 37 // ------------------------------------------- 41 // ---------------------------------------------------------------------- 38 // Constructor 42 // Constructor 39 // 43 // 40 G4PVPlacement::G4PVPlacement( G4RotationMatrix << 44 G4PVPlacement::G4PVPlacement( G4RotationMatrix *pRot, 41 const G4ThreeVector& t << 45 const G4ThreeVector &tlate, 42 const G4String& pName, 46 const G4String& pName, 43 G4LogicalVolume* << 47 G4LogicalVolume *pLogical, 44 G4VPhysicalVolum << 48 G4VPhysicalVolume *pMother, 45 G4bool pMany, 49 G4bool pMany, 46 G4int pCopyNo, 50 G4int pCopyNo, 47 G4bool pSurfChk 51 G4bool pSurfChk ) 48 : G4VPhysicalVolume(pRot, tlate, pName, pLog << 52 : G4VPhysicalVolume(pRot,tlate,pName,pLogical,pMother), 49 fmany(pMany), fcopyNo(pCopyNo) << 53 fmany(pMany), fallocatedRotM(false), fcopyNo(pCopyNo) 50 { 54 { 51 if (pMother != nullptr) << 55 if (pMother) 52 { 56 { 53 G4LogicalVolume* motherLogical = pMother-> 57 G4LogicalVolume* motherLogical = pMother->GetLogicalVolume(); 54 if (pLogical == motherLogical) 58 if (pLogical == motherLogical) 55 { 59 { 56 G4Exception("G4PVPlacement::G4PVPlacemen << 60 G4Exception("G4PVPlacement::G4PVPlacement()", "InvalidSetup", 57 FatalException, "Cannot plac 61 FatalException, "Cannot place a volume inside itself!"); 58 } 62 } 59 SetMotherLogical(motherLogical); 63 SetMotherLogical(motherLogical); 60 motherLogical->AddDaughter(this); 64 motherLogical->AddDaughter(this); 61 if (pSurfChk) { CheckOverlaps(); } 65 if (pSurfChk) { CheckOverlaps(); } 62 } 66 } 63 } 67 } 64 68 65 // ------------------------------------------- 69 // ---------------------------------------------------------------------- 66 // Constructor 70 // Constructor 67 // 71 // 68 G4PVPlacement::G4PVPlacement( const G4Transfor << 72 G4PVPlacement::G4PVPlacement( const G4Transform3D &Transform3D, 69 const G4String& 73 const G4String& pName, 70 G4LogicalV << 74 G4LogicalVolume *pLogical, 71 G4VPhysica << 75 G4VPhysicalVolume *pMother, 72 G4bool pMa 76 G4bool pMany, 73 G4int pCop 77 G4int pCopyNo, 74 G4bool pSu 78 G4bool pSurfChk ) 75 : G4VPhysicalVolume(NewPtrRotMatrix(Transfor 79 : G4VPhysicalVolume(NewPtrRotMatrix(Transform3D.getRotation().inverse()), 76 Transform3D.getTranslati << 80 Transform3D.getTranslation(),pName,pLogical,pMother), 77 fmany(pMany), fcopyNo(pCopyNo) 81 fmany(pMany), fcopyNo(pCopyNo) 78 { 82 { 79 fallocatedRotM = (GetRotation() != nullptr); << 83 fallocatedRotM = (GetRotation() != 0); 80 if (pMother != nullptr) << 84 if (pMother) 81 { 85 { 82 G4LogicalVolume* motherLogical = pMother-> 86 G4LogicalVolume* motherLogical = pMother->GetLogicalVolume(); 83 if (pLogical == motherLogical) 87 if (pLogical == motherLogical) 84 G4Exception("G4PVPlacement::G4PVPlacemen << 88 G4Exception("G4PVPlacement::G4PVPlacement()", "InvalidSetup", 85 FatalException, "Cannot plac 89 FatalException, "Cannot place a volume inside itself!"); 86 SetMotherLogical(motherLogical); 90 SetMotherLogical(motherLogical); 87 motherLogical->AddDaughter(this); 91 motherLogical->AddDaughter(this); 88 if (pSurfChk) { CheckOverlaps(); } 92 if (pSurfChk) { CheckOverlaps(); } 89 } 93 } 90 } 94 } 91 95 92 // ------------------------------------------- 96 // ---------------------------------------------------------------------- 93 // Constructor 97 // Constructor 94 // 98 // 95 // The logical volume of the mother is utilise 99 // The logical volume of the mother is utilised (not the physical) 96 // 100 // 97 G4PVPlacement::G4PVPlacement( G4RotationMatrix << 101 G4PVPlacement::G4PVPlacement( G4RotationMatrix *pRot, 98 const G4ThreeVector& t << 102 const G4ThreeVector &tlate, 99 G4LogicalVolume* << 103 G4LogicalVolume *pCurrentLogical, 100 const G4String& pName, 104 const G4String& pName, 101 G4LogicalVolume* << 105 G4LogicalVolume *pMotherLogical, 102 G4bool pMany, 106 G4bool pMany, 103 G4int pCopyNo, 107 G4int pCopyNo, 104 G4bool pSurfChk 108 G4bool pSurfChk ) 105 : G4VPhysicalVolume(pRot, tlate, pName, pCur << 109 : G4VPhysicalVolume(pRot,tlate,pName,pCurrentLogical,0), 106 fmany(pMany), fcopyNo(pCopyNo) << 110 fmany(pMany), fallocatedRotM(false), fcopyNo(pCopyNo) 107 { 111 { 108 if (pCurrentLogical == pMotherLogical) 112 if (pCurrentLogical == pMotherLogical) 109 { 113 { 110 G4Exception("G4PVPlacement::G4PVPlacement( << 114 G4Exception("G4PVPlacement::G4PVPlacement()", "InvalidSetup", 111 FatalException, "Cannot place 115 FatalException, "Cannot place a volume inside itself!"); 112 } 116 } 113 SetMotherLogical(pMotherLogical); 117 SetMotherLogical(pMotherLogical); 114 if (pMotherLogical != nullptr) { pMotherLogi << 118 if (pMotherLogical) { pMotherLogical->AddDaughter(this); } 115 if ((pSurfChk) && ((pMotherLogical) != nullp << 119 if ((pSurfChk) && (pMotherLogical)) { CheckOverlaps(); } 116 } 120 } 117 121 >> 122 118 // ------------------------------------------- 123 // ---------------------------------------------------------------------- 119 // Constructor 124 // Constructor 120 // 125 // 121 G4PVPlacement::G4PVPlacement( const G4Transfor << 126 G4PVPlacement::G4PVPlacement( const G4Transform3D &Transform3D, 122 G4LogicalV << 127 G4LogicalVolume *pCurrentLogical, 123 const G4String& 128 const G4String& pName, 124 G4LogicalV << 129 G4LogicalVolume *pMotherLogical, 125 G4bool pMa 130 G4bool pMany, 126 G4int pCop 131 G4int pCopyNo, 127 G4bool pSu 132 G4bool pSurfChk ) 128 : G4VPhysicalVolume(nullptr, Transform3D.get << 133 : G4VPhysicalVolume(0,Transform3D.getTranslation(),pName,pCurrentLogical,0), 129 pName, pCurrentLogical, << 130 fmany(pMany), fcopyNo(pCopyNo) 134 fmany(pMany), fcopyNo(pCopyNo) 131 { 135 { 132 if (pCurrentLogical == pMotherLogical) 136 if (pCurrentLogical == pMotherLogical) 133 { 137 { 134 G4Exception("G4PVPlacement::G4PVPlacement( << 138 G4Exception("G4PVPlacement::G4PVPlacement()", "InvalidSetup", 135 FatalException, "Cannot place 139 FatalException, "Cannot place a volume inside itself!"); 136 } 140 } 137 SetRotation( NewPtrRotMatrix(Transform3D.get 141 SetRotation( NewPtrRotMatrix(Transform3D.getRotation().inverse()) ); 138 fallocatedRotM = (GetRotation() != nullptr); << 142 fallocatedRotM = (GetRotation() != 0); 139 SetMotherLogical(pMotherLogical); 143 SetMotherLogical(pMotherLogical); 140 if (pMotherLogical != nullptr) { pMotherLogi << 144 if (pMotherLogical) { pMotherLogical->AddDaughter(this); } 141 if ((pSurfChk) && ((pMotherLogical) != nullp << 145 if ((pSurfChk) && (pMotherLogical)) { CheckOverlaps(); } 142 } 146 } 143 147 144 // ------------------------------------------- 148 // ---------------------------------------------------------------------- 145 // Fake default constructor - sets only member 149 // Fake default constructor - sets only member data and allocates memory 146 // for usage restri 150 // for usage restricted to object persistency. 147 // 151 // 148 G4PVPlacement::G4PVPlacement( __void__& a ) 152 G4PVPlacement::G4PVPlacement( __void__& a ) 149 : G4VPhysicalVolume(a) 153 : G4VPhysicalVolume(a) 150 { 154 { 151 } 155 } 152 156 153 // ------------------------------------------- 157 // ---------------------------------------------------------------------- 154 // Destructor 158 // Destructor 155 // 159 // 156 G4PVPlacement::~G4PVPlacement() 160 G4PVPlacement::~G4PVPlacement() 157 { 161 { 158 if( fallocatedRotM ){ delete this->GetRotati << 162 if( fallocatedRotM ){ delete frot; } 159 } 163 } 160 164 161 // ------------------------------------------- 165 // ---------------------------------------------------------------------- 162 // IsMany 166 // IsMany 163 // 167 // 164 G4bool G4PVPlacement::IsMany() const 168 G4bool G4PVPlacement::IsMany() const 165 { 169 { 166 return fmany; << 170 return fmany; >> 171 } >> 172 >> 173 // ---------------------------------------------------------------------- >> 174 // GetCopyNo >> 175 // >> 176 G4int G4PVPlacement::GetCopyNo() const >> 177 { >> 178 return fcopyNo; 167 } 179 } 168 180 169 // ------------------------------------------- 181 // ---------------------------------------------------------------------- 170 // SetCopyNo 182 // SetCopyNo 171 // 183 // 172 void G4PVPlacement::SetCopyNo(G4int newCopyNo) 184 void G4PVPlacement::SetCopyNo(G4int newCopyNo) 173 { 185 { 174 fcopyNo = newCopyNo; << 186 fcopyNo= newCopyNo; 175 } 187 } 176 188 177 // ------------------------------------------- 189 // ---------------------------------------------------------------------- 178 // IsReplicated 190 // IsReplicated 179 // 191 // 180 G4bool G4PVPlacement::IsReplicated() const 192 G4bool G4PVPlacement::IsReplicated() const 181 { 193 { 182 return false; 194 return false; 183 } 195 } 184 196 185 // ------------------------------------------- 197 // ---------------------------------------------------------------------- 186 // IsParameterised 198 // IsParameterised 187 // 199 // 188 G4bool G4PVPlacement::IsParameterised() const 200 G4bool G4PVPlacement::IsParameterised() const 189 { 201 { 190 return false; 202 return false; 191 } 203 } 192 204 193 // ------------------------------------------- 205 // ---------------------------------------------------------------------- 194 // GetParameterisation 206 // GetParameterisation 195 // 207 // 196 G4VPVParameterisation* G4PVPlacement::GetParam 208 G4VPVParameterisation* G4PVPlacement::GetParameterisation() const 197 { 209 { 198 return nullptr; << 210 return 0; 199 } 211 } 200 212 201 // ------------------------------------------- 213 // ---------------------------------------------------------------------- 202 // GetReplicationData 214 // GetReplicationData 203 // 215 // 204 void G4PVPlacement:: 216 void G4PVPlacement:: 205 GetReplicationData( EAxis&, G4int&, G4double&, 217 GetReplicationData( EAxis&, G4int&, G4double&, G4double&, G4bool& ) const 206 { 218 { 207 // No-operations 219 // No-operations 208 } 220 } 209 221 210 // ------------------------------------------- 222 // ---------------------------------------------------------------------- 211 // IsRegularRepeatedStructure 223 // IsRegularRepeatedStructure 212 // 224 // 213 // This is for specialised repeated volumes (r 225 // This is for specialised repeated volumes (replicas, parameterised vol.) 214 // 226 // 215 G4bool G4PVPlacement::IsRegularStructure() con 227 G4bool G4PVPlacement::IsRegularStructure() const 216 { 228 { 217 return false; 229 return false; 218 } << 230 } 219 231 220 // ------------------------------------------- 232 // ---------------------------------------------------------------------- 221 // IsRegularRepeatedStructure 233 // IsRegularRepeatedStructure 222 // 234 // 223 // This is for specialised repeated volumes (r 235 // This is for specialised repeated volumes (replicas, parameterised vol.) 224 // 236 // 225 G4int G4PVPlacement::GetRegularStructureId() c 237 G4int G4PVPlacement::GetRegularStructureId() const 226 { 238 { 227 return 0; << 239 return 0; 228 } << 240 } 229 << 230 // ------------------------------------------- << 231 // VolumeType << 232 // << 233 // Information to help identify sub-navigator << 234 // << 235 EVolume G4PVPlacement::VolumeType() const << 236 { << 237 return kNormal; << 238 } << 239 241 240 // ------------------------------------------- 242 // ---------------------------------------------------------------------- 241 // CheckOverlaps 243 // CheckOverlaps 242 // 244 // 243 G4bool G4PVPlacement::CheckOverlaps(G4int res, << 245 G4bool G4PVPlacement::CheckOverlaps(G4int res, G4double tol, G4bool verbose) 244 G4bool ver << 245 { 246 { 246 if (res <= 0) { return false; } << 247 if (res<=0) { return false; } 247 248 248 G4VSolid* solid = GetLogicalVolume()->GetSol 249 G4VSolid* solid = GetLogicalVolume()->GetSolid(); 249 G4LogicalVolume* motherLog = GetMotherLogica 250 G4LogicalVolume* motherLog = GetMotherLogical(); 250 if (motherLog == nullptr) { return false; } << 251 if (!motherLog) { return false; } 251 252 252 G4int trials = 0; << 253 G4VSolid* motherSolid = motherLog->GetSolid(); 253 G4bool retval = false; << 254 254 255 if (verbose) 255 if (verbose) 256 { 256 { 257 G4cout << "Checking overlaps for volume " << 257 G4cout << "Checking overlaps for volume " << GetName() << " ... "; 258 << GetName() << ':' << GetCopyNo() << 259 << " (" << solid->GetEntityType() < << 260 } 258 } 261 259 262 // Check that random points are gererated co << 260 // Create the transformation from daughter to mother 263 // 261 // 264 G4ThreeVector ptmp = solid->GetPointOnSurfac << 262 G4AffineTransform Tm( GetRotation(), GetTranslation() ); 265 if (solid->Inside(ptmp) != kSurface) << 266 { << 267 G4String position[3] = { "outside", "surfa << 268 std::ostringstream message; << 269 message << "Sample point is not on the sur << 270 << " The issue is detecte << 271 << GetName() << ':' << GetCopyNo() << 272 << " (" << solid->GetEntityType() << 273 << " generated point " << << 274 << " is " << position[solid->Insid << 275 G4Exception("G4PVPlacement::CheckOverlaps( << 276 "GeomVol1002", JustWarning, me << 277 return false; << 278 } << 279 263 280 // Generate random points on the surface of << 264 for (G4int n=0; n<res; n++) 281 // transform them into the mother volume coo << 282 // and find the bonding box << 283 // << 284 std::vector<G4ThreeVector> points(res); << 285 G4double xmin = kInfinity, ymin = kInfinit << 286 G4double xmax = -kInfinity, ymax = -kInfinit << 287 G4AffineTransform Tm(GetRotation(), GetTrans << 288 for (G4int i = 0; i < res; ++i) << 289 { 265 { 290 points[i] = Tm.TransformPoint(solid->GetPo << 266 // Generate a random point on the solid's surface 291 xmin = std::min(xmin, points[i].x()); << 267 // 292 ymin = std::min(ymin, points[i].y()); << 268 G4ThreeVector point = solid->GetPointOnSurface(); 293 zmin = std::min(zmin, points[i].z()); << 294 xmax = std::max(xmax, points[i].x()); << 295 ymax = std::max(ymax, points[i].y()); << 296 zmax = std::max(zmax, points[i].z()); << 297 } << 298 G4ThreeVector scenter(0.5*(xmax+xmin), 0.5*( << 299 G4double sradius = 0.5*G4ThreeVector(xmax-xm << 300 << 301 // Check overlap with the mother volume << 302 // << 303 G4int overlapCount = 0; << 304 G4double overlapSize = -kInfinity; << 305 G4ThreeVector overlapPoint; << 306 G4VSolid* motherSolid = motherLog->GetSolid( << 307 for (G4int i = 0; i < res; ++i) << 308 { << 309 G4ThreeVector mp = points[i]; << 310 if (motherSolid->Inside(mp) != kOutside) c << 311 G4double distin = motherSolid->DistanceToI << 312 if (distin < tol) continue; // too small o << 313 ++overlapCount; << 314 if (distin <= overlapSize) continue; << 315 overlapSize = distin; << 316 overlapPoint = mp; << 317 } << 318 << 319 // Print information on overlap << 320 // << 321 if (overlapCount > 0) << 322 { << 323 ++trials; << 324 retval = true; << 325 std::ostringstream message; << 326 message << "Overlap with mother volume !" << 327 << " Overlap is detected << 328 << GetName() << ':' << GetCopyNo() << 329 << " (" << solid->GetEntityType() << 330 << " with its mother volume " << m << 331 << " (" << motherSolid->GetEntityT << 332 << " protrusion at mother << 333 << " by " << G4BestUnit(overlapSiz << 334 << " (max of " << overlapCount << << 335 if (trials >= maxErr) << 336 { << 337 message << G4endl << 338 << "NOTE: Reached maximum fixed << 339 << "- of overlaps reports for th << 340 } << 341 G4Exception("G4PVPlacement::CheckOverlaps( << 342 "GeomVol1002", JustWarning, me << 343 if (trials >= maxErr) { return true; } << 344 } << 345 269 346 // Checking overlaps with each 'sister' volu << 270 // Transform the generated point to the mother's coordinate system 347 // << 271 // 348 G4VSolid* previous = nullptr; << 272 G4ThreeVector mp = Tm.TransformPoint(point); 349 G4ThreeVector pmin_local(0.,0.,0.), pmax_loc << 350 273 351 for (std::size_t k = 0; k < motherLog->GetNo << 274 // Checking overlaps with the mother volume 352 { << 275 // 353 G4VPhysicalVolume* daughter = motherLog->G << 276 if (motherSolid->Inside(mp)==kOutside) 354 if (daughter == this) continue; << 355 G4bool check_encapsulation = true; << 356 << 357 G4AffineTransform Td(daughter->GetRotation << 358 G4VSolid* daughterSolid = daughter->GetLog << 359 if (previous != daughterSolid) << 360 { 277 { 361 daughterSolid->BoundingLimits(pmin_local << 278 G4double distin = motherSolid->DistanceToIn(mp); 362 previous = daughterSolid; << 279 if (distin > tol) 363 } << 364 overlapCount = 0; << 365 overlapSize = -kInfinity; << 366 if (!Td.IsRotated()) { // no rotation, onl << 367 G4ThreeVector offset = Td.NetTranslation << 368 G4ThreeVector pmin(pmin_local + offset); << 369 G4ThreeVector pmax(pmax_local + offset); << 370 if (pmin.x() >= xmax) continue; << 371 if (pmin.y() >= ymax) continue; << 372 if (pmin.z() >= zmax) continue; << 373 if (pmax.x() <= xmin) continue; << 374 if (pmax.y() <= ymin) continue; << 375 if (pmax.z() <= zmin) continue; << 376 for (G4int i = 0; i < res; ++i) << 377 { 280 { 378 G4ThreeVector p = points[i]; << 281 G4cout << G4endl; 379 if (p.x() <= pmin.x()) continue; << 282 G4cout << "WARNING - G4PVPlacement::CheckOverlaps()" << G4endl 380 if (p.x() >= pmax.x()) continue; << 283 << " Overlap is detected for volume " 381 if (p.y() <= pmin.y()) continue; << 284 << GetName() << G4endl 382 if (p.y() >= pmax.y()) continue; << 285 << " with its mother volume " 383 if (p.z() <= pmin.z()) continue; << 286 << motherLog->GetName() << G4endl 384 if (p.z() >= pmax.z()) continue; << 287 << " at mother local point " << mp << ", " 385 G4ThreeVector md = p - offset; << 288 << "overlapping by at least: " << G4BestUnit(distin, "Length") 386 if (daughterSolid->Inside(md) == kInsi << 289 << G4endl; 387 { << 290 G4Exception("G4PVPlacement::CheckOverlaps()", "InvalidSetup", 388 check_encapsulation = false; << 291 JustWarning, "Overlap with mother volume !"); 389 G4double distout = daughterSolid->Di << 292 return true; 390 if (distout < tol) continue; // too << 391 ++overlapCount; << 392 if (distout <= overlapSize) continue << 393 overlapSize = distout; << 394 overlapPoint = md; << 395 } << 396 } 293 } 397 } 294 } 398 else // transformation with rotation << 295 >> 296 // Checking overlaps with each 'sister' volume >> 297 // >> 298 for (G4int i=0; i<motherLog->GetNoDaughters(); i++) 399 { 299 { 400 G4ThreeVector pmin(pmin_local), pmax(pma << 300 G4VPhysicalVolume* daughter = motherLog->GetDaughter(i); 401 G4ThreeVector dcenter = Td.TransformPoin << 301 402 G4double dradius = 0.5*((pmax - pmin).ma << 302 if (daughter == this) { continue; } 403 if ((scenter - dcenter).mag2() >= (sradi << 303 404 if (dcenter.x() - dradius >= xmax) conti << 304 // Create the transformation for daughter volume and transform point 405 if (dcenter.y() - dradius >= ymax) conti << 305 // 406 if (dcenter.z() - dradius >= zmax) conti << 306 G4AffineTransform Td( daughter->GetRotation(), 407 if (dcenter.x() + dradius <= xmin) conti << 307 daughter->GetTranslation() ); 408 if (dcenter.y() + dradius <= ymin) conti << 308 G4ThreeVector md = Td.Inverse().TransformPoint(mp); 409 if (dcenter.z() + dradius <= zmin) conti << 309 410 << 310 G4VSolid* daughterSolid = daughter->GetLogicalVolume()->GetSolid(); 411 G4ThreeVector pbox[8] = { << 311 if (daughterSolid->Inside(md)==kInside) 412 G4ThreeVector(pmin.x(), pmin.y(), pmin << 413 G4ThreeVector(pmax.x(), pmin.y(), pmin << 414 G4ThreeVector(pmin.x(), pmax.y(), pmin << 415 G4ThreeVector(pmax.x(), pmax.y(), pmin << 416 G4ThreeVector(pmin.x(), pmin.y(), pmax << 417 G4ThreeVector(pmax.x(), pmin.y(), pmax << 418 G4ThreeVector(pmin.x(), pmax.y(), pmax << 419 G4ThreeVector(pmax.x(), pmax.y(), pmax << 420 }; << 421 G4double dxmin = kInfinity, dymin = kI << 422 G4double dxmax = -kInfinity, dymax = -kI << 423 for (const auto & i : pbox) << 424 { << 425 G4ThreeVector p = Td.TransformPoint(i) << 426 dxmin = std::min(dxmin, p.x()); << 427 dymin = std::min(dymin, p.y()); << 428 dzmin = std::min(dzmin, p.z()); << 429 dxmax = std::max(dxmax, p.x()); << 430 dymax = std::max(dymax, p.y()); << 431 dzmax = std::max(dzmax, p.z()); << 432 } << 433 if (dxmin >= xmax) continue; << 434 if (dymin >= ymax) continue; << 435 if (dzmin >= zmax) continue; << 436 if (dxmax <= xmin) continue; << 437 if (dymax <= ymin) continue; << 438 if (dzmax <= zmin) continue; << 439 for (G4int i = 0; i < res; ++i) << 440 { 312 { 441 G4ThreeVector p = points[i]; << 313 G4double distout = daughterSolid->DistanceToOut(md); 442 if (p.x() >= dxmax) continue; << 314 if (distout > tol) 443 if (p.x() <= dxmin) continue; << 444 if (p.y() >= dymax) continue; << 445 if (p.y() <= dymin) continue; << 446 if (p.z() >= dzmax) continue; << 447 if (p.z() <= dzmin) continue; << 448 G4ThreeVector md = Td.InverseTransform << 449 if (daughterSolid->Inside(md) == kInsi << 450 { 315 { 451 check_encapsulation = false; << 316 G4cout << G4endl; 452 G4double distout = daughterSolid->Di << 317 G4cout << "WARNING - G4PVPlacement::CheckOverlaps()" << G4endl 453 if (distout < tol) continue; // too << 318 << " Overlap is detected for volume " 454 ++overlapCount; << 319 << GetName() << G4endl 455 if (distout <= overlapSize) continue << 320 << " with " << daughter->GetName() << " volume's" 456 overlapSize = distout; << 321 << G4endl 457 overlapPoint = md; << 322 << " local point " << md << ", " >> 323 << "overlapping by at least: " << G4BestUnit(distout,"Length") >> 324 << G4endl; >> 325 G4Exception("G4PVPlacement::CheckOverlaps()", "InvalidSetup", >> 326 JustWarning, "Overlap with volume already placed !"); >> 327 return true; 458 } 328 } 459 } 329 } 460 } << 461 330 462 // Print information on overlap << 331 // Now checking that 'sister' volume is not totally included and 463 // << 332 // overlapping. Do it only once, for the first point generated 464 if (overlapCount > 0) << 465 { << 466 ++trials; << 467 retval = true; << 468 std::ostringstream message; << 469 message << "Overlap with volume already << 470 << " Overlap is detecte << 471 << GetName() << ':' << GetCopyNo << 472 << " (" << solid->GetEntityType( << 473 << daughter->GetName() << ':' << << 474 << " (" << daughterSolid->GetEnt << 475 << " overlap at local p << 476 << " by " << G4BestUnit(overlapS << 477 << " (max of " << overlapCount < << 478 if (trials >= maxErr) << 479 { << 480 message << G4endl << 481 << "NOTE: Reached maximum fixe << 482 << "- of overlaps reports for << 483 } << 484 G4Exception("G4PVPlacement::CheckOverlap << 485 "GeomVol1002", JustWarning, << 486 if (trials >= maxErr) { return true; } << 487 } << 488 else if (check_encapsulation) << 489 { << 490 // Now checking that 'sister' volume is << 491 // and overlapping. Generate a single po << 492 // the 'sister' volume and verify that t << 493 // the current volume << 494 // 333 // 495 G4ThreeVector pSurface = daughterSolid-> << 334 if (n==0) 496 G4ThreeVector normal = daughterSolid->Su << 335 { 497 G4ThreeVector pInside = pSurface - norma << 336 // Generate a single point on the surface of the 'sister' volume 498 G4ThreeVector dPoint = (daughterSolid->I << 337 // and verify that the point is NOT inside the current volume 499 pInside : pSurface; << 500 338 501 // Transform the generated point to the << 339 G4ThreeVector dPoint = daughterSolid->GetPointOnSurface(); 502 // and then to current volume's coordina << 503 // << 504 G4ThreeVector mp2 = Td.TransformPoint(dP << 505 G4ThreeVector msi = Tm.InverseTransformP << 506 340 507 if (solid->Inside(msi) == kInside) << 341 // Transform the generated point to the mother's coordinate system 508 { << 342 // and finally to current volume's coordinate system 509 ++trials; << 343 // 510 retval = true; << 344 G4ThreeVector mp2 = Td.TransformPoint(dPoint); 511 std::ostringstream message; << 345 G4ThreeVector ms = Tm.Inverse().TransformPoint(mp2); 512 message << "Overlap with volume alread << 346 513 << " Overlap is detec << 347 if (solid->Inside(ms)==kInside) 514 << GetName() << ':' << GetCopy << 515 << " (" << solid->GetEntityTyp << 516 << " apparently fully << 517 << daughter->GetName() << ':' << 518 << " (" << daughterSolid->GetE << 519 << " at the same level!"; << 520 if (trials >= maxErr) << 521 { 348 { 522 message << G4endl << 349 G4cout << G4endl; 523 << "NOTE: Reached maximum fi << 350 G4cout << "WARNING - G4PVPlacement::CheckOverlaps()" << G4endl 524 << "- of overlaps reports fo << 351 << " Overlap is detected for volume " >> 352 << GetName() << G4endl >> 353 << " apparently fully encapsulating volume " >> 354 << daughter->GetName() << G4endl >> 355 << " at the same level !" << G4endl; >> 356 G4Exception("G4PVPlacement::CheckOverlaps()", "InvalidSetup", >> 357 JustWarning, "Overlap with volume already placed !"); >> 358 return true; 525 } 359 } 526 G4Exception("G4PVPlacement::CheckOverl << 527 "GeomVol1002", JustWarning << 528 if (trials >= maxErr) { return true; << 529 } 360 } 530 } 361 } 531 } 362 } 532 363 533 if (verbose && trials == 0) { G4cout << "OK! << 364 if (verbose) 534 return retval; << 365 { >> 366 G4cout << "OK! " << G4endl; >> 367 } >> 368 >> 369 return false; 535 } 370 } 536 371 537 // ------------------------------------------- 372 // ---------------------------------------------------------------------- 538 // NewPtrRotMatrix 373 // NewPtrRotMatrix 539 // 374 // 540 // Auxiliary function for 2nd & 4th constructo 375 // Auxiliary function for 2nd & 4th constructors (those with G4Transform3D) 541 // Creates a new rotation matrix on the heap ( 376 // Creates a new rotation matrix on the heap (using "new") and copies its 542 // argument into it. 377 // argument into it. 543 // 378 // 544 // NOTE: Ownership of the returned pointer is 379 // NOTE: Ownership of the returned pointer is left to the caller ! 545 // No entity is currently responsible to << 380 // No entity is currently responsible to delete this memory. 546 // 381 // 547 G4RotationMatrix* 382 G4RotationMatrix* 548 G4PVPlacement::NewPtrRotMatrix(const G4Rotatio 383 G4PVPlacement::NewPtrRotMatrix(const G4RotationMatrix &RotMat) 549 { 384 { 550 G4RotationMatrix* pRotMatrix; << 385 G4RotationMatrix *pRotMatrix; 551 if ( RotMat.isIdentity() ) 386 if ( RotMat.isIdentity() ) 552 { 387 { 553 pRotMatrix = nullptr; << 388 pRotMatrix = 0; 554 } 389 } 555 else 390 else 556 { 391 { 557 pRotMatrix = new G4RotationMatrix(RotMat) 392 pRotMatrix = new G4RotationMatrix(RotMat); 558 } 393 } >> 394 // fallocatedRotM= ! (RotMat.isIdentity()); >> 395 559 return pRotMatrix; 396 return pRotMatrix; 560 } 397 } 561 398