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 74459 2013-10-07 15:24:43Z gcosmo $ >> 28 // >> 29 // 26 // class G4PVPlacement Implementation 30 // class G4PVPlacement Implementation 27 // 31 // 28 // 24.07.95 P.Kent, First non-stub version. << 29 // ------------------------------------------- 32 // ---------------------------------------------------------------------- 30 33 31 #include "G4PVPlacement.hh" 34 #include "G4PVPlacement.hh" 32 #include "G4AffineTransform.hh" 35 #include "G4AffineTransform.hh" 33 #include "G4UnitsTable.hh" 36 #include "G4UnitsTable.hh" 34 #include "G4LogicalVolume.hh" 37 #include "G4LogicalVolume.hh" 35 #include "G4VSolid.hh" 38 #include "G4VSolid.hh" 36 39 37 // ------------------------------------------- 40 // ---------------------------------------------------------------------- 38 // Constructor 41 // Constructor 39 // 42 // 40 G4PVPlacement::G4PVPlacement( G4RotationMatrix << 43 G4PVPlacement::G4PVPlacement( G4RotationMatrix *pRot, 41 const G4ThreeVector& t << 44 const G4ThreeVector &tlate, 42 const G4String& pName, 45 const G4String& pName, 43 G4LogicalVolume* << 46 G4LogicalVolume *pLogical, 44 G4VPhysicalVolum << 47 G4VPhysicalVolume *pMother, 45 G4bool pMany, 48 G4bool pMany, 46 G4int pCopyNo, 49 G4int pCopyNo, 47 G4bool pSurfChk 50 G4bool pSurfChk ) 48 : G4VPhysicalVolume(pRot, tlate, pName, pLog << 51 : G4VPhysicalVolume(pRot,tlate,pName,pLogical,pMother), 49 fmany(pMany), fcopyNo(pCopyNo) << 52 fmany(pMany), fallocatedRotM(false), fcopyNo(pCopyNo) 50 { 53 { 51 if (pMother != nullptr) << 54 if (pMother) 52 { 55 { 53 G4LogicalVolume* motherLogical = pMother-> 56 G4LogicalVolume* motherLogical = pMother->GetLogicalVolume(); 54 if (pLogical == motherLogical) 57 if (pLogical == motherLogical) 55 { 58 { 56 G4Exception("G4PVPlacement::G4PVPlacemen 59 G4Exception("G4PVPlacement::G4PVPlacement()", "GeomVol0002", 57 FatalException, "Cannot plac 60 FatalException, "Cannot place a volume inside itself!"); 58 } 61 } 59 SetMotherLogical(motherLogical); 62 SetMotherLogical(motherLogical); 60 motherLogical->AddDaughter(this); 63 motherLogical->AddDaughter(this); 61 if (pSurfChk) { CheckOverlaps(); } 64 if (pSurfChk) { CheckOverlaps(); } 62 } 65 } 63 } 66 } 64 67 65 // ------------------------------------------- 68 // ---------------------------------------------------------------------- 66 // Constructor 69 // Constructor 67 // 70 // 68 G4PVPlacement::G4PVPlacement( const G4Transfor << 71 G4PVPlacement::G4PVPlacement( const G4Transform3D &Transform3D, 69 const G4String& 72 const G4String& pName, 70 G4LogicalV << 73 G4LogicalVolume *pLogical, 71 G4VPhysica << 74 G4VPhysicalVolume *pMother, 72 G4bool pMa 75 G4bool pMany, 73 G4int pCop 76 G4int pCopyNo, 74 G4bool pSu 77 G4bool pSurfChk ) 75 : G4VPhysicalVolume(NewPtrRotMatrix(Transfor 78 : G4VPhysicalVolume(NewPtrRotMatrix(Transform3D.getRotation().inverse()), 76 Transform3D.getTranslati << 79 Transform3D.getTranslation(),pName,pLogical,pMother), 77 fmany(pMany), fcopyNo(pCopyNo) 80 fmany(pMany), fcopyNo(pCopyNo) 78 { 81 { 79 fallocatedRotM = (GetRotation() != nullptr); << 82 fallocatedRotM = (GetRotation() != 0); 80 if (pMother != nullptr) << 83 if (pMother) 81 { 84 { 82 G4LogicalVolume* motherLogical = pMother-> 85 G4LogicalVolume* motherLogical = pMother->GetLogicalVolume(); 83 if (pLogical == motherLogical) 86 if (pLogical == motherLogical) 84 G4Exception("G4PVPlacement::G4PVPlacemen 87 G4Exception("G4PVPlacement::G4PVPlacement()", "GeomVol0002", 85 FatalException, "Cannot plac 88 FatalException, "Cannot place a volume inside itself!"); 86 SetMotherLogical(motherLogical); 89 SetMotherLogical(motherLogical); 87 motherLogical->AddDaughter(this); 90 motherLogical->AddDaughter(this); 88 if (pSurfChk) { CheckOverlaps(); } 91 if (pSurfChk) { CheckOverlaps(); } 89 } 92 } 90 } 93 } 91 94 92 // ------------------------------------------- 95 // ---------------------------------------------------------------------- 93 // Constructor 96 // Constructor 94 // 97 // 95 // The logical volume of the mother is utilise 98 // The logical volume of the mother is utilised (not the physical) 96 // 99 // 97 G4PVPlacement::G4PVPlacement( G4RotationMatrix << 100 G4PVPlacement::G4PVPlacement( G4RotationMatrix *pRot, 98 const G4ThreeVector& t << 101 const G4ThreeVector &tlate, 99 G4LogicalVolume* << 102 G4LogicalVolume *pCurrentLogical, 100 const G4String& pName, 103 const G4String& pName, 101 G4LogicalVolume* << 104 G4LogicalVolume *pMotherLogical, 102 G4bool pMany, 105 G4bool pMany, 103 G4int pCopyNo, 106 G4int pCopyNo, 104 G4bool pSurfChk 107 G4bool pSurfChk ) 105 : G4VPhysicalVolume(pRot, tlate, pName, pCur << 108 : G4VPhysicalVolume(pRot,tlate,pName,pCurrentLogical,0), 106 fmany(pMany), fcopyNo(pCopyNo) << 109 fmany(pMany), fallocatedRotM(false), fcopyNo(pCopyNo) 107 { 110 { 108 if (pCurrentLogical == pMotherLogical) 111 if (pCurrentLogical == pMotherLogical) 109 { 112 { 110 G4Exception("G4PVPlacement::G4PVPlacement( 113 G4Exception("G4PVPlacement::G4PVPlacement()", "GeomVol0002", 111 FatalException, "Cannot place 114 FatalException, "Cannot place a volume inside itself!"); 112 } 115 } 113 SetMotherLogical(pMotherLogical); 116 SetMotherLogical(pMotherLogical); 114 if (pMotherLogical != nullptr) { pMotherLogi << 117 if (pMotherLogical) { pMotherLogical->AddDaughter(this); } 115 if ((pSurfChk) && ((pMotherLogical) != nullp << 118 if ((pSurfChk) && (pMotherLogical)) { CheckOverlaps(); } 116 } 119 } 117 120 >> 121 118 // ------------------------------------------- 122 // ---------------------------------------------------------------------- 119 // Constructor 123 // Constructor 120 // 124 // 121 G4PVPlacement::G4PVPlacement( const G4Transfor << 125 G4PVPlacement::G4PVPlacement( const G4Transform3D &Transform3D, 122 G4LogicalV << 126 G4LogicalVolume *pCurrentLogical, 123 const G4String& 127 const G4String& pName, 124 G4LogicalV << 128 G4LogicalVolume *pMotherLogical, 125 G4bool pMa 129 G4bool pMany, 126 G4int pCop 130 G4int pCopyNo, 127 G4bool pSu 131 G4bool pSurfChk ) 128 : G4VPhysicalVolume(nullptr, Transform3D.get << 132 : G4VPhysicalVolume(0,Transform3D.getTranslation(),pName,pCurrentLogical,0), 129 pName, pCurrentLogical, << 130 fmany(pMany), fcopyNo(pCopyNo) 133 fmany(pMany), fcopyNo(pCopyNo) 131 { 134 { 132 if (pCurrentLogical == pMotherLogical) 135 if (pCurrentLogical == pMotherLogical) 133 { 136 { 134 G4Exception("G4PVPlacement::G4PVPlacement( 137 G4Exception("G4PVPlacement::G4PVPlacement()", "GeomVol0002", 135 FatalException, "Cannot place 138 FatalException, "Cannot place a volume inside itself!"); 136 } 139 } 137 SetRotation( NewPtrRotMatrix(Transform3D.get 140 SetRotation( NewPtrRotMatrix(Transform3D.getRotation().inverse()) ); 138 fallocatedRotM = (GetRotation() != nullptr); << 141 fallocatedRotM = (GetRotation() != 0); 139 SetMotherLogical(pMotherLogical); 142 SetMotherLogical(pMotherLogical); 140 if (pMotherLogical != nullptr) { pMotherLogi << 143 if (pMotherLogical) { pMotherLogical->AddDaughter(this); } 141 if ((pSurfChk) && ((pMotherLogical) != nullp << 144 if ((pSurfChk) && (pMotherLogical)) { CheckOverlaps(); } 142 } 145 } 143 146 144 // ------------------------------------------- 147 // ---------------------------------------------------------------------- 145 // Fake default constructor - sets only member 148 // Fake default constructor - sets only member data and allocates memory 146 // for usage restri 149 // for usage restricted to object persistency. 147 // 150 // 148 G4PVPlacement::G4PVPlacement( __void__& a ) 151 G4PVPlacement::G4PVPlacement( __void__& a ) 149 : G4VPhysicalVolume(a) << 152 : G4VPhysicalVolume(a), fmany(false), fallocatedRotM(0), fcopyNo(0) 150 { 153 { 151 } 154 } 152 155 153 // ------------------------------------------- 156 // ---------------------------------------------------------------------- 154 // Destructor 157 // Destructor 155 // 158 // 156 G4PVPlacement::~G4PVPlacement() 159 G4PVPlacement::~G4PVPlacement() 157 { 160 { 158 if( fallocatedRotM ){ delete this->GetRotati 161 if( fallocatedRotM ){ delete this->GetRotation() ; } 159 } 162 } 160 163 161 // ------------------------------------------- 164 // ---------------------------------------------------------------------- 162 // IsMany 165 // IsMany 163 // 166 // 164 G4bool G4PVPlacement::IsMany() const 167 G4bool G4PVPlacement::IsMany() const 165 { 168 { 166 return fmany; << 169 return fmany; >> 170 } >> 171 >> 172 // ---------------------------------------------------------------------- >> 173 // GetCopyNo >> 174 // >> 175 G4int G4PVPlacement::GetCopyNo() const >> 176 { >> 177 return fcopyNo; 167 } 178 } 168 179 169 // ------------------------------------------- 180 // ---------------------------------------------------------------------- 170 // SetCopyNo 181 // SetCopyNo 171 // 182 // 172 void G4PVPlacement::SetCopyNo(G4int newCopyNo) 183 void G4PVPlacement::SetCopyNo(G4int newCopyNo) 173 { 184 { 174 fcopyNo = newCopyNo; << 185 fcopyNo= newCopyNo; 175 } 186 } 176 187 177 // ------------------------------------------- 188 // ---------------------------------------------------------------------- 178 // IsReplicated 189 // IsReplicated 179 // 190 // 180 G4bool G4PVPlacement::IsReplicated() const 191 G4bool G4PVPlacement::IsReplicated() const 181 { 192 { 182 return false; 193 return false; 183 } 194 } 184 195 185 // ------------------------------------------- 196 // ---------------------------------------------------------------------- 186 // IsParameterised 197 // IsParameterised 187 // 198 // 188 G4bool G4PVPlacement::IsParameterised() const 199 G4bool G4PVPlacement::IsParameterised() const 189 { 200 { 190 return false; 201 return false; 191 } 202 } 192 203 193 // ------------------------------------------- 204 // ---------------------------------------------------------------------- 194 // GetParameterisation 205 // GetParameterisation 195 // 206 // 196 G4VPVParameterisation* G4PVPlacement::GetParam 207 G4VPVParameterisation* G4PVPlacement::GetParameterisation() const 197 { 208 { 198 return nullptr; << 209 return 0; 199 } 210 } 200 211 201 // ------------------------------------------- 212 // ---------------------------------------------------------------------- 202 // GetReplicationData 213 // GetReplicationData 203 // 214 // 204 void G4PVPlacement:: 215 void G4PVPlacement:: 205 GetReplicationData( EAxis&, G4int&, G4double&, 216 GetReplicationData( EAxis&, G4int&, G4double&, G4double&, G4bool& ) const 206 { 217 { 207 // No-operations 218 // No-operations 208 } 219 } 209 220 210 // ------------------------------------------- 221 // ---------------------------------------------------------------------- 211 // IsRegularRepeatedStructure 222 // IsRegularRepeatedStructure 212 // 223 // 213 // This is for specialised repeated volumes (r 224 // This is for specialised repeated volumes (replicas, parameterised vol.) 214 // 225 // 215 G4bool G4PVPlacement::IsRegularStructure() con 226 G4bool G4PVPlacement::IsRegularStructure() const 216 { 227 { 217 return false; 228 return false; 218 } << 229 } 219 230 220 // ------------------------------------------- 231 // ---------------------------------------------------------------------- 221 // IsRegularRepeatedStructure 232 // IsRegularRepeatedStructure 222 // 233 // 223 // This is for specialised repeated volumes (r 234 // This is for specialised repeated volumes (replicas, parameterised vol.) 224 // 235 // 225 G4int G4PVPlacement::GetRegularStructureId() c 236 G4int G4PVPlacement::GetRegularStructureId() const 226 { 237 { 227 return 0; << 238 return 0; 228 } << 239 } 229 << 230 // ------------------------------------------- << 231 // VolumeType << 232 // << 233 // Information to help identify sub-navigator << 234 // << 235 EVolume G4PVPlacement::VolumeType() const << 236 { << 237 return kNormal; << 238 } << 239 240 240 // ------------------------------------------- 241 // ---------------------------------------------------------------------- 241 // CheckOverlaps 242 // CheckOverlaps 242 // 243 // 243 G4bool G4PVPlacement::CheckOverlaps(G4int res, 244 G4bool G4PVPlacement::CheckOverlaps(G4int res, G4double tol, 244 G4bool ver 245 G4bool verbose, G4int maxErr) 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 G4int trials = 0; 253 G4bool retval = false; 254 G4bool retval = false; 254 255 255 if (verbose) << 256 G4VSolid* motherSolid = motherLog->GetSolid(); 256 { << 257 G4cout << "Checking overlaps for volume " << 258 << GetName() << ':' << GetCopyNo() << 259 << " (" << solid->GetEntityType() < << 260 } << 261 << 262 // Check that random points are gererated co << 263 // << 264 G4ThreeVector ptmp = solid->GetPointOnSurfac << 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 257 280 // Generate random points on the surface of << 258 if (verbose) 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 { 259 { 290 points[i] = Tm.TransformPoint(solid->GetPo << 260 G4cout << "Checking overlaps for volume " << GetName() << " ... "; 291 xmin = std::min(xmin, points[i].x()); << 292 ymin = std::min(ymin, points[i].y()); << 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 } 261 } 298 G4ThreeVector scenter(0.5*(xmax+xmin), 0.5*( << 299 G4double sradius = 0.5*G4ThreeVector(xmax-xm << 300 262 301 // Check overlap with the mother volume << 263 // Create the transformation from daughter to mother 302 // 264 // 303 G4int overlapCount = 0; << 265 G4AffineTransform Tm( GetRotation(), GetTranslation() ); 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 266 319 // Print information on overlap << 267 for (G4int n=0; n<res; n++) 320 // << 321 if (overlapCount > 0) << 322 { 268 { 323 ++trials; << 269 // Generate a random point on the solid's surface 324 retval = true; << 270 // 325 std::ostringstream message; << 271 G4ThreeVector point = solid->GetPointOnSurface(); 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 272 346 // Checking overlaps with each 'sister' volu << 273 // Transform the generated point to the mother's coordinate system 347 // << 274 // 348 G4VSolid* previous = nullptr; << 275 G4ThreeVector mp = Tm.TransformPoint(point); 349 G4ThreeVector pmin_local(0.,0.,0.), pmax_loc << 350 276 351 for (std::size_t k = 0; k < motherLog->GetNo << 277 // Checking overlaps with the mother volume 352 { << 278 // 353 G4VPhysicalVolume* daughter = motherLog->G << 279 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 { 280 { 361 daughterSolid->BoundingLimits(pmin_local << 281 G4double distin = motherSolid->DistanceToIn(mp); 362 previous = daughterSolid; << 282 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 { 283 { 378 G4ThreeVector p = points[i]; << 284 trials++; retval = true; 379 if (p.x() <= pmin.x()) continue; << 285 std::ostringstream message; 380 if (p.x() >= pmax.x()) continue; << 286 message << "Overlap with mother volume !" << G4endl 381 if (p.y() <= pmin.y()) continue; << 287 << " Overlap is detected for volume " 382 if (p.y() >= pmax.y()) continue; << 288 << GetName() << G4endl 383 if (p.z() <= pmin.z()) continue; << 289 << " with its mother volume " 384 if (p.z() >= pmax.z()) continue; << 290 << motherLog->GetName() << G4endl 385 G4ThreeVector md = p - offset; << 291 << " at mother local point " << mp << ", " 386 if (daughterSolid->Inside(md) == kInsi << 292 << "overlapping by at least: " >> 293 << G4BestUnit(distin, "Length"); >> 294 if (trials>=maxErr) 387 { 295 { 388 check_encapsulation = false; << 296 message << G4endl 389 G4double distout = daughterSolid->Di << 297 << "NOTE: Reached maximum fixed number -" << maxErr 390 if (distout < tol) continue; // too << 298 << "- of overlaps reports for this volume !"; 391 ++overlapCount; << 392 if (distout <= overlapSize) continue << 393 overlapSize = distout; << 394 overlapPoint = md; << 395 } 299 } >> 300 G4Exception("G4PVPlacement::CheckOverlaps()", >> 301 "GeomVol1002", JustWarning, message); >> 302 if (trials>=maxErr) { return true; } 396 } 303 } 397 } 304 } 398 else // transformation with rotation << 305 >> 306 // Checking overlaps with each 'sister' volume >> 307 // >> 308 for (G4int i=0; i<motherLog->GetNoDaughters(); i++) 399 { 309 { 400 G4ThreeVector pmin(pmin_local), pmax(pma << 310 G4VPhysicalVolume* daughter = motherLog->GetDaughter(i); 401 G4ThreeVector dcenter = Td.TransformPoin << 311 402 G4double dradius = 0.5*((pmax - pmin).ma << 312 if (daughter == this) { continue; } 403 if ((scenter - dcenter).mag2() >= (sradi << 313 404 if (dcenter.x() - dradius >= xmax) conti << 314 // Create the transformation for daughter volume and transform point 405 if (dcenter.y() - dradius >= ymax) conti << 315 // 406 if (dcenter.z() - dradius >= zmax) conti << 316 G4AffineTransform Td( daughter->GetRotation(), 407 if (dcenter.x() + dradius <= xmin) conti << 317 daughter->GetTranslation() ); 408 if (dcenter.y() + dradius <= ymin) conti << 318 G4ThreeVector md = Td.Inverse().TransformPoint(mp); 409 if (dcenter.z() + dradius <= zmin) conti << 319 410 << 320 G4VSolid* daughterSolid = daughter->GetLogicalVolume()->GetSolid(); 411 G4ThreeVector pbox[8] = { << 321 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 { 322 { 441 G4ThreeVector p = points[i]; << 323 G4double distout = daughterSolid->DistanceToOut(md); 442 if (p.x() >= dxmax) continue; << 324 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 { 325 { 451 check_encapsulation = false; << 326 trials++; retval = true; 452 G4double distout = daughterSolid->Di << 327 std::ostringstream message; 453 if (distout < tol) continue; // too << 328 message << "Overlap with volume already placed !" << G4endl 454 ++overlapCount; << 329 << " Overlap is detected for volume " 455 if (distout <= overlapSize) continue << 330 << GetName() << G4endl 456 overlapSize = distout; << 331 << " with " << daughter->GetName() << " volume's" 457 overlapPoint = md; << 332 << G4endl >> 333 << " local point " << md << ", " >> 334 << "overlapping by at least: " >> 335 << G4BestUnit(distout,"Length"); >> 336 if (trials>=maxErr) >> 337 { >> 338 message << G4endl >> 339 << "NOTE: Reached maximum fixed number -" << maxErr >> 340 << "- of overlaps reports for this volume !"; >> 341 } >> 342 G4Exception("G4PVPlacement::CheckOverlaps()", >> 343 "GeomVol1002", JustWarning, message); >> 344 if (trials>=maxErr) { return true; } 458 } 345 } 459 } 346 } 460 } << 461 347 462 // Print information on overlap << 348 // Now checking that 'sister' volume is not totally included and 463 // << 349 // 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 // 350 // 495 G4ThreeVector pSurface = daughterSolid-> << 351 if (n==0) 496 G4ThreeVector normal = daughterSolid->Su << 352 { 497 G4ThreeVector pInside = pSurface - norma << 353 // Generate a single point on the surface of the 'sister' volume 498 G4ThreeVector dPoint = (daughterSolid->I << 354 // and verify that the point is NOT inside the current volume 499 pInside : pSurface; << 500 355 501 // Transform the generated point to the << 356 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 357 507 if (solid->Inside(msi) == kInside) << 358 // Transform the generated point to the mother's coordinate system 508 { << 359 // and finally to current volume's coordinate system 509 ++trials; << 360 // 510 retval = true; << 361 G4ThreeVector mp2 = Td.TransformPoint(dPoint); 511 std::ostringstream message; << 362 G4ThreeVector msi = Tm.Inverse().TransformPoint(mp2); 512 message << "Overlap with volume alread << 363 513 << " Overlap is detec << 364 if (solid->Inside(msi)==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 { 365 { 522 message << G4endl << 366 trials++; retval = true; 523 << "NOTE: Reached maximum fi << 367 std::ostringstream message; 524 << "- of overlaps reports fo << 368 message << "Overlap with volume already placed !" << G4endl >> 369 << " Overlap is detected for volume " >> 370 << GetName() << G4endl >> 371 << " apparently fully encapsulating volume " >> 372 << daughter->GetName() << G4endl >> 373 << " at the same level !"; >> 374 G4Exception("G4PVPlacement::CheckOverlaps()", >> 375 "GeomVol1002", JustWarning, message); >> 376 if (trials>=maxErr) { return true; } 525 } 377 } 526 G4Exception("G4PVPlacement::CheckOverl << 527 "GeomVol1002", JustWarning << 528 if (trials >= maxErr) { return true; << 529 } 378 } 530 } 379 } 531 } 380 } 532 381 533 if (verbose && trials == 0) { G4cout << "OK! << 382 if (verbose) >> 383 { >> 384 G4cout << "OK! " << G4endl; >> 385 } >> 386 534 return retval; 387 return retval; 535 } 388 } 536 389 537 // ------------------------------------------- 390 // ---------------------------------------------------------------------- 538 // NewPtrRotMatrix 391 // NewPtrRotMatrix 539 // 392 // 540 // Auxiliary function for 2nd & 4th constructo 393 // Auxiliary function for 2nd & 4th constructors (those with G4Transform3D) 541 // Creates a new rotation matrix on the heap ( 394 // Creates a new rotation matrix on the heap (using "new") and copies its 542 // argument into it. 395 // argument into it. 543 // 396 // 544 // NOTE: Ownership of the returned pointer is 397 // NOTE: Ownership of the returned pointer is left to the caller ! 545 // No entity is currently responsible to << 398 // No entity is currently responsible to delete this memory. 546 // 399 // 547 G4RotationMatrix* 400 G4RotationMatrix* 548 G4PVPlacement::NewPtrRotMatrix(const G4Rotatio 401 G4PVPlacement::NewPtrRotMatrix(const G4RotationMatrix &RotMat) 549 { 402 { 550 G4RotationMatrix* pRotMatrix; << 403 G4RotationMatrix *pRotMatrix; 551 if ( RotMat.isIdentity() ) 404 if ( RotMat.isIdentity() ) 552 { 405 { 553 pRotMatrix = nullptr; << 406 pRotMatrix = 0; 554 } 407 } 555 else 408 else 556 { 409 { 557 pRotMatrix = new G4RotationMatrix(RotMat) 410 pRotMatrix = new G4RotationMatrix(RotMat); 558 } 411 } >> 412 // fallocatedRotM= ! (RotMat.isIdentity()); >> 413 559 return pRotMatrix; 414 return pRotMatrix; 560 } 415 } 561 416